1 #ifndef _MAGIC_SENTRY_H 2 #define _MAGIC_SENTRY_H 3 4 #include <magic.h> 5 #include <magic_def.h> 6 #include <magic_common.h> 7 #include <magic_structs.h> 8 #include <common/ut/utlist.h> 9 10 /* Magic state entry macros. */ 11 #define MAGIC_SENTRY_SITE_ID(E) \ 12 (MAGIC_STATE_FLAG(E, MAGIC_STATE_DYNAMIC) ? \ 13 MAGIC_DSENTRY_FROM_SENTRY(E)->site_id : MAGIC_DSENTRY_SITE_ID_NULL) 14 #define MAGIC_SENTRY_PARENT(E) \ 15 (MAGIC_STATE_FLAG(E, MAGIC_STATE_DYNAMIC) ? \ 16 MAGIC_DSENTRY_FROM_SENTRY(E)->parent_name : "") 17 #define MAGIC_SENTRY_ID(E) ((E)->id) 18 #define MAGIC_SENTRY_IS_STRING(E) MAGIC_STATE_FLAG(E,MAGIC_STATE_STRING) 19 #define MAGIC_SENTRY_IS_NAMED_STRING(E) \ 20 MAGIC_STATE_FLAG(E,MAGIC_STATE_NAMED_STRING) 21 #define MAGIC_SENTRY_IS_DSENTRY(E) MAGIC_STATE_FLAG(E,MAGIC_STATE_DYNAMIC) 22 /* XXX: Be careful when negating the following macros! */ 23 #define MAGIC_SENTRY_IS_ALLOC(E) \ 24 (MAGIC_SENTRY_IS_DSENTRY(E) && !MAGIC_STATE_FLAG(E,MAGIC_STATE_STACK)) 25 #define MAGIC_SENTRY_IS_EXT_ALLOC(E) \ 26 (MAGIC_SENTRY_IS_ALLOC(E) && !strcmp((E)->name, MAGIC_ALLOC_EXT_NAME) && \ 27 !strcmp(MAGIC_DSENTRY_FROM_SENTRY(E)->parent_name, \ 28 MAGIC_ALLOC_EXT_PARENT_NAME)) 29 #define MAGIC_SENTRY_IS_LIB_ALLOC(E) \ 30 (MAGIC_SENTRY_IS_ALLOC(E) && \ 31 !strncmp((E)->name, MAGIC_ALLOC_EXT_NAME, strlen(MAGIC_ALLOC_EXT_NAME)) && \ 32 strlen((E)->name) > strlen(MAGIC_ALLOC_EXT_NAME)) 33 #define MAGIC_SENTRY_PRINT(E, EXPAND_TYPE_STR) do { \ 34 _magic_printf("SENTRY: (id=%5lu, name=%s, parent=%s, address=0x%08x, " \ 35 "flags(RLDCdeTAOSNrwxtpbEZIiP)=" \ 36 "%c%c%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d, type=", \ 37 (unsigned long)MAGIC_SENTRY_ID(E), (E)->name, \ 38 MAGIC_SENTRY_PARENT(E), (unsigned) (E)->address, \ 39 MAGIC_STATE_REGION_C(E), MAGIC_STATE_LIBSPEC_C(E), \ 40 MAGIC_STATE_FLAG(E,MAGIC_STATE_DIRTY), \ 41 MAGIC_STATE_FLAG(E,MAGIC_STATE_CONSTANT), \ 42 MAGIC_STATE_FLAG(E,MAGIC_STATE_DYNAMIC), \ 43 MAGIC_STATE_FLAG(E,MAGIC_STATE_EXT), \ 44 MAGIC_STATE_FLAG(E,MAGIC_STATE_DETACHED), \ 45 MAGIC_STATE_FLAG(E,MAGIC_STATE_ADDR_NOT_TAKEN), \ 46 MAGIC_STATE_FLAG(E,MAGIC_STATE_OUT_OF_BAND), \ 47 MAGIC_STATE_FLAG(E,MAGIC_STATE_STRING), \ 48 MAGIC_STATE_FLAG(E,MAGIC_STATE_NAMED_STRING), \ 49 MAGIC_STATE_FLAG(E,MAGIC_STATE_MODE_R), \ 50 MAGIC_STATE_FLAG(E,MAGIC_STATE_MODE_W), \ 51 MAGIC_STATE_FLAG(E,MAGIC_STATE_MODE_X), \ 52 MAGIC_STATE_FLAG(E,MAGIC_STATE_THREAD_LOCAL), \ 53 MAGIC_STATE_FLAG(E,MAGIC_STATE_MEMPOOL), \ 54 MAGIC_STATE_FLAG(E,MAGIC_STATE_MEMBLOCK), \ 55 MAGIC_STATE_FLAG(E,MAGIC_STATE_EXTERNAL), \ 56 MAGIC_STATE_FLAG(E,MAGIC_STATE_TYPE_SIZE_MISMATCH), \ 57 MAGIC_STATE_FLAG(E,MAGIC_STATE_IMMUTABLE), \ 58 MAGIC_STATE_FLAG(E,MAGIC_STATE_INIT), \ 59 MAGIC_STATE_FLAG(E,MAGIC_STATE_DIRTY_PAGE)); \ 60 MAGIC_TYPE_PRINT((E)->type, EXPAND_TYPE_STR); \ 61 _magic_printf(")"); \ 62 } while(0) 63 64 #define MAGIC_SENTRY_OFF_BY_N_NO_DUPLICATES 0x01 65 #define MAGIC_SENTRY_OFF_BY_N_POSITIVE 0x02 66 #define MAGIC_SENTRY_OFF_BY_N_NEGATIVE 0x04 67 #define MAGIC_SENTRY_OFF_BY_N_ZERO 0x08 68 #define MAGIC_SENTRY_OFF_BY_N_ALL_N (MAGIC_SENTRY_OFF_BY_N_POSITIVE | \ 69 MAGIC_SENTRY_OFF_BY_N_NEGATIVE | MAGIC_SENTRY_OFF_BY_N_ZERO) 70 71 /* Magic state entry array. */ 72 #define _magic_sentries (_magic_vars->sentries) 73 #define _magic_sentries_num (_magic_vars->sentries_num) 74 #define _magic_sentries_str_num (_magic_vars->sentries_str_num) 75 #define _magic_sentries_next_id (_magic_vars->sentries_next_id) 76 77 /* Range lookup index */ 78 #define magic_sentry_rl_buff (_magic_vars->sentry_rl_buff) 79 #define magic_sentry_rl_buff_offset (_magic_vars->sentry_rl_buff_offset) 80 #define magic_sentry_rl_buff_size (_magic_vars->sentry_rl_buff_size) 81 #define magic_sentry_rl_index (_magic_vars->sentry_rl_index) 82 83 /* Hash vars */ 84 #define magic_sentry_hash_buff (_magic_vars->sentry_hash_buff) 85 #define magic_sentry_hash_buff_offset (_magic_vars->sentry_hash_buff_offset) 86 #define magic_sentry_hash_buff_size (_magic_vars->sentry_hash_buff_size) 87 #define magic_sentry_hash_head (_magic_vars->sentry_hash_head) 88 89 /* Estimated maximum number of buckets needed. Increase as necessary. */ 90 #define MAGIC_SENTRY_NAME_EST_MAX_BUCKETS 32768 91 /* 92 * Since we don't support freeing memory, we need to allocate _all_ the 93 * intermediate buckets as well. For simplicity, just assume 1 + 2 + 4 + ... 94 * + 2^n, though it will probably be less than that. 95 */ 96 #define MAGIC_SENTRY_NAME_EST_TOTAL_BUCKETS \ 97 ((MAGIC_SENTRY_NAME_EST_MAX_BUCKETS << 1) - 1) 98 #define MAGIC_SENTRY_NAME_HASH_OVERHEAD \ 99 (MAGIC_SENTRY_NAME_EST_TOTAL_BUCKETS * sizeof(UT_hash_bucket) + \ 100 sizeof(UT_hash_table)) 101 102 #define MAGIC_SENTRY_TO_HASH_EL(sentry, sentry_hash, sentry_list) \ 103 do { \ 104 assert(strlen(sentry->name) + 2 * strlen(MAGIC_DSENTRY_ABS_NAME_SEP) \ 105 + 2 < MAGIC_SENTRY_NAME_MAX_KEY_LEN \ 106 && "Sentry key length too long!"); \ 107 \ 108 sentry_hash->key[0] = 0; \ 109 snprintf(sentry_hash->key, sizeof(sentry_hash->key), \ 110 "%s%s%s" MAGIC_ID_FORMAT, MAGIC_DSENTRY_ABS_NAME_SEP, \ 111 sentry->name, MAGIC_DSENTRY_ABS_NAME_SEP, \ 112 (_magic_id_t) MAGIC_DSENTRY_SITE_ID_NULL); \ 113 sentry_list->sentry = sentry; \ 114 sentry_hash->sentry_list = sentry_list; \ 115 } while (0) 116 117 #define MAGIC_DSENTRY_TO_HASH_EL(dsentry, sentry, sentry_hash, sentry_list) \ 118 do { \ 119 assert(strlen(sentry->name) + strlen(dsentry->parent_name) \ 120 + 2 * strlen(MAGIC_DSENTRY_ABS_NAME_SEP) \ 121 + 10 + \ 122 + 1 < MAGIC_SENTRY_NAME_MAX_KEY_LEN \ 123 && "Dsentry key length too long!"); \ 124 \ 125 sentry_hash->key[0] = 0; \ 126 snprintf(sentry_hash->key, sizeof(sentry_hash->key), \ 127 "%s%s%s%s" MAGIC_ID_FORMAT, dsentry->parent_name, \ 128 MAGIC_DSENTRY_ABS_NAME_SEP, sentry->name, \ 129 MAGIC_DSENTRY_ABS_NAME_SEP, dsentry->site_id); \ 130 sentry_list->sentry = sentry; \ 131 sentry_hash->sentry_list = sentry_list; \ 132 } while (0) 133 134 /* Lookup functions. */ 135 PUBLIC struct _magic_sentry *magic_sentry_lookup_by_id(_magic_id_t id, 136 struct _magic_dsentry *dsentry_buff); 137 PUBLIC struct _magic_sentry *magic_sentry_lookup_by_addr(void *addr, 138 struct _magic_dsentry *dsentry_buff); 139 PUBLIC struct _magic_sentry * 140 magic_sentry_lookup_by_name(const char *parent_name, const char *name, 141 _magic_id_t site_id, struct _magic_dsentry *dsentry_buff); 142 PUBLIC struct _magic_sentry *magic_sentry_lookup_by_range(void *addr, 143 struct _magic_dsentry *dsentry_buff); 144 PUBLIC struct _magic_sentry *magic_sentry_lookup_by_min_off_by_n(void *addr, 145 int flags, long *min_n_ptr, struct _magic_dsentry *dsentry_buff); 146 PUBLIC struct _magic_sentry * 147 magic_sentry_lookup_by_string(const char *string); 148 149 /* Lookup index functions. */ 150 PUBLIC void magic_sentry_rl_build_index(void *buff, size_t buff_size); 151 PUBLIC void magic_sentry_rl_destroy_index(void); 152 PUBLIC size_t magic_sentry_rl_estimate_index_buff_size(int sentries_num); 153 PUBLIC void magic_sentry_rl_print_index(void); 154 PUBLIC struct _magic_sentry *magic_sentry_rl_lookup(void* start_addr); 155 PUBLIC struct _magic_sentry *magic_sentry_rl_insert(void* start_addr, 156 struct _magic_sentry *sentry); 157 PUBLIC struct _magic_sentry *magic_sentry_rl_pred_lookup(void* addr); 158 PUBLIC struct _magic_sentry *magic_sentry_lookup_by_range_index(void *addr, 159 struct _magic_dsentry *dsentry_buff); 160 161 /* Lookup hash functions. */ 162 PUBLIC void magic_sentry_hash_build(void *buff, size_t buff_size); 163 PUBLIC void magic_sentry_hash_destroy(void); 164 PUBLIC size_t magic_sentry_hash_estimate_buff_size(int sentries_num); 165 PUBLIC struct _magic_sentry * 166 magic_sentry_lookup_by_name_hash(const char *parent_name, 167 const char *name, _magic_id_t site_id, 168 struct _magic_dsentry *dsentry_buff); 169 PUBLIC void *magic_sentry_hash_alloc(size_t size); 170 PUBLIC void magic_sentry_hash_dealloc(void *object, size_t size); 171 PUBLIC struct _magic_sentry_list *magic_sentry_list_lookup_by_name_hash( 172 const char *parent_name, const char *name, _magic_id_t site_id, 173 struct _magic_dsentry *dsentry_buff); 174 175 /* Magic state entry functions. */ 176 PUBLIC int magic_check_sentry(struct _magic_sentry *entry); 177 PUBLIC int magic_check_sentries(void); 178 PUBLIC void magic_print_sentry(struct _magic_sentry* entry); 179 PUBLIC void magic_print_sentry_abs_name(struct _magic_sentry *sentry); 180 PUBLIC void magic_print_sentries(void); 181 PUBLIC void magic_print_nonstr_sentries(void); 182 PUBLIC void magic_print_str_sentries(void); 183 PUBLIC long magic_sentry_get_off_by_n(struct _magic_sentry* sentry, 184 void *addr, int flags); 185 186 #endif /* _MAGIC_SENTRY_H */ 187