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