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