1 #ifndef _MAGIC_MEM_H 2 #define _MAGIC_MEM_H 3 4 #include <magic.h> 5 6 #define __MA_ARGS__ struct _magic_type *type, const char *name, const char *parent_name, 7 #define __MA_VALUES__ type, name, parent_name, 8 #define __MA_VALUES_EXT__ MAGIC_VOID_TYPE, MAGIC_ALLOC_EXT_NAME, MAGIC_ALLOC_EXT_PARENT_NAME, 9 10 #define __MD_ARGS__ 11 #define __MD_VALUES__ 12 #define __MD_VALUES_EXT__ 13 #define __MD_VALUES_DEFAULT__ 14 15 /* External callbacks. */ 16 typedef void *(*magic_mem_heap_alloc_cb_t)(size_t size, const char *name, const char *parent_name); 17 typedef void (*magic_mem_create_dsentry_cb_t)(struct _magic_dsentry *dsentry); 18 typedef int (*magic_mem_heap_free_cb_t)(struct _magic_dsentry *dsentry); 19 extern magic_mem_heap_alloc_cb_t magic_mem_heap_alloc_cb; 20 extern magic_mem_create_dsentry_cb_t magic_mem_create_dsentry_cb; 21 extern magic_mem_heap_free_cb_t magic_mem_heap_free_cb; 22 23 /* Public dsentry functions. */ 24 typedef void (*magic_dsentry_cb_t)(struct _magic_dsentry*); 25 PUBLIC int magic_create_dsentry(struct _magic_dsentry *dsentry, 26 void *data_ptr, struct _magic_type *type, size_t size, int flags, 27 const char *name, const char *parent_name); 28 PUBLIC struct _magic_obdsentry* magic_create_obdsentry(void *data_ptr, 29 struct _magic_type *type, size_t size, int flags, 30 const char *name, const char *parent_name); 31 PUBLIC int magic_update_dsentry_state(struct _magic_dsentry *dsentry, 32 unsigned long mstate); 33 PUBLIC void magic_free_dead_dsentries(void); 34 PUBLIC void magic_destroy_dsentry(struct _magic_dsentry *dsentry, 35 struct _magic_dsentry *prev_dsentry); 36 PUBLIC void magic_destroy_dsentry_set_ext_cb(const magic_dsentry_cb_t cb); 37 PUBLIC int magic_destroy_obdsentry_by_addr(void *data_ptr); 38 PUBLIC int magic_update_dsentry(void* addr, struct _magic_type *type); 39 PUBLIC void magic_stack_dsentries_create( 40 struct _magic_dsentry **prev_last_stack_dsentry, int num_dsentries, 41 /* struct _magic_dsentry *dsentry, struct _magic_type *type, void* data_ptr, const char* function_name, const char* name, */ ...); 42 PUBLIC void magic_stack_dsentries_destroy( 43 struct _magic_dsentry **prev_last_stack_dsentry, int num_dsentries, 44 /* struct _magic_dsentry *dsentry, */ ...); 45 46 /* Public dfunction functions. */ 47 PUBLIC int magic_create_dfunction(struct _magic_dfunction *dfunction, 48 void *data_ptr, struct _magic_type *type, int flags, 49 const char *name, const char *parent_name); 50 PUBLIC void magic_destroy_dfunction(struct _magic_dfunction *dfunction); 51 52 /* Public sodesc functions. */ 53 PUBLIC int magic_create_sodesc(struct _magic_sodesc *sodesc); 54 PUBLIC int magic_destroy_sodesc(struct _magic_sodesc *sodesc); 55 56 /* Public dsodesc functions. */ 57 PUBLIC int magic_create_dsodesc(struct _magic_dsodesc *dsodesc); 58 PUBLIC int magic_destroy_dsodesc(struct _magic_dsodesc *dsodesc); 59 60 /* Memory usage logging support. */ 61 #if MAGIC_MEM_USAGE_OUTPUT_CTL 62 /* CPU frequency (used for timestamp generation) */ 63 EXTERN double magic_cycles_per_ns; 64 #endif 65 66 /* Magic malloc wrappers. */ 67 #include <stdlib.h> 68 #ifndef __MINIX 69 #include <malloc.h> 70 #endif 71 72 PUBLIC void *magic_alloc(__MA_ARGS__ void *ptr, size_t size, int flags); 73 PUBLIC void *magic_malloc( __MA_ARGS__ size_t size); 74 PUBLIC void *magic_calloc( __MA_ARGS__ size_t nmemb, size_t size); 75 PUBLIC void magic_free( __MD_ARGS__ void *ptr); 76 PUBLIC void *magic_realloc(__MA_ARGS__ void *ptr, size_t size); 77 78 PUBLIC void *(*magic_real_malloc)(size_t size); 79 PUBLIC void *(*magic_real_calloc)(size_t nmemb, size_t size); 80 PUBLIC void (*magic_real_free)(void *ptr); 81 PUBLIC void *(*magic_real_realloc)(void *ptr, size_t size); 82 83 PUBLIC int magic_posix_memalign(__MA_ARGS__ void **memptr, size_t alignment, size_t size); 84 PUBLIC int (*magic_real_posix_memalign)(void **memptr, size_t alignment, size_t size); 85 86 #ifndef __MINIX 87 PUBLIC void *magic_valloc( __MA_ARGS__ size_t size); 88 PUBLIC void *magic_memalign( __MA_ARGS__ size_t boundary, size_t size); 89 90 PUBLIC void *(*magic_real_valloc)(size_t size); 91 PUBLIC void *(*magic_real_memalign)(size_t boundary, size_t size); 92 #endif 93 94 /* Magic mmap wrappers. */ 95 #include <sys/mman.h> 96 97 #ifdef __MINIX 98 #ifndef MAP_ANONYMOUS 99 #define MAP_ANONYMOUS MAP_ANON 100 #endif 101 #endif 102 103 #ifndef _GNU_SOURCE 104 void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset); 105 #endif 106 107 PUBLIC void *magic_mmap(__MA_ARGS__ void *start, size_t length, int prot, int flags, 108 int fd, off_t offset); 109 PUBLIC int magic_munmap(__MD_ARGS__ void *start, size_t length); 110 111 PUBLIC void *(*magic_real_mmap)(void *start, size_t length, int prot, int flags, 112 int fd, off_t offset); 113 PUBLIC int (*magic_real_munmap)(void *start, size_t length); 114 115 /* Magic brk wrappers. */ 116 #include <unistd.h> 117 118 PUBLIC int magic_brk( __MA_ARGS__ void *addr); 119 PUBLIC void *magic_sbrk(__MA_ARGS__ intptr_t increment); 120 121 PUBLIC int (*magic_real_brk)(void *addr); 122 PUBLIC void *(*magic_real_sbrk)(intptr_t increment); 123 124 #ifndef __MINIX 125 /* Magic shm wrappers. */ 126 #include <sys/types.h> 127 #include <sys/shm.h> 128 129 PUBLIC void *magic_shmat(__MA_ARGS__ int shmid, const void *shmaddr, int shmflg); 130 PUBLIC int magic_shmdt( __MD_ARGS__ const void *shmaddr); 131 132 PUBLIC void *(*magic_real_shmat)(int shmid, const void *shmaddr, int shmflg); 133 PUBLIC int (*magic_real_shmdt)(const void *shmaddr); 134 135 /* Magic other wrappers. */ 136 PUBLIC void *magic_mmap64(__MA_ARGS__ void *start, size_t length, int prot, int flags, 137 int fd, off_t pgoffset); 138 139 PUBLIC void *(*magic_real_mmap64)(void *start, size_t length, int prot, int flags, 140 int fd, off_t pgoffset); 141 #else 142 #include <minix/vm.h> 143 144 PUBLIC void *magic_vm_map_cacheblock(__MA_ARGS__ dev_t dev, off_t dev_offset, 145 ino_t ino, off_t ino_offset, u32_t *flags, int blocksize); 146 PUBLIC void *(*magic_real_vm_map_cacheblock)(dev_t dev, off_t dev_offset, 147 ino_t ino, off_t ino_offset, u32_t *flags, int blocksize); 148 #endif 149 150 /* wrappers to skip alloction */ 151 PUBLIC void *magic_malloc_positioned( __MA_ARGS__ size_t size, void *ptr); 152 PUBLIC void *magic_mmap_positioned(__MA_ARGS__ void *start, size_t length, int prot, int flags, 153 int fd, off_t offset, struct _magic_dsentry *cached_dsentry); 154 155 /* Macros. */ 156 #define MAGIC_ALLOC_SIZE (sizeof(struct _magic_dsentry)) 157 158 #define MAGIC_SIZE_TO_REAL(S) (S + MAGIC_ALLOC_SIZE) 159 #define MAGIC_SIZE_TO_SOURCE(S) (S - MAGIC_ALLOC_SIZE) 160 #define MAGIC_PTR_TO_DSENTRY(P) \ 161 ((struct _magic_dsentry *) (((char *)P))) 162 #define MAGIC_PTR_FROM_DSENTRY(P) ((void *) P) 163 #define MAGIC_PTR_TO_DATA(P) \ 164 ((void *) (((char *)P) + MAGIC_ALLOC_SIZE)) 165 #define MAGIC_PTR_FROM_DATA(P) \ 166 ((void *) (((char *)P) - MAGIC_ALLOC_SIZE)) 167 168 /* Variables to keep track of magic mem wrappers. */ 169 EXTERN THREAD_LOCAL short magic_mem_wrapper_active; 170 EXTERN short magic_mem_create_dsentry_site_id; 171 172 /* Variables to indicate if dsentry site_ids should be created. */ 173 174 #if MAGIC_ALLOW_DYN_MEM_WRAPPER_NESTING 175 #define MAGIC_MEM_WRAPPER_IS_ACTIVE() (magic_mem_wrapper_active > 0) 176 #define MAGIC_MEM_WRAPPER_BEGIN() do { \ 177 magic_mem_wrapper_active++; \ 178 } while(0) 179 #define MAGIC_MEM_WRAPPER_END() do { \ 180 assert(MAGIC_MEM_WRAPPER_IS_ACTIVE()); \ 181 magic_mem_wrapper_active--; \ 182 } while(0) 183 #else 184 #define MAGIC_MEM_WRAPPER_IS_ACTIVE() (magic_mem_wrapper_active == 1) 185 #define MAGIC_MEM_WRAPPER_BEGIN() do { \ 186 assert(!MAGIC_MEM_WRAPPER_IS_ACTIVE()); \ 187 magic_mem_wrapper_active = 1; \ 188 } while(0) 189 #define MAGIC_MEM_WRAPPER_END() do { \ 190 assert(MAGIC_MEM_WRAPPER_IS_ACTIVE()); \ 191 magic_mem_wrapper_active = 0; \ 192 } while(0) 193 #endif 194 195 #define MAGIC_MEM_WRAPPER_LBEGIN() do { \ 196 MAGIC_MEM_WRAPPER_BEGIN(); \ 197 MAGIC_DSENTRY_LOCK(); \ 198 } while(0) 199 #define MAGIC_MEM_WRAPPER_LEND() do { \ 200 MAGIC_MEM_WRAPPER_END(); \ 201 MAGIC_DSENTRY_UNLOCK(); \ 202 } while(0) 203 #define MAGIC_MEM_WRAPPER_BLOCK(BLOCK) do { \ 204 MAGIC_MEM_WRAPPER_BEGIN(); \ 205 BLOCK \ 206 MAGIC_MEM_WRAPPER_END(); \ 207 } while(0) 208 #define MAGIC_MEM_WRAPPER_LBLOCK(BLOCK) do { \ 209 MAGIC_MEM_WRAPPER_LBEGIN(); \ 210 BLOCK \ 211 MAGIC_MEM_WRAPPER_LEND(); \ 212 } while(0) 213 214 /* Variables to keep track of memory pool management functions. */ 215 #define MAGIC_MEMPOOL_ID_UNKNOWN -1 216 #define MAGIC_MEMPOOL_ID_DETACHED -2 217 #define MAGIC_MEMPOOL_MAX_FUNC_RECURSIONS 100 218 EXTERN THREAD_LOCAL short magic_mempool_mgmt_active_level; 219 EXTERN THREAD_LOCAL short magic_mempool_ids[MAGIC_MEMPOOL_MAX_FUNC_RECURSIONS]; 220 EXTERN int magic_mempool_allow_reset; 221 EXTERN int magic_mempool_allow_reuse; 222 223 /* TLS flags to be set when pool management functions are active. */ 224 #define MAGIC_MEMPOOL_MGMT_SET_ACTIVE() \ 225 assert((++magic_mempool_mgmt_active_level <= MAGIC_MEMPOOL_MAX_FUNC_RECURSIONS) \ 226 && "Reached the maximum number of nested pool function calls!") 227 #define MAGIC_MEMPOOL_MGMT_IS_ACTIVE() \ 228 (magic_mempool_mgmt_active_level > 0) 229 #define MAGIC_MEMPOOL_MGMT_UNSET_ACTIVE() \ 230 assert((--magic_mempool_mgmt_active_level >= 0) && "Invalid nested pool call level!") 231 #define MAGIC_MEMPOOL_SET_ID(ID) \ 232 (magic_mempool_ids[magic_mempool_mgmt_active_level - 1] = ID) 233 #define MAGIC_MEMPOOL_GET_ID() \ 234 (magic_mempool_ids[magic_mempool_mgmt_active_level - 1]) 235 #define MAGIC_MEMPOOL_ID_IS_SET() \ 236 (magic_mempool_ids[magic_mempool_mgmt_active_level - 1] > 0) 237 #define MAGIC_MEMPOOL_GET_NAME() \ 238 (MAGIC_MEMPOOL_ID_IS_SET() ? \ 239 _magic_mpdescs[MAGIC_MEMPOOL_GET_ID() - 1].name : \ 240 ((MAGIC_MEMPOOL_GET_ID() == MAGIC_MEMPOOL_ID_UNKNOWN) ? \ 241 MAGIC_MEMPOOL_NAME_UNKNOWN : MAGIC_MEMPOOL_NAME_DETACHED)) 242 /* Store dynamic type in TLS if memory usage logging is enabled */ 243 #if MAGIC_MEM_USAGE_OUTPUT_CTL 244 #define MAGIC_MEMPOOL_SET_DTYPE(TYPE) \ 245 do { \ 246 if (MAGIC_MEMPOOL_ID_IS_SET()) { \ 247 _magic_mpdescs[MAGIC_MEMPOOL_GET_ID() - 1].dtype_id = TYPE; \ 248 } \ 249 } while(0) 250 #define MAGIC_MEMPOOL_GET_DTYPE() \ 251 (MAGIC_MEMPOOL_ID_IS_SET() ? \ 252 _magic_mpdescs[MAGIC_MEMPOOL_GET_ID() - 1].dtype_id : 0) 253 #else 254 #define MAGIC_MEMPOOL_SET_DTYPE(TYPE) 255 #define MAGIC_MEMPOOL_GET_DTYPE() 0 256 #endif 257 258 /* Pass call site information when logging is activated. */ 259 #if (MAGIC_MEM_USAGE_OUTPUT_CTL == 1) 260 #define __MDEBUG_ARGS__ const char* name 261 #else 262 #define __MDEBUG_ARGS__ 263 #endif 264 /* Specific wrapper for the memory pool creation. */ 265 MAGIC_HOOK void magic_mempool_create_begin(__MDEBUG_ARGS__); 266 MAGIC_HOOK void magic_mempool_create_end(void* addr, int indirection); 267 268 /* Specific wrappers for the memory pool destruction. */ 269 MAGIC_HOOK void magic_mempool_destroy_begin(void* addr, int memory_reuse); 270 MAGIC_HOOK void magic_mempool_destroy_end(void); 271 272 /* Specific wrappers for the memory pool resetting */ 273 MAGIC_HOOK void magic_mempool_reset_begin(void* addr); 274 275 /* Generic wrappers for the rest of the memory pool management functions. */ 276 MAGIC_HOOK void magic_mempool_mgmt_begin(void* addr); 277 MAGIC_HOOK void magic_mempool_mgmt_end(void); 278 279 /* Pool block allocation template function and magic wrapper. */ 280 MAGIC_FUNC void *mempool_block_alloc_template(void* addr, size_t size); 281 PUBLIC void *magic_mempool_block_alloc_template(__MA_ARGS__ void* addr, size_t size); 282 283 #endif 284 285