1 #include <magic.h> 2 #include <magic_mem.h> 3 #include <magic_asr.h> 4 #include <magic_eval.h> 5 #include <magic_analysis.h> 6 #include <magic_splay_tree.h> 7 #include <stdarg.h> 8 #if MAGIC_MEM_USAGE_OUTPUT_CTL 9 #include <common/util/time.h> 10 #endif 11 12 /* Workaround for extern-only structs. */ 13 #ifndef __MINIX 14 #include <stdio.h> 15 EXTERN FILE *stdout; 16 PUBLIC FILE **UNUSED(_____magic_instr_FILE_unused) = &stdout; 17 18 #include <ncurses.h> 19 PUBLIC WINDOW *UNUSED(_____magic_instr_WINDOW_unused); 20 #endif 21 22 #include <netinet/in.h> 23 PUBLIC struct in6_addr *UNUSED(_____magic_instr_in6_addr_unused); 24 25 /* Magic printf. */ 26 MAGIC_VAR printf_ptr_t _magic_printf = MAGIC_PRINTF_DEFAULT; 27 28 /* Magic lock primitives. */ 29 PUBLIC magic_lock_t magic_dsentry_lock = NULL; 30 PUBLIC magic_unlock_t magic_dsentry_unlock = NULL; 31 PUBLIC void *magic_dsentry_lock_args = NULL; 32 PUBLIC void *magic_dsentry_unlock_args = NULL; 33 34 PUBLIC magic_lock_t magic_dfunction_lock = NULL; 35 PUBLIC magic_unlock_t magic_dfunction_unlock = NULL; 36 PUBLIC void *magic_dfunction_lock_args = NULL; 37 PUBLIC void *magic_dfunction_unlock_args = NULL; 38 39 PUBLIC magic_lock_t magic_dsodesc_lock = NULL; 40 PUBLIC magic_unlock_t magic_dsodesc_unlock = NULL; 41 PUBLIC void *magic_dsodesc_lock_args = NULL; 42 PUBLIC void *magic_dsodesc_unlock_args = NULL; 43 44 PUBLIC magic_lock_t magic_mpdesc_lock = NULL; 45 PUBLIC magic_unlock_t magic_mpdesc_unlock = NULL; 46 PUBLIC void *magic_mpdesc_lock_args = NULL; 47 PUBLIC void *magic_mpdesc_unlock_args = NULL; 48 49 /* Magic vars references. */ 50 MAGIC_VAR struct _magic_vars_t _magic_vars_buff = { 51 52 /* Address Space Randomization (ASRPass) */ 53 0, /* asr_seed */ 54 0, /* asr_heap_map_do_permutate */ 55 0, /* asr_heap_max_offset */ 56 0, /* asr_heap_max_padding */ 57 0, /* asr_map_max_offset_pages */ 58 0, /* asr_map_max_padding_pages */ 59 60 /* Runtime flags. */ 61 0, /* no_mem_inst */ 62 63 /* Magic type array. */ 64 NULL, /* types */ 65 0, /* types_num */ 66 0, /* types_next_id */ 67 68 /* Magic function array. */ 69 NULL, /* functions */ 70 0, /* functions_num */ 71 0, /* functions_next_id */ 72 73 /* Magic state entry array. */ 74 NULL, /* sentries */ 75 0, /* sentries_num */ 76 0, /* sentries_str_num */ 77 0, /* sentries_next_id */ 78 79 /* Magic dynamic state index array. */ 80 NULL, /* dsindexes */ 81 0, /* dsindexes_num */ 82 83 /* Magic dynamic state entry list. */ 84 NULL, /* first_dsentry */ 85 0, /* num_dead_sentries */ 86 0, /* size_dead_dsentries */ 87 88 /* Magic memory pool dynamic state entry list. */ 89 NULL, /* first_mempool_dsentry */ 90 91 /* Magic dynamic function list. */ 92 NULL, /* first_dfunction */ 93 NULL, /* last_dfunction */ 94 0, /* dfunctions_num */ 95 96 /* Magic SO library descriptor list. */ 97 NULL, /* first_sodesc */ 98 NULL, /* last_sodesc */ 99 0, /* sodescs_num */ 100 101 /* Magic DSO library descriptor list. */ 102 NULL, /* first_dsodesc */ 103 NULL, /* last_dsodesc */ 104 0, /* dsodescs_num */ 105 106 /* Magic stack-related variables. */ 107 NULL, /* first_stack_dsentry */ 108 NULL, /* last_stack_dsentry */ 109 110 /* Magic memory ranges */ 111 112 { (void*) ULONG_MAX, (void*) 0 }, /* *null_range[2] */ 113 {0,0}, /* *data_range[2] */ 114 {0,0}, /* *heap_range[2] */ 115 {0,0}, /* *map_range[2] */ 116 {0,0}, /* *shm_range[2] */ 117 {0,0}, /* *stack_range[2] */ 118 {0,0}, /* *text_range[2] */ 119 120 {0,0}, /* *sentry_range[2] */ 121 {0,0}, /* *function_range[2] */ 122 {0,0}, /* *dfunction_range[2] */ 123 124 NULL, /* *heap_start */ 125 NULL, /* *heap_end */ 126 1, /* update_dsentry_ranges */ 127 1, /* update_dfunction_ranges */ 128 129 #ifdef __MINIX 130 { { NULL, 0 } }, /* unmap_mem */ 131 #endif 132 133 NULL, /* sentry_rl_buff */ 134 0, /* sentry_rl_buff_offset */ 135 0, /* sentry_rl_buff_size */ 136 NULL, /* sentry_rl_index */ 137 138 NULL, /* sentry_hash_buff */ 139 0, /* sentry_hash_buff_offset */ 140 0, /* sentry_hash_buff_size */ 141 NULL, /* sentry_hash_head */ 142 143 NULL, /* function_hash_buff */ 144 0, /* function_hash_buff_offset */ 145 0, /* function_hash_buff_size */ 146 NULL, /* function_hash_head */ 147 148 0 /* fake_malloc */ 149 }; 150 151 PUBLIC struct _magic_vars_t *_magic_vars = &_magic_vars_buff; 152 153 /* Magic void ptr and array (force at the least 1 void* and 1 void array in the list of globals). */ 154 PUBLIC void* MAGIC_VOID_PTR = NULL; 155 PUBLIC char MAGIC_VOID_ARRAY[1]; 156 157 /* Magic special types. */ 158 MAGIC_VAR struct _magic_type *MAGIC_VOID_PTR_TYPE = NULL; 159 MAGIC_VAR struct _magic_type *MAGIC_VOID_PTR_INT_CAST_TYPE = NULL; 160 MAGIC_VAR struct _magic_type *MAGIC_VOID_ARRAY_TYPE = NULL; 161 MAGIC_VAR struct _magic_type *MAGIC_PTRINT_TYPE = NULL; 162 MAGIC_VAR struct _magic_type *MAGIC_PTRINT_ARRAY_TYPE = NULL; 163 164 /* Magic annotations. */ 165 MAGIC_VAR VOLATILE int MAGIC_CALL_ANNOTATION_VAR; 166 167 /* Magic status variables. */ 168 PUBLIC int magic_init_done = 0; 169 PUBLIC int magic_libcommon_active = 0; 170 PUBLIC int magic_lookup_nested_dsentries = 1; 171 PUBLIC int magic_allow_dead_dsentries = MAGIC_ALLOW_DEAD_DSENTRIES_DEFAULT; 172 PUBLIC int magic_ignore_dead_dsentries = 0; 173 PUBLIC int magic_mmap_dsentry_header_prot = PROT_READ | PROT_WRITE; 174 MAGIC_VAR int _magic_enabled = 0; 175 MAGIC_VAR int _magic_checkpoint_enabled = 0; 176 MAGIC_VAR int _magic_lazy_checkpoint_enabled = 0; 177 178 /* Magic out-of-band dsentries. */ 179 PUBLIC struct _magic_obdsentry _magic_obdsentries[MAGIC_MAX_OBDSENTRIES]; 180 181 /* Pool management data. */ 182 PUBLIC struct _magic_mpdesc _magic_mpdescs[MAGIC_MAX_MEMPOOLS]; 183 184 /* Magic page size. */ 185 PUBLIC unsigned long magic_sys_pagesize = 0; 186 187 /* Private variables. */ 188 PUBLIC int magic_type_str_print_style = MAGIC_TYPE_STR_PRINT_STYLE_DEFAULT; 189 PRIVATE THREAD_LOCAL const struct _magic_type* magic_nested_types[MAGIC_MAX_RECURSIVE_TYPES] = {0}; 190 PRIVATE THREAD_LOCAL const struct _magic_type* magic_nested_types2[MAGIC_MAX_RECURSIVE_TYPES] = {0}; 191 PRIVATE THREAD_LOCAL unsigned magic_level = 0; 192 PRIVATE THREAD_LOCAL unsigned magic_counter; 193 PRIVATE THREAD_LOCAL struct _magic_dsentry magic_dsentry_buff; 194 PRIVATE THREAD_LOCAL struct _magic_dfunction magic_dfunction_buff; 195 196 /* Magic default stubs. */ 197 PUBLIC struct _magic_type magic_default_type = { 198 0, "", NULL, 0, "", 0, 0, NULL, NULL, NULL, NULL, NULL, MAGIC_TYPE_OPAQUE, 0, 0, NULL 199 }; 200 201 PUBLIC struct _magic_dsentry magic_default_dsentry = { 202 MAGIC_DSENTRY_MNUM, /* magic_number */ 203 "", /* parent_name */ 204 { 0 }, /* name_ext_buff */ 205 { 0, "", NULL, MAGIC_STATE_DYNAMIC, NULL, NULL }, /* sentry */ 206 { 0, "", NULL, 0, "", 0, 0, NULL, NULL, NULL, NULL, NULL, MAGIC_TYPE_ARRAY, MAGIC_TYPE_IS_ROOT|MAGIC_TYPE_DYNAMIC, 0, NULL }, /* type */ 207 { NULL }, /* type_array */ 208 #if MAGIC_DSENTRY_ALLOW_PREV 209 NULL, /* prev */ 210 #endif 211 NULL, /* next */ 212 NULL, /* next_mpool */ 213 NULL, /* next_mblock */ 214 #ifndef __MINIX 215 NULL, /* next_sobject */ 216 NULL, /* sobject_base_addr */ 217 #endif 218 NULL, /* ext */ 219 MAGIC_DSENTRY_MSTATE_ALIVE, /* magic_state */ 220 { { 0, 0 } }, /* alloc_flags */ 221 0 /* site_id */ 222 }; 223 224 PUBLIC struct _magic_dfunction magic_default_dfunction = { 225 MAGIC_DFUNCTION_MNUM, 226 "", 227 { 0, "", NULL, MAGIC_STATE_DYNAMIC|MAGIC_STATE_TEXT|MAGIC_STATE_CONSTANT, NULL }, 228 NULL, 229 NULL 230 }; 231 232 PUBLIC struct _magic_type magic_default_ret_addr_type = { 233 0, "", NULL, 0, "", sizeof(void*), 1, NULL, NULL, NULL, NULL, NULL, MAGIC_TYPE_POINTER, MAGIC_TYPE_IS_ROOT|MAGIC_TYPE_DYNAMIC|MAGIC_TYPE_INT_CAST|MAGIC_TYPE_STRICT_VALUE_SET, 0, NULL 234 }; 235 236 /* Magic code reentrant flag. */ 237 PRIVATE int magic_reentrant = 1; 238 239 /*===========================================================================* 240 * _magic_vars_addr * 241 *===========================================================================*/ 242 void *_magic_vars_addr() 243 { 244 return _magic_vars; 245 } 246 247 /*===========================================================================* 248 * _magic_vars_size * 249 *===========================================================================*/ 250 size_t _magic_vars_size() 251 { 252 return sizeof(struct _magic_vars_t); 253 } 254 255 /*===========================================================================* 256 * magic_null_printf * 257 *===========================================================================*/ 258 PUBLIC int magic_null_printf(const char *format, ...) 259 { 260 return 0; 261 } 262 263 #ifndef __MINIX 264 /*===========================================================================* 265 * magic_err_printf * 266 *===========================================================================*/ 267 PUBLIC int magic_err_printf(const char *format, ...) 268 { 269 va_list va; 270 int ret; 271 va_start(va, format); 272 ret = vfprintf(stderr, format, va); 273 va_end(va); 274 275 return ret; 276 } 277 #endif 278 279 /*===========================================================================* 280 * magic_set_printf * 281 *===========================================================================*/ 282 PUBLIC void magic_set_printf(printf_ptr_t func_ptr) 283 { 284 assert(func_ptr); 285 _magic_printf = func_ptr; 286 } 287 288 /*===========================================================================* 289 * magic_get_printf * 290 *===========================================================================*/ 291 PUBLIC printf_ptr_t magic_get_printf(void) 292 { 293 return _magic_printf; 294 } 295 296 /*===========================================================================* 297 * magic_reentrant_enable * 298 *===========================================================================*/ 299 PUBLIC void magic_reentrant_enable(void) 300 { 301 magic_reentrant = 1; 302 } 303 /*===========================================================================* 304 * magic_reentrant_disable * 305 *===========================================================================*/ 306 PUBLIC void magic_reentrant_disable(void) 307 { 308 magic_reentrant = 0; 309 } 310 311 /*===========================================================================* 312 * magic_assert_failed * 313 *===========================================================================*/ 314 PUBLIC void __dead magic_assert_failed(const char *assertion, const char *file, 315 const char *function, const int line) 316 { 317 _magic_printf("Assertion '%s' failed in file %s, function %s(), line %d, pid %d\n", 318 assertion, file, function, line, getpid()); 319 abort(); 320 } 321 322 /*===========================================================================* 323 * magic_get_sys_pagesize * 324 *===========================================================================*/ 325 PUBLIC unsigned long magic_get_sys_pagesize() 326 { 327 if(!magic_sys_pagesize) { 328 magic_sys_pagesize = SYS_PAGESIZE; 329 } 330 return magic_sys_pagesize; 331 } 332 333 /*===========================================================================* 334 * magic_dsentry_set_lock_primitives * 335 *===========================================================================*/ 336 PUBLIC void magic_dsentry_set_lock_primitives(magic_lock_t lock, 337 magic_unlock_t unlock, void *lock_args, void *unlock_args) 338 { 339 assert(lock && unlock); 340 magic_dsentry_lock = lock; 341 magic_dsentry_unlock = unlock; 342 magic_dsentry_lock_args = lock_args; 343 magic_dsentry_unlock_args = unlock_args; 344 } 345 346 /*===========================================================================* 347 * magic_dfunction_set_lock_primitives * 348 *===========================================================================*/ 349 PUBLIC void magic_dfunction_set_lock_primitives(magic_lock_t lock, 350 magic_unlock_t unlock, void *lock_args, void *unlock_args) 351 { 352 assert(lock && unlock); 353 magic_dfunction_lock = lock; 354 magic_dfunction_unlock = unlock; 355 magic_dfunction_lock_args = lock_args; 356 magic_dfunction_unlock_args = unlock_args; 357 } 358 359 /*===========================================================================* 360 * magic_dsodesc_set_lock_primitives * 361 *===========================================================================*/ 362 PUBLIC void magic_dsodesc_set_lock_primitives(magic_lock_t lock, 363 magic_unlock_t unlock, void *lock_args, void *unlock_args) 364 { 365 assert(lock && unlock); 366 magic_dsodesc_lock = lock; 367 magic_dsodesc_unlock = unlock; 368 magic_dsodesc_lock_args = lock_args; 369 magic_dsodesc_unlock_args = unlock_args; 370 } 371 372 /*===========================================================================* 373 * magic_mpdesc_set_lock_primitives * 374 *===========================================================================*/ 375 PUBLIC void magic_mpdesc_set_lock_primitives(magic_lock_t lock, 376 magic_unlock_t unlock, void *lock_args, void *unlock_args) 377 { 378 assert(lock && unlock); 379 magic_mpdesc_lock = lock; 380 magic_mpdesc_unlock = unlock; 381 magic_mpdesc_lock_args = lock_args; 382 magic_mpdesc_unlock_args = unlock_args; 383 } 384 385 /*===========================================================================* 386 * magic_types_init * 387 *===========================================================================*/ 388 PRIVATE void magic_types_init() 389 { 390 static struct _magic_type _magic_void_ptr_type_buff; 391 static struct _magic_type _magic_void_array_type_buff; 392 static struct _magic_type *_magic_void_array_type_contained_types[1]; 393 static struct _magic_type _magic_ptrint_type_buff; 394 static const char* _magic_ptrint_type_name = "ptrint"; 395 static char _magic_ptrint_type_str_buff[8]; 396 static struct _magic_type _magic_ptrint_array_type_buff; 397 static struct _magic_type *_magic_ptrint_array_type_contained_types[1]; 398 399 assert(MAGIC_VOID_PTR_TYPE); 400 assert(MAGIC_VOID_PTR_TYPE->size == sizeof(void*)); 401 assert(MAGIC_VOID_TYPE->size == sizeof(char)); 402 403 MAGIC_VOID_PTR_INT_CAST_TYPE = &_magic_void_ptr_type_buff; 404 *MAGIC_VOID_PTR_INT_CAST_TYPE = *MAGIC_VOID_PTR_TYPE; 405 MAGIC_VOID_PTR_INT_CAST_TYPE->flags |= MAGIC_TYPE_INT_CAST; 406 407 MAGIC_VOID_ARRAY_TYPE = &_magic_void_array_type_buff; 408 *MAGIC_VOID_ARRAY_TYPE = magic_default_type; 409 MAGIC_TYPE_ARRAY_CREATE_FROM_N(MAGIC_VOID_ARRAY_TYPE, MAGIC_VOID_TYPE, 410 _magic_void_array_type_contained_types, 1); 411 412 MAGIC_PTRINT_TYPE = &_magic_ptrint_type_buff; 413 *MAGIC_PTRINT_TYPE = magic_default_type; 414 MAGIC_TYPE_INT_CREATE(MAGIC_PTRINT_TYPE, MAGIC_VOID_PTR_TYPE->size, 415 _magic_ptrint_type_name, _magic_ptrint_type_str_buff); 416 417 MAGIC_PTRINT_ARRAY_TYPE = &_magic_ptrint_array_type_buff; 418 *MAGIC_PTRINT_ARRAY_TYPE = magic_default_type; 419 MAGIC_TYPE_ARRAY_CREATE_FROM_N(MAGIC_PTRINT_ARRAY_TYPE, MAGIC_PTRINT_TYPE, 420 _magic_ptrint_array_type_contained_types, 1); 421 } 422 423 /*===========================================================================* 424 * magic_data_init * 425 *===========================================================================*/ 426 MAGIC_FUNC void magic_data_init(void) 427 { 428 MAGIC_FUNC_BODY(); 429 } 430 431 /*===========================================================================* 432 * magic_init * 433 *===========================================================================*/ 434 PUBLIC void magic_init(void) 435 { 436 unsigned i; 437 438 if(magic_init_done || !_magic_enabled) { 439 return; 440 } 441 442 /* Initialize magic data structures first. */ 443 magic_data_init(); 444 445 /* Initialize asr support. */ 446 magic_asr_init(); 447 448 /* Initialize eval support. */ 449 magic_eval_init(); 450 451 /* Initialize magic obdsentries. */ 452 memset(_magic_obdsentries, 0, MAGIC_MAX_OBDSENTRIES * sizeof(struct _magic_obdsentry)); 453 454 /* Initialize memory pool descriptors. */ 455 for (i = 0; i < MAGIC_MAX_MEMPOOLS; i++) { 456 snprintf(_magic_mpdescs[i].name, sizeof(_magic_mpdescs[i].name), "%s%d%s", MAGIC_MEMPOOL_NAME_PREFIX, i, MAGIC_ALLOC_NAME_SUFFIX); 457 } 458 459 /* Initialize special types. */ 460 magic_types_init(); 461 462 /* Initialize magic ranges. */ 463 magic_ranges_init(); 464 465 /* Perform stack-related initialization. */ 466 magic_stack_init(); 467 468 #if MAGIC_MEM_USAGE_OUTPUT_CTL 469 /* Initialize CPU frequency - used for timestamp logging. */ 470 magic_cycles_per_ns = util_time_get_cycles_per_ns(1); 471 #endif 472 473 /* Checks. */ 474 assert(magic_check_sentries() && "Bad sentries!"); 475 assert(magic_check_dsentries_safe() && "Bad dsentries!"); 476 477 /* All done. */ 478 magic_init_done = 1; 479 } 480 481 /*===========================================================================* 482 * magic_do_check_dfunction * 483 *===========================================================================*/ 484 PRIVATE INLINE int magic_do_check_dfunction(struct _magic_dfunction *dfunction, int flags) 485 { 486 struct _magic_function *function; 487 int is_mnum_ok, is_flags_ok, is_prev_ok, is_next_ok; 488 assert(dfunction && "NULL dfunction found!"); 489 function = MAGIC_DFUNCTION_TO_FUNCTION(dfunction); 490 assert(function && "NULL function found!"); 491 is_mnum_ok = MAGIC_DFUNCTION_MNUM_OK(dfunction); 492 if(!is_mnum_ok) { 493 return FALSE; 494 } 495 is_flags_ok = ((function->flags & flags) == flags) && (function->flags & MAGIC_STATE_DYNAMIC) && (MAGIC_STATE_REGION(function) & MAGIC_STATE_TEXT); 496 is_prev_ok = (dfunction->prev ? dfunction->prev->next && dfunction->prev->next == dfunction : dfunction == _magic_first_dfunction); 497 is_next_ok = (dfunction->next ? dfunction->next->prev && dfunction->next->prev == dfunction : dfunction == _magic_last_dfunction); 498 if(!is_flags_ok || !is_prev_ok || !is_next_ok) { 499 _magic_printf("magic_do_check_dfunction: bad dfunction, checks: %d %d %d\n", is_flags_ok, is_prev_ok, is_next_ok); 500 MAGIC_DFUNCTION_PRINT(dfunction, MAGIC_EXPAND_TYPE_STR); 501 _magic_printf("\n"); 502 return FALSE; 503 } 504 return TRUE; 505 } 506 507 /*===========================================================================* 508 * magic_check_dfunction * 509 *===========================================================================*/ 510 PUBLIC int magic_check_dfunction(struct _magic_dfunction *dfunction, int flags) 511 { 512 int check; 513 check = magic_do_check_dfunction(dfunction, flags); 514 if(!check) { 515 return FALSE; 516 } 517 518 #if MAGIC_CHECK_LEVEL == 2 519 check = magic_check_dfunctions(); 520 if(!check) { 521 _magic_printf("magic_check_dfunction: bad other dfunction\n"); 522 return FALSE; 523 } 524 #endif 525 526 return TRUE; 527 } 528 529 /*===========================================================================* 530 * magic_check_dfunctions * 531 *===========================================================================*/ 532 PUBLIC int magic_check_dfunctions() 533 { 534 int magic_dfunctions_found = 0; 535 struct _magic_dfunction* dfunction = NULL; 536 struct _magic_function* function = NULL; 537 int ret, check = TRUE; 538 539 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function, 540 ret = magic_do_check_dfunction(dfunction, 0); 541 if(ret == FALSE) { 542 check = FALSE; 543 } 544 magic_dfunctions_found++; 545 ); 546 if(magic_dfunctions_found != _magic_dfunctions_num) { 547 _magic_printf("magic_check_dfunctions: magic_dfunctions_found=%d != _magic_dfunctions_num%d\n", magic_dfunctions_found, _magic_dfunctions_num); 548 check = FALSE; 549 } 550 if(dfunction != _magic_last_dfunction) { 551 _magic_printf("magic_check_dfunctions: dfunction=0x%08x != _magic_last_dfunction=0x%08x\n", dfunction, _magic_last_dfunction); 552 check = FALSE; 553 } 554 return check; 555 } 556 557 /*===========================================================================* 558 * magic_check_dfunctions_safe * 559 *===========================================================================*/ 560 PUBLIC int magic_check_dfunctions_safe() 561 { 562 int ret; 563 MAGIC_DFUNCTION_LOCK(); 564 ret = magic_check_dfunctions(); 565 MAGIC_DFUNCTION_UNLOCK(); 566 return ret; 567 } 568 569 /*===========================================================================* 570 * magic_print_dfunction * 571 *===========================================================================*/ 572 PUBLIC void magic_print_dfunction(struct _magic_dfunction *dfunction) 573 { 574 MAGIC_DFUNCTION_PRINT(dfunction, MAGIC_EXPAND_TYPE_STR); 575 } 576 577 /*===========================================================================* 578 * magic_print_dfunctions * 579 *===========================================================================*/ 580 PUBLIC void magic_print_dfunctions() 581 { 582 int magic_dfunctions_found = 0; 583 struct _magic_dfunction* dfunction; 584 struct _magic_function* function; 585 586 _magic_printf("magic_print_dfunctions: Printing %d functions\n", _magic_dfunctions_num); 587 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function, 588 MAGIC_DFUNCTION_PRINT(dfunction, MAGIC_EXPAND_TYPE_STR); 589 _magic_printf("\n"); 590 magic_dfunctions_found++; 591 ); 592 if(magic_dfunctions_found != _magic_dfunctions_num) { 593 _magic_printf("magic_print_dfunctions: magic_dfunctions_found=%d != _magic_dfunctions_num%d\n", magic_dfunctions_found, _magic_dfunctions_num); 594 } 595 } 596 597 /*===========================================================================* 598 * magic_print_dfunctions_safe * 599 *===========================================================================*/ 600 PUBLIC void magic_print_dfunctions_safe() 601 { 602 MAGIC_DFUNCTION_LOCK(); 603 magic_print_dfunctions(); 604 MAGIC_DFUNCTION_UNLOCK(); 605 } 606 607 /*===========================================================================* 608 * magic_copy_dfunction * 609 *===========================================================================*/ 610 PUBLIC void magic_copy_dfunction(struct _magic_dfunction *dfunction, 611 struct _magic_dfunction *dst_dfunction) 612 { 613 /* Raw copy. */ 614 memcpy(dst_dfunction, dfunction, sizeof(struct _magic_dfunction)); 615 } 616 617 /*===========================================================================* 618 * magic_print_dsindex * 619 *===========================================================================*/ 620 PUBLIC void magic_print_dsindex(struct _magic_dsindex *dsindex) 621 { 622 MAGIC_DSINDEX_PRINT(dsindex, MAGIC_EXPAND_TYPE_STR); 623 } 624 625 /*===========================================================================* 626 * magic_print_dsindexes * 627 *===========================================================================*/ 628 PUBLIC void magic_print_dsindexes() 629 { 630 int i; 631 struct _magic_dsindex* dsindex; 632 633 _magic_printf("magic_print_dsindexes: Printing %d indexes\n", _magic_dsindexes_num); 634 for(i=0;i<_magic_dsindexes_num;i++) { 635 dsindex = &_magic_dsindexes[i]; 636 MAGIC_DSINDEX_PRINT(dsindex, MAGIC_EXPAND_TYPE_STR); 637 _magic_printf("\n"); 638 } 639 } 640 641 /*===========================================================================* 642 * magic_do_check_dsentry * 643 *===========================================================================*/ 644 PRIVATE INLINE int magic_do_check_dsentry(struct _magic_dsentry *dsentry, int flags) 645 { 646 struct _magic_sentry *sentry; 647 int is_mnum_ok, is_mstate_ok, is_flags_ok; 648 assert(dsentry && "NULL dsentry found!"); 649 sentry = MAGIC_DSENTRY_TO_SENTRY(dsentry); 650 assert(sentry && "NULL sentry found!"); 651 is_mnum_ok = MAGIC_DSENTRY_MNUM_OK(dsentry); 652 if(!is_mnum_ok) { 653 _magic_printf("magic_do_check_dsentry: bad ~mnum %08x\n", ~(dsentry->magic_number)); 654 return FALSE; 655 } 656 is_mstate_ok = MAGIC_DSENTRY_MSTATE_OK(dsentry); 657 is_flags_ok = ((sentry->flags & flags) == flags) && (sentry->flags & MAGIC_STATE_DYNAMIC) && MAGIC_STATE_REGION(sentry); 658 if(!is_mstate_ok || !is_flags_ok) { 659 _magic_printf("magic_do_check_dsentry: bad dsentry, checks: %d %d\n", is_mstate_ok, is_flags_ok); 660 MAGIC_DSENTRY_PRINT(dsentry, MAGIC_EXPAND_TYPE_STR); 661 _magic_printf("\n"); 662 return FALSE; 663 } 664 return TRUE; 665 } 666 667 /*===========================================================================* 668 * magic_check_dsentry * 669 *===========================================================================*/ 670 PUBLIC int magic_check_dsentry(struct _magic_dsentry *dsentry, int flags) 671 { 672 #if MAGIC_CHECK_LEVEL >= 1 673 int check; 674 check = magic_do_check_dsentry(dsentry, flags); 675 if(!check) { 676 return FALSE; 677 } 678 #endif 679 680 #if MAGIC_CHECK_LEVEL == 2 681 check = magic_check_dsentries(); 682 if(!check) { 683 _magic_printf("magic_check_dsentry: bad other dsentry\n"); 684 return FALSE; 685 } 686 #endif 687 688 return TRUE; 689 } 690 691 /*===========================================================================* 692 * magic_check_dsentries * 693 *===========================================================================*/ 694 PUBLIC int magic_check_dsentries() 695 { 696 struct _magic_dsentry *prev_dsentry, *dsentry; 697 struct _magic_sentry* sentry; 698 int ret, check = TRUE; 699 700 MAGIC_DSENTRY_NESTED_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry, 701 ret = magic_do_check_dsentry(dsentry, 0); 702 if(ret == FALSE) { 703 check = FALSE; 704 } 705 ); 706 return check; 707 } 708 709 /*===========================================================================* 710 * magic_check_dsentries_safe * 711 *===========================================================================*/ 712 PUBLIC int magic_check_dsentries_safe() 713 { 714 int ret; 715 MAGIC_DSENTRY_LOCK(); 716 ret = magic_check_dsentries(); 717 MAGIC_DSENTRY_UNLOCK(); 718 return ret; 719 } 720 721 /*===========================================================================* 722 * magic_print_dsentry * 723 *===========================================================================*/ 724 PUBLIC void magic_print_dsentry(struct _magic_dsentry *dsentry) 725 { 726 MAGIC_DSENTRY_PRINT(dsentry, MAGIC_EXPAND_TYPE_STR); 727 } 728 729 /*===========================================================================* 730 * magic_print_dsentries * 731 *===========================================================================*/ 732 PUBLIC void magic_print_dsentries() 733 { 734 struct _magic_dsentry *prev_dsentry, *dsentry; 735 struct _magic_sentry* sentry; 736 int magic_dsentries_num = 0; 737 738 _magic_printf("magic_print_dsentries: Printing entries\n"); 739 MAGIC_DSENTRY_NESTED_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry, 740 MAGIC_DSENTRY_PRINT(dsentry, MAGIC_EXPAND_TYPE_STR); 741 _magic_printf("\n"); 742 magic_dsentries_num++; 743 ); 744 _magic_printf("magic_print_dsentries: %d entries found\n", magic_dsentries_num); 745 } 746 747 /*===========================================================================* 748 * magic_print_dsentries_safe * 749 *===========================================================================*/ 750 PUBLIC void magic_print_dsentries_safe() 751 { 752 MAGIC_DSENTRY_LOCK(); 753 magic_print_dsentries(); 754 MAGIC_DSENTRY_UNLOCK(); 755 } 756 757 /*===========================================================================* 758 * magic_copy_dsentry * 759 *===========================================================================*/ 760 PUBLIC void magic_copy_dsentry(struct _magic_dsentry *dsentry, 761 struct _magic_dsentry *dst_dsentry) 762 { 763 struct _magic_sentry *sentry; 764 765 /* Raw copy. */ 766 memcpy(dst_dsentry, dsentry, sizeof(struct _magic_dsentry)); 767 768 /* Adjust pointers. */ 769 sentry = MAGIC_DSENTRY_TO_SENTRY(dsentry); 770 if(sentry->type == &dsentry->type) { 771 MAGIC_DSENTRY_TO_SENTRY(dst_dsentry)->type = &dst_dsentry->type; 772 if(sentry->type->contained_types == dsentry->type_array) { 773 MAGIC_DSENTRY_TO_SENTRY(dst_dsentry)->type->contained_types = dst_dsentry->type_array; 774 } 775 } 776 } 777 778 /*===========================================================================* 779 * magic_print_sodesc * 780 *===========================================================================*/ 781 PUBLIC void magic_print_sodesc(struct _magic_sodesc *sodesc) 782 { 783 MAGIC_SODESC_PRINT(sodesc); 784 } 785 786 /*===========================================================================* 787 * magic_print_sodescs * 788 *===========================================================================*/ 789 PUBLIC void magic_print_sodescs() 790 { 791 int magic_sodescs_found = 0; 792 struct _magic_sodesc* sodesc; 793 794 _magic_printf("magic_print_sodescs: Printing %d sodescs\n", _magic_sodescs_num); 795 MAGIC_SODESC_ITER(_magic_first_sodesc, sodesc, 796 MAGIC_SODESC_PRINT(sodesc); 797 _magic_printf("\n"); 798 magic_sodescs_found++; 799 ); 800 if(magic_sodescs_found != _magic_sodescs_num) { 801 _magic_printf("magic_print_sodescs: magic_sodescs_found=%d != _magic_sodescs_num%d\n", magic_sodescs_found, _magic_sodescs_num); 802 } 803 } 804 805 /*===========================================================================* 806 * magic_print_dsodesc * 807 *===========================================================================*/ 808 PUBLIC void magic_print_dsodesc(struct _magic_dsodesc *dsodesc) 809 { 810 MAGIC_DSODESC_PRINT(dsodesc); 811 } 812 813 /*===========================================================================* 814 * magic_print_dsodescs * 815 *===========================================================================*/ 816 PUBLIC void magic_print_dsodescs() 817 { 818 int magic_dsodescs_found = 0; 819 struct _magic_dsodesc* dsodesc; 820 821 _magic_printf("magic_print_dsodescs: Printing %d dsodescs\n", _magic_dsodescs_num); 822 MAGIC_DSODESC_ITER(_magic_first_dsodesc, dsodesc, 823 MAGIC_DSODESC_PRINT(dsodesc); 824 _magic_printf("\n"); 825 magic_dsodescs_found++; 826 ); 827 if(magic_dsodescs_found != _magic_dsodescs_num) { 828 _magic_printf("magic_print_dsodescs: magic_dsodescs_found=%d != _magic_dsodescs_num%d\n", magic_dsodescs_found, _magic_dsodescs_num); 829 } 830 } 831 832 /*===========================================================================* 833 * magic_print_dsodescs_safe * 834 *===========================================================================*/ 835 PUBLIC void magic_print_dsodescs_safe() 836 { 837 MAGIC_DSODESC_LOCK(); 838 magic_print_dsodescs(); 839 MAGIC_DSODESC_UNLOCK(); 840 } 841 842 /*===========================================================================* 843 * magic_print_sections * 844 *===========================================================================*/ 845 PUBLIC void magic_print_sections(void) 846 { 847 _magic_printf("magic_print_sections: data=[0x%08x;0x%08x], ro=[0x%08x;0x%08x], text=[0x%08x;0x%08x], st_data=[0x%08x;0x%08x], st_ro=[0x%08x;0x%08x], st_text=[0x%08x;0x%08x]", 848 (unsigned long) MAGIC_DATA_SECTION_START, (unsigned long) MAGIC_DATA_SECTION_END, 849 (unsigned long) MAGIC_DATA_RO_SECTION_START, (unsigned long) MAGIC_DATA_RO_SECTION_END, 850 (unsigned long) MAGIC_TEXT_SECTION_START, (unsigned long) MAGIC_TEXT_SECTION_END, 851 (unsigned long) MAGIC_ST_DATA_SECTION_START, (unsigned long) MAGIC_ST_DATA_SECTION_END, 852 (unsigned long) MAGIC_ST_DATA_RO_SECTION_START, (unsigned long) MAGIC_ST_DATA_RO_SECTION_END, 853 (unsigned long) MAGIC_ST_TEXT_SECTION_START, (unsigned long) MAGIC_ST_TEXT_SECTION_END); 854 } 855 856 /*===========================================================================* 857 * magic_mempool_sentry_lookup_by_addr * 858 *===========================================================================*/ 859 PUBLIC struct _magic_sentry* magic_mempool_sentry_lookup_by_range(void *addr, struct _magic_dsentry *dsentry_buff) 860 { 861 struct _magic_dsentry *prev_dsentry, *dsentry; 862 struct _magic_sentry* sentry; 863 struct _magic_sentry* entry = NULL; 864 void *start_address, *end_address; 865 866 MAGIC_DSENTRY_LOCK(); 867 MAGIC_DSENTRY_MEMPOOL_ALIVE_ITER(_magic_first_mempool_dsentry, prev_dsentry, dsentry, sentry, 868 start_address = sentry->address; 869 end_address = (void*) (((char*)sentry->address) + sentry->type->size - 1); 870 if(MAGIC_ADDR_IS_WITHIN(addr, start_address, end_address)) { 871 if(dsentry_buff) { 872 magic_copy_dsentry(dsentry, dsentry_buff); 873 entry = MAGIC_DSENTRY_TO_SENTRY(dsentry_buff); 874 } 875 else { 876 entry = sentry; 877 } 878 break; 879 } 880 ); 881 MAGIC_DSENTRY_UNLOCK(); 882 883 return entry; 884 } 885 886 /*===========================================================================* 887 * magic_dsindex_lookup_by_name * 888 *===========================================================================*/ 889 PUBLIC struct _magic_dsindex* 890 magic_dsindex_lookup_by_name(const char *parent_name, const char *name) 891 { 892 int i; 893 struct _magic_dsindex* index = NULL; 894 assert(parent_name && name); 895 896 /* Scan all the indexes and return the one matching the provided names. */ 897 for(i=0;i<_magic_dsindexes_num;i++) { 898 if(!strcmp(_magic_dsindexes[i].parent_name, parent_name) 899 && !strcmp(_magic_dsindexes[i].name, name)) { 900 index = &_magic_dsindexes[i]; 901 break; 902 } 903 } 904 905 return index; 906 } 907 908 /*===========================================================================* 909 * magic_dsentry_prev_lookup * 910 *===========================================================================*/ 911 PUBLIC struct _magic_dsentry* magic_dsentry_prev_lookup(struct _magic_dsentry* dsentry) 912 { 913 struct _magic_dsentry *prev_dsentry, *it_dsentry; 914 struct _magic_sentry *sentry; 915 int found = 0; 916 917 #if MAGIC_DSENTRY_ALLOW_PREV 918 return dsentry->prev; 919 #else 920 MAGIC_DSENTRY_ITER(_magic_first_dsentry, prev_dsentry, it_dsentry, sentry, 921 if(dsentry == it_dsentry) { 922 found = 1; 923 break; 924 } 925 ); 926 if(!found) { 927 return (struct _magic_dsentry*) MAGIC_ENOPTR; 928 } 929 return prev_dsentry; 930 #endif 931 } 932 933 /*===========================================================================* 934 * magic_mempool_dsentry_prev_lookup * 935 *===========================================================================*/ 936 PUBLIC struct _magic_dsentry* magic_mempool_dsentry_prev_lookup(struct _magic_dsentry* dsentry) 937 { 938 struct _magic_dsentry *prev_dsentry, *it_dsentry; 939 struct _magic_sentry *sentry; 940 int found = 0; 941 942 MAGIC_DSENTRY_MEMPOOL_ITER(_magic_first_mempool_dsentry, prev_dsentry, it_dsentry, sentry, 943 if(dsentry == it_dsentry) { 944 found = 1; 945 break; 946 } 947 ); 948 if(!found) { 949 return (struct _magic_dsentry*) MAGIC_ENOPTR; 950 } 951 return prev_dsentry; 952 } 953 954 /*===========================================================================* 955 * magic_function_lookup_by_id * 956 *===========================================================================*/ 957 PUBLIC struct _magic_function* magic_function_lookup_by_id(_magic_id_t id, 958 struct _magic_dfunction *dfunction_buff) 959 { 960 struct _magic_function* entry = NULL; 961 struct _magic_function* function; 962 struct _magic_dfunction* dfunction; 963 964 if(id <= 0) { 965 return NULL; 966 } 967 968 /* O(1) ID lookup for functions. */ 969 #if MAGIC_LOOKUP_FUNCTION 970 if((int)id <= _magic_functions_num) { 971 return &_magic_functions[id - 1]; 972 } 973 #endif 974 975 /* O(N) ID lookup for dfunctions. */ 976 #if MAGIC_LOOKUP_DFUNCTION 977 MAGIC_DFUNCTION_LOCK(); 978 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function, 979 if(function->id == id) { 980 if(dfunction_buff) { 981 magic_copy_dfunction(dfunction, dfunction_buff); 982 entry = MAGIC_DFUNCTION_TO_FUNCTION(dfunction_buff); 983 } 984 else { 985 entry = function; 986 } 987 break; 988 } 989 ); 990 MAGIC_DFUNCTION_UNLOCK(); 991 #endif 992 993 return entry; 994 } 995 996 /*===========================================================================* 997 * magic_function_lookup_by_addr * 998 *===========================================================================*/ 999 PUBLIC struct _magic_function* magic_function_lookup_by_addr(void *addr, 1000 struct _magic_dfunction *dfunction_buff) 1001 { 1002 int i; 1003 struct _magic_function *entry = NULL; 1004 struct _magic_function *function; 1005 struct _magic_dfunction *dfunction; 1006 1007 #if MAGIC_LOOKUP_FUNCTION_ALLOW_ADDR_HASH 1008 if (magic_function_hash_head) { 1009 return magic_function_lookup_by_addr_hash(addr, dfunction_buff); 1010 } 1011 #endif 1012 1013 /* Scan all the entries and return the one matching the provided address. */ 1014 #if MAGIC_LOOKUP_FUNCTION 1015 if (MAGIC_ADDR_IS_IN_RANGE(addr, magic_function_range)) { 1016 for (i = 0 ; i < _magic_functions_num ; i++) { 1017 if (_magic_functions[i].address == addr) { 1018 entry = &_magic_functions[i]; 1019 break; 1020 } 1021 } 1022 } 1023 #endif 1024 1025 #if MAGIC_LOOKUP_DFUNCTION 1026 MAGIC_DFUNCTION_LOCK(); 1027 if(!MAGIC_ADDR_LOOKUP_USE_DFUNCTION_RANGES || magic_range_is_dfunction(addr)) { 1028 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function, 1029 if(function->address == addr) { 1030 if(dfunction_buff) { 1031 magic_copy_dfunction(dfunction, dfunction_buff); 1032 entry = MAGIC_DFUNCTION_TO_FUNCTION(dfunction_buff); 1033 } 1034 else { 1035 entry = function; 1036 } 1037 break; 1038 } 1039 ); 1040 } 1041 MAGIC_DFUNCTION_UNLOCK(); 1042 #endif 1043 1044 return entry; 1045 } 1046 1047 /*===========================================================================* 1048 * magic_function_lookup_by_name * 1049 *===========================================================================*/ 1050 PUBLIC struct _magic_function* 1051 magic_function_lookup_by_name(const char *parent_name, const char *name) 1052 { 1053 int i; 1054 struct _magic_function* entry = NULL; 1055 1056 /* Scan all the entries and return the one matching the provided name(s). */ 1057 #if MAGIC_LOOKUP_FUNCTION 1058 for (i = 0 ; i < _magic_functions_num ; i++) { 1059 if (!strcmp(_magic_functions[i].name, name)) { 1060 if (!parent_name || !strcmp(MAGIC_FUNCTION_PARENT(&_magic_functions[i]), parent_name)) { 1061 entry = &_magic_functions[i]; 1062 break; 1063 } 1064 } 1065 } 1066 #endif 1067 1068 return entry; 1069 } 1070 1071 /*===========================================================================* 1072 * magic_function_hash_insert * 1073 *===========================================================================*/ 1074 PRIVATE void magic_function_hash_insert(struct _magic_function_hash **head, 1075 struct _magic_function_hash *elem) 1076 { 1077 if (head != NULL) { 1078 struct _magic_function_hash *tmp; 1079 HASH_FIND_PTR(*head, &elem->key, tmp); 1080 /* Skip inserting this function if an identical one already exists. */ 1081 if (tmp) 1082 return; 1083 } 1084 /* 1085 * **** START UTHASH SPECIFIC DEFINITIONS **** 1086 */ 1087 #undef uthash_malloc 1088 #undef uthash_free 1089 #define uthash_malloc(size) magic_function_hash_alloc(size) 1090 #define uthash_free(addr, size) magic_function_hash_dealloc(addr, size) 1091 /* 1092 * Since we have a limited buffer, we need to stop bucket expansion when 1093 * reaching a certain limit. 1094 */ 1095 #undef uthash_expand_fyi 1096 #define uthash_expand_fyi(tbl) \ 1097 do { \ 1098 if (tbl->num_buckets == MAGIC_FUNCTION_ADDR_EST_MAX_BUCKETS) { \ 1099 _magic_printf("Warning! Function address hash maximum bucket " \ 1100 "number reached! Consider increasing " \ 1101 "MAGIC_FUNCTION_ADDR_EST_MAX_BUCKETS, unless you are " \ 1102 "comfortable with the current performance.\n"); \ 1103 tbl->noexpand = 1; \ 1104 } \ 1105 } while(0); 1106 /* 1107 * **** FINISH UTHASH SPECIFIC DEFINITIONS **** 1108 */ 1109 HASH_ADD_PTR(*head, key, elem); 1110 /* 1111 * **** START UTHASH DEFINITION REMOVAL **** 1112 */ 1113 #undef uthash_malloc 1114 #undef uthash_free 1115 #undef uthash_expand_fyi 1116 /* 1117 * **** FINISH UTHASH DEFINITION REMOVAL **** 1118 */ 1119 } 1120 1121 /*===========================================================================* 1122 * magic_function_hash_build * 1123 *===========================================================================*/ 1124 PUBLIC void magic_function_hash_build(void *buff, size_t buff_size) 1125 { 1126 /* 1127 * XXX: 1128 * Warning: this implementation is thread unsafe and also makes 1129 * magic_function_lookup_by_addr thread unsafe! 1130 */ 1131 int i; 1132 struct _magic_dfunction *dfunction; 1133 struct _magic_function *function; 1134 struct _magic_function_hash *function_hash, *head; 1135 1136 assert(buff && buff_size > 0); 1137 magic_function_hash_buff = buff; 1138 magic_function_hash_buff_offset = 0; 1139 magic_function_hash_buff_size = buff_size; 1140 1141 head = NULL; 1142 1143 /* Add all the functions to the hash. */ 1144 #if MAGIC_LOOKUP_FUNCTION 1145 for(i = 0 ; i < _magic_functions_num ; i++) { 1146 function_hash = (struct _magic_function_hash *) 1147 magic_function_hash_alloc(sizeof(struct _magic_function_hash)); 1148 function = &_magic_functions[i]; 1149 MAGIC_FUNCTION_TO_HASH_EL(function, function_hash); 1150 magic_function_hash_insert(&head, function_hash); 1151 } 1152 #endif 1153 1154 /* Add all the dfunctions to the hash. */ 1155 #if MAGIC_LOOKUP_DFUNCTION 1156 MAGIC_DFUNCTION_LOCK(); 1157 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function, 1158 function_hash = (struct _magic_function_hash *) 1159 magic_function_hash_alloc(sizeof(struct _magic_function_hash)); 1160 MAGIC_DFUNCTION_TO_HASH_EL(dfunction, function, function_hash); 1161 magic_function_hash_insert(&head, function_hash); 1162 ); 1163 MAGIC_DFUNCTION_UNLOCK(); 1164 #endif 1165 magic_function_hash_head = (void *)head; 1166 assert(magic_function_hash_head); 1167 } 1168 1169 /*===========================================================================* 1170 * magic_function_hash_destroy * 1171 *===========================================================================*/ 1172 PUBLIC void magic_function_hash_destroy(void) 1173 { 1174 magic_function_hash_buff = NULL; 1175 magic_function_hash_buff_offset = 0; 1176 magic_function_hash_buff_size = 0; 1177 magic_function_hash_head = NULL; 1178 } 1179 1180 /*===========================================================================* 1181 * magic_function_hash_estimate_buff_size * 1182 *===========================================================================*/ 1183 PUBLIC size_t magic_function_hash_estimate_buff_size(int functions_num) 1184 { 1185 if (functions_num == 0) { 1186 functions_num = _magic_dfunctions_num; 1187 functions_num += _magic_functions_num; 1188 } 1189 1190 return (functions_num * sizeof(struct _magic_function_hash)) + 1191 MAGIC_FUNCTION_ADDR_HASH_OVERHEAD; 1192 } 1193 1194 /*===========================================================================* 1195 * magic_function_hash_alloc * 1196 *===========================================================================*/ 1197 PUBLIC void* magic_function_hash_alloc(size_t size) 1198 { 1199 void *addr; 1200 1201 assert(magic_function_hash_buff); 1202 assert(magic_function_hash_buff_offset + size <= 1203 magic_function_hash_buff_size); 1204 1205 addr = (char*) magic_function_hash_buff + magic_function_hash_buff_offset; 1206 magic_function_hash_buff_offset += size; 1207 1208 return addr; 1209 } 1210 1211 /*===========================================================================* 1212 * magic_function_hash_dealloc * 1213 *===========================================================================*/ 1214 PUBLIC void magic_function_hash_dealloc(UNUSED(void *object), UNUSED(size_t sz)) 1215 { 1216 return; 1217 } 1218 1219 /*===========================================================================* 1220 * magic_function_lookup_by_addr_hash * 1221 *===========================================================================*/ 1222 PUBLIC struct _magic_function *magic_function_lookup_by_addr_hash( 1223 void *addr, struct _magic_dfunction *dfunction_buff) 1224 { 1225 /* 1226 * Warning: this implementation is thread unsafe! 1227 */ 1228 struct _magic_function_hash *res, *head; 1229 head = (struct _magic_function_hash *) magic_function_hash_head; 1230 1231 HASH_FIND_PTR(head, &addr, res); 1232 if (res == NULL) 1233 return NULL; 1234 1235 if (MAGIC_STATE_FLAG(res->function, MAGIC_STATE_DYNAMIC) && 1236 dfunction_buff != NULL) { 1237 magic_copy_dfunction(MAGIC_DFUNCTION_FROM_FUNCTION(res->function), 1238 dfunction_buff); 1239 } 1240 1241 return res->function; 1242 } 1243 1244 /*===========================================================================* 1245 * magic_type_lookup_by_name * 1246 *===========================================================================*/ 1247 PUBLIC struct _magic_type* magic_type_lookup_by_name(const char *name) 1248 { 1249 int i; 1250 unsigned int j; 1251 struct _magic_type* entry = NULL; 1252 1253 /* Scan all the entries and return the one matching the provided name. */ 1254 #if MAGIC_LOOKUP_TYPE 1255 for (i = 0 ; i < _magic_types_num ; i++) { 1256 if (!strcmp(_magic_types[i].name, name)) { 1257 entry = &_magic_types[i]; 1258 break; 1259 } 1260 if (_magic_types[i].names) { 1261 for (j = 0 ; j < _magic_types[i].num_names ; j++) { 1262 if (!strcmp(_magic_types[i].names[j], name)) { 1263 entry = &_magic_types[i]; 1264 break; 1265 } 1266 } 1267 if (entry) { 1268 break; 1269 } 1270 } 1271 } 1272 #endif 1273 1274 return entry; 1275 } 1276 1277 /*===========================================================================* 1278 * magic_dsodesc_lookup_by_handle * 1279 *===========================================================================*/ 1280 PUBLIC struct _magic_dsodesc* magic_dsodesc_lookup_by_handle(void *handle) 1281 { 1282 struct _magic_dsodesc* desc = NULL; 1283 struct _magic_dsodesc* dsodesc; 1284 1285 /* 1286 * Scan all the descriptors and return the one matching the provided handle. 1287 * Note that there is no locking here. The caller has to explicitely call 1288 * MAGIC_DSODESC_LOCK/UNLOCK before/after invoking this function. 1289 */ 1290 MAGIC_DSODESC_ITER(_magic_first_dsodesc, dsodesc, 1291 if(dsodesc->handle == handle) { 1292 desc = dsodesc; 1293 break; 1294 } 1295 ); 1296 1297 return desc; 1298 } 1299 1300 /*===========================================================================* 1301 * magic_print_function * 1302 *===========================================================================*/ 1303 PUBLIC void magic_print_function(struct _magic_function *function) 1304 { 1305 MAGIC_FUNCTION_PRINT(function, MAGIC_EXPAND_TYPE_STR); 1306 } 1307 1308 /*===========================================================================* 1309 * magic_print_functions * 1310 *===========================================================================*/ 1311 PUBLIC void magic_print_functions() 1312 { 1313 int i; 1314 struct _magic_function* function; 1315 1316 _magic_printf("magic_print_functions: Printing %d entries\n", _magic_functions_num); 1317 for(i=0;i<_magic_functions_num;i++) { 1318 function = &_magic_functions[i]; 1319 MAGIC_FUNCTION_PRINT(function, MAGIC_EXPAND_TYPE_STR); 1320 _magic_printf("\n"); 1321 } 1322 } 1323 1324 /*===========================================================================* 1325 * magic_print_type * 1326 *===========================================================================*/ 1327 PUBLIC void magic_print_type(const struct _magic_type* type) 1328 { 1329 MAGIC_TYPE_PRINT(type, MAGIC_EXPAND_TYPE_STR); 1330 } 1331 1332 /*===========================================================================* 1333 * magic_print_types * 1334 *===========================================================================*/ 1335 PUBLIC void magic_print_types() 1336 { 1337 int i; 1338 struct _magic_type* type; 1339 1340 _magic_printf("magic_print_types: Printing %d types\n", _magic_types_num); 1341 for(i=0;i<_magic_types_num;i++) { 1342 type = &_magic_types[i]; 1343 MAGIC_TYPE_PRINT(type, MAGIC_EXPAND_TYPE_STR); 1344 _magic_printf("\n"); 1345 } 1346 } 1347 1348 /*===========================================================================* 1349 * magic_type_str_set_print_style * 1350 *===========================================================================*/ 1351 PUBLIC void magic_type_str_set_print_style(const int style) 1352 { 1353 magic_type_str_print_style = style; 1354 } 1355 1356 /*===========================================================================* 1357 * magic_type_str_get_print_style * 1358 *===========================================================================*/ 1359 PUBLIC int magic_type_str_get_print_style() 1360 { 1361 return magic_type_str_print_style; 1362 } 1363 1364 /*===========================================================================* 1365 * magic_type_get_nesting_level * 1366 *===========================================================================*/ 1367 PRIVATE INLINE int magic_type_get_nesting_level(const struct _magic_type* type, 1368 int level) 1369 { 1370 int i; 1371 int nesting_level = -1; 1372 1373 for(i=0;i<level;i++) { 1374 if(magic_nested_types[i] == type) { 1375 nesting_level = i; 1376 break; 1377 } 1378 } 1379 1380 return nesting_level; 1381 } 1382 1383 /*===========================================================================* 1384 * magic_type_str_print * 1385 *===========================================================================*/ 1386 PUBLIC void magic_type_str_print(const struct _magic_type* type) 1387 { 1388 int num_contained_types; 1389 int is_empty_str = !type->type_str || !strcmp(type->type_str, ""); 1390 int type_has_name = type->name && strcmp(type->name, ""); 1391 int print_multi_names = (magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_MULTI_NAMES) && MAGIC_TYPE_HAS_MULTI_NAMES(type); 1392 int print_ptr_name = (magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_MULTI_NAMES) && !MAGIC_TYPE_HAS_MULTI_NAMES(type) && type_has_name; 1393 assert(magic_level < MAGIC_MAX_RECURSIVE_TYPES); 1394 1395 if(magic_level == 0) { 1396 magic_counter = 0; 1397 } 1398 else if(magic_counter >= MAGIC_TYPE_STR_PRINT_MAX) { 1399 _magic_printf("%%"); 1400 return; 1401 } 1402 else if(magic_level >= MAGIC_TYPE_STR_PRINT_MAX_LEVEL) { 1403 _magic_printf("%%"); 1404 return; 1405 } 1406 1407 if(MAGIC_TYPE_STR_PRINT_DEBUG) { 1408 _magic_printf("Entering level %d...\n", magic_level); 1409 } 1410 1411 if(type->type_id == MAGIC_TYPE_OPAQUE) { 1412 _magic_printf("opaque"); 1413 magic_counter += strlen("opaque"); 1414 return; 1415 } 1416 1417 num_contained_types = MAGIC_TYPE_NUM_CONTAINED_TYPES(type); 1418 if(num_contained_types == 0) { 1419 assert(!is_empty_str); 1420 if((magic_type_str_print_style & (MAGIC_TYPE_STR_PRINT_LLVM_TYPES|MAGIC_TYPE_STR_PRINT_SOURCE_TYPES)) == (MAGIC_TYPE_STR_PRINT_LLVM_TYPES|MAGIC_TYPE_STR_PRINT_SOURCE_TYPES)) { 1421 if(print_multi_names) { 1422 _magic_printf("%s/", type->type_str); 1423 magic_type_names_print(type); 1424 magic_counter += strlen(type->type_str)+1+strlen(type->name)*type->num_names; 1425 } 1426 else { 1427 _magic_printf("%s/%s", type->type_str, type->name); 1428 magic_counter += strlen(type->type_str)+1+strlen(type->name); 1429 } 1430 } 1431 else if(magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_LLVM_TYPES) { 1432 _magic_printf(type->type_str); 1433 magic_counter += strlen(type->type_str); 1434 } 1435 else if(magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_SOURCE_TYPES) { 1436 if(print_multi_names) { 1437 magic_type_names_print(type); 1438 magic_counter += strlen(type->name)*type->num_names; 1439 } 1440 else { 1441 _magic_printf(type->name); 1442 magic_counter += strlen(type->name); 1443 } 1444 } 1445 return; 1446 } 1447 1448 if(type->type_id == MAGIC_TYPE_POINTER) { 1449 int nesting_level = magic_type_get_nesting_level(type, magic_level); 1450 if(nesting_level >= 0) { 1451 _magic_printf("\\%d", magic_level - nesting_level); 1452 magic_counter += 2; 1453 return; 1454 } 1455 } 1456 1457 magic_nested_types[magic_level] = type; 1458 magic_level++; 1459 if(type->type_id == MAGIC_TYPE_POINTER) { 1460 magic_type_str_print(type->contained_types[0]); 1461 _magic_printf("*"); 1462 magic_counter += 1; 1463 if(print_multi_names) { 1464 _magic_printf("|"); 1465 magic_type_names_print(type); 1466 magic_counter += 1+strlen(type->name)*type->num_names; 1467 } 1468 else if(print_ptr_name) { 1469 _magic_printf("|"); 1470 _magic_printf("%s", type->name); 1471 magic_counter += 1+strlen(type->name); 1472 } 1473 } 1474 else if(type->type_id == MAGIC_TYPE_ARRAY || type->type_id == MAGIC_TYPE_VECTOR) { 1475 int num_elements = type->num_child_types; 1476 char start_sep = type->type_id == MAGIC_TYPE_ARRAY ? '[' : '<'; 1477 char end_sep = type->type_id == MAGIC_TYPE_ARRAY ? ']' : '>'; 1478 _magic_printf("%c", start_sep); 1479 magic_counter += 1; 1480 if(MAGIC_TYPE_FLAG(type, MAGIC_TYPE_VARSIZE)) { 1481 _magic_printf(" (V) "); 1482 magic_counter += 5; 1483 } 1484 if(num_elements) { 1485 _magic_printf("%d x ", num_elements); 1486 magic_counter += 5; 1487 } 1488 magic_type_str_print(type->contained_types[0]); 1489 _magic_printf("%c", end_sep); 1490 magic_counter += 1; 1491 } 1492 else if(type->type_id == MAGIC_TYPE_STRUCT || type->type_id == MAGIC_TYPE_UNION) { 1493 int i; 1494 int skip_struct = type->type_id == MAGIC_TYPE_STRUCT && (magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_SKIP_STRUCTS); 1495 int skip_union = type->type_id == MAGIC_TYPE_UNION && (magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_SKIP_UNIONS); 1496 _magic_printf("{ "); 1497 magic_counter += 2; 1498 if(type->type_id == MAGIC_TYPE_UNION) { 1499 _magic_printf("(U) "); 1500 magic_counter += 4; 1501 } 1502 if(print_multi_names) { 1503 _magic_printf("$"); 1504 magic_type_names_print(type); 1505 _magic_printf(" "); 1506 magic_counter += 2 + strlen(type->name)*type->num_names; 1507 } 1508 else { 1509 _magic_printf("$%s ", strcmp(type->name, "") ? type->name : "ANONYMOUS"); 1510 magic_counter += 2 + strlen(strcmp(type->name, "") ? type->name : "ANONYMOUS"); 1511 } 1512 assert(type->member_names); 1513 if(!skip_struct && !skip_union) { 1514 for(i=0;i<num_contained_types;i++) { 1515 if(i > 0) { 1516 _magic_printf(", "); 1517 magic_counter += 2; 1518 } 1519 if((magic_type_str_print_style & MAGIC_TYPE_STR_PRINT_MEMBER_NAMES) 1520 && (!MAGIC_TYPE_STR_PRINT_MAX || magic_counter < MAGIC_TYPE_STR_PRINT_MAX)) { 1521 assert(type->member_names[i] && strcmp(type->member_names[i], "") && "Invalid member name!"); 1522 _magic_printf("%s ", type->member_names[i]); 1523 magic_counter += strlen(type->member_names[i])+1; 1524 } 1525 magic_type_str_print(type->contained_types[i]); 1526 } 1527 } 1528 _magic_printf(" }"); 1529 magic_counter += 2; 1530 } 1531 else if(type->type_id == MAGIC_TYPE_FUNCTION) { 1532 int i; 1533 assert(num_contained_types > 0); 1534 magic_type_str_print(type->contained_types[0]); 1535 num_contained_types--; 1536 _magic_printf(" ("); 1537 magic_counter += 2; 1538 for(i=0;i<num_contained_types;i++) { 1539 if(i > 0) { 1540 _magic_printf(", "); 1541 magic_counter += 2; 1542 } 1543 magic_type_str_print(type->contained_types[i+1]); 1544 } 1545 _magic_printf(")"); 1546 magic_counter += 1; 1547 } 1548 else { 1549 _magic_printf("???[id=%d,child_types=%d,size=%zu]", type->type_id, type->num_child_types, type->size); 1550 magic_counter += 30; 1551 } 1552 magic_level--; 1553 if(MAGIC_TYPE_STR_PRINT_DEBUG) { 1554 _magic_printf("Exiting level %d...\n", magic_level); 1555 } 1556 } 1557 1558 /*===========================================================================* 1559 * magic_type_values_print * 1560 *===========================================================================*/ 1561 PUBLIC void magic_type_values_print(const struct _magic_type* type) 1562 { 1563 int i=0; 1564 1565 if(!MAGIC_TYPE_HAS_VALUE_SET(type)) { 1566 return; 1567 } 1568 while(MAGIC_TYPE_HAS_VALUE(type, i)) { 1569 int value = MAGIC_TYPE_VALUE(type, i); 1570 _magic_printf("%s%d", (i==0 ? "" : ", "), value); 1571 i++; 1572 } 1573 } 1574 1575 /*===========================================================================* 1576 * magic_type_names_print * 1577 *===========================================================================*/ 1578 PUBLIC void magic_type_names_print(const struct _magic_type* type) 1579 { 1580 unsigned int i; 1581 1582 for(i=0;i<type->num_names;i++) { 1583 _magic_printf("%s%s", (i==0 ? "" : "|"), type->names[i]); 1584 } 1585 } 1586 1587 /*===========================================================================* 1588 * magic_type_comp_types_print * 1589 *===========================================================================*/ 1590 PUBLIC void magic_type_comp_types_print(const struct _magic_type* type, 1591 int flags) 1592 { 1593 int num; 1594 int i=0; 1595 const struct _magic_type* comp_type; 1596 1597 if(!MAGIC_TYPE_HAS_COMP_TYPES(type)) { 1598 return; 1599 } 1600 MAGIC_TYPE_NUM_COMP_TYPES(type, &num); 1601 _magic_printf("#%d", num); 1602 if(flags & MAGIC_SKIP_COMP_TYPES) { 1603 return; 1604 } 1605 flags &= ~MAGIC_EXPAND_TYPE_STR; 1606 1607 MAGIC_TYPE_COMP_ITER(type, comp_type, 1608 _magic_printf("%s%d=", (i==0 ? ": " : ", "), i+1); 1609 MAGIC_TYPE_PRINT(comp_type, flags|MAGIC_SKIP_COMP_TYPES); 1610 i++; 1611 ); 1612 } 1613 1614 /*===========================================================================* 1615 * magic_type_str_print_from_target * 1616 *===========================================================================*/ 1617 PUBLIC int magic_type_str_print_from_target(void* target) 1618 { 1619 int printed_types=0; 1620 int ret; 1621 ret = magic_type_target_walk(target, NULL, NULL, 1622 magic_type_str_print_cb, &printed_types); 1623 if(ret < 0) { 1624 return ret; 1625 } 1626 if(printed_types == 0) { 1627 _magic_printf("BAD OFFSET"); 1628 } 1629 return printed_types; 1630 } 1631 1632 /*===========================================================================* 1633 * magic_type_equals * 1634 *===========================================================================*/ 1635 PUBLIC int magic_type_equals(const struct _magic_type* type, const struct _magic_type* other_type) 1636 { 1637 assert(magic_level < MAGIC_MAX_RECURSIVE_TYPES); 1638 1639 if(type == other_type) { 1640 return TRUE; 1641 } 1642 if(type->type_id != other_type->type_id) { 1643 return FALSE; 1644 } 1645 if((type->flags & MAGIC_TYPE_EXTERNAL) || (other_type->flags & MAGIC_TYPE_EXTERNAL)) { 1646 int i, nesting_level; 1647 if(type->num_child_types == other_type->num_child_types) { 1648 int num_contained_types = MAGIC_TYPE_NUM_CONTAINED_TYPES(type); 1649 if(num_contained_types == 0) { 1650 return !strcmp(type->type_str, other_type->type_str); 1651 } 1652 nesting_level = magic_type_get_nesting_level(type, magic_level); 1653 if(nesting_level >= 0) { 1654 return (other_type == magic_nested_types2[nesting_level]); 1655 } 1656 magic_nested_types[magic_level] = type; 1657 magic_nested_types2[magic_level] = other_type; 1658 magic_level++; 1659 for(i=0;i<num_contained_types;i++) { 1660 if(magic_type_equals(type->contained_types[i], other_type->contained_types[i]) == FALSE) { 1661 magic_level--; 1662 return FALSE; 1663 } 1664 } 1665 magic_level--; 1666 return TRUE; 1667 } 1668 } 1669 return FALSE; 1670 } 1671 1672 /*===========================================================================* 1673 * magic_type_compatible * 1674 *===========================================================================*/ 1675 PUBLIC int magic_type_compatible(const struct _magic_type* type, const struct _magic_type* other_type, int flags) 1676 { 1677 int i, nesting_level, num_contained_types; 1678 assert(magic_level < MAGIC_MAX_RECURSIVE_TYPES); 1679 1680 if(type == other_type) { 1681 return TRUE; 1682 } 1683 1684 if(type->type_id != other_type->type_id) { 1685 return FALSE; 1686 } 1687 1688 if(type->num_child_types != other_type->num_child_types) { 1689 return FALSE; 1690 } 1691 1692 if(flags & MAGIC_TYPE_COMPARE_FLAGS) { 1693 if((type->flags & (~MAGIC_TYPE_IS_ROOT)) != (other_type->flags & (~MAGIC_TYPE_IS_ROOT))){ 1694 return FALSE; 1695 } 1696 } 1697 1698 if(flags & MAGIC_TYPE_COMPARE_VALUE_SET) { 1699 if(MAGIC_TYPE_HAS_VALUE_SET(type) != MAGIC_TYPE_HAS_VALUE_SET(other_type)){ 1700 return FALSE; 1701 } 1702 if(MAGIC_TYPE_HAS_VALUE_SET(type)){ 1703 i=0; 1704 while(MAGIC_TYPE_HAS_VALUE(type, i) && MAGIC_TYPE_HAS_VALUE(other_type, i)) { 1705 if(MAGIC_TYPE_VALUE(type, i) != MAGIC_TYPE_VALUE(other_type, i)){ 1706 /* a value is different */ 1707 return FALSE; 1708 } 1709 i++; 1710 } 1711 if(MAGIC_TYPE_HAS_VALUE(type, i) || MAGIC_TYPE_HAS_VALUE(other_type, i)) { 1712 return FALSE; 1713 } 1714 } 1715 } 1716 1717 if(flags & MAGIC_TYPE_COMPARE_NAME) { 1718 if(strcmp(type->name, other_type->name)){ 1719 return FALSE; 1720 } 1721 } 1722 1723 if(flags & MAGIC_TYPE_COMPARE_NAMES) { 1724 if(type->num_names != other_type->num_names) { 1725 return FALSE; 1726 } 1727 if(type->num_names > 1) { 1728 for(i=0; (unsigned int)i<type->num_names; i++){ 1729 if(strcmp(type->names[i], other_type->names[i])) { 1730 return FALSE; 1731 } 1732 } 1733 } 1734 } 1735 1736 num_contained_types = MAGIC_TYPE_NUM_CONTAINED_TYPES(type); 1737 if(num_contained_types == 0) { 1738 return type->size == other_type->size && !strcmp(type->type_str, other_type->type_str); 1739 } 1740 1741 if(type->type_id == MAGIC_TYPE_STRUCT) { 1742 if(flags & MAGIC_TYPE_COMPARE_MEMBER_NAMES) { 1743 for(i=0; (unsigned int)i<type->num_child_types; i++){ 1744 if(strcmp(type->member_names[i], other_type->member_names[i])) { 1745 return FALSE; 1746 } 1747 } 1748 } 1749 if(flags & MAGIC_TYPE_COMPARE_MEMBER_OFFSETS) { 1750 for(i=0; (unsigned int)i<type->num_child_types; i++){ 1751 if(type->member_offsets[i] != other_type->member_offsets[i]) { 1752 return FALSE; 1753 } 1754 } 1755 } 1756 } 1757 1758 nesting_level = magic_type_get_nesting_level(type, magic_level); 1759 if(nesting_level >= 0) { 1760 return (other_type == magic_nested_types2[nesting_level]); 1761 } 1762 magic_nested_types[magic_level] = type; 1763 magic_nested_types2[magic_level] = other_type; 1764 magic_level++; 1765 for(i=0;i<num_contained_types;i++) { 1766 if(!magic_type_compatible(type->contained_types[i], other_type->contained_types[i], flags)) { 1767 magic_level--; 1768 return FALSE; 1769 } 1770 } 1771 magic_level--; 1772 return TRUE; 1773 } 1774 1775 /*===========================================================================* 1776 * magic_type_comp_compatible * 1777 *===========================================================================*/ 1778 PUBLIC int magic_type_comp_compatible(const struct _magic_type* type, const struct _magic_type* other_type) 1779 { 1780 const struct _magic_type *comp_type; 1781 1782 MAGIC_TYPE_COMP_ITER(type, comp_type, 1783 if(magic_type_compatible(comp_type, other_type, 0)) { 1784 return TRUE; 1785 } 1786 ); 1787 1788 return FALSE; 1789 } 1790 1791 /*===========================================================================* 1792 * magic_type_ptr_is_text * 1793 *===========================================================================*/ 1794 PUBLIC int magic_type_ptr_is_text(const struct _magic_type* ptr_type) 1795 { 1796 const struct _magic_type *comp_type; 1797 1798 assert(ptr_type->type_id == MAGIC_TYPE_POINTER); 1799 if(ptr_type->contained_types[0]->type_id == MAGIC_TYPE_FUNCTION 1800 || MAGIC_TYPE_IS_VOID(ptr_type->contained_types[0])) { 1801 return TRUE; 1802 } 1803 1804 MAGIC_TYPE_COMP_ITER(ptr_type, comp_type, 1805 if(comp_type->type_id == MAGIC_TYPE_FUNCTION 1806 || MAGIC_TYPE_IS_VOID(comp_type)) { 1807 return TRUE; 1808 } 1809 ); 1810 1811 return FALSE; 1812 } 1813 1814 /*===========================================================================* 1815 * magic_type_ptr_is_data * 1816 *===========================================================================*/ 1817 PUBLIC int magic_type_ptr_is_data(const struct _magic_type* ptr_type) 1818 { 1819 const struct _magic_type *comp_type; 1820 1821 assert(ptr_type->type_id == MAGIC_TYPE_POINTER); 1822 if(ptr_type->contained_types[0]->type_id != MAGIC_TYPE_FUNCTION) { 1823 return TRUE; 1824 } 1825 1826 MAGIC_TYPE_COMP_ITER(ptr_type, comp_type, 1827 if(comp_type->type_id != MAGIC_TYPE_FUNCTION) { 1828 return TRUE; 1829 } 1830 ); 1831 1832 return FALSE; 1833 } 1834 1835 /*===========================================================================* 1836 * magic_type_alloc_needs_varsized_array * 1837 *===========================================================================*/ 1838 PUBLIC int magic_type_alloc_needs_varsized_array(const struct _magic_type* type, 1839 size_t alloc_size, int *num_elements) 1840 { 1841 /* See if this type needs a var-sized array for the given allocation size */ 1842 const struct _magic_type *array_type, *array_el_type; 1843 size_t array_offset, array_size; 1844 if(!MAGIC_TYPE_FLAG(type, MAGIC_TYPE_VARSIZE)) { 1845 return FALSE; 1846 } 1847 assert(type->type_id == MAGIC_TYPE_STRUCT); 1848 1849 if(alloc_size <= type->size || type->num_child_types == 0) { 1850 return FALSE; 1851 } 1852 array_type = type->contained_types[type->num_child_types-1]; 1853 if(array_type->type_id != MAGIC_TYPE_ARRAY) { 1854 return FALSE; 1855 } 1856 array_el_type = array_type->contained_types[0]; 1857 array_offset = type->member_offsets[type->num_child_types-1]+array_type->num_child_types*array_el_type->size; 1858 array_size = alloc_size - array_offset; 1859 if(array_size == 0 || array_size % array_el_type->size != 0) { 1860 return FALSE; 1861 } 1862 if(num_elements) { 1863 *num_elements = 1+array_size/array_el_type->size; 1864 } 1865 1866 return TRUE; 1867 } 1868 1869 /*===========================================================================* 1870 * magic_type_alloc_get_varsized_array_size * 1871 *===========================================================================*/ 1872 PUBLIC size_t magic_type_alloc_get_varsized_array_size(const struct _magic_type* type, 1873 int num_elements) 1874 { 1875 /* Get the allocation size from the number of elements of the varsized array. */ 1876 const struct _magic_type *array_type, *array_el_type; 1877 size_t array_offset; 1878 if(!MAGIC_TYPE_FLAG(type, MAGIC_TYPE_VARSIZE)) { 1879 return 0; 1880 } 1881 assert(type->type_id == MAGIC_TYPE_STRUCT); 1882 1883 if(num_elements == 1) { 1884 return type->size; 1885 } 1886 array_type = type->contained_types[type->num_child_types-1]; 1887 if(array_type->type_id != MAGIC_TYPE_ARRAY) { 1888 return 0; 1889 } 1890 array_el_type = array_type->contained_types[0]; 1891 array_offset = type->member_offsets[type->num_child_types-1]+array_type->num_child_types*array_el_type->size; 1892 return array_offset + array_el_type->size*(num_elements-1); 1893 } 1894 1895 /*===========================================================================* 1896 * magic_type_parse_varsized_array * 1897 *===========================================================================*/ 1898 PUBLIC void magic_type_parse_varsized_array(const struct _magic_type *type, 1899 const struct _magic_type **sub_struct_type, const struct _magic_type **sub_array_type, 1900 size_t *sub_array_offset, size_t *sub_array_size) 1901 { 1902 /* Parse a var-sized array containing a variable-sized struct. */ 1903 const struct _magic_type *_sub_struct_type, *_sub_array_type, *_sub_array_el_type; 1904 size_t _sub_array_offset, _sub_array_size; 1905 1906 assert(type->type_id == MAGIC_TYPE_ARRAY && MAGIC_TYPE_FLAG(type, MAGIC_TYPE_DYNAMIC)); 1907 _sub_struct_type = type->contained_types[0]; 1908 assert(magic_type_alloc_needs_varsized_array(_sub_struct_type, type->size, NULL)); 1909 1910 _sub_array_type = _sub_struct_type->contained_types[_sub_struct_type->num_child_types-1]; 1911 _sub_array_el_type = _sub_array_type->contained_types[0]; 1912 _sub_array_offset = _sub_struct_type->member_offsets[_sub_struct_type->num_child_types-1]+_sub_array_type->num_child_types*_sub_array_el_type->size; 1913 _sub_array_size = type->size - _sub_array_offset; 1914 1915 if(sub_struct_type) *sub_struct_type = _sub_struct_type; 1916 if(sub_array_type) *sub_array_type = _sub_array_type; 1917 if(sub_array_offset) *sub_array_offset = _sub_array_offset; 1918 if(sub_array_size) *sub_array_size = _sub_array_size; 1919 } 1920 1921 /*===========================================================================* 1922 * magic_type_walk_flags * 1923 *===========================================================================*/ 1924 PUBLIC int magic_type_walk_flags(const struct _magic_type* parent_type, 1925 unsigned parent_offset, int child_num, 1926 const struct _magic_type* type, unsigned offset, 1927 const unsigned min_offset, const unsigned max_offset, 1928 const magic_type_walk_cb_t cb, void* cb_args, int flags) { 1929 static THREAD_LOCAL int magic_depth = 0; 1930 int ret, status, action; 1931 ret = MAGIC_TYPE_WALK_CONTINUE; 1932 1933 if(offset >= min_offset && offset <= max_offset) { 1934 ret = cb(parent_type, parent_offset, child_num, type, offset, magic_depth, cb_args); 1935 } 1936 else if(offset > max_offset) { 1937 ret = MAGIC_TYPE_WALK_STOP; 1938 } 1939 else if(offset+type->size <= min_offset) { 1940 ret = MAGIC_TYPE_WALK_SKIP_PATH; 1941 } 1942 1943 /* The status code returned to the caller is propagated directly from the 1944 * callback only in case of ret<0 and ret == MAGIC_TYPE_WALK_STOP. 1945 * In all the other cases, we return 0 the caller. 1946 */ 1947 status = ret < 0 ? ret : 0; 1948 action = ret < 0 ? MAGIC_TYPE_WALK_STOP : ret; 1949 switch(action) { 1950 case MAGIC_TYPE_WALK_STOP: 1951 status = status ? status : MAGIC_TYPE_WALK_STOP; 1952 break; 1953 case MAGIC_TYPE_WALK_SKIP_PATH: 1954 status = 0; 1955 break; 1956 case MAGIC_TYPE_WALK_CONTINUE: 1957 if(!MAGIC_TYPE_IS_WALKABLE(type)) { 1958 status = 0; 1959 } 1960 else { 1961 int i, num_child_types, start; 1962 num_child_types = type->num_child_types; 1963 start = 0; 1964 if(type->type_id == MAGIC_TYPE_ARRAY || type->type_id == MAGIC_TYPE_VECTOR) { 1965 if(!MAGIC_TYPE_FLAG(type, MAGIC_TYPE_VARSIZE) && offset < min_offset) { 1966 /* Skip irrelevant array iterations. */ 1967 start = (min_offset-offset)/(type->contained_types[0]->size); 1968 } 1969 } 1970 for(i=start;i<num_child_types;i++) { 1971 const struct _magic_type *child_type; 1972 unsigned child_offset; 1973 magic_type_walk_step(type, i, &child_type, &child_offset, flags); 1974 magic_depth++; 1975 status = magic_type_walk_flags(type, offset, i, child_type, offset+child_offset, min_offset, max_offset, cb, cb_args, flags); 1976 magic_depth--; 1977 if(status < 0 || status == MAGIC_TYPE_WALK_STOP) { 1978 break; 1979 } 1980 } 1981 } 1982 break; 1983 default: 1984 _magic_printf("magic_type_walk: unrecognized callback return code: %d, stopping type walk...\n", action); 1985 status = MAGIC_TYPE_WALK_STOP; 1986 break; 1987 } 1988 return status; 1989 } 1990 1991 /*===========================================================================* 1992 * magic_type_target_walk * 1993 *===========================================================================*/ 1994 PUBLIC int magic_type_target_walk(void *target, 1995 struct _magic_dsentry **trg_dsentry, struct _magic_dfunction **trg_dfunction, 1996 const magic_type_walk_cb_t cb, void *cb_args) 1997 { 1998 int ret; 1999 struct _magic_sentry *sentry = NULL; 2000 struct _magic_function *function = NULL; 2001 sentry = magic_sentry_lookup_by_range(target, magic_reentrant ? &magic_dsentry_buff : NULL); 2002 if (sentry == NULL) { 2003 function = magic_function_lookup_by_addr(target, magic_reentrant ? &magic_dfunction_buff : NULL); 2004 if (function == NULL) { 2005 /* No known entry found. */ 2006 return MAGIC_ENOENT; 2007 } 2008 if (MAGIC_STATE_FLAG(function, MAGIC_STATE_ADDR_NOT_TAKEN)) { 2009 /* A function has been found, but it was not supposed to be a target. */ 2010 return MAGIC_EBADENT; 2011 } 2012 } 2013 else if (MAGIC_STATE_FLAG(sentry, MAGIC_STATE_ADDR_NOT_TAKEN)) { 2014 /* An entry has been found, but it was not supposed to be a target. */ 2015 return MAGIC_EBADENT; 2016 } 2017 assert(sentry || function); 2018 if (magic_reentrant) { 2019 if (sentry) { 2020 if (trg_dsentry) { 2021 if (MAGIC_STATE_FLAG(sentry, MAGIC_STATE_DYNAMIC)) { 2022 magic_copy_dsentry(MAGIC_DSENTRY_FROM_SENTRY(sentry), *trg_dsentry); 2023 } 2024 else { 2025 memcpy(MAGIC_DSENTRY_TO_SENTRY(*trg_dsentry), sentry, sizeof(struct _magic_sentry)); 2026 } 2027 } 2028 if (trg_dfunction) { 2029 *trg_dfunction = NULL; 2030 } 2031 } 2032 else { 2033 if (trg_dfunction) { 2034 if (MAGIC_STATE_FLAG(function, MAGIC_STATE_DYNAMIC)) { 2035 magic_copy_dfunction(MAGIC_DFUNCTION_FROM_FUNCTION(function), *trg_dfunction); 2036 } 2037 else { 2038 memcpy(MAGIC_DFUNCTION_TO_FUNCTION(*trg_dfunction), function, sizeof(struct _magic_function)); 2039 } 2040 } 2041 if (trg_dsentry) { 2042 *trg_dsentry = NULL; 2043 } 2044 } 2045 } else { 2046 /* 2047 * Just return the pointer to the target object. 2048 * NB!: Because the target objects can be static (i.e. sentries, 2049 * functions), the user MUST first check the flag 2050 * of the returned target element to see if it is a sentry 2051 * or function. Otherwise, he might end up accessing invalid 2052 * memory. 2053 */ 2054 if (sentry) { 2055 if (trg_dsentry) { 2056 *trg_dsentry = MAGIC_DSENTRY_FROM_SENTRY(sentry); 2057 } 2058 if (trg_dfunction) { 2059 *trg_dfunction = NULL; 2060 } 2061 } 2062 else { 2063 if (trg_dfunction) { 2064 *trg_dfunction = MAGIC_DFUNCTION_FROM_FUNCTION(function); 2065 } 2066 if (trg_dsentry) { 2067 *trg_dsentry = NULL; 2068 } 2069 } 2070 } 2071 2072 if (sentry) { 2073 ret = magic_type_walk_root_at_offset(sentry->type, (char *) target - (char *) sentry->address, cb, cb_args); 2074 } else { 2075 ret = magic_type_walk_root_at_offset(function->type, (char*) target - (char*) function->address, cb, cb_args); 2076 } 2077 2078 return ret; 2079 } 2080 2081 /*===========================================================================* 2082 * magic_type_walk_as_void_array * 2083 *===========================================================================*/ 2084 PUBLIC int magic_type_walk_as_void_array(const struct _magic_type* parent_type, 2085 unsigned parent_offset, int child_num, const struct _magic_type* type, 2086 unsigned offset, const unsigned min_offset, const unsigned max_offset, 2087 const magic_type_walk_cb_t cb, void* cb_args) 2088 { 2089 struct _magic_type void_array_type; 2090 MAGIC_TYPE_VOID_ARRAY_GET_FROM_SIZE(&void_array_type, type->size); 2091 return magic_type_walk(parent_type, parent_offset, child_num, &void_array_type, 2092 offset, min_offset, max_offset, cb, cb_args); 2093 } 2094 2095 /*===========================================================================* 2096 * magic_type_walk_as_ptrint_array * 2097 *===========================================================================*/ 2098 PUBLIC int magic_type_walk_as_ptrint_array(const struct _magic_type* parent_type, 2099 unsigned parent_offset, int child_num, const struct _magic_type* type, void* offset_addr, 2100 unsigned offset, const unsigned min_offset, const unsigned max_offset, 2101 const magic_type_walk_cb_t cb, void* cb_args) 2102 { 2103 struct _magic_type ptrint_array_type; 2104 unsigned type_size = type->size; 2105 unsigned addr_diff = ((unsigned)offset_addr) % sizeof(void*); 2106 if(addr_diff > 0) { 2107 unsigned addr_off_by = sizeof(void*) - addr_diff; 2108 if(type_size <= addr_off_by) { 2109 return MAGIC_EBADWALK; 2110 } 2111 type_size -= addr_off_by; 2112 offset_addr = (void*)((unsigned)offset_addr + addr_off_by); 2113 offset += addr_off_by; 2114 } 2115 addr_diff = (((unsigned)offset_addr)+type_size) % sizeof(void*); 2116 if(addr_diff > 0) { 2117 unsigned addr_off_by = addr_diff; 2118 if(type_size <= addr_off_by) { 2119 return MAGIC_EBADWALK; 2120 } 2121 type_size -= addr_off_by; 2122 } 2123 MAGIC_TYPE_PTRINT_ARRAY_GET_FROM_SIZE(&ptrint_array_type, type_size); 2124 return magic_type_walk(parent_type, parent_offset, child_num, &ptrint_array_type, 2125 offset, min_offset, max_offset, cb, cb_args); 2126 } 2127 2128 /*===========================================================================* 2129 * magic_type_str_print_cb * 2130 *===========================================================================*/ 2131 PUBLIC int magic_type_str_print_cb(const struct _magic_type* parent_type, 2132 const unsigned parent_offset, int child_num, 2133 const struct _magic_type* type, const unsigned offset, int depth, void* cb_args) 2134 { 2135 int *printed_types = (int*) cb_args; 2136 if(printed_types) (*printed_types)++; 2137 magic_type_str_print(type); 2138 _magic_printf("; "); 2139 return MAGIC_TYPE_WALK_CONTINUE; 2140 } 2141 2142 /*===========================================================================* 2143 * magic_type_count_cb * 2144 *===========================================================================*/ 2145 PUBLIC int magic_type_count_cb(const struct _magic_type* parent_type, 2146 const unsigned parent_offset, int child_num, 2147 const struct _magic_type* type, const unsigned offset, int depth, void* cb_args) 2148 { 2149 int *type_counter = (int*) cb_args; 2150 if(type_counter) (*type_counter)++; 2151 return MAGIC_TYPE_WALK_CONTINUE; 2152 } 2153 2154 /*===========================================================================* 2155 * magic_type_child_offset_cb * 2156 *===========================================================================*/ 2157 PUBLIC int magic_type_child_offset_cb(const struct _magic_type* parent_type, 2158 const unsigned parent_offset, int child_num, 2159 const struct _magic_type* type, const unsigned offset, int depth, void* cb_args) 2160 { 2161 void **args_array = (void**) cb_args; 2162 int *my_child_num = (int*) args_array[0]; 2163 unsigned *child_offset = (unsigned*) args_array[1]; 2164 2165 if(!parent_type) { 2166 return MAGIC_TYPE_WALK_CONTINUE; 2167 } 2168 if(child_num == *my_child_num) { 2169 *child_offset = offset; 2170 return MAGIC_TYPE_WALK_STOP; 2171 } 2172 return MAGIC_TYPE_WALK_SKIP_PATH; 2173 } 2174 2175 /*===========================================================================* 2176 * magic_type_walk_step * 2177 *===========================================================================*/ 2178 PUBLIC void magic_type_walk_step(const struct _magic_type *type, 2179 int child_num, const struct _magic_type **child_type, unsigned *child_offset, 2180 int walk_flags) 2181 { 2182 int type_id; 2183 struct _magic_type type_buff; 2184 if(type->type_id == MAGIC_TYPE_UNION && (walk_flags & MAGIC_TYPE_WALK_UNIONS_AS_VOID)) { 2185 MAGIC_TYPE_VOID_ARRAY_GET_FROM_SIZE(&type_buff, type->size); 2186 type = &type_buff; 2187 } 2188 type_id = type->type_id; 2189 if(type_id == MAGIC_TYPE_STRUCT || type_id == MAGIC_TYPE_UNION) { 2190 *child_type = type->contained_types[child_num]; 2191 *child_offset = type->member_offsets[child_num]; 2192 } 2193 else { 2194 assert(type_id == MAGIC_TYPE_ARRAY || type_id == MAGIC_TYPE_VECTOR); 2195 if(MAGIC_TYPE_FLAG(type, MAGIC_TYPE_VARSIZE) && child_num > 0) { 2196 const struct _magic_type *sub_array_type, *sub_array_el_type; 2197 size_t sub_array_offset; 2198 magic_type_parse_varsized_array(type, NULL, &sub_array_type, &sub_array_offset, NULL); 2199 sub_array_el_type = sub_array_type->contained_types[0]; 2200 *child_type = sub_array_el_type; 2201 *child_offset = sub_array_offset + (child_num-1)*sub_array_el_type->size; 2202 } 2203 else { 2204 *child_type = type->contained_types[0]; 2205 *child_offset = child_num*((*child_type)->size); 2206 } 2207 } 2208 } 2209 2210 /*===========================================================================* 2211 * magic_type_get_size * 2212 *===========================================================================*/ 2213 PUBLIC size_t magic_type_get_size(struct _magic_type *type, int flags) 2214 { 2215 size_t size; 2216 int i, num_contained_types; 2217 2218 size = sizeof(type->size) + 2219 sizeof(type->num_child_types) + sizeof(type->contained_types) + 2220 sizeof(type->member_offsets) + sizeof(type->type_id) + sizeof(type->flags); 2221 num_contained_types = MAGIC_TYPE_NUM_CONTAINED_TYPES(type); 2222 2223 if(num_contained_types > 0) { 2224 size += sizeof(*(type->contained_types))*num_contained_types; 2225 } 2226 if(type->type_id == MAGIC_TYPE_STRUCT) { 2227 size += sizeof(*(type->member_offsets))*num_contained_types; 2228 if(flags & MAGIC_SIZE_MEMBER_NAMES) { 2229 size += sizeof(*(type->member_names))*num_contained_types; 2230 for(i=0;i<num_contained_types;i++) { 2231 size += strlen(type->member_names[i])+1; 2232 } 2233 } 2234 } 2235 2236 if(flags & MAGIC_SIZE_VALUE_SET) { 2237 if(MAGIC_TYPE_HAS_VALUE_SET(type)) { 2238 int num; 2239 MAGIC_TYPE_NUM_VALUES(type, &num); 2240 size += sizeof(int)+(num+1); 2241 } 2242 } 2243 if(flags & MAGIC_SIZE_TYPE_NAMES) { 2244 size += sizeof(type->num_names) + sizeof(type->names) + sizeof(*(type->names))*(type->num_names); 2245 for(i=0;(unsigned int)i<type->num_names;i++) { 2246 size += strlen(type->names[i])+1; 2247 } 2248 } 2249 if(flags & MAGIC_SIZE_COMP_TYPES) { 2250 if(MAGIC_TYPE_HAS_COMP_TYPES(type)) { 2251 int num; 2252 MAGIC_TYPE_NUM_COMP_TYPES(type, &num); 2253 size += sizeof(*(type->compatible_types))*num; 2254 } 2255 } 2256 2257 return size; 2258 } 2259 2260 /*===========================================================================* 2261 * magic_types_get_size * 2262 *===========================================================================*/ 2263 PUBLIC size_t magic_types_get_size(int flags) 2264 { 2265 size_t size; 2266 int i; 2267 2268 size = 0; 2269 for(i=0;i<_magic_types_num;i++) { 2270 size += magic_type_get_size(&_magic_types[i], flags); 2271 } 2272 2273 return size; 2274 } 2275 2276 /*===========================================================================* 2277 * magic_function_get_size * 2278 *===========================================================================*/ 2279 PUBLIC size_t magic_function_get_size(struct _magic_function *function, int flags) 2280 { 2281 size_t size; 2282 2283 size = sizeof(function->type) + sizeof(function->flags) + sizeof(function->address); 2284 2285 if(flags & MAGIC_SIZE_NAMES) { 2286 size += sizeof(function->name) + strlen(function->name)+1; 2287 } 2288 2289 return size; 2290 } 2291 2292 /*===========================================================================* 2293 * magic_functions_get_size * 2294 *===========================================================================*/ 2295 PUBLIC size_t magic_functions_get_size(int flags) 2296 { 2297 size_t size; 2298 int i; 2299 2300 size = 0; 2301 for(i=0;i<_magic_functions_num;i++) { 2302 size += magic_function_get_size(&_magic_functions[i], flags); 2303 } 2304 2305 return size; 2306 } 2307 2308 /*===========================================================================* 2309 * magic_dfunctions_get_size * 2310 *===========================================================================*/ 2311 PUBLIC size_t magic_dfunctions_get_size(int flags) 2312 { 2313 size_t size; 2314 struct _magic_dfunction* dfunction; 2315 struct _magic_function* function; 2316 2317 size = 0; 2318 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function, 2319 size += magic_function_get_size(function, flags); 2320 ); 2321 2322 return size; 2323 } 2324 2325 /*===========================================================================* 2326 * magic_sentry_get_size * 2327 *===========================================================================*/ 2328 PUBLIC size_t magic_sentry_get_size(struct _magic_sentry *sentry, int flags) 2329 { 2330 size_t size; 2331 2332 size = sizeof(sentry->type) + sizeof(sentry->flags); 2333 2334 if(MAGIC_SENTRY_IS_DSENTRY(sentry)) { 2335 struct _magic_dsentry *dsentry = MAGIC_DSENTRY_FROM_SENTRY(sentry); 2336 if(flags & MAGIC_SIZE_DSENTRY_NAMES) { 2337 size += sizeof(sentry->name) + strlen(sentry->name)+1; 2338 if(dsentry->parent_name) { 2339 size += sizeof(dsentry->parent_name) + strlen(dsentry->parent_name)+1; 2340 } 2341 } 2342 if(sentry->type == &dsentry->type) { 2343 size += sizeof(dsentry->type.num_child_types); 2344 } 2345 size += sizeof(dsentry->next); 2346 } 2347 else { 2348 size += sizeof(sentry->address); 2349 if(flags & MAGIC_SIZE_NAMES) { 2350 size += sizeof(sentry->name) + strlen(sentry->name)+1; 2351 } 2352 } 2353 2354 return size; 2355 } 2356 2357 /*===========================================================================* 2358 * magic_sentries_get_size * 2359 *===========================================================================*/ 2360 PUBLIC size_t magic_sentries_get_size(int flags) 2361 { 2362 size_t size; 2363 int i; 2364 2365 size = 0; 2366 for(i=0;i<_magic_sentries_num;i++) { 2367 size += magic_sentry_get_size(&_magic_sentries[i], flags); 2368 } 2369 2370 return size; 2371 } 2372 2373 /*===========================================================================* 2374 * magic_dsentries_get_size * 2375 *===========================================================================*/ 2376 PUBLIC size_t magic_dsentries_get_size(int flags) 2377 { 2378 size_t size; 2379 struct _magic_dsentry *prev_dsentry, *dsentry; 2380 struct _magic_sentry* sentry; 2381 2382 size = 0; 2383 MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry, 2384 if(!MAGIC_STATE_FLAG(sentry, MAGIC_STATE_OUT_OF_BAND)) { 2385 size += magic_sentry_get_size(sentry, flags); 2386 } 2387 ); 2388 2389 return size; 2390 } 2391 2392 /*===========================================================================* 2393 * magic_dsindex_get_size * 2394 *===========================================================================*/ 2395 PUBLIC size_t magic_dsindex_get_size(struct _magic_dsindex *dsindex, int flags) 2396 { 2397 size_t size; 2398 2399 size = sizeof(dsindex->type) + sizeof(dsindex->flags); 2400 2401 if(flags & MAGIC_SIZE_DSINDEX_NAMES) { 2402 size += sizeof(dsindex->parent_name) + strlen(dsindex->parent_name)+1; 2403 size += sizeof(dsindex->name) + strlen(dsindex->name)+1; 2404 } 2405 2406 return size; 2407 } 2408 2409 /*===========================================================================* 2410 * magic_dsindexes_get_size * 2411 *===========================================================================*/ 2412 PUBLIC size_t magic_dsindexes_get_size(int flags) 2413 { 2414 size_t size; 2415 int i; 2416 2417 size = 0; 2418 for(i=0;i<_magic_dsindexes_num;i++) { 2419 size += magic_dsindex_get_size(&_magic_dsindexes[i], flags); 2420 } 2421 2422 return size; 2423 } 2424 2425 /*===========================================================================* 2426 * magic_sodesc_get_size * 2427 *===========================================================================*/ 2428 PUBLIC size_t magic_sodesc_get_size(struct _magic_sodesc *sodesc, int flags) 2429 { 2430 return sizeof(struct _magic_sodesc); 2431 } 2432 2433 /*===========================================================================* 2434 * magic_sodescs_get_size * 2435 *===========================================================================*/ 2436 PUBLIC size_t magic_sodescs_get_size(int flags) 2437 { 2438 size_t size; 2439 struct _magic_sodesc* sodesc; 2440 2441 size = 0; 2442 MAGIC_SODESC_ITER(_magic_first_sodesc, sodesc, 2443 size += magic_sodesc_get_size(sodesc, flags); 2444 ); 2445 2446 return size; 2447 } 2448 2449 /*===========================================================================* 2450 * magic_dsodesc_get_size * 2451 *===========================================================================*/ 2452 PUBLIC size_t magic_dsodesc_get_size(struct _magic_dsodesc *dsodesc, int flags) 2453 { 2454 return sizeof(struct _magic_dsodesc); 2455 } 2456 2457 /*===========================================================================* 2458 * magic_dsodescs_get_size * 2459 *===========================================================================*/ 2460 PUBLIC size_t magic_dsodescs_get_size(int flags) 2461 { 2462 size_t size; 2463 struct _magic_dsodesc* dsodesc; 2464 2465 size = 0; 2466 MAGIC_DSODESC_ITER(_magic_first_dsodesc, dsodesc, 2467 size += magic_dsodesc_get_size(dsodesc, flags); 2468 ); 2469 2470 return size; 2471 } 2472 2473 /*===========================================================================* 2474 * magic_metadata_get_size * 2475 *===========================================================================*/ 2476 PUBLIC size_t magic_metadata_get_size(int flags) 2477 { 2478 size_t size = 0; 2479 2480 size += magic_types_get_size(flags); 2481 size += magic_functions_get_size(flags); 2482 size += magic_dfunctions_get_size(flags); 2483 size += magic_sentries_get_size(flags); 2484 size += magic_dsentries_get_size(flags); 2485 size += magic_dsindexes_get_size(flags); 2486 size += magic_dsodescs_get_size(flags); 2487 2488 return size; 2489 } 2490 2491 /*===========================================================================* 2492 * magic_sentries_data_get_size * 2493 *===========================================================================*/ 2494 PUBLIC size_t magic_sentries_data_get_size(int flags) 2495 { 2496 size_t size; 2497 int i; 2498 2499 size = 0; 2500 for(i=0;i<_magic_sentries_num;i++) { 2501 size += _magic_sentries[i].type->size; 2502 } 2503 2504 return size; 2505 } 2506 2507 /*===========================================================================* 2508 * magic_dsentries_data_get_size * 2509 *===========================================================================*/ 2510 PUBLIC size_t magic_dsentries_data_get_size(int flags) 2511 { 2512 size_t size; 2513 struct _magic_dsentry *prev_dsentry, *dsentry; 2514 struct _magic_sentry* sentry; 2515 2516 size = 0; 2517 MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry, 2518 if(!MAGIC_STATE_FLAG(sentry, MAGIC_STATE_OUT_OF_BAND)) { 2519 size += sentry->type->size; 2520 if(MAGIC_STATE_FLAG(sentry, MAGIC_STATE_HEAP)) { 2521 /* Assume a couple of words for malloc header. */ 2522 size += 2*sizeof(void*); 2523 } 2524 } 2525 ); 2526 2527 return size; 2528 } 2529 2530 /*===========================================================================* 2531 * magic_other_data_get_size * 2532 *===========================================================================*/ 2533 PUBLIC size_t magic_other_data_get_size(int flags) 2534 { 2535 size_t size = 0; 2536 2537 MAGIC_DSENTRY_LOCK(); 2538 magic_range_is_stack(NULL); 2539 MAGIC_DSENTRY_UNLOCK(); 2540 size += MAGIC_RANGE_SIZE(magic_stack_range); 2541 size += MAGIC_RANGE_SIZE(magic_text_range); 2542 2543 return size; 2544 } 2545 2546 /*===========================================================================* 2547 * magic_data_get_size * 2548 *===========================================================================*/ 2549 PUBLIC size_t magic_data_get_size(int flags) 2550 { 2551 size_t size = 0; 2552 2553 size += magic_sentries_data_get_size(flags); 2554 size += magic_dsentries_data_get_size(flags); 2555 size += magic_other_data_get_size(flags); 2556 2557 return size; 2558 } 2559 2560 /*===========================================================================* 2561 * magic_print_size_stats * 2562 *===========================================================================*/ 2563 PUBLIC void magic_print_size_stats(int flags) 2564 { 2565 size_t sentries_data_size, sentries_metadata_size; 2566 size_t dsentries_data_size, dsentries_metadata_size; 2567 size_t data_size, metadata_size; 2568 int dsentries_num; 2569 sentries_data_size = magic_sentries_data_get_size(flags); 2570 sentries_metadata_size = magic_sentries_get_size(flags); 2571 dsentries_data_size = magic_dsentries_data_get_size(flags); 2572 dsentries_metadata_size = magic_dsentries_get_size(flags); 2573 data_size = magic_data_get_size(flags); 2574 metadata_size = magic_metadata_get_size(flags); 2575 MAGIC_DSENTRY_NUM(_magic_first_dsentry, &dsentries_num); 2576 _magic_printf("--------------------------------------------------------\n"); 2577 _magic_printf("magic_print_size_stats: Printing size stats:\n"); 2578 _magic_printf(" - sentries: # %6d, data %8d, metadata %8d, total %8d, ratio %.3f\n", _magic_sentries_num, sentries_data_size, sentries_metadata_size, sentries_data_size+sentries_metadata_size, ((double)sentries_metadata_size)/sentries_data_size); 2579 _magic_printf(" - dsentries: # %6d, data %8d, metadata %8d, total %8d, ratio %.3f\n", dsentries_num, dsentries_data_size, dsentries_metadata_size, dsentries_data_size+dsentries_metadata_size, ((double)dsentries_metadata_size)/dsentries_data_size); 2580 _magic_printf(" - other: # %6d, data %8d\n", 2, magic_other_data_get_size(flags)); 2581 _magic_printf(" - state all: # %6d, data %8d, metadata %8d, total %8d, ratio %.3f\n", _magic_sentries_num+dsentries_num, sentries_data_size+dsentries_data_size, metadata_size, sentries_data_size+dsentries_data_size+metadata_size, ((double)metadata_size)/(sentries_data_size+dsentries_data_size)); 2582 _magic_printf(" - all: # %6d, data %8d, metadata %8d, total %8d, ratio %.3f\n", _magic_sentries_num+dsentries_num+2, data_size, metadata_size, data_size+metadata_size, ((double)metadata_size)/data_size); 2583 _magic_printf("--------------------------------------------------------\n"); 2584 _magic_printf("magic_print_size_stats: Printing metadata size breakdown:\n"); 2585 _magic_printf(" - types: # %6d, metadata %8d\n", _magic_types_num, magic_types_get_size(flags)); 2586 _magic_printf(" - functions: # %6d, metadata %8d\n", _magic_functions_num, magic_functions_get_size(flags)); 2587 _magic_printf(" - dfunctions # %6d, metadata %8d\n", 0, magic_dfunctions_get_size(flags)); 2588 _magic_printf(" - sentries: # %6d, metadata %8d\n", _magic_sentries_num, sentries_metadata_size); 2589 _magic_printf(" - dsentries: # %6d, metadata %8d\n", dsentries_num, dsentries_metadata_size); 2590 _magic_printf(" - dsindexes: # %6d, metadata %8d\n", _magic_dsindexes_num, magic_dsindexes_get_size(flags)); 2591 _magic_printf(" - dsodescs: # %6d, metadata %8d\n", 0, magic_dsodescs_get_size(flags)); 2592 _magic_printf("--------------------------------------------------------\n"); 2593 } 2594 2595