--- elf/dl-minimal.c | 12 +-- elf/rtld.c | 10 ++- malloc/arena.c | 5 + malloc/malloc.c | 148 +++++++++++++-------------------------------- nptl/allocatestack.c | 2 nptl/init.c | 4 + sysdeps/generic/ldsodefs.h | 8 ++ 7 files changed, 77 insertions(+), 112 deletions(-) Index: glibc-2.5/elf/dl-minimal.c =================================================================== --- glibc-2.5.orig/elf/dl-minimal.c 2005-12-17 15:08:29.000000000 -0800 +++ glibc-2.5/elf/dl-minimal.c 2007-06-26 15:55:04.000000000 -0700 @@ -80,7 +80,7 @@ caddr_t page; size_t nup = (n + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1); page = __mmap (0, nup, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); + MAP_ANON|MAP_PRIVATE|GLRO(ld_mmap_flags), _dl_zerofd, 0); assert (page != MAP_FAILED); if (page != alloc_end) alloc_ptr = page; @@ -104,10 +104,13 @@ void * weak_function calloc (size_t nmemb, size_t size) { + void *data = malloc (nmemb * size); + if (data) + memset(data, 0, nmemb * size); /* New memory from the trivial malloc above is always already cleared. (We make sure that's true in the rare occasion it might not be, by clearing memory in free, below.) */ - return malloc (nmemb * size); + return data; } /* This will rarely be called. */ @@ -116,12 +119,7 @@ { /* We can free only the last block allocated. */ if (ptr == alloc_last_block) - { - /* Since this is rare, we clear the freed block here - so that calloc can presume malloc returns cleared memory. */ - memset (alloc_last_block, '\0', alloc_ptr - alloc_last_block); alloc_ptr = alloc_last_block; - } } /* This is only called with the most recent block returned by malloc. */ Index: glibc-2.5/elf/rtld.c =================================================================== --- glibc-2.5.orig/elf/rtld.c 2006-09-29 09:56:15.000000000 -0700 +++ glibc-2.5/elf/rtld.c 2007-06-26 15:55:04.000000000 -0700 @@ -2589,7 +2589,15 @@ /* Path where the binary is found. */ if (!INTUSE(__libc_enable_secure) && memcmp (envline, "ORIGIN_PATH", 11) == 0) - GLRO(dl_origin_path) = &envline[12]; + { + GLRO(dl_origin_path) = &envline[12]; + break; + } + if (memcmp (envline, "MMAP_NOZERO", 11) == 0) + { + GLRO(ld_mmap_flags) |= MAP_NOZERO; + break; + } break; case 12: Index: glibc-2.5/malloc/arena.c =================================================================== --- glibc-2.5.orig/malloc/arena.c 2006-09-07 09:04:22.000000000 -0700 +++ glibc-2.5/malloc/arena.c 2007-06-26 15:55:04.000000000 -0700 @@ -487,6 +487,8 @@ # undef NO_STARTER # endif #endif + if((s = getenv("MALLOC_NOZERO")) != NULL && atoi(s) > 0) + mmap_flags |= MAP_NOZERO; #ifdef _LIBC secure = __libc_enable_secure; s = NULL; @@ -691,6 +693,7 @@ return 0; } h = (heap_info *)p2; + memset(h, 0, sizeof(heap_info)); h->size = size; THREAD_STAT(stat_n_heaps++); return h; @@ -818,6 +821,7 @@ return 0; } a = h->ar_ptr = (mstate)(h+1); + memset(a, 0, sizeof(struct malloc_state)); malloc_init_state(a); /*a->next = NULL;*/ a->system_mem = a->max_system_mem = h->size; @@ -834,6 +838,7 @@ if (misalign > 0) ptr += MALLOC_ALIGNMENT - misalign; top(a) = (mchunkptr)ptr; + memset(ptr, 0, sizeof(struct malloc_chunk)); set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE); return a; Index: glibc-2.5/malloc/malloc.c =================================================================== --- glibc-2.5.orig/malloc/malloc.c 2006-09-07 09:06:02.000000000 -0700 +++ glibc-2.5/malloc/malloc.c 2007-06-26 15:55:04.000000000 -0700 @@ -496,7 +496,6 @@ #define MORECORE_FAILURE 0 Void_t * __default_morecore (ptrdiff_t); -Void_t *(*__morecore)(ptrdiff_t) = __default_morecore; #else /* !_LIBC */ #define public_cALLOc calloc @@ -1754,14 +1753,50 @@ #else +#ifndef MAP_NOZERO +#define MAP_NOZERO 0x04000000 +#endif + #define MMAP(addr, size, prot, flags) \ - (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS, -1, 0)) + (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS|mmap_flags, -1, 0)) #endif #endif /* HAVE_MMAP */ +static unsigned int mmap_flags; + +#include + +#ifndef __NR_brk2 +#if defined(__x86_64__) +#define __NR_brk2 285 +#elif defined(__i386__) +#define __NR_brk2 324 +#else +#error Cannot detect your architecture! +#endif +#endif + +static unsigned long brk2(unsigned long addr, unsigned long flags) { + + return syscall(__NR_brk2, addr, flags); +} + +static Void_t *nz_morecore(ptrdiff_t cdiff) { + static Void_t *curr_brk = NULL, *prev_brk; + + if (curr_brk == NULL) + curr_brk = (Void_t *) brk2(0, 0); + prev_brk = curr_brk; + curr_brk = (Void_t *) brk2((unsigned long) (curr_brk + cdiff), mmap_flags); + return prev_brk; +} + +Void_t *(*__morecore)(ptrdiff_t) = nz_morecore; + + /* ----------------------- Chunk representations ----------------------- @@ -2907,11 +2942,13 @@ if (front_misalign > 0) { correction = MALLOC_ALIGNMENT - front_misalign; p = (mchunkptr)(mm + correction); + memset(p, 0, sizeof(struct malloc_chunk)); p->prev_size = correction; set_head(p, (size - correction) |IS_MMAPPED); } else { p = (mchunkptr)mm; + memset(p, 0, sizeof(struct malloc_chunk)); set_head(p, size|IS_MMAPPED); } @@ -3079,7 +3116,7 @@ char *mbrk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE)); if (mbrk != MAP_FAILED) { - + memset(mbrk, 0, sizeof(struct malloc_chunk)); /* We do not need, and cannot use, another sbrk call to find end */ brk = mbrk; snd_brk = brk + size; @@ -3753,12 +3790,9 @@ public_cALLOc(size_t n, size_t elem_size) { mstate av; - mchunkptr oldtop, p; - INTERNAL_SIZE_T bytes, sz, csz, oldtopsize; + mchunkptr oldtop; + INTERNAL_SIZE_T bytes, sz, oldtopsize; Void_t* mem; - unsigned long clearsize; - unsigned long nclears; - INTERNAL_SIZE_T* d; __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, __const __malloc_ptr_t)) = __malloc_hook; @@ -3832,56 +3866,7 @@ } if (mem == 0) return 0; } - p = mem2chunk(mem); - - /* Two optional cases in which clearing not necessary */ -#if HAVE_MMAP - if (chunk_is_mmapped (p)) - { - if (__builtin_expect (perturb_byte, 0)) - MALLOC_ZERO (mem, sz); - return mem; - } -#endif - - csz = chunksize(p); - -#if MORECORE_CLEARS - if (perturb_byte == 0 && (p == oldtop && csz > oldtopsize)) { - /* clear only the bytes from non-freshly-sbrked memory */ - csz = oldtopsize; - } -#endif - - /* Unroll clear of <= 36 bytes (72 if 8byte sizes). We know that - contents have an odd number of INTERNAL_SIZE_T-sized words; - minimally 3. */ - d = (INTERNAL_SIZE_T*)mem; - clearsize = csz - SIZE_SZ; - nclears = clearsize / sizeof(INTERNAL_SIZE_T); - assert(nclears >= 3); - - if (nclears > 9) - MALLOC_ZERO(d, clearsize); - - else { - *(d+0) = 0; - *(d+1) = 0; - *(d+2) = 0; - if (nclears > 4) { - *(d+3) = 0; - *(d+4) = 0; - if (nclears > 6) { - *(d+5) = 0; - *(d+6) = 0; - if (nclears > 8) { - *(d+7) = 0; - *(d+8) = 0; - } - } - } - } - + MALLOC_ZERO (mem, sz); return mem; } @@ -4322,7 +4307,6 @@ /* Split */ else { remainder = chunk_at_offset(victim, nb); - /* We cannot assume the unsorted list is empty and therefore have to perform a complete insert here. */ bck = unsorted_chunks(av); @@ -5096,53 +5080,11 @@ Void_t* cALLOc(n_elements, elem_size) size_t n_elements; size_t elem_size; #endif { - mchunkptr p; - unsigned long clearsize; - unsigned long nclears; - INTERNAL_SIZE_T* d; - Void_t* mem = mALLOc(n_elements * elem_size); - if (mem != 0) { - p = mem2chunk(mem); - -#if MMAP_CLEARS - if (!chunk_is_mmapped(p)) /* don't need to clear mmapped space */ -#endif - { - /* - Unroll clear of <= 36 bytes (72 if 8byte sizes) - We know that contents have an odd number of - INTERNAL_SIZE_T-sized words; minimally 3. - */ - - d = (INTERNAL_SIZE_T*)mem; - clearsize = chunksize(p) - SIZE_SZ; - nclears = clearsize / sizeof(INTERNAL_SIZE_T); - assert(nclears >= 3); - - if (nclears > 9) - MALLOC_ZERO(d, clearsize); + if (mem != 0) + MALLOC_ZERO(mem, n_elements * elem_size); - else { - *(d+0) = 0; - *(d+1) = 0; - *(d+2) = 0; - if (nclears > 4) { - *(d+3) = 0; - *(d+4) = 0; - if (nclears > 6) { - *(d+5) = 0; - *(d+6) = 0; - if (nclears > 8) { - *(d+7) = 0; - *(d+8) = 0; - } - } - } - } - } - } return mem; } #endif /* 0 */ Index: glibc-2.5/nptl/allocatestack.c =================================================================== --- glibc-2.5.orig/nptl/allocatestack.c 2006-08-23 10:39:47.000000000 -0700 +++ glibc-2.5/nptl/allocatestack.c 2007-06-26 15:55:04.000000000 -0700 @@ -442,7 +442,7 @@ #endif mem = mmap (NULL, size, prot, - MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS, -1, 0); + MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS | GL(ld_mmap_flags), -1, 0); if (__builtin_expect (mem == MAP_FAILED, 0)) { Index: glibc-2.5/nptl/init.c =================================================================== --- glibc-2.5.orig/nptl/init.c 2006-08-23 10:41:31.000000000 -0700 +++ glibc-2.5/nptl/init.c 2007-06-26 15:55:04.000000000 -0700 @@ -395,6 +395,10 @@ /* Determine whether the machine is SMP or not. */ __is_smp = is_smp_system (); + + char const *s = getenv("LD_MMAP_NOZERO"); + if (s && atoi(s) > 0) + GL(ld_mmap_flags) |= MAP_NOZERO; } strong_alias (__pthread_initialize_minimal_internal, __pthread_initialize_minimal) Index: glibc-2.5/sysdeps/generic/ldsodefs.h =================================================================== --- glibc-2.5.orig/sysdeps/generic/ldsodefs.h 2006-08-24 13:27:05.000000000 -0700 +++ glibc-2.5/sysdeps/generic/ldsodefs.h 2007-06-26 15:55:04.000000000 -0700 @@ -41,6 +41,10 @@ __BEGIN_DECLS +#ifndef MAP_NOZERO +#define MAP_NOZERO 0x04000000 +#endif + /* We use this macro to refer to ELF types independent of the native wordsize. `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) @@ -491,6 +495,8 @@ EXTERN size_t _dl_tls_generation; EXTERN void (*_dl_init_static_tls) (struct link_map *); + + EXTERN unsigned int _ld_mmap_flags; #endif #ifdef SHARED @@ -639,6 +645,8 @@ EXTERN struct link_map *_dl_sysinfo_map; #endif + EXTERN unsigned int _ld_mmap_flags; + #ifdef SHARED /* We add a function table to _rtld_global which is then used to call the function instead of going through the PLT. The result