--- OpenBSD_malloc_orig.c 2006-06-25 23:10:35.000000000 +0400 +++ OpenBSD_malloc_Linux.c 2006-06-30 22:50:59.000000000 +0400 @@ -1,3 +1,8 @@ +/* Version 1.83 for Linux. + * Compilation: gcc -shared -fPIC -O2 OpenBSD_malloc_Linux.c -o malloc.so + * Launching: LD_PRELOAD=/path/to/malloc.so firefox + */ + /* $OpenBSD: malloc.c,v 1.83 2006/05/14 19:53:40 otto Exp $ */ /* @@ -50,7 +55,7 @@ #include #include -#include "thread_private.h" +//#include "thread_private.h" /* * The basic parameters you can tweak. @@ -67,6 +72,28 @@ * */ +static int align = 0; +static size_t g_alignment = 0; + +extern int __libc_enable_secure; + +static int issetugid(void) +{ + if (__libc_enable_secure) return 1; + if (getuid() != geteuid()) return 1; + if (getgid() != getegid()) return 1; + return 0; +} + +#define PGSHIFT 12 +#define MADV_FREE MADV_DONTNEED +#include +static pthread_mutex_t gen_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define _MALLOC_LOCK_INIT() {;} +#define _MALLOC_LOCK() {pthread_mutex_lock(&gen_mutex);} +#define _MALLOC_UNLOCK() {pthread_mutex_unlock(&gen_mutex);} + #if defined(__sparc__) #define malloc_pageshift 13U #endif /* __sparc__ */ @@ -194,7 +221,7 @@ static size_t malloc_guarded; /* align pointers to end of page? */ static int malloc_ptrguard; -static int malloc_hint; +static int malloc_hint = 1; /* xmalloc behaviour ? */ static int malloc_xmalloc; @@ -477,6 +504,28 @@ malloc_exit(void) #endif /* MALLOC_STATS */ /* + * Allocate aligned mmaped chunk + */ + +static void *MMAP_A(size_t pages, size_t alignment) +{ + void *j; + if (pages%malloc_pagesize != 0) + pages = pages - pages%malloc_pagesize + malloc_pagesize; + size_t first_size = pages + alignment - malloc_pagesize; + void *p = MMAP(first_size); + size_t rest = ((size_t)p) % alignment; + j = (rest == 0) ? p : (void*) ((size_t)p + alignment - rest); + size_t begin = (size_t)j - (size_t)p; + if (begin != 0) munmap(p, begin); + size_t end = (size_t)p + first_size - ((size_t)j + pages); + if(end != 0) munmap( (void*) ((size_t)j + pages), end); + + return j; +} + + +/* * Allocate a number of pages from the OS */ static void * @@ -491,7 +540,11 @@ map_pages(size_t pages) size_t dirs, cnt; pages <<= malloc_pageshift; - result = MMAP(pages + malloc_guard); + if (!align) + result = MMAP(pages + malloc_guard); + else { + result = MMAP_A(pages + malloc_guard, g_alignment); + } if (result == MAP_FAILED) { #ifdef MALLOC_EXTRA_SANITY wrtwarning("(ES): map_pages fails"); @@ -775,6 +828,7 @@ malloc_pages(size_t size) p = NULL; /* Look for free pages before asking for more */ + if (!align) for (pf = free_list.next; pf; pf = pf->next) { #ifdef MALLOC_EXTRA_SANITY @@ -1099,7 +1153,8 @@ malloc_bytes(size_t size) if (malloc_guard) { /* Walk to a random position. */ - i = arc4random() % bp->free; +// i = arc4random() % bp->free; + i = rand() % bp->free; while (i > 0) { u += u; k++; @@ -1805,6 +1860,7 @@ malloc(size_t size) { void *r; + if (!align) _MALLOC_LOCK(); malloc_func = " in malloc():"; if (malloc_active++) { @@ -1814,6 +1870,7 @@ malloc(size_t size) r = imalloc(size); UTRACE(0, size, r); malloc_active--; + if (!align) _MALLOC_UNLOCK(); if (malloc_xmalloc && r == NULL) { wrterror("out of memory"); @@ -1868,3 +1925,71 @@ realloc(void *ptr, size_t size) } return (r); } + +#if defined(__i386__)||defined(__arm__)||defined(__powerpc__) +#define SIZE_MAX 0xffffffff +#endif +#if defined(__x86_64__) +#define SIZE_MAX 0xffffffffffffffff +#endif + +void * +calloc(size_t num, size_t size) +{ + void *p; + + if (num && SIZE_MAX / num < size) { + fprintf(stderr,"OOOOPS"); + errno = ENOMEM; + return NULL; + } + size *= num; + p = malloc(size); + if (p) + memset(p, 0, size); + return(p); +} + +static int ispowerof2 (size_t a) { + size_t b; + for (b = 1ULL << (sizeof(size_t)*NBBY - 1); b > 1; b >>= 1) + if (b == a) + return 1; + return 0; +} + +int posix_memalign(void **memptr, size_t alignment, size_t size) +{ + void *r; + if ((alignment < PTR_SIZE) || (alignment%PTR_SIZE != 0)) return EINVAL; + if (!ispowerof2(alignment)) return EINVAL; + if (alignment < malloc_minsize) alignment = malloc_minsize; + size_t max = alignment > size ? alignment : size; + if (alignment <= malloc_pagesize) + r = malloc(max); + else { + _MALLOC_LOCK(); + align = 1; + g_alignment = alignment; + r = malloc(size); + align=0; + _MALLOC_UNLOCK(); + } + *memptr = r; + if (!r) return ENOMEM; + return 0; +} + +void *memalign(size_t boundary, size_t size) +{ + void *r; + posix_memalign(&r, boundary, size); + return r; +} + +void *valloc(size_t size) +{ + void *r; + posix_memalign(&r, malloc_pagesize, size); + return r; +}