1 #ifndef _MAGIC_SENTRY_H
2 #define _MAGIC_SENTRY_H
6 #include <magic_common.h>
7 #include <magic_structs.h>
8 #include <common/ut/utlist.h>
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); \
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)
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)
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)
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)
89 /* Estimated maximum number of buckets needed. Increase as necessary. */
90 #define MAGIC_SENTRY_NAME_EST_MAX_BUCKETS 32768
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.
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))
102 #define MAGIC_SENTRY_TO_HASH_EL(sentry, sentry_hash, sentry_list) \
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!"); \
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; \
117 #define MAGIC_DSENTRY_TO_HASH_EL(dsentry, sentry, sentry_hash, sentry_list) \
119 assert(strlen(sentry->name) + strlen(dsentry->parent_name) \
120 + 2 * strlen(MAGIC_DSENTRY_ABS_NAME_SEP) \
122 + 1 < MAGIC_SENTRY_NAME_MAX_KEY_LEN \
123 && "Dsentry key length too long!"); \
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; \
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
);
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
);
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
);
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
);
186 #endif /* _MAGIC_SENTRY_H */