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