xref: /minix3/minix/lib/libmagicrt/include/magic_sentry.h (revision b2ed49a5d83e311ee0fa9e5ff613639b1bf77aaf)
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