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