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