2 * Copyright (C) 2009 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
20 #include "smatch_extra.h"
21 #include "smatch_slist.h"
23 ALLOCATOR(data_info
, "smatch extra data");
24 ALLOCATOR(data_range
, "data range");
25 __DO_ALLOCATOR(struct data_range
, sizeof(struct data_range
), __alignof__(struct data_range
),
26 "permanent ranges", perm_data_range
);
27 __DECLARE_ALLOCATOR(struct ptr_list
, rl_ptrlist
);
29 bool is_err_ptr(sval_t sval
)
31 if (option_project
!= PROJ_KERNEL
)
33 if (!type_is_ptr(sval
.type
))
35 if (sval_cmp(sval
, valid_ptr_max_sval
) <= 0)
40 bool is_err_or_null(struct range_list
*rl
)
42 struct range_list
*no_null
;
47 if (rl_min(rl
).value
== 0 && rl_max(rl
).value
== 0)
50 if (rl_min(rl
).value
!= 0)
53 no_null
= remove_range(rl
, rl_min(rl
), rl_min(rl
));
55 return is_err_ptr(rl_min(no_null
)) && is_err_ptr(rl_max(no_null
));
58 static bool is_oxdead(struct range_list
*rl
)
62 /* check for 0xdead000000000000 */
63 if (!rl_to_sval(rl
, &sval
))
65 if ((sval
.uvalue
>> (bits_in_pointer
- 16)) == 0xdead)
71 bool is_noderef_ptr_rl(struct range_list
*rl
)
76 if (rl_min(rl
).value
== 0 && rl_max(rl
).value
== 0)
78 if (is_err_or_null(rl
))
85 bool rl_is_zero(struct range_list
*rl
)
89 if (rl_min(rl
).value
== 0 && rl_max(rl
).value
== 0)
94 long long sign_extend_err_ptr(long long value
)
96 if (sval_type_max(&ulong_ctype
).value
== UINT_MAX
)
101 static char *get_err_pointer_str(struct data_range
*drange
)
107 * The kernel has error pointers where you do essentially:
109 * return (void *)(unsigned long)-12;
111 * But what I want here is to print -12 instead of the unsigned version
115 if (!is_err_ptr(drange
->min
))
118 min
= drange
->min
.value
;
119 max
= drange
->max
.value
;
121 if (drange
->min
.value
== drange
->max
.value
)
122 snprintf(buf
, sizeof(buf
), "(%lld)", sign_extend_err_ptr(min
));
124 snprintf(buf
, sizeof(buf
), "(%lld)-(%lld)",
125 sign_extend_err_ptr(min
), sign_extend_err_ptr(max
));
129 char *show_rl(struct range_list
*list
)
131 struct data_range
*prev_drange
= NULL
;
132 struct data_range
*tmp
;
142 FOR_EACH_PTR(list
, tmp
) {
143 remain
= full
+ sizeof(full
) - p
;
145 snprintf(prev
, full
+ sizeof(full
) - prev
, ",%s-%s",
146 sval_to_str(prev_drange
->min
),
147 sval_to_str(sval_type_max(prev_drange
->min
.type
)));
153 err_ptr
= get_err_pointer_str(tmp
);
155 p
+= snprintf(p
, remain
, "%s%s", i
++ ? "," : "", err_ptr
);
156 } else if (sval_cmp(tmp
->min
, tmp
->max
) == 0) {
157 p
+= snprintf(p
, remain
, "%s%s", i
++ ? "," : "",
158 sval_to_str(tmp
->min
));
160 p
+= snprintf(p
, remain
, "%s%s-%s", i
++ ? "," : "",
161 sval_to_str(tmp
->min
),
162 sval_to_str(tmp
->max
));
164 } END_FOR_EACH_PTR(tmp
);
166 return alloc_sname(full
);
169 void free_all_rl(void)
171 clear_rl_ptrlist_alloc();
174 static int sval_too_big(struct symbol
*type
, sval_t sval
)
176 if (type_bits(type
) >= 32 &&
177 type_bits(sval
.type
) <= type_bits(type
))
179 if (sval
.uvalue
<= ((1ULL << type_bits(type
)) - 1))
181 if (type_signed(sval
.type
)) {
182 if (type_unsigned(type
)) {
183 unsigned long long neg
= ~sval
.uvalue
;
184 if (neg
<= sval_type_max(type
).uvalue
)
187 if (sval
.value
< sval_type_min(type
).value
)
189 if (sval
.value
> sval_type_max(type
).value
)
193 if (sval
.uvalue
> sval_type_max(type
).uvalue
)
198 static int truncates_nicely(struct symbol
*type
, sval_t min
, sval_t max
)
200 unsigned long long mask
;
201 int bits
= type_bits(type
);
203 if (type_is_fp(min
.type
) && !type_is_fp(type
))
206 if (bits
>= type_bits(min
.type
))
209 mask
= -1ULL << bits
;
210 return (min
.uvalue
& mask
) == (max
.uvalue
& mask
);
213 static void add_range_t(struct symbol
*type
, struct range_list
**rl
, sval_t min
, sval_t max
)
215 /* If we're just adding a number, cast it and add it */
216 if (sval_cmp(min
, max
) == 0) {
217 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
221 /* If the range is within the type range then add it */
222 if (sval_fits(type
, min
) && sval_fits(type
, max
)) {
223 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
227 if (truncates_nicely(type
, min
, max
)) {
228 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
233 * If the range we are adding has more bits than the range type then
234 * add the whole range type. Eg:
235 * 0x8000000000000000 - 0xf000000000000000 -> cast to int
238 if (sval_too_big(type
, min
) || sval_too_big(type
, max
)) {
239 add_range(rl
, sval_type_min(type
), sval_type_max(type
));
243 /* Cast negative values to high positive values */
244 if (sval_is_negative(min
) && type_unsigned(type
)) {
245 if (sval_is_positive(max
)) {
246 if (sval_too_high(type
, max
)) {
247 add_range(rl
, sval_type_min(type
), sval_type_max(type
));
250 add_range(rl
, sval_type_val(type
, 0), sval_cast(type
, max
));
251 max
= sval_type_max(type
);
253 max
= sval_cast(type
, max
);
255 min
= sval_cast(type
, min
);
256 add_range(rl
, min
, max
);
259 /* Cast high positive numbers to negative */
260 if (sval_unsigned(max
) && sval_is_negative(sval_cast(type
, max
))) {
261 if (!sval_is_negative(sval_cast(type
, min
))) {
262 add_range(rl
, sval_cast(type
, min
), sval_type_max(type
));
263 min
= sval_type_min(type
);
265 min
= sval_cast(type
, min
);
267 max
= sval_cast(type
, max
);
268 add_range(rl
, min
, max
);
271 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
275 static int str_to_comparison_arg_helper(const char *str
,
276 struct expression
*call
, int *comparison
,
277 struct expression
**arg
, const char **endp
)
289 *comparison
= SPECIAL_LTE
;
294 } else if (*c
== '=') {
297 *comparison
= SPECIAL_EQUAL
;
298 } else if (*c
== '>') {
301 *comparison
= SPECIAL_GTE
;
306 } else if (*c
== '!') {
309 *comparison
= SPECIAL_NOTEQUAL
;
310 } else if (*c
== '$') {
311 *comparison
= SPECIAL_EQUAL
;
320 param
= strtoll(c
, (char **)&c
, 10);
322 * FIXME: handle parameter math. [==$1 + 100]
328 if (*c
== ',' || *c
== ']')
329 c
++; /* skip the ']' character */
335 *arg
= get_argument_from_call_expr(call
->args
, param
);
338 if (*c
== '-' && *(c
+ 1) == '>') {
342 n
= snprintf(buf
, sizeof(buf
), "$%s", c
);
343 if (n
>= sizeof(buf
))
345 if (buf
[n
- 1] == ']')
347 *arg
= gen_expression_from_key(*arg
, buf
);
348 while (*c
&& *c
!= ']')
354 int str_to_comparison_arg(const char *str
, struct expression
*call
, int *comparison
, struct expression
**arg
)
363 return str_to_comparison_arg_helper(str
, call
, comparison
, arg
, NULL
);
366 static int get_val_from_key(int use_max
, struct symbol
*type
, const char *c
, struct expression
*call
, const char **endp
, sval_t
*sval
)
368 struct expression
*arg
;
373 ret
= sval_type_max(type
);
375 ret
= sval_type_min(type
);
377 if (!str_to_comparison_arg_helper(c
, call
, &comparison
, &arg
, endp
)) {
382 if (use_max
&& get_implied_max(arg
, &tmp
)) {
384 if (comparison
== '<') {
386 ret
= sval_binop(ret
, '-', tmp
);
389 if (!use_max
&& get_implied_min(arg
, &tmp
)) {
391 if (comparison
== '>') {
393 ret
= sval_binop(ret
, '+', tmp
);
401 static sval_t
add_one(sval_t sval
)
407 static sval_t
sub_one(sval_t sval
)
413 void filter_by_comparison(struct range_list
**rl
, int comparison
, struct range_list
*right
)
415 struct range_list
*left_orig
= *rl
;
416 struct range_list
*right_orig
= right
;
417 struct range_list
*ret_rl
= *rl
;
418 struct symbol
*cast_type
;
421 if (comparison
== UNKNOWN_COMPARISON
||
422 comparison
== IMPOSSIBLE_COMPARISON
)
425 cast_type
= rl_type(left_orig
);
426 if (sval_type_max(rl_type(left_orig
)).uvalue
< sval_type_max(rl_type(right_orig
)).uvalue
)
427 cast_type
= rl_type(right_orig
);
428 if (sval_type_max(cast_type
).uvalue
< INT_MAX
)
429 cast_type
= &int_ctype
;
431 min
= sval_type_min(cast_type
);
432 max
= sval_type_max(cast_type
);
433 left_orig
= cast_rl(cast_type
, left_orig
);
434 right_orig
= cast_rl(cast_type
, right_orig
);
436 switch (comparison
) {
438 case SPECIAL_UNSIGNED_LT
:
439 ret_rl
= remove_range(left_orig
, rl_max(right_orig
), max
);
442 case SPECIAL_UNSIGNED_LTE
:
443 if (!sval_is_max(rl_max(right_orig
)))
444 ret_rl
= remove_range(left_orig
, add_one(rl_max(right_orig
)), max
);
447 ret_rl
= rl_intersection(left_orig
, right_orig
);
450 case SPECIAL_UNSIGNED_GTE
:
451 if (!sval_is_min(rl_min(right_orig
)))
452 ret_rl
= remove_range(left_orig
, min
, sub_one(rl_min(right_orig
)));
455 case SPECIAL_UNSIGNED_GT
:
456 ret_rl
= remove_range(left_orig
, min
, rl_min(right_orig
));
458 case SPECIAL_NOTEQUAL
:
459 if (sval_cmp(rl_min(right_orig
), rl_max(right_orig
)) == 0)
460 ret_rl
= remove_range(left_orig
, rl_min(right_orig
), rl_min(right_orig
));
463 sm_perror("unhandled comparison %s", show_special(comparison
));
467 *rl
= cast_rl(rl_type(*rl
), ret_rl
);
470 static struct range_list
*filter_by_comparison_call(const char *c
, struct expression
*call
, const char **endp
, struct range_list
*start_rl
)
473 struct expression
*arg
;
474 struct range_list
*casted_start
, *right_orig
;
477 /* For when we have a function that takes a function pointer. */
478 if (!call
|| call
->type
!= EXPR_CALL
)
481 if (!str_to_comparison_arg_helper(c
, call
, &comparison
, &arg
, endp
))
484 if (!get_implied_rl(arg
, &right_orig
))
488 if (type_positive_bits(rl_type(start_rl
)) > type_positive_bits(type
))
489 type
= rl_type(start_rl
);
490 if (type_positive_bits(rl_type(right_orig
)) > type_positive_bits(type
))
491 type
= rl_type(right_orig
);
493 casted_start
= cast_rl(type
, start_rl
);
494 right_orig
= cast_rl(type
, right_orig
);
496 filter_by_comparison(&casted_start
, comparison
, right_orig
);
497 return cast_rl(rl_type(start_rl
), casted_start
);
500 static sval_t
parse_val(int use_max
, struct expression
*call
, struct symbol
*type
, const char *c
, const char **endp
)
502 const char *start
= c
;
505 if (type
== &float_ctype
)
506 return sval_type_fval(type
, strtof(start
, (char **)endp
));
507 else if (type
== &double_ctype
)
508 return sval_type_fval(type
, strtod(start
, (char **)endp
));
509 else if (type
== &ldouble_ctype
)
510 return sval_type_fval(type
, strtold(start
, (char **)endp
));
512 if (!strncmp(start
, "max", 3)) {
513 ret
= sval_type_max(type
);
515 } else if (!strncmp(start
, "u64max", 6)) {
516 ret
= sval_type_val(type
, ULLONG_MAX
);
518 } else if (!strncmp(start
, "s64max", 6)) {
519 ret
= sval_type_val(type
, LLONG_MAX
);
521 } else if (!strncmp(start
, "u32max", 6)) {
522 ret
= sval_type_val(type
, UINT_MAX
);
524 } else if (!strncmp(start
, "s32max", 6)) {
525 ret
= sval_type_val(type
, INT_MAX
);
527 } else if (!strncmp(start
, "u16max", 6)) {
528 ret
= sval_type_val(type
, USHRT_MAX
);
530 } else if (!strncmp(start
, "s16max", 6)) {
531 ret
= sval_type_val(type
, SHRT_MAX
);
533 } else if (!strncmp(start
, "min", 3)) {
534 ret
= sval_type_min(type
);
536 } else if (!strncmp(start
, "s64min", 6)) {
537 ret
= sval_type_val(type
, LLONG_MIN
);
539 } else if (!strncmp(start
, "s32min", 6)) {
540 ret
= sval_type_val(type
, INT_MIN
);
542 } else if (!strncmp(start
, "s16min", 6)) {
543 ret
= sval_type_val(type
, SHRT_MIN
);
545 } else if (!strncmp(start
, "long_min", 8)) {
546 ret
= sval_type_val(type
, LONG_MIN
);
548 } else if (!strncmp(start
, "long_max", 8)) {
549 ret
= sval_type_val(type
, LONG_MAX
);
551 } else if (!strncmp(start
, "ulong_max", 9)) {
552 ret
= sval_type_val(type
, ULONG_MAX
);
554 } else if (!strncmp(start
, "ptr_max", 7)) {
555 ret
= sval_type_val(type
, valid_ptr_max
);
557 } else if (start
[0] == '[') {
558 /* this parses [==p0] comparisons */
559 get_val_from_key(1, type
, start
, call
, &c
, &ret
);
560 } else if (type_is_ptr(type
)) {
561 ret
= sval_type_val(type
, strtoll(start
, (char **)&c
, 0));
562 if (sval_type_max(&ulong_ctype
).value
== UINT_MAX
)
563 ret
.uvalue
&= UINT_MAX
;
564 } else if (type_positive_bits(type
) == 64) {
565 ret
= sval_type_val(type
, strtoull(start
, (char **)&c
, 0));
567 ret
= sval_type_val(type
, strtoll(start
, (char **)&c
, 0));
573 static const char *jump_to_call_math(const char *value
)
575 const char *c
= value
;
577 while (*c
&& *c
!= '[')
583 if (*c
== '<' || *c
== '=' || *c
== '>' || *c
== '!')
589 static struct range_list
*get_param_return_rl(struct expression
*call
, const char *call_math
)
591 struct expression
*arg
;
595 param
= atoi(call_math
);
597 arg
= get_argument_from_call_expr(call
->args
, param
);
601 return db_return_vals_no_args(arg
);
604 static void str_to_rl_helper(struct expression
*call
, struct symbol
*type
, const char *str
, const char **endp
, struct range_list
**rl
)
606 struct range_list
*rl_tmp
= NULL
;
607 sval_t prev_min
, min
, max
;
610 prev_min
= sval_type_min(type
);
611 min
= sval_type_min(type
);
612 max
= sval_type_max(type
);
614 while (*c
!= '\0' && *c
!= '[') {
616 if (sval_cmp(min
, sval_type_min(type
)) != 0)
618 max
= sval_type_max(type
);
619 add_range_t(type
, &rl_tmp
, min
, max
);
624 min
= parse_val(0, call
, type
, c
, &c
);
625 if (!sval_fits(type
, min
))
626 min
= sval_type_min(type
);
630 if (*c
== '\0' || *c
== '[') {
631 add_range_t(type
, &rl_tmp
, min
, min
);
635 add_range_t(type
, &rl_tmp
, min
, min
);
641 max
= sval_type_max(type
);
642 add_range_t(type
, &rl_tmp
, min
, max
);
644 if (*c
== '[' || *c
== '\0')
648 sm_msg("debug XXX: trouble parsing %s c = %s", str
, c
);
654 max
= parse_val(1, call
, type
, c
, &c
);
655 if (!sval_fits(type
, max
))
656 max
= sval_type_max(type
);
658 max
= sval_type_max(type
);
659 add_range_t(type
, &rl_tmp
, min
, max
);
661 if (*c
== '[' || *c
== '\0')
665 add_range_t(type
, &rl_tmp
, min
, max
);
676 static void str_to_dinfo(struct expression
*call
, struct symbol
*type
, const char *value
, struct data_info
*dinfo
)
678 struct range_list
*math_rl
;
679 const char *call_math
;
681 struct range_list
*rl
= NULL
;
686 if (strcmp(value
, "empty") == 0)
689 if (strncmp(value
, "[==$", 4) == 0) {
690 struct expression
*arg
;
693 if (!str_to_comparison_arg(value
, call
, &comparison
, &arg
))
695 if (!get_implied_rl(arg
, &rl
))
700 str_to_rl_helper(call
, type
, value
, &c
, &rl
);
704 call_math
= jump_to_call_math(value
);
705 if (call_math
&& call_math
[0] == 'r') {
706 math_rl
= get_param_return_rl(call
, call_math
);
708 rl
= rl_intersection(rl
, math_rl
);
711 if (call_math
&& parse_call_math_rl(call
, call_math
, &math_rl
)) {
712 rl
= rl_intersection(rl
, math_rl
);
717 * For now if we already tried to handle the call math and couldn't
718 * figure it out then bail.
720 if (jump_to_call_math(c
) == c
+ 1)
723 rl
= filter_by_comparison_call(c
, call
, &c
, rl
);
726 rl
= cast_rl(type
, rl
);
727 dinfo
->value_ranges
= rl
;
730 static int rl_is_sane(struct range_list
*rl
)
732 struct data_range
*tmp
;
736 FOR_EACH_PTR(rl
, tmp
) {
737 if (!sval_fits(type
, tmp
->min
))
739 if (!sval_fits(type
, tmp
->max
))
741 if (sval_cmp(tmp
->min
, tmp
->max
) > 0)
743 } END_FOR_EACH_PTR(tmp
);
748 void str_to_rl(struct symbol
*type
, char *value
, struct range_list
**rl
)
750 struct data_info dinfo
= {};
752 str_to_dinfo(NULL
, type
, value
, &dinfo
);
753 if (!rl_is_sane(dinfo
.value_ranges
))
754 dinfo
.value_ranges
= alloc_whole_rl(type
);
755 *rl
= dinfo
.value_ranges
;
758 void call_results_to_rl(struct expression
*expr
, struct symbol
*type
, const char *value
, struct range_list
**rl
)
760 struct data_info dinfo
= {};
762 str_to_dinfo(strip_expr(expr
), type
, value
, &dinfo
);
763 *rl
= dinfo
.value_ranges
;
766 int is_whole_rl(struct range_list
*rl
)
768 struct data_range
*drange
;
770 if (ptr_list_empty((struct ptr_list
*)rl
))
772 drange
= first_ptr_list((struct ptr_list
*)rl
);
773 if (sval_is_min(drange
->min
) && sval_is_max(drange
->max
))
778 int is_unknown_ptr(struct range_list
*rl
)
780 struct data_range
*drange
;
786 FOR_EACH_PTR(rl
, drange
) {
789 if (sval_cmp(drange
->min
, valid_ptr_min_sval
) == 0 &&
790 sval_cmp(drange
->max
, valid_ptr_max_sval
) == 0)
792 } END_FOR_EACH_PTR(drange
);
797 bool is_whole_ptr_rl(struct range_list
*rl
)
799 struct data_range
*drange
;
802 /* A whole pointer range is either 0-ulong_max or NULL, valid range, and
808 if (ptr_list_size((struct ptr_list
*)rl
) != 2)
811 FOR_EACH_PTR(rl
, drange
) {
815 if (drange
->min
.value
!= 0 ||
816 drange
->max
.value
!= 0)
819 if (drange
->min
.value
!= valid_ptr_min
||
820 drange
->max
.value
!= ULONG_MAX
)
823 } END_FOR_EACH_PTR(drange
);
828 int is_whole_rl_non_zero(struct range_list
*rl
)
830 struct data_range
*drange
;
832 if (ptr_list_empty((struct ptr_list
*)rl
))
834 drange
= first_ptr_list((struct ptr_list
*)rl
);
835 if (sval_unsigned(drange
->min
) &&
836 drange
->min
.value
== 1 &&
837 sval_is_max(drange
->max
))
839 if (!sval_is_min(drange
->min
) || drange
->max
.value
!= -1)
841 drange
= last_ptr_list((struct ptr_list
*)rl
);
842 if (drange
->min
.value
!= 1 || !sval_is_max(drange
->max
))
847 sval_t
rl_min(struct range_list
*rl
)
849 struct data_range
*drange
;
852 ret
.type
= &llong_ctype
;
853 ret
.value
= LLONG_MIN
;
854 if (ptr_list_empty((struct ptr_list
*)rl
))
856 drange
= first_ptr_list((struct ptr_list
*)rl
);
860 sval_t
rl_max(struct range_list
*rl
)
862 struct data_range
*drange
;
865 ret
.type
= &llong_ctype
;
866 ret
.value
= LLONG_MAX
;
867 if (ptr_list_empty((struct ptr_list
*)rl
))
869 drange
= last_ptr_list((struct ptr_list
*)rl
);
873 int rl_to_sval(struct range_list
*rl
, sval_t
*sval
)
882 if (sval_cmp(min
, max
) != 0)
888 struct symbol
*rl_type(struct range_list
*rl
)
892 return rl_min(rl
).type
;
895 static struct data_range
*alloc_range_helper_sval(sval_t min
, sval_t max
, int perm
)
897 struct data_range
*ret
;
900 ret
= __alloc_perm_data_range(0);
902 ret
= __alloc_data_range(0);
908 struct data_range
*alloc_range(sval_t min
, sval_t max
)
910 return alloc_range_helper_sval(min
, max
, 0);
913 struct data_range
*alloc_range_perm(sval_t min
, sval_t max
)
915 return alloc_range_helper_sval(min
, max
, 1);
918 struct range_list
*alloc_rl(sval_t min
, sval_t max
)
920 struct range_list
*rl
= NULL
;
922 if (sval_cmp(min
, max
) > 0)
923 return alloc_whole_rl(min
.type
);
925 add_range(&rl
, min
, max
);
929 struct range_list
*alloc_whole_rl(struct symbol
*type
)
931 if (!type
|| type_positive_bits(type
) < 0)
933 if (type
->type
== SYM_ARRAY
)
936 if (type
->type
== SYM_FN
)
938 while (type
->type
== SYM_NODE
)
939 type
= get_real_base_type(type
);
941 return alloc_rl(sval_type_min(type
), sval_type_max(type
));
944 static bool collapse_pointer_rl(struct range_list
**rl
, sval_t min
, sval_t max
)
946 struct range_list
*new_rl
= NULL
;
947 struct data_range
*tmp
;
953 * With the mtag work, then we end up getting huge lists of mtags.
954 * That seems cool, but the problem is that we can only store about
955 * 8-10 mtags in the DB before we truncate the list. Also the mtags
956 * aren't really used at all so it's a waste of resources for now...
957 * In the future, we maybe will revisit this code.
964 if (!type_is_ptr(min
.type
))
967 if (ptr_list_size((struct ptr_list
*)*rl
) < 8)
969 FOR_EACH_PTR(*rl
, tmp
) {
970 if (!is_err_ptr(tmp
->min
))
972 } END_FOR_EACH_PTR(tmp
);
976 FOR_EACH_PTR(*rl
, tmp
) {
977 if (sval_cmp(tmp
->min
, valid_ptr_min_sval
) >= 0 &&
978 sval_cmp(tmp
->max
, valid_ptr_max_sval
) <= 0)
979 add_range(&new_rl
, valid_ptr_min_sval
, valid_ptr_max_sval
);
981 add_range(&new_rl
, tmp
->min
, tmp
->max
);
982 } END_FOR_EACH_PTR(tmp
);
984 add_range(&new_rl
, min
, max
);
993 extern int rl_ptrlist_hack
;
994 void add_range(struct range_list
**list
, sval_t min
, sval_t max
)
996 struct data_range
*tmp
;
997 struct data_range
*new = NULL
;
1001 * There is at least on valid reason why the types might be confusing
1002 * and that's when you have a void pointer and on some paths you treat
1003 * it as a u8 pointer and on other paths you treat it as a u16 pointer.
1004 * This case is hard to deal with.
1006 * There are other cases where we probably should be more specific about
1007 * the types than we are. For example, we end up merging a lot of ulong
1008 * with pointers and I have not figured out why we do that.
1010 * But this hack works for both cases, I think. We cast it to pointers
1011 * or we use the bigger size.
1014 if (*list
&& rl_type(*list
) != min
.type
) {
1015 if (rl_type(*list
)->type
== SYM_PTR
) {
1016 min
= sval_cast(rl_type(*list
), min
);
1017 max
= sval_cast(rl_type(*list
), max
);
1018 } else if (min
.type
->type
== SYM_PTR
) {
1019 *list
= cast_rl(min
.type
, *list
);
1020 } else if (type_bits(rl_type(*list
)) >= type_bits(min
.type
)) {
1021 min
= sval_cast(rl_type(*list
), min
);
1022 max
= sval_cast(rl_type(*list
), max
);
1024 *list
= cast_rl(min
.type
, *list
);
1028 if (sval_cmp(min
, max
) > 0) {
1029 min
= sval_type_min(min
.type
);
1030 max
= sval_type_max(min
.type
);
1033 if (collapse_pointer_rl(list
, min
, max
))
1037 * FIXME: This has a problem merging a range_list like: min-0,3-max
1038 * with a range like 1-2. You end up with min-2,3-max instead of
1041 FOR_EACH_PTR(*list
, tmp
) {
1043 /* Sometimes we overlap with more than one range
1044 so we have to delete or modify the next range. */
1045 if (!sval_is_max(max
) && max
.value
+ 1 == tmp
->min
.value
) {
1046 /* join 2 ranges here */
1047 new->max
= tmp
->max
;
1048 DELETE_CURRENT_PTR(tmp
);
1052 /* Doesn't overlap with the next one. */
1053 if (sval_cmp(max
, tmp
->min
) < 0)
1056 if (sval_cmp(max
, tmp
->max
) <= 0) {
1057 /* Partially overlaps the next one. */
1058 new->max
= tmp
->max
;
1059 DELETE_CURRENT_PTR(tmp
);
1062 /* Completely overlaps the next one. */
1063 DELETE_CURRENT_PTR(tmp
);
1064 /* there could be more ranges to delete */
1068 if (!sval_is_max(max
) && max
.value
+ 1 == tmp
->min
.value
) {
1069 /* join 2 ranges into a big range */
1070 new = alloc_range(min
, tmp
->max
);
1071 REPLACE_CURRENT_PTR(tmp
, new);
1074 if (sval_cmp(max
, tmp
->min
) < 0) { /* new range entirely below */
1075 new = alloc_range(min
, max
);
1076 INSERT_CURRENT(new, tmp
);
1079 if (sval_cmp(min
, tmp
->min
) < 0) { /* new range partially below */
1080 if (sval_cmp(max
, tmp
->max
) < 0)
1084 new = alloc_range(min
, max
);
1085 REPLACE_CURRENT_PTR(tmp
, new);
1090 if (sval_cmp(max
, tmp
->max
) <= 0) /* new range already included */
1092 if (sval_cmp(min
, tmp
->max
) <= 0) { /* new range partially above */
1094 new = alloc_range(min
, max
);
1095 REPLACE_CURRENT_PTR(tmp
, new);
1099 if (!sval_is_min(min
) && min
.value
- 1 == tmp
->max
.value
) {
1100 /* join 2 ranges into a big range */
1101 new = alloc_range(tmp
->min
, max
);
1102 REPLACE_CURRENT_PTR(tmp
, new);
1106 /* the new range is entirely above the existing ranges */
1107 } END_FOR_EACH_PTR(tmp
);
1110 new = alloc_range(min
, max
);
1112 rl_ptrlist_hack
= 1;
1113 add_ptr_list(list
, new);
1114 rl_ptrlist_hack
= 0;
1117 struct range_list
*clone_rl(struct range_list
*list
)
1119 struct data_range
*tmp
;
1120 struct range_list
*ret
= NULL
;
1122 FOR_EACH_PTR(list
, tmp
) {
1123 add_ptr_list(&ret
, tmp
);
1124 } END_FOR_EACH_PTR(tmp
);
1128 struct range_list
*clone_rl_permanent(struct range_list
*list
)
1130 struct data_range
*tmp
;
1131 struct data_range
*new;
1132 struct range_list
*ret
= NULL
;
1134 FOR_EACH_PTR(list
, tmp
) {
1135 new = alloc_range_perm(tmp
->min
, tmp
->max
);
1136 add_ptr_list(&ret
, new);
1137 } END_FOR_EACH_PTR(tmp
);
1141 struct range_list
*rl_union(struct range_list
*one
, struct range_list
*two
)
1143 struct data_range
*tmp
;
1144 struct range_list
*ret
= NULL
;
1146 FOR_EACH_PTR(one
, tmp
) {
1147 add_range(&ret
, tmp
->min
, tmp
->max
);
1148 } END_FOR_EACH_PTR(tmp
);
1149 FOR_EACH_PTR(two
, tmp
) {
1150 add_range(&ret
, tmp
->min
, tmp
->max
);
1151 } END_FOR_EACH_PTR(tmp
);
1155 struct range_list
*remove_range(struct range_list
*list
, sval_t min
, sval_t max
)
1157 struct data_range
*tmp
;
1158 struct range_list
*ret
= NULL
;
1163 min
= sval_cast(rl_type(list
), min
);
1164 max
= sval_cast(rl_type(list
), max
);
1165 if (sval_cmp(min
, max
) > 0) {
1171 FOR_EACH_PTR(list
, tmp
) {
1172 if (sval_cmp(tmp
->max
, min
) < 0) {
1173 add_range(&ret
, tmp
->min
, tmp
->max
);
1176 if (sval_cmp(tmp
->min
, max
) > 0) {
1177 add_range(&ret
, tmp
->min
, tmp
->max
);
1180 if (sval_cmp(tmp
->min
, min
) >= 0 && sval_cmp(tmp
->max
, max
) <= 0)
1182 if (sval_cmp(tmp
->min
, min
) >= 0) {
1184 add_range(&ret
, max
, tmp
->max
);
1185 } else if (sval_cmp(tmp
->max
, max
) <= 0) {
1187 add_range(&ret
, tmp
->min
, min
);
1191 add_range(&ret
, tmp
->min
, min
);
1192 add_range(&ret
, max
, tmp
->max
);
1194 } END_FOR_EACH_PTR(tmp
);
1198 int ranges_equiv(struct data_range
*one
, struct data_range
*two
)
1204 if (sval_cmp(one
->min
, two
->min
) != 0)
1206 if (sval_cmp(one
->max
, two
->max
) != 0)
1211 int rl_equiv(struct range_list
*one
, struct range_list
*two
)
1213 struct data_range
*one_range
;
1214 struct data_range
*two_range
;
1219 PREPARE_PTR_LIST(one
, one_range
);
1220 PREPARE_PTR_LIST(two
, two_range
);
1222 if (!one_range
&& !two_range
)
1224 if (!ranges_equiv(one_range
, two_range
))
1226 NEXT_PTR_LIST(one_range
);
1227 NEXT_PTR_LIST(two_range
);
1229 FINISH_PTR_LIST(two_range
);
1230 FINISH_PTR_LIST(one_range
);
1235 int true_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
1237 switch (comparison
) {
1239 case SPECIAL_UNSIGNED_LT
:
1240 if (sval_cmp(left
->min
, right
->max
) < 0)
1243 case SPECIAL_UNSIGNED_LTE
:
1245 if (sval_cmp(left
->min
, right
->max
) <= 0)
1249 if (sval_cmp(left
->max
, right
->min
) < 0)
1251 if (sval_cmp(left
->min
, right
->max
) > 0)
1254 case SPECIAL_UNSIGNED_GTE
:
1256 if (sval_cmp(left
->max
, right
->min
) >= 0)
1260 case SPECIAL_UNSIGNED_GT
:
1261 if (sval_cmp(left
->max
, right
->min
) > 0)
1264 case SPECIAL_NOTEQUAL
:
1265 if (sval_cmp(left
->min
, left
->max
) != 0)
1267 if (sval_cmp(right
->min
, right
->max
) != 0)
1269 if (sval_cmp(left
->min
, right
->min
) != 0)
1273 sm_perror("unhandled comparison %d", comparison
);
1279 int true_comparison_range_LR(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
1282 return true_comparison_range(var
, comparison
, val
);
1284 return true_comparison_range(val
, comparison
, var
);
1287 static int false_comparison_range_sval(struct data_range
*left
, int comparison
, struct data_range
*right
)
1289 switch (comparison
) {
1291 case SPECIAL_UNSIGNED_LT
:
1292 if (sval_cmp(left
->max
, right
->min
) >= 0)
1295 case SPECIAL_UNSIGNED_LTE
:
1297 if (sval_cmp(left
->max
, right
->min
) > 0)
1301 if (sval_cmp(left
->min
, left
->max
) != 0)
1303 if (sval_cmp(right
->min
, right
->max
) != 0)
1305 if (sval_cmp(left
->min
, right
->min
) != 0)
1308 case SPECIAL_UNSIGNED_GTE
:
1310 if (sval_cmp(left
->min
, right
->max
) < 0)
1314 case SPECIAL_UNSIGNED_GT
:
1315 if (sval_cmp(left
->min
, right
->max
) <= 0)
1318 case SPECIAL_NOTEQUAL
:
1319 if (sval_cmp(left
->max
, right
->min
) < 0)
1321 if (sval_cmp(left
->min
, right
->max
) > 0)
1325 sm_perror("unhandled comparison %d", comparison
);
1331 int false_comparison_range_LR(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
1334 return false_comparison_range_sval(var
, comparison
, val
);
1336 return false_comparison_range_sval(val
, comparison
, var
);
1339 int possibly_true(struct expression
*left
, int comparison
, struct expression
*right
)
1341 struct range_list
*rl_left
, *rl_right
;
1342 struct data_range
*tmp_left
, *tmp_right
;
1343 struct symbol
*type
;
1345 if (comparison
== UNKNOWN_COMPARISON
)
1347 if (comparison
== IMPOSSIBLE_COMPARISON
)
1349 if (!get_implied_rl(left
, &rl_left
))
1351 if (!get_implied_rl(right
, &rl_right
))
1354 type
= rl_type(rl_left
);
1355 if (type_positive_bits(type
) < type_positive_bits(rl_type(rl_right
)))
1356 type
= rl_type(rl_right
);
1357 if (type_positive_bits(type
) < 31)
1360 rl_left
= cast_rl(type
, rl_left
);
1361 rl_right
= cast_rl(type
, rl_right
);
1363 FOR_EACH_PTR(rl_left
, tmp_left
) {
1364 FOR_EACH_PTR(rl_right
, tmp_right
) {
1365 if (true_comparison_range(tmp_left
, comparison
, tmp_right
))
1367 } END_FOR_EACH_PTR(tmp_right
);
1368 } END_FOR_EACH_PTR(tmp_left
);
1372 int possibly_false(struct expression
*left
, int comparison
, struct expression
*right
)
1374 struct range_list
*rl_left
, *rl_right
;
1375 struct data_range
*tmp_left
, *tmp_right
;
1376 struct symbol
*type
;
1378 if (!get_implied_rl(left
, &rl_left
))
1380 if (!get_implied_rl(right
, &rl_right
))
1383 type
= rl_type(rl_left
);
1384 if (type_positive_bits(type
) < type_positive_bits(rl_type(rl_right
)))
1385 type
= rl_type(rl_right
);
1386 if (type_positive_bits(type
) < 31)
1389 rl_left
= cast_rl(type
, rl_left
);
1390 rl_right
= cast_rl(type
, rl_right
);
1392 FOR_EACH_PTR(rl_left
, tmp_left
) {
1393 FOR_EACH_PTR(rl_right
, tmp_right
) {
1394 if (false_comparison_range_sval(tmp_left
, comparison
, tmp_right
))
1396 } END_FOR_EACH_PTR(tmp_right
);
1397 } END_FOR_EACH_PTR(tmp_left
);
1401 int possibly_true_rl(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
1403 struct data_range
*left_tmp
, *right_tmp
;
1404 struct symbol
*type
;
1406 if (!left_ranges
|| !right_ranges
|| comparison
== UNKNOWN_COMPARISON
)
1408 if (comparison
== IMPOSSIBLE_COMPARISON
)
1411 type
= rl_type(left_ranges
);
1412 if (type_positive_bits(type
) < type_positive_bits(rl_type(right_ranges
)))
1413 type
= rl_type(right_ranges
);
1414 if (type_positive_bits(type
) < 31)
1417 left_ranges
= cast_rl(type
, left_ranges
);
1418 right_ranges
= cast_rl(type
, right_ranges
);
1420 FOR_EACH_PTR(left_ranges
, left_tmp
) {
1421 FOR_EACH_PTR(right_ranges
, right_tmp
) {
1422 if (true_comparison_range(left_tmp
, comparison
, right_tmp
))
1424 } END_FOR_EACH_PTR(right_tmp
);
1425 } END_FOR_EACH_PTR(left_tmp
);
1429 int possibly_false_rl(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
1431 struct data_range
*left_tmp
, *right_tmp
;
1432 struct symbol
*type
;
1434 if (!left_ranges
|| !right_ranges
|| comparison
== UNKNOWN_COMPARISON
)
1436 if (comparison
== IMPOSSIBLE_COMPARISON
)
1439 type
= rl_type(left_ranges
);
1440 if (type_positive_bits(type
) < type_positive_bits(rl_type(right_ranges
)))
1441 type
= rl_type(right_ranges
);
1442 if (type_positive_bits(type
) < 31)
1445 left_ranges
= cast_rl(type
, left_ranges
);
1446 right_ranges
= cast_rl(type
, right_ranges
);
1448 FOR_EACH_PTR(left_ranges
, left_tmp
) {
1449 FOR_EACH_PTR(right_ranges
, right_tmp
) {
1450 if (false_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
1452 } END_FOR_EACH_PTR(right_tmp
);
1453 } END_FOR_EACH_PTR(left_tmp
);
1457 /* FIXME: the _rl here stands for right left so really it should be _lr */
1458 int possibly_true_rl_LR(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
1461 return possibly_true_rl(a
, comparison
, b
);
1463 return possibly_true_rl(b
, comparison
, a
);
1466 int possibly_false_rl_LR(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
1469 return possibly_false_rl(a
, comparison
, b
);
1471 return possibly_false_rl(b
, comparison
, a
);
1474 int rl_has_sval(struct range_list
*rl
, sval_t sval
)
1476 struct data_range
*tmp
;
1478 FOR_EACH_PTR(rl
, tmp
) {
1479 if (sval_cmp(tmp
->min
, sval
) <= 0 &&
1480 sval_cmp(tmp
->max
, sval
) >= 0)
1482 } END_FOR_EACH_PTR(tmp
);
1486 void tack_on(struct range_list
**list
, struct data_range
*drange
)
1488 add_ptr_list(list
, drange
);
1491 void push_rl(struct range_list_stack
**rl_stack
, struct range_list
*rl
)
1493 add_ptr_list(rl_stack
, rl
);
1496 struct range_list
*pop_rl(struct range_list_stack
**rl_stack
)
1498 struct range_list
*rl
;
1500 rl
= last_ptr_list((struct ptr_list
*)*rl_stack
);
1501 delete_ptr_list_last((struct ptr_list
**)rl_stack
);
1505 struct range_list
*top_rl(struct range_list_stack
*rl_stack
)
1507 struct range_list
*rl
;
1509 rl
= last_ptr_list((struct ptr_list
*)rl_stack
);
1513 void filter_top_rl(struct range_list_stack
**rl_stack
, struct range_list
*filter
)
1515 struct range_list
*rl
;
1517 rl
= pop_rl(rl_stack
);
1518 rl
= rl_filter(rl
, filter
);
1519 push_rl(rl_stack
, rl
);
1522 struct range_list
*rl_truncate_cast(struct symbol
*type
, struct range_list
*rl
)
1524 struct data_range
*tmp
;
1525 struct range_list
*ret
= NULL
;
1531 if (!type
|| type
== rl_type(rl
))
1534 FOR_EACH_PTR(rl
, tmp
) {
1537 if (type_bits(type
) < type_bits(rl_type(rl
))) {
1538 min
.uvalue
= tmp
->min
.uvalue
& ((1ULL << type_bits(type
)) - 1);
1539 max
.uvalue
= tmp
->max
.uvalue
& ((1ULL << type_bits(type
)) - 1);
1541 if (sval_cmp(min
, max
) > 0) {
1542 min
= sval_cast(type
, min
);
1543 max
= sval_cast(type
, max
);
1545 add_range_t(type
, &ret
, min
, max
);
1546 } END_FOR_EACH_PTR(tmp
);
1551 int rl_fits_in_type(struct range_list
*rl
, struct symbol
*type
)
1553 if (type_bits(rl_type(rl
)) <= type_bits(type
))
1555 if (sval_cmp(rl_max(rl
), sval_type_max(type
)) > 0)
1557 if (sval_is_negative(rl_min(rl
)) &&
1558 sval_cmp(rl_min(rl
), sval_type_min(type
)) < 0)
1563 static int rl_type_consistent(struct range_list
*rl
)
1565 struct data_range
*tmp
;
1566 struct symbol
*type
;
1569 FOR_EACH_PTR(rl
, tmp
) {
1570 if (type
!= tmp
->min
.type
|| type
!= tmp
->max
.type
)
1572 } END_FOR_EACH_PTR(tmp
);
1576 static struct range_list
*cast_to_bool(struct range_list
*rl
)
1578 struct data_range
*tmp
;
1579 struct range_list
*ret
= NULL
;
1582 sval_t min
= { .type
= &bool_ctype
};
1583 sval_t max
= { .type
= &bool_ctype
};
1585 FOR_EACH_PTR(rl
, tmp
) {
1586 if (tmp
->min
.value
|| tmp
->max
.value
)
1588 if (sval_is_negative(tmp
->min
) &&
1589 sval_is_negative(tmp
->max
))
1591 if (tmp
->min
.value
== 0 ||
1592 tmp
->max
.value
== 0)
1594 if (sval_is_negative(tmp
->min
) &&
1597 } END_FOR_EACH_PTR(tmp
);
1604 add_range(&ret
, min
, max
);
1608 struct range_list
*cast_rl(struct symbol
*type
, struct range_list
*rl
)
1610 struct data_range
*tmp
;
1611 struct range_list
*ret
= NULL
;
1618 if (!rl_is_sane(rl
))
1619 return alloc_whole_rl(type
);
1620 if (type
== rl_type(rl
) && rl_type_consistent(rl
))
1623 if (type
== &bool_ctype
)
1624 return cast_to_bool(rl
);
1626 FOR_EACH_PTR(rl
, tmp
) {
1627 add_range_t(type
, &ret
, tmp
->min
, tmp
->max
);
1628 } END_FOR_EACH_PTR(tmp
);
1631 return alloc_whole_rl(type
);
1637 * This is the opposite of rl_intersection().
1639 struct range_list
*rl_filter(struct range_list
*rl
, struct range_list
*filter
)
1641 struct data_range
*tmp
;
1643 FOR_EACH_PTR(filter
, tmp
) {
1644 rl
= remove_range(rl
, tmp
->min
, tmp
->max
);
1645 } END_FOR_EACH_PTR(tmp
);
1650 struct range_list
*do_intersection(struct range_list
*one_rl
, struct range_list
*two_rl
)
1652 struct data_range
*one
, *two
;
1653 struct range_list
*ret
= NULL
;
1656 PREPARE_PTR_LIST(one_rl
, one
);
1657 PREPARE_PTR_LIST(two_rl
, two
);
1662 if (sval_cmp(one
->max
, two
->min
) < 0) {
1666 if (sval_cmp(one
->min
, two
->min
) < 0 && sval_cmp(one
->max
, two
->max
) <= 0) {
1667 add_range(&ret
, two
->min
, one
->max
);
1671 if (sval_cmp(one
->min
, two
->min
) >= 0 && sval_cmp(one
->max
, two
->max
) <= 0) {
1672 add_range(&ret
, one
->min
, one
->max
);
1676 if (sval_cmp(one
->min
, two
->min
) < 0 && sval_cmp(one
->max
, two
->max
) > 0) {
1677 add_range(&ret
, two
->min
, two
->max
);
1681 if (sval_cmp(one
->min
, two
->max
) <= 0 && sval_cmp(one
->max
, two
->max
) > 0) {
1682 add_range(&ret
, one
->min
, two
->max
);
1686 if (sval_cmp(one
->min
, two
->max
) <= 0) {
1687 sm_fatal("error calculating intersection of '%s' and '%s'", show_rl(one_rl
), show_rl(two_rl
));
1693 FINISH_PTR_LIST(two
);
1694 FINISH_PTR_LIST(one
);
1699 struct range_list
*rl_intersection(struct range_list
*one
, struct range_list
*two
)
1701 struct range_list
*ret
;
1702 struct symbol
*ret_type
;
1703 struct symbol
*small_type
;
1704 struct symbol
*large_type
;
1709 ret_type
= rl_type(one
);
1710 small_type
= rl_type(one
);
1711 large_type
= rl_type(two
);
1713 if (type_bits(rl_type(two
)) < type_bits(small_type
)) {
1714 small_type
= rl_type(two
);
1715 large_type
= rl_type(one
);
1718 one
= cast_rl(large_type
, one
);
1719 two
= cast_rl(large_type
, two
);
1721 ret
= do_intersection(one
, two
);
1722 return cast_rl(ret_type
, ret
);
1725 static struct range_list
*handle_mod_rl(struct range_list
*left
, struct range_list
*right
)
1730 max
= rl_max(right
);
1731 if (sval_is_max(max
))
1736 if (sval_is_negative(max
))
1738 if (sval_cmp(rl_max(left
), max
) < 0)
1742 return alloc_rl(zero
, max
);
1745 static struct range_list
*get_neg_rl(struct range_list
*rl
)
1747 struct data_range
*tmp
;
1748 struct data_range
*new;
1749 struct range_list
*ret
= NULL
;
1753 if (sval_is_positive(rl_min(rl
)))
1756 FOR_EACH_PTR(rl
, tmp
) {
1757 if (sval_is_positive(tmp
->min
))
1759 if (sval_is_positive(tmp
->max
)) {
1760 new = alloc_range(tmp
->min
, tmp
->max
);
1761 new->max
.value
= -1;
1762 add_range(&ret
, new->min
, new->max
);
1765 add_range(&ret
, tmp
->min
, tmp
->max
);
1766 } END_FOR_EACH_PTR(tmp
);
1771 static struct range_list
*get_pos_rl(struct range_list
*rl
)
1773 struct data_range
*tmp
;
1774 struct data_range
*new;
1775 struct range_list
*ret
= NULL
;
1779 if (sval_is_negative(rl_max(rl
)))
1782 FOR_EACH_PTR(rl
, tmp
) {
1783 if (sval_is_negative(tmp
->max
))
1785 if (sval_is_positive(tmp
->min
)) {
1786 add_range(&ret
, tmp
->min
, tmp
->max
);
1789 new = alloc_range(tmp
->min
, tmp
->max
);
1791 add_range(&ret
, new->min
, new->max
);
1792 } END_FOR_EACH_PTR(tmp
);
1797 static struct range_list
*divide_rl_helper(struct range_list
*left
, struct range_list
*right
)
1799 sval_t right_min
, right_max
;
1802 if (!left
|| !right
)
1805 /* let's assume we never divide by zero */
1806 right_min
= rl_min(right
);
1807 right_max
= rl_max(right
);
1808 if (right_min
.value
== 0 && right_max
.value
== 0)
1810 if (right_min
.value
== 0)
1811 right_min
.value
= 1;
1812 if (right_max
.value
== 0)
1813 right_max
.value
= -1;
1815 max
= sval_binop(rl_max(left
), '/', right_min
);
1816 min
= sval_binop(rl_min(left
), '/', right_max
);
1818 return alloc_rl(min
, max
);
1821 static struct range_list
*handle_divide_rl(struct range_list
*left
, struct range_list
*right
)
1823 struct range_list
*left_neg
, *left_pos
, *right_neg
, *right_pos
;
1824 struct range_list
*neg_neg
, *neg_pos
, *pos_neg
, *pos_pos
;
1825 struct range_list
*ret
;
1827 if (is_whole_rl(right
))
1830 left_neg
= get_neg_rl(left
);
1831 left_pos
= get_pos_rl(left
);
1832 right_neg
= get_neg_rl(right
);
1833 right_pos
= get_pos_rl(right
);
1835 neg_neg
= divide_rl_helper(left_neg
, right_neg
);
1836 neg_pos
= divide_rl_helper(left_neg
, right_pos
);
1837 pos_neg
= divide_rl_helper(left_pos
, right_neg
);
1838 pos_pos
= divide_rl_helper(left_pos
, right_pos
);
1840 ret
= rl_union(neg_neg
, neg_pos
);
1841 ret
= rl_union(ret
, pos_neg
);
1842 return rl_union(ret
, pos_pos
);
1845 static struct range_list
*ptr_add_mult(struct range_list
*left
, int op
, struct range_list
*right
)
1847 struct range_list
*ret
;
1848 sval_t l_sval
, r_sval
, res
;
1851 * This function is sort of the wrong API because it takes two pointer
1852 * and adds them together. The caller is expected to figure out
1853 * alignment. Neither of those are the correct things to do.
1855 * Really this function is quite bogus...
1858 if (rl_to_sval(left
, &l_sval
) && rl_to_sval(right
, &r_sval
)) {
1859 res
= sval_binop(l_sval
, op
, r_sval
);
1860 return alloc_rl(res
, res
);
1863 if (rl_min(left
).value
!= 0 || rl_max(right
).value
!= 0) {
1864 ret
= alloc_rl(valid_ptr_min_sval
, valid_ptr_max_sval
);
1865 return cast_rl(rl_type(left
), ret
);
1868 return alloc_whole_rl(rl_type(left
));
1871 static struct range_list
*handle_add_mult_rl(struct range_list
*left
, int op
, struct range_list
*right
)
1875 if (type_is_ptr(rl_type(left
)) || type_is_ptr(rl_type(right
)))
1876 return ptr_add_mult(left
, op
, right
);
1878 if (sval_binop_overflows(rl_min(left
), op
, rl_min(right
)))
1880 min
= sval_binop(rl_min(left
), op
, rl_min(right
));
1882 if (sval_binop_overflows(rl_max(left
), op
, rl_max(right
)))
1884 max
= sval_binop(rl_max(left
), op
, rl_max(right
));
1886 return alloc_rl(min
, max
);
1889 static struct range_list
*handle_sub_rl(struct range_list
*left_orig
, struct range_list
*right_orig
)
1891 struct range_list
*left_rl
, *right_rl
;
1892 struct symbol
*type
;
1894 sval_t min_ll
, max_ll
, res_ll
;
1897 /* TODO: These things should totally be using dranges where possible */
1899 if (!left_orig
|| !right_orig
)
1903 if (type_positive_bits(rl_type(left_orig
)) > type_positive_bits(type
))
1904 type
= rl_type(left_orig
);
1905 if (type_positive_bits(rl_type(right_orig
)) > type_positive_bits(type
))
1906 type
= rl_type(right_orig
);
1908 left_rl
= cast_rl(type
, left_orig
);
1909 right_rl
= cast_rl(type
, right_orig
);
1911 max
= rl_max(left_rl
);
1912 min
= sval_type_min(type
);
1914 min_ll
= rl_min(left_rl
);
1915 min_ll
.type
= &llong_ctype
;
1916 max_ll
= rl_max(right_rl
);
1917 max_ll
.type
= &llong_ctype
;
1919 res_ll
.value
= min_ll
.value
- max_ll
.value
;
1921 if (!sval_binop_overflows(rl_min(left_rl
), '-', rl_max(right_rl
))) {
1922 tmp
= sval_binop(rl_min(left_rl
), '-', rl_max(right_rl
));
1923 if (sval_cmp(tmp
, min
) > 0)
1925 } else if (type_positive_bits(type
) < 63 &&
1926 !sval_binop_overflows(min_ll
, '-', max_ll
) &&
1927 (min
.value
!= 0 && sval_cmp(res_ll
, min
) >= 0)) {
1928 struct range_list
*left_casted
, *right_casted
, *result
;
1930 left_casted
= cast_rl(&llong_ctype
, left_orig
);
1931 right_casted
= cast_rl(&llong_ctype
, right_orig
);
1932 result
= handle_sub_rl(left_casted
, right_casted
);
1933 return cast_rl(type
, result
);
1936 if (!sval_is_max(rl_max(left_rl
))) {
1937 tmp
= sval_binop(rl_max(left_rl
), '-', rl_min(right_rl
));
1938 if (sval_cmp(tmp
, max
) < 0)
1942 if (sval_is_min(min
) && sval_is_max(max
))
1945 return alloc_rl(min
, max
);
1948 static unsigned long long rl_bits_always_set(struct range_list
*rl
)
1950 return sval_fls_mask(rl_min(rl
));
1953 static unsigned long long rl_bits_maybe_set(struct range_list
*rl
)
1955 return sval_fls_mask(rl_max(rl
));
1958 static struct range_list
*handle_OR_rl(struct range_list
*left
, struct range_list
*right
)
1960 unsigned long long left_min
, left_max
, right_min
, right_max
;
1964 if ((rl_to_sval(left
, &sval
) || rl_to_sval(right
, &sval
)) &&
1965 !sval_binop_overflows(rl_max(left
), '+', rl_max(right
)))
1966 return rl_binop(left
, '+', right
);
1968 left_min
= rl_bits_always_set(left
);
1969 left_max
= rl_bits_maybe_set(left
);
1970 right_min
= rl_bits_always_set(right
);
1971 right_max
= rl_bits_maybe_set(right
);
1973 min
.type
= max
.type
= &ullong_ctype
;
1974 min
.uvalue
= left_min
| right_min
;
1975 max
.uvalue
= left_max
| right_max
;
1977 return cast_rl(rl_type(left
), alloc_rl(min
, max
));
1980 static struct range_list
*handle_XOR_rl(struct range_list
*left
, struct range_list
*right
)
1982 unsigned long long left_set
, left_maybe
;
1983 unsigned long long right_set
, right_maybe
;
1986 left_set
= rl_bits_always_set(left
);
1987 left_maybe
= rl_bits_maybe_set(left
);
1989 right_set
= rl_bits_always_set(right
);
1990 right_maybe
= rl_bits_maybe_set(right
);
1992 zero
= max
= rl_min(left
);
1994 max
.uvalue
= fls_mask((left_maybe
| right_maybe
) ^ (left_set
& right_set
));
1996 return cast_rl(rl_type(left
), alloc_rl(zero
, max
));
1999 static sval_t
sval_lowest_set_bit(sval_t sval
)
2001 sval_t ret
= { .type
= sval
.type
};
2004 for (i
= 0; i
< 64; i
++) {
2005 if (sval
.uvalue
& 1ULL << i
) {
2006 ret
.uvalue
= (1ULL << i
);
2013 static struct range_list
*handle_AND_rl(struct range_list
*left
, struct range_list
*right
)
2015 struct bit_info
*one
, *two
;
2016 struct range_list
*rl
;
2017 sval_t min
, max
, zero
, bits_sval
;
2018 unsigned long long bits
;
2020 one
= rl_to_binfo(left
);
2021 two
= rl_to_binfo(right
);
2022 bits
= one
->possible
& two
->possible
;
2023 bits_sval
= rl_max(left
);
2024 bits_sval
.uvalue
= bits
;
2026 max
= sval_min_nonneg(rl_max(left
), rl_max(right
));
2027 min
= sval_lowest_set_bit(bits_sval
);
2029 rl
= alloc_rl(min
, max
);
2033 add_range(&rl
, zero
, zero
);
2038 static struct range_list
*handle_lshift(struct range_list
*left_orig
, struct range_list
*right_orig
)
2040 struct range_list
*left
;
2041 struct data_range
*tmp
;
2042 struct range_list
*ret
= NULL
;
2043 sval_t zero
= { .type
= rl_type(left_orig
), };
2044 sval_t shift
, min
, max
;
2045 bool add_zero
= false;
2047 if (!rl_to_sval(right_orig
, &shift
) || sval_is_negative(shift
))
2049 if (shift
.value
== 0)
2052 /* Cast to unsigned for easier left shift math */
2053 if (type_positive_bits(rl_type(left_orig
)) < 32)
2054 left
= cast_rl(&uint_ctype
, left_orig
);
2055 else if(type_positive_bits(rl_type(left_orig
)) == 63)
2056 left
= cast_rl(&ullong_ctype
, left_orig
);
2060 FOR_EACH_PTR(left
, tmp
) {
2064 if (min
.value
== 0 || max
.value
> sval_type_max(max
.type
).uvalue
>> shift
.uvalue
)
2066 if (min
.value
== 0 && max
.value
== 0)
2070 min
= sval_binop(min
, SPECIAL_LEFTSHIFT
, shift
);
2071 max
= sval_binop(max
, SPECIAL_LEFTSHIFT
, shift
);
2072 add_range(&ret
, min
, max
);
2073 } END_FOR_EACH_PTR(tmp
);
2075 if (!rl_fits_in_type(ret
, rl_type(left_orig
)))
2077 ret
= cast_rl(rl_type(left_orig
), ret
);
2079 add_range(&ret
, zero
, zero
);
2084 static struct range_list
*handle_rshift(struct range_list
*left_orig
, struct range_list
*right_orig
)
2086 struct data_range
*tmp
;
2087 struct range_list
*ret
= NULL
;
2088 sval_t shift
, min
, max
;
2090 if (!rl_to_sval(right_orig
, &shift
) || sval_is_negative(shift
))
2092 if (shift
.value
== 0)
2095 FOR_EACH_PTR(left_orig
, tmp
) {
2096 min
= sval_binop(tmp
->min
, SPECIAL_RIGHTSHIFT
, shift
);
2097 max
= sval_binop(tmp
->max
, SPECIAL_RIGHTSHIFT
, shift
);
2098 add_range(&ret
, min
, max
);
2099 } END_FOR_EACH_PTR(tmp
);
2104 struct range_list
*rl_binop(struct range_list
*left
, int op
, struct range_list
*right
)
2106 struct symbol
*cast_type
;
2107 sval_t left_sval
, right_sval
;
2108 struct range_list
*ret
= NULL
;
2110 cast_type
= rl_type(left
);
2111 if (sval_type_max(rl_type(left
)).uvalue
< sval_type_max(rl_type(right
)).uvalue
)
2112 cast_type
= rl_type(right
);
2113 if (sval_type_max(cast_type
).uvalue
< INT_MAX
)
2114 cast_type
= &int_ctype
;
2116 left
= cast_rl(cast_type
, left
);
2117 right
= cast_rl(cast_type
, right
);
2119 if (!left
&& !right
)
2122 if (rl_to_sval(left
, &left_sval
) && rl_to_sval(right
, &right_sval
)) {
2123 sval_t val
= sval_binop(left_sval
, op
, right_sval
);
2124 return alloc_rl(val
, val
);
2129 ret
= handle_mod_rl(left
, right
);
2132 ret
= handle_divide_rl(left
, right
);
2136 ret
= handle_add_mult_rl(left
, op
, right
);
2139 ret
= handle_OR_rl(left
, right
);
2142 ret
= handle_XOR_rl(left
, right
);
2145 ret
= handle_AND_rl(left
, right
);
2148 ret
= handle_sub_rl(left
, right
);
2150 case SPECIAL_RIGHTSHIFT
:
2151 return handle_rshift(left
, right
);
2152 case SPECIAL_LEFTSHIFT
:
2153 return handle_lshift(left
, right
);
2159 void free_data_info_allocs(void)
2161 struct allocator_struct
*desc
= &data_info_allocator
;
2162 struct allocation_blob
*blob
= desc
->blobs
;
2166 clear_strip_cache();
2169 desc
->allocations
= 0;
2170 desc
->total_bytes
= 0;
2171 desc
->useful_bytes
= 0;
2172 desc
->freelist
= NULL
;
2174 struct allocation_blob
*next
= blob
->next
;
2175 blob_free(blob
, desc
->chunking
);
2178 clear_array_values_cache();
2179 clear_type_value_cache();
2180 clear_data_range_alloc();
2183 void split_comparison_rl(struct range_list
*left_orig
, int op
, struct range_list
*right_orig
,
2184 struct range_list
**left_true_rl
, struct range_list
**left_false_rl
,
2185 struct range_list
**right_true_rl
, struct range_list
**right_false_rl
)
2187 struct range_list
*left_true
, *left_false
;
2188 struct range_list
*right_true
, *right_false
;
2191 min
= sval_type_min(rl_type(left_orig
));
2192 max
= sval_type_max(rl_type(left_orig
));
2194 left_true
= clone_rl(left_orig
);
2195 left_false
= clone_rl(left_orig
);
2196 right_true
= clone_rl(right_orig
);
2197 right_false
= clone_rl(right_orig
);
2201 case SPECIAL_UNSIGNED_LT
:
2202 left_true
= remove_range(left_orig
, rl_max(right_orig
), max
);
2203 if (!sval_is_min(rl_min(right_orig
))) {
2204 left_false
= remove_range(left_orig
, min
, sub_one(rl_min(right_orig
)));
2207 right_true
= remove_range(right_orig
, min
, rl_min(left_orig
));
2208 if (!sval_is_max(rl_max(left_orig
)))
2209 right_false
= remove_range(right_orig
, add_one(rl_max(left_orig
)), max
);
2211 case SPECIAL_UNSIGNED_LTE
:
2213 if (!sval_is_max(rl_max(right_orig
)))
2214 left_true
= remove_range(left_orig
, add_one(rl_max(right_orig
)), max
);
2215 left_false
= remove_range(left_orig
, min
, rl_min(right_orig
));
2217 if (!sval_is_min(rl_min(left_orig
)))
2218 right_true
= remove_range(right_orig
, min
, sub_one(rl_min(left_orig
)));
2219 right_false
= remove_range(right_orig
, rl_max(left_orig
), max
);
2221 if (sval_cmp(rl_min(left_orig
), rl_min(right_orig
)) == 0)
2222 left_false
= remove_range(left_false
, rl_min(left_orig
), rl_min(left_orig
));
2223 if (sval_cmp(rl_max(left_orig
), rl_max(right_orig
)) == 0)
2224 right_false
= remove_range(right_false
, rl_max(left_orig
), rl_max(left_orig
));
2227 left_true
= rl_intersection(left_orig
, right_orig
);
2228 right_true
= clone_rl(left_true
);
2230 if (sval_cmp(rl_min(right_orig
), rl_max(right_orig
)) == 0)
2231 left_false
= remove_range(left_orig
, rl_min(right_orig
), rl_min(right_orig
));
2232 if (sval_cmp(rl_min(left_orig
), rl_max(left_orig
)) == 0)
2233 right_false
= remove_range(right_orig
, rl_min(left_orig
), rl_min(left_orig
));
2235 case SPECIAL_UNSIGNED_GTE
:
2237 if (!sval_is_min(rl_min(right_orig
)))
2238 left_true
= remove_range(left_orig
, min
, sub_one(rl_min(right_orig
)));
2239 left_false
= remove_range(left_orig
, rl_max(right_orig
), max
);
2241 if (!sval_is_max(rl_max(left_orig
)))
2242 right_true
= remove_range(right_orig
, add_one(rl_max(left_orig
)), max
);
2243 right_false
= remove_range(right_orig
, min
, rl_min(left_orig
));
2245 if (sval_cmp(rl_min(left_orig
), rl_min(right_orig
)) == 0)
2246 right_false
= remove_range(right_false
, rl_min(left_orig
), rl_min(left_orig
));
2247 if (sval_cmp(rl_max(left_orig
), rl_max(right_orig
)) == 0)
2248 left_false
= remove_range(left_false
, rl_max(left_orig
), rl_max(left_orig
));
2251 case SPECIAL_UNSIGNED_GT
:
2252 left_true
= remove_range(left_orig
, min
, rl_min(right_orig
));
2253 if (!sval_is_max(rl_max(right_orig
)))
2254 left_false
= remove_range(left_orig
, add_one(rl_max(right_orig
)), max
);
2256 right_true
= remove_range(right_orig
, rl_max(left_orig
), max
);
2257 if (!sval_is_min(rl_min(left_orig
)))
2258 right_false
= remove_range(right_orig
, min
, sub_one(rl_min(left_orig
)));
2260 case SPECIAL_NOTEQUAL
:
2261 left_false
= rl_intersection(left_orig
, right_orig
);
2262 right_false
= clone_rl(left_false
);
2264 if (sval_cmp(rl_min(right_orig
), rl_max(right_orig
)) == 0)
2265 left_true
= remove_range(left_orig
, rl_min(right_orig
), rl_min(right_orig
));
2266 if (sval_cmp(rl_min(left_orig
), rl_max(left_orig
)) == 0)
2267 right_true
= remove_range(right_orig
, rl_min(left_orig
), rl_min(left_orig
));
2270 sm_perror(" unhandled comparison %d", op
);
2274 *left_true_rl
= left_true
;
2275 *left_false_rl
= left_false
;
2277 if (right_true_rl
) {
2278 *right_true_rl
= right_true
;
2279 *right_false_rl
= right_false
;