2 * sparse/smatch_ranges.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
12 #include "smatch_extra.h"
13 #include "smatch_slist.h"
15 ALLOCATOR(data_info
, "smatch extra data");
16 ALLOCATOR(data_range
, "data range");
17 __DO_ALLOCATOR(struct data_range
, sizeof(struct data_range
), __alignof__(struct data_range
),
18 "permanent ranges", perm_data_range
);
20 char *show_rl(struct range_list
*list
)
22 struct data_range
*tmp
;
28 FOR_EACH_PTR(list
, tmp
) {
30 strncat(full
, ",", 254 - strlen(full
));
31 if (sval_cmp(tmp
->min
, tmp
->max
) == 0) {
32 strncat(full
, sval_to_str(tmp
->min
), 254 - strlen(full
));
35 strncat(full
, sval_to_str(tmp
->min
), 254 - strlen(full
));
36 strncat(full
, "-", 254 - strlen(full
));
37 strncat(full
, sval_to_str(tmp
->max
), 254 - strlen(full
));
38 } END_FOR_EACH_PTR(tmp
);
39 return alloc_sname(full
);
42 static int str_to_comparison_arg_helper(const char *str
,
43 struct expression
*call
, int *comparison
,
44 struct expression
**arg
, char **endp
)
47 char *c
= (char *)str
;
56 *comparison
= SPECIAL_LTE
;
61 } else if (*c
== '=') {
64 *comparison
= SPECIAL_EQUAL
;
65 } else if (*c
== '>') {
68 *comparison
= SPECIAL_GTE
;
81 param
= strtoll(c
, &c
, 10);
82 c
++; /* skip the ']' character */
88 *arg
= get_argument_from_call_expr(call
->args
, param
);
94 int str_to_comparison_arg(const char *str
, struct expression
*call
, int *comparison
, struct expression
**arg
)
103 return str_to_comparison_arg_helper(str
, call
, comparison
, arg
, NULL
);
106 static sval_t
get_val_from_key(int use_max
, struct symbol
*type
, char *c
, struct expression
*call
, char **endp
)
108 struct expression
*arg
;
113 ret
= sval_type_max(type
);
115 ret
= sval_type_min(type
);
117 if (!str_to_comparison_arg_helper(c
, call
, &comparison
, &arg
, endp
))
120 if (use_max
&& get_implied_max(arg
, &tmp
)) {
122 if (comparison
== '<') {
124 ret
= sval_binop(ret
, '-', tmp
);
127 if (!use_max
&& get_implied_min(arg
, &tmp
)) {
129 if (comparison
== '>') {
131 ret
= sval_binop(ret
, '+', tmp
);
138 static sval_t
parse_val(int use_max
, struct expression
*call
, struct symbol
*type
, char *c
, char **endp
)
143 if (!strncmp(start
, "max", 3)) {
144 ret
= sval_type_max(type
);
146 } else if (!strncmp(start
, "u64max", 6)) {
147 ret
= sval_type_val(type
, ULLONG_MAX
);
149 } else if (!strncmp(start
, "s64max", 6)) {
150 ret
= sval_type_val(type
, LLONG_MAX
);
152 } else if (!strncmp(start
, "u32max", 6)) {
153 ret
= sval_type_val(type
, UINT_MAX
);
155 } else if (!strncmp(start
, "s32max", 6)) {
156 ret
= sval_type_val(type
, INT_MAX
);
158 } else if (!strncmp(start
, "u16max", 6)) {
159 ret
= sval_type_val(type
, USHRT_MAX
);
161 } else if (!strncmp(start
, "s16max", 6)) {
162 ret
= sval_type_val(type
, SHRT_MAX
);
164 } else if (!strncmp(start
, "min", 3)) {
165 ret
= sval_type_min(type
);
167 } else if (!strncmp(start
, "s64min", 6)) {
168 ret
= sval_type_val(type
, LLONG_MIN
);
170 } else if (!strncmp(start
, "s32min", 6)) {
171 ret
= sval_type_val(type
, INT_MIN
);
173 } else if (!strncmp(start
, "s16min", 6)) {
174 ret
= sval_type_val(type
, SHRT_MIN
);
176 } else if (start
[0] == '[') {
177 /* this parses [==p0] comparisons */
178 ret
= get_val_from_key(1, type
, start
, call
, &c
);
180 ret
= sval_type_val(type
, strtoll(start
, &c
, 10));
186 static void str_to_rl_helper(struct expression
*call
, struct symbol
*type
, char *value
, struct range_list
**rl
)
188 sval_t min
, max
, arg_max
;
195 if (value
&& strcmp(value
, "empty") == 0)
198 if (strncmp(value
, "[==p", 4) == 0) {
199 struct expression
*arg
;
202 if (!str_to_comparison_arg(value
, call
, &comparison
, &arg
))
204 get_implied_rl(arg
, rl
);
212 min
= parse_val(0, call
, type
, c
, &c
);
215 if (*c
== '\0' || *c
== '[') {
216 add_range(rl
, min
, min
);
220 add_range(rl
, min
, min
);
225 sm_msg("debug XXX: trouble parsing %s ", value
);
231 max
= parse_val(1, call
, type
, c
, &c
);
235 arg_max
= get_val_from_key(1, type
, c
, call
, &c
);
236 if (sval_cmp(arg_max
, max
) < 0)
239 add_range(rl
, min
, max
);
243 sm_msg("debug YYY: trouble parsing %s %s", value
, c
);
250 *rl
= cast_rl(type
, *rl
);
253 void str_to_rl(struct symbol
*type
, char *value
, struct range_list
**rl
)
255 return str_to_rl_helper(NULL
, type
, value
, rl
);
258 void call_results_to_rl(struct expression
*expr
, struct symbol
*type
, char *value
, struct range_list
**rl
)
260 return str_to_rl_helper(strip_expr(expr
), type
, value
, rl
);
263 int is_whole_rl(struct range_list
*rl
)
265 struct data_range
*drange
;
267 if (ptr_list_empty(rl
))
269 drange
= first_ptr_list((struct ptr_list
*)rl
);
270 if (sval_is_min(drange
->min
) && sval_is_max(drange
->max
))
275 sval_t
rl_min(struct range_list
*rl
)
277 struct data_range
*drange
;
280 ret
.type
= &llong_ctype
;
281 ret
.value
= LLONG_MIN
;
282 if (ptr_list_empty(rl
))
284 drange
= first_ptr_list((struct ptr_list
*)rl
);
288 sval_t
rl_max(struct range_list
*rl
)
290 struct data_range
*drange
;
293 ret
.type
= &llong_ctype
;
294 ret
.value
= LLONG_MAX
;
295 if (ptr_list_empty(rl
))
297 drange
= last_ptr_list((struct ptr_list
*)rl
);
301 int rl_to_sval(struct range_list
*rl
, sval_t
*sval
)
310 if (sval_cmp(min
, max
) != 0)
316 struct symbol
*rl_type(struct range_list
*rl
)
320 return rl_min(rl
).type
;
323 static struct data_range
*alloc_range_helper_sval(sval_t min
, sval_t max
, int perm
)
325 struct data_range
*ret
;
328 ret
= __alloc_perm_data_range(0);
330 ret
= __alloc_data_range(0);
336 struct data_range
*alloc_range(sval_t min
, sval_t max
)
338 return alloc_range_helper_sval(min
, max
, 0);
341 struct data_range
*alloc_range_perm(sval_t min
, sval_t max
)
343 return alloc_range_helper_sval(min
, max
, 1);
346 struct range_list
*alloc_rl(sval_t min
, sval_t max
)
348 struct range_list
*rl
= NULL
;
350 if (sval_cmp(min
, max
) > 0)
351 return alloc_whole_rl(min
.type
);
353 add_range(&rl
, min
, max
);
357 struct range_list
*alloc_whole_rl(struct symbol
*type
)
359 if (!type
|| type_positive_bits(type
) < 0)
362 return alloc_rl(sval_type_min(type
), sval_type_max(type
));
365 void add_range(struct range_list
**list
, sval_t min
, sval_t max
)
367 struct data_range
*tmp
= NULL
;
368 struct data_range
*new = NULL
;
372 * FIXME: This has a problem merging a range_list like: min-0,3-max
373 * with a range like 1-2. You end up with min-2,3-max instead of
376 FOR_EACH_PTR(*list
, tmp
) {
378 /* Sometimes we overlap with more than one range
379 so we have to delete or modify the next range. */
380 if (max
.value
+ 1 == tmp
->min
.value
) {
381 /* join 2 ranges here */
383 DELETE_CURRENT_PTR(tmp
);
387 /* Doesn't overlap with the next one. */
388 if (sval_cmp(max
, tmp
->min
) < 0)
390 /* Partially overlaps with the next one. */
391 if (sval_cmp(max
, tmp
->max
) < 0) {
392 tmp
->min
.value
= max
.value
+ 1;
395 /* Completely overlaps with the next one. */
396 if (sval_cmp(max
, tmp
->max
) >= 0) {
397 DELETE_CURRENT_PTR(tmp
);
398 /* there could be more ranges to delete */
402 if (!sval_is_max(max
) && max
.value
+ 1 == tmp
->min
.value
) {
403 /* join 2 ranges into a big range */
404 new = alloc_range(min
, tmp
->max
);
405 REPLACE_CURRENT_PTR(tmp
, new);
408 if (sval_cmp(max
, tmp
->min
) < 0) { /* new range entirely below */
409 new = alloc_range(min
, max
);
410 INSERT_CURRENT(new, tmp
);
413 if (sval_cmp(min
, tmp
->min
) < 0) { /* new range partially below */
414 if (sval_cmp(max
, tmp
->max
) < 0)
418 new = alloc_range(min
, max
);
419 REPLACE_CURRENT_PTR(tmp
, new);
424 if (sval_cmp(max
, tmp
->max
) <= 0) /* new range already included */
426 if (sval_cmp(min
, tmp
->max
) <= 0) { /* new range partially above */
428 new = alloc_range(min
, max
);
429 REPLACE_CURRENT_PTR(tmp
, new);
433 if (!sval_is_min(min
) && min
.value
- 1 == tmp
->max
.value
) {
434 /* join 2 ranges into a big range */
435 new = alloc_range(tmp
->min
, max
);
436 REPLACE_CURRENT_PTR(tmp
, new);
440 /* the new range is entirely above the existing ranges */
441 } END_FOR_EACH_PTR(tmp
);
444 new = alloc_range(min
, max
);
445 add_ptr_list(list
, new);
448 struct range_list
*clone_rl(struct range_list
*list
)
450 struct data_range
*tmp
;
451 struct range_list
*ret
= NULL
;
453 FOR_EACH_PTR(list
, tmp
) {
454 add_ptr_list(&ret
, tmp
);
455 } END_FOR_EACH_PTR(tmp
);
459 struct range_list
*clone_rl_permanent(struct range_list
*list
)
461 struct data_range
*tmp
;
462 struct data_range
*new;
463 struct range_list
*ret
= NULL
;
465 FOR_EACH_PTR(list
, tmp
) {
466 new = alloc_range_perm(tmp
->min
, tmp
->max
);
467 add_ptr_list(&ret
, new);
468 } END_FOR_EACH_PTR(tmp
);
472 struct range_list
*rl_union(struct range_list
*one
, struct range_list
*two
)
474 struct data_range
*tmp
;
475 struct range_list
*ret
= NULL
;
477 FOR_EACH_PTR(one
, tmp
) {
478 add_range(&ret
, tmp
->min
, tmp
->max
);
479 } END_FOR_EACH_PTR(tmp
);
480 FOR_EACH_PTR(two
, tmp
) {
481 add_range(&ret
, tmp
->min
, tmp
->max
);
482 } END_FOR_EACH_PTR(tmp
);
486 struct range_list
*remove_range(struct range_list
*list
, sval_t min
, sval_t max
)
488 struct data_range
*tmp
;
489 struct range_list
*ret
= NULL
;
491 FOR_EACH_PTR(list
, tmp
) {
492 if (sval_cmp(tmp
->max
, min
) < 0) {
493 add_range(&ret
, tmp
->min
, tmp
->max
);
496 if (sval_cmp(tmp
->min
, max
) > 0) {
497 add_range(&ret
, tmp
->min
, tmp
->max
);
500 if (sval_cmp(tmp
->min
, min
) >= 0 && sval_cmp(tmp
->max
, max
) <= 0)
502 if (sval_cmp(tmp
->min
, min
) >= 0) {
504 add_range(&ret
, max
, tmp
->max
);
505 } else if (sval_cmp(tmp
->max
, max
) <= 0) {
507 add_range(&ret
, tmp
->min
, min
);
511 add_range(&ret
, tmp
->min
, min
);
512 add_range(&ret
, max
, tmp
->max
);
514 } END_FOR_EACH_PTR(tmp
);
518 int ranges_equiv(struct data_range
*one
, struct data_range
*two
)
524 if (sval_cmp(one
->min
, two
->min
) != 0)
526 if (sval_cmp(one
->max
, two
->max
) != 0)
531 int rl_equiv(struct range_list
*one
, struct range_list
*two
)
533 struct data_range
*one_range
;
534 struct data_range
*two_range
;
539 PREPARE_PTR_LIST(one
, one_range
);
540 PREPARE_PTR_LIST(two
, two_range
);
542 if (!one_range
&& !two_range
)
544 if (!ranges_equiv(one_range
, two_range
))
546 NEXT_PTR_LIST(one_range
);
547 NEXT_PTR_LIST(two_range
);
549 FINISH_PTR_LIST(two_range
);
550 FINISH_PTR_LIST(one_range
);
555 int true_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
557 switch (comparison
) {
559 case SPECIAL_UNSIGNED_LT
:
560 if (sval_cmp(left
->min
, right
->max
) < 0)
563 case SPECIAL_UNSIGNED_LTE
:
565 if (sval_cmp(left
->min
, right
->max
) <= 0)
569 if (sval_cmp(left
->max
, right
->min
) < 0)
571 if (sval_cmp(left
->min
, right
->max
) > 0)
574 case SPECIAL_UNSIGNED_GTE
:
576 if (sval_cmp(left
->max
, right
->min
) >= 0)
580 case SPECIAL_UNSIGNED_GT
:
581 if (sval_cmp(left
->max
, right
->min
) > 0)
584 case SPECIAL_NOTEQUAL
:
585 if (sval_cmp(left
->min
, left
->max
) != 0)
587 if (sval_cmp(right
->min
, right
->max
) != 0)
589 if (sval_cmp(left
->min
, right
->min
) != 0)
593 sm_msg("unhandled comparison %d\n", comparison
);
599 int true_comparison_range_LR(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
602 return true_comparison_range(var
, comparison
, val
);
604 return true_comparison_range(val
, comparison
, var
);
607 static int false_comparison_range_sval(struct data_range
*left
, int comparison
, struct data_range
*right
)
609 switch (comparison
) {
611 case SPECIAL_UNSIGNED_LT
:
612 if (sval_cmp(left
->max
, right
->min
) >= 0)
615 case SPECIAL_UNSIGNED_LTE
:
617 if (sval_cmp(left
->max
, right
->min
) > 0)
621 if (sval_cmp(left
->min
, left
->max
) != 0)
623 if (sval_cmp(right
->min
, right
->max
) != 0)
625 if (sval_cmp(left
->min
, right
->min
) != 0)
628 case SPECIAL_UNSIGNED_GTE
:
630 if (sval_cmp(left
->min
, right
->max
) < 0)
634 case SPECIAL_UNSIGNED_GT
:
635 if (sval_cmp(left
->min
, right
->max
) <= 0)
638 case SPECIAL_NOTEQUAL
:
639 if (sval_cmp(left
->max
, right
->min
) < 0)
641 if (sval_cmp(left
->min
, right
->max
) > 0)
645 sm_msg("unhandled comparison %d\n", comparison
);
651 int false_comparison_range_LR(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
654 return false_comparison_range_sval(var
, comparison
, val
);
656 return false_comparison_range_sval(val
, comparison
, var
);
659 int possibly_true(struct expression
*left
, int comparison
, struct expression
*right
)
661 struct range_list
*rl_left
, *rl_right
;
662 struct data_range
*tmp_left
, *tmp_right
;
664 if (!get_implied_rl(left
, &rl_left
))
666 if (!get_implied_rl(right
, &rl_right
))
669 FOR_EACH_PTR(rl_left
, tmp_left
) {
670 FOR_EACH_PTR(rl_right
, tmp_right
) {
671 if (true_comparison_range(tmp_left
, comparison
, tmp_right
))
673 } END_FOR_EACH_PTR(tmp_right
);
674 } END_FOR_EACH_PTR(tmp_left
);
678 int possibly_false(struct expression
*left
, int comparison
, struct expression
*right
)
680 struct range_list
*rl_left
, *rl_right
;
681 struct data_range
*tmp_left
, *tmp_right
;
683 if (!get_implied_rl(left
, &rl_left
))
685 if (!get_implied_rl(right
, &rl_right
))
688 FOR_EACH_PTR(rl_left
, tmp_left
) {
689 FOR_EACH_PTR(rl_right
, tmp_right
) {
690 if (false_comparison_range_sval(tmp_left
, comparison
, tmp_right
))
692 } END_FOR_EACH_PTR(tmp_right
);
693 } END_FOR_EACH_PTR(tmp_left
);
697 int possibly_true_rl(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
699 struct data_range
*left_tmp
, *right_tmp
;
701 if (!left_ranges
|| !right_ranges
)
704 FOR_EACH_PTR(left_ranges
, left_tmp
) {
705 FOR_EACH_PTR(right_ranges
, right_tmp
) {
706 if (true_comparison_range(left_tmp
, comparison
, right_tmp
))
708 } END_FOR_EACH_PTR(right_tmp
);
709 } END_FOR_EACH_PTR(left_tmp
);
713 int possibly_false_rl(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
715 struct data_range
*left_tmp
, *right_tmp
;
717 if (!left_ranges
|| !right_ranges
)
720 FOR_EACH_PTR(left_ranges
, left_tmp
) {
721 FOR_EACH_PTR(right_ranges
, right_tmp
) {
722 if (false_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
724 } END_FOR_EACH_PTR(right_tmp
);
725 } END_FOR_EACH_PTR(left_tmp
);
729 /* FIXME: the _rl here stands for right left so really it should be _lr */
730 int possibly_true_rl_LR(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
733 return possibly_true_rl(a
, comparison
, b
);
735 return possibly_true_rl(b
, comparison
, a
);
738 int possibly_false_rl_LR(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
741 return possibly_false_rl(a
, comparison
, b
);
743 return possibly_false_rl(b
, comparison
, a
);
746 int rl_has_sval(struct range_list
*rl
, sval_t sval
)
748 struct data_range
*tmp
;
750 FOR_EACH_PTR(rl
, tmp
) {
751 if (sval_cmp(tmp
->min
, sval
) <= 0 &&
752 sval_cmp(tmp
->max
, sval
) >= 0)
754 } END_FOR_EACH_PTR(tmp
);
758 void tack_on(struct range_list
**list
, struct data_range
*drange
)
760 add_ptr_list(list
, drange
);
763 void push_rl(struct range_list_stack
**rl_stack
, struct range_list
*rl
)
765 add_ptr_list(rl_stack
, rl
);
768 struct range_list
*pop_rl(struct range_list_stack
**rl_stack
)
770 struct range_list
*rl
;
772 rl
= last_ptr_list((struct ptr_list
*)*rl_stack
);
773 delete_ptr_list_last((struct ptr_list
**)rl_stack
);
777 struct range_list
*top_rl(struct range_list_stack
*rl_stack
)
779 struct range_list
*rl
;
781 rl
= last_ptr_list((struct ptr_list
*)rl_stack
);
785 void filter_top_rl(struct range_list_stack
**rl_stack
, sval_t sval
)
787 struct range_list
*rl
;
789 rl
= pop_rl(rl_stack
);
790 rl
= remove_range(rl
, sval
, sval
);
791 push_rl(rl_stack
, rl
);
794 static int sval_too_big(struct symbol
*type
, sval_t sval
)
796 if (type_bits(type
) == 64)
798 if (sval
.uvalue
> ((1ULL << type_bits(type
)) - 1))
803 static void add_range_t(struct symbol
*type
, struct range_list
**rl
, sval_t min
, sval_t max
)
805 /* If we're just adding a number, cast it and add it */
806 if (sval_cmp(min
, max
) == 0) {
807 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
811 /* If the range is within the type range then add it */
812 if (sval_fits(type
, min
) && sval_fits(type
, max
)) {
813 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
818 * If the range we are adding has more bits than the range type then
819 * add the whole range type. Eg:
820 * 0x8000000000000000 - 0xf000000000000000 -> cast to int
821 * This isn't totally the right thing to do. We could be more granular.
823 if (sval_too_big(type
, min
) || sval_too_big(type
, max
)) {
824 add_range(rl
, sval_type_min(type
), sval_type_max(type
));
828 /* Cast negative values to high positive values */
829 if (sval_is_negative(min
) && type_unsigned(type
)) {
830 if (sval_is_positive(max
)) {
831 if (sval_too_high(type
, max
)) {
832 add_range(rl
, sval_type_min(type
), sval_type_max(type
));
835 add_range(rl
, sval_type_val(type
, 0), sval_cast(type
, max
));
836 max
= sval_type_max(type
);
838 max
= sval_cast(type
, max
);
840 min
= sval_cast(type
, min
);
841 add_range(rl
, min
, max
);
844 /* Cast high positive numbers to negative */
845 if (sval_unsigned(max
) && sval_is_negative(sval_cast(type
, max
))) {
846 if (!sval_is_negative(sval_cast(type
, min
))) {
847 add_range(rl
, sval_cast(type
, min
), sval_type_max(type
));
848 min
= sval_type_min(type
);
850 min
= sval_cast(type
, min
);
852 max
= sval_cast(type
, max
);
853 add_range(rl
, min
, max
);
859 struct range_list
*rl_truncate_cast(struct symbol
*type
, struct range_list
*rl
)
861 struct data_range
*tmp
;
862 struct range_list
*ret
= NULL
;
868 if (!type
|| type
== rl_type(rl
))
871 FOR_EACH_PTR(rl
, tmp
) {
874 if (type_bits(type
) < type_bits(rl_type(rl
))) {
875 min
.uvalue
= tmp
->min
.uvalue
& ((1ULL << type_bits(type
)) - 1);
876 max
.uvalue
= tmp
->max
.uvalue
& ((1ULL << type_bits(type
)) - 1);
878 if (sval_cmp(min
, max
) > 0) {
879 min
= sval_cast(type
, min
);
880 max
= sval_cast(type
, max
);
882 add_range_t(type
, &ret
, min
, max
);
883 } END_FOR_EACH_PTR(tmp
);
888 static int rl_is_sane(struct range_list
*rl
)
890 struct data_range
*tmp
;
894 FOR_EACH_PTR(rl
, tmp
) {
895 if (!sval_fits(type
, tmp
->min
))
897 if (!sval_fits(type
, tmp
->max
))
899 if (sval_cmp(tmp
->min
, tmp
->max
) > 0)
901 } END_FOR_EACH_PTR(tmp
);
906 static int rl_type_consistent(struct range_list
*rl
)
908 struct data_range
*tmp
;
912 FOR_EACH_PTR(rl
, tmp
) {
913 if (type
!= tmp
->min
.type
|| type
!= tmp
->max
.type
)
915 } END_FOR_EACH_PTR(tmp
);
919 struct range_list
*cast_rl(struct symbol
*type
, struct range_list
*rl
)
921 struct data_range
*tmp
;
922 struct range_list
*ret
= NULL
;
930 return alloc_whole_rl(type
);
931 if (type
== rl_type(rl
) && rl_type_consistent(rl
))
934 FOR_EACH_PTR(rl
, tmp
) {
935 add_range_t(type
, &ret
, tmp
->min
, tmp
->max
);
936 } END_FOR_EACH_PTR(tmp
);
939 return alloc_whole_rl(type
);
944 struct range_list
*rl_invert(struct range_list
*orig
)
946 struct range_list
*ret
= NULL
;
947 struct data_range
*tmp
;
948 sval_t gap_min
, abs_max
, sval
;
953 gap_min
= sval_type_min(rl_min(orig
).type
);
954 abs_max
= sval_type_max(rl_max(orig
).type
);
956 FOR_EACH_PTR(orig
, tmp
) {
957 if (sval_cmp(tmp
->min
, gap_min
) > 0) {
958 sval
= sval_type_val(tmp
->min
.type
, tmp
->min
.value
- 1);
959 add_range(&ret
, gap_min
, sval
);
961 gap_min
= sval_type_val(tmp
->max
.type
, tmp
->max
.value
+ 1);
962 if (sval_cmp(tmp
->max
, abs_max
) == 0)
964 } END_FOR_EACH_PTR(tmp
);
966 if (sval_cmp(gap_min
, abs_max
) < 0)
967 add_range(&ret
, gap_min
, abs_max
);
972 struct range_list
*rl_filter(struct range_list
*rl
, struct range_list
*filter
)
974 struct data_range
*tmp
;
976 FOR_EACH_PTR(filter
, tmp
) {
977 rl
= remove_range(rl
, tmp
->min
, tmp
->max
);
978 } END_FOR_EACH_PTR(tmp
);
983 struct range_list
*rl_intersection(struct range_list
*one
, struct range_list
*two
)
987 two
= rl_invert(two
);
988 return rl_filter(one
, two
);
991 void free_rl(struct range_list
**rlist
)
993 __free_ptr_list((struct ptr_list
**)rlist
);
996 static void free_single_dinfo(struct data_info
*dinfo
)
998 free_rl(&dinfo
->value_ranges
);
1001 static void free_dinfos(struct allocation_blob
*blob
)
1003 unsigned int size
= sizeof(struct data_info
);
1004 unsigned int offset
= 0;
1006 while (offset
< blob
->offset
) {
1007 free_single_dinfo((struct data_info
*)(blob
->data
+ offset
));
1012 void free_data_info_allocs(void)
1014 struct allocator_struct
*desc
= &data_info_allocator
;
1015 struct allocation_blob
*blob
= desc
->blobs
;
1018 desc
->allocations
= 0;
1019 desc
->total_bytes
= 0;
1020 desc
->useful_bytes
= 0;
1021 desc
->freelist
= NULL
;
1023 struct allocation_blob
*next
= blob
->next
;
1025 blob_free(blob
, desc
->chunking
);
1028 clear_data_range_alloc();