1 #include <magic_sentry.h>
2 #include <magic_splay_tree.h>
4 /*===========================================================================*
5 * magic_sentry_get_off_by_n *
6 *===========================================================================*/
7 PUBLIC
long magic_sentry_get_off_by_n(struct _magic_sentry
*sentry
,
10 char *el_addr
= (char*) addr
, *first_el_addr
, *last_el_addr
;
12 unsigned long n
, diff
;
15 if (sentry
->type
->type_id
!= MAGIC_TYPE_ARRAY
) {
18 el_size
= sentry
->type
->contained_types
[0]->size
;
19 first_el_addr
= (char*) sentry
->address
;
20 last_el_addr
= (first_el_addr
+sentry
->type
->size
-el_size
);
21 if (el_addr
>= last_el_addr
) {
22 diff
= (unsigned long) (el_addr
- last_el_addr
);
24 else if (el_addr
<= first_el_addr
) {
25 diff
= (unsigned long) (first_el_addr
- el_addr
);
30 if (diff
% el_size
!= 0) {
37 long_n
= (el_addr
>= last_el_addr
? (long) n
: -((long)n
));
38 if ((long_n
< 0 && !(flags
& MAGIC_SENTRY_OFF_BY_N_NEGATIVE
))
39 || (long_n
> 0 && !(flags
& MAGIC_SENTRY_OFF_BY_N_POSITIVE
))
40 || (long_n
== 0 && !(flags
& MAGIC_SENTRY_OFF_BY_N_ZERO
))) {
46 /*===========================================================================*
47 * magic_do_check_sentry *
48 *===========================================================================*/
49 PRIVATE INLINE
int magic_do_check_sentry(struct _magic_sentry
*sentry
)
52 assert(sentry
&& "NULL sentry found!");
53 is_size_ok
= sentry
->type
->size
> 0;
55 _magic_printf("magic_do_check_sentry: bad sentry, checks: %d\n", is_size_ok
);
56 MAGIC_SENTRY_PRINT(sentry
, MAGIC_EXPAND_TYPE_STR
);
63 /*===========================================================================*
64 * magic_check_sentry *
65 *===========================================================================*/
66 PUBLIC
int magic_check_sentry(struct _magic_sentry
*sentry
)
69 check
= magic_do_check_sentry(sentry
);
74 #if MAGIC_CHECK_LEVEL == 2
75 check
= magic_check_sentries();
77 _magic_printf("magic_check_sentry: bad other sentry\n");
85 /*===========================================================================*
86 * magic_check_sentries *
87 *===========================================================================*/
88 PUBLIC
int magic_check_sentries()
90 int i
, ret
, check
= TRUE
;
92 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
93 ret
= magic_do_check_sentry(&_magic_sentries
[i
]);
102 /*===========================================================================*
103 * magic_sentry_lookup_by_id *
104 *===========================================================================*/
105 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_id(_magic_id_t id
,
106 struct _magic_dsentry
*dsentry_buff
)
108 struct _magic_sentry
*entry
= NULL
;
109 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
110 struct _magic_sentry
*sentry
;
116 /* O(1) ID lookup for sentries. */
117 #if MAGIC_LOOKUP_SENTRY
118 if ((int)id
<= _magic_sentries_num
) {
119 return &_magic_sentries
[id
- 1];
123 /* O(N) ID lookup for dsentries. */
124 #if MAGIC_LOOKUP_DSENTRY
125 MAGIC_DSENTRY_LOCK();
126 MAGIC_DSENTRY_ALIVE_NESTED_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
127 if(sentry
->id
== id
) {
129 magic_copy_dsentry(dsentry
, dsentry_buff
);
130 entry
= MAGIC_DSENTRY_TO_SENTRY(dsentry_buff
);
138 MAGIC_DSENTRY_UNLOCK();
144 /*===========================================================================*
145 * magic_sentry_lookup_by_addr *
146 *===========================================================================*/
147 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_addr(void *addr
,
148 struct _magic_dsentry
*dsentry_buff
)
151 struct _magic_sentry
*entry
= NULL
;
152 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
153 struct _magic_sentry
*sentry
;
155 #if MAGIC_LOOKUP_SENTRY_ALLOW_RANGE_INDEX
156 if (magic_sentry_rl_index
) {
157 sentry
= magic_sentry_lookup_by_range_index(addr
, dsentry_buff
);
158 if (sentry
&& sentry
->address
== addr
) {
166 /* Scan all the entries and return the one matching the provided address. */
167 #if MAGIC_LOOKUP_SENTRY
168 if (MAGIC_ADDR_IS_IN_RANGE(addr
, magic_sentry_range
)) {
169 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
170 if (_magic_sentries
[i
].address
== addr
) {
171 entry
= &_magic_sentries
[i
];
181 #if MAGIC_LOOKUP_DSENTRY
182 MAGIC_DSENTRY_LOCK();
183 if (!MAGIC_ADDR_LOOKUP_USE_DSENTRY_RANGES
|| magic_range_is_dsentry(addr
)) {
184 MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
185 if (sentry
->address
== addr
) {
187 magic_copy_dsentry(dsentry
, dsentry_buff
);
188 entry
= MAGIC_DSENTRY_TO_SENTRY(dsentry_buff
);
197 MAGIC_DSENTRY_UNLOCK();
203 /*===========================================================================*
204 * magic_sentry_lookup_by_name *
205 *===========================================================================*/
206 PUBLIC
struct _magic_sentry
*
207 magic_sentry_lookup_by_name(const char *parent_name
, const char *name
,
208 _magic_id_t site_id
, struct _magic_dsentry
*dsentry_buff
)
211 struct _magic_sentry
*entry
= NULL
;
212 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
213 struct _magic_sentry
*sentry
;
215 #if MAGIC_LOOKUP_SENTRY_ALLOW_NAME_HASH
216 if (magic_sentry_hash_head
) {
217 return magic_sentry_lookup_by_name_hash(parent_name
, name
,
218 site_id
, dsentry_buff
);
222 /* Scan all the entries and return the one matching the provided name. */
223 #if MAGIC_LOOKUP_SENTRY
224 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
225 if (!strcmp(_magic_sentries
[i
].name
, name
)) {
227 !strcmp(MAGIC_SENTRY_PARENT(&_magic_sentries
[i
]),
229 if (MAGIC_SENTRY_SITE_ID(&_magic_sentries
[i
]) == site_id
) {
230 entry
= &_magic_sentries
[i
];
241 #if MAGIC_LOOKUP_DSENTRY
242 MAGIC_DSENTRY_LOCK();
243 MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry
, prev_dsentry
,
245 if (!strcmp(sentry
->name
, name
)) {
247 !strcmp(MAGIC_SENTRY_PARENT(sentry
), parent_name
)) {
248 if (site_id
== MAGIC_DSENTRY_SITE_ID_NULL
||
249 dsentry
->site_id
== site_id
) {
251 magic_copy_dsentry(dsentry
, dsentry_buff
);
252 entry
= MAGIC_DSENTRY_TO_SENTRY(dsentry_buff
);
262 MAGIC_DSENTRY_UNLOCK();
268 /*===========================================================================*
269 * magic_sentry_lookup_by_range *
270 *===========================================================================*/
271 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_range(void *addr
,
272 struct _magic_dsentry
*dsentry_buff
)
275 struct _magic_sentry
*entry
= NULL
;
276 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
277 struct _magic_sentry
*sentry
;
278 void *start_address
, *end_address
;
280 #if MAGIC_LOOKUP_SENTRY_ALLOW_RANGE_INDEX
281 if (magic_sentry_rl_index
) {
282 return magic_sentry_lookup_by_range_index(addr
, dsentry_buff
);
286 /* Scan all the entries and return the one with a valid range. */
287 #if MAGIC_LOOKUP_SENTRY
288 if (MAGIC_ADDR_IS_IN_RANGE(addr
, magic_sentry_range
)) {
289 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
290 start_address
= _magic_sentries
[i
].address
;
291 end_address
= (void *) (((char *)_magic_sentries
[i
].address
) +
292 _magic_sentries
[i
].type
->size
- 1);
293 if (MAGIC_ADDR_IS_WITHIN(addr
, start_address
, end_address
)) {
294 entry
= &_magic_sentries
[i
];
304 #if MAGIC_LOOKUP_DSENTRY
305 MAGIC_DSENTRY_LOCK();
306 if (!MAGIC_ADDR_LOOKUP_USE_DSENTRY_RANGES
|| magic_range_is_dsentry(addr
)) {
307 MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
308 start_address
= sentry
->address
;
309 end_address
= (void *) (((char *)sentry
->address
) +
310 sentry
->type
->size
- 1);
311 if (MAGIC_ADDR_IS_WITHIN(addr
, start_address
, end_address
)) {
313 magic_copy_dsentry(dsentry
, dsentry_buff
);
314 entry
= MAGIC_DSENTRY_TO_SENTRY(dsentry_buff
);
323 MAGIC_DSENTRY_UNLOCK();
329 /*===========================================================================*
330 * magic_sentry_lookup_by_min_off_by_n *
331 *===========================================================================*/
332 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_min_off_by_n(void *addr
,
333 int flags
, long *min_n_ptr
, struct _magic_dsentry
*dsentry_buff
)
336 struct _magic_sentry
*entry
= NULL
;
337 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
338 struct _magic_sentry
*sentry
;
339 long n
, abs_n
, min_n
, min_abs_n
= LONG_MAX
;
340 int has_multiple_min_entries
= FALSE
;
342 /* Scan all the entries and return the one with the minimum off-by-n. */
343 #if MAGIC_LOOKUP_SENTRY
344 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
345 n
= magic_sentry_get_off_by_n(&_magic_sentries
[i
], addr
, flags
);
346 abs_n
= MAGIC_ABS(n
);
347 if (n
== LONG_MAX
|| abs_n
> min_abs_n
) {
350 if (abs_n
== min_abs_n
) {
351 has_multiple_min_entries
= TRUE
;
356 has_multiple_min_entries
= FALSE
;
357 entry
= &_magic_sentries
[i
];
362 #if MAGIC_LOOKUP_DSENTRY
363 MAGIC_DSENTRY_LOCK();
364 MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
365 n
= magic_sentry_get_off_by_n(sentry
, addr
, flags
);
366 abs_n
= MAGIC_ABS(n
);
367 if (n
== LONG_MAX
|| abs_n
> min_abs_n
) {
370 if (abs_n
== min_abs_n
) {
371 has_multiple_min_entries
= TRUE
;
376 has_multiple_min_entries
= FALSE
;
378 magic_copy_dsentry(dsentry
, dsentry_buff
);
379 entry
= MAGIC_DSENTRY_TO_SENTRY(dsentry_buff
);
386 MAGIC_DSENTRY_UNLOCK();
389 if (has_multiple_min_entries
&& (flags
& MAGIC_SENTRY_OFF_BY_N_NO_DUPLICATES
)) {
392 if (entry
&& min_n_ptr
) {
398 /*===========================================================================*
399 * magic_sentry_lookup_by_string *
400 *===========================================================================*/
401 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_string(const char *string
)
404 struct _magic_sentry
*entry
= NULL
;
406 /* Scan all the string entries and return the matching one. */
407 #if MAGIC_LOOKUP_SENTRY
408 for(i
= 0 ; i
< _magic_sentries_num
; i
++) {
409 if (MAGIC_STATE_FLAG(&_magic_sentries
[i
], MAGIC_STATE_STRING
)
410 && !strcmp((char *)_magic_sentries
[i
].address
, string
)) {
411 entry
= &_magic_sentries
[i
];
420 /*===========================================================================*
421 * magic_print_sentry *
422 *===========================================================================*/
423 PUBLIC
void magic_print_sentry(struct _magic_sentry
*sentry
)
425 MAGIC_SENTRY_PRINT(sentry
, MAGIC_EXPAND_TYPE_STR
);
428 /*===========================================================================*
429 * magic_print_sentry_abs_name *
430 *===========================================================================*/
431 PUBLIC
void magic_print_sentry_abs_name(struct _magic_sentry
*sentry
)
433 if (!(sentry
->flags
& MAGIC_STATE_DYNAMIC
)) {
434 _magic_printf(sentry
->name
);
437 struct _magic_dsentry
*dsentry
= MAGIC_DSENTRY_FROM_SENTRY(sentry
);
438 assert(dsentry
->parent_name
&& strcmp(dsentry
->parent_name
, ""));
439 assert(sentry
->name
);
440 assert(strcmp(sentry
->name
, ""));
441 _magic_printf("%lu%s%s%s%s%s" MAGIC_ID_FORMAT
, (unsigned long)MAGIC_SENTRY_ID(sentry
),
442 MAGIC_DSENTRY_ABS_NAME_SEP
, dsentry
->parent_name
,
443 MAGIC_DSENTRY_ABS_NAME_SEP
, sentry
->name
,
444 MAGIC_DSENTRY_ABS_NAME_SEP
, dsentry
->site_id
);
448 /*===========================================================================*
449 * magic_print_sentries *
450 *===========================================================================*/
451 PUBLIC
void magic_print_sentries()
454 struct _magic_sentry
* sentry
;
456 _magic_printf("magic_print_sentries: Printing %d entries\n", _magic_sentries_num
);
457 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
458 sentry
= &_magic_sentries
[i
];
459 MAGIC_SENTRY_PRINT(sentry
, MAGIC_EXPAND_TYPE_STR
);
464 /*===========================================================================*
465 * magic_print_nonstr_sentries *
466 *===========================================================================*/
467 PUBLIC
void magic_print_nonstr_sentries()
470 struct _magic_sentry
*sentry
;
472 _magic_printf("magic_print_nonstr_sentries: Printing %d/%d non-string entries\n",
473 _magic_sentries_num
- _magic_sentries_str_num
, _magic_sentries_num
);
474 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
475 sentry
= &_magic_sentries
[i
];
476 if (MAGIC_SENTRY_IS_STRING(sentry
)) {
479 MAGIC_SENTRY_PRINT(sentry
, MAGIC_EXPAND_TYPE_STR
);
484 /*===========================================================================*
485 * magic_print_str_sentries *
486 *===========================================================================*/
487 PUBLIC
void magic_print_str_sentries()
490 struct _magic_sentry
*sentry
;
492 _magic_printf("magic_print_str_sentries: Printing %d/%d string entries\n",
493 _magic_sentries_str_num
, _magic_sentries_num
);
494 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
495 sentry
= &_magic_sentries
[i
];
496 if (!MAGIC_SENTRY_IS_STRING(sentry
)) {
499 MAGIC_SENTRY_PRINT(sentry
, MAGIC_EXPAND_TYPE_STR
);
500 _magic_printf(", string=\"%s\"\n", (char*)sentry
->address
);
504 /*===========================================================================*
505 * magic_sentry_rl_alloc *
506 *===========================================================================*/
507 PRIVATE
void *magic_sentry_rl_alloc(int size
, UNUSED(void *data
))
511 assert(magic_sentry_rl_buff
);
512 assert(magic_sentry_rl_buff_offset
+ size
<= magic_sentry_rl_buff_size
);
514 addr
= (char*) magic_sentry_rl_buff
+ magic_sentry_rl_buff_offset
;
515 magic_sentry_rl_buff_offset
+= size
;
520 /*===========================================================================*
521 * magic_sentry_rl_dealloc *
522 *===========================================================================*/
523 PRIVATE
void magic_sentry_rl_dealloc(UNUSED(void *object
), UNUSED(void *data
))
528 /*===========================================================================*
529 * magic_sentry_rl_build_index *
530 *===========================================================================*/
531 PUBLIC
void magic_sentry_rl_build_index(void *buff
, size_t buff_size
)
534 * Warning: this implementation is thread unsafe and also makes
535 * magic_sentry_lookup_by_range thread unsafe!
538 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
539 struct _magic_sentry
*sentry
;
543 assert(buff
&& buff_size
> 0);
544 magic_sentry_rl_buff
= buff
;
545 magic_sentry_rl_buff_offset
= 0;
546 magic_sentry_rl_buff_size
= buff_size
;
547 index
= splay_tree_new_with_allocator(
548 splay_tree_compare_pointers
,
550 magic_sentry_rl_alloc
, magic_sentry_rl_dealloc
,
552 magic_sentry_rl_index
= index
;
553 assert(magic_sentry_rl_index
);
555 /* Add all the sentries to the index. */
556 #if MAGIC_LOOKUP_SENTRY
557 for (i
= 0 ; i
< _magic_sentries_num
; i
++) {
558 start_address
= _magic_sentries
[i
].address
;
559 sentry
= &_magic_sentries
[i
];
560 magic_sentry_rl_insert(start_address
, sentry
);
564 /* Add all the dsentries to the index. */
565 #if MAGIC_LOOKUP_DSENTRY
566 MAGIC_DSENTRY_LOCK();
567 MAGIC_DSENTRY_ALIVE_BLOCK_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
568 start_address
= sentry
->address
;
569 magic_sentry_rl_insert(start_address
, sentry
);
571 MAGIC_DSENTRY_UNLOCK();
575 /*===========================================================================*
576 * magic_sentry_rl_destroy_index *
577 *===========================================================================*/
578 PUBLIC
void magic_sentry_rl_destroy_index(void)
580 magic_sentry_rl_buff
= NULL
;
581 magic_sentry_rl_buff_offset
= 0;
582 magic_sentry_rl_buff_size
= 0;
583 magic_sentry_rl_index
= NULL
;
586 /*===========================================================================*
587 * magic_sentry_rl_estimate_index_buff_size *
588 *===========================================================================*/
589 PUBLIC
size_t magic_sentry_rl_estimate_index_buff_size(int sentries_num
)
591 if (sentries_num
== 0) {
592 MAGIC_DSENTRY_ALIVE_BLOCK_NUM(_magic_first_dsentry
, &sentries_num
);
593 sentries_num
+= _magic_sentries_num
;
596 return (sentries_num
* sizeof(struct splay_tree_node_s
)) +
597 (sizeof(struct splay_tree_s
) * 2);
600 /*===========================================================================*
601 * magic_sentry_rl_count_index_cb *
602 *===========================================================================*/
603 PRIVATE
int magic_sentry_rl_count_index_cb(splay_tree_node node
, void *data
)
605 size_t *count
= (size_t *) data
;
611 /*===========================================================================*
612 * magic_sentry_rl_print_index_cb *
613 *===========================================================================*/
614 PRIVATE
int magic_sentry_rl_print_index_cb(splay_tree_node node
, void *data
)
616 _magic_printf("NODE<key, value>: <%08x, %08x>\n", (unsigned int) node
->key
,
617 (unsigned int) node
->value
);
621 /*===========================================================================*
622 * magic_sentry_rl_print_index *
623 *===========================================================================*/
624 PUBLIC
void magic_sentry_rl_print_index(void)
626 size_t num_nodes
= 0;
627 assert(magic_sentry_rl_index
);
629 splay_tree_foreach((splay_tree
) magic_sentry_rl_index
,
630 magic_sentry_rl_count_index_cb
, &num_nodes
);
631 _magic_printf("magic_sentry_rl_print_index: Found %d nodes:\n", num_nodes
);
632 splay_tree_foreach((splay_tree
) magic_sentry_rl_index
,
633 magic_sentry_rl_print_index_cb
, NULL
);
636 /*===========================================================================*
637 * magic_sentry_rl_lookup *
638 *===========================================================================*/
639 PUBLIC
struct _magic_sentry
*magic_sentry_rl_lookup(void *start_addr
)
641 splay_tree_node node
;
642 struct _magic_sentry
*sentry
= NULL
;
644 node
= splay_tree_lookup((splay_tree
) magic_sentry_rl_index
,
645 (splay_tree_key
) start_addr
);
647 sentry
= (struct _magic_sentry
*) node
->value
;
653 /*===========================================================================*
654 * magic_sentry_rl_insert *
655 *===========================================================================*/
656 PUBLIC
struct _magic_sentry
*magic_sentry_rl_insert(void *start_addr
,
657 struct _magic_sentry
*sentry
)
659 if (!splay_tree_lookup((splay_tree
) magic_sentry_rl_index
,
660 (splay_tree_key
) start_addr
)) {
661 splay_tree_insert((splay_tree
) magic_sentry_rl_index
,
662 (splay_tree_key
) start_addr
,
663 (splay_tree_value
) sentry
);
672 /*===========================================================================*
673 * magic_sentry_rl_pred_lookup *
674 *===========================================================================*/
675 PUBLIC
struct _magic_sentry
*magic_sentry_rl_pred_lookup(void *addr
)
677 splay_tree_node node
;
678 struct _magic_sentry
*sentry
= NULL
;
680 node
= splay_tree_predecessor((splay_tree
) magic_sentry_rl_index
,
681 (splay_tree_key
) addr
);
683 sentry
= (struct _magic_sentry
*) node
->value
;
689 /*===========================================================================*
690 * magic_sentry_lookup_by_range_index *
691 *===========================================================================*/
692 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_range_index(
693 void *addr
, struct _magic_dsentry
*dsentry_buff
)
696 * Warning: this implementation is thread unsafe!
698 void *start_address
, *end_address
;
699 struct _magic_sentry
*sentry
=
700 magic_sentry_rl_pred_lookup((char *)addr
+ 1);
703 start_address
= sentry
->address
;
704 end_address
= (void *) (((char *)start_address
) +
705 sentry
->type
->size
- 1);
706 if (!MAGIC_ADDR_IS_WITHIN(addr
, start_address
, end_address
)) {
709 if (MAGIC_STATE_FLAG(sentry
, MAGIC_STATE_DYNAMIC
) &&
710 dsentry_buff
!= NULL
) {
711 magic_copy_dsentry(MAGIC_DSENTRY_FROM_SENTRY(sentry
),
720 /*===========================================================================*
721 * magic_sentry_hash_insert *
722 *===========================================================================*/
723 PRIVATE
void magic_sentry_hash_insert(struct _magic_sentry_hash
**head
,
724 struct _magic_sentry_hash
*elem
)
727 struct _magic_sentry_hash
*tmp
;
728 HASH_FIND_STR(*head
, elem
->key
, tmp
);
730 LL_APPEND(tmp
->sentry_list
, elem
->sentry_list
);
735 * **** START UTHASH SPECIFIC DEFINITIONS ****
739 #define uthash_malloc(size) magic_sentry_hash_alloc(size)
740 #define uthash_free(addr, size) magic_sentry_hash_dealloc(addr, size)
742 * Since we have a limited buffer, we need to stop bucket expansion when
743 * reaching a certain limit.
745 #undef uthash_expand_fyi
746 #define uthash_expand_fyi(tbl) \
748 if (tbl->num_buckets == MAGIC_SENTRY_NAME_EST_MAX_BUCKETS) { \
749 _magic_printf("Warning! Sentry name hash maximum bucket number " \
750 "reached! Consider increasing " \
751 "MAGIC_SENTRY_NAME_EST_MAX_BUCKETS, unless you are comfortable"\
752 " with the current performance.\n"); \
757 * **** FINISH UTHASH SPECIFIC DEFINITIONS ****
759 HASH_ADD_STR(*head
, key
, elem
);
761 * **** START UTHASH DEFINITION REMOVAL ****
765 #undef uthash_expand_fyi
767 * **** FINISH UTHASH DEFINITION REMOVAL ****
771 /*===========================================================================*
772 * magic_sentry_hash_build *
773 *===========================================================================*/
774 PUBLIC
void magic_sentry_hash_build(void *buff
, size_t buff_size
)
778 * Warning: this implementation is thread unsafe and also makes
779 * magic_sentry_lookup_by_name thread unsafe!
782 struct _magic_dsentry
*prev_dsentry
, *dsentry
;
783 struct _magic_sentry
*sentry
;
784 struct _magic_sentry_hash
*sentry_hash
, *head
;
785 struct _magic_sentry_list
*sentry_list
;
787 assert(buff
&& buff_size
> 0);
788 magic_sentry_hash_buff
= buff
;
789 magic_sentry_hash_buff_offset
= 0;
790 magic_sentry_hash_buff_size
= buff_size
;
794 /* Add all the sentries to the hash. */
795 #if MAGIC_LOOKUP_SENTRY
796 for(i
= 0 ; i
< _magic_sentries_num
; i
++) {
797 sentry_hash
= (struct _magic_sentry_hash
*)
798 magic_sentry_hash_alloc(sizeof(struct _magic_sentry_hash
));
799 sentry_list
= (struct _magic_sentry_list
*)
800 magic_sentry_hash_alloc(sizeof(struct _magic_sentry_list
));
801 sentry
= &_magic_sentries
[i
];
802 MAGIC_SENTRY_TO_HASH_EL(sentry
, sentry_hash
, sentry_list
);
803 magic_sentry_hash_insert(&head
, sentry_hash
);
807 /* Add all the dsentries to the hash. */
808 #if MAGIC_LOOKUP_DSENTRY
809 MAGIC_DSENTRY_LOCK();
810 MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry
, prev_dsentry
, dsentry
, sentry
,
811 sentry_hash
= (struct _magic_sentry_hash
*)
812 magic_sentry_hash_alloc(sizeof(struct _magic_sentry_hash
));
813 sentry_list
= (struct _magic_sentry_list
*)
814 magic_sentry_hash_alloc(sizeof(struct _magic_sentry_list
));
815 MAGIC_DSENTRY_TO_HASH_EL(dsentry
, sentry
, sentry_hash
, sentry_list
);
816 magic_sentry_hash_insert(&head
, sentry_hash
);
818 MAGIC_DSENTRY_UNLOCK();
820 magic_sentry_hash_head
= (void *)head
;
821 assert(magic_sentry_hash_head
|| (!_magic_sentries_num
&& _magic_first_dsentry
== NULL
));
824 /*===========================================================================*
825 * magic_sentry_hash_destroy *
826 *===========================================================================*/
827 PUBLIC
void magic_sentry_hash_destroy(void)
829 magic_sentry_hash_buff
= NULL
;
830 magic_sentry_hash_buff_offset
= 0;
831 magic_sentry_hash_buff_size
= 0;
832 magic_sentry_hash_head
= NULL
;
835 /*===========================================================================*
836 * magic_sentry_hash_estimate_buff_size *
837 *===========================================================================*/
838 PUBLIC
size_t magic_sentry_hash_estimate_buff_size(int sentries_num
)
840 if (sentries_num
== 0) {
841 MAGIC_DSENTRY_ALIVE_NUM(_magic_first_dsentry
, &sentries_num
);
842 sentries_num
+= _magic_sentries_num
;
845 return (sentries_num
* (sizeof(struct _magic_sentry_hash
) +
846 sizeof(struct _magic_sentry_list
))) + MAGIC_SENTRY_NAME_HASH_OVERHEAD
;
849 /*===========================================================================*
850 * magic_sentry_hash_alloc *
851 *===========================================================================*/
852 PUBLIC
void *magic_sentry_hash_alloc(size_t size
)
856 assert(magic_sentry_hash_buff
);
857 assert(magic_sentry_hash_buff_offset
+ size
<= magic_sentry_hash_buff_size
);
859 addr
= (char *) magic_sentry_hash_buff
+ magic_sentry_hash_buff_offset
;
860 magic_sentry_hash_buff_offset
+= size
;
865 /*===========================================================================*
866 * magic_sentry_hash_dealloc *
867 *===========================================================================*/
868 PUBLIC
void magic_sentry_hash_dealloc(UNUSED(void *object
), UNUSED(size_t sz
))
873 /*===========================================================================*
874 * magic_sentry_lookup_by_name_hash *
875 *===========================================================================*/
876 PUBLIC
struct _magic_sentry
*magic_sentry_lookup_by_name_hash(
877 const char *parent_name
, const char *name
, _magic_id_t site_id
,
878 struct _magic_dsentry
*dsentry_buff
)
881 * Warning: this implementation is thread unsafe!
883 char key
[MAGIC_SENTRY_NAME_MAX_KEY_LEN
];
884 struct _magic_sentry_hash
*res
, *head
;
886 snprintf(key
, sizeof(key
), "%s%s%s%s" MAGIC_ID_FORMAT
, parent_name
,
887 MAGIC_DSENTRY_ABS_NAME_SEP
, name
, MAGIC_DSENTRY_ABS_NAME_SEP
, site_id
);
888 head
= (struct _magic_sentry_hash
*) magic_sentry_hash_head
;
890 HASH_FIND_STR(head
, key
, res
);
894 return res
->sentry_list
->sentry
;
897 /*===========================================================================*
898 * magic_sentry_list_lookup_by_name_hash *
899 *===========================================================================*/
900 PUBLIC
struct _magic_sentry_list
*magic_sentry_list_lookup_by_name_hash(
901 const char *parent_name
, const char *name
, _magic_id_t site_id
,
902 struct _magic_dsentry
*dsentry_buff
)
905 * Warning: this implementation is thread unsafe!
907 char key
[MAGIC_SENTRY_NAME_MAX_KEY_LEN
];
908 struct _magic_sentry_hash
*res
, *head
;
910 snprintf(key
, sizeof(key
), "%s%s%s%s" MAGIC_ID_FORMAT
, parent_name
,
911 MAGIC_DSENTRY_ABS_NAME_SEP
, name
, MAGIC_DSENTRY_ABS_NAME_SEP
, site_id
);
912 head
= (struct _magic_sentry_hash
*) magic_sentry_hash_head
;
914 HASH_FIND_STR(head
, key
, res
);
918 return res
->sentry_list
;