1*b2ed49a5SDavid van Moolenbroek #include <magic_sentry.h>
2*b2ed49a5SDavid van Moolenbroek #include <magic_splay_tree.h>
3*b2ed49a5SDavid van Moolenbroek
4*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
5*b2ed49a5SDavid van Moolenbroek * magic_sentry_get_off_by_n *
6*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_get_off_by_n(struct _magic_sentry * sentry,void * addr,int flags)7*b2ed49a5SDavid van Moolenbroek PUBLIC long magic_sentry_get_off_by_n(struct _magic_sentry *sentry,
8*b2ed49a5SDavid van Moolenbroek void *addr, int flags)
9*b2ed49a5SDavid van Moolenbroek {
10*b2ed49a5SDavid van Moolenbroek char *el_addr = (char*) addr, *first_el_addr, *last_el_addr;
11*b2ed49a5SDavid van Moolenbroek size_t el_size;
12*b2ed49a5SDavid van Moolenbroek unsigned long n, diff;
13*b2ed49a5SDavid van Moolenbroek long long_n;
14*b2ed49a5SDavid van Moolenbroek
15*b2ed49a5SDavid van Moolenbroek if (sentry->type->type_id != MAGIC_TYPE_ARRAY) {
16*b2ed49a5SDavid van Moolenbroek return LONG_MAX;
17*b2ed49a5SDavid van Moolenbroek }
18*b2ed49a5SDavid van Moolenbroek el_size = sentry->type->contained_types[0]->size;
19*b2ed49a5SDavid van Moolenbroek first_el_addr = (char*) sentry->address;
20*b2ed49a5SDavid van Moolenbroek last_el_addr = (first_el_addr+sentry->type->size-el_size);
21*b2ed49a5SDavid van Moolenbroek if (el_addr >= last_el_addr) {
22*b2ed49a5SDavid van Moolenbroek diff = (unsigned long) (el_addr - last_el_addr);
23*b2ed49a5SDavid van Moolenbroek }
24*b2ed49a5SDavid van Moolenbroek else if (el_addr <= first_el_addr) {
25*b2ed49a5SDavid van Moolenbroek diff = (unsigned long) (first_el_addr - el_addr);
26*b2ed49a5SDavid van Moolenbroek }
27*b2ed49a5SDavid van Moolenbroek else {
28*b2ed49a5SDavid van Moolenbroek return LONG_MAX;
29*b2ed49a5SDavid van Moolenbroek }
30*b2ed49a5SDavid van Moolenbroek if (diff % el_size != 0) {
31*b2ed49a5SDavid van Moolenbroek return LONG_MAX;
32*b2ed49a5SDavid van Moolenbroek }
33*b2ed49a5SDavid van Moolenbroek n = diff / el_size;
34*b2ed49a5SDavid van Moolenbroek if (n >= LONG_MAX) {
35*b2ed49a5SDavid van Moolenbroek return LONG_MAX;
36*b2ed49a5SDavid van Moolenbroek }
37*b2ed49a5SDavid van Moolenbroek long_n = (el_addr >= last_el_addr ? (long) n : -((long)n));
38*b2ed49a5SDavid van Moolenbroek if ((long_n < 0 && !(flags & MAGIC_SENTRY_OFF_BY_N_NEGATIVE))
39*b2ed49a5SDavid van Moolenbroek || (long_n > 0 && !(flags & MAGIC_SENTRY_OFF_BY_N_POSITIVE))
40*b2ed49a5SDavid van Moolenbroek || (long_n == 0 && !(flags & MAGIC_SENTRY_OFF_BY_N_ZERO))) {
41*b2ed49a5SDavid van Moolenbroek return LONG_MAX;
42*b2ed49a5SDavid van Moolenbroek }
43*b2ed49a5SDavid van Moolenbroek return long_n;
44*b2ed49a5SDavid van Moolenbroek }
45*b2ed49a5SDavid van Moolenbroek
46*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
47*b2ed49a5SDavid van Moolenbroek * magic_do_check_sentry *
48*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_do_check_sentry(struct _magic_sentry * sentry)49*b2ed49a5SDavid van Moolenbroek PRIVATE INLINE int magic_do_check_sentry(struct _magic_sentry *sentry)
50*b2ed49a5SDavid van Moolenbroek {
51*b2ed49a5SDavid van Moolenbroek int is_size_ok;
52*b2ed49a5SDavid van Moolenbroek assert(sentry && "NULL sentry found!");
53*b2ed49a5SDavid van Moolenbroek is_size_ok = sentry->type->size > 0;
54*b2ed49a5SDavid van Moolenbroek if (!is_size_ok) {
55*b2ed49a5SDavid van Moolenbroek _magic_printf("magic_do_check_sentry: bad sentry, checks: %d\n", is_size_ok);
56*b2ed49a5SDavid van Moolenbroek MAGIC_SENTRY_PRINT(sentry, MAGIC_EXPAND_TYPE_STR);
57*b2ed49a5SDavid van Moolenbroek _magic_printf("\n");
58*b2ed49a5SDavid van Moolenbroek return FALSE;
59*b2ed49a5SDavid van Moolenbroek }
60*b2ed49a5SDavid van Moolenbroek return TRUE;
61*b2ed49a5SDavid van Moolenbroek }
62*b2ed49a5SDavid van Moolenbroek
63*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
64*b2ed49a5SDavid van Moolenbroek * magic_check_sentry *
65*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_check_sentry(struct _magic_sentry * sentry)66*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_check_sentry(struct _magic_sentry *sentry)
67*b2ed49a5SDavid van Moolenbroek {
68*b2ed49a5SDavid van Moolenbroek int check;
69*b2ed49a5SDavid van Moolenbroek check = magic_do_check_sentry(sentry);
70*b2ed49a5SDavid van Moolenbroek if (!check) {
71*b2ed49a5SDavid van Moolenbroek return FALSE;
72*b2ed49a5SDavid van Moolenbroek }
73*b2ed49a5SDavid van Moolenbroek
74*b2ed49a5SDavid van Moolenbroek #if MAGIC_CHECK_LEVEL == 2
75*b2ed49a5SDavid van Moolenbroek check = magic_check_sentries();
76*b2ed49a5SDavid van Moolenbroek if (!check) {
77*b2ed49a5SDavid van Moolenbroek _magic_printf("magic_check_sentry: bad other sentry\n");
78*b2ed49a5SDavid van Moolenbroek return FALSE;
79*b2ed49a5SDavid van Moolenbroek }
80*b2ed49a5SDavid van Moolenbroek #endif
81*b2ed49a5SDavid van Moolenbroek
82*b2ed49a5SDavid van Moolenbroek return TRUE;
83*b2ed49a5SDavid van Moolenbroek }
84*b2ed49a5SDavid van Moolenbroek
85*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
86*b2ed49a5SDavid van Moolenbroek * magic_check_sentries *
87*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_check_sentries()88*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_check_sentries()
89*b2ed49a5SDavid van Moolenbroek {
90*b2ed49a5SDavid van Moolenbroek int i, ret, check = TRUE;
91*b2ed49a5SDavid van Moolenbroek
92*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
93*b2ed49a5SDavid van Moolenbroek ret = magic_do_check_sentry(&_magic_sentries[i]);
94*b2ed49a5SDavid van Moolenbroek if (ret == FALSE) {
95*b2ed49a5SDavid van Moolenbroek check = FALSE;
96*b2ed49a5SDavid van Moolenbroek }
97*b2ed49a5SDavid van Moolenbroek }
98*b2ed49a5SDavid van Moolenbroek
99*b2ed49a5SDavid van Moolenbroek return check;
100*b2ed49a5SDavid van Moolenbroek }
101*b2ed49a5SDavid van Moolenbroek
102*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
103*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_id *
104*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_id(_magic_id_t id,struct _magic_dsentry * dsentry_buff)105*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_id(_magic_id_t id,
106*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *dsentry_buff)
107*b2ed49a5SDavid van Moolenbroek {
108*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *entry = NULL;
109*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
110*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
111*b2ed49a5SDavid van Moolenbroek
112*b2ed49a5SDavid van Moolenbroek if (id <= 0) {
113*b2ed49a5SDavid van Moolenbroek return NULL;
114*b2ed49a5SDavid van Moolenbroek }
115*b2ed49a5SDavid van Moolenbroek
116*b2ed49a5SDavid van Moolenbroek /* O(1) ID lookup for sentries. */
117*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
118*b2ed49a5SDavid van Moolenbroek if ((int)id <= _magic_sentries_num) {
119*b2ed49a5SDavid van Moolenbroek return &_magic_sentries[id - 1];
120*b2ed49a5SDavid van Moolenbroek }
121*b2ed49a5SDavid van Moolenbroek #endif
122*b2ed49a5SDavid van Moolenbroek
123*b2ed49a5SDavid van Moolenbroek /* O(N) ID lookup for dsentries. */
124*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
125*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
126*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_NESTED_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
127*b2ed49a5SDavid van Moolenbroek if(sentry->id == id) {
128*b2ed49a5SDavid van Moolenbroek if(dsentry_buff) {
129*b2ed49a5SDavid van Moolenbroek magic_copy_dsentry(dsentry, dsentry_buff);
130*b2ed49a5SDavid van Moolenbroek entry = MAGIC_DSENTRY_TO_SENTRY(dsentry_buff);
131*b2ed49a5SDavid van Moolenbroek }
132*b2ed49a5SDavid van Moolenbroek else {
133*b2ed49a5SDavid van Moolenbroek entry = sentry;
134*b2ed49a5SDavid van Moolenbroek }
135*b2ed49a5SDavid van Moolenbroek break;
136*b2ed49a5SDavid van Moolenbroek }
137*b2ed49a5SDavid van Moolenbroek );
138*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
139*b2ed49a5SDavid van Moolenbroek #endif
140*b2ed49a5SDavid van Moolenbroek
141*b2ed49a5SDavid van Moolenbroek return entry;
142*b2ed49a5SDavid van Moolenbroek }
143*b2ed49a5SDavid van Moolenbroek
144*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
145*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_addr *
146*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_addr(void * addr,struct _magic_dsentry * dsentry_buff)147*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_addr(void *addr,
148*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *dsentry_buff)
149*b2ed49a5SDavid van Moolenbroek {
150*b2ed49a5SDavid van Moolenbroek int i;
151*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *entry = NULL;
152*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
153*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
154*b2ed49a5SDavid van Moolenbroek
155*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY_ALLOW_RANGE_INDEX
156*b2ed49a5SDavid van Moolenbroek if (magic_sentry_rl_index) {
157*b2ed49a5SDavid van Moolenbroek sentry = magic_sentry_lookup_by_range_index(addr, dsentry_buff);
158*b2ed49a5SDavid van Moolenbroek if (sentry && sentry->address == addr) {
159*b2ed49a5SDavid van Moolenbroek return sentry;
160*b2ed49a5SDavid van Moolenbroek } else {
161*b2ed49a5SDavid van Moolenbroek return NULL;
162*b2ed49a5SDavid van Moolenbroek }
163*b2ed49a5SDavid van Moolenbroek }
164*b2ed49a5SDavid van Moolenbroek #endif
165*b2ed49a5SDavid van Moolenbroek
166*b2ed49a5SDavid van Moolenbroek /* Scan all the entries and return the one matching the provided address. */
167*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
168*b2ed49a5SDavid van Moolenbroek if (MAGIC_ADDR_IS_IN_RANGE(addr, magic_sentry_range)) {
169*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
170*b2ed49a5SDavid van Moolenbroek if (_magic_sentries[i].address == addr) {
171*b2ed49a5SDavid van Moolenbroek entry = &_magic_sentries[i];
172*b2ed49a5SDavid van Moolenbroek break;
173*b2ed49a5SDavid van Moolenbroek }
174*b2ed49a5SDavid van Moolenbroek }
175*b2ed49a5SDavid van Moolenbroek if (entry) {
176*b2ed49a5SDavid van Moolenbroek return entry;
177*b2ed49a5SDavid van Moolenbroek }
178*b2ed49a5SDavid van Moolenbroek }
179*b2ed49a5SDavid van Moolenbroek #endif
180*b2ed49a5SDavid van Moolenbroek
181*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
182*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
183*b2ed49a5SDavid van Moolenbroek if (!MAGIC_ADDR_LOOKUP_USE_DSENTRY_RANGES || magic_range_is_dsentry(addr)) {
184*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
185*b2ed49a5SDavid van Moolenbroek if (sentry->address == addr) {
186*b2ed49a5SDavid van Moolenbroek if (dsentry_buff) {
187*b2ed49a5SDavid van Moolenbroek magic_copy_dsentry(dsentry, dsentry_buff);
188*b2ed49a5SDavid van Moolenbroek entry = MAGIC_DSENTRY_TO_SENTRY(dsentry_buff);
189*b2ed49a5SDavid van Moolenbroek }
190*b2ed49a5SDavid van Moolenbroek else {
191*b2ed49a5SDavid van Moolenbroek entry = sentry;
192*b2ed49a5SDavid van Moolenbroek }
193*b2ed49a5SDavid van Moolenbroek break;
194*b2ed49a5SDavid van Moolenbroek }
195*b2ed49a5SDavid van Moolenbroek );
196*b2ed49a5SDavid van Moolenbroek }
197*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
198*b2ed49a5SDavid van Moolenbroek #endif
199*b2ed49a5SDavid van Moolenbroek
200*b2ed49a5SDavid van Moolenbroek return entry;
201*b2ed49a5SDavid van Moolenbroek }
202*b2ed49a5SDavid van Moolenbroek
203*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
204*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_name *
205*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
206*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *
magic_sentry_lookup_by_name(const char * parent_name,const char * name,_magic_id_t site_id,struct _magic_dsentry * dsentry_buff)207*b2ed49a5SDavid van Moolenbroek magic_sentry_lookup_by_name(const char *parent_name, const char *name,
208*b2ed49a5SDavid van Moolenbroek _magic_id_t site_id, struct _magic_dsentry *dsentry_buff)
209*b2ed49a5SDavid van Moolenbroek {
210*b2ed49a5SDavid van Moolenbroek int i;
211*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *entry = NULL;
212*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
213*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
214*b2ed49a5SDavid van Moolenbroek
215*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY_ALLOW_NAME_HASH
216*b2ed49a5SDavid van Moolenbroek if (magic_sentry_hash_head) {
217*b2ed49a5SDavid van Moolenbroek return magic_sentry_lookup_by_name_hash(parent_name, name,
218*b2ed49a5SDavid van Moolenbroek site_id, dsentry_buff);
219*b2ed49a5SDavid van Moolenbroek }
220*b2ed49a5SDavid van Moolenbroek #endif
221*b2ed49a5SDavid van Moolenbroek
222*b2ed49a5SDavid van Moolenbroek /* Scan all the entries and return the one matching the provided name. */
223*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
224*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
225*b2ed49a5SDavid van Moolenbroek if (!strcmp(_magic_sentries[i].name, name)) {
226*b2ed49a5SDavid van Moolenbroek if (!parent_name ||
227*b2ed49a5SDavid van Moolenbroek !strcmp(MAGIC_SENTRY_PARENT(&_magic_sentries[i]),
228*b2ed49a5SDavid van Moolenbroek parent_name)) {
229*b2ed49a5SDavid van Moolenbroek if (MAGIC_SENTRY_SITE_ID(&_magic_sentries[i]) == site_id) {
230*b2ed49a5SDavid van Moolenbroek entry = &_magic_sentries[i];
231*b2ed49a5SDavid van Moolenbroek break;
232*b2ed49a5SDavid van Moolenbroek }
233*b2ed49a5SDavid van Moolenbroek }
234*b2ed49a5SDavid van Moolenbroek }
235*b2ed49a5SDavid van Moolenbroek }
236*b2ed49a5SDavid van Moolenbroek if (entry) {
237*b2ed49a5SDavid van Moolenbroek return entry;
238*b2ed49a5SDavid van Moolenbroek }
239*b2ed49a5SDavid van Moolenbroek #endif
240*b2ed49a5SDavid van Moolenbroek
241*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
242*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
243*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry, prev_dsentry,
244*b2ed49a5SDavid van Moolenbroek dsentry, sentry,
245*b2ed49a5SDavid van Moolenbroek if (!strcmp(sentry->name, name)) {
246*b2ed49a5SDavid van Moolenbroek if (!parent_name ||
247*b2ed49a5SDavid van Moolenbroek !strcmp(MAGIC_SENTRY_PARENT(sentry), parent_name)) {
248*b2ed49a5SDavid van Moolenbroek if (site_id == MAGIC_DSENTRY_SITE_ID_NULL ||
249*b2ed49a5SDavid van Moolenbroek dsentry->site_id == site_id) {
250*b2ed49a5SDavid van Moolenbroek if (dsentry_buff) {
251*b2ed49a5SDavid van Moolenbroek magic_copy_dsentry(dsentry, dsentry_buff);
252*b2ed49a5SDavid van Moolenbroek entry = MAGIC_DSENTRY_TO_SENTRY(dsentry_buff);
253*b2ed49a5SDavid van Moolenbroek }
254*b2ed49a5SDavid van Moolenbroek else {
255*b2ed49a5SDavid van Moolenbroek entry = sentry;
256*b2ed49a5SDavid van Moolenbroek }
257*b2ed49a5SDavid van Moolenbroek break;
258*b2ed49a5SDavid van Moolenbroek }
259*b2ed49a5SDavid van Moolenbroek }
260*b2ed49a5SDavid van Moolenbroek }
261*b2ed49a5SDavid van Moolenbroek );
262*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
263*b2ed49a5SDavid van Moolenbroek #endif
264*b2ed49a5SDavid van Moolenbroek
265*b2ed49a5SDavid van Moolenbroek return entry;
266*b2ed49a5SDavid van Moolenbroek }
267*b2ed49a5SDavid van Moolenbroek
268*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
269*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_range *
270*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_range(void * addr,struct _magic_dsentry * dsentry_buff)271*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_range(void *addr,
272*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *dsentry_buff)
273*b2ed49a5SDavid van Moolenbroek {
274*b2ed49a5SDavid van Moolenbroek int i;
275*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *entry = NULL;
276*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
277*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
278*b2ed49a5SDavid van Moolenbroek void *start_address, *end_address;
279*b2ed49a5SDavid van Moolenbroek
280*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY_ALLOW_RANGE_INDEX
281*b2ed49a5SDavid van Moolenbroek if (magic_sentry_rl_index) {
282*b2ed49a5SDavid van Moolenbroek return magic_sentry_lookup_by_range_index(addr, dsentry_buff);
283*b2ed49a5SDavid van Moolenbroek }
284*b2ed49a5SDavid van Moolenbroek #endif
285*b2ed49a5SDavid van Moolenbroek
286*b2ed49a5SDavid van Moolenbroek /* Scan all the entries and return the one with a valid range. */
287*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
288*b2ed49a5SDavid van Moolenbroek if (MAGIC_ADDR_IS_IN_RANGE(addr, magic_sentry_range)) {
289*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
290*b2ed49a5SDavid van Moolenbroek start_address = _magic_sentries[i].address;
291*b2ed49a5SDavid van Moolenbroek end_address = (void *) (((char *)_magic_sentries[i].address) +
292*b2ed49a5SDavid van Moolenbroek _magic_sentries[i].type->size - 1);
293*b2ed49a5SDavid van Moolenbroek if (MAGIC_ADDR_IS_WITHIN(addr, start_address, end_address)) {
294*b2ed49a5SDavid van Moolenbroek entry = &_magic_sentries[i];
295*b2ed49a5SDavid van Moolenbroek break;
296*b2ed49a5SDavid van Moolenbroek }
297*b2ed49a5SDavid van Moolenbroek }
298*b2ed49a5SDavid van Moolenbroek if (entry) {
299*b2ed49a5SDavid van Moolenbroek return entry;
300*b2ed49a5SDavid van Moolenbroek }
301*b2ed49a5SDavid van Moolenbroek }
302*b2ed49a5SDavid van Moolenbroek #endif
303*b2ed49a5SDavid van Moolenbroek
304*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
305*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
306*b2ed49a5SDavid van Moolenbroek if (!MAGIC_ADDR_LOOKUP_USE_DSENTRY_RANGES || magic_range_is_dsentry(addr)) {
307*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
308*b2ed49a5SDavid van Moolenbroek start_address = sentry->address;
309*b2ed49a5SDavid van Moolenbroek end_address = (void *) (((char *)sentry->address) +
310*b2ed49a5SDavid van Moolenbroek sentry->type->size - 1);
311*b2ed49a5SDavid van Moolenbroek if (MAGIC_ADDR_IS_WITHIN(addr, start_address, end_address)) {
312*b2ed49a5SDavid van Moolenbroek if (dsentry_buff) {
313*b2ed49a5SDavid van Moolenbroek magic_copy_dsentry(dsentry, dsentry_buff);
314*b2ed49a5SDavid van Moolenbroek entry = MAGIC_DSENTRY_TO_SENTRY(dsentry_buff);
315*b2ed49a5SDavid van Moolenbroek }
316*b2ed49a5SDavid van Moolenbroek else {
317*b2ed49a5SDavid van Moolenbroek entry = sentry;
318*b2ed49a5SDavid van Moolenbroek }
319*b2ed49a5SDavid van Moolenbroek break;
320*b2ed49a5SDavid van Moolenbroek }
321*b2ed49a5SDavid van Moolenbroek );
322*b2ed49a5SDavid van Moolenbroek }
323*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
324*b2ed49a5SDavid van Moolenbroek #endif
325*b2ed49a5SDavid van Moolenbroek
326*b2ed49a5SDavid van Moolenbroek return entry;
327*b2ed49a5SDavid van Moolenbroek }
328*b2ed49a5SDavid van Moolenbroek
329*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
330*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_min_off_by_n *
331*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_min_off_by_n(void * addr,int flags,long * min_n_ptr,struct _magic_dsentry * dsentry_buff)332*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_min_off_by_n(void *addr,
333*b2ed49a5SDavid van Moolenbroek int flags, long *min_n_ptr, struct _magic_dsentry *dsentry_buff)
334*b2ed49a5SDavid van Moolenbroek {
335*b2ed49a5SDavid van Moolenbroek int i;
336*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *entry = NULL;
337*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
338*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
339*b2ed49a5SDavid van Moolenbroek long n, abs_n, min_n, min_abs_n = LONG_MAX;
340*b2ed49a5SDavid van Moolenbroek int has_multiple_min_entries = FALSE;
341*b2ed49a5SDavid van Moolenbroek
342*b2ed49a5SDavid van Moolenbroek /* Scan all the entries and return the one with the minimum off-by-n. */
343*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
344*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
345*b2ed49a5SDavid van Moolenbroek n = magic_sentry_get_off_by_n(&_magic_sentries[i], addr, flags);
346*b2ed49a5SDavid van Moolenbroek abs_n = MAGIC_ABS(n);
347*b2ed49a5SDavid van Moolenbroek if (n == LONG_MAX || abs_n > min_abs_n) {
348*b2ed49a5SDavid van Moolenbroek continue;
349*b2ed49a5SDavid van Moolenbroek }
350*b2ed49a5SDavid van Moolenbroek if (abs_n == min_abs_n) {
351*b2ed49a5SDavid van Moolenbroek has_multiple_min_entries = TRUE;
352*b2ed49a5SDavid van Moolenbroek }
353*b2ed49a5SDavid van Moolenbroek else {
354*b2ed49a5SDavid van Moolenbroek min_abs_n = abs_n;
355*b2ed49a5SDavid van Moolenbroek min_n = n;
356*b2ed49a5SDavid van Moolenbroek has_multiple_min_entries = FALSE;
357*b2ed49a5SDavid van Moolenbroek entry = &_magic_sentries[i];
358*b2ed49a5SDavid van Moolenbroek }
359*b2ed49a5SDavid van Moolenbroek }
360*b2ed49a5SDavid van Moolenbroek #endif
361*b2ed49a5SDavid van Moolenbroek
362*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
363*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
364*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
365*b2ed49a5SDavid van Moolenbroek n = magic_sentry_get_off_by_n(sentry, addr, flags);
366*b2ed49a5SDavid van Moolenbroek abs_n = MAGIC_ABS(n);
367*b2ed49a5SDavid van Moolenbroek if (n == LONG_MAX || abs_n > min_abs_n) {
368*b2ed49a5SDavid van Moolenbroek continue;
369*b2ed49a5SDavid van Moolenbroek }
370*b2ed49a5SDavid van Moolenbroek if (abs_n == min_abs_n) {
371*b2ed49a5SDavid van Moolenbroek has_multiple_min_entries = TRUE;
372*b2ed49a5SDavid van Moolenbroek }
373*b2ed49a5SDavid van Moolenbroek else {
374*b2ed49a5SDavid van Moolenbroek min_abs_n = abs_n;
375*b2ed49a5SDavid van Moolenbroek min_n = n;
376*b2ed49a5SDavid van Moolenbroek has_multiple_min_entries = FALSE;
377*b2ed49a5SDavid van Moolenbroek if (dsentry_buff) {
378*b2ed49a5SDavid van Moolenbroek magic_copy_dsentry(dsentry, dsentry_buff);
379*b2ed49a5SDavid van Moolenbroek entry = MAGIC_DSENTRY_TO_SENTRY(dsentry_buff);
380*b2ed49a5SDavid van Moolenbroek }
381*b2ed49a5SDavid van Moolenbroek else {
382*b2ed49a5SDavid van Moolenbroek entry = sentry;
383*b2ed49a5SDavid van Moolenbroek }
384*b2ed49a5SDavid van Moolenbroek }
385*b2ed49a5SDavid van Moolenbroek );
386*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
387*b2ed49a5SDavid van Moolenbroek #endif
388*b2ed49a5SDavid van Moolenbroek
389*b2ed49a5SDavid van Moolenbroek if (has_multiple_min_entries && (flags & MAGIC_SENTRY_OFF_BY_N_NO_DUPLICATES)) {
390*b2ed49a5SDavid van Moolenbroek entry = NULL;
391*b2ed49a5SDavid van Moolenbroek }
392*b2ed49a5SDavid van Moolenbroek if (entry && min_n_ptr) {
393*b2ed49a5SDavid van Moolenbroek *min_n_ptr = min_n;
394*b2ed49a5SDavid van Moolenbroek }
395*b2ed49a5SDavid van Moolenbroek return entry;
396*b2ed49a5SDavid van Moolenbroek }
397*b2ed49a5SDavid van Moolenbroek
398*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
399*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_string *
400*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_string(const char * string)401*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_string(const char *string)
402*b2ed49a5SDavid van Moolenbroek {
403*b2ed49a5SDavid van Moolenbroek int i;
404*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *entry = NULL;
405*b2ed49a5SDavid van Moolenbroek
406*b2ed49a5SDavid van Moolenbroek /* Scan all the string entries and return the matching one. */
407*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
408*b2ed49a5SDavid van Moolenbroek for(i = 0 ; i < _magic_sentries_num ; i++) {
409*b2ed49a5SDavid van Moolenbroek if (MAGIC_STATE_FLAG(&_magic_sentries[i], MAGIC_STATE_STRING)
410*b2ed49a5SDavid van Moolenbroek && !strcmp((char *)_magic_sentries[i].address, string)) {
411*b2ed49a5SDavid van Moolenbroek entry = &_magic_sentries[i];
412*b2ed49a5SDavid van Moolenbroek break;
413*b2ed49a5SDavid van Moolenbroek }
414*b2ed49a5SDavid van Moolenbroek }
415*b2ed49a5SDavid van Moolenbroek #endif
416*b2ed49a5SDavid van Moolenbroek
417*b2ed49a5SDavid van Moolenbroek return entry;
418*b2ed49a5SDavid van Moolenbroek }
419*b2ed49a5SDavid van Moolenbroek
420*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
421*b2ed49a5SDavid van Moolenbroek * magic_print_sentry *
422*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_print_sentry(struct _magic_sentry * sentry)423*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_print_sentry(struct _magic_sentry *sentry)
424*b2ed49a5SDavid van Moolenbroek {
425*b2ed49a5SDavid van Moolenbroek MAGIC_SENTRY_PRINT(sentry, MAGIC_EXPAND_TYPE_STR);
426*b2ed49a5SDavid van Moolenbroek }
427*b2ed49a5SDavid van Moolenbroek
428*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
429*b2ed49a5SDavid van Moolenbroek * magic_print_sentry_abs_name *
430*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_print_sentry_abs_name(struct _magic_sentry * sentry)431*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_print_sentry_abs_name(struct _magic_sentry *sentry)
432*b2ed49a5SDavid van Moolenbroek {
433*b2ed49a5SDavid van Moolenbroek if (!(sentry->flags & MAGIC_STATE_DYNAMIC)) {
434*b2ed49a5SDavid van Moolenbroek _magic_printf(sentry->name);
435*b2ed49a5SDavid van Moolenbroek }
436*b2ed49a5SDavid van Moolenbroek else {
437*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *dsentry = MAGIC_DSENTRY_FROM_SENTRY(sentry);
438*b2ed49a5SDavid van Moolenbroek assert(dsentry->parent_name && strcmp(dsentry->parent_name, ""));
439*b2ed49a5SDavid van Moolenbroek assert(sentry->name);
440*b2ed49a5SDavid van Moolenbroek assert(strcmp(sentry->name, ""));
441*b2ed49a5SDavid van Moolenbroek _magic_printf("%lu%s%s%s%s%s" MAGIC_ID_FORMAT, (unsigned long)MAGIC_SENTRY_ID(sentry),
442*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ABS_NAME_SEP, dsentry->parent_name,
443*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ABS_NAME_SEP, sentry->name,
444*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ABS_NAME_SEP, dsentry->site_id);
445*b2ed49a5SDavid van Moolenbroek }
446*b2ed49a5SDavid van Moolenbroek }
447*b2ed49a5SDavid van Moolenbroek
448*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
449*b2ed49a5SDavid van Moolenbroek * magic_print_sentries *
450*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_print_sentries()451*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_print_sentries()
452*b2ed49a5SDavid van Moolenbroek {
453*b2ed49a5SDavid van Moolenbroek int i;
454*b2ed49a5SDavid van Moolenbroek struct _magic_sentry* sentry;
455*b2ed49a5SDavid van Moolenbroek
456*b2ed49a5SDavid van Moolenbroek _magic_printf("magic_print_sentries: Printing %d entries\n", _magic_sentries_num);
457*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
458*b2ed49a5SDavid van Moolenbroek sentry = &_magic_sentries[i];
459*b2ed49a5SDavid van Moolenbroek MAGIC_SENTRY_PRINT(sentry, MAGIC_EXPAND_TYPE_STR);
460*b2ed49a5SDavid van Moolenbroek _magic_printf("\n");
461*b2ed49a5SDavid van Moolenbroek }
462*b2ed49a5SDavid van Moolenbroek }
463*b2ed49a5SDavid van Moolenbroek
464*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
465*b2ed49a5SDavid van Moolenbroek * magic_print_nonstr_sentries *
466*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_print_nonstr_sentries()467*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_print_nonstr_sentries()
468*b2ed49a5SDavid van Moolenbroek {
469*b2ed49a5SDavid van Moolenbroek int i;
470*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
471*b2ed49a5SDavid van Moolenbroek
472*b2ed49a5SDavid van Moolenbroek _magic_printf("magic_print_nonstr_sentries: Printing %d/%d non-string entries\n",
473*b2ed49a5SDavid van Moolenbroek _magic_sentries_num - _magic_sentries_str_num, _magic_sentries_num);
474*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
475*b2ed49a5SDavid van Moolenbroek sentry = &_magic_sentries[i];
476*b2ed49a5SDavid van Moolenbroek if (MAGIC_SENTRY_IS_STRING(sentry)) {
477*b2ed49a5SDavid van Moolenbroek continue;
478*b2ed49a5SDavid van Moolenbroek }
479*b2ed49a5SDavid van Moolenbroek MAGIC_SENTRY_PRINT(sentry, MAGIC_EXPAND_TYPE_STR);
480*b2ed49a5SDavid van Moolenbroek _magic_printf("\n");
481*b2ed49a5SDavid van Moolenbroek }
482*b2ed49a5SDavid van Moolenbroek }
483*b2ed49a5SDavid van Moolenbroek
484*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
485*b2ed49a5SDavid van Moolenbroek * magic_print_str_sentries *
486*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_print_str_sentries()487*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_print_str_sentries()
488*b2ed49a5SDavid van Moolenbroek {
489*b2ed49a5SDavid van Moolenbroek int i;
490*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
491*b2ed49a5SDavid van Moolenbroek
492*b2ed49a5SDavid van Moolenbroek _magic_printf("magic_print_str_sentries: Printing %d/%d string entries\n",
493*b2ed49a5SDavid van Moolenbroek _magic_sentries_str_num, _magic_sentries_num);
494*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
495*b2ed49a5SDavid van Moolenbroek sentry = &_magic_sentries[i];
496*b2ed49a5SDavid van Moolenbroek if (!MAGIC_SENTRY_IS_STRING(sentry)) {
497*b2ed49a5SDavid van Moolenbroek continue;
498*b2ed49a5SDavid van Moolenbroek }
499*b2ed49a5SDavid van Moolenbroek MAGIC_SENTRY_PRINT(sentry, MAGIC_EXPAND_TYPE_STR);
500*b2ed49a5SDavid van Moolenbroek _magic_printf(", string=\"%s\"\n", (char*)sentry->address);
501*b2ed49a5SDavid van Moolenbroek }
502*b2ed49a5SDavid van Moolenbroek }
503*b2ed49a5SDavid van Moolenbroek
504*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
505*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_alloc *
506*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_alloc(int size,UNUSED (void * data))507*b2ed49a5SDavid van Moolenbroek PRIVATE void *magic_sentry_rl_alloc(int size, UNUSED(void *data))
508*b2ed49a5SDavid van Moolenbroek {
509*b2ed49a5SDavid van Moolenbroek void *addr;
510*b2ed49a5SDavid van Moolenbroek
511*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_rl_buff);
512*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_rl_buff_offset + size <= magic_sentry_rl_buff_size);
513*b2ed49a5SDavid van Moolenbroek
514*b2ed49a5SDavid van Moolenbroek addr = (char*) magic_sentry_rl_buff + magic_sentry_rl_buff_offset;
515*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff_offset += size;
516*b2ed49a5SDavid van Moolenbroek
517*b2ed49a5SDavid van Moolenbroek return addr;
518*b2ed49a5SDavid van Moolenbroek }
519*b2ed49a5SDavid van Moolenbroek
520*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
521*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_dealloc *
522*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_dealloc(UNUSED (void * object),UNUSED (void * data))523*b2ed49a5SDavid van Moolenbroek PRIVATE void magic_sentry_rl_dealloc(UNUSED(void *object), UNUSED(void *data))
524*b2ed49a5SDavid van Moolenbroek {
525*b2ed49a5SDavid van Moolenbroek return;
526*b2ed49a5SDavid van Moolenbroek }
527*b2ed49a5SDavid van Moolenbroek
528*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
529*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_build_index *
530*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_build_index(void * buff,size_t buff_size)531*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_sentry_rl_build_index(void *buff, size_t buff_size)
532*b2ed49a5SDavid van Moolenbroek {
533*b2ed49a5SDavid van Moolenbroek /*
534*b2ed49a5SDavid van Moolenbroek * Warning: this implementation is thread unsafe and also makes
535*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_range thread unsafe!
536*b2ed49a5SDavid van Moolenbroek */
537*b2ed49a5SDavid van Moolenbroek int i;
538*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
539*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
540*b2ed49a5SDavid van Moolenbroek void *start_address;
541*b2ed49a5SDavid van Moolenbroek splay_tree index;
542*b2ed49a5SDavid van Moolenbroek
543*b2ed49a5SDavid van Moolenbroek assert(buff && buff_size > 0);
544*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff = buff;
545*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff_offset = 0;
546*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff_size = buff_size;
547*b2ed49a5SDavid van Moolenbroek index = splay_tree_new_with_allocator(
548*b2ed49a5SDavid van Moolenbroek splay_tree_compare_pointers,
549*b2ed49a5SDavid van Moolenbroek NULL, NULL,
550*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_alloc, magic_sentry_rl_dealloc,
551*b2ed49a5SDavid van Moolenbroek NULL);
552*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_index = index;
553*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_rl_index);
554*b2ed49a5SDavid van Moolenbroek
555*b2ed49a5SDavid van Moolenbroek /* Add all the sentries to the index. */
556*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
557*b2ed49a5SDavid van Moolenbroek for (i = 0 ; i < _magic_sentries_num ; i++) {
558*b2ed49a5SDavid van Moolenbroek start_address = _magic_sentries[i].address;
559*b2ed49a5SDavid van Moolenbroek sentry = &_magic_sentries[i];
560*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_insert(start_address, sentry);
561*b2ed49a5SDavid van Moolenbroek }
562*b2ed49a5SDavid van Moolenbroek #endif
563*b2ed49a5SDavid van Moolenbroek
564*b2ed49a5SDavid van Moolenbroek /* Add all the dsentries to the index. */
565*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
566*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
567*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
568*b2ed49a5SDavid van Moolenbroek start_address = sentry->address;
569*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_insert(start_address, sentry);
570*b2ed49a5SDavid van Moolenbroek );
571*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
572*b2ed49a5SDavid van Moolenbroek #endif
573*b2ed49a5SDavid van Moolenbroek }
574*b2ed49a5SDavid van Moolenbroek
575*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
576*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_destroy_index *
577*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_destroy_index(void)578*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_sentry_rl_destroy_index(void)
579*b2ed49a5SDavid van Moolenbroek {
580*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff = NULL;
581*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff_offset = 0;
582*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_buff_size = 0;
583*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_index = NULL;
584*b2ed49a5SDavid van Moolenbroek }
585*b2ed49a5SDavid van Moolenbroek
586*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
587*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_estimate_index_buff_size *
588*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_estimate_index_buff_size(int sentries_num)589*b2ed49a5SDavid van Moolenbroek PUBLIC size_t magic_sentry_rl_estimate_index_buff_size(int sentries_num)
590*b2ed49a5SDavid van Moolenbroek {
591*b2ed49a5SDavid van Moolenbroek if (sentries_num == 0) {
592*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_BLOCK_NUM(_magic_first_dsentry, &sentries_num);
593*b2ed49a5SDavid van Moolenbroek sentries_num += _magic_sentries_num;
594*b2ed49a5SDavid van Moolenbroek }
595*b2ed49a5SDavid van Moolenbroek
596*b2ed49a5SDavid van Moolenbroek return (sentries_num * sizeof(struct splay_tree_node_s)) +
597*b2ed49a5SDavid van Moolenbroek (sizeof(struct splay_tree_s) * 2);
598*b2ed49a5SDavid van Moolenbroek }
599*b2ed49a5SDavid van Moolenbroek
600*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
601*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_count_index_cb *
602*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_count_index_cb(splay_tree_node node,void * data)603*b2ed49a5SDavid van Moolenbroek PRIVATE int magic_sentry_rl_count_index_cb(splay_tree_node node, void *data)
604*b2ed49a5SDavid van Moolenbroek {
605*b2ed49a5SDavid van Moolenbroek size_t *count = (size_t *) data;
606*b2ed49a5SDavid van Moolenbroek
607*b2ed49a5SDavid van Moolenbroek (*count)++;
608*b2ed49a5SDavid van Moolenbroek return 0;
609*b2ed49a5SDavid van Moolenbroek }
610*b2ed49a5SDavid van Moolenbroek
611*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
612*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_print_index_cb *
613*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_print_index_cb(splay_tree_node node,void * data)614*b2ed49a5SDavid van Moolenbroek PRIVATE int magic_sentry_rl_print_index_cb(splay_tree_node node, void *data)
615*b2ed49a5SDavid van Moolenbroek {
616*b2ed49a5SDavid van Moolenbroek _magic_printf("NODE<key, value>: <%08x, %08x>\n", (unsigned int) node->key,
617*b2ed49a5SDavid van Moolenbroek (unsigned int) node->value);
618*b2ed49a5SDavid van Moolenbroek return 0;
619*b2ed49a5SDavid van Moolenbroek }
620*b2ed49a5SDavid van Moolenbroek
621*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
622*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_print_index *
623*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_print_index(void)624*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_sentry_rl_print_index(void)
625*b2ed49a5SDavid van Moolenbroek {
626*b2ed49a5SDavid van Moolenbroek size_t num_nodes = 0;
627*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_rl_index);
628*b2ed49a5SDavid van Moolenbroek
629*b2ed49a5SDavid van Moolenbroek splay_tree_foreach((splay_tree) magic_sentry_rl_index,
630*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_count_index_cb, &num_nodes);
631*b2ed49a5SDavid van Moolenbroek _magic_printf("magic_sentry_rl_print_index: Found %d nodes:\n", num_nodes);
632*b2ed49a5SDavid van Moolenbroek splay_tree_foreach((splay_tree) magic_sentry_rl_index,
633*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_print_index_cb, NULL);
634*b2ed49a5SDavid van Moolenbroek }
635*b2ed49a5SDavid van Moolenbroek
636*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
637*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_lookup *
638*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_lookup(void * start_addr)639*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_rl_lookup(void *start_addr)
640*b2ed49a5SDavid van Moolenbroek {
641*b2ed49a5SDavid van Moolenbroek splay_tree_node node;
642*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry = NULL;
643*b2ed49a5SDavid van Moolenbroek
644*b2ed49a5SDavid van Moolenbroek node = splay_tree_lookup((splay_tree) magic_sentry_rl_index,
645*b2ed49a5SDavid van Moolenbroek (splay_tree_key) start_addr);
646*b2ed49a5SDavid van Moolenbroek if (node) {
647*b2ed49a5SDavid van Moolenbroek sentry = (struct _magic_sentry*) node->value;
648*b2ed49a5SDavid van Moolenbroek }
649*b2ed49a5SDavid van Moolenbroek
650*b2ed49a5SDavid van Moolenbroek return sentry;
651*b2ed49a5SDavid van Moolenbroek }
652*b2ed49a5SDavid van Moolenbroek
653*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
654*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_insert *
655*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_insert(void * start_addr,struct _magic_sentry * sentry)656*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_rl_insert(void *start_addr,
657*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry)
658*b2ed49a5SDavid van Moolenbroek {
659*b2ed49a5SDavid van Moolenbroek if (!splay_tree_lookup((splay_tree) magic_sentry_rl_index,
660*b2ed49a5SDavid van Moolenbroek (splay_tree_key) start_addr)) {
661*b2ed49a5SDavid van Moolenbroek splay_tree_insert((splay_tree) magic_sentry_rl_index,
662*b2ed49a5SDavid van Moolenbroek (splay_tree_key) start_addr,
663*b2ed49a5SDavid van Moolenbroek (splay_tree_value) sentry);
664*b2ed49a5SDavid van Moolenbroek }
665*b2ed49a5SDavid van Moolenbroek else {
666*b2ed49a5SDavid van Moolenbroek sentry = NULL;
667*b2ed49a5SDavid van Moolenbroek }
668*b2ed49a5SDavid van Moolenbroek
669*b2ed49a5SDavid van Moolenbroek return sentry;
670*b2ed49a5SDavid van Moolenbroek }
671*b2ed49a5SDavid van Moolenbroek
672*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
673*b2ed49a5SDavid van Moolenbroek * magic_sentry_rl_pred_lookup *
674*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_rl_pred_lookup(void * addr)675*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_rl_pred_lookup(void *addr)
676*b2ed49a5SDavid van Moolenbroek {
677*b2ed49a5SDavid van Moolenbroek splay_tree_node node;
678*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry = NULL;
679*b2ed49a5SDavid van Moolenbroek
680*b2ed49a5SDavid van Moolenbroek node = splay_tree_predecessor((splay_tree) magic_sentry_rl_index,
681*b2ed49a5SDavid van Moolenbroek (splay_tree_key) addr);
682*b2ed49a5SDavid van Moolenbroek if (node) {
683*b2ed49a5SDavid van Moolenbroek sentry = (struct _magic_sentry*) node->value;
684*b2ed49a5SDavid van Moolenbroek }
685*b2ed49a5SDavid van Moolenbroek
686*b2ed49a5SDavid van Moolenbroek return sentry;
687*b2ed49a5SDavid van Moolenbroek }
688*b2ed49a5SDavid van Moolenbroek
689*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
690*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_range_index *
691*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_range_index(void * addr,struct _magic_dsentry * dsentry_buff)692*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_range_index(
693*b2ed49a5SDavid van Moolenbroek void *addr, struct _magic_dsentry *dsentry_buff)
694*b2ed49a5SDavid van Moolenbroek {
695*b2ed49a5SDavid van Moolenbroek /*
696*b2ed49a5SDavid van Moolenbroek * Warning: this implementation is thread unsafe!
697*b2ed49a5SDavid van Moolenbroek */
698*b2ed49a5SDavid van Moolenbroek void *start_address, *end_address;
699*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry =
700*b2ed49a5SDavid van Moolenbroek magic_sentry_rl_pred_lookup((char *)addr + 1);
701*b2ed49a5SDavid van Moolenbroek
702*b2ed49a5SDavid van Moolenbroek if (sentry) {
703*b2ed49a5SDavid van Moolenbroek start_address = sentry->address;
704*b2ed49a5SDavid van Moolenbroek end_address = (void *) (((char *)start_address) +
705*b2ed49a5SDavid van Moolenbroek sentry->type->size - 1);
706*b2ed49a5SDavid van Moolenbroek if (!MAGIC_ADDR_IS_WITHIN(addr, start_address, end_address)) {
707*b2ed49a5SDavid van Moolenbroek sentry = NULL;
708*b2ed49a5SDavid van Moolenbroek } else {
709*b2ed49a5SDavid van Moolenbroek if (MAGIC_STATE_FLAG(sentry, MAGIC_STATE_DYNAMIC) &&
710*b2ed49a5SDavid van Moolenbroek dsentry_buff != NULL) {
711*b2ed49a5SDavid van Moolenbroek magic_copy_dsentry(MAGIC_DSENTRY_FROM_SENTRY(sentry),
712*b2ed49a5SDavid van Moolenbroek dsentry_buff);
713*b2ed49a5SDavid van Moolenbroek }
714*b2ed49a5SDavid van Moolenbroek }
715*b2ed49a5SDavid van Moolenbroek }
716*b2ed49a5SDavid van Moolenbroek
717*b2ed49a5SDavid van Moolenbroek return sentry;
718*b2ed49a5SDavid van Moolenbroek }
719*b2ed49a5SDavid van Moolenbroek
720*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
721*b2ed49a5SDavid van Moolenbroek * magic_sentry_hash_insert *
722*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_hash_insert(struct _magic_sentry_hash ** head,struct _magic_sentry_hash * elem)723*b2ed49a5SDavid van Moolenbroek PRIVATE void magic_sentry_hash_insert(struct _magic_sentry_hash **head,
724*b2ed49a5SDavid van Moolenbroek struct _magic_sentry_hash *elem)
725*b2ed49a5SDavid van Moolenbroek {
726*b2ed49a5SDavid van Moolenbroek if (head != NULL) {
727*b2ed49a5SDavid van Moolenbroek struct _magic_sentry_hash *tmp;
728*b2ed49a5SDavid van Moolenbroek HASH_FIND_STR(*head, elem->key, tmp);
729*b2ed49a5SDavid van Moolenbroek if (tmp) {
730*b2ed49a5SDavid van Moolenbroek LL_APPEND(tmp->sentry_list, elem->sentry_list);
731*b2ed49a5SDavid van Moolenbroek return;
732*b2ed49a5SDavid van Moolenbroek }
733*b2ed49a5SDavid van Moolenbroek }
734*b2ed49a5SDavid van Moolenbroek /*
735*b2ed49a5SDavid van Moolenbroek * **** START UTHASH SPECIFIC DEFINITIONS ****
736*b2ed49a5SDavid van Moolenbroek */
737*b2ed49a5SDavid van Moolenbroek #undef uthash_malloc
738*b2ed49a5SDavid van Moolenbroek #undef uthash_free
739*b2ed49a5SDavid van Moolenbroek #define uthash_malloc(size) magic_sentry_hash_alloc(size)
740*b2ed49a5SDavid van Moolenbroek #define uthash_free(addr, size) magic_sentry_hash_dealloc(addr, size)
741*b2ed49a5SDavid van Moolenbroek /*
742*b2ed49a5SDavid van Moolenbroek * Since we have a limited buffer, we need to stop bucket expansion when
743*b2ed49a5SDavid van Moolenbroek * reaching a certain limit.
744*b2ed49a5SDavid van Moolenbroek */
745*b2ed49a5SDavid van Moolenbroek #undef uthash_expand_fyi
746*b2ed49a5SDavid van Moolenbroek #define uthash_expand_fyi(tbl) \
747*b2ed49a5SDavid van Moolenbroek do { \
748*b2ed49a5SDavid van Moolenbroek if (tbl->num_buckets == MAGIC_SENTRY_NAME_EST_MAX_BUCKETS) { \
749*b2ed49a5SDavid van Moolenbroek _magic_printf("Warning! Sentry name hash maximum bucket number " \
750*b2ed49a5SDavid van Moolenbroek "reached! Consider increasing " \
751*b2ed49a5SDavid van Moolenbroek "MAGIC_SENTRY_NAME_EST_MAX_BUCKETS, unless you are comfortable"\
752*b2ed49a5SDavid van Moolenbroek " with the current performance.\n"); \
753*b2ed49a5SDavid van Moolenbroek tbl->noexpand = 1; \
754*b2ed49a5SDavid van Moolenbroek } \
755*b2ed49a5SDavid van Moolenbroek } while(0);
756*b2ed49a5SDavid van Moolenbroek /*
757*b2ed49a5SDavid van Moolenbroek * **** FINISH UTHASH SPECIFIC DEFINITIONS ****
758*b2ed49a5SDavid van Moolenbroek */
759*b2ed49a5SDavid van Moolenbroek HASH_ADD_STR(*head, key, elem);
760*b2ed49a5SDavid van Moolenbroek /*
761*b2ed49a5SDavid van Moolenbroek * **** START UTHASH DEFINITION REMOVAL ****
762*b2ed49a5SDavid van Moolenbroek */
763*b2ed49a5SDavid van Moolenbroek #undef uthash_malloc
764*b2ed49a5SDavid van Moolenbroek #undef uthash_free
765*b2ed49a5SDavid van Moolenbroek #undef uthash_expand_fyi
766*b2ed49a5SDavid van Moolenbroek /*
767*b2ed49a5SDavid van Moolenbroek * **** FINISH UTHASH DEFINITION REMOVAL ****
768*b2ed49a5SDavid van Moolenbroek */
769*b2ed49a5SDavid van Moolenbroek }
770*b2ed49a5SDavid van Moolenbroek
771*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
772*b2ed49a5SDavid van Moolenbroek * magic_sentry_hash_build *
773*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_hash_build(void * buff,size_t buff_size)774*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_sentry_hash_build(void *buff, size_t buff_size)
775*b2ed49a5SDavid van Moolenbroek {
776*b2ed49a5SDavid van Moolenbroek /*
777*b2ed49a5SDavid van Moolenbroek * XXX:
778*b2ed49a5SDavid van Moolenbroek * Warning: this implementation is thread unsafe and also makes
779*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_name thread unsafe!
780*b2ed49a5SDavid van Moolenbroek */
781*b2ed49a5SDavid van Moolenbroek int i;
782*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *prev_dsentry, *dsentry;
783*b2ed49a5SDavid van Moolenbroek struct _magic_sentry *sentry;
784*b2ed49a5SDavid van Moolenbroek struct _magic_sentry_hash *sentry_hash, *head;
785*b2ed49a5SDavid van Moolenbroek struct _magic_sentry_list *sentry_list;
786*b2ed49a5SDavid van Moolenbroek
787*b2ed49a5SDavid van Moolenbroek assert(buff && buff_size > 0);
788*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff = buff;
789*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff_offset = 0;
790*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff_size = buff_size;
791*b2ed49a5SDavid van Moolenbroek
792*b2ed49a5SDavid van Moolenbroek head = NULL;
793*b2ed49a5SDavid van Moolenbroek
794*b2ed49a5SDavid van Moolenbroek /* Add all the sentries to the hash. */
795*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_SENTRY
796*b2ed49a5SDavid van Moolenbroek for(i = 0 ; i < _magic_sentries_num ; i++) {
797*b2ed49a5SDavid van Moolenbroek sentry_hash = (struct _magic_sentry_hash *)
798*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_alloc(sizeof(struct _magic_sentry_hash));
799*b2ed49a5SDavid van Moolenbroek sentry_list = (struct _magic_sentry_list *)
800*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_alloc(sizeof(struct _magic_sentry_list));
801*b2ed49a5SDavid van Moolenbroek sentry = &_magic_sentries[i];
802*b2ed49a5SDavid van Moolenbroek MAGIC_SENTRY_TO_HASH_EL(sentry, sentry_hash, sentry_list);
803*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_insert(&head, sentry_hash);
804*b2ed49a5SDavid van Moolenbroek }
805*b2ed49a5SDavid van Moolenbroek #endif
806*b2ed49a5SDavid van Moolenbroek
807*b2ed49a5SDavid van Moolenbroek /* Add all the dsentries to the hash. */
808*b2ed49a5SDavid van Moolenbroek #if MAGIC_LOOKUP_DSENTRY
809*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_LOCK();
810*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
811*b2ed49a5SDavid van Moolenbroek sentry_hash = (struct _magic_sentry_hash *)
812*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_alloc(sizeof(struct _magic_sentry_hash));
813*b2ed49a5SDavid van Moolenbroek sentry_list = (struct _magic_sentry_list *)
814*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_alloc(sizeof(struct _magic_sentry_list));
815*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_TO_HASH_EL(dsentry, sentry, sentry_hash, sentry_list);
816*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_insert(&head, sentry_hash);
817*b2ed49a5SDavid van Moolenbroek );
818*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_UNLOCK();
819*b2ed49a5SDavid van Moolenbroek #endif
820*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_head = (void *)head;
821*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_hash_head || (!_magic_sentries_num && _magic_first_dsentry == NULL));
822*b2ed49a5SDavid van Moolenbroek }
823*b2ed49a5SDavid van Moolenbroek
824*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
825*b2ed49a5SDavid van Moolenbroek * magic_sentry_hash_destroy *
826*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_hash_destroy(void)827*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_sentry_hash_destroy(void)
828*b2ed49a5SDavid van Moolenbroek {
829*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff = NULL;
830*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff_offset = 0;
831*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff_size = 0;
832*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_head = NULL;
833*b2ed49a5SDavid van Moolenbroek }
834*b2ed49a5SDavid van Moolenbroek
835*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
836*b2ed49a5SDavid van Moolenbroek * magic_sentry_hash_estimate_buff_size *
837*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_hash_estimate_buff_size(int sentries_num)838*b2ed49a5SDavid van Moolenbroek PUBLIC size_t magic_sentry_hash_estimate_buff_size(int sentries_num)
839*b2ed49a5SDavid van Moolenbroek {
840*b2ed49a5SDavid van Moolenbroek if (sentries_num == 0) {
841*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ALIVE_NUM(_magic_first_dsentry, &sentries_num);
842*b2ed49a5SDavid van Moolenbroek sentries_num += _magic_sentries_num;
843*b2ed49a5SDavid van Moolenbroek }
844*b2ed49a5SDavid van Moolenbroek
845*b2ed49a5SDavid van Moolenbroek return (sentries_num * (sizeof(struct _magic_sentry_hash) +
846*b2ed49a5SDavid van Moolenbroek sizeof(struct _magic_sentry_list))) + MAGIC_SENTRY_NAME_HASH_OVERHEAD;
847*b2ed49a5SDavid van Moolenbroek }
848*b2ed49a5SDavid van Moolenbroek
849*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
850*b2ed49a5SDavid van Moolenbroek * magic_sentry_hash_alloc *
851*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_hash_alloc(size_t size)852*b2ed49a5SDavid van Moolenbroek PUBLIC void *magic_sentry_hash_alloc(size_t size)
853*b2ed49a5SDavid van Moolenbroek {
854*b2ed49a5SDavid van Moolenbroek void *addr;
855*b2ed49a5SDavid van Moolenbroek
856*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_hash_buff);
857*b2ed49a5SDavid van Moolenbroek assert(magic_sentry_hash_buff_offset + size <= magic_sentry_hash_buff_size);
858*b2ed49a5SDavid van Moolenbroek
859*b2ed49a5SDavid van Moolenbroek addr = (char *) magic_sentry_hash_buff + magic_sentry_hash_buff_offset;
860*b2ed49a5SDavid van Moolenbroek magic_sentry_hash_buff_offset += size;
861*b2ed49a5SDavid van Moolenbroek
862*b2ed49a5SDavid van Moolenbroek return addr;
863*b2ed49a5SDavid van Moolenbroek }
864*b2ed49a5SDavid van Moolenbroek
865*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
866*b2ed49a5SDavid van Moolenbroek * magic_sentry_hash_dealloc *
867*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_hash_dealloc(UNUSED (void * object),UNUSED (size_t sz))868*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_sentry_hash_dealloc(UNUSED(void *object), UNUSED(size_t sz))
869*b2ed49a5SDavid van Moolenbroek {
870*b2ed49a5SDavid van Moolenbroek return;
871*b2ed49a5SDavid van Moolenbroek }
872*b2ed49a5SDavid van Moolenbroek
873*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
874*b2ed49a5SDavid van Moolenbroek * magic_sentry_lookup_by_name_hash *
875*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_lookup_by_name_hash(const char * parent_name,const char * name,_magic_id_t site_id,struct _magic_dsentry * dsentry_buff)876*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry *magic_sentry_lookup_by_name_hash(
877*b2ed49a5SDavid van Moolenbroek const char *parent_name, const char *name, _magic_id_t site_id,
878*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *dsentry_buff)
879*b2ed49a5SDavid van Moolenbroek {
880*b2ed49a5SDavid van Moolenbroek /*
881*b2ed49a5SDavid van Moolenbroek * Warning: this implementation is thread unsafe!
882*b2ed49a5SDavid van Moolenbroek */
883*b2ed49a5SDavid van Moolenbroek char key[MAGIC_SENTRY_NAME_MAX_KEY_LEN];
884*b2ed49a5SDavid van Moolenbroek struct _magic_sentry_hash *res, *head;
885*b2ed49a5SDavid van Moolenbroek key[0] = 0;
886*b2ed49a5SDavid van Moolenbroek snprintf(key, sizeof(key), "%s%s%s%s" MAGIC_ID_FORMAT, parent_name,
887*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ABS_NAME_SEP, name, MAGIC_DSENTRY_ABS_NAME_SEP, site_id);
888*b2ed49a5SDavid van Moolenbroek head = (struct _magic_sentry_hash *) magic_sentry_hash_head;
889*b2ed49a5SDavid van Moolenbroek
890*b2ed49a5SDavid van Moolenbroek HASH_FIND_STR(head, key, res);
891*b2ed49a5SDavid van Moolenbroek if (res == NULL)
892*b2ed49a5SDavid van Moolenbroek return NULL;
893*b2ed49a5SDavid van Moolenbroek
894*b2ed49a5SDavid van Moolenbroek return res->sentry_list->sentry;
895*b2ed49a5SDavid van Moolenbroek }
896*b2ed49a5SDavid van Moolenbroek
897*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
898*b2ed49a5SDavid van Moolenbroek * magic_sentry_list_lookup_by_name_hash *
899*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_sentry_list_lookup_by_name_hash(const char * parent_name,const char * name,_magic_id_t site_id,struct _magic_dsentry * dsentry_buff)900*b2ed49a5SDavid van Moolenbroek PUBLIC struct _magic_sentry_list *magic_sentry_list_lookup_by_name_hash(
901*b2ed49a5SDavid van Moolenbroek const char *parent_name, const char *name, _magic_id_t site_id,
902*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry *dsentry_buff)
903*b2ed49a5SDavid van Moolenbroek {
904*b2ed49a5SDavid van Moolenbroek /*
905*b2ed49a5SDavid van Moolenbroek * Warning: this implementation is thread unsafe!
906*b2ed49a5SDavid van Moolenbroek */
907*b2ed49a5SDavid van Moolenbroek char key[MAGIC_SENTRY_NAME_MAX_KEY_LEN];
908*b2ed49a5SDavid van Moolenbroek struct _magic_sentry_hash *res, *head;
909*b2ed49a5SDavid van Moolenbroek key[0] = 0;
910*b2ed49a5SDavid van Moolenbroek snprintf(key, sizeof(key), "%s%s%s%s" MAGIC_ID_FORMAT, parent_name,
911*b2ed49a5SDavid van Moolenbroek MAGIC_DSENTRY_ABS_NAME_SEP, name, MAGIC_DSENTRY_ABS_NAME_SEP, site_id);
912*b2ed49a5SDavid van Moolenbroek head = (struct _magic_sentry_hash *) magic_sentry_hash_head;
913*b2ed49a5SDavid van Moolenbroek
914*b2ed49a5SDavid van Moolenbroek HASH_FIND_STR(head, key, res);
915*b2ed49a5SDavid van Moolenbroek if (res == NULL)
916*b2ed49a5SDavid van Moolenbroek return NULL;
917*b2ed49a5SDavid van Moolenbroek
918*b2ed49a5SDavid van Moolenbroek return res->sentry_list;
919*b2ed49a5SDavid van Moolenbroek }
920*b2ed49a5SDavid van Moolenbroek
921