xref: /minix3/minix/lib/libmagicrt/include/magic_analysis.h (revision b2ed49a5d83e311ee0fa9e5ff613639b1bf77aaf)
1 #ifndef _MAGIC_ANALYSIS_H
2 #define _MAGIC_ANALYSIS_H
3 
4 #include <magic.h>
5 #include <magic_mem.h>
6 
7 /* Special convenience types. */
8 #define MAGIC_TYPE_SPECIAL_INIT(STR) { 0, STR, NULL, 0, STR, 0, 0, 0, 0, 0, 0, \
9     0, MAGIC_TYPE_FUNCTION, MAGIC_TYPE_EXTERNAL, 0, NULL }
10 EXTERN char magic_ne_str[];
11 EXTERN char magic_enf_str[];
12 EXTERN char magic_bo_str[];
13 EXTERN char magic_be_str[];
14 EXTERN char magic_bv_str[];
15 EXTERN char magic_vf_str[];
16 EXTERN const struct _magic_type magic_NULL_ENTRY_TYPE;
17 EXTERN const struct _magic_type magic_ENTRY_NOT_FOUND_TYPE;
18 EXTERN const struct _magic_type magic_BAD_OFFSET_TYPE;
19 EXTERN const struct _magic_type magic_BAD_ENTRY_TYPE;
20 EXTERN const struct _magic_type magic_BAD_VALUE_TYPE;
21 EXTERN const struct _magic_type magic_VALUE_FOUND;
22 #define MAGIC_TYPE_NULL_ENTRY               (&magic_NULL_ENTRY_TYPE)
23 #define MAGIC_TYPE_ENTRY_NOT_FOUND          (&magic_ENTRY_NOT_FOUND_TYPE)
24 #define MAGIC_TYPE_BAD_OFFSET               (&magic_BAD_OFFSET_TYPE)
25 #define MAGIC_TYPE_BAD_ENTRY                (&magic_BAD_ENTRY_TYPE)
26 #define MAGIC_TYPE_BAD_VALUE                (&magic_BAD_VALUE_TYPE)
27 #define MAGIC_TYPE_VALUE_FOUND              (&magic_VALUE_FOUND)
28 #define MAGIC_TYPE_IS_SPECIAL(T) (T == MAGIC_TYPE_NULL_ENTRY                   \
29     || T == MAGIC_TYPE_ENTRY_NOT_FOUND || T == MAGIC_TYPE_BAD_OFFSET           \
30     || T == MAGIC_TYPE_BAD_ENTRY || T == MAGIC_TYPE_BAD_VALUE                  \
31     || T == MAGIC_TYPE_VALUE_FOUND)
32 
33 /* Magic state element macros. */
34 #define MAGIC_SEL_ANALYZE_POINTERS          0x00001
35 #define MAGIC_SEL_ANALYZE_NONPOINTERS       0x00002
36 #define MAGIC_SEL_ANALYZE_LIKELYPOINTERS    0x00004
37 #define MAGIC_SEL_ANALYZE_DATA              0x00008
38 #define MAGIC_SEL_ANALYZE_INVARIANTS        0x00010
39 #define MAGIC_SEL_ANALYZE_VIOLATIONS        0x00020
40 #define MAGIC_SEL_ANALYZE_WALKABLE          0x00040
41 #define MAGIC_SEL_ANALYZE_DYNAMIC           0x00080
42 #define MAGIC_SEL_ANALYZE_OUT_OF_BAND       0x00100
43 #define MAGIC_SEL_ANALYZE_LIB_SRC           0x00200
44 #define MAGIC_SEL_ANALYZE_ALL                                                  \
45     (MAGIC_SEL_ANALYZE_POINTERS | MAGIC_SEL_ANALYZE_NONPOINTERS                \
46     | MAGIC_SEL_ANALYZE_DATA | MAGIC_SEL_ANALYZE_INVARIANTS                    \
47     | MAGIC_SEL_ANALYZE_VIOLATIONS | MAGIC_SEL_ANALYZE_WALKABLE                \
48     | MAGIC_SEL_ANALYZE_DYNAMIC | MAGIC_SEL_ANALYZE_OUT_OF_BAND                \
49     | MAGIC_SEL_ANALYZE_LIB_SRC)
50 
51 #define MAGIC_SEL_SKIP_UNIONS               0x00400
52 #define MAGIC_SEL_SKIP_INTEGERS             0x00800
53 #define MAGIC_SEL_ANALYZE_NONPTRS_AS_PTRS   0x01000
54 #define MAGIC_SEL_ANALYZE_RETURN_TRG_PTRS   0x02000
55 
56 #define MAGIC_SEL_FOUND_DATA                0x04000
57 #define MAGIC_SEL_FOUND_INVARIANTS          0x08000
58 #define MAGIC_SEL_FOUND_VIOLATIONS          0X10000
59 #define MAGIC_SEL_FOUND_WALKABLE            0x20000
60 
61 /* Magic state element analyzed. */
62 typedef enum {
63     _ptr_type_found,
64     _other_types_found,
65     _void_type_found,
66     _comp_trg_types_found,
67     _badentry_found
68 } _magic_trg_stats_t;
69 struct _magic_sel_analyzed_s {
70     unsigned type_id, contained_type_id;
71     int flags;
72     int num;
73     union {
74         struct {
75             void *value;
76             union {
77                 struct _magic_dsentry dsentry;
78                 struct _magic_dfunction dfunction;
79             } trg;
80             struct {
81                 struct _magic_dsentry *dsentry;
82                 struct _magic_dfunction *dfunction;
83             } trg_p;
84             int trg_flags;
85             int trg_offset;
86             _magic_selement_t trg_selements[MAGIC_MAX_RECURSIVE_TYPES + 1];
87             _magic_trg_stats_t trg_stats[MAGIC_MAX_RECURSIVE_TYPES + 1];
88             int first_legal_trg_type;
89             unsigned num_legal_trg_types;
90             unsigned num_trg_types;
91         } ptr;
92         struct {
93             int value;
94             int trg_flags;
95         } nonptr;
96     } u;
97 };
98 typedef struct _magic_sel_analyzed_s _magic_sel_analyzed_t;
99 
100 #define MAGIC_SEL_ANALYZED_PTR_HAS_TRG_FUNCTION(E)                             \
101     (((E)->u.ptr.trg_flags & MAGIC_STATE_TEXT) != 0)
102 #define MAGIC_SEL_ANALYZED_PTR_HAS_TRG_SENTRY(E)                               \
103     ((E)->u.ptr.trg_flags && !MAGIC_SEL_ANALYZED_PTR_HAS_TRG_FUNCTION(E))
104 #define MAGIC_SEL_ANALYZED_PTR_SENTRY(E)                                       \
105     ((E)->u.ptr.trg_flags & MAGIC_SEL_ANALYZE_RETURN_TRG_PTRS)                 \
106     ? (E)->u.ptr.trg_p.dsentry->sentry                                         \
107     : (E)->u.ptr.trg.dsentry.sentry
108 #define MAGIC_SEL_ANALYZED_PTR_SENTRY_ADDRESS(E)                               \
109     ((E)->u.ptr.trg_flags & MAGIC_SEL_ANALYZE_RETURN_TRG_PTRS)                 \
110     ? &((E)->u.ptr.trg_p.dsentry->sentry)                                      \
111     : &((E)->u.ptr.trg.dsentry.sentry)
112 #define MAGIC_SEL_ANALYZED_PTR_FUNCTION(E)                                     \
113     ((E)->u.ptr.trg_flags & MAGIC_SEL_ANALYZE_RETURN_TRG_PTRS)                 \
114     ? (E)->u.ptr.trg_p.dfunction->function                                     \
115     : (E)->u.ptr.trg.dfunction.function
116 #define MAGIC_SEL_ANALYZED_PTR_TRG_NAME(E)                                     \
117     (MAGIC_SEL_ANALYZED_PTR_HAS_SPECIAL_TRG_TYPE(E) ? ""                       \
118     : MAGIC_SEL_ANALYZED_PTR_HAS_TRG_FUNCTION(E)                               \
119     ? (MAGIC_SEL_ANALYZED_PTR_FUNCTION(E)).name                                \
120     : (MAGIC_SEL_ANALYZED_PTR_HAS_TRG_SENTRY(E)                                \
121     ? (MAGIC_SEL_ANALYZED_PTR_SENTRY(E)).name : "?"))
122 #define MAGIC_SEL_ANALYZED_PTR_TRG_ADDRESS(E)                                  \
123     (MAGIC_SEL_ANALYZED_PTR_HAS_SPECIAL_TRG_TYPE(E) ? NULL                     \
124     : MAGIC_SEL_ANALYZED_PTR_HAS_TRG_FUNCTION(E)                               \
125     ? (MAGIC_SEL_ANALYZED_PTR_FUNCTION(E)).address                             \
126     : (MAGIC_SEL_ANALYZED_PTR_SENTRY(E)).address)
127 #define MAGIC_SEL_ANALYZED_PTR_PRINT_TRG_ABS_NAME(E)                           \
128     do {                                                                       \
129         if (MAGIC_SEL_ANALYZED_PTR_HAS_SPECIAL_TRG_TYPE(E)                     \
130             || MAGIC_SEL_ANALYZED_PTR_HAS_TRG_FUNCTION(E)) {                   \
131             _magic_printf(MAGIC_SEL_ANALYZED_PTR_TRG_NAME(E));                 \
132         } else {                                                               \
133             magic_print_sentry_abs_name(                                       \
134                 MAGIC_SEL_ANALYZED_PTR_SENTRY_ADDRESS(E));                     \
135         }                                                                      \
136     } while(0)
137 #define MAGIC_SEL_ANALYZED_PTR_FIRST_TRG_TYPE(E)                               \
138     ((E)->u.ptr.trg_selements[0].type)
139 #define MAGIC_SEL_ANALYZED_PTR_HAS_SPECIAL_TRG_TYPE(E)                         \
140     (MAGIC_TYPE_IS_SPECIAL(MAGIC_SEL_ANALYZED_PTR_FIRST_TRG_TYPE(E)))
141 #define MAGIC_SEL_ANALYZED_PTR_SET_SPECIAL_TRG_TYPE(E,T)                       \
142     do {                                                                       \
143         (E)->u.ptr.trg_selements[0].type = T;                                  \
144         (E)->u.ptr.num_trg_types = 1;                                          \
145         (E)->u.ptr.num_legal_trg_types = 0;                                    \
146         (E)->u.ptr.first_legal_trg_type = -1;                                  \
147     } while(0)
148 #define MAGIC_SEL_ANALYZED_TRG_FLAGS(E)                                        \
149     ((E)->type_id == MAGIC_TYPE_POINTER ? (E)->u.ptr.trg_flags                 \
150     : (E)->u.nonptr.trg_flags)
151 #define MAGIC_SEL_ANALYZED_FLAG(E,F) (((E)->flags & F) != 0)
152 #define MAGIC_SEL_ANALYZED_TRG_STATS_HAS_VIOLATIONS(E)                         \
153     ((E) == _other_types_found || (E) == _badentry_found)
154 #define MAGIC_SEL_ANALYZED_TRG_STATS_C(E)                                      \
155     ((E) == _ptr_type_found ? 'p' : (E) == _other_types_found ? 'o'            \
156     : (E) == _void_type_found ? 'v' : (E) == _comp_trg_types_found ? 'c'       \
157     : (E) == _badentry_found ? 'b' : '?')
158 
159 #define MAGIC_SEL_ANALYZED_PRINT(E, FLAGS) do {                                \
160         _magic_printf("SEL_ANALYZED: (num=%d, type=%s, flags(DIVW)=%d%d%d%d",  \
161             (E)->num, (E)->type_id == MAGIC_TYPE_POINTER ? "ptr" : "nonptr",   \
162             MAGIC_SEL_ANALYZED_FLAG(E, MAGIC_SEL_FOUND_DATA),                  \
163             MAGIC_SEL_ANALYZED_FLAG(E, MAGIC_SEL_FOUND_INVARIANTS),            \
164             MAGIC_SEL_ANALYZED_FLAG(E, MAGIC_SEL_FOUND_VIOLATIONS),            \
165             MAGIC_SEL_ANALYZED_FLAG(E, MAGIC_SEL_FOUND_WALKABLE));             \
166         if((E)->type_id == MAGIC_TYPE_POINTER) {                               \
167             _magic_printf(", value=0x%08x, trg_name=", (E)->u.ptr.value);      \
168             MAGIC_SEL_ANALYZED_PTR_PRINT_TRG_ABS_NAME(E);                      \
169             _magic_printf(", trg_offset=%d, trg_flags(RL)=%c%c",               \
170                 (E)->u.ptr.trg_offset,                                         \
171                 (E)->u.ptr.trg_flags                                           \
172                     ? MAGIC_STATE_FLAGS_REGION_C((E)->u.ptr.trg_flags) : 0,    \
173                 (E)->u.ptr.trg_flags                                           \
174                     ? MAGIC_STATE_FLAGS_LIBSPEC_C((E)->u.ptr.trg_flags) : 0);  \
175             if((E)->u.ptr.num_trg_types > 0) {                                 \
176                 _magic_printf(", trg_selements=(");                            \
177                 magic_sel_analyzed_trg_selements_print(E, FLAGS);              \
178                 _magic_printf(")");                                            \
179             }                                                                  \
180         } else {                                                               \
181             _magic_printf(", value=%d/0x%08x",                                 \
182                 (E)->u.nonptr.value, (E)->u.nonptr.value);                     \
183             if((E)->u.nonptr.trg_flags) {                                      \
184                 _magic_printf(", trg_flags(RL)=%c%c",                          \
185                     MAGIC_STATE_FLAGS_REGION_C((E)->u.nonptr.trg_flags),       \
186                     MAGIC_STATE_FLAGS_LIBSPEC_C((E)->u.nonptr.trg_flags));     \
187             }                                                                  \
188         }                                                                      \
189         _magic_printf(")");                                                    \
190     } while(0)
191 
192 /* Magic state element stats. */
193 struct _magic_sel_stats_s {
194     unsigned ptr_found;
195     unsigned nonptr_found;
196     unsigned nonptr_unconstrained_found;
197     int trg_flags;
198     int ptr_type_found;
199     int other_types_found;
200     int null_type_found;
201     int badoffset_found;
202     int unknown_found;
203     int void_type_found;
204     int comp_trg_types_found;
205     int value_found;
206     int badvalue_found;
207     int badentry_found;
208 };
209 typedef struct _magic_sel_stats_s _magic_sel_stats_t;
210 
211 /* Magic state element stats. */
212 #define MAGIC_SEL_STAT_INCR(S,I,F) ((S)->F += (I)->F)
213 #define MAGIC_SEL_STATS_INCR(S,I) do {                                         \
214         MAGIC_SEL_STAT_INCR(S,I, ptr_found);                                   \
215         MAGIC_SEL_STAT_INCR(S,I, nonptr_found);                                \
216         MAGIC_SEL_STAT_INCR(S,I, nonptr_unconstrained_found);                  \
217         S->trg_flags |= I->trg_flags;                                          \
218         MAGIC_SEL_STAT_INCR(S,I, ptr_type_found);                              \
219         MAGIC_SEL_STAT_INCR(S,I, other_types_found);                           \
220         MAGIC_SEL_STAT_INCR(S,I, null_type_found);                             \
221         MAGIC_SEL_STAT_INCR(S,I, badoffset_found);                             \
222         MAGIC_SEL_STAT_INCR(S,I, unknown_found);                               \
223         MAGIC_SEL_STAT_INCR(S,I, void_type_found);                             \
224         MAGIC_SEL_STAT_INCR(S,I, comp_trg_types_found);                        \
225         MAGIC_SEL_STAT_INCR(S,I, value_found);                                 \
226         MAGIC_SEL_STAT_INCR(S,I, badvalue_found);                              \
227         MAGIC_SEL_STAT_INCR(S,I, badentry_found);                              \
228     } while(0)
229 
230 #define MAGIC_SEL_STATS_HAS_VIOLATIONS(S)                                      \
231     (MAGIC_SEL_STATS_NUM_VIOLATIONS(S) > 0)
232 #define MAGIC_SEL_STATS_NUM_VIOLATIONS(S)                                      \
233     ((S)->ptr_found ? MAGIC_SEL_PTR_STATS_NUM_VIOLATIONS(S)                    \
234         : MAGIC_SEL_NONPTR_STATS_NUM_VIOLATIONS(S))
235 #define MAGIC_SEL_PTR_STATS_NUM_VIOLATIONS(S) ((S)->other_types_found          \
236     + (S)->badoffset_found + (S)->unknown_found + (S)->badvalue_found          \
237     + (S)->badentry_found)
238 #define MAGIC_SEL_NONPTR_STATS_NUM_VIOLATIONS(S) ((S)->badvalue_found)
239 
240 #define MAGIC_SEL_STATS_PRINT(E) do {                                          \
241         _magic_printf("SEL_STATS: (type=%s",                                   \
242             (E)->ptr_found ? "ptr" : "nonptr");                                \
243         if((E)->trg_flags) {                                                   \
244             _magic_printf(", trg_flags(RL)=%c%c",                              \
245                 MAGIC_STATE_FLAGS_REGION_C((E)->trg_flags),                    \
246                 MAGIC_STATE_FLAGS_LIBSPEC_C((E)->trg_flags));                  \
247         }                                                                      \
248         if((E)->ptr_found) _magic_printf(", ptr_found=%d", (E)->ptr_found);    \
249         if((E)->nonptr_found)                                                  \
250             _magic_printf(", nonptr_found=%d", (E)->nonptr_found);             \
251         if((E)->nonptr_unconstrained_found)                                    \
252             _magic_printf(", nonptr_unconstrained_found=%d",                   \
253                 (E)->nonptr_unconstrained_found);                              \
254         if((E)->ptr_type_found)                                                \
255             _magic_printf(", ptr_type_found=%d", (E)->ptr_type_found);         \
256         if((E)->other_types_found)                                             \
257             _magic_printf(", other_types_found=%d", (E)->other_types_found);   \
258         if((E)->null_type_found)                                               \
259             _magic_printf(", null_type_found=%d", (E)->null_type_found);       \
260         if((E)->badoffset_found)                                               \
261             _magic_printf(", badoffset_found=%d", (E)->badoffset_found);       \
262         if((E)->unknown_found)                                                 \
263             _magic_printf(", unknown_found=%d", (E)->unknown_found);           \
264         if((E)->void_type_found)                                               \
265             _magic_printf(", void_type_found=%d", (E)->void_type_found);       \
266         if((E)->comp_trg_types_found)                                          \
267             _magic_printf(", comp_trg_types_found=%d",                         \
268                 (E)->comp_trg_types_found);                                    \
269         if((E)->value_found)                                                   \
270             _magic_printf(", value_found=%d", (E)->value_found);               \
271         if((E)->badvalue_found)                                                \
272             _magic_printf(", badvalue_found=%d", (E)->badvalue_found);         \
273         if((E)->badentry_found)                                                \
274             _magic_printf(", badentry_found=%d", (E)->badentry_found);         \
275         _magic_printf(", violations=%d", MAGIC_SEL_STATS_NUM_VIOLATIONS(E));   \
276         _magic_printf(")");                                                    \
277     } while(0)
278 
279 /* Magic sentry macros. */
280 #define MAGIC_SENTRY_ANALYZE_STOP           1
281 #define MAGIC_SENTRY_ANALYZE_CONTINUE       2
282 #define MAGIC_SENTRY_ANALYZE_SKIP_PATH      3
283 #define MAGIC_SENTRY_ANALYZE_IS_VALID_RET(R)                                   \
284    ((R)>=MAGIC_SENTRY_ANALYZE_STOP && (R)<=MAGIC_SENTRY_ANALYZE_SKIP_PATH)
285 
286 #ifndef __MINIX
287 #define MAGIC_PTR_LIKELY_INTS_START         0xFFFFF000
288 #else
289 #define MAGIC_PTR_LIKELY_INTS_START         0xE0000000
290 #endif
291 #define MAGIC_PTR_LIKELY_INTS_END           0xFFF
292 #define MAGIC_PTR_IS_LIKELY_INT(V)                                             \
293     ((V) && ((unsigned)(V)>=MAGIC_PTR_LIKELY_INTS_START                        \
294     || (unsigned)(V)<=MAGIC_PTR_LIKELY_INTS_END))
295 #define MAGIC_INT_IS_LIKELY_PTR(V)                                             \
296     ((V) && !MAGIC_PTR_IS_LIKELY_INT((void*)V))
297 
298 /* Magic callbacks. */
299 typedef int (*magic_cb_sentries_analyze_pre_t)(void);
300 PUBLIC void magic_setcb_sentries_analyze_pre(magic_cb_sentries_analyze_pre_t cb);
301 
302 /* Magic state entry functions. */
303 typedef int (*magic_sentry_analyze_cb_t)(_magic_selement_t* selement,
304     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats,
305     void* cb_args);
306 PUBLIC int magic_sentry_print_ptr_types(struct _magic_sentry* entry);
307 PUBLIC int magic_sentry_extract_ptrs(struct _magic_sentry* entry,
308     void ****ptr_map, const struct _magic_type ***ptr_type_map, int *ptr_num);
309 PUBLIC int magic_sentry_analyze(struct _magic_sentry* sentry, int flags,
310     const magic_sentry_analyze_cb_t cb, void* cb_args,
311     _magic_sel_stats_t *sentry_stats);
312 PUBLIC int magic_sentries_analyze(int flags, const magic_sentry_analyze_cb_t cb,
313     void* cb_args, _magic_sel_stats_t *sentries_stats);
314 PUBLIC int magic_sentry_print_selements(struct _magic_sentry* sentry);
315 PUBLIC int magic_sentry_print_ptr_selements(struct _magic_sentry* sentry,
316     int skip_null_ptrs, int max_target_recusions);
317 
318 /* Magic dynamic state entry functions. */
319 PUBLIC int magic_dsentries_analyze(int flags,
320     const magic_sentry_analyze_cb_t cb, void* cb_args,
321     _magic_sel_stats_t *dsentries_stats);
322 
323 /* Magic sentry analyze callbacks. */
324 PUBLIC int magic_sentry_print_el_cb(_magic_selement_t* selement,
325     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats,
326     void* cb_args);
327 PUBLIC int magic_sentry_print_ptr_el_cb(_magic_selement_t* selement,
328     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats,
329     void* cb_args);
330 PUBLIC int magic_sentry_print_el_with_trg_reg_cb(_magic_selement_t* selement,
331     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats,
332     void* cb_args);
333 PUBLIC int magic_sentry_print_el_with_trg_cb(_magic_selement_t* selement,
334     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats,
335     void* cb_args);
336 
337 /* Magic sentry analyze helpers. */
338 #define magic_sentry_analyze_invariants(sentry, cb, cb_args, sentry_stats)     \
339     magic_sentry_analyze(sentry, MAGIC_SEL_ANALYZE_POINTERS                    \
340         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_INVARIANTS, cb,    \
341         cb_args, sentry_stats)
342 #define magic_sentries_analyze_invariants(cb, cb_args, sentries_stats)         \
343     magic_sentries_analyze(MAGIC_SEL_ANALYZE_POINTERS                          \
344         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_INVARIANTS, cb,    \
345         cb_args, sentries_stats)
346 #define magic_dsentries_analyze_invariants(cb, cb_args, dsentries_stats)       \
347     magic_dsentries_analyze(MAGIC_SEL_ANALYZE_POINTERS                         \
348         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_INVARIANTS, cb,    \
349         cb_args, dsentries_stats)
350 #define magic_allsentries_analyze_invariants(cb, cb_args, sentries_stats)      \
351     magic_sentries_analyze(MAGIC_SEL_ANALYZE_POINTERS                          \
352         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_INVARIANTS         \
353         | MAGIC_SEL_ANALYZE_DYNAMIC, cb, cb_args, sentries_stats)
354 
355 #define magic_sentry_analyze_violations(sentry, cb, cb_args, sentry_stats)     \
356     magic_sentry_analyze(sentry, MAGIC_SEL_ANALYZE_POINTERS                    \
357         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_VIOLATIONS, cb,    \
358         cb_args, sentry_stats)
359 #define magic_sentries_analyze_violations(cb, cb_args, sentries_stats)         \
360     magic_sentries_analyze(MAGIC_SEL_ANALYZE_POINTERS                          \
361         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_VIOLATIONS, cb,    \
362         cb_args, sentries_stats)
363 #define magic_dsentries_analyze_violations(cb, cb_args, dsentries_stats)       \
364     magic_dsentries_analyze(MAGIC_SEL_ANALYZE_POINTERS                         \
365         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_VIOLATIONS, cb,    \
366         cb_args, dsentries_stats)
367 #define magic_allsentries_analyze_violations(cb, cb_args, sentries_stats)      \
368     magic_sentries_analyze(MAGIC_SEL_ANALYZE_POINTERS                          \
369         | MAGIC_SEL_ANALYZE_NONPOINTERS | MAGIC_SEL_ANALYZE_VIOLATIONS         \
370         | MAGIC_SEL_ANALYZE_DYNAMIC, cb, cb_args, sentries_stats)
371 
372 #define magic_sentry_analyze_likely_pointers(sentry, cb, cb_args, sentry_stats)\
373     magic_sentry_analyze(sentry, MAGIC_SEL_ANALYZE_LIKELYPOINTERS              \
374         | MAGIC_SEL_ANALYZE_DATA, cb, cb_args, sentry_stats)
375 #define magic_sentries_analyze_likely_pointers(cb, cb_args, sentries_stats)    \
376     magic_sentries_analyze(MAGIC_SEL_ANALYZE_LIKELYPOINTERS                    \
377         | MAGIC_SEL_ANALYZE_DATA, cb, cb_args, sentries_stats)
378 #define magic_dsentries_analyze_likely_pointers(cb, cb_args, dsentries_stats)  \
379     magic_dsentries_analyze(MAGIC_SEL_ANALYZE_LIKELYPOINTERS                   \
380         | MAGIC_SEL_ANALYZE_DATA, cb, cb_args, dsentries_stats)
381 #define magic_allsentries_analyze_likely_pointers(cb, cb_args, sentries_stats) \
382     magic_sentries_analyze(MAGIC_SEL_ANALYZE_LIKELYPOINTERS                    \
383         | MAGIC_SEL_ANALYZE_DATA | MAGIC_SEL_ANALYZE_DYNAMIC, cb, cb_args,     \
384         sentries_stats)
385 
386 /* Magic state type functions. */
387 PUBLIC int magic_type_count_ptrs(const struct _magic_type* type, int *ptr_num);
388 
389 /* Magic type walk callbacks. */
390 PUBLIC int magic_type_examine_ptr_cb(const struct _magic_type* parent_type,
391     const unsigned parent_offset, int child_num, const struct _magic_type* type,
392     const unsigned offset, int depth, void* cb_args);
393 PUBLIC int magic_type_extract_ptr_cb(const struct _magic_type* parent_type,
394     const unsigned parent_offset, int child_num, const struct _magic_type* type,
395     const unsigned offset, int depth, void* cb_args);
396 PUBLIC int magic_type_analyzer_cb(const struct _magic_type* parent_type,
397     const unsigned parent_offset, int child_num, const struct _magic_type* type,
398     const unsigned offset, int depth, void* cb_args);
399 
400 /* Magic state element functions. */
401 PUBLIC int magic_selement_analyze(_magic_selement_t *selement, int flags,
402     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats);
403 PUBLIC int magic_selement_analyze_ptr(_magic_selement_t *selement, int flags,
404     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats);
405 PUBLIC int magic_selement_analyze_nonptr(_magic_selement_t *selement, int flags,
406     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats);
407 PUBLIC int magic_selement_analyze_ptr_value_invs(_magic_selement_t *selement,
408     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats);
409 PUBLIC int magic_selement_analyze_ptr_trg_invs(_magic_selement_t *selement,
410     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats);
411 PUBLIC _magic_trg_stats_t
412 magic_selement_analyze_ptr_target(const struct _magic_type *ptr_type,
413     const struct _magic_type *trg_type, int trg_flags);
414 PUBLIC int magic_selement_analyze_ptr_type_invs(_magic_selement_t *selement,
415     _magic_sel_analyzed_t *sel_analyzed, _magic_sel_stats_t *sel_stats);
416 PUBLIC int magic_selement_recurse_ptr(_magic_selement_t *selement,
417     _magic_selement_t *new_selement, int max_steps);
418 PUBLIC void
419 magic_sel_analyzed_trg_selements_print(_magic_sel_analyzed_t *sel_analyzed,
420     int flags);
421 PUBLIC _magic_selement_t*
422 magic_selement_type_cast(_magic_selement_t *selement, int flags,
423     const struct _magic_type* type, _magic_sel_analyzed_t *sel_analyzed,
424     _magic_sel_stats_t *sel_stats);
425 
426 #endif /* _MAGIC_ANALYSIS_H */
427 
428