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 *===========================================================================*/
_magic_vars_addr()242 void *_magic_vars_addr()
243 {
244 return _magic_vars;
245 }
246
247 /*===========================================================================*
248 * _magic_vars_size *
249 *===========================================================================*/
_magic_vars_size()250 size_t _magic_vars_size()
251 {
252 return sizeof(struct _magic_vars_t);
253 }
254
255 /*===========================================================================*
256 * magic_null_printf *
257 *===========================================================================*/
magic_null_printf(const char * format,...)258 PUBLIC int magic_null_printf(const char *format, ...)
259 {
260 return 0;
261 }
262
263 #ifndef __MINIX
264 /*===========================================================================*
265 * magic_err_printf *
266 *===========================================================================*/
magic_err_printf(const char * format,...)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 *===========================================================================*/
magic_set_printf(printf_ptr_t func_ptr)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 *===========================================================================*/
magic_get_printf(void)291 PUBLIC printf_ptr_t magic_get_printf(void)
292 {
293 return _magic_printf;
294 }
295
296 /*===========================================================================*
297 * magic_reentrant_enable *
298 *===========================================================================*/
magic_reentrant_enable(void)299 PUBLIC void magic_reentrant_enable(void)
300 {
301 magic_reentrant = 1;
302 }
303 /*===========================================================================*
304 * magic_reentrant_disable *
305 *===========================================================================*/
magic_reentrant_disable(void)306 PUBLIC void magic_reentrant_disable(void)
307 {
308 magic_reentrant = 0;
309 }
310
311 /*===========================================================================*
312 * magic_assert_failed *
313 *===========================================================================*/
magic_assert_failed(const char * assertion,const char * file,const char * function,const int line)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 *===========================================================================*/
magic_get_sys_pagesize()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 *===========================================================================*/
magic_dsentry_set_lock_primitives(magic_lock_t lock,magic_unlock_t unlock,void * lock_args,void * unlock_args)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 *===========================================================================*/
magic_dfunction_set_lock_primitives(magic_lock_t lock,magic_unlock_t unlock,void * lock_args,void * unlock_args)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 *===========================================================================*/
magic_dsodesc_set_lock_primitives(magic_lock_t lock,magic_unlock_t unlock,void * lock_args,void * unlock_args)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 *===========================================================================*/
magic_mpdesc_set_lock_primitives(magic_lock_t lock,magic_unlock_t unlock,void * lock_args,void * unlock_args)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 *===========================================================================*/
magic_types_init()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 *===========================================================================*/
magic_data_init(void)426 MAGIC_FUNC void magic_data_init(void)
427 {
428 MAGIC_FUNC_BODY();
429 }
430
431 /*===========================================================================*
432 * magic_init *
433 *===========================================================================*/
magic_init(void)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 *===========================================================================*/
magic_do_check_dfunction(struct _magic_dfunction * dfunction,int flags)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 *===========================================================================*/
magic_check_dfunction(struct _magic_dfunction * dfunction,int flags)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 *===========================================================================*/
magic_check_dfunctions()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 *===========================================================================*/
magic_check_dfunctions_safe()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 *===========================================================================*/
magic_print_dfunction(struct _magic_dfunction * dfunction)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 *===========================================================================*/
magic_print_dfunctions()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 *===========================================================================*/
magic_print_dfunctions_safe()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 *===========================================================================*/
magic_copy_dfunction(struct _magic_dfunction * dfunction,struct _magic_dfunction * dst_dfunction)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 *===========================================================================*/
magic_print_dsindex(struct _magic_dsindex * dsindex)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 *===========================================================================*/
magic_print_dsindexes()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 *===========================================================================*/
magic_do_check_dsentry(struct _magic_dsentry * dsentry,int flags)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 *===========================================================================*/
magic_check_dsentry(struct _magic_dsentry * dsentry,int flags)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 *===========================================================================*/
magic_check_dsentries()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 *===========================================================================*/
magic_check_dsentries_safe()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 *===========================================================================*/
magic_print_dsentry(struct _magic_dsentry * dsentry)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 *===========================================================================*/
magic_print_dsentries()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 *===========================================================================*/
magic_print_dsentries_safe()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 *===========================================================================*/
magic_copy_dsentry(struct _magic_dsentry * dsentry,struct _magic_dsentry * dst_dsentry)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 *===========================================================================*/
magic_print_sodesc(struct _magic_sodesc * sodesc)781 PUBLIC void magic_print_sodesc(struct _magic_sodesc *sodesc)
782 {
783 MAGIC_SODESC_PRINT(sodesc);
784 }
785
786 /*===========================================================================*
787 * magic_print_sodescs *
788 *===========================================================================*/
magic_print_sodescs()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 *===========================================================================*/
magic_print_dsodesc(struct _magic_dsodesc * dsodesc)808 PUBLIC void magic_print_dsodesc(struct _magic_dsodesc *dsodesc)
809 {
810 MAGIC_DSODESC_PRINT(dsodesc);
811 }
812
813 /*===========================================================================*
814 * magic_print_dsodescs *
815 *===========================================================================*/
magic_print_dsodescs()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 *===========================================================================*/
magic_print_dsodescs_safe()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 *===========================================================================*/
magic_print_sections(void)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 *===========================================================================*/
magic_mempool_sentry_lookup_by_range(void * addr,struct _magic_dsentry * dsentry_buff)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*
magic_dsindex_lookup_by_name(const char * parent_name,const char * name)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 *===========================================================================*/
magic_dsentry_prev_lookup(struct _magic_dsentry * dsentry)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 *===========================================================================*/
magic_mempool_dsentry_prev_lookup(struct _magic_dsentry * dsentry)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 *===========================================================================*/
magic_function_lookup_by_id(_magic_id_t id,struct _magic_dfunction * dfunction_buff)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 *===========================================================================*/
magic_function_lookup_by_addr(void * addr,struct _magic_dfunction * dfunction_buff)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*
magic_function_lookup_by_name(const char * parent_name,const char * name)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 *===========================================================================*/
magic_function_hash_insert(struct _magic_function_hash ** head,struct _magic_function_hash * elem)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 *===========================================================================*/
magic_function_hash_build(void * buff,size_t buff_size)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 *===========================================================================*/
magic_function_hash_destroy(void)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 *===========================================================================*/
magic_function_hash_estimate_buff_size(int functions_num)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 *===========================================================================*/
magic_function_hash_alloc(size_t size)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 *===========================================================================*/
magic_function_hash_dealloc(UNUSED (void * object),UNUSED (size_t sz))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 *===========================================================================*/
magic_function_lookup_by_addr_hash(void * addr,struct _magic_dfunction * dfunction_buff)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 *===========================================================================*/
magic_type_lookup_by_name(const char * name)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 *===========================================================================*/
magic_dsodesc_lookup_by_handle(void * handle)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 *===========================================================================*/
magic_print_function(struct _magic_function * function)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 *===========================================================================*/
magic_print_functions()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 *===========================================================================*/
magic_print_type(const struct _magic_type * type)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 *===========================================================================*/
magic_print_types()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 *===========================================================================*/
magic_type_str_set_print_style(const int style)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 *===========================================================================*/
magic_type_str_get_print_style()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 *===========================================================================*/
magic_type_get_nesting_level(const struct _magic_type * type,int level)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 *===========================================================================*/
magic_type_str_print(const struct _magic_type * type)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 *===========================================================================*/
magic_type_values_print(const struct _magic_type * type)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 *===========================================================================*/
magic_type_names_print(const struct _magic_type * type)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 *===========================================================================*/
magic_type_comp_types_print(const struct _magic_type * type,int flags)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 *===========================================================================*/
magic_type_str_print_from_target(void * target)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 *===========================================================================*/
magic_type_equals(const struct _magic_type * type,const struct _magic_type * other_type)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 *===========================================================================*/
magic_type_compatible(const struct _magic_type * type,const struct _magic_type * other_type,int flags)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 *===========================================================================*/
magic_type_comp_compatible(const struct _magic_type * type,const struct _magic_type * other_type)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 *===========================================================================*/
magic_type_ptr_is_text(const struct _magic_type * ptr_type)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 *===========================================================================*/
magic_type_ptr_is_data(const struct _magic_type * ptr_type)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 *===========================================================================*/
magic_type_alloc_needs_varsized_array(const struct _magic_type * type,size_t alloc_size,int * num_elements)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 *===========================================================================*/
magic_type_alloc_get_varsized_array_size(const struct _magic_type * type,int num_elements)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 *===========================================================================*/
magic_type_parse_varsized_array(const struct _magic_type * type,const struct _magic_type ** sub_struct_type,const struct _magic_type ** sub_array_type,size_t * sub_array_offset,size_t * sub_array_size)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 *===========================================================================*/
magic_type_walk_flags(const struct _magic_type * parent_type,unsigned parent_offset,int child_num,const struct _magic_type * type,unsigned offset,const unsigned min_offset,const unsigned max_offset,const magic_type_walk_cb_t cb,void * cb_args,int flags)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 *===========================================================================*/
magic_type_target_walk(void * target,struct _magic_dsentry ** trg_dsentry,struct _magic_dfunction ** trg_dfunction,const magic_type_walk_cb_t cb,void * cb_args)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 *===========================================================================*/
magic_type_walk_as_void_array(const struct _magic_type * parent_type,unsigned parent_offset,int child_num,const struct _magic_type * type,unsigned offset,const unsigned min_offset,const unsigned max_offset,const magic_type_walk_cb_t cb,void * cb_args)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 *===========================================================================*/
magic_type_walk_as_ptrint_array(const struct _magic_type * parent_type,unsigned parent_offset,int child_num,const struct _magic_type * type,void * offset_addr,unsigned offset,const unsigned min_offset,const unsigned max_offset,const magic_type_walk_cb_t cb,void * cb_args)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 *===========================================================================*/
magic_type_str_print_cb(const struct _magic_type * parent_type,const unsigned parent_offset,int child_num,const struct _magic_type * type,const unsigned offset,int depth,void * cb_args)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 *===========================================================================*/
magic_type_count_cb(const struct _magic_type * parent_type,const unsigned parent_offset,int child_num,const struct _magic_type * type,const unsigned offset,int depth,void * cb_args)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 *===========================================================================*/
magic_type_child_offset_cb(const struct _magic_type * parent_type,const unsigned parent_offset,int child_num,const struct _magic_type * type,const unsigned offset,int depth,void * cb_args)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 *===========================================================================*/
magic_type_walk_step(const struct _magic_type * type,int child_num,const struct _magic_type ** child_type,unsigned * child_offset,int walk_flags)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 *===========================================================================*/
magic_type_get_size(struct _magic_type * type,int flags)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 *===========================================================================*/
magic_types_get_size(int flags)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 *===========================================================================*/
magic_function_get_size(struct _magic_function * function,int flags)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 *===========================================================================*/
magic_functions_get_size(int flags)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 *===========================================================================*/
magic_dfunctions_get_size(int flags)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 *===========================================================================*/
magic_sentry_get_size(struct _magic_sentry * sentry,int flags)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 *===========================================================================*/
magic_sentries_get_size(int flags)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 *===========================================================================*/
magic_dsentries_get_size(int flags)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 *===========================================================================*/
magic_dsindex_get_size(struct _magic_dsindex * dsindex,int flags)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 *===========================================================================*/
magic_dsindexes_get_size(int flags)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 *===========================================================================*/
magic_sodesc_get_size(struct _magic_sodesc * sodesc,int flags)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 *===========================================================================*/
magic_sodescs_get_size(int flags)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 *===========================================================================*/
magic_dsodesc_get_size(struct _magic_dsodesc * dsodesc,int flags)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 *===========================================================================*/
magic_dsodescs_get_size(int flags)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 *===========================================================================*/
magic_metadata_get_size(int flags)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 *===========================================================================*/
magic_sentries_data_get_size(int flags)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 *===========================================================================*/
magic_dsentries_data_get_size(int flags)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 *===========================================================================*/
magic_other_data_get_size(int flags)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 *===========================================================================*/
magic_data_get_size(int flags)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 *===========================================================================*/
magic_print_size_stats(int flags)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