1 #ifndef _MAGIC_H 2 #define _MAGIC_H 3 4 #include <magic_def.h> 5 #include <magic_common.h> 6 #include <magic_extern.h> 7 #include <magic_structs.h> 8 #include <magic_sentry.h> 9 #include <magic_selement.h> 10 #include <magic_range.h> 11 #include <magic_eval.h> 12 13 #include <stdio.h> 14 #include <stddef.h> 15 #include <errno.h> 16 #include <limits.h> 17 #include <string.h> 18 #include <stdlib.h> 19 #include <unistd.h> 20 21 /* Magic type macros. */ 22 #define MAGIC_TYPE_WALK_STOP 1 23 #define MAGIC_TYPE_WALK_SKIP_PATH 2 24 #define MAGIC_TYPE_WALK_CONTINUE 3 25 26 #define MAGIC_TYPE_WALK_UNIONS_AS_VOID 0x1 27 #define MAGIC_TYPE_WALK_DEFAULT_FLAGS (MAGIC_TYPE_WALK_UNIONS_AS_VOID) 28 29 #define MAGIC_TYPE_COMPARE_VALUE_SET 0x01 30 #define MAGIC_TYPE_COMPARE_FLAGS 0x02 31 #define MAGIC_TYPE_COMPARE_NAME 0x04 32 #define MAGIC_TYPE_COMPARE_NAMES 0x08 33 #define MAGIC_TYPE_COMPARE_MEMBER_NAMES 0x10 34 #define MAGIC_TYPE_COMPARE_MEMBER_OFFSETS 0x20 35 #define MAGIC_TYPE_COMPARE_ALL (MAGIC_TYPE_COMPARE_VALUE_SET | \ 36 MAGIC_TYPE_COMPARE_FLAGS | MAGIC_TYPE_COMPARE_NAME | \ 37 MAGIC_TYPE_COMPARE_NAMES | MAGIC_TYPE_COMPARE_MEMBER_NAMES | \ 38 MAGIC_TYPE_COMPARE_MEMBER_OFFSETS) 39 40 #define MAGIC_TYPE_IS_WALKABLE(T) ((T)->type_id == MAGIC_TYPE_ARRAY \ 41 || (T)->type_id == MAGIC_TYPE_VECTOR || (T)->type_id == MAGIC_TYPE_UNION \ 42 || (T)->type_id == MAGIC_TYPE_STRUCT) 43 #define MAGIC_TYPE_NUM_CONTAINED_TYPES(T) \ 44 ((T)->type_id == MAGIC_TYPE_ARRAY ? 1 : (T)->num_child_types) 45 46 #define MAGIC_TYPE_IS_VOID(T) ((T)->type_id == MAGIC_TYPE_VOID \ 47 || ( ((T)->flags & MAGIC_TYPE_EXTERNAL) && !strcmp((T)->type_str, "i8") )) 48 #define MAGIC_TYPE_IS_RAW_ARRAY(T) \ 49 (((T)->type_id == MAGIC_TYPE_ARRAY \ 50 && (T)->contained_types[0]->type_id == MAGIC_TYPE_VOID) \ 51 || (T)->type_id == MAGIC_TYPE_UNION) 52 #define MAGIC_TYPE_IS_INT_ARRAY(T) \ 53 ((T)->type_id == MAGIC_TYPE_ARRAY \ 54 && (T)->contained_types[0]->type_id == MAGIC_TYPE_INTEGER) 55 56 #define MAGIC_EXPAND_TYPE_STR 0x1 57 #define MAGIC_SKIP_COMP_TYPES 0x2 58 #define MAGIC_EXPAND_SENTRY 0x4 59 60 #define MAGIC_TYPE_STR_PRINT_LLVM_TYPES 0x01 61 #define MAGIC_TYPE_STR_PRINT_SOURCE_TYPES 0x02 62 #define MAGIC_TYPE_STR_PRINT_MEMBER_NAMES 0x04 63 #define MAGIC_TYPE_STR_PRINT_SKIP_UNIONS 0x08 64 #define MAGIC_TYPE_STR_PRINT_SKIP_STRUCTS 0x10 65 #define MAGIC_TYPE_STR_PRINT_MULTI_NAMES 0x20 66 #define MAGIC_TYPE_STR_PRINT_STYLE_DEFAULT \ 67 (MAGIC_TYPE_STR_PRINT_LLVM_TYPES | MAGIC_TYPE_STR_PRINT_SOURCE_TYPES | \ 68 MAGIC_TYPE_STR_PRINT_MEMBER_NAMES) 69 70 #define MAGIC_TYPE_STR_PRINT_DEBUG MAGIC_DEBUG_SET(0) 71 72 #define MAGIC_TYPE_HAS_COMP_TYPES(T) ((T)->compatible_types != NULL) 73 #define MAGIC_TYPE_HAS_COMP_TYPE(T, I) \ 74 ((T)->compatible_types[(I)] != NULL) 75 #define MAGIC_TYPE_COMP_TYPE(T, I) ((T)->compatible_types[(I)]) 76 #define MAGIC_TYPE_NUM_COMP_TYPES(T, NUM) \ 77 do { \ 78 *(NUM) = 0; \ 79 while(MAGIC_TYPE_HAS_COMP_TYPE(T, (*(NUM))++)); \ 80 (*(NUM))--; \ 81 } while(0) 82 #define MAGIC_TYPE_HAS_VALUE_SET(T) ((T)->value_set != NULL) 83 #define MAGIC_TYPE_HAS_VALUE(T, I) ((I) < ((int*)(T)->value_set)[0]) 84 #define MAGIC_TYPE_VALUE(T, I) (((int*)(T)->value_set)[(I)+1]) 85 #define MAGIC_TYPE_NUM_VALUES(T, NUM) (*(NUM) = ((int*)(T)->value_set)[0]) 86 #define MAGIC_TYPE_HAS_MULTI_NAMES(T) ((T)->num_names > 1) 87 88 #define MAGIC_TYPE_FLAG(T,F) (((T)->flags & (F)) != 0) 89 #define MAGIC_TYPE_ID(T) ((T)->id) 90 #define MAGIC_TYPE_IS_STRING(T) (MAGIC_TYPE_FLAG(T,MAGIC_TYPE_EXTERNAL) \ 91 && (T)->type_id == MAGIC_TYPE_ARRAY \ 92 && !strcmp((T)->contained_types[0]->type_str, "i8")) 93 #define MAGIC_TYPE_PRINT(T, FLAGS) do { \ 94 _magic_printf("TYPE: (id=%5d, name=%s, size=%d, num_child_types=%d, " \ 95 "type_id=%d, bit_width=%d, flags(ERDIVvUP)=%d%d%d%d%d%d%d%d, " \ 96 "values='", MAGIC_TYPE_ID(T), (T)->name, (T)->size, \ 97 (T)->num_child_types, (T)->type_id, (T)->bit_width, \ 98 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_EXTERNAL), \ 99 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_IS_ROOT), \ 100 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_DYNAMIC), \ 101 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_INT_CAST), \ 102 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_STRICT_VALUE_SET), \ 103 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_VARSIZE), \ 104 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_UNSIGNED), \ 105 MAGIC_TYPE_FLAG(T,MAGIC_TYPE_NO_INNER_PTRS)); \ 106 if(MAGIC_TYPE_HAS_VALUE_SET(T)) magic_type_values_print(T); \ 107 if(MAGIC_TYPE_HAS_MULTI_NAMES(T)) { \ 108 _magic_printf("', names='"); \ 109 magic_type_names_print(T); \ 110 } \ 111 _magic_printf("', type_str="); \ 112 if((FLAGS) & MAGIC_EXPAND_TYPE_STR) magic_type_str_print(T); \ 113 else _magic_printf("%s", (T)->type_str ? (T)->type_str : ""); \ 114 if(MAGIC_TYPE_HAS_COMP_TYPES(T)) { \ 115 _magic_printf(", comp_types=("); \ 116 magic_type_comp_types_print(T, FLAGS); \ 117 _magic_printf(")"); \ 118 } \ 119 _magic_printf(")"); \ 120 } while(0) 121 122 #define MAGIC_TYPE_VARSIZE_EL_TYPE(T) \ 123 (T)->contained_types[(T)->num_child_types - 1]->contained_types[0] 124 125 #define MAGIC_TYPE_ARRAY_CREATE_FROM_SIZE(AT,T,CT,S,VSN) do { \ 126 assert(((S) && ((S) % (T)->size == 0 || VSN)) && "Bad size!"); \ 127 (AT)->id = MAGIC_ID_NONE; \ 128 (AT)->flags |= MAGIC_TYPE_DYNAMIC; \ 129 (AT)->type_id = MAGIC_TYPE_ARRAY; \ 130 (AT)->size = S; \ 131 (AT)->num_child_types = (S)/(T)->size; \ 132 (AT)->contained_types = CT; \ 133 (AT)->contained_types[0] = T; \ 134 if(VSN) { \ 135 (AT)->flags |= MAGIC_TYPE_VARSIZE; \ 136 (AT)->num_child_types = VSN; \ 137 } \ 138 } while(0) 139 #define MAGIC_TYPE_ARRAY_CREATE_FROM_N(AT,T,CT,N) \ 140 MAGIC_TYPE_ARRAY_CREATE_FROM_SIZE(AT,T,CT,(T)->size*N, 0) 141 142 #define MAGIC_TYPE_VOID_ARRAY_GET_FROM_SIZE(AT,S) do { \ 143 *(AT) = *MAGIC_VOID_ARRAY_TYPE; \ 144 MAGIC_TYPE_ARRAY_CREATE_FROM_SIZE(AT,MAGIC_VOID_TYPE, \ 145 MAGIC_VOID_ARRAY_TYPE->contained_types,S,0); \ 146 } while(0) 147 #define MAGIC_TYPE_VOID_ARRAY_GET_FROM_N(AT,N) \ 148 MAGIC_TYPE_VOID_ARRAY_GET_FROM_SIZE(AT,MAGIC_VOID_TYPE->size*N) 149 150 #define MAGIC_TYPE_PTRINT_ARRAY_GET_FROM_SIZE(AT,S) do { \ 151 *(AT) = *MAGIC_PTRINT_ARRAY_TYPE; \ 152 MAGIC_TYPE_ARRAY_CREATE_FROM_SIZE(AT,MAGIC_PTRINT_TYPE, \ 153 MAGIC_PTRINT_ARRAY_TYPE->contained_types,S,0); \ 154 } while(0) 155 #define MAGIC_TYPE_PTRINT_ARRAY_GET_FROM_N(AT,N) \ 156 MAGIC_TYPE_PTRINT_ARRAY_GET_FROM_SIZE(AT,MAGIC_PTRINT_TYPE->size*N) 157 158 #define MAGIC_TYPE_INT_CREATE(T,S,N,B) do { \ 159 (T)->id = MAGIC_ID_NONE; \ 160 (T)->flags |= MAGIC_TYPE_DYNAMIC; \ 161 (T)->type_id = MAGIC_TYPE_INTEGER; \ 162 (T)->size = S; \ 163 (T)->num_child_types = 0; \ 164 (T)->contained_types = NULL; \ 165 (T)->bit_width = (S)*8; \ 166 (T)->name = N; \ 167 snprintf(B, sizeof(B), "i%d", (T)->bit_width); \ 168 (T)->type_str = B; \ 169 } while(0) 170 171 #define MAGIC_TYPE_COMP_ITER(TYPE,COMP_TYPE,DO) do { \ 172 if(MAGIC_TYPE_HAS_COMP_TYPES(TYPE)) { \ 173 int __i = 0; \ 174 while(MAGIC_TYPE_HAS_COMP_TYPE(TYPE, __i)) { \ 175 COMP_TYPE=MAGIC_TYPE_COMP_TYPE(TYPE, __i); \ 176 DO \ 177 __i++; \ 178 } \ 179 } \ 180 } while(0) 181 182 /* Magic function macros. */ 183 #define MAGIC_FUNCTION_PARENT(F) \ 184 (MAGIC_STATE_FLAG(F,MAGIC_STATE_DYNAMIC) ? \ 185 MAGIC_DFUNCTION_FROM_FUNCTION(F)->parent_name : "") 186 #define MAGIC_FUNCTION_ID(F) ((F)->id) 187 #define MAGIC_FUNCTION_PRINT(F, EXPAND_TYPE_STR) do { \ 188 _magic_printf("FUNCTION: (id=%5lu, name=%s, parent=%s, address=0x%08x,"\ 189 " flags(RLDCdTArwxEI)=%c%c%d%d%d%d%d%d%d%d%d%d, type=", \ 190 (unsigned long)MAGIC_FUNCTION_ID(F), (F)->name, \ 191 MAGIC_FUNCTION_PARENT(F), (unsigned) (F)->address, \ 192 MAGIC_STATE_REGION_C(F), MAGIC_STATE_LIBSPEC_C(F), \ 193 MAGIC_STATE_FLAG(F,MAGIC_STATE_DIRTY), \ 194 MAGIC_STATE_FLAG(F,MAGIC_STATE_CONSTANT), \ 195 MAGIC_STATE_FLAG(F,MAGIC_STATE_DYNAMIC), \ 196 MAGIC_STATE_FLAG(F,MAGIC_STATE_DETACHED), \ 197 MAGIC_STATE_FLAG(F,MAGIC_STATE_ADDR_NOT_TAKEN), \ 198 MAGIC_STATE_FLAG(F,MAGIC_STATE_MODE_R), \ 199 MAGIC_STATE_FLAG(F,MAGIC_STATE_MODE_W), \ 200 MAGIC_STATE_FLAG(F,MAGIC_STATE_MODE_X), \ 201 MAGIC_STATE_FLAG(F,MAGIC_STATE_EXTERNAL), \ 202 MAGIC_STATE_FLAG(F,MAGIC_STATE_IMMUTABLE)); \ 203 MAGIC_TYPE_PRINT((F)->type, EXPAND_TYPE_STR); \ 204 _magic_printf(")"); \ 205 } while(0) 206 207 /* Magic function hash macros. */ 208 #define MAGIC_FUNCTION_TO_HASH_EL(function, function_hash) \ 209 do { \ 210 function_hash->key = function->address; \ 211 function_hash->function = function; \ 212 } while (0) 213 214 #define MAGIC_DFUNCTION_TO_HASH_EL(dfunction, function, function_hash) \ 215 do { \ 216 function_hash->key = function->address; \ 217 function_hash->function = function; \ 218 } while (0) 219 220 /* Estimated maximum number of buckets needed. Increase as necessary. */ 221 #define MAGIC_FUNCTION_ADDR_EST_MAX_BUCKETS 32768 222 /* 223 * Since we don't support freeing memory, we need to allocate _all_ the 224 * intermediate buckets as well. For simplicity, just assume 1 + 2 + 4 + ... 225 * + 2^n, though it will probably be less than that. 226 */ 227 #define MAGIC_FUNCTION_ADDR_EST_TOTAL_BUCKETS \ 228 ((MAGIC_FUNCTION_ADDR_EST_MAX_BUCKETS << 1) - 1) 229 #define MAGIC_FUNCTION_ADDR_HASH_OVERHEAD \ 230 (MAGIC_FUNCTION_ADDR_EST_TOTAL_BUCKETS * sizeof(UT_hash_bucket) + \ 231 sizeof(UT_hash_table)) 232 233 /* Magic dynamic function macros. */ 234 #define MAGIC_DFUNCTION_PREV(DF) ((DF)->prev) 235 #define MAGIC_DFUNCTION_HAS_PREV(DF) ((DF)->prev != NULL) 236 #define MAGIC_DFUNCTION_NEXT(DF) ((DF)->next) 237 #define MAGIC_DFUNCTION_HAS_NEXT(DF) ((DF)->next != NULL) 238 #define MAGIC_DFUNCTION_TO_FUNCTION(DF) (&((DF)->function)) 239 #define MAGIC_DFUNCTION_FROM_FUNCTION(F) \ 240 ((struct _magic_dfunction*)(((char*)(F)) - \ 241 offsetof(struct _magic_dfunction, function))) 242 243 #define MAGIC_DFUNCTION_MNUM (~(0xFEE1DEAF)) 244 #define MAGIC_DFUNCTION_MNUM_NULL 0 245 246 #define MAGIC_DFUNCTION_MNUM_OK(D) ((D)->magic_number == MAGIC_DFUNCTION_MNUM) 247 248 #define MAGIC_DFUNCTION_PRINT(DF, EXPAND_TYPE_STR) do { \ 249 _magic_printf("DFUNCTION: (~mnum=%08x, address=0x%08x, prev=0x%08x, " \ 250 "next=0x%08x, function=", ~((DF)->magic_number), (unsigned) (DF), \ 251 (unsigned) (DF)->prev, (unsigned) (DF)->next); \ 252 MAGIC_FUNCTION_PRINT(MAGIC_DFUNCTION_TO_FUNCTION(DF), EXPAND_TYPE_STR);\ 253 _magic_printf(")"); \ 254 } while(0) 255 256 #define MAGIC_DFUNCTION_ITER(HEAD, DFUNC, DO) do { \ 257 if(HEAD) { \ 258 DFUNC = NULL; \ 259 while(!DFUNC || MAGIC_DFUNCTION_HAS_NEXT(DFUNC)) { \ 260 DFUNC = !DFUNC ? HEAD : MAGIC_DFUNCTION_NEXT(DFUNC); \ 261 assert(magic_check_dfunction(DFUNC, 0) \ 262 && "Bad magic dfunction looked up!"); \ 263 DO \ 264 } \ 265 } \ 266 } while(0) 267 268 #define MAGIC_DFUNCTION_FUNC_ITER(HEAD, DFUNC, FUNC, DO) \ 269 MAGIC_DFUNCTION_ITER(HEAD, DFUNC, \ 270 FUNC = MAGIC_DFUNCTION_TO_FUNCTION(DFUNC); \ 271 DO \ 272 ); 273 274 /* Magic dynamic state index macros. */ 275 #define MAGIC_DSINDEX_ID(I) ((I) - _magic_dsindexes + 1) 276 #define MAGIC_DSINDEX_IS_ALLOC(I) \ 277 ((I) && !MAGIC_STATE_FLAG(I, MAGIC_STATE_STACK)) 278 #define MAGIC_DSINDEX_PRINT(I, EXPAND_TYPE_STR) do { \ 279 _magic_printf("DSINDEX: (id=%5d, name=%s, parent=%s, " \ 280 "flags(SHMs)=%d%d%d%d type=", \ 281 MAGIC_DSINDEX_ID(I), (I)->name, (I)->parent_name, \ 282 MAGIC_STATE_FLAG((I), MAGIC_STATE_STACK), MAGIC_STATE_FLAG((I), \ 283 MAGIC_STATE_HEAP), MAGIC_STATE_FLAG((I), MAGIC_STATE_MAP), \ 284 MAGIC_STATE_FLAG((I), MAGIC_STATE_SHM)); \ 285 MAGIC_TYPE_PRINT((I)->type, EXPAND_TYPE_STR); \ 286 _magic_printf(")"); \ 287 } while(0) 288 289 /* Magic dynamic state entry macros. */ 290 #define MAGIC_DSENTRY_PREV(DE) ((DE)->prev) 291 #define MAGIC_DSENTRY_HAS_PREV(DE) ((DE)->prev != NULL) 292 #define MAGIC_DSENTRY_NEXT(DE) ((DE)->next) 293 #define MAGIC_DSENTRY_HAS_NEXT(DE) ((DE)->next != NULL) 294 #define MAGIC_DSENTRY_HAS_EXT(DE) \ 295 ((DE)->ext && MAGIC_STATE_FLAG(MAGIC_DSENTRY_TO_SENTRY(DE), \ 296 MAGIC_STATE_EXT)) 297 #define MAGIC_DSENTRY_TO_SENTRY(DE) (&((DE)->sentry)) 298 #define MAGIC_DSENTRY_FROM_SENTRY(E) \ 299 ((struct _magic_dsentry*)(((char*)(E)) - \ 300 offsetof(struct _magic_dsentry, sentry))) 301 #define MAGIC_DSENTRY_TO_TYPE_ARR(DE) ((DE)->type_array) 302 #define MAGIC_DSENTRY_NEXT_MEMPOOL(DE) ((DE)->next_mpool) 303 #define MAGIC_DSENTRY_NEXT_MEMBLOCK(DE) ((DE)->next_mblock) 304 #define MAGIC_DSENTRY_HAS_NEXT_MEMPOOL(DE) ((DE)->next_mpool != NULL) 305 #define MAGIC_DSENTRY_HAS_NEXT_MEMBLOCK(DE) ((DE)->next_mblock != NULL) 306 307 #define MAGIC_DSENTRY_MSTATE_ALIVE (~(0xFEE1DEAD)) 308 #define MAGIC_DSENTRY_MSTATE_DEAD 0xFEE1DEAD 309 #define MAGIC_DSENTRY_MSTATE_FREED 0xDEADBEEF 310 #define MAGIC_DSENTRY_MNUM MAGIC_DSENTRY_MSTATE_ALIVE 311 #define MAGIC_DSENTRY_MNUM_NULL 0 312 #define MAGIC_DSENTRY_SITE_ID_NULL 0 313 314 #define MAGIC_DSENTRY_MNUM_OK(D) ((D)->magic_number == MAGIC_DSENTRY_MNUM) 315 #define MAGIC_DSENTRY_MSTATE_OK(D) \ 316 ((D)->magic_state == MAGIC_DSENTRY_MSTATE_ALIVE \ 317 || (D)->magic_state == MAGIC_DSENTRY_MSTATE_DEAD \ 318 || (D)->magic_state == MAGIC_DSENTRY_MSTATE_FREED) 319 #define MAGIC_DSENTRY_MSTATE_C(D) \ 320 ((D)->magic_state == MAGIC_DSENTRY_MSTATE_ALIVE ? 'A' \ 321 : (D)->magic_state == MAGIC_DSENTRY_MSTATE_DEAD ? 'D' \ 322 : (D)->magic_state == MAGIC_DSENTRY_MSTATE_FREED ? 'F' : '?') 323 324 #define MAGIC_DSENTRY_PRINT(DE, EXPAND_TYPE_STR) do { \ 325 _magic_printf("DSENTRY: (~mnum=%08x, mstate=%c, address=0x%08x, " \ 326 "site_id=" MAGIC_ID_FORMAT ", next=0x%08x, sentry=", \ 327 ~((DE)->magic_number), MAGIC_DSENTRY_MSTATE_C(DE), (unsigned) (DE),\ 328 (DE)->site_id, (unsigned) (DE)->next); \ 329 MAGIC_SENTRY_PRINT(MAGIC_DSENTRY_TO_SENTRY(DE), EXPAND_TYPE_STR); \ 330 _magic_printf(")"); \ 331 } while(0) 332 333 /* Iterate through all the top-level dsentries. */ 334 #define MAGIC_DSENTRY_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) do { \ 335 if(HEAD) { \ 336 DSENTRY=NULL; \ 337 while(!DSENTRY || MAGIC_DSENTRY_HAS_NEXT(DSENTRY)) { \ 338 PREV_DSENTRY = DSENTRY; \ 339 DSENTRY = !DSENTRY ? HEAD : MAGIC_DSENTRY_NEXT(DSENTRY); \ 340 assert(magic_check_dsentry(DSENTRY, 0) \ 341 && "Bad magic dsentry looked up!"); \ 342 SENTRY = MAGIC_DSENTRY_TO_SENTRY(DSENTRY); \ 343 DO \ 344 } \ 345 } \ 346 } while(0) 347 348 #define MAGIC_DSENTRY_ALIVE_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) do { \ 349 MAGIC_DSENTRY_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 350 if((DSENTRY)->magic_state == MAGIC_DSENTRY_MSTATE_ALIVE) { \ 351 DO \ 352 } \ 353 ); \ 354 } while(0) 355 356 /* Iterate through all the top-level dsentries and nest at the block level. */ 357 #define MAGIC_DSENTRY_NESTED_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) do { \ 358 MAGIC_DSENTRY_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 359 DO \ 360 if(magic_lookup_nested_dsentries \ 361 && MAGIC_STATE_FLAG(SENTRY, MAGIC_STATE_MEMPOOL)) { \ 362 struct _magic_dsentry *MEMPOOL_DSENTRY = DSENTRY; \ 363 MAGIC_DSENTRY_MEMBLOCK_ITER(MEMPOOL_DSENTRY, DSENTRY, SENTRY, \ 364 DO \ 365 ); \ 366 DSENTRY = MEMPOOL_DSENTRY; \ 367 } \ 368 ); \ 369 } while(0) 370 371 #define MAGIC_DSENTRY_ALIVE_NESTED_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) \ 372 do { \ 373 MAGIC_DSENTRY_NESTED_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 374 if((DSENTRY)->magic_state == MAGIC_DSENTRY_MSTATE_ALIVE) { \ 375 DO \ 376 } \ 377 ); \ 378 } while(0) 379 380 /* Iterate through all the block-level dsentries. */ 381 #define MAGIC_DSENTRY_BLOCK_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) do { \ 382 MAGIC_DSENTRY_NESTED_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 383 if(!MAGIC_STATE_FLAG(SENTRY, MAGIC_STATE_MEMPOOL)) { \ 384 DO \ 385 } \ 386 ); \ 387 } while(0) 388 389 #define MAGIC_DSENTRY_ALIVE_BLOCK_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) \ 390 do { \ 391 MAGIC_DSENTRY_BLOCK_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 392 if((DSENTRY)->magic_state == MAGIC_DSENTRY_MSTATE_ALIVE) { \ 393 DO \ 394 } \ 395 ); \ 396 } while(0) 397 398 #define MAGIC_DSENTRY_MEMPOOL_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) do { \ 399 if(HEAD) { \ 400 DSENTRY=NULL; \ 401 while(!DSENTRY || MAGIC_DSENTRY_HAS_NEXT_MEMPOOL(DSENTRY)) { \ 402 PREV_DSENTRY = DSENTRY; \ 403 DSENTRY = !DSENTRY ? HEAD \ 404 : MAGIC_DSENTRY_NEXT_MEMPOOL(DSENTRY); \ 405 assert(magic_check_dsentry(DSENTRY, 0) \ 406 && "Bad magic dsentry looked up!"); \ 407 SENTRY = MAGIC_DSENTRY_TO_SENTRY(DSENTRY); \ 408 DO \ 409 } \ 410 } \ 411 } while(0) 412 413 #define MAGIC_DSENTRY_MEMPOOL_ALIVE_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY,DO) \ 414 do { \ 415 MAGIC_DSENTRY_MEMPOOL_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 416 if((DSENTRY)->magic_state == MAGIC_DSENTRY_MSTATE_ALIVE) { \ 417 DO \ 418 } \ 419 ); \ 420 } while(0) 421 422 #define MAGIC_DSENTRY_MEMBLOCK_ITER(MEMPOOL_DSENTRY, \ 423 MEMBLOCK_DSENTRY,MEMBLOCK_SENTRY,DO) \ 424 do { \ 425 if(MEMPOOL_DSENTRY) { \ 426 assert(magic_check_dsentry(MEMPOOL_DSENTRY, 0) \ 427 && "Bad magic dsentry looked up!"); \ 428 assert(MAGIC_STATE_FLAG(MAGIC_DSENTRY_TO_SENTRY(MEMPOOL_DSENTRY), \ 429 MAGIC_STATE_MEMPOOL) && "Bad mempool dsentry looked up!"); \ 430 MEMBLOCK_DSENTRY = MAGIC_DSENTRY_NEXT_MEMBLOCK(MEMPOOL_DSENTRY); \ 431 while (MEMBLOCK_DSENTRY && (MEMBLOCK_DSENTRY != MEMPOOL_DSENTRY)) {\ 432 assert(magic_check_dsentry(MEMBLOCK_DSENTRY, 0) \ 433 && "Bad magic dsentry looked up!"); \ 434 MEMBLOCK_SENTRY = MAGIC_DSENTRY_TO_SENTRY(MEMBLOCK_DSENTRY); \ 435 assert(MAGIC_STATE_FLAG(MEMBLOCK_SENTRY, MAGIC_STATE_MEMBLOCK) \ 436 && "Bad memblock dsentry looked up!"); \ 437 DO \ 438 MEMBLOCK_DSENTRY=MAGIC_DSENTRY_NEXT_MEMBLOCK(MEMBLOCK_DSENTRY);\ 439 } \ 440 } \ 441 } while(0) 442 443 #define MAGIC_DSENTRY_MEMPOOL_LOOKUP(MEMBLOCK_DSENTRY,MEMPOOL_DSENTRY) do { \ 444 if (MEMBLOCK_DSENTRY) { \ 445 struct _magic_dsentry *DSENTRY; \ 446 struct _magic_sentry *SENTRY; \ 447 DSENTRY = MEMBLOCK_DSENTRY; \ 448 do { \ 449 assert(magic_check_dsentry(DSENTRY, 0) \ 450 && "Bad magic dsentry looked up!"); \ 451 SENTRY = MAGIC_DSENTRY_TO_SENTRY(DSENTRY); \ 452 if (MAGIC_STATE_FLAG(SENTRY, MAGIC_STATE_MEMPOOL)) { \ 453 MEMPOOL_DSENTRY = DSENTRY; \ 454 break; \ 455 } \ 456 DSENTRY = MAGIC_DSENTRY_NEXT_MEMBLOCK(DSENTRY); \ 457 } while (DSENTRY != MEMBLOCK_DSENTRY); \ 458 } \ 459 } while(0) 460 461 #define MAGIC_DSENTRY_ALIVE_NAME_ID_ITER(HEAD, PREV_DSENTRY, DSENTRY, SENTRY, \ 462 PN, N, ID, DO) do { \ 463 MAGIC_DSENTRY_ALIVE_ITER(HEAD,PREV_DSENTRY,DSENTRY,SENTRY, \ 464 if((!(PN) || !strcmp((DSENTRY)->parent_name, (PN))) \ 465 && (!(N) || !strcmp((SENTRY)->name, (N))) \ 466 && (!(ID) || ((ID) == (DSENTRY)->site_id))) { \ 467 DO \ 468 } \ 469 ); \ 470 } while(0) 471 472 #define MAGIC_DSENTRY_NUM(HEAD,NUM) do { \ 473 struct _magic_dsentry *_prev_dsentry, *_dsentry; \ 474 struct _magic_sentry *_sentry; \ 475 *(NUM) = 0; \ 476 MAGIC_DSENTRY_ITER(HEAD,_prev_dsentry,_dsentry,_sentry,(*(NUM))++;); \ 477 } while(0) 478 479 #define MAGIC_DSENTRY_ALIVE_NUM(HEAD,NUM) do { \ 480 struct _magic_dsentry *_prev_dsentry, *_dsentry; \ 481 struct _magic_sentry *_sentry; \ 482 *(NUM) = 0; \ 483 MAGIC_DSENTRY_ALIVE_ITER(HEAD,_prev_dsentry,_dsentry,_sentry,(*(NUM))++;); \ 484 } while(0) 485 486 #define MAGIC_DSENTRY_BLOCK_NUM(HEAD,NUM) do { \ 487 struct _magic_dsentry *_prev_dsentry, *_dsentry; \ 488 struct _magic_sentry *_sentry; \ 489 *(NUM) = 0; \ 490 MAGIC_DSENTRY_BLOCK_ITER(HEAD,_prev_dsentry,_dsentry,_sentry,(*(NUM))++;); \ 491 } while(0) 492 493 #define MAGIC_DSENTRY_ALIVE_BLOCK_NUM(HEAD,NUM) do { \ 494 struct _magic_dsentry *_prev_dsentry, *_dsentry; \ 495 struct _magic_sentry *_sentry; \ 496 *(NUM) = 0; \ 497 MAGIC_DSENTRY_ALIVE_BLOCK_ITER(HEAD,_prev_dsentry,_dsentry,_sentry,(*(NUM))++;); \ 498 } while(0) 499 500 #define MAGIC_DEAD_DSENTRIES_NEED_FREEING() \ 501 (magic_num_dead_dsentries > MAGIC_MAX_DEAD_DSENTRIES \ 502 || magic_size_dead_dsentries > MAGIC_MAX_DEAD_DSENTRIES_SIZE) 503 504 #define MAGIC_SENTRY_OVERLAPS(S, START, END) \ 505 ((char*)(S)->address<=(char*)(END) \ 506 && (char*)(S)->address+(S)->type->size-1>=(char*)(START)) 507 508 #define MAGIC_SENTRY_RANGE_ALIVE_BLOCK_ITER(SENTRY,START,END,DO) do { \ 509 int __i; \ 510 struct _magic_dsentry *__prev_dsentry, *__dsentry; \ 511 if (magic_sentry_rl_index) { \ 512 char *__addr = NULL; \ 513 SENTRY = NULL; \ 514 while (1) { \ 515 __addr = __addr ? SENTRY->address : ((char*)END) + 1; \ 516 SENTRY = magic_sentry_rl_pred_lookup(__addr); \ 517 if (!SENTRY || !MAGIC_SENTRY_OVERLAPS(SENTRY, START, ((char*)-1))) break; \ 518 DO \ 519 } \ 520 break; \ 521 } \ 522 for (__i=0;__i<_magic_sentries_num;__i++) { \ 523 SENTRY = &_magic_sentries[__i]; \ 524 if (MAGIC_SENTRY_OVERLAPS(SENTRY, START, END)) { DO } \ 525 } \ 526 MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry, __prev_dsentry, __dsentry, SENTRY, \ 527 if (MAGIC_SENTRY_OVERLAPS(SENTRY, START, END)) { \ 528 if(magic_lookup_nested_dsentries \ 529 && MAGIC_STATE_FLAG(SENTRY, MAGIC_STATE_MEMPOOL)) { \ 530 struct _magic_dsentry *MEMPOOL_DSENTRY = __dsentry; \ 531 struct _magic_dsentry *__dsentry2; \ 532 MAGIC_DSENTRY_MEMBLOCK_ITER(MEMPOOL_DSENTRY, __dsentry2, SENTRY, \ 533 if (MAGIC_SENTRY_OVERLAPS(SENTRY, START, END)) { DO } \ 534 ); \ 535 } \ 536 else { DO } \ 537 } \ 538 ); \ 539 } while(0) 540 541 /* Magic out-of-band dynamic state entry macros. */ 542 #define MAGIC_OBDSENTRY_TO_DSENTRY(OBDE) (&((OBDE)->dsentry)) 543 #define MAGIC_OBDSENTRY_FROM_DSENTRY(DE) \ 544 ((struct _magic_obdsentry*)(((char*)(DE)) - \ 545 offsetof(struct _magic_obdsentry, dsentry))) 546 #define MAGIC_OBDSENTRY_TO_SENTRY(OBDE) \ 547 MAGIC_DSENTRY_TO_SENTRY(MAGIC_OBDSENTRY_TO_DSENTRY(OBDE)) 548 #define MAGIC_OBDSENTRY_FROM_SENTRY(E) \ 549 MAGIC_OBDSENTRY_FROM_DSENTRY(MAGIC_DSENTRY_FROM_SENTRY(E)) 550 #define MAGIC_OBDSENTRY_IS_FREE(OBDE) \ 551 ((OBDE)->dsentry.sentry.flags == 0) 552 #define MAGIC_OBDSENTRY_FREE(OBDE) ((OBDE)->dsentry.sentry.flags = 0) 553 554 /* Magic memory pool state entry macros. */ 555 #define MAGIC_MPDESC_IS_FREE(POOL) ((POOL)->is_alive == 0) 556 #define MAGIC_MPDESC_ALLOC(POOL) ((POOL)->is_alive = 1) 557 #if MAGIC_MEM_USAGE_OUTPUT_CTL 558 #define MAGIC_MPDESC_FREE(POOL) do { \ 559 (POOL)->is_alive = 0; \ 560 (POOL)->addr = NULL; \ 561 (POOL)->dtype_id = 0; \ 562 } while (0) 563 #else 564 #define MAGIC_MPDESC_FREE(POOL) do { \ 565 (POOL)->is_alive = 0; \ 566 (POOL)->addr = NULL; \ 567 } while (0) 568 #endif 569 570 #define MAGIC_SELEMENT_MAX_PTR_RECURSIONS 100 571 572 #define MAGIC_SELEMENT_NAME_PRINT(E) do { \ 573 if((E)->sentry) { \ 574 magic_type_walk_root((E)->sentry->type, 0, \ 575 (unsigned long) ((char*)(E)->address - \ 576 (char*)(E)->sentry->address), magic_selement_name_print_cb, \ 577 (void*)__UNCONST((E))); \ 578 } \ 579 else { \ 580 _magic_printf("???"); \ 581 } \ 582 } while(0) 583 #define MAGIC_CHECK_TRG(T) \ 584 (magic_type_target_walk(T, NULL, NULL, magic_type_count_cb, NULL) >= 0) 585 #define MAGIC_SELEMENT_HAS_TRG(E) \ 586 ((E)->type->size == sizeof(void*) \ 587 && MAGIC_CHECK_TRG(*((void**)(E)->address))) 588 #define MAGIC_SELEMENT_PRINT(E, FLAGS) do { \ 589 _magic_printf("SELEMENT: (parent=%s, num=%d, depth=%d, address=0x%08x,"\ 590 " name=", (E)->sentry ? (E)->sentry->name : "???", (E)->num, \ 591 (E)->depth, (E)->address); \ 592 MAGIC_SELEMENT_NAME_PRINT(E); \ 593 _magic_printf(", type="); \ 594 if ((E)->type) MAGIC_TYPE_PRINT((E)->type, FLAGS); \ 595 if(((FLAGS) & MAGIC_EXPAND_SENTRY) && (E)->sentry) { \ 596 _magic_printf(", sentry="); \ 597 MAGIC_SENTRY_PRINT((E)->sentry, FLAGS); \ 598 } \ 599 _magic_printf(")"); \ 600 } while(0) 601 602 /* Magic external library descriptor macros. */ 603 #define MAGIC_LIBDESC_PRINT(LD) \ 604 _magic_printf("LIBDESC: (name=%s, text_range=[%p,%p], data_range=[%p,%p], "\ 605 "alloc_address=%p, alloc_size=%zu)", (LD)->name, (LD)->text_range[0], \ 606 (LD)->text_range[1], (LD)->data_range[0], (LD)->data_range[1], \ 607 (LD)->alloc_address, (LD)->alloc_size); 608 609 /* Magic SO library descriptor macros. */ 610 #define MAGIC_SODESC_PREV(SD) ((SD)->prev) 611 #define MAGIC_SODESC_HAS_PREV(SD) ((SD)->prev != NULL) 612 #define MAGIC_SODESC_NEXT(SD) ((SD)->next) 613 #define MAGIC_SODESC_HAS_NEXT(SD) ((SD)->next != NULL) 614 615 #define MAGIC_SODESC_PRINT(SD) do { \ 616 _magic_printf("SODESC: (address=%p, prev=%p, next=%p, ", (SD), \ 617 (SD)->prev, (SD)->next); \ 618 MAGIC_LIBDESC_PRINT(&((SD)->lib)); \ 619 _magic_printf(")"); \ 620 } while(0) 621 622 #define MAGIC_SODESC_ITER(HEAD, SODESC, DO) do { \ 623 if (HEAD) { \ 624 SODESC = NULL; \ 625 while(!SODESC || MAGIC_SODESC_HAS_NEXT(SODESC)) { \ 626 SODESC = !SODESC ? HEAD : MAGIC_SODESC_NEXT(SODESC); \ 627 DO \ 628 } \ 629 } \ 630 } while(0) 631 632 #define MAGIC_SODESC_ITER_SAFE(HEAD, SODESC, DO) do { \ 633 struct _magic_sodesc *sodesc_next; \ 634 if (HEAD) { \ 635 SODESC = NULL; \ 636 while(!SODESC || sodesc_next != NULL) { \ 637 SODESC = !SODESC ? HEAD : sodesc_next; \ 638 sodesc_next = MAGIC_SODESC_NEXT(SODESC); \ 639 DO \ 640 } \ 641 } \ 642 } while(0) 643 644 /* Magic DSO library descriptor macros. */ 645 #define MAGIC_DSODESC_PREV(DD) ((DD)->prev) 646 #define MAGIC_DSODESC_HAS_PREV(DD) ((DD)->prev != NULL) 647 #define MAGIC_DSODESC_NEXT(DD) ((DD)->next) 648 #define MAGIC_DSODESC_HAS_NEXT(DD) ((DD)->next != NULL) 649 650 #define MAGIC_DSODESC_PRINT(DD) do { \ 651 _magic_printf("DSODESC: (address=%p, prev=%p, next=%p, handle=%p, " \ 652 "ref_count=%d, ", (DD), (DD)->prev, (DD)->next, (DD)->handle, \ 653 (DD)->ref_count); \ 654 MAGIC_LIBDESC_PRINT(&((DD)->lib)); \ 655 _magic_printf(")"); \ 656 } while(0) 657 658 #define MAGIC_DSODESC_ITER(HEAD, DSODESC, DO) do { \ 659 if (HEAD) { \ 660 DSODESC = NULL; \ 661 while(!DSODESC || MAGIC_DSODESC_HAS_NEXT(DSODESC)) { \ 662 DSODESC = !DSODESC ? HEAD : MAGIC_DSODESC_NEXT(DSODESC); \ 663 DO \ 664 } \ 665 } \ 666 } while(0) 667 668 #define MAGIC_DSODESC_ITER_SAFE(HEAD, DSODESC, DO) do { \ 669 struct _magic_dsodesc *dsodesc_next; \ 670 if (HEAD) { \ 671 DSODESC = NULL; \ 672 while(!DSODESC || dsodesc_next != NULL) { \ 673 DSODESC = !DSODESC ? HEAD : dsodesc_next; \ 674 dsodesc_next = MAGIC_DSODESC_NEXT(DSODESC); \ 675 DO \ 676 } \ 677 } \ 678 } while(0) 679 680 /* Magic value casts. */ 681 #define MAGIC_VALUE_CAST_DEBUG MAGIC_DEBUG_SET(0) 682 683 #define MAGIC_CHECKED_VALUE_SRC_CAST(SV, ST, DV, DT, RP, CS) \ 684 do { \ 685 ST value = SV; \ 686 DV = (DT) value; \ 687 if (((ST) (DV)) != value) { \ 688 *(RP) = MAGIC_ERANGE; \ 689 } \ 690 else if(CS && value && (((DV) <= (DT) 0 && value >= (ST) 0) || \ 691 ((DV) >= (DT) 0 && value <= (ST) 0))) { \ 692 *(RP) = MAGIC_ESIGN; \ 693 } \ 694 if(MAGIC_VALUE_CAST_DEBUG) { \ 695 _magic_printf("SRC "); \ 696 MAGIC_SELEMENT_PRINT(src_selement, MAGIC_EXPAND_TYPE_STR); \ 697 _magic_printf("\n"); \ 698 _magic_printf("DST "); \ 699 MAGIC_SELEMENT_PRINT(dst_selement, MAGIC_EXPAND_TYPE_STR); \ 700 _magic_printf("\n"); \ 701 _magic_printf("MAGIC_CHECKED_VALUE_SRC_CAST: " \ 702 "types=%s-->%s, value=", #ST, #DT); \ 703 magic_selement_print_value(src_selement); \ 704 _magic_printf("-->(long/unsigned long/void*)%d/%u/%08x, " \ 705 "ERANGE=%d, ESIGN=%d\n", (long) (DV), (unsigned long) (DV), \ 706 (unsigned long) (DV), *(RP) == MAGIC_ERANGE, \ 707 *(RP) == MAGIC_ESIGN); \ 708 } \ 709 } while(0) 710 711 #define MAGIC_CHECKED_VALUE_DST_CAST(SV, ST, DV, DT, RP) \ 712 do { \ 713 DT value = (DT) SV; \ 714 if (((ST) value) != (SV)) { \ 715 *(RP) = MAGIC_ERANGE; \ 716 } \ 717 *((DT*) (DV)) = value; \ 718 if (MAGIC_VALUE_CAST_DEBUG) { \ 719 _magic_selement_t tmp_selement = *dst_selement; \ 720 tmp_selement.address = DV; \ 721 _magic_printf("MAGIC_CHECKED_VALUE_DST_CAST: types=%s-->%s, " \ 722 "value=(long/unsigned long/void*)%d/%u/%08x-->", #ST, #DT, \ 723 (long) (SV), (unsigned long) (SV), (unsigned long) (SV)); \ 724 magic_selement_print_value(&tmp_selement); \ 725 _magic_printf(", ERANGE=%d\n", *(RP) == MAGIC_ERANGE); \ 726 } \ 727 } while(0) 728 729 /* Magic utility macros. */ 730 #define MAGIC_ABS(X) ((X) >= 0 ? (X) : -(X)) 731 732 /* Magic page size. */ 733 #define MAGIC_PAGE_SIZE (magic_sys_pagesize ? magic_sys_pagesize : magic_get_sys_pagesize()) 734 EXTERN unsigned long magic_sys_pagesize; 735 736 /* Magic sections. */ 737 #define MAGIC_DATA_SECTION_START ((void*)&__start_magic_data) 738 #define MAGIC_DATA_SECTION_END ((void*)&__stop_magic_data) 739 #define MAGIC_DATA_RO_SECTION_START ((void*)&__start_magic_data_ro) 740 #define MAGIC_DATA_RO_SECTION_END ((void*)&__stop_magic_data_ro) 741 #define MAGIC_ST_DATA_SECTION_START ((void*)&__start_magic_data_st) 742 #define MAGIC_ST_DATA_SECTION_END ((void*)&__stop_magic_data_st) 743 #define MAGIC_ST_DATA_RO_SECTION_START ((void*)&__start_magic_data_st_ro) 744 #define MAGIC_ST_DATA_RO_SECTION_END ((void*)&__stop_magic_data_st_ro) 745 #define MAGIC_TEXT_SECTION_START ((void*)&__start_magic_functions) 746 #define MAGIC_TEXT_SECTION_END ((void*)&__stop_magic_functions) 747 #define MAGIC_ST_TEXT_SECTION_START ((void*)&__start_magic_functions_st) 748 #define MAGIC_ST_TEXT_SECTION_END ((void*)&__stop_magic_functions_st) 749 EXTERN void* __start_magic_data; 750 EXTERN void* __stop_magic_data; 751 EXTERN void* __start_magic_data_ro; 752 EXTERN void* __stop_magic_data_ro; 753 EXTERN void* __start_magic_data_st; 754 EXTERN void* __stop_magic_data_st; 755 EXTERN void* __start_magic_data_st_ro; 756 EXTERN void* __stop_magic_data_st_ro; 757 EXTERN void* __start_magic_functions; 758 EXTERN void* __stop_magic_functions; 759 EXTERN void* __start_magic_functions_st; 760 EXTERN void* __stop_magic_functions_st; 761 762 #if MAGIC_THREAD_SAFE 763 #if MAGIC_FORCE_LOCKS 764 #define MAGIC_DSENTRY_LOCK() magic_dsentry_lock(magic_dsentry_lock_args) 765 #define MAGIC_DSENTRY_UNLOCK() magic_dsentry_unlock(magic_dsentry_unlock_args) 766 #define MAGIC_DFUNCTION_LOCK() magic_dfunction_lock(magic_dfunction_lock_args) 767 #define MAGIC_DFUNCTION_UNLOCK() \ 768 magic_dfunction_unlock(magic_dfunction_unlock_args) 769 #define MAGIC_DSODESC_LOCK() magic_dsodesc_lock(magic_dsodesc_lock_args) 770 #define MAGIC_DSODESC_UNLOCK() magic_dsodesc_unlock(magic_dsodesc_unlock_args) 771 #define MAGIC_MPDESC_LOCK() magic_mpdesc_lock(magic_mpdesc_lock_args) 772 #define MAGIC_MPDESC_UNLOCK() magic_mpdesc_unlock(magic_mpdesc_unlock_args) 773 #else 774 #define MAGIC_GENERIC_LOCK(LOCK,ARGS) \ 775 do { \ 776 int l; \ 777 if (LOCK) { \ 778 l = LOCK(ARGS); \ 779 assert(l == 0 && "bad lock"); \ 780 } \ 781 } while (0) 782 783 #define MAGIC_DSENTRY_LOCK() \ 784 MAGIC_GENERIC_LOCK(magic_dsentry_lock,magic_dsentry_lock_args) 785 #define MAGIC_DSENTRY_UNLOCK() \ 786 MAGIC_GENERIC_LOCK(magic_dsentry_unlock,magic_dsentry_unlock_args) 787 #define MAGIC_DFUNCTION_LOCK() \ 788 MAGIC_GENERIC_LOCK(magic_dfunction_lock,magic_dfunction_lock_args) 789 #define MAGIC_DFUNCTION_UNLOCK() \ 790 MAGIC_GENERIC_LOCK(magic_dfunction_unlock,magic_dfunction_unlock_args) 791 #define MAGIC_DSODESC_LOCK() \ 792 MAGIC_GENERIC_LOCK(magic_dsodesc_lock,magic_dsodesc_lock_args) 793 #define MAGIC_DSODESC_UNLOCK() \ 794 MAGIC_GENERIC_LOCK(magic_dsodesc_unlock,magic_dsodesc_unlock_args) 795 #define MAGIC_MPDESC_LOCK() \ 796 MAGIC_GENERIC_LOCK(magic_mpdesc_lock,magic_mpdesc_lock_args) 797 #define MAGIC_MPDESC_UNLOCK() \ 798 MAGIC_GENERIC_LOCK(magic_mpdesc_unlock,magic_mpdesc_unlock_args) 799 #endif 800 #define MAGIC_MULTIPLE_LOCK(DS, DF, DSO, MP) \ 801 do { \ 802 if (DS) \ 803 MAGIC_DSENTRY_LOCK(); \ 804 if (DF) \ 805 MAGIC_DFUNCTION_LOCK(); \ 806 if (DSO) \ 807 MAGIC_DSODESC_LOCK(); \ 808 if (MP) \ 809 MAGIC_MPDESC_LOCK(); \ 810 } while (0) 811 #define MAGIC_MULTIPLE_UNLOCK(DS, DF, DSO, MP) \ 812 do { \ 813 if (MP) \ 814 MAGIC_MPDESC_UNLOCK(); \ 815 if (DSO) \ 816 MAGIC_DSODESC_UNLOCK(); \ 817 if (DF) \ 818 MAGIC_DFUNCTION_UNLOCK(); \ 819 if (DS) \ 820 MAGIC_DSENTRY_UNLOCK(); \ 821 } while (0) 822 #define MAGIC_MULTIPLE_LOCK_BLOCK(DS, DF, DSO, MP, BLOCK) \ 823 do { \ 824 MAGIC_MULTIPLE_LOCK(DS, DF, DSO, MP); \ 825 BLOCK \ 826 MAGIC_MULTIPLE_UNLOCK(DS, DF, DSO, MP); \ 827 } while (0) 828 #else 829 #define MAGIC_DSENTRY_LOCK() 830 #define MAGIC_DSENTRY_UNLOCK() 831 #define MAGIC_DFUNCTION_LOCK() 832 #define MAGIC_DFUNCTION_UNLOCK() 833 #define MAGIC_DSODESC_LOCK() 834 #define MAGIC_DSODESC_UNLOCK() 835 #define MAGIC_MPDESC_LOCK() 836 #define MAGIC_MPDESC_UNLOCK() 837 #define MAGIC_MULTIPLE_LOCK(DS, DF, DSO, MP) 838 #define MAGIC_MULTIPLE_UNLOCK(DS, DF, DSO, MP) 839 #define MAGIC_MULTIPLE_LOCK_BLOCK(DS, DF, DSO, MP, BLOCK) \ 840 do { \ 841 BLOCK \ 842 } while (0) 843 #endif 844 845 /* Debug. */ 846 #define MAGIC_DEBUG_HIGH 3 847 #define MAGIC_DEBUG_AVG 2 848 #define MAGIC_DEBUG_LOW 1 849 #define MAGIC_DEBUG_NONE 0 850 #define MAGIC_DEBUG \ 851 MAGIC_DEBUG_SELECT(MAGIC_DEBUG_HIGH, MAGIC_DEBUG_NONE) 852 853 #if MAGIC_DEBUG 854 #define MAGIC_DEBUG_CODE(L, X) \ 855 do { \ 856 if(L > MAGIC_DEBUG) break; \ 857 X \ 858 } while(0) 859 #else 860 #define MAGIC_DEBUG_CODE(L, X) 861 #endif 862 863 /* Magic Address Space Randomization (ASRPass) */ 864 #define _magic_asr_seed (_magic_vars->asr_seed) 865 #define _magic_asr_heap_map_do_permutate ( \ 866 _magic_vars->asr_heap_map_do_permutate) 867 #define _magic_asr_heap_max_offset (_magic_vars->asr_heap_max_offset) 868 #define _magic_asr_heap_max_padding (_magic_vars->asr_heap_max_padding) 869 #define _magic_asr_map_max_offset_pages (_magic_vars->asr_map_max_offset_pages) 870 #define _magic_asr_map_max_padding_pages ( \ 871 _magic_vars->asr_map_max_padding_pages) 872 873 /* Runtime flags. */ 874 #define _magic_no_mem_inst (_magic_vars->no_mem_inst) 875 876 /* Magic type array. */ 877 #define _magic_types (_magic_vars->types) 878 #define _magic_types_num (_magic_vars->types_num) 879 #define _magic_types_next_id (_magic_vars->types_next_id) 880 881 /* Magic function array. */ 882 #define _magic_functions (_magic_vars->functions) 883 #define _magic_functions_num (_magic_vars->functions_num) 884 #define _magic_functions_next_id (_magic_vars->functions_next_id) 885 886 /* Magic dynamic function list. */ 887 #define _magic_first_dfunction (_magic_vars->first_dfunction) 888 #define _magic_last_dfunction (_magic_vars->last_dfunction) 889 #define _magic_dfunctions_num (_magic_vars->dfunctions_num) 890 891 /* Magic functions hash vars. */ 892 #define magic_function_hash_buff (_magic_vars->function_hash_buff) 893 #define magic_function_hash_buff_offset (_magic_vars->function_hash_buff_offset) 894 #define magic_function_hash_buff_size (_magic_vars->function_hash_buff_size) 895 #define magic_function_hash_head (_magic_vars->function_hash_head) 896 897 /* Magic dynamic state index array. */ 898 #define _magic_dsindexes (_magic_vars->dsindexes) 899 #define _magic_dsindexes_num (_magic_vars->dsindexes_num) 900 901 /* Magic dynamic state entry list. */ 902 #define _magic_first_dsentry (_magic_vars->first_dsentry) 903 #define magic_num_dead_dsentries (_magic_vars->num_dead_dsentries) 904 #define magic_size_dead_dsentries (_magic_vars->size_dead_dsentries) 905 906 /* Magic memory pool dynamic state entry list. */ 907 #define _magic_first_mempool_dsentry (_magic_vars->first_mempool_dsentry) 908 909 /* Magic SO library descriptor list. */ 910 #define _magic_first_sodesc (_magic_vars->first_sodesc) 911 #define _magic_last_sodesc (_magic_vars->last_sodesc) 912 #define _magic_sodescs_num (_magic_vars->sodescs_num) 913 914 /* Magic DSO library descriptor list. */ 915 #define _magic_first_dsodesc (_magic_vars->first_dsodesc) 916 #define _magic_last_dsodesc (_magic_vars->last_dsodesc) 917 #define _magic_dsodescs_num (_magic_vars->dsodescs_num) 918 919 /* Magic stack-related variables. */ 920 #define _magic_first_stack_dsentry (_magic_vars->first_stack_dsentry) 921 #define _magic_last_stack_dsentry (_magic_vars->last_stack_dsentry) 922 923 /* Magic unmap-memory variables. */ 924 #ifdef __MINIX 925 #define _magic_unmap_mem (_magic_vars->unmap_mem) 926 #endif 927 928 /* Magic default stubs. */ 929 EXTERN struct _magic_type magic_default_type; 930 EXTERN struct _magic_dsentry magic_default_dsentry; 931 EXTERN struct _magic_dfunction magic_default_dfunction; 932 EXTERN struct _magic_type magic_default_ret_addr_type; 933 934 /* Magic vars references. */ 935 EXTERN struct _magic_vars_t _magic_vars_buff; 936 EXTERN struct _magic_vars_t *_magic_vars; 937 938 FUNCTION_BLOCK( 939 940 /* Magic vars wrappers. */ 941 PUBLIC void *_magic_vars_addr(void); 942 PUBLIC size_t _magic_vars_size(void); 943 944 /* Magic printf. */ 945 PUBLIC int magic_null_printf(const char* format, ...); 946 PUBLIC int magic_err_printf(const char* format, ...); 947 PUBLIC void magic_set_printf(printf_ptr_t func_ptr); 948 PUBLIC printf_ptr_t magic_get_printf(void); 949 PUBLIC void magic_assert_failed(const char *assertion, const char *file, 950 const char *function, const int line); 951 952 /* Magic utility functions. */ 953 PUBLIC unsigned long magic_get_sys_pagesize(void); 954 955 /* Magic lock primitives. */ 956 typedef int (*magic_lock_t)(void*); 957 typedef int (*magic_unlock_t)(void*); 958 959 EXTERN magic_lock_t magic_dsentry_lock; 960 EXTERN magic_unlock_t magic_dsentry_unlock; 961 EXTERN void *magic_dsentry_lock_args; 962 EXTERN void *magic_dsentry_unlock_args; 963 964 EXTERN magic_lock_t magic_dfunction_lock; 965 EXTERN magic_unlock_t magic_dfunction_unlock; 966 EXTERN void *magic_dfunction_lock_args; 967 EXTERN void *magic_dfunction_unlock_args; 968 969 EXTERN magic_lock_t magic_dsodesc_lock; 970 EXTERN magic_unlock_t magic_dsodesc_unlock; 971 EXTERN void *magic_dsodesc_lock_args; 972 EXTERN void *magic_dsodesc_unlock_args; 973 974 EXTERN magic_lock_t magic_mpdesc_lock; 975 EXTERN magic_unlock_t magic_mpdesc_unlock; 976 EXTERN void *magic_mpdesc_lock_args; 977 EXTERN void *magic_mpdesc_unlock_args; 978 979 PUBLIC void magic_dsentry_set_lock_primitives(magic_lock_t lock, 980 magic_unlock_t unlock, void *lock_args, void *unlock_args); 981 PUBLIC void magic_dfunction_set_lock_primitives(magic_lock_t lock, 982 magic_unlock_t unlock, void *lock_args, void *unlock_args); 983 PUBLIC void magic_dsodesc_set_lock_primitives(magic_lock_t lock, 984 magic_unlock_t unlock, void *lock_args, void *unlock_args); 985 PUBLIC void magic_mpdesc_set_lock_primitives(magic_lock_t lock, 986 magic_unlock_t unlock, void *lock_args, void *unlock_args); 987 988 /* 989 * Magic void ptr and array (force at the least 1 void* and 1 void array in the 990 * list of globals). 991 */ 992 EXTERN void* MAGIC_VOID_PTR; 993 EXTERN char MAGIC_VOID_ARRAY[1]; 994 995 /* Magic special types. */ 996 EXTERN struct _magic_type *MAGIC_VOID_PTR_TYPE; 997 EXTERN struct _magic_type *MAGIC_VOID_PTR_INT_CAST_TYPE; 998 EXTERN struct _magic_type *MAGIC_VOID_ARRAY_TYPE; 999 EXTERN struct _magic_type *MAGIC_PTRINT_TYPE; 1000 EXTERN struct _magic_type *MAGIC_PTRINT_ARRAY_TYPE; 1001 1002 /* Magic annotations. */ 1003 EXTERN VOLATILE int MAGIC_CALL_ANNOTATION_VAR; 1004 1005 /* Magic status variables. */ 1006 EXTERN int magic_init_done; 1007 EXTERN int magic_libcommon_active; 1008 EXTERN int magic_lookup_nested_dsentries; 1009 EXTERN int magic_allow_dead_dsentries; 1010 EXTERN int magic_ignore_dead_dsentries; 1011 EXTERN int magic_mmap_dsentry_header_prot; 1012 EXTERN int _magic_enabled; 1013 EXTERN int _magic_checkpoint_enabled; 1014 EXTERN int _magic_lazy_checkpoint_enabled; 1015 1016 /* Magic page size. */ 1017 EXTERN unsigned long magic_sys_pagesize; 1018 1019 /* Initialization functions. */ 1020 PUBLIC void magic_init(void); 1021 PUBLIC void magic_stack_init(void); 1022 1023 /* Dfunction functions. */ 1024 PUBLIC int magic_check_dfunction(struct _magic_dfunction *ptr, int flags); 1025 PUBLIC int magic_check_dfunctions(void); 1026 PUBLIC int magic_check_dfunctions_safe(void); 1027 PUBLIC void magic_print_dfunction(struct _magic_dfunction *dfunction); 1028 PUBLIC void magic_print_dfunctions(void); 1029 PUBLIC void magic_print_dfunctions_safe(void); 1030 PUBLIC void magic_copy_dfunction(struct _magic_dfunction *dfunction, 1031 struct _magic_dfunction *dst_dfunction); 1032 1033 /* Dsindex functions. */ 1034 PUBLIC void magic_print_dsindex(struct _magic_dsindex *dsindex); 1035 PUBLIC void magic_print_dsindexes(void); 1036 1037 /* Dsentry functions. */ 1038 PUBLIC int magic_check_dsentry(struct _magic_dsentry *ptr, int flags); 1039 PUBLIC int magic_check_dsentries(void); 1040 PUBLIC int magic_check_dsentries_safe(void); 1041 PUBLIC void magic_print_dsentry(struct _magic_dsentry *dsentry); 1042 PUBLIC void magic_print_dsentries(void); 1043 PUBLIC void magic_print_dsentries_safe(void); 1044 PUBLIC void magic_copy_dsentry(struct _magic_dsentry *dsentry, 1045 struct _magic_dsentry *dst_dsentry); 1046 1047 /* Sodesc functions. */ 1048 PUBLIC void magic_print_sodesc(struct _magic_sodesc *sodesc); 1049 PUBLIC void magic_print_sodescs(void); 1050 1051 /* Dsodesc functions. */ 1052 PUBLIC void magic_print_dsodesc(struct _magic_dsodesc *dsodesc); 1053 PUBLIC void magic_print_dsodescs(void); 1054 PUBLIC void magic_print_dsodescs_safe(void); 1055 1056 /* Section functions. */ 1057 PUBLIC void magic_print_sections(void); 1058 1059 /* Lookup functions. */ 1060 PUBLIC struct _magic_sentry* magic_mempool_sentry_lookup_by_range(void *addr, 1061 struct _magic_dsentry *dsentry_buff); 1062 PUBLIC struct _magic_dsindex* 1063 magic_dsindex_lookup_by_name(const char *parent_name, const char *name); 1064 PUBLIC struct _magic_dsentry* 1065 magic_dsentry_prev_lookup(struct _magic_dsentry* dsentry); 1066 PUBLIC struct _magic_dsentry* 1067 magic_mempool_dsentry_prev_lookup(struct _magic_dsentry* dsentry); 1068 PUBLIC struct _magic_function* magic_function_lookup_by_id(_magic_id_t id, 1069 struct _magic_dfunction *dfunction_buff); 1070 PUBLIC struct _magic_function* magic_function_lookup_by_addr(void *addr, 1071 struct _magic_dfunction *dfunction_buff); 1072 PUBLIC struct _magic_function* 1073 magic_function_lookup_by_name(const char *parent_name, const char *name); 1074 PUBLIC struct _magic_type* magic_type_lookup_by_name(const char *name); 1075 PUBLIC struct _magic_dsodesc* magic_dsodesc_lookup_by_handle(void *handle); 1076 PUBLIC int magic_selement_lookup_by_name(char* name, 1077 _magic_selement_t *selement, struct _magic_dsentry *dsentry_buff); 1078 1079 /* Magic state function functions. */ 1080 PUBLIC void magic_print_function(struct _magic_function *function); 1081 PUBLIC void magic_print_functions(void); 1082 1083 /* Magic state function lookup hash functions. */ 1084 PUBLIC void magic_function_hash_build(void *buff, size_t buff_size); 1085 PUBLIC void magic_function_hash_destroy(void); 1086 PUBLIC size_t magic_function_hash_estimate_buff_size(int functions_num); 1087 PUBLIC struct _magic_function *magic_function_lookup_by_addr_hash(void *addr, 1088 struct _magic_dfunction *dfunction_buff); 1089 PUBLIC void *magic_function_hash_alloc(size_t size); 1090 PUBLIC void magic_function_hash_dealloc(void *object, size_t size); 1091 1092 /* Magic state type functions. */ 1093 PUBLIC void magic_print_type(const struct _magic_type* type); 1094 PUBLIC void magic_print_types(void); 1095 PUBLIC void magic_type_str_set_print_style(const int style); 1096 PUBLIC int magic_type_str_get_print_style(void); 1097 PUBLIC void magic_type_str_print(const struct _magic_type* type); 1098 PUBLIC void magic_type_values_print(const struct _magic_type* type); 1099 PUBLIC void magic_type_names_print(const struct _magic_type* type); 1100 PUBLIC void magic_type_comp_types_print(const struct _magic_type* type, 1101 int flags); 1102 PUBLIC int magic_type_str_print_from_target(void* target); 1103 PUBLIC int magic_type_equals(const struct _magic_type* type, 1104 const struct _magic_type* other_type); 1105 PUBLIC int magic_type_compatible(const struct _magic_type* type, 1106 const struct _magic_type* other_type, int flags); 1107 PUBLIC int magic_type_comp_compatible(const struct _magic_type* type, 1108 const struct _magic_type* other_type); 1109 PUBLIC int magic_type_ptr_is_text(const struct _magic_type* ptr_type); 1110 PUBLIC int magic_type_ptr_is_data(const struct _magic_type* ptr_type); 1111 PUBLIC int magic_type_alloc_needs_varsized_array(const struct _magic_type* type, 1112 size_t alloc_size, int *num_elements); 1113 PUBLIC size_t 1114 magic_type_alloc_get_varsized_array_size(const struct _magic_type* type, 1115 int num_elements); 1116 PUBLIC void magic_type_parse_varsized_array(const struct _magic_type *type, 1117 const struct _magic_type **sub_struct_type, 1118 const struct _magic_type **sub_array_type, 1119 size_t *sub_array_offset, 1120 size_t *sub_array_size); 1121 1122 /* Magic type walk functions. */ 1123 typedef int (*magic_type_walk_cb_t)(const struct _magic_type*, unsigned, int, 1124 const struct _magic_type*, const unsigned, int, void*); 1125 PUBLIC int magic_type_walk_flags(const struct _magic_type* parent_type, 1126 unsigned parent_offset, int child_num, const struct _magic_type* type, 1127 unsigned offset, const unsigned min_offset, const unsigned max_offset, 1128 const magic_type_walk_cb_t cb, void* cb_args, int flags); 1129 PUBLIC int magic_type_target_walk(void* target, 1130 struct _magic_dsentry** trg_dsentry, 1131 struct _magic_dfunction** trg_dfunction, 1132 const magic_type_walk_cb_t cb, void* cb_args); 1133 PUBLIC int magic_type_walk_as_void_array(const struct _magic_type* parent_type, 1134 unsigned parent_offset, int child_num, const struct _magic_type* type, 1135 unsigned offset, const unsigned min_offset, const unsigned max_offset, 1136 const magic_type_walk_cb_t cb, void* cb_args); 1137 PUBLIC int 1138 magic_type_walk_as_ptrint_array(const struct _magic_type* parent_type, 1139 unsigned parent_offset, int child_num, const struct _magic_type* type, 1140 void* offset_addr, unsigned offset, const unsigned min_offset, 1141 const unsigned max_offset, const magic_type_walk_cb_t cb, void* cb_args); 1142 PUBLIC void magic_type_walk_step(const struct _magic_type *type, 1143 int child_num, const struct _magic_type **child_type, 1144 unsigned *child_offset, int walk_flags); 1145 1146 /* Magic type walk callbacks. */ 1147 PUBLIC int magic_type_str_print_cb(const struct _magic_type* parent_type, 1148 const unsigned parent_offset, int child_num, const struct _magic_type* type, 1149 const unsigned offset, int depth, void* cb_args); 1150 PUBLIC int magic_selement_name_print_cb(const struct _magic_type* parent_type, 1151 const unsigned parent_offset, int child_num, const struct _magic_type* type, 1152 const unsigned offset, int depth, void* cb_args); 1153 PUBLIC int magic_selement_name_get_cb(const struct _magic_type *parent_type, 1154 const unsigned parent_offset, int child_num, const struct _magic_type *type, 1155 const unsigned offset, int depth, void *args_array); 1156 PUBLIC int magic_type_count_cb(const struct _magic_type* parent_type, 1157 const unsigned parent_offset, int child_num, const struct _magic_type* type, 1158 const unsigned offset, int depth, void* cb_args); 1159 PUBLIC int magic_type_child_offset_cb(const struct _magic_type* parent_type, 1160 const unsigned parent_offset, int child_num, const struct _magic_type* type, 1161 const unsigned offset, int depth, void* cb_args); 1162 1163 ) 1164 1165 /* Magic type walk helpers. */ 1166 #define magic_type_walk(parent_type, parent_offset, child_num, type, offset, \ 1167 min_offset, max_offset, cb, cb_args) \ 1168 magic_type_walk_flags(parent_type, parent_offset, child_num, type, offset, \ 1169 min_offset, max_offset, cb, cb_args, MAGIC_TYPE_WALK_DEFAULT_FLAGS) 1170 #define magic_type_walk_root(type, min_offset, max_offset, cb, cb_args) \ 1171 magic_type_walk(NULL, 0, 0, type, 0, min_offset, max_offset, cb, cb_args) 1172 #define magic_type_walk_root_at_offset(type, offset, cb, cb_args) \ 1173 magic_type_walk_root(type, offset, offset, cb, cb_args) 1174 #define magic_type_walk_root_all(type, cb, cb_args) \ 1175 magic_type_walk_root(type, 0, ULONG_MAX, cb, cb_args) 1176 1177 /* Magic size functions. */ 1178 PUBLIC size_t magic_type_get_size(struct _magic_type *type, int flags); 1179 PUBLIC size_t magic_types_get_size(int flags); 1180 PUBLIC size_t magic_function_get_size(struct _magic_function *function, 1181 int flags); 1182 PUBLIC size_t magic_functions_get_size(int flags); 1183 PUBLIC size_t magic_dfunctions_get_size(int flags); 1184 PUBLIC size_t magic_sentry_get_size(struct _magic_sentry *sentry, int flags); 1185 PUBLIC size_t magic_sentries_get_size(int flags); 1186 PUBLIC size_t magic_dsentries_get_size(int flags); 1187 PUBLIC size_t magic_dsindex_get_size(struct _magic_dsindex *dsindex, 1188 int flags); 1189 PUBLIC size_t magic_dsindexes_get_size(int flags); 1190 PUBLIC size_t magic_sodesc_get_size(struct _magic_sodesc *sodesc, 1191 int flags); 1192 PUBLIC size_t magic_sodescs_get_size(int flags); 1193 PUBLIC size_t magic_dsodesc_get_size(struct _magic_dsodesc *dsodesc, 1194 int flags); 1195 PUBLIC size_t magic_dsodescs_get_size(int flags); 1196 PUBLIC size_t magic_metadata_get_size(int flags); 1197 PUBLIC size_t magic_sentries_data_get_size(int flags); 1198 PUBLIC size_t magic_dsentries_data_get_size(int flags); 1199 PUBLIC size_t magic_other_data_get_size(int flags); 1200 PUBLIC size_t magic_data_get_size(int flags); 1201 PUBLIC void magic_print_size_stats(int flags); 1202 1203 #define MAGIC_SIZE_VALUE_SET 0x0001 1204 #define MAGIC_SIZE_NAMES 0x0002 1205 #define MAGIC_SIZE_DSENTRY_NAMES 0x0004 1206 #define MAGIC_SIZE_DSINDEX_NAMES 0x0008 1207 #define MAGIC_SIZE_TYPE_NAMES 0x0010 1208 #define MAGIC_SIZE_MEMBER_NAMES 0x0020 1209 #define MAGIC_SIZE_COMP_TYPES 0x0040 1210 #define MAGIC_SIZE_ALL (MAGIC_SIZE_VALUE_SET | MAGIC_SIZE_NAMES | \ 1211 MAGIC_SIZE_DSENTRY_NAMES | MAGIC_SIZE_DSINDEX_NAMES | MAGIC_SIZE_TYPE_NAMES\ 1212 | MAGIC_SIZE_MEMBER_NAMES | MAGIC_SIZE_COMP_TYPES) 1213 1214 #endif 1215 1216 /* Magic reentrant functions. */ 1217 PUBLIC void magic_reentrant_enable(void); 1218 PUBLIC void magic_reentrant_disable(void); 1219