4 #include <magic_eval.h>
5 #include <magic_analysis.h>
6 #include <magic_splay_tree.h>
8 #if MAGIC_MEM_USAGE_OUTPUT_CTL
9 #include <common/util/time.h>
12 /* Workaround for extern-only structs. */
16 PUBLIC
FILE **UNUSED(_____magic_instr_FILE_unused
) = &stdout
;
19 PUBLIC WINDOW
*UNUSED(_____magic_instr_WINDOW_unused
);
22 #include <netinet/in.h>
23 PUBLIC
struct in6_addr
*UNUSED(_____magic_instr_in6_addr_unused
);
26 MAGIC_VAR printf_ptr_t _magic_printf
= MAGIC_PRINTF_DEFAULT
;
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
;
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
;
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
;
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
;
49 /* Magic vars references. */
50 MAGIC_VAR
struct _magic_vars_t _magic_vars_buff
= {
52 /* Address Space Randomization (ASRPass) */
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 */
63 /* Magic type array. */
66 0, /* types_next_id */
68 /* Magic function array. */
70 0, /* functions_num */
71 0, /* functions_next_id */
73 /* Magic state entry array. */
76 0, /* sentries_str_num */
77 0, /* sentries_next_id */
79 /* Magic dynamic state index array. */
81 0, /* dsindexes_num */
83 /* Magic dynamic state entry list. */
84 NULL
, /* first_dsentry */
85 0, /* num_dead_sentries */
86 0, /* size_dead_dsentries */
88 /* Magic memory pool dynamic state entry list. */
89 NULL
, /* first_mempool_dsentry */
91 /* Magic dynamic function list. */
92 NULL
, /* first_dfunction */
93 NULL
, /* last_dfunction */
94 0, /* dfunctions_num */
96 /* Magic SO library descriptor list. */
97 NULL
, /* first_sodesc */
98 NULL
, /* last_sodesc */
101 /* Magic DSO library descriptor list. */
102 NULL
, /* first_dsodesc */
103 NULL
, /* last_dsodesc */
104 0, /* dsodescs_num */
106 /* Magic stack-related variables. */
107 NULL
, /* first_stack_dsentry */
108 NULL
, /* last_stack_dsentry */
110 /* Magic memory ranges */
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] */
120 {0,0}, /* *sentry_range[2] */
121 {0,0}, /* *function_range[2] */
122 {0,0}, /* *dfunction_range[2] */
124 NULL
, /* *heap_start */
125 NULL
, /* *heap_end */
126 1, /* update_dsentry_ranges */
127 1, /* update_dfunction_ranges */
130 { { NULL
, 0 } }, /* unmap_mem */
133 NULL
, /* sentry_rl_buff */
134 0, /* sentry_rl_buff_offset */
135 0, /* sentry_rl_buff_size */
136 NULL
, /* sentry_rl_index */
138 NULL
, /* sentry_hash_buff */
139 0, /* sentry_hash_buff_offset */
140 0, /* sentry_hash_buff_size */
141 NULL
, /* sentry_hash_head */
143 NULL
, /* function_hash_buff */
144 0, /* function_hash_buff_offset */
145 0, /* function_hash_buff_size */
146 NULL
, /* function_hash_head */
151 PUBLIC
struct _magic_vars_t
*_magic_vars
= &_magic_vars_buff
;
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];
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
;
164 /* Magic annotations. */
165 MAGIC_VAR VOLATILE
int MAGIC_CALL_ANNOTATION_VAR
;
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;
178 /* Magic out-of-band dsentries. */
179 PUBLIC
struct _magic_obdsentry _magic_obdsentries
[MAGIC_MAX_OBDSENTRIES
];
181 /* Pool management data. */
182 PUBLIC
struct _magic_mpdesc _magic_mpdescs
[MAGIC_MAX_MEMPOOLS
];
184 /* Magic page size. */
185 PUBLIC
unsigned long magic_sys_pagesize
= 0;
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
;
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
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
212 NULL
, /* next_mpool */
213 NULL
, /* next_mblock */
215 NULL
, /* next_sobject */
216 NULL
, /* sobject_base_addr */
219 MAGIC_DSENTRY_MSTATE_ALIVE
, /* magic_state */
220 { { 0, 0 } }, /* alloc_flags */
224 PUBLIC
struct _magic_dfunction magic_default_dfunction
= {
225 MAGIC_DFUNCTION_MNUM
,
227 { 0, "", NULL
, MAGIC_STATE_DYNAMIC
|MAGIC_STATE_TEXT
|MAGIC_STATE_CONSTANT
, NULL
},
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
236 /* Magic code reentrant flag. */
237 PRIVATE
int magic_reentrant
= 1;
239 /*===========================================================================*
241 *===========================================================================*/
242 void *_magic_vars_addr()
247 /*===========================================================================*
249 *===========================================================================*/
250 size_t _magic_vars_size()
252 return sizeof(struct _magic_vars_t
);
255 /*===========================================================================*
256 * magic_null_printf *
257 *===========================================================================*/
258 PUBLIC
int magic_null_printf(const char *format
, ...)
264 /*===========================================================================*
266 *===========================================================================*/
267 PUBLIC
int magic_err_printf(const char *format
, ...)
271 va_start(va
, format
);
272 ret
= vfprintf(stderr
, format
, va
);
279 /*===========================================================================*
281 *===========================================================================*/
282 PUBLIC
void magic_set_printf(printf_ptr_t func_ptr
)
285 _magic_printf
= func_ptr
;
288 /*===========================================================================*
290 *===========================================================================*/
291 PUBLIC printf_ptr_t
magic_get_printf(void)
293 return _magic_printf
;
296 /*===========================================================================*
297 * magic_reentrant_enable *
298 *===========================================================================*/
299 PUBLIC
void magic_reentrant_enable(void)
303 /*===========================================================================*
304 * magic_reentrant_disable *
305 *===========================================================================*/
306 PUBLIC
void magic_reentrant_disable(void)
311 /*===========================================================================*
312 * magic_assert_failed *
313 *===========================================================================*/
314 PUBLIC
void __dead
magic_assert_failed(const char *assertion
, const char *file
,
315 const char *function
, const int line
)
317 _magic_printf("Assertion '%s' failed in file %s, function %s(), line %d, pid %d\n",
318 assertion
, file
, function
, line
, getpid());
322 /*===========================================================================*
323 * magic_get_sys_pagesize *
324 *===========================================================================*/
325 PUBLIC
unsigned long magic_get_sys_pagesize()
327 if(!magic_sys_pagesize
) {
328 magic_sys_pagesize
= SYS_PAGESIZE
;
330 return magic_sys_pagesize
;
333 /*===========================================================================*
334 * magic_dsentry_set_lock_primitives *
335 *===========================================================================*/
336 PUBLIC
void magic_dsentry_set_lock_primitives(magic_lock_t lock
,
337 magic_unlock_t unlock
, void *lock_args
, void *unlock_args
)
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
;
346 /*===========================================================================*
347 * magic_dfunction_set_lock_primitives *
348 *===========================================================================*/
349 PUBLIC
void magic_dfunction_set_lock_primitives(magic_lock_t lock
,
350 magic_unlock_t unlock
, void *lock_args
, void *unlock_args
)
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
;
359 /*===========================================================================*
360 * magic_dsodesc_set_lock_primitives *
361 *===========================================================================*/
362 PUBLIC
void magic_dsodesc_set_lock_primitives(magic_lock_t lock
,
363 magic_unlock_t unlock
, void *lock_args
, void *unlock_args
)
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
;
372 /*===========================================================================*
373 * magic_mpdesc_set_lock_primitives *
374 *===========================================================================*/
375 PUBLIC
void magic_mpdesc_set_lock_primitives(magic_lock_t lock
,
376 magic_unlock_t unlock
, void *lock_args
, void *unlock_args
)
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
;
385 /*===========================================================================*
387 *===========================================================================*/
388 PRIVATE
void magic_types_init()
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];
399 assert(MAGIC_VOID_PTR_TYPE
);
400 assert(MAGIC_VOID_PTR_TYPE
->size
== sizeof(void*));
401 assert(MAGIC_VOID_TYPE
->size
== sizeof(char));
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
;
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);
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
);
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);
423 /*===========================================================================*
425 *===========================================================================*/
426 MAGIC_FUNC
void magic_data_init(void)
431 /*===========================================================================*
433 *===========================================================================*/
434 PUBLIC
void magic_init(void)
438 if(magic_init_done
|| !_magic_enabled
) {
442 /* Initialize magic data structures first. */
445 /* Initialize asr support. */
448 /* Initialize eval support. */
451 /* Initialize magic obdsentries. */
452 memset(_magic_obdsentries
, 0, MAGIC_MAX_OBDSENTRIES
* sizeof(struct _magic_obdsentry
));
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
);
459 /* Initialize special types. */
462 /* Initialize magic ranges. */
465 /* Perform stack-related initialization. */
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);
474 assert(magic_check_sentries() && "Bad sentries!");
475 assert(magic_check_dsentries_safe() && "Bad dsentries!");
481 /*===========================================================================*
482 * magic_do_check_dfunction *
483 *===========================================================================*/
484 PRIVATE INLINE
int magic_do_check_dfunction(struct _magic_dfunction
*dfunction
, int flags
)
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
);
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
);
507 /*===========================================================================*
508 * magic_check_dfunction *
509 *===========================================================================*/
510 PUBLIC
int magic_check_dfunction(struct _magic_dfunction
*dfunction
, int flags
)
513 check
= magic_do_check_dfunction(dfunction
, flags
);
518 #if MAGIC_CHECK_LEVEL == 2
519 check
= magic_check_dfunctions();
521 _magic_printf("magic_check_dfunction: bad other dfunction\n");
529 /*===========================================================================*
530 * magic_check_dfunctions *
531 *===========================================================================*/
532 PUBLIC
int magic_check_dfunctions()
534 int magic_dfunctions_found
= 0;
535 struct _magic_dfunction
* dfunction
= NULL
;
536 struct _magic_function
* function
= NULL
;
537 int ret
, check
= TRUE
;
539 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction
, dfunction
, function
,
540 ret
= magic_do_check_dfunction(dfunction
, 0);
544 magic_dfunctions_found
++;
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
);
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
);
557 /*===========================================================================*
558 * magic_check_dfunctions_safe *
559 *===========================================================================*/
560 PUBLIC
int magic_check_dfunctions_safe()
563 MAGIC_DFUNCTION_LOCK();
564 ret
= magic_check_dfunctions();
565 MAGIC_DFUNCTION_UNLOCK();
569 /*===========================================================================*
570 * magic_print_dfunction *
571 *===========================================================================*/
572 PUBLIC
void magic_print_dfunction(struct _magic_dfunction
*dfunction
)
574 MAGIC_DFUNCTION_PRINT(dfunction
, MAGIC_EXPAND_TYPE_STR
);
577 /*===========================================================================*
578 * magic_print_dfunctions *
579 *===========================================================================*/
580 PUBLIC
void magic_print_dfunctions()
582 int magic_dfunctions_found
= 0;
583 struct _magic_dfunction
* dfunction
;
584 struct _magic_function
* function
;
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
);
590 magic_dfunctions_found
++;
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
);
597 /*===========================================================================*
598 * magic_print_dfunctions_safe *
599 *===========================================================================*/
600 PUBLIC
void magic_print_dfunctions_safe()
602 MAGIC_DFUNCTION_LOCK();
603 magic_print_dfunctions();
604 MAGIC_DFUNCTION_UNLOCK();
607 /*===========================================================================*
608 * magic_copy_dfunction *
609 *===========================================================================*/
610 PUBLIC
void magic_copy_dfunction(struct _magic_dfunction
*dfunction
,
611 struct _magic_dfunction
*dst_dfunction
)
614 memcpy(dst_dfunction
, dfunction
, sizeof(struct _magic_dfunction
));
617 /*===========================================================================*
618 * magic_print_dsindex *
619 *===========================================================================*/
620 PUBLIC
void magic_print_dsindex(struct _magic_dsindex
*dsindex
)
622 MAGIC_DSINDEX_PRINT(dsindex
, MAGIC_EXPAND_TYPE_STR
);
625 /*===========================================================================*
626 * magic_print_dsindexes *
627 *===========================================================================*/
628 PUBLIC
void magic_print_dsindexes()
631 struct _magic_dsindex
* dsindex
;
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
);
641 /*===========================================================================*
642 * magic_do_check_dsentry *
643 *===========================================================================*/
644 PRIVATE INLINE
int magic_do_check_dsentry(struct _magic_dsentry
*dsentry
, int flags
)
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
);
653 _magic_printf("magic_do_check_dsentry: bad ~mnum %08x\n", ~(dsentry
->magic_number
));
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
);
667 /*===========================================================================*
668 * magic_check_dsentry *
669 *===========================================================================*/
670 PUBLIC
int magic_check_dsentry(struct _magic_dsentry
*dsentry
, int flags
)
672 #if MAGIC_CHECK_LEVEL >= 1
674 check
= magic_do_check_dsentry(dsentry
, flags
);
680 #if MAGIC_CHECK_LEVEL == 2
681 check
= magic_check_dsentries();
683 _magic_printf("magic_check_dsentry: bad other dsentry\n");
691 /*===========================================================================*
692 * magic_check_dsentries *
693 *===========================================================================*/
694 PUBLIC
int magic_check_dsentries()
696 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
697 struct _magic_sentry
* sentry
;
698 int ret
, check
= TRUE
;
700 MAGIC_DSENTRY_NESTED_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
701 ret
= magic_do_check_dsentry(dsentry
, 0);
709 /*===========================================================================*
710 * magic_check_dsentries_safe *
711 *===========================================================================*/
712 PUBLIC
int magic_check_dsentries_safe()
715 MAGIC_DSENTRY_LOCK();
716 ret
= magic_check_dsentries();
717 MAGIC_DSENTRY_UNLOCK();
721 /*===========================================================================*
722 * magic_print_dsentry *
723 *===========================================================================*/
724 PUBLIC
void magic_print_dsentry(struct _magic_dsentry
*dsentry
)
726 MAGIC_DSENTRY_PRINT(dsentry
, MAGIC_EXPAND_TYPE_STR
);
729 /*===========================================================================*
730 * magic_print_dsentries *
731 *===========================================================================*/
732 PUBLIC
void magic_print_dsentries()
734 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
735 struct _magic_sentry
* sentry
;
736 int magic_dsentries_num
= 0;
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
);
742 magic_dsentries_num
++;
744 _magic_printf("magic_print_dsentries: %d entries found\n", magic_dsentries_num
);
747 /*===========================================================================*
748 * magic_print_dsentries_safe *
749 *===========================================================================*/
750 PUBLIC
void magic_print_dsentries_safe()
752 MAGIC_DSENTRY_LOCK();
753 magic_print_dsentries();
754 MAGIC_DSENTRY_UNLOCK();
757 /*===========================================================================*
758 * magic_copy_dsentry *
759 *===========================================================================*/
760 PUBLIC
void magic_copy_dsentry(struct _magic_dsentry
*dsentry
,
761 struct _magic_dsentry
*dst_dsentry
)
763 struct _magic_sentry
*sentry
;
766 memcpy(dst_dsentry
, dsentry
, sizeof(struct _magic_dsentry
));
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
;
778 /*===========================================================================*
779 * magic_print_sodesc *
780 *===========================================================================*/
781 PUBLIC
void magic_print_sodesc(struct _magic_sodesc
*sodesc
)
783 MAGIC_SODESC_PRINT(sodesc
);
786 /*===========================================================================*
787 * magic_print_sodescs *
788 *===========================================================================*/
789 PUBLIC
void magic_print_sodescs()
791 int magic_sodescs_found
= 0;
792 struct _magic_sodesc
* sodesc
;
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
);
798 magic_sodescs_found
++;
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
);
805 /*===========================================================================*
806 * magic_print_dsodesc *
807 *===========================================================================*/
808 PUBLIC
void magic_print_dsodesc(struct _magic_dsodesc
*dsodesc
)
810 MAGIC_DSODESC_PRINT(dsodesc
);
813 /*===========================================================================*
814 * magic_print_dsodescs *
815 *===========================================================================*/
816 PUBLIC
void magic_print_dsodescs()
818 int magic_dsodescs_found
= 0;
819 struct _magic_dsodesc
* dsodesc
;
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
);
825 magic_dsodescs_found
++;
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
);
832 /*===========================================================================*
833 * magic_print_dsodescs_safe *
834 *===========================================================================*/
835 PUBLIC
void magic_print_dsodescs_safe()
837 MAGIC_DSODESC_LOCK();
838 magic_print_dsodescs();
839 MAGIC_DSODESC_UNLOCK();
842 /*===========================================================================*
843 * magic_print_sections *
844 *===========================================================================*/
845 PUBLIC
void magic_print_sections(void)
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
);
856 /*===========================================================================*
857 * magic_mempool_sentry_lookup_by_addr *
858 *===========================================================================*/
859 PUBLIC
struct _magic_sentry
* magic_mempool_sentry_lookup_by_range(void *addr
, struct _magic_dsentry
*dsentry_buff
)
861 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
862 struct _magic_sentry
* sentry
;
863 struct _magic_sentry
* entry
= NULL
;
864 void *start_address
, *end_address
;
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
)) {
872 magic_copy_dsentry(dsentry
, dsentry_buff
);
873 entry
= MAGIC_DSENTRY_TO_SENTRY(dsentry_buff
);
881 MAGIC_DSENTRY_UNLOCK();
886 /*===========================================================================*
887 * magic_dsindex_lookup_by_name *
888 *===========================================================================*/
889 PUBLIC
struct _magic_dsindex
*
890 magic_dsindex_lookup_by_name(const char *parent_name
, const char *name
)
893 struct _magic_dsindex
* index
= NULL
;
894 assert(parent_name
&& name
);
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
];
908 /*===========================================================================*
909 * magic_dsentry_prev_lookup *
910 *===========================================================================*/
911 PUBLIC
struct _magic_dsentry
* magic_dsentry_prev_lookup(struct _magic_dsentry
* dsentry
)
913 struct _magic_dsentry
*prev_dsentry
, *it_dsentry
;
914 struct _magic_sentry
*sentry
;
917 #if MAGIC_DSENTRY_ALLOW_PREV
918 return dsentry
->prev
;
920 MAGIC_DSENTRY_ITER(_magic_first_dsentry
, prev_dsentry
, it_dsentry
, sentry
,
921 if(dsentry
== it_dsentry
) {
927 return (struct _magic_dsentry
*) MAGIC_ENOPTR
;
933 /*===========================================================================*
934 * magic_mempool_dsentry_prev_lookup *
935 *===========================================================================*/
936 PUBLIC
struct _magic_dsentry
* magic_mempool_dsentry_prev_lookup(struct _magic_dsentry
* dsentry
)
938 struct _magic_dsentry
*prev_dsentry
, *it_dsentry
;
939 struct _magic_sentry
*sentry
;
942 MAGIC_DSENTRY_MEMPOOL_ITER(_magic_first_mempool_dsentry
, prev_dsentry
, it_dsentry
, sentry
,
943 if(dsentry
== it_dsentry
) {
949 return (struct _magic_dsentry
*) MAGIC_ENOPTR
;
954 /*===========================================================================*
955 * magic_function_lookup_by_id *
956 *===========================================================================*/
957 PUBLIC
struct _magic_function
* magic_function_lookup_by_id(_magic_id_t id
,
958 struct _magic_dfunction
*dfunction_buff
)
960 struct _magic_function
* entry
= NULL
;
961 struct _magic_function
* function
;
962 struct _magic_dfunction
* dfunction
;
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];
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
) {
981 magic_copy_dfunction(dfunction
, dfunction_buff
);
982 entry
= MAGIC_DFUNCTION_TO_FUNCTION(dfunction_buff
);
990 MAGIC_DFUNCTION_UNLOCK();
996 /*===========================================================================*
997 * magic_function_lookup_by_addr *
998 *===========================================================================*/
999 PUBLIC
struct _magic_function
* magic_function_lookup_by_addr(void *addr
,
1000 struct _magic_dfunction
*dfunction_buff
)
1003 struct _magic_function
*entry
= NULL
;
1004 struct _magic_function
*function
;
1005 struct _magic_dfunction
*dfunction
;
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
);
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
];
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
);
1041 MAGIC_DFUNCTION_UNLOCK();
1047 /*===========================================================================*
1048 * magic_function_lookup_by_name *
1049 *===========================================================================*/
1050 PUBLIC
struct _magic_function
*
1051 magic_function_lookup_by_name(const char *parent_name
, const char *name
)
1054 struct _magic_function
* entry
= NULL
;
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
];
1071 /*===========================================================================*
1072 * magic_function_hash_insert *
1073 *===========================================================================*/
1074 PRIVATE
void magic_function_hash_insert(struct _magic_function_hash
**head
,
1075 struct _magic_function_hash
*elem
)
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. */
1085 * **** START UTHASH SPECIFIC DEFINITIONS ****
1087 #undef uthash_malloc
1089 #define uthash_malloc(size) magic_function_hash_alloc(size)
1090 #define uthash_free(addr, size) magic_function_hash_dealloc(addr, size)
1092 * Since we have a limited buffer, we need to stop bucket expansion when
1093 * reaching a certain limit.
1095 #undef uthash_expand_fyi
1096 #define uthash_expand_fyi(tbl) \
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; \
1107 * **** FINISH UTHASH SPECIFIC DEFINITIONS ****
1109 HASH_ADD_PTR(*head
, key
, elem
);
1111 * **** START UTHASH DEFINITION REMOVAL ****
1113 #undef uthash_malloc
1115 #undef uthash_expand_fyi
1117 * **** FINISH UTHASH DEFINITION REMOVAL ****
1121 /*===========================================================================*
1122 * magic_function_hash_build *
1123 *===========================================================================*/
1124 PUBLIC
void magic_function_hash_build(void *buff
, size_t buff_size
)
1128 * Warning: this implementation is thread unsafe and also makes
1129 * magic_function_lookup_by_addr thread unsafe!
1132 struct _magic_dfunction
*dfunction
;
1133 struct _magic_function
*function
;
1134 struct _magic_function_hash
*function_hash
, *head
;
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
;
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
);
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
);
1163 MAGIC_DFUNCTION_UNLOCK();
1165 magic_function_hash_head
= (void *)head
;
1166 assert(magic_function_hash_head
);
1169 /*===========================================================================*
1170 * magic_function_hash_destroy *
1171 *===========================================================================*/
1172 PUBLIC
void magic_function_hash_destroy(void)
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
;
1180 /*===========================================================================*
1181 * magic_function_hash_estimate_buff_size *
1182 *===========================================================================*/
1183 PUBLIC
size_t magic_function_hash_estimate_buff_size(int functions_num
)
1185 if (functions_num
== 0) {
1186 functions_num
= _magic_dfunctions_num
;
1187 functions_num
+= _magic_functions_num
;
1190 return (functions_num
* sizeof(struct _magic_function_hash
)) +
1191 MAGIC_FUNCTION_ADDR_HASH_OVERHEAD
;
1194 /*===========================================================================*
1195 * magic_function_hash_alloc *
1196 *===========================================================================*/
1197 PUBLIC
void* magic_function_hash_alloc(size_t size
)
1201 assert(magic_function_hash_buff
);
1202 assert(magic_function_hash_buff_offset
+ size
<=
1203 magic_function_hash_buff_size
);
1205 addr
= (char*) magic_function_hash_buff
+ magic_function_hash_buff_offset
;
1206 magic_function_hash_buff_offset
+= size
;
1211 /*===========================================================================*
1212 * magic_function_hash_dealloc *
1213 *===========================================================================*/
1214 PUBLIC
void magic_function_hash_dealloc(UNUSED(void *object
), UNUSED(size_t sz
))
1219 /*===========================================================================*
1220 * magic_function_lookup_by_addr_hash *
1221 *===========================================================================*/
1222 PUBLIC
struct _magic_function
*magic_function_lookup_by_addr_hash(
1223 void *addr
, struct _magic_dfunction
*dfunction_buff
)
1226 * Warning: this implementation is thread unsafe!
1228 struct _magic_function_hash
*res
, *head
;
1229 head
= (struct _magic_function_hash
*) magic_function_hash_head
;
1231 HASH_FIND_PTR(head
, &addr
, res
);
1235 if (MAGIC_STATE_FLAG(res
->function
, MAGIC_STATE_DYNAMIC
) &&
1236 dfunction_buff
!= NULL
) {
1237 magic_copy_dfunction(MAGIC_DFUNCTION_FROM_FUNCTION(res
->function
),
1241 return res
->function
;
1244 /*===========================================================================*
1245 * magic_type_lookup_by_name *
1246 *===========================================================================*/
1247 PUBLIC
struct _magic_type
* magic_type_lookup_by_name(const char *name
)
1251 struct _magic_type
* entry
= NULL
;
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
];
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
];
1277 /*===========================================================================*
1278 * magic_dsodesc_lookup_by_handle *
1279 *===========================================================================*/
1280 PUBLIC
struct _magic_dsodesc
* magic_dsodesc_lookup_by_handle(void *handle
)
1282 struct _magic_dsodesc
* desc
= NULL
;
1283 struct _magic_dsodesc
* dsodesc
;
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.
1290 MAGIC_DSODESC_ITER(_magic_first_dsodesc
, dsodesc
,
1291 if(dsodesc
->handle
== handle
) {
1300 /*===========================================================================*
1301 * magic_print_function *
1302 *===========================================================================*/
1303 PUBLIC
void magic_print_function(struct _magic_function
*function
)
1305 MAGIC_FUNCTION_PRINT(function
, MAGIC_EXPAND_TYPE_STR
);
1308 /*===========================================================================*
1309 * magic_print_functions *
1310 *===========================================================================*/
1311 PUBLIC
void magic_print_functions()
1314 struct _magic_function
* function
;
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");
1324 /*===========================================================================*
1325 * magic_print_type *
1326 *===========================================================================*/
1327 PUBLIC
void magic_print_type(const struct _magic_type
* type
)
1329 MAGIC_TYPE_PRINT(type
, MAGIC_EXPAND_TYPE_STR
);
1332 /*===========================================================================*
1333 * magic_print_types *
1334 *===========================================================================*/
1335 PUBLIC
void magic_print_types()
1338 struct _magic_type
* type
;
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");
1348 /*===========================================================================*
1349 * magic_type_str_set_print_style *
1350 *===========================================================================*/
1351 PUBLIC
void magic_type_str_set_print_style(const int style
)
1353 magic_type_str_print_style
= style
;
1356 /*===========================================================================*
1357 * magic_type_str_get_print_style *
1358 *===========================================================================*/
1359 PUBLIC
int magic_type_str_get_print_style()
1361 return magic_type_str_print_style
;
1364 /*===========================================================================*
1365 * magic_type_get_nesting_level *
1366 *===========================================================================*/
1367 PRIVATE INLINE
int magic_type_get_nesting_level(const struct _magic_type
* type
,
1371 int nesting_level
= -1;
1373 for(i
=0;i
<level
;i
++) {
1374 if(magic_nested_types
[i
] == type
) {
1380 return nesting_level
;
1383 /*===========================================================================*
1384 * magic_type_str_print *
1385 *===========================================================================*/
1386 PUBLIC
void magic_type_str_print(const struct _magic_type
* type
)
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
);
1395 if(magic_level
== 0) {
1398 else if(magic_counter
>= MAGIC_TYPE_STR_PRINT_MAX
) {
1399 _magic_printf("%%");
1402 else if(magic_level
>= MAGIC_TYPE_STR_PRINT_MAX_LEVEL
) {
1403 _magic_printf("%%");
1407 if(MAGIC_TYPE_STR_PRINT_DEBUG
) {
1408 _magic_printf("Entering level %d...\n", magic_level
);
1411 if(type
->type_id
== MAGIC_TYPE_OPAQUE
) {
1412 _magic_printf("opaque");
1413 magic_counter
+= strlen("opaque");
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
;
1427 _magic_printf("%s/%s", type
->type_str
, type
->name
);
1428 magic_counter
+= strlen(type
->type_str
)+1+strlen(type
->name
);
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
);
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
;
1441 _magic_printf(type
->name
);
1442 magic_counter
+= strlen(type
->name
);
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
);
1457 magic_nested_types
[magic_level
] = type
;
1459 if(type
->type_id
== MAGIC_TYPE_POINTER
) {
1460 magic_type_str_print(type
->contained_types
[0]);
1463 if(print_multi_names
) {
1465 magic_type_names_print(type
);
1466 magic_counter
+= 1+strlen(type
->name
)*type
->num_names
;
1468 else if(print_ptr_name
) {
1470 _magic_printf("%s", type
->name
);
1471 magic_counter
+= 1+strlen(type
->name
);
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
);
1480 if(MAGIC_TYPE_FLAG(type
, MAGIC_TYPE_VARSIZE
)) {
1481 _magic_printf(" (V) ");
1485 _magic_printf("%d x ", num_elements
);
1488 magic_type_str_print(type
->contained_types
[0]);
1489 _magic_printf("%c", end_sep
);
1492 else if(type
->type_id
== MAGIC_TYPE_STRUCT
|| type
->type_id
== MAGIC_TYPE_UNION
) {
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("{ ");
1498 if(type
->type_id
== MAGIC_TYPE_UNION
) {
1499 _magic_printf("(U) ");
1502 if(print_multi_names
) {
1504 magic_type_names_print(type
);
1506 magic_counter
+= 2 + strlen(type
->name
)*type
->num_names
;
1509 _magic_printf("$%s ", strcmp(type
->name
, "") ? type
->name
: "ANONYMOUS");
1510 magic_counter
+= 2 + strlen(strcmp(type
->name
, "") ? type
->name
: "ANONYMOUS");
1512 assert(type
->member_names
);
1513 if(!skip_struct
&& !skip_union
) {
1514 for(i
=0;i
<num_contained_types
;i
++) {
1516 _magic_printf(", ");
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;
1525 magic_type_str_print(type
->contained_types
[i
]);
1528 _magic_printf(" }");
1531 else if(type
->type_id
== MAGIC_TYPE_FUNCTION
) {
1533 assert(num_contained_types
> 0);
1534 magic_type_str_print(type
->contained_types
[0]);
1535 num_contained_types
--;
1536 _magic_printf(" (");
1538 for(i
=0;i
<num_contained_types
;i
++) {
1540 _magic_printf(", ");
1543 magic_type_str_print(type
->contained_types
[i
+1]);
1549 _magic_printf("???[id=%d,child_types=%d,size=%zu]", type
->type_id
, type
->num_child_types
, type
->size
);
1550 magic_counter
+= 30;
1553 if(MAGIC_TYPE_STR_PRINT_DEBUG
) {
1554 _magic_printf("Exiting level %d...\n", magic_level
);
1558 /*===========================================================================*
1559 * magic_type_values_print *
1560 *===========================================================================*/
1561 PUBLIC
void magic_type_values_print(const struct _magic_type
* type
)
1565 if(!MAGIC_TYPE_HAS_VALUE_SET(type
)) {
1568 while(MAGIC_TYPE_HAS_VALUE(type
, i
)) {
1569 int value
= MAGIC_TYPE_VALUE(type
, i
);
1570 _magic_printf("%s%d", (i
==0 ? "" : ", "), value
);
1575 /*===========================================================================*
1576 * magic_type_names_print *
1577 *===========================================================================*/
1578 PUBLIC
void magic_type_names_print(const struct _magic_type
* type
)
1582 for(i
=0;i
<type
->num_names
;i
++) {
1583 _magic_printf("%s%s", (i
==0 ? "" : "|"), type
->names
[i
]);
1587 /*===========================================================================*
1588 * magic_type_comp_types_print *
1589 *===========================================================================*/
1590 PUBLIC
void magic_type_comp_types_print(const struct _magic_type
* type
,
1595 const struct _magic_type
* comp_type
;
1597 if(!MAGIC_TYPE_HAS_COMP_TYPES(type
)) {
1600 MAGIC_TYPE_NUM_COMP_TYPES(type
, &num
);
1601 _magic_printf("#%d", num
);
1602 if(flags
& MAGIC_SKIP_COMP_TYPES
) {
1605 flags
&= ~MAGIC_EXPAND_TYPE_STR
;
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
);
1614 /*===========================================================================*
1615 * magic_type_str_print_from_target *
1616 *===========================================================================*/
1617 PUBLIC
int magic_type_str_print_from_target(void* target
)
1619 int printed_types
=0;
1621 ret
= magic_type_target_walk(target
, NULL
, NULL
,
1622 magic_type_str_print_cb
, &printed_types
);
1626 if(printed_types
== 0) {
1627 _magic_printf("BAD OFFSET");
1629 return printed_types
;
1632 /*===========================================================================*
1633 * magic_type_equals *
1634 *===========================================================================*/
1635 PUBLIC
int magic_type_equals(const struct _magic_type
* type
, const struct _magic_type
* other_type
)
1637 assert(magic_level
< MAGIC_MAX_RECURSIVE_TYPES
);
1639 if(type
== other_type
) {
1642 if(type
->type_id
!= other_type
->type_id
) {
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
);
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
]);
1656 magic_nested_types
[magic_level
] = type
;
1657 magic_nested_types2
[magic_level
] = other_type
;
1659 for(i
=0;i
<num_contained_types
;i
++) {
1660 if(magic_type_equals(type
->contained_types
[i
], other_type
->contained_types
[i
]) == FALSE
) {
1672 /*===========================================================================*
1673 * magic_type_compatible *
1674 *===========================================================================*/
1675 PUBLIC
int magic_type_compatible(const struct _magic_type
* type
, const struct _magic_type
* other_type
, int flags
)
1677 int i
, nesting_level
, num_contained_types
;
1678 assert(magic_level
< MAGIC_MAX_RECURSIVE_TYPES
);
1680 if(type
== other_type
) {
1684 if(type
->type_id
!= other_type
->type_id
) {
1688 if(type
->num_child_types
!= other_type
->num_child_types
) {
1692 if(flags
& MAGIC_TYPE_COMPARE_FLAGS
) {
1693 if((type
->flags
& (~MAGIC_TYPE_IS_ROOT
)) != (other_type
->flags
& (~MAGIC_TYPE_IS_ROOT
))){
1698 if(flags
& MAGIC_TYPE_COMPARE_VALUE_SET
) {
1699 if(MAGIC_TYPE_HAS_VALUE_SET(type
) != MAGIC_TYPE_HAS_VALUE_SET(other_type
)){
1702 if(MAGIC_TYPE_HAS_VALUE_SET(type
)){
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 */
1711 if(MAGIC_TYPE_HAS_VALUE(type
, i
) || MAGIC_TYPE_HAS_VALUE(other_type
, i
)) {
1717 if(flags
& MAGIC_TYPE_COMPARE_NAME
) {
1718 if(strcmp(type
->name
, other_type
->name
)){
1723 if(flags
& MAGIC_TYPE_COMPARE_NAMES
) {
1724 if(type
->num_names
!= other_type
->num_names
) {
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
])) {
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
);
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
])) {
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
]) {
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
]);
1762 magic_nested_types
[magic_level
] = type
;
1763 magic_nested_types2
[magic_level
] = other_type
;
1765 for(i
=0;i
<num_contained_types
;i
++) {
1766 if(!magic_type_compatible(type
->contained_types
[i
], other_type
->contained_types
[i
], flags
)) {
1775 /*===========================================================================*
1776 * magic_type_comp_compatible *
1777 *===========================================================================*/
1778 PUBLIC
int magic_type_comp_compatible(const struct _magic_type
* type
, const struct _magic_type
* other_type
)
1780 const struct _magic_type
*comp_type
;
1782 MAGIC_TYPE_COMP_ITER(type
, comp_type
,
1783 if(magic_type_compatible(comp_type
, other_type
, 0)) {
1791 /*===========================================================================*
1792 * magic_type_ptr_is_text *
1793 *===========================================================================*/
1794 PUBLIC
int magic_type_ptr_is_text(const struct _magic_type
* ptr_type
)
1796 const struct _magic_type
*comp_type
;
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])) {
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
)) {
1814 /*===========================================================================*
1815 * magic_type_ptr_is_data *
1816 *===========================================================================*/
1817 PUBLIC
int magic_type_ptr_is_data(const struct _magic_type
* ptr_type
)
1819 const struct _magic_type
*comp_type
;
1821 assert(ptr_type
->type_id
== MAGIC_TYPE_POINTER
);
1822 if(ptr_type
->contained_types
[0]->type_id
!= MAGIC_TYPE_FUNCTION
) {
1826 MAGIC_TYPE_COMP_ITER(ptr_type
, comp_type
,
1827 if(comp_type
->type_id
!= MAGIC_TYPE_FUNCTION
) {
1835 /*===========================================================================*
1836 * magic_type_alloc_needs_varsized_array *
1837 *===========================================================================*/
1838 PUBLIC
int magic_type_alloc_needs_varsized_array(const struct _magic_type
* type
,
1839 size_t alloc_size
, int *num_elements
)
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
)) {
1847 assert(type
->type_id
== MAGIC_TYPE_STRUCT
);
1849 if(alloc_size
<= type
->size
|| type
->num_child_types
== 0) {
1852 array_type
= type
->contained_types
[type
->num_child_types
-1];
1853 if(array_type
->type_id
!= MAGIC_TYPE_ARRAY
) {
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) {
1863 *num_elements
= 1+array_size
/array_el_type
->size
;
1869 /*===========================================================================*
1870 * magic_type_alloc_get_varsized_array_size *
1871 *===========================================================================*/
1872 PUBLIC
size_t magic_type_alloc_get_varsized_array_size(const struct _magic_type
* type
,
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
)) {
1881 assert(type
->type_id
== MAGIC_TYPE_STRUCT
);
1883 if(num_elements
== 1) {
1886 array_type
= type
->contained_types
[type
->num_child_types
-1];
1887 if(array_type
->type_id
!= MAGIC_TYPE_ARRAY
) {
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);
1895 /*===========================================================================*
1896 * magic_type_parse_varsized_array *
1897 *===========================================================================*/
1898 PUBLIC
void magic_type_parse_varsized_array(const struct _magic_type
*type
,
1899 const struct _magic_type
**sub_struct_type
, const struct _magic_type
**sub_array_type
,
1900 size_t *sub_array_offset
, size_t *sub_array_size
)
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
;
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
));
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
;
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
;
1921 /*===========================================================================*
1922 * magic_type_walk_flags *
1923 *===========================================================================*/
1924 PUBLIC
int magic_type_walk_flags(const struct _magic_type
* parent_type
,
1925 unsigned parent_offset
, int child_num
,
1926 const struct _magic_type
* type
, unsigned offset
,
1927 const unsigned min_offset
, const unsigned max_offset
,
1928 const magic_type_walk_cb_t cb
, void* cb_args
, int flags
) {
1929 static THREAD_LOCAL
int magic_depth
= 0;
1930 int ret
, status
, action
;
1931 ret
= MAGIC_TYPE_WALK_CONTINUE
;
1933 if(offset
>= min_offset
&& offset
<= max_offset
) {
1934 ret
= cb(parent_type
, parent_offset
, child_num
, type
, offset
, magic_depth
, cb_args
);
1936 else if(offset
> max_offset
) {
1937 ret
= MAGIC_TYPE_WALK_STOP
;
1939 else if(offset
+type
->size
<= min_offset
) {
1940 ret
= MAGIC_TYPE_WALK_SKIP_PATH
;
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.
1947 status
= ret
< 0 ? ret
: 0;
1948 action
= ret
< 0 ? MAGIC_TYPE_WALK_STOP
: ret
;
1950 case MAGIC_TYPE_WALK_STOP
:
1951 status
= status
? status
: MAGIC_TYPE_WALK_STOP
;
1953 case MAGIC_TYPE_WALK_SKIP_PATH
:
1956 case MAGIC_TYPE_WALK_CONTINUE
:
1957 if(!MAGIC_TYPE_IS_WALKABLE(type
)) {
1961 int i
, num_child_types
, start
;
1962 num_child_types
= type
->num_child_types
;
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
);
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
);
1975 status
= magic_type_walk_flags(type
, offset
, i
, child_type
, offset
+child_offset
, min_offset
, max_offset
, cb
, cb_args
, flags
);
1977 if(status
< 0 || status
== MAGIC_TYPE_WALK_STOP
) {
1984 _magic_printf("magic_type_walk: unrecognized callback return code: %d, stopping type walk...\n", action
);
1985 status
= MAGIC_TYPE_WALK_STOP
;
1991 /*===========================================================================*
1992 * magic_type_target_walk *
1993 *===========================================================================*/
1994 PUBLIC
int magic_type_target_walk(void *target
,
1995 struct _magic_dsentry
**trg_dsentry
, struct _magic_dfunction
**trg_dfunction
,
1996 const magic_type_walk_cb_t cb
, void *cb_args
)
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
;
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
;
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
;
2017 assert(sentry
|| function
);
2018 if (magic_reentrant
) {
2021 if (MAGIC_STATE_FLAG(sentry
, MAGIC_STATE_DYNAMIC
)) {
2022 magic_copy_dsentry(MAGIC_DSENTRY_FROM_SENTRY(sentry
), *trg_dsentry
);
2025 memcpy(MAGIC_DSENTRY_TO_SENTRY(*trg_dsentry
), sentry
, sizeof(struct _magic_sentry
));
2028 if (trg_dfunction
) {
2029 *trg_dfunction
= NULL
;
2033 if (trg_dfunction
) {
2034 if (MAGIC_STATE_FLAG(function
, MAGIC_STATE_DYNAMIC
)) {
2035 magic_copy_dfunction(MAGIC_DFUNCTION_FROM_FUNCTION(function
), *trg_dfunction
);
2038 memcpy(MAGIC_DFUNCTION_TO_FUNCTION(*trg_dfunction
), function
, sizeof(struct _magic_function
));
2042 *trg_dsentry
= NULL
;
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
2056 *trg_dsentry
= MAGIC_DSENTRY_FROM_SENTRY(sentry
);
2058 if (trg_dfunction
) {
2059 *trg_dfunction
= NULL
;
2063 if (trg_dfunction
) {
2064 *trg_dfunction
= MAGIC_DFUNCTION_FROM_FUNCTION(function
);
2067 *trg_dsentry
= NULL
;
2073 ret
= magic_type_walk_root_at_offset(sentry
->type
, (char *) target
- (char *) sentry
->address
, cb
, cb_args
);
2075 ret
= magic_type_walk_root_at_offset(function
->type
, (char*) target
- (char*) function
->address
, cb
, cb_args
);
2081 /*===========================================================================*
2082 * magic_type_walk_as_void_array *
2083 *===========================================================================*/
2084 PUBLIC
int magic_type_walk_as_void_array(const struct _magic_type
* parent_type
,
2085 unsigned parent_offset
, int child_num
, const struct _magic_type
* type
,
2086 unsigned offset
, const unsigned min_offset
, const unsigned max_offset
,
2087 const magic_type_walk_cb_t cb
, void* cb_args
)
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
);
2095 /*===========================================================================*
2096 * magic_type_walk_as_ptrint_array *
2097 *===========================================================================*/
2098 PUBLIC
int magic_type_walk_as_ptrint_array(const struct _magic_type
* parent_type
,
2099 unsigned parent_offset
, int child_num
, const struct _magic_type
* type
, void* offset_addr
,
2100 unsigned offset
, const unsigned min_offset
, const unsigned max_offset
,
2101 const magic_type_walk_cb_t cb
, void* cb_args
)
2103 struct _magic_type ptrint_array_type
;
2104 unsigned type_size
= type
->size
;
2105 unsigned addr_diff
= ((unsigned)offset_addr
) % sizeof(void*);
2107 unsigned addr_off_by
= sizeof(void*) - addr_diff
;
2108 if(type_size
<= addr_off_by
) {
2109 return MAGIC_EBADWALK
;
2111 type_size
-= addr_off_by
;
2112 offset_addr
= (void*)((unsigned)offset_addr
+ addr_off_by
);
2113 offset
+= addr_off_by
;
2115 addr_diff
= (((unsigned)offset_addr
)+type_size
) % sizeof(void*);
2117 unsigned addr_off_by
= addr_diff
;
2118 if(type_size
<= addr_off_by
) {
2119 return MAGIC_EBADWALK
;
2121 type_size
-= addr_off_by
;
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
);
2128 /*===========================================================================*
2129 * magic_type_str_print_cb *
2130 *===========================================================================*/
2131 PUBLIC
int magic_type_str_print_cb(const struct _magic_type
* parent_type
,
2132 const unsigned parent_offset
, int child_num
,
2133 const struct _magic_type
* type
, const unsigned offset
, int depth
, void* cb_args
)
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
;
2142 /*===========================================================================*
2143 * magic_type_count_cb *
2144 *===========================================================================*/
2145 PUBLIC
int magic_type_count_cb(const struct _magic_type
* parent_type
,
2146 const unsigned parent_offset
, int child_num
,
2147 const struct _magic_type
* type
, const unsigned offset
, int depth
, void* cb_args
)
2149 int *type_counter
= (int*) cb_args
;
2150 if(type_counter
) (*type_counter
)++;
2151 return MAGIC_TYPE_WALK_CONTINUE
;
2154 /*===========================================================================*
2155 * magic_type_child_offset_cb *
2156 *===========================================================================*/
2157 PUBLIC
int magic_type_child_offset_cb(const struct _magic_type
* parent_type
,
2158 const unsigned parent_offset
, int child_num
,
2159 const struct _magic_type
* type
, const unsigned offset
, int depth
, void* cb_args
)
2161 void **args_array
= (void**) cb_args
;
2162 int *my_child_num
= (int*) args_array
[0];
2163 unsigned *child_offset
= (unsigned*) args_array
[1];
2166 return MAGIC_TYPE_WALK_CONTINUE
;
2168 if(child_num
== *my_child_num
) {
2169 *child_offset
= offset
;
2170 return MAGIC_TYPE_WALK_STOP
;
2172 return MAGIC_TYPE_WALK_SKIP_PATH
;
2175 /*===========================================================================*
2176 * magic_type_walk_step *
2177 *===========================================================================*/
2178 PUBLIC
void magic_type_walk_step(const struct _magic_type
*type
,
2179 int child_num
, const struct _magic_type
**child_type
, unsigned *child_offset
,
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
);
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
];
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
;
2204 *child_type
= type
->contained_types
[0];
2205 *child_offset
= child_num
*((*child_type
)->size
);
2210 /*===========================================================================*
2211 * magic_type_get_size *
2212 *===========================================================================*/
2213 PUBLIC
size_t magic_type_get_size(struct _magic_type
*type
, int flags
)
2216 int i
, num_contained_types
;
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
);
2223 if(num_contained_types
> 0) {
2224 size
+= sizeof(*(type
->contained_types
))*num_contained_types
;
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;
2236 if(flags
& MAGIC_SIZE_VALUE_SET
) {
2237 if(MAGIC_TYPE_HAS_VALUE_SET(type
)) {
2239 MAGIC_TYPE_NUM_VALUES(type
, &num
);
2240 size
+= sizeof(int)+(num
+1);
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;
2249 if(flags
& MAGIC_SIZE_COMP_TYPES
) {
2250 if(MAGIC_TYPE_HAS_COMP_TYPES(type
)) {
2252 MAGIC_TYPE_NUM_COMP_TYPES(type
, &num
);
2253 size
+= sizeof(*(type
->compatible_types
))*num
;
2260 /*===========================================================================*
2261 * magic_types_get_size *
2262 *===========================================================================*/
2263 PUBLIC
size_t magic_types_get_size(int flags
)
2269 for(i
=0;i
<_magic_types_num
;i
++) {
2270 size
+= magic_type_get_size(&_magic_types
[i
], flags
);
2276 /*===========================================================================*
2277 * magic_function_get_size *
2278 *===========================================================================*/
2279 PUBLIC
size_t magic_function_get_size(struct _magic_function
*function
, int flags
)
2283 size
= sizeof(function
->type
) + sizeof(function
->flags
) + sizeof(function
->address
);
2285 if(flags
& MAGIC_SIZE_NAMES
) {
2286 size
+= sizeof(function
->name
) + strlen(function
->name
)+1;
2292 /*===========================================================================*
2293 * magic_functions_get_size *
2294 *===========================================================================*/
2295 PUBLIC
size_t magic_functions_get_size(int flags
)
2301 for(i
=0;i
<_magic_functions_num
;i
++) {
2302 size
+= magic_function_get_size(&_magic_functions
[i
], flags
);
2308 /*===========================================================================*
2309 * magic_dfunctions_get_size *
2310 *===========================================================================*/
2311 PUBLIC
size_t magic_dfunctions_get_size(int flags
)
2314 struct _magic_dfunction
* dfunction
;
2315 struct _magic_function
* function
;
2318 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction
, dfunction
, function
,
2319 size
+= magic_function_get_size(function
, flags
);
2325 /*===========================================================================*
2326 * magic_sentry_get_size *
2327 *===========================================================================*/
2328 PUBLIC
size_t magic_sentry_get_size(struct _magic_sentry
*sentry
, int flags
)
2332 size
= sizeof(sentry
->type
) + sizeof(sentry
->flags
);
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;
2342 if(sentry
->type
== &dsentry
->type
) {
2343 size
+= sizeof(dsentry
->type
.num_child_types
);
2345 size
+= sizeof(dsentry
->next
);
2348 size
+= sizeof(sentry
->address
);
2349 if(flags
& MAGIC_SIZE_NAMES
) {
2350 size
+= sizeof(sentry
->name
) + strlen(sentry
->name
)+1;
2357 /*===========================================================================*
2358 * magic_sentries_get_size *
2359 *===========================================================================*/
2360 PUBLIC
size_t magic_sentries_get_size(int flags
)
2366 for(i
=0;i
<_magic_sentries_num
;i
++) {
2367 size
+= magic_sentry_get_size(&_magic_sentries
[i
], flags
);
2373 /*===========================================================================*
2374 * magic_dsentries_get_size *
2375 *===========================================================================*/
2376 PUBLIC
size_t magic_dsentries_get_size(int flags
)
2379 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
2380 struct _magic_sentry
* sentry
;
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
);
2392 /*===========================================================================*
2393 * magic_dsindex_get_size *
2394 *===========================================================================*/
2395 PUBLIC
size_t magic_dsindex_get_size(struct _magic_dsindex
*dsindex
, int flags
)
2399 size
= sizeof(dsindex
->type
) + sizeof(dsindex
->flags
);
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;
2409 /*===========================================================================*
2410 * magic_dsindexes_get_size *
2411 *===========================================================================*/
2412 PUBLIC
size_t magic_dsindexes_get_size(int flags
)
2418 for(i
=0;i
<_magic_dsindexes_num
;i
++) {
2419 size
+= magic_dsindex_get_size(&_magic_dsindexes
[i
], flags
);
2425 /*===========================================================================*
2426 * magic_sodesc_get_size *
2427 *===========================================================================*/
2428 PUBLIC
size_t magic_sodesc_get_size(struct _magic_sodesc
*sodesc
, int flags
)
2430 return sizeof(struct _magic_sodesc
);
2433 /*===========================================================================*
2434 * magic_sodescs_get_size *
2435 *===========================================================================*/
2436 PUBLIC
size_t magic_sodescs_get_size(int flags
)
2439 struct _magic_sodesc
* sodesc
;
2442 MAGIC_SODESC_ITER(_magic_first_sodesc
, sodesc
,
2443 size
+= magic_sodesc_get_size(sodesc
, flags
);
2449 /*===========================================================================*
2450 * magic_dsodesc_get_size *
2451 *===========================================================================*/
2452 PUBLIC
size_t magic_dsodesc_get_size(struct _magic_dsodesc
*dsodesc
, int flags
)
2454 return sizeof(struct _magic_dsodesc
);
2457 /*===========================================================================*
2458 * magic_dsodescs_get_size *
2459 *===========================================================================*/
2460 PUBLIC
size_t magic_dsodescs_get_size(int flags
)
2463 struct _magic_dsodesc
* dsodesc
;
2466 MAGIC_DSODESC_ITER(_magic_first_dsodesc
, dsodesc
,
2467 size
+= magic_dsodesc_get_size(dsodesc
, flags
);
2473 /*===========================================================================*
2474 * magic_metadata_get_size *
2475 *===========================================================================*/
2476 PUBLIC
size_t magic_metadata_get_size(int flags
)
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
);
2491 /*===========================================================================*
2492 * magic_sentries_data_get_size *
2493 *===========================================================================*/
2494 PUBLIC
size_t magic_sentries_data_get_size(int flags
)
2500 for(i
=0;i
<_magic_sentries_num
;i
++) {
2501 size
+= _magic_sentries
[i
].type
->size
;
2507 /*===========================================================================*
2508 * magic_dsentries_data_get_size *
2509 *===========================================================================*/
2510 PUBLIC
size_t magic_dsentries_data_get_size(int flags
)
2513 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
2514 struct _magic_sentry
* sentry
;
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*);
2530 /*===========================================================================*
2531 * magic_other_data_get_size *
2532 *===========================================================================*/
2533 PUBLIC
size_t magic_other_data_get_size(int flags
)
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
);
2546 /*===========================================================================*
2547 * magic_data_get_size *
2548 *===========================================================================*/
2549 PUBLIC
size_t magic_data_get_size(int flags
)
2553 size
+= magic_sentries_data_get_size(flags
);
2554 size
+= magic_dsentries_data_get_size(flags
);
2555 size
+= magic_other_data_get_size(flags
);
2560 /*===========================================================================*
2561 * magic_print_size_stats *
2562 *===========================================================================*/
2563 PUBLIC
void magic_print_size_stats(int flags
)
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
;
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");