dawn@0: /* dawn@0: 19 Dec 94 - Sept 95 dawn@0: Alain de Cheveigne, LLF, CNRS/Universite Paris 7. dawn@0: Modified: Sept 2000 dawn@0: dawn@0: file mwrap.h dawn@0: dawn@0: To use the malloc wrappers: dawn@0: - include this file in all source files that call malloc routines, dawn@0: - link with mwrap.o, dawn@0: - compile all files with -DMWRAP to turn on wrapping and checking. dawn@0: dawn@0: */ dawn@0: dawn@0: #ifndef MWRAP_H dawn@0: #define MWRAP_H dawn@0: dawn@0: #include dawn@0: #include dawn@0: dawn@0: /* NOTE: (char *) is used for pointer arithmetic. dawn@0: Pointer arguments of all macros are cast to (char *). */ dawn@0: dawn@0: /* node structure for binary splay tree */ dawn@0: typedef struct mwrap_node_struct *mwrap_node ; dawn@0: struct mwrap_node_struct { dawn@0: char *lo; /* base of block */ dawn@0: char *hi; /* one beyond last address in block */ dawn@0: mwrap_node up; dawn@0: mwrap_node left; dawn@0: mwrap_node right; dawn@0: }; dawn@0: dawn@0: dawn@0: /* Abbreviations for macros. Change in case of conflict. dawn@0: dawn@0: Assignment macros: dawn@0: GET(x) equivalent to 'x' on a rhs, but memory address is checked before access dawn@0: SET(x) equivalent to 'x' on a lhs, but memory address is checked before assignment dawn@0: CPY(p,q,n) copy n values starting from p to n values starting from q, after checking both dawn@0: dawn@0: Test macros: dawn@0: POK(p) pointer p is within an allocated block. dawn@0: BOK(b) pointer b is the base of an allocated block. dawn@0: PQOK(p, q) pointers p and q are in same allocated block. dawn@0: PBOK(p, b) pointer p is in block of base b. dawn@0: dawn@0: MWRAPOK() check internal tree for sanity (slow) dawn@0: dawn@0: Query macros: dawn@0: PBASE(p) base of block containing p, NULL if there is none. dawn@0: PBUMP(p) one beyond last byte of block. dawn@0: PSIZE(p) size of block containing p, -1 if none. dawn@0: dawn@0: Explicit block registering macros. dawn@0: CHECKIN(lo, hi) register block of bounds lo, hi dawn@0: CHECKOUT(lo) unregister block of base lo dawn@0: dawn@0: */ dawn@0: dawn@0: #define GET(x) MWRAP_GET(x) dawn@0: #define SET(x) MWRAP_SET(x) dawn@0: #define CPY(p,q,n) MWRAP_CPY(p,q,n) dawn@0: #define POK(p) MWRAP_POK(p) dawn@0: #define BOK(b) MWRAP_BOK(b) dawn@0: #define PQOK(p,q) MWRAP_PQOK((p),(q)) dawn@0: #define PBOK(p,b) MWRAP_PBOK((p),(b)) dawn@0: #define MWRAPOK() MWRAP_MWRAPOK() dawn@0: #define PBASE(p) MWRAP_PBASE(p) dawn@0: #define PSIZE(p) MWRAP_PSIZE(p) dawn@0: #define CHECKIN(lo, hi) MWRAP_CHECKIN((lo), (hi)) dawn@0: #define CHECKOUT(lo) MWRAP_CHECKOUT(lo) dawn@0: dawn@0: dawn@0: /* Definitions of macros. dawn@0: All are conditional on MWRAP being defined. dawn@0: For speed, macros check for a "lucky" hit (block already dawn@0: at root) before handing over to functions. */ dawn@0: dawn@0: #ifdef MWRAP dawn@0: dawn@0: #define MWRAP_GET(x) \ dawn@0: ( (MWRAP_POK(&x)) ? (x) : (x) ) dawn@0: dawn@0: #define MWRAP_SET(x) \ dawn@0: MWRAP_POK(&x) ; (x) dawn@0: dawn@0: #define MWRAP_CPY(p, q, n) \ dawn@0: do {int i; \ dawn@0: MWRAP_PQOK((p),(p)+(n-1)); \ dawn@0: MWRAP_PQOK((q),(q)+(n-1)); \ dawn@0: for(i=0;i= mwrap_tree->lo \ dawn@0: && (char *) (p) < mwrap_tree->hi) break; \ dawn@0: mwrap_pok((char *) (p), __FILE__, __LINE__); } while (0) */ dawn@0: dawn@0: #define MWRAP_POK(p) \ dawn@0: ((mwrap_tree && (char *) (p) >= mwrap_tree->lo && (char *) (p) hi) ? \ dawn@0: 1 : mwrap_pok((char *) (p), __FILE__, __LINE__)) dawn@0: dawn@0: dawn@0: /* #define MWRAP_BOK(b) \ dawn@0: do { if (mwrap_tree \ dawn@0: && (char *) (b) == mwrap_tree->lo) break; \ dawn@0: mwrap_bok((char *) (b), __FILE__, __LINE__); } while (0) */ dawn@0: dawn@0: #define MWRAP_BOK(b) \ dawn@0: ((mwrap_tree && (char *) (b) == mwrap_tree->lo) ? 1 : mwrap_bok((char *) (b), __FILE__, __LINE__)) dawn@0: dawn@0: dawn@0: /* #define MWRAP_PQOK(p, q) \ dawn@0: do { if (mwrap_tree \ dawn@0: && (char *) (p) >= mwrap_tree->lo \ dawn@0: && (char *) (p) < mwrap_tree->hi \ dawn@0: && (char *) (q) >= mwrap_tree->lo \ dawn@0: && (char *) (q) < mwrap_tree->lo) break; \ dawn@0: mwrap_pqok((char *)(p), (char *)(q), __FILE__, __LINE__); } while (0) */ dawn@0: dawn@0: #define MWRAP_PQOK(p,q) \ dawn@0: ((mwrap_tree \ dawn@0: && (char *) (p) >= mwrap_tree->lo \ dawn@0: && (char *) (p) < mwrap_tree->hi \ dawn@0: && (char *) (q) >= mwrap_tree->lo \ dawn@0: && (char *) (q) < mwrap_tree->lo ) ? \ dawn@0: 1 : mwrap_pqok((char *)(p), (char *)(q), __FILE__, __LINE__)) dawn@0: dawn@0: /* #define MWRAP_PBOK(p, b) \ dawn@0: do { if (mwrap_tree \ dawn@0: && (char *) (b) == mwrap_tree->lo \ dawn@0: && (char *) (p) >= mwrap_tree->lo \ dawn@0: && (char *) (p) < mwrap_tree->lo) break; \ dawn@0: mwrap_pbok((char *)(p), (char *)(b), __FILE__, __LINE__); } while (0) */ dawn@0: dawn@0: #define MWRAP_PBOK(p, b) \ dawn@0: (( mwrap_tree \ dawn@0: && (char *) (b) == mwrap_tree->lo \ dawn@0: && (char *) (p) >= mwrap_tree->lo \ dawn@0: && (char *) (p) < mwrap_tree->lo) ? \ dawn@0: 1 : mwrap_pbok((char *)(p), (char *)(b), __FILE__, __LINE__)) dawn@0: dawn@0: #define MWRAP_MWRAPOK() mwrap_checktree(__FILE__, __LINE__) dawn@0: dawn@0: #define MWRAP_PBASE(p) mwrap_pbase((char *) p) dawn@0: #define MWRAP_PBUMP(p) mwrap_pbump((char *) p) dawn@0: #define MWRAP_PSIZE(p) mwrap_psize((char *) p) dawn@0: #define MWRAP_CHECKIN(lo, hi) \ dawn@0: mwrap_checkin((char *) (lo), (char *) (hi), __FILE__, __LINE__) dawn@0: #define MWRAP_CHECKOUT(lo) \ dawn@0: mwrap_checkout( (char *) (lo), __FILE__, __LINE__) dawn@0: dawn@0: #else dawn@0: dawn@0: #define MWRAP_GET(x) (x) dawn@0: #define MWRAP_SET(x) (x) dawn@0: #define MWRAP_CPY(p,q,n) dawn@0: #define MWRAP_POK(p) dawn@0: #define MWRAP_BOK(p) dawn@0: #define MWRAP_PBOK(p,b) dawn@0: #define MWRAP_PQOK(p,q) dawn@0: #define MWRAP_MWRAPOK() dawn@0: #define MWRAP_PBASE(p) (void *) mwrap_squeal(__FILE__, __LINE__) dawn@0: #define MWRAP_PBUMP(p) (void *) mwrap_squeal(__FILE__, __LINE__) dawn@0: #define MWRAP_PSIZE(p) (long) mwrap_squeal(__FILE__, __LINE__) dawn@0: #define MWRAP_CHECKIN(lo, hi) dawn@0: #define MWRAP_CHECKOUT(lo) dawn@0: #endif dawn@0: dawn@0: dawn@0: /* Wrapping macros. dawn@0: dawn@0: If MWRAP is defined, all malloc routines are wrapped and the dawn@0: original routines are available as "nowrap_malloc()", etc.. dawn@0: dawn@0: If MWRAP is not defined, malloc routines are not wrapped dawn@0: and "nowrap_malloc()", etc. are #defined to "malloc()", etc. dawn@0: */ dawn@0: dawn@0: #ifdef MWRAP dawn@0: dawn@0: #ifndef MWRAP_C dawn@0: #define malloc(size) mwrap_malloc((size), __FILE__, __LINE__) dawn@0: #define free(p) mwrap_free((p), __FILE__, __LINE__) dawn@0: #define realloc(p, size) mwrap_realloc((p), (size), __FILE__, __LINE__) dawn@0: #define calloc(n, size) mwrap_calloc((n), (size), __FILE__, __LINE__) dawn@0: #define cfree(p) mwrap_cfree((p), __FILE__, __LINE__) dawn@0: #define valloc(size) mwrap_valloc((size), __FILE__, __LINE__) dawn@0: #define vfree(p) mwrap_vfree((p), __FILE__, __LINE__) dawn@0: #define memalign(a, p) mwrap_memalign((a), (p), __FILE__, __LINE__) dawn@0: #endif /* MWRAP_C */ dawn@0: dawn@0: #else dawn@0: dawn@0: #ifndef MWRAP_C dawn@0: #define nowrap_malloc(size) malloc(size) dawn@0: #define nowrap_free(p) free(p) dawn@0: #define nowrap_realloc(p, size) realloc(p) dawn@0: #define nowrap_calloc(n, size) calloc((n), (size)) dawn@0: #define nowrap_cfree(p) cfree(p) dawn@0: #define nowrap_valloc(size) valloc(size) dawn@0: #define nowrap_vfree(p) vfree(p) dawn@0: #define nowrap_memalign(a, p) memalign((a), (p)) dawn@0: #endif /* MWRAP_C */ dawn@0: dawn@0: #endif /* MWRAP */ dawn@0: dawn@0: dawn@0: /* three global variables */ dawn@0: dawn@0: #ifndef MWRAP_C dawn@0: extern mwrap_node mwrap_tree; /* the tree */ dawn@0: extern char *mwrap_file; /* caller source file */ dawn@0: extern long mwrap_line; /* line in caller source file */ dawn@0: #endif dawn@0: dawn@0: dawn@0: /* Data types used by malloc library. Modify if necessary */ dawn@0: typedef void DATATYPE; /* returned by malloc(), etc. */ dawn@0: typedef size_t SIZETYPE; /* fed to malloc(), etc. */ dawn@0: typedef void VOIDTYPE; /* returned by free(), etc. */ dawn@0: dawn@0: dawn@0: /* prototypes of routines made public */ dawn@0: dawn@0: /* malloc wrappers */ dawn@0: DATATYPE *mwrap_malloc(SIZETYPE size, char *file, long line); dawn@0: VOIDTYPE mwrap_free(DATATYPE *p, char *file, long line); dawn@0: DATATYPE *mwrap_realloc(DATATYPE *p, SIZETYPE size, char *file, long line); dawn@0: DATATYPE *mwrap_calloc(SIZETYPE n, SIZETYPE size, char *file, long line); dawn@0: VOIDTYPE mwrap_cfree(DATATYPE *p, char *file, long line); dawn@0: DATATYPE *mwrap_valloc(SIZETYPE size, char *file, long line); dawn@0: VOIDTYPE mwrap_vfree(DATATYPE *p, char *file, long line); dawn@0: DATATYPE *mwrap_memalign(SIZETYPE alignment, SIZETYPE size, char *file, long line); dawn@0: dawn@0: /* unwrapped versions */ dawn@0: #ifdef MWRAP dawn@0: DATATYPE *nowrap_malloc(SIZETYPE size); dawn@0: VOIDTYPE nowrap_free(DATATYPE *p); dawn@0: DATATYPE *nowrap_realloc(DATATYPE *p, SIZETYPE size); dawn@0: DATATYPE *nowrap_calloc(SIZETYPE n, SIZETYPE size); dawn@0: VOIDTYPE nowrap_cfree(DATATYPE *p); dawn@0: DATATYPE *nowrap_valloc(SIZETYPE size); dawn@0: VOIDTYPE nowrap_vfree(DATATYPE *p); dawn@0: DATATYPE *nowrap_memalign(SIZETYPE alignment, SIZETYPE size); dawn@0: #endif dawn@0: dawn@0: /* explicit block registering */ dawn@0: void mwrap_checkin(char *lo, char *hi, char *file, long line); dawn@0: void mwrap_checkout(char *lo, char *file, long line); dawn@0: dawn@0: /* tests & queries */ dawn@0: int mwrap_pok(char *p, char *file, long line); dawn@0: int mwrap_bok(char *b, char *file, long line); dawn@0: int mwrap_pqok(char *p, char *q, char *file, long line); dawn@0: int mwrap_pbok(char *p, char *b, char *file, long line); dawn@0: char *mwrap_pbase(char *p); dawn@0: char *mwrap_pbump(char *p); dawn@0: long mwrap_psize(char *p); dawn@0: long mwrap_squeal(char *file, long line); dawn@0: dawn@0: /* change default functions */ dawn@0: void mwrap_set_errorfunction(void (*f)(int level)); dawn@0: void mwrap_set_messagefunction(void (*f)(int level, char * message)); dawn@0: dawn@0: #endif