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