Ooops... This one actually compiles..
Description: Aligned memory allocation Changes to the allocators, to allow for aligned allocation. Not very well tested. May not be portable. Also changed GET_RET_ADDR macro. . dmalloc (5.5.2-2) unstable; urgency=low . * Added posix_memalign * changed GET_RET_ADDR() to use __builtin_return_address Author: Johann Klammer <klamm...@a1.net> Bug-Debian: http://bugs.debian.org/676585 Bug-Debian: http://bugs.debian.org/676587 --- dmalloc-5.5.2.orig/malloc.c +++ dmalloc-5.5.2/malloc.c @@ -38,6 +38,20 @@ # include <unistd.h> /* for write */ #endif +#if HAVE_ERRNO_H +# include <errno.h> /* for ENOMEM EINVAL */ +#else + +#ifndef ENOMEM +#define ENOMEM 1 +#endif /*ENOMEM*/ + +#ifndef EINVAL +#define EINVAL 2 +#endif /*EINVAL*/ + +#endif /*HAVE_ERRNO_H*/ + /* * cygwin includes */ @@ -719,6 +733,12 @@ void __fini_dmalloc(void) } #endif + +static int is_aligned_to(const char * rv,const DMALLOC_SIZE alignment) +{ + return 0==(((DMALLOC_SIZE)rv)%alignment);//alignment must not be zero +} + /* * DMALLOC_PNT dmalloc_malloc * @@ -754,6 +774,41 @@ DMALLOC_PNT dmalloc_malloc(const char *f const DMALLOC_SIZE alignment, const int xalloc_b) { + DMALLOC_SIZE align=(alignment==0)?1:alignment;//0==bad + DMALLOC_SIZE overhead=align-1+sizeof(DMALLOC_SIZE); + DMALLOC_SIZE offset=0,sz; + DMALLOC_PNT base; + char * rv; + + sz=size+overhead; +#if ALLOW_ALLOC_ZERO_SIZE == 0 + if (size == 0) { + sz=0; + } +#endif + + base=dmalloc_malloc_real(file, line, sz, func_id, 0, xalloc_b); + rv=base; + + if(NULL==rv) + return NULL; + /*byte addressable?*/ + while(! is_aligned_to(rv+sizeof(offset),align)) + { + offset++; + rv++; + } + + memmove(rv,&offset,sizeof(offset)); + rv+=sizeof(offset); + return rv; +} + +DMALLOC_PNT dmalloc_malloc_real(const char *file, const int line, + const DMALLOC_SIZE size, const int func_id, + const DMALLOC_SIZE alignment, + const int xalloc_b) +{ void *new_p; DMALLOC_SIZE align; @@ -825,12 +880,79 @@ DMALLOC_PNT dmalloc_malloc(const char *f return new_p; } + +static int power_of_two(DMALLOC_SIZE v) +{ + unsigned i; + for(i=0;i<(sizeof(v)*8);i++) { + if((((DMALLOC_SIZE)1)<<i)==v) + return 1; + } + return 0; +} + +/* + * int dmalloc_posix_memalign + * + * DESCRIPTION: + * + * Overloading the posix_memalign(3) function. Allocate and return a memory + * block of a certain size which has been aligned to a certain + * alignment. + * + * RETURNS: + * + * Success - zero. + * EINVAL The alignment argument was not a power of two, or was not a multiple of sizeof(void *). + * ENOMEM There was insufficient memory to fulfill the allocation request. + * + * ARGUMENTS: + * memptr -> pointer will be returned here on success + * + * alignment -> Value to which the allocation must be aligned. This + * should probably be a multiple of 2 with a maximum value equivalent + * to the block-size which is often 1k or 4k. + * + * size -> Number of bytes requested. + * + * file -> File-name or return-address of the caller. + * + * line -> Line-number of the caller. + * + * func_id -> Function-id to identify the type of call. See + * dmalloc.h. + * + * xalloc_b -> If set to 1 then print an error and exit if we run out + * of memory. + */ +extern +int dmalloc_posix_memalign(const char *file, const int line, DMALLOC_PNT *memptr, + const DMALLOC_SIZE size, const int func_id, + const DMALLOC_SIZE alignment, + const int xalloc_b) +{ + DMALLOC_PNT rv; + if((NULL==memptr)||(!power_of_two(alignment))||(alignment<sizeof(void*))) + return EINVAL; + + rv=dmalloc_malloc(file, line,size, func_id, alignment, xalloc_b); + if(NULL==rv) + return ENOMEM; + *memptr=rv; + return 0; +} + +extern +DMALLOC_PNT _dmalloc_chunk_get_baseptr(DMALLOC_PNT p); + + /* * DMALLOC_PNT dmalloc_realloc * * DESCRIPTION: * * Resizes and old pointer to a new number of bytes. + * Will destroy previous alignment. * * RETURNS: * @@ -855,7 +977,69 @@ DMALLOC_PNT dmalloc_malloc(const char *f * xalloc_b -> If set to 1 then print an error and exit if we run out * of memory. */ + DMALLOC_PNT dmalloc_realloc(const char *file, const int line, + DMALLOC_PNT old_p, DMALLOC_SIZE new_size, + const int func_id, const int xalloc_b) +{ + DMALLOC_PNT old_pnt=NULL; + DMALLOC_PNT new_pnt=NULL; + DMALLOC_SIZE old_offs=0,offs=0,nsz=0;//no alignment + + if(NULL!=old_p) { + old_pnt=_dmalloc_chunk_get_baseptr(old_p); + memmove(&old_offs,old_p-sizeof(old_offs),sizeof(old_offs)); + } + + nsz=new_size+sizeof(offs)+old_offs; + + //hope I got those right now.. + if(0==new_size) { + +#if ALLOW_REALLOC_SIZE_ZERO + nsz=0; +#else +#if ALLOW_ALLOC_ZERO_SIZE == 0 + nsz=0; +#else + nsz=sizeof(offs); +#endif +#endif + } + /* + something like this.. + if((0==ALLOW_ALLOC_ZERO_SIZE)&&(1==ALLOW_REALLOC_SIZE_ZERO)&&(0==new_size)) + { + //dmalloc_chunk_free + } + if((1==ALLOW_ALLOC_ZERO_SIZE)&&(1==ALLOW_REALLOC_SIZE_ZERO)&&(0==new_size)) + { + //dmalloc_chunk_free + } + if((0==ALLOW_ALLOC_ZERO_SIZE)&&(0==ALLOW_REALLOC_SIZE_ZERO)&&(0==new_size)) + { + //should generate error (and we get a NULL back)... the same as dmalloc_chunk_free, but no free + } + if((1==ALLOW_ALLOC_ZERO_SIZE)&&(0==ALLOW_REALLOC_SIZE_ZERO)&&(0==new_size)) + { + //allocate a min sized block(offset should fit) + } + */ + + + + new_pnt=dmalloc_realloc_real(file, line, old_pnt, nsz, + func_id, xalloc_b); + if(NULL==new_pnt) + return NULL; + + memmove(new_pnt,&offs,sizeof(offs)); + if((0!=old_offs)&&(0!=new_size)) + memmove(new_pnt+sizeof(offs),new_pnt+sizeof(offs)+old_offs,new_size); + return new_pnt+sizeof(offs); +} + +DMALLOC_PNT dmalloc_realloc_real(const char *file, const int line, DMALLOC_PNT old_pnt, DMALLOC_SIZE new_size, const int func_id, const int xalloc_b) { @@ -932,6 +1116,7 @@ DMALLOC_PNT dmalloc_realloc(const char * return new_p; } + /* * int dmalloc_free * @@ -962,6 +1147,14 @@ DMALLOC_PNT dmalloc_realloc(const char * int dmalloc_free(const char *file, const int line, DMALLOC_PNT pnt, const int func_id) { + DMALLOC_PNT p; + p=_dmalloc_chunk_get_baseptr(pnt); + return dmalloc_free_real(file,line,p,func_id); +} + +int dmalloc_free_real(const char *file, const int line, DMALLOC_PNT pnt, + const int func_id) +{ int ret; if (! dmalloc_in(file, line, 1)) { @@ -1209,6 +1402,40 @@ DMALLOC_PNT memalign(DMALLOC_SIZE alignm 0 /* no xalloc messages */); } + +/* + * int posix_memalign + * + * DESCRIPTION: + * + * Overloading the posix_memalign(3) function. Allocate and return a memory + * block of a certain size which has been aligned to a certain + * alignment. + * + * RETURNS: + * + * Success - zero. + * EINVAL The alignment argument was not a power of two, or was not a multiple of sizeof(void *). + * ENOMEM There was insufficient memory to fulfill the allocation request. + * + * + * ARGUMENTS: + * memptr -> pointer will be returned here on success + * alignment -> Value to which the allocation must be aligned. This + * should probably be a multiple of 2 with a maximum value equivalent + * to the block-size which is often 1k or 4k. + * + * size -> Number of bytes requested. + */ +#undef posix_memalign +int posix_memalign(DMALLOC_PNT *memptr, DMALLOC_SIZE alignment, DMALLOC_SIZE size) +{ + char *file; + GET_RET_ADDR(file); + return dmalloc_posix_memalign(file, DMALLOC_DEFAULT_LINE, memptr, + size, DMALLOC_FUNC_POSIX_MEMALIGN, alignment, + 0); +} /* * DMALLOC_PNT valloc * @@ -1428,6 +1655,13 @@ DMALLOC_FREE_RET cfree(DMALLOC_PNT pnt) */ int dmalloc_verify(const DMALLOC_PNT pnt) { + DMALLOC_PNT p; + p=_dmalloc_chunk_get_baseptr((DMALLOC_PNT)pnt); + return dmalloc_verify_real(p); +} + +int dmalloc_verify_real(const DMALLOC_PNT pnt) +{ int ret; if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 0)) { @@ -1526,6 +1760,9 @@ int dmalloc_verify_pnt_strsize(const cha if (! dmalloc_in(file, line, 0)) { return MALLOC_VERIFY_NOERROR; } + + if(exact_b)/* we need the exact ptr... may weaken checks... */ + pnt=_dmalloc_chunk_get_baseptr((DMALLOC_PNT)pnt); /* call the pnt checking chunk code */ ret = _dmalloc_chunk_pnt_check(func, pnt, exact_b, strlen_b, min_size); @@ -1737,6 +1974,34 @@ int dmalloc_examine(const DMALLOC_PNT pn unsigned int *line_p, DMALLOC_PNT *ret_attr_p, unsigned long *used_mark_p, unsigned long *seen_p) { + DMALLOC_PNT p; + int rv; + DMALLOC_SIZE s,offs,u_s; + if(NULL!=user_size_p) + s=*user_size_p; + + p=_dmalloc_chunk_get_baseptr((DMALLOC_PNT)pnt); + rv=dmalloc_examine_real(p, &s, + total_size_p, file_p,line_p, ret_attr_p,used_mark_p, seen_p); + if(NULL!=p) + { + memmove(&offs,((char *)pnt)-sizeof(offs),sizeof(offs)); + u_s=s-sizeof(offs)-offs; + } + else + { + u_s=s; + } + if(NULL!=user_size_p) + *user_size_p=u_s; + return rv; +} + +int dmalloc_examine_real(const DMALLOC_PNT pnt, DMALLOC_SIZE *user_size_p, + DMALLOC_SIZE *total_size_p, char **file_p, + unsigned int *line_p, DMALLOC_PNT *ret_attr_p, + unsigned long *used_mark_p, unsigned long *seen_p) +{ int ret; unsigned int user_size_map, tot_size_map; unsigned long *loc_seen_p; --- dmalloc-5.5.2.orig/chunk.c +++ dmalloc-5.5.2/chunk.c @@ -2463,6 +2463,9 @@ void *_dmalloc_chunk_malloc(const char * case DMALLOC_FUNC_MEMALIGN: trans_log = "memalign"; break; + case DMALLOC_FUNC_POSIX_MEMALIGN: + trans_log = "posix_memalign"; + break; case DMALLOC_FUNC_VALLOC: trans_log = "valloc"; break; @@ -3130,6 +3133,19 @@ void _dmalloc_chunk_log_changed(const un } } +DMALLOC_PNT _dmalloc_chunk_get_baseptr(DMALLOC_PNT p) +{ + char * rv=p; + DMALLOC_SIZE offset=0; + if(NULL==p) + return NULL; + rv-=sizeof(offset); + memmove(&offset,rv,sizeof(offset)); + rv-=offset; + return rv; +} + + /* * unsigned long _dmalloc_chunk_count_changed * @@ -3207,6 +3223,7 @@ unsigned long _dmalloc_chunk_count_chang mem_count += slot_p->sa_user_size; } else if (count_freed_b && freed_b) { + char * a,*b; mem_count += slot_p->sa_user_size; } } --- dmalloc-5.5.2.orig/dmalloc.h.3 +++ dmalloc-5.5.2/dmalloc.h.3 @@ -41,15 +41,16 @@ #define DMALLOC_FUNC_REALLOC 12 /* realloc function called */ #define DMALLOC_FUNC_RECALLOC 13 /* recalloc called */ #define DMALLOC_FUNC_MEMALIGN 14 /* memalign function called */ -#define DMALLOC_FUNC_VALLOC 15 /* valloc function called */ -#define DMALLOC_FUNC_STRDUP 16 /* strdup function called */ -#define DMALLOC_FUNC_FREE 17 /* free function called */ -#define DMALLOC_FUNC_CFREE 18 /* cfree function called */ - -#define DMALLOC_FUNC_NEW 20 /* new function called */ -#define DMALLOC_FUNC_NEW_ARRAY 21 /* new[] function called */ -#define DMALLOC_FUNC_DELETE 22 /* delete function called */ -#define DMALLOC_FUNC_DELETE_ARRAY 23 /* delete[] function called */ +#define DMALLOC_FUNC_POSIX_MEMALIGN 15 /* memalign function called */ +#define DMALLOC_FUNC_VALLOC 16 /* valloc function called */ +#define DMALLOC_FUNC_STRDUP 17 /* strdup function called */ +#define DMALLOC_FUNC_FREE 18 /* free function called */ +#define DMALLOC_FUNC_CFREE 19 /* cfree function called */ + +#define DMALLOC_FUNC_NEW 21 /* new function called */ +#define DMALLOC_FUNC_NEW_ARRAY 22 /* new[] function called */ +#define DMALLOC_FUNC_DELETE 23 /* delete function called */ +#define DMALLOC_FUNC_DELETE_ARRAY 24 /* delete[] function called */ #ifdef __cplusplus extern "C" { @@ -148,6 +149,52 @@ DMALLOC_PNT dmalloc_malloc(const char *f const DMALLOC_SIZE alignment, const int xalloc_b); +extern +DMALLOC_PNT dmalloc_malloc_real(const char *file, const int line, + const DMALLOC_SIZE size, const int func_id, + const DMALLOC_SIZE alignment, + const int xalloc_b); + +/* + * int dmalloc_posix_memalign + * + * DESCRIPTION: + * + * Overloading the posix_memalign(3) function. Allocate and return a memory + * block of a certain size which has been aligned to a certain + * alignment. + * + * RETURNS: + * + * Success - zero. + * EINVAL The alignment argument was not a power of two, or was not a multiple of sizeof(void *). + * ENOMEM There was insufficient memory to fulfill the allocation request. + * + * + * ARGUMENTS: + * memptr -> pointer will be returned here on success + * + * alignment -> Value to which the allocation must be aligned. This + * should probably be a multiple of 2 with a maximum value equivalent + * to the block-size which is often 1k or 4k. + * + * size -> Number of bytes requested. + * + * file -> File-name or return-address of the caller. + * + * line -> Line-number of the caller. + * + * func_id -> Function-id to identify the type of call. See + * dmalloc.h. + * + * xalloc_b -> If set to 1 then print an error and exit if we run out + * of memory. + */ +extern +int dmalloc_posix_memalign(const char *file, const int line, DMALLOC_PNT *memptr, + const DMALLOC_SIZE size, const int func_id, + const DMALLOC_SIZE alignment, + const int xalloc_b); /* * DMALLOC_PNT dmalloc_realloc * @@ -182,6 +229,10 @@ extern DMALLOC_PNT dmalloc_realloc(const char *file, const int line, DMALLOC_PNT old_pnt, DMALLOC_SIZE new_size, const int func_id, const int xalloc_b); +extern +DMALLOC_PNT dmalloc_realloc_real(const char *file, const int line, + DMALLOC_PNT old_pnt, DMALLOC_SIZE new_size, + const int func_id, const int xalloc_b); /* * int dmalloc_free @@ -213,6 +264,9 @@ DMALLOC_PNT dmalloc_realloc(const char * extern int dmalloc_free(const char *file, const int line, DMALLOC_PNT pnt, const int func_id); +extern +int dmalloc_free_real(const char *file, const int line, DMALLOC_PNT pnt, + const int func_id); /* * DMALLOC_PNT dmalloc_strndup @@ -1030,10 +1084,14 @@ const char *dmalloc_strerror(const int e #define memalign(alignment, size) \ dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MEMALIGN, \ (alignment), 0 /* no xalloc */) +#undef posix_memalign +#define posix_memalign(memptr,alignment, size) \ + dmalloc_posix_memalign(__FILE__, __LINE__, (memptr), (size), DMALLOC_FUNC_POSIX_MEMALIGN, \ + (alignment), 0 /* no xalloc */) #undef valloc #define valloc(size) \ dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_VALLOC, \ - 0 /* special case */, 0 /* no xalloc */) + BLOCK_SIZE, 0 /* no xalloc */) #ifndef DMALLOC_STRDUP_MACRO #undef strdup #define strdup(str) \ --- dmalloc-5.5.2.orig/configure.ac +++ dmalloc-5.5.2/configure.ac @@ -79,6 +79,9 @@ AC_CHECK_HEADER([string.h], AC_CHECK_HEADER([unistd.h], [AC_DEFINE(HAVE_UNISTD_H,1) AC_SUBST([HAVE_UNISTD_H],1)], [AC_DEFINE(HAVE_UNISTD_H,0) AC_SUBST([HAVE_UNISTD_H],0)]) +AC_CHECK_HEADER([errno.h], + [AC_DEFINE(HAVE_ERRNO_H,1) AC_SUBST([HAVE_ERRNO_H],1)], + [AC_DEFINE(HAVE_ERRNO_H,0) AC_SUBST([HAVE_ERRNO_H],0)]) AC_CHECK_HEADER([sys/types.h], [AC_DEFINE(HAVE_SYS_TYPES_H,1) AC_SUBST([HAVE_SYS_TYPES_H],1)], [AC_DEFINE(HAVE_SYS_TYPES_H,0) AC_SUBST([HAVE_SYS_TYPES_H],0)]) --- dmalloc-5.5.2.orig/dmalloc_t.c +++ dmalloc-5.5.2/dmalloc_t.c @@ -3945,6 +3945,10 @@ static void track_alloc_trxn(const char (void)printf("%s memalign %d bytes alignment %d got %#lx\n", file_line, byte_size, alignment, (long)new_addr); break; + case DMALLOC_FUNC_POSIX_MEMALIGN: + (void)printf("%s posix_memalign %d bytes alignment %d got %#lx\n", + file_line, byte_size, alignment, (long)new_addr); + break; case DMALLOC_FUNC_VALLOC: (void)printf("%s valloc %d bytes alignment %d got %#lx\n", file_line, byte_size, alignment, (long)new_addr); --- dmalloc-5.5.2.orig/Makefile.in +++ dmalloc-5.5.2/Makefile.in @@ -25,6 +25,7 @@ DEFS = -DHAVE_STDARG_H=@HAVE_STDARG_H@ \ -DHAVE_STDLIB_H=@HAVE_STDLIB_H@ \ -DHAVE_STRING_H=@HAVE_STRING_H@ \ -DHAVE_UNISTD_H=@HAVE_UNISTD_H@ \ + -DHAVE_ERRNO_H=@HAVE_ERRNO_H@ \ -DHAVE_SYS_MMAN_H=@HAVE_SYS_MMAN_H@ \ -DHAVE_SYS_TYPES_H=@HAVE_SYS_TYPES_H@ \ -DHAVE_W32API_WINBASE_H=@HAVE_W32API_WINBASE_H@ \ --- dmalloc-5.5.2.orig/return.h +++ dmalloc-5.5.2/return.h @@ -94,7 +94,50 @@ /*************************************/ /* for i[34]86 machines with GCC */ -#if __i386 && __GNUC__ > 1 +/*assembly... blechhh.. the first opcode segfaults dmalloc_fc_t -s... somewhere in the argument checking*/ +/* +Dump of assembler code for function malloc: + 0x08053870 <+0>: sub esp,0x2c +=> 0x08053873 <+3>: mov eax,DWORD PTR [ebp+0x4] + 0x08053876 <+6>: mov edx,eax + + + +(gdb) backtrace +#0 malloc (size=8) at malloc.c:1226 +#1 0x0804f906 in argv_process_no_env (args=0x805f120, arg_n=2, + argv=0xbffffcc4) at dmalloc_argv.c:3201 +#2 0x0804fc61 in argv_process (args=0x805f120, argc=2, argv=0xbffffcc4) + at dmalloc_argv.c:3290 +#3 0x080496e6 in main (argc=2, argv=0xbffffcc4) at dmalloc_fc_t.c:1078 + +(gdb) info registers +eax 0x8 8 +ecx 0x805f770 134608752 +edx 0x7b 123 +ebx 0x0 0 +esp 0xbffffb20 0xbffffb20 +ebp 0x14 0x14 +esi 0xf7fa0ee0 -134607136 +edi 0x805f138 134607160 +eip 0x8053873 0x8053873 <malloc+3> +eflags 0x10282 [ SF IF RF ] +cs 0x73 115 +ss 0x7b 123 +ds 0x7b 123 +es 0x7b 123 +fs 0x0 0 +gs 0x33 51 + +turns out ebp is never written... +I wonder if it might be that -fstack_protector +gcc version (Debian 4.6.2-11) +changing to use __builtin_ +*/ +#if __i386 && __GNUC__ > 3 +#define GET_RET_ADDR(file) ((file)=(char *)__builtin_return_address(0)) + +#elif __i386 && __GNUC__ > 1 #define GET_RET_ADDR(file) asm("movl 4(%%ebp),%%eax ; movl %%eax,%0" : \ "=g" (file) : \