kernel: fix a type bug handling err_cast()
[smatch.git] / smatch_ranges.c
blobed705111388c75f66a44f9855bc86d923745219b
1 /*
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
18 #include "parse.h"
19 #include "smatch.h"
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)
32 return false;
33 if (!type_is_ptr(sval.type))
34 return false;
35 if (sval.uvalue < -4095ULL)
36 return false;
37 return true;
40 static char *get_err_pointer_str(struct data_range *drange)
42 static char buf[20];
45 * The kernel has error pointers where you do essentially:
47 * return (void *)(unsigned long)-12;
49 * But what I want here is to print -12 instead of the unsigned version
50 * of that.
53 if (!is_err_ptr(drange->min))
54 return NULL;
56 if (drange->min.value == drange->max.value)
57 snprintf(buf, sizeof(buf), "(%lld)", drange->min.value);
58 else
59 snprintf(buf, sizeof(buf), "(%lld)-(%lld)", drange->min.value, drange->max.value);
60 return buf;
63 char *show_rl(struct range_list *list)
65 struct data_range *prev_drange = NULL;
66 struct data_range *tmp;
67 char full[255];
68 char *p = full;
69 char *prev = full;
70 char *err_ptr;
71 int remain;
72 int i = 0;
74 full[0] = '\0';
76 FOR_EACH_PTR(list, tmp) {
77 remain = full + sizeof(full) - p;
78 if (remain < 48) {
79 snprintf(prev, full + sizeof(full) - prev, ",%s-%s",
80 sval_to_str(prev_drange->min),
81 sval_to_str(sval_type_max(prev_drange->min.type)));
82 break;
84 prev_drange = tmp;
85 prev = p;
87 err_ptr = get_err_pointer_str(tmp);
88 if (err_ptr) {
89 p += snprintf(p, remain, "%s%s", i++ ? "," : "", err_ptr);
90 } else if (sval_cmp(tmp->min, tmp->max) == 0) {
91 p += snprintf(p, remain, "%s%s", i++ ? "," : "",
92 sval_to_str(tmp->min));
93 } else {
94 p += snprintf(p, remain, "%s%s-%s", i++ ? "," : "",
95 sval_to_str(tmp->min),
96 sval_to_str(tmp->max));
98 } END_FOR_EACH_PTR(tmp);
100 return alloc_sname(full);
103 void free_all_rl(void)
105 clear_rl_ptrlist_alloc();
108 static int sval_too_big(struct symbol *type, sval_t sval)
110 if (type_bits(type) >= 32 &&
111 type_bits(sval.type) <= type_bits(type))
112 return 0;
113 if (sval.uvalue <= ((1ULL << type_bits(type)) - 1))
114 return 0;
115 if (type_signed(sval.type)) {
116 if (type_unsigned(type)) {
117 unsigned long long neg = ~sval.uvalue;
118 if (neg <= sval_type_max(type).uvalue)
119 return 0;
121 if (sval.value < sval_type_min(type).value)
122 return 1;
123 if (sval.value > sval_type_max(type).value)
124 return 1;
125 return 0;
127 if (sval.uvalue > sval_type_max(type).uvalue)
128 return 1;
129 return 0;
132 static int truncates_nicely(struct symbol *type, sval_t min, sval_t max)
134 unsigned long long mask;
135 int bits = type_bits(type);
137 if (type_is_fp(min.type) && !type_is_fp(type))
138 return 0;
140 if (bits >= type_bits(min.type))
141 return 0;
143 mask = -1ULL << bits;
144 return (min.uvalue & mask) == (max.uvalue & mask);
147 static void add_range_t(struct symbol *type, struct range_list **rl, sval_t min, sval_t max)
149 /* If we're just adding a number, cast it and add it */
150 if (sval_cmp(min, max) == 0) {
151 add_range(rl, sval_cast(type, min), sval_cast(type, max));
152 return;
155 /* If the range is within the type range then add it */
156 if (sval_fits(type, min) && sval_fits(type, max)) {
157 add_range(rl, sval_cast(type, min), sval_cast(type, max));
158 return;
161 if (truncates_nicely(type, min, max)) {
162 add_range(rl, sval_cast(type, min), sval_cast(type, max));
163 return;
167 * If the range we are adding has more bits than the range type then
168 * add the whole range type. Eg:
169 * 0x8000000000000000 - 0xf000000000000000 -> cast to int
172 if (sval_too_big(type, min) || sval_too_big(type, max)) {
173 add_range(rl, sval_type_min(type), sval_type_max(type));
174 return;
177 /* Cast negative values to high positive values */
178 if (sval_is_negative(min) && type_unsigned(type)) {
179 if (sval_is_positive(max)) {
180 if (sval_too_high(type, max)) {
181 add_range(rl, sval_type_min(type), sval_type_max(type));
182 return;
184 add_range(rl, sval_type_val(type, 0), sval_cast(type, max));
185 max = sval_type_max(type);
186 } else {
187 max = sval_cast(type, max);
189 min = sval_cast(type, min);
190 add_range(rl, min, max);
193 /* Cast high positive numbers to negative */
194 if (sval_unsigned(max) && sval_is_negative(sval_cast(type, max))) {
195 if (!sval_is_negative(sval_cast(type, min))) {
196 add_range(rl, sval_cast(type, min), sval_type_max(type));
197 min = sval_type_min(type);
198 } else {
199 min = sval_cast(type, min);
201 max = sval_cast(type, max);
202 add_range(rl, min, max);
205 add_range(rl, sval_cast(type, min), sval_cast(type, max));
206 return;
209 static int str_to_comparison_arg_helper(const char *str,
210 struct expression *call, int *comparison,
211 struct expression **arg, const char **endp)
213 int param;
214 const char *c = str;
216 if (*c != '[')
217 return 0;
218 c++;
220 if (*c == '<') {
221 c++;
222 if (*c == '=') {
223 *comparison = SPECIAL_LTE;
224 c++;
225 } else {
226 *comparison = '<';
228 } else if (*c == '=') {
229 c++;
230 c++;
231 *comparison = SPECIAL_EQUAL;
232 } else if (*c == '>') {
233 c++;
234 if (*c == '=') {
235 *comparison = SPECIAL_GTE;
236 c++;
237 } else {
238 *comparison = '>';
240 } else if (*c == '!') {
241 c++;
242 c++;
243 *comparison = SPECIAL_NOTEQUAL;
244 } else if (*c == '$') {
245 *comparison = SPECIAL_EQUAL;
246 } else {
247 return 0;
250 if (*c != '$')
251 return 0;
252 c++;
254 param = strtoll(c, (char **)&c, 10);
256 * FIXME: handle parameter math. [==$1 + 100]
259 if (*c == ' ')
260 return 0;
262 if (*c == ',' || *c == ']')
263 c++; /* skip the ']' character */
264 if (endp)
265 *endp = (char *)c;
267 if (!call)
268 return 0;
269 *arg = get_argument_from_call_expr(call->args, param);
270 if (!*arg)
271 return 0;
272 if (*c == '-' && *(c + 1) == '>') {
273 char buf[256];
274 int n;
276 n = snprintf(buf, sizeof(buf), "$%s", c);
277 if (n >= sizeof(buf))
278 return 0;
279 if (buf[n - 1] == ']')
280 buf[n - 1] = '\0';
281 *arg = gen_expression_from_key(*arg, buf);
282 while (*c && *c != ']')
283 c++;
285 return 1;
288 int str_to_comparison_arg(const char *str, struct expression *call, int *comparison, struct expression **arg)
290 while (1) {
291 if (!*str)
292 return 0;
293 if (*str == '[')
294 break;
295 str++;
297 return str_to_comparison_arg_helper(str, call, comparison, arg, NULL);
300 static int get_val_from_key(int use_max, struct symbol *type, const char *c, struct expression *call, const char **endp, sval_t *sval)
302 struct expression *arg;
303 int comparison;
304 sval_t ret, tmp;
306 if (use_max)
307 ret = sval_type_max(type);
308 else
309 ret = sval_type_min(type);
311 if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp)) {
312 *sval = ret;
313 return 0;
316 if (use_max && get_implied_max(arg, &tmp)) {
317 ret = tmp;
318 if (comparison == '<') {
319 tmp.value = 1;
320 ret = sval_binop(ret, '-', tmp);
323 if (!use_max && get_implied_min(arg, &tmp)) {
324 ret = tmp;
325 if (comparison == '>') {
326 tmp.value = 1;
327 ret = sval_binop(ret, '+', tmp);
331 *sval = ret;
332 return 1;
335 static sval_t add_one(sval_t sval)
337 sval.value++;
338 return sval;
341 static sval_t sub_one(sval_t sval)
343 sval.value--;
344 return sval;
347 void filter_by_comparison(struct range_list **rl, int comparison, struct range_list *right)
349 struct range_list *left_orig = *rl;
350 struct range_list *right_orig = right;
351 struct range_list *ret_rl = *rl;
352 struct symbol *cast_type;
353 sval_t min, max;
355 if (comparison == UNKNOWN_COMPARISON)
356 return;
358 cast_type = rl_type(left_orig);
359 if (sval_type_max(rl_type(left_orig)).uvalue < sval_type_max(rl_type(right_orig)).uvalue)
360 cast_type = rl_type(right_orig);
361 if (sval_type_max(cast_type).uvalue < INT_MAX)
362 cast_type = &int_ctype;
364 min = sval_type_min(cast_type);
365 max = sval_type_max(cast_type);
366 left_orig = cast_rl(cast_type, left_orig);
367 right_orig = cast_rl(cast_type, right_orig);
369 switch (comparison) {
370 case '<':
371 case SPECIAL_UNSIGNED_LT:
372 ret_rl = remove_range(left_orig, rl_max(right_orig), max);
373 break;
374 case SPECIAL_LTE:
375 case SPECIAL_UNSIGNED_LTE:
376 if (!sval_is_max(rl_max(right_orig)))
377 ret_rl = remove_range(left_orig, add_one(rl_max(right_orig)), max);
378 break;
379 case SPECIAL_EQUAL:
380 ret_rl = rl_intersection(left_orig, right_orig);
381 break;
382 case SPECIAL_GTE:
383 case SPECIAL_UNSIGNED_GTE:
384 if (!sval_is_min(rl_min(right_orig)))
385 ret_rl = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
386 break;
387 case '>':
388 case SPECIAL_UNSIGNED_GT:
389 ret_rl = remove_range(left_orig, min, rl_min(right_orig));
390 break;
391 case SPECIAL_NOTEQUAL:
392 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
393 ret_rl = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
394 break;
395 default:
396 sm_perror("unhandled comparison %s", show_special(comparison));
397 return;
400 *rl = cast_rl(rl_type(*rl), ret_rl);
403 static struct range_list *filter_by_comparison_call(const char *c, struct expression *call, const char **endp, struct range_list *start_rl)
405 struct symbol *type;
406 struct expression *arg;
407 struct range_list *casted_start, *right_orig;
408 int comparison;
410 /* For when we have a function that takes a function pointer. */
411 if (!call || call->type != EXPR_CALL)
412 return start_rl;
414 if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp))
415 return start_rl;
417 if (!get_implied_rl(arg, &right_orig))
418 return start_rl;
420 type = &int_ctype;
421 if (type_positive_bits(rl_type(start_rl)) > type_positive_bits(type))
422 type = rl_type(start_rl);
423 if (type_positive_bits(rl_type(right_orig)) > type_positive_bits(type))
424 type = rl_type(right_orig);
426 casted_start = cast_rl(type, start_rl);
427 right_orig = cast_rl(type, right_orig);
429 filter_by_comparison(&casted_start, comparison, right_orig);
430 return cast_rl(rl_type(start_rl), casted_start);
433 static sval_t parse_val(int use_max, struct expression *call, struct symbol *type, const char *c, const char **endp)
435 const char *start = c;
436 sval_t ret;
438 if (type == &float_ctype)
439 return sval_type_fval(type, strtof(start, (char **)endp));
440 else if (type == &double_ctype)
441 return sval_type_fval(type, strtod(start, (char **)endp));
442 else if (type == &ldouble_ctype)
443 return sval_type_fval(type, strtold(start, (char **)endp));
445 if (!strncmp(start, "max", 3)) {
446 ret = sval_type_max(type);
447 c += 3;
448 } else if (!strncmp(start, "u64max", 6)) {
449 ret = sval_type_val(type, ULLONG_MAX);
450 c += 6;
451 } else if (!strncmp(start, "s64max", 6)) {
452 ret = sval_type_val(type, LLONG_MAX);
453 c += 6;
454 } else if (!strncmp(start, "u32max", 6)) {
455 ret = sval_type_val(type, UINT_MAX);
456 c += 6;
457 } else if (!strncmp(start, "s32max", 6)) {
458 ret = sval_type_val(type, INT_MAX);
459 c += 6;
460 } else if (!strncmp(start, "u16max", 6)) {
461 ret = sval_type_val(type, USHRT_MAX);
462 c += 6;
463 } else if (!strncmp(start, "s16max", 6)) {
464 ret = sval_type_val(type, SHRT_MAX);
465 c += 6;
466 } else if (!strncmp(start, "min", 3)) {
467 ret = sval_type_min(type);
468 c += 3;
469 } else if (!strncmp(start, "s64min", 6)) {
470 ret = sval_type_val(type, LLONG_MIN);
471 c += 6;
472 } else if (!strncmp(start, "s32min", 6)) {
473 ret = sval_type_val(type, INT_MIN);
474 c += 6;
475 } else if (!strncmp(start, "s16min", 6)) {
476 ret = sval_type_val(type, SHRT_MIN);
477 c += 6;
478 } else if (!strncmp(start, "long_min", 8)) {
479 ret = sval_type_val(type, LONG_MIN);
480 c += 8;
481 } else if (!strncmp(start, "long_max", 8)) {
482 ret = sval_type_val(type, LONG_MAX);
483 c += 8;
484 } else if (!strncmp(start, "ulong_max", 9)) {
485 ret = sval_type_val(type, ULONG_MAX);
486 c += 9;
487 } else if (!strncmp(start, "ptr_max", 7)) {
488 ret = sval_type_val(type, valid_ptr_max);
489 c += 7;
490 } else if (start[0] == '[') {
491 /* this parses [==p0] comparisons */
492 get_val_from_key(1, type, start, call, &c, &ret);
493 } else if (type_positive_bits(type) == 64) {
494 ret = sval_type_val(type, strtoull(start, (char **)&c, 0));
495 } else {
496 ret = sval_type_val(type, strtoll(start, (char **)&c, 0));
498 *endp = c;
499 return ret;
502 static const char *jump_to_call_math(const char *value)
504 const char *c = value;
506 while (*c && *c != '[')
507 c++;
509 if (!*c)
510 return NULL;
511 c++;
512 if (*c == '<' || *c == '=' || *c == '>' || *c == '!')
513 return NULL;
515 return c;
518 static struct range_list *get_param_return_rl(struct expression *call, const char *call_math)
520 struct expression *arg;
521 int param;
523 call_math += 3;
524 param = atoi(call_math);
526 arg = get_argument_from_call_expr(call->args, param);
527 if (!arg)
528 return NULL;
530 return db_return_vals_no_args(arg);
533 static void str_to_rl_helper(struct expression *call, struct symbol *type, const char *str, const char **endp, struct range_list **rl)
535 struct range_list *rl_tmp = NULL;
536 sval_t prev_min, min, max;
537 const char *c;
539 prev_min = sval_type_min(type);
540 min = sval_type_min(type);
541 max = sval_type_max(type);
542 c = str;
543 while (*c != '\0' && *c != '[') {
544 if (*c == '+') {
545 if (sval_cmp(min, sval_type_min(type)) != 0)
546 min = max;
547 max = sval_type_max(type);
548 add_range_t(type, &rl_tmp, min, max);
549 break;
551 if (*c == '(')
552 c++;
553 min = parse_val(0, call, type, c, &c);
554 if (!sval_fits(type, min))
555 min = sval_type_min(type);
556 max = min;
557 if (*c == ')')
558 c++;
559 if (*c == '\0' || *c == '[') {
560 add_range_t(type, &rl_tmp, min, min);
561 break;
563 if (*c == ',') {
564 add_range_t(type, &rl_tmp, min, min);
565 c++;
566 continue;
568 if (*c == '+') {
569 min = prev_min;
570 max = sval_type_max(type);
571 add_range_t(type, &rl_tmp, min, max);
572 c++;
573 if (*c == '[' || *c == '\0')
574 break;
576 if (*c != '-') {
577 sm_msg("debug XXX: trouble parsing %s c = %s", str, c);
578 break;
580 c++;
581 if (*c == '(')
582 c++;
583 max = parse_val(1, call, type, c, &c);
584 if (!sval_fits(type, max))
585 max = sval_type_max(type);
586 if (*c == '+') {
587 max = sval_type_max(type);
588 add_range_t(type, &rl_tmp, min, max);
589 c++;
590 if (*c == '[' || *c == '\0')
591 break;
593 prev_min = max;
594 add_range_t(type, &rl_tmp, min, max);
595 if (*c == ')')
596 c++;
597 if (*c == ',')
598 c++;
601 *rl = rl_tmp;
602 *endp = c;
605 static void str_to_dinfo(struct expression *call, struct symbol *type, const char *value, struct data_info *dinfo)
607 struct range_list *math_rl;
608 const char *call_math;
609 const char *c;
610 struct range_list *rl = NULL;
612 if (!type)
613 type = &llong_ctype;
615 if (strcmp(value, "empty") == 0)
616 return;
618 if (strncmp(value, "[==$", 4) == 0) {
619 struct expression *arg;
620 int comparison;
622 if (!str_to_comparison_arg(value, call, &comparison, &arg))
623 return;
624 if (!get_implied_rl(arg, &rl))
625 return;
626 goto cast;
629 str_to_rl_helper(call, type, value, &c, &rl);
630 if (*c == '\0')
631 goto cast;
633 call_math = jump_to_call_math(value);
634 if (call_math && call_math[0] == 'r') {
635 math_rl = get_param_return_rl(call, call_math);
636 if (math_rl)
637 rl = rl_intersection(rl, math_rl);
638 goto cast;
640 if (call_math && parse_call_math_rl(call, call_math, &math_rl)) {
641 rl = rl_intersection(rl, math_rl);
642 goto cast;
646 * For now if we already tried to handle the call math and couldn't
647 * figure it out then bail.
649 if (jump_to_call_math(c) == c + 1)
650 goto cast;
652 rl = filter_by_comparison_call(c, call, &c, rl);
654 cast:
655 rl = cast_rl(type, rl);
656 dinfo->value_ranges = rl;
659 static int rl_is_sane(struct range_list *rl)
661 struct data_range *tmp;
662 struct symbol *type;
664 type = rl_type(rl);
665 FOR_EACH_PTR(rl, tmp) {
666 if (!sval_fits(type, tmp->min))
667 return 0;
668 if (!sval_fits(type, tmp->max))
669 return 0;
670 if (sval_cmp(tmp->min, tmp->max) > 0)
671 return 0;
672 } END_FOR_EACH_PTR(tmp);
674 return 1;
677 void str_to_rl(struct symbol *type, char *value, struct range_list **rl)
679 struct data_info dinfo = {};
681 str_to_dinfo(NULL, type, value, &dinfo);
682 if (!rl_is_sane(dinfo.value_ranges))
683 dinfo.value_ranges = alloc_whole_rl(type);
684 *rl = dinfo.value_ranges;
687 void call_results_to_rl(struct expression *expr, struct symbol *type, const char *value, struct range_list **rl)
689 struct data_info dinfo = {};
691 str_to_dinfo(strip_expr(expr), type, value, &dinfo);
692 *rl = dinfo.value_ranges;
695 int is_whole_rl(struct range_list *rl)
697 struct data_range *drange;
699 if (ptr_list_empty((struct ptr_list *)rl))
700 return 0;
701 drange = first_ptr_list((struct ptr_list *)rl);
702 if (sval_is_min(drange->min) && sval_is_max(drange->max))
703 return 1;
704 return 0;
707 int is_unknown_ptr(struct range_list *rl)
709 struct data_range *drange;
710 int cnt = 0;
712 if (is_whole_rl(rl))
713 return 1;
715 FOR_EACH_PTR(rl, drange) {
716 if (++cnt >= 3)
717 return 0;
718 if (sval_cmp(drange->min, valid_ptr_min_sval) == 0 &&
719 sval_cmp(drange->max, valid_ptr_max_sval) == 0)
720 return 1;
721 } END_FOR_EACH_PTR(drange);
723 return 0;
726 int is_whole_rl_non_zero(struct range_list *rl)
728 struct data_range *drange;
730 if (ptr_list_empty((struct ptr_list *)rl))
731 return 0;
732 drange = first_ptr_list((struct ptr_list *)rl);
733 if (sval_unsigned(drange->min) &&
734 drange->min.value == 1 &&
735 sval_is_max(drange->max))
736 return 1;
737 if (!sval_is_min(drange->min) || drange->max.value != -1)
738 return 0;
739 drange = last_ptr_list((struct ptr_list *)rl);
740 if (drange->min.value != 1 || !sval_is_max(drange->max))
741 return 0;
742 return 1;
745 sval_t rl_min(struct range_list *rl)
747 struct data_range *drange;
748 sval_t ret;
750 ret.type = &llong_ctype;
751 ret.value = LLONG_MIN;
752 if (ptr_list_empty((struct ptr_list *)rl))
753 return ret;
754 drange = first_ptr_list((struct ptr_list *)rl);
755 return drange->min;
758 sval_t rl_max(struct range_list *rl)
760 struct data_range *drange;
761 sval_t ret;
763 ret.type = &llong_ctype;
764 ret.value = LLONG_MAX;
765 if (ptr_list_empty((struct ptr_list *)rl))
766 return ret;
767 drange = last_ptr_list((struct ptr_list *)rl);
768 return drange->max;
771 int rl_to_sval(struct range_list *rl, sval_t *sval)
773 sval_t min, max;
775 if (!rl)
776 return 0;
778 min = rl_min(rl);
779 max = rl_max(rl);
780 if (sval_cmp(min, max) != 0)
781 return 0;
782 *sval = min;
783 return 1;
786 struct symbol *rl_type(struct range_list *rl)
788 if (!rl)
789 return NULL;
790 return rl_min(rl).type;
793 static struct data_range *alloc_range_helper_sval(sval_t min, sval_t max, int perm)
795 struct data_range *ret;
797 if (perm)
798 ret = __alloc_perm_data_range(0);
799 else
800 ret = __alloc_data_range(0);
801 ret->min = min;
802 ret->max = max;
803 return ret;
806 struct data_range *alloc_range(sval_t min, sval_t max)
808 return alloc_range_helper_sval(min, max, 0);
811 struct data_range *alloc_range_perm(sval_t min, sval_t max)
813 return alloc_range_helper_sval(min, max, 1);
816 struct range_list *alloc_rl(sval_t min, sval_t max)
818 struct range_list *rl = NULL;
820 if (sval_cmp(min, max) > 0)
821 return alloc_whole_rl(min.type);
823 add_range(&rl, min, max);
824 return rl;
827 struct range_list *alloc_whole_rl(struct symbol *type)
829 if (!type || type_positive_bits(type) < 0)
830 type = &llong_ctype;
831 if (type->type == SYM_ARRAY)
832 type = &ptr_ctype;
834 return alloc_rl(sval_type_min(type), sval_type_max(type));
837 static bool collapse_pointer_rl(struct range_list **rl, sval_t min, sval_t max)
839 struct range_list *new_rl = NULL;
840 struct data_range *tmp;
841 static bool recurse;
842 bool ret = false;
843 int cnt = 0;
846 * With the mtag work, then we end up getting huge lists of mtags.
847 * That seems cool, but the problem is that we can only store about
848 * 8-10 mtags in the DB before we truncate the list. Also the mtags
849 * aren't really used at all so it's a waste of resources for now...
850 * In the future, we maybe will revisit this code.
854 if (recurse)
855 return false;
856 recurse = true;
857 if (!type_is_ptr(min.type))
858 goto out;
860 if (ptr_list_size((struct ptr_list *)*rl) < 8)
861 goto out;
862 FOR_EACH_PTR(*rl, tmp) {
863 if (!is_err_ptr(tmp->min))
864 cnt++;
865 } END_FOR_EACH_PTR(tmp);
866 if (cnt < 8)
867 goto out;
869 FOR_EACH_PTR(*rl, tmp) {
870 if (sval_cmp(tmp->min, valid_ptr_min_sval) >= 0 &&
871 sval_cmp(tmp->max, valid_ptr_max_sval) <= 0)
872 add_range(&new_rl, valid_ptr_min_sval, valid_ptr_max_sval);
873 else
874 add_range(&new_rl, tmp->min, tmp->max);
875 } END_FOR_EACH_PTR(tmp);
877 add_range(&new_rl, min, max);
879 *rl = new_rl;
880 ret = true;
881 out:
882 recurse = false;
883 return ret;
886 extern int rl_ptrlist_hack;
887 void add_range(struct range_list **list, sval_t min, sval_t max)
889 struct data_range *tmp;
890 struct data_range *new = NULL;
891 int check_next = 0;
894 * There is at least on valid reason why the types might be confusing
895 * and that's when you have a void pointer and on some paths you treat
896 * it as a u8 pointer and on other paths you treat it as a u16 pointer.
897 * This case is hard to deal with.
899 * There are other cases where we probably should be more specific about
900 * the types than we are. For example, we end up merging a lot of ulong
901 * with pointers and I have not figured out why we do that.
903 * But this hack works for both cases, I think. We cast it to pointers
904 * or we use the bigger size.
907 if (*list && rl_type(*list) != min.type) {
908 if (rl_type(*list)->type == SYM_PTR) {
909 min = sval_cast(rl_type(*list), min);
910 max = sval_cast(rl_type(*list), max);
911 } else if (min.type->type == SYM_PTR) {
912 *list = cast_rl(min.type, *list);
913 } else if (type_bits(rl_type(*list)) >= type_bits(min.type)) {
914 min = sval_cast(rl_type(*list), min);
915 max = sval_cast(rl_type(*list), max);
916 } else {
917 *list = cast_rl(min.type, *list);
921 if (sval_cmp(min, max) > 0) {
922 min = sval_type_min(min.type);
923 max = sval_type_max(min.type);
926 if (collapse_pointer_rl(list, min, max))
927 return;
930 * FIXME: This has a problem merging a range_list like: min-0,3-max
931 * with a range like 1-2. You end up with min-2,3-max instead of
932 * just min-max.
934 FOR_EACH_PTR(*list, tmp) {
935 if (check_next) {
936 /* Sometimes we overlap with more than one range
937 so we have to delete or modify the next range. */
938 if (!sval_is_max(max) && max.value + 1 == tmp->min.value) {
939 /* join 2 ranges here */
940 new->max = tmp->max;
941 DELETE_CURRENT_PTR(tmp);
942 return;
945 /* Doesn't overlap with the next one. */
946 if (sval_cmp(max, tmp->min) < 0)
947 return;
949 if (sval_cmp(max, tmp->max) <= 0) {
950 /* Partially overlaps the next one. */
951 new->max = tmp->max;
952 DELETE_CURRENT_PTR(tmp);
953 return;
954 } else {
955 /* Completely overlaps the next one. */
956 DELETE_CURRENT_PTR(tmp);
957 /* there could be more ranges to delete */
958 continue;
961 if (!sval_is_max(max) && max.value + 1 == tmp->min.value) {
962 /* join 2 ranges into a big range */
963 new = alloc_range(min, tmp->max);
964 REPLACE_CURRENT_PTR(tmp, new);
965 return;
967 if (sval_cmp(max, tmp->min) < 0) { /* new range entirely below */
968 new = alloc_range(min, max);
969 INSERT_CURRENT(new, tmp);
970 return;
972 if (sval_cmp(min, tmp->min) < 0) { /* new range partially below */
973 if (sval_cmp(max, tmp->max) < 0)
974 max = tmp->max;
975 else
976 check_next = 1;
977 new = alloc_range(min, max);
978 REPLACE_CURRENT_PTR(tmp, new);
979 if (!check_next)
980 return;
981 continue;
983 if (sval_cmp(max, tmp->max) <= 0) /* new range already included */
984 return;
985 if (sval_cmp(min, tmp->max) <= 0) { /* new range partially above */
986 min = tmp->min;
987 new = alloc_range(min, max);
988 REPLACE_CURRENT_PTR(tmp, new);
989 check_next = 1;
990 continue;
992 if (!sval_is_min(min) && min.value - 1 == tmp->max.value) {
993 /* join 2 ranges into a big range */
994 new = alloc_range(tmp->min, max);
995 REPLACE_CURRENT_PTR(tmp, new);
996 check_next = 1;
997 continue;
999 /* the new range is entirely above the existing ranges */
1000 } END_FOR_EACH_PTR(tmp);
1001 if (check_next)
1002 return;
1003 new = alloc_range(min, max);
1005 rl_ptrlist_hack = 1;
1006 add_ptr_list(list, new);
1007 rl_ptrlist_hack = 0;
1010 struct range_list *clone_rl(struct range_list *list)
1012 struct data_range *tmp;
1013 struct range_list *ret = NULL;
1015 FOR_EACH_PTR(list, tmp) {
1016 add_ptr_list(&ret, tmp);
1017 } END_FOR_EACH_PTR(tmp);
1018 return ret;
1021 struct range_list *clone_rl_permanent(struct range_list *list)
1023 struct data_range *tmp;
1024 struct data_range *new;
1025 struct range_list *ret = NULL;
1027 FOR_EACH_PTR(list, tmp) {
1028 new = alloc_range_perm(tmp->min, tmp->max);
1029 add_ptr_list(&ret, new);
1030 } END_FOR_EACH_PTR(tmp);
1031 return ret;
1034 struct range_list *rl_union(struct range_list *one, struct range_list *two)
1036 struct data_range *tmp;
1037 struct range_list *ret = NULL;
1039 FOR_EACH_PTR(one, tmp) {
1040 add_range(&ret, tmp->min, tmp->max);
1041 } END_FOR_EACH_PTR(tmp);
1042 FOR_EACH_PTR(two, tmp) {
1043 add_range(&ret, tmp->min, tmp->max);
1044 } END_FOR_EACH_PTR(tmp);
1045 return ret;
1048 struct range_list *remove_range(struct range_list *list, sval_t min, sval_t max)
1050 struct data_range *tmp;
1051 struct range_list *ret = NULL;
1053 if (!list)
1054 return NULL;
1056 min = sval_cast(rl_type(list), min);
1057 max = sval_cast(rl_type(list), max);
1058 if (sval_cmp(min, max) > 0) {
1059 sval_t tmp = min;
1060 min = max;
1061 max = tmp;
1064 FOR_EACH_PTR(list, tmp) {
1065 if (sval_cmp(tmp->max, min) < 0) {
1066 add_range(&ret, tmp->min, tmp->max);
1067 continue;
1069 if (sval_cmp(tmp->min, max) > 0) {
1070 add_range(&ret, tmp->min, tmp->max);
1071 continue;
1073 if (sval_cmp(tmp->min, min) >= 0 && sval_cmp(tmp->max, max) <= 0)
1074 continue;
1075 if (sval_cmp(tmp->min, min) >= 0) {
1076 max.value++;
1077 add_range(&ret, max, tmp->max);
1078 } else if (sval_cmp(tmp->max, max) <= 0) {
1079 min.value--;
1080 add_range(&ret, tmp->min, min);
1081 } else {
1082 min.value--;
1083 max.value++;
1084 add_range(&ret, tmp->min, min);
1085 add_range(&ret, max, tmp->max);
1087 } END_FOR_EACH_PTR(tmp);
1088 return ret;
1091 int ranges_equiv(struct data_range *one, struct data_range *two)
1093 if (!one && !two)
1094 return 1;
1095 if (!one || !two)
1096 return 0;
1097 if (sval_cmp(one->min, two->min) != 0)
1098 return 0;
1099 if (sval_cmp(one->max, two->max) != 0)
1100 return 0;
1101 return 1;
1104 int rl_equiv(struct range_list *one, struct range_list *two)
1106 struct data_range *one_range;
1107 struct data_range *two_range;
1109 if (one == two)
1110 return 1;
1112 PREPARE_PTR_LIST(one, one_range);
1113 PREPARE_PTR_LIST(two, two_range);
1114 for (;;) {
1115 if (!one_range && !two_range)
1116 return 1;
1117 if (!ranges_equiv(one_range, two_range))
1118 return 0;
1119 NEXT_PTR_LIST(one_range);
1120 NEXT_PTR_LIST(two_range);
1122 FINISH_PTR_LIST(two_range);
1123 FINISH_PTR_LIST(one_range);
1125 return 1;
1128 int true_comparison_range(struct data_range *left, int comparison, struct data_range *right)
1130 switch (comparison) {
1131 case '<':
1132 case SPECIAL_UNSIGNED_LT:
1133 if (sval_cmp(left->min, right->max) < 0)
1134 return 1;
1135 return 0;
1136 case SPECIAL_UNSIGNED_LTE:
1137 case SPECIAL_LTE:
1138 if (sval_cmp(left->min, right->max) <= 0)
1139 return 1;
1140 return 0;
1141 case SPECIAL_EQUAL:
1142 if (sval_cmp(left->max, right->min) < 0)
1143 return 0;
1144 if (sval_cmp(left->min, right->max) > 0)
1145 return 0;
1146 return 1;
1147 case SPECIAL_UNSIGNED_GTE:
1148 case SPECIAL_GTE:
1149 if (sval_cmp(left->max, right->min) >= 0)
1150 return 1;
1151 return 0;
1152 case '>':
1153 case SPECIAL_UNSIGNED_GT:
1154 if (sval_cmp(left->max, right->min) > 0)
1155 return 1;
1156 return 0;
1157 case SPECIAL_NOTEQUAL:
1158 if (sval_cmp(left->min, left->max) != 0)
1159 return 1;
1160 if (sval_cmp(right->min, right->max) != 0)
1161 return 1;
1162 if (sval_cmp(left->min, right->min) != 0)
1163 return 1;
1164 return 0;
1165 default:
1166 sm_perror("unhandled comparison %d", comparison);
1167 return 0;
1169 return 0;
1172 int true_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left)
1174 if (left)
1175 return true_comparison_range(var, comparison, val);
1176 else
1177 return true_comparison_range(val, comparison, var);
1180 static int false_comparison_range_sval(struct data_range *left, int comparison, struct data_range *right)
1182 switch (comparison) {
1183 case '<':
1184 case SPECIAL_UNSIGNED_LT:
1185 if (sval_cmp(left->max, right->min) >= 0)
1186 return 1;
1187 return 0;
1188 case SPECIAL_UNSIGNED_LTE:
1189 case SPECIAL_LTE:
1190 if (sval_cmp(left->max, right->min) > 0)
1191 return 1;
1192 return 0;
1193 case SPECIAL_EQUAL:
1194 if (sval_cmp(left->min, left->max) != 0)
1195 return 1;
1196 if (sval_cmp(right->min, right->max) != 0)
1197 return 1;
1198 if (sval_cmp(left->min, right->min) != 0)
1199 return 1;
1200 return 0;
1201 case SPECIAL_UNSIGNED_GTE:
1202 case SPECIAL_GTE:
1203 if (sval_cmp(left->min, right->max) < 0)
1204 return 1;
1205 return 0;
1206 case '>':
1207 case SPECIAL_UNSIGNED_GT:
1208 if (sval_cmp(left->min, right->max) <= 0)
1209 return 1;
1210 return 0;
1211 case SPECIAL_NOTEQUAL:
1212 if (sval_cmp(left->max, right->min) < 0)
1213 return 0;
1214 if (sval_cmp(left->min, right->max) > 0)
1215 return 0;
1216 return 1;
1217 default:
1218 sm_perror("unhandled comparison %d", comparison);
1219 return 0;
1221 return 0;
1224 int false_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left)
1226 if (left)
1227 return false_comparison_range_sval(var, comparison, val);
1228 else
1229 return false_comparison_range_sval(val, comparison, var);
1232 int possibly_true(struct expression *left, int comparison, struct expression *right)
1234 struct range_list *rl_left, *rl_right;
1235 struct data_range *tmp_left, *tmp_right;
1236 struct symbol *type;
1238 if (comparison == UNKNOWN_COMPARISON)
1239 return 1;
1240 if (!get_implied_rl(left, &rl_left))
1241 return 1;
1242 if (!get_implied_rl(right, &rl_right))
1243 return 1;
1245 type = rl_type(rl_left);
1246 if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
1247 type = rl_type(rl_right);
1248 if (type_positive_bits(type) < 31)
1249 type = &int_ctype;
1251 rl_left = cast_rl(type, rl_left);
1252 rl_right = cast_rl(type, rl_right);
1254 FOR_EACH_PTR(rl_left, tmp_left) {
1255 FOR_EACH_PTR(rl_right, tmp_right) {
1256 if (true_comparison_range(tmp_left, comparison, tmp_right))
1257 return 1;
1258 } END_FOR_EACH_PTR(tmp_right);
1259 } END_FOR_EACH_PTR(tmp_left);
1260 return 0;
1263 int possibly_false(struct expression *left, int comparison, struct expression *right)
1265 struct range_list *rl_left, *rl_right;
1266 struct data_range *tmp_left, *tmp_right;
1267 struct symbol *type;
1269 if (!get_implied_rl(left, &rl_left))
1270 return 1;
1271 if (!get_implied_rl(right, &rl_right))
1272 return 1;
1274 type = rl_type(rl_left);
1275 if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
1276 type = rl_type(rl_right);
1277 if (type_positive_bits(type) < 31)
1278 type = &int_ctype;
1280 rl_left = cast_rl(type, rl_left);
1281 rl_right = cast_rl(type, rl_right);
1283 FOR_EACH_PTR(rl_left, tmp_left) {
1284 FOR_EACH_PTR(rl_right, tmp_right) {
1285 if (false_comparison_range_sval(tmp_left, comparison, tmp_right))
1286 return 1;
1287 } END_FOR_EACH_PTR(tmp_right);
1288 } END_FOR_EACH_PTR(tmp_left);
1289 return 0;
1292 int possibly_true_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
1294 struct data_range *left_tmp, *right_tmp;
1295 struct symbol *type;
1297 if (!left_ranges || !right_ranges || comparison == UNKNOWN_COMPARISON)
1298 return 1;
1300 type = rl_type(left_ranges);
1301 if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
1302 type = rl_type(right_ranges);
1303 if (type_positive_bits(type) < 31)
1304 type = &int_ctype;
1306 left_ranges = cast_rl(type, left_ranges);
1307 right_ranges = cast_rl(type, right_ranges);
1309 FOR_EACH_PTR(left_ranges, left_tmp) {
1310 FOR_EACH_PTR(right_ranges, right_tmp) {
1311 if (true_comparison_range(left_tmp, comparison, right_tmp))
1312 return 1;
1313 } END_FOR_EACH_PTR(right_tmp);
1314 } END_FOR_EACH_PTR(left_tmp);
1315 return 0;
1318 int possibly_false_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
1320 struct data_range *left_tmp, *right_tmp;
1321 struct symbol *type;
1323 if (!left_ranges || !right_ranges || comparison == UNKNOWN_COMPARISON)
1324 return 1;
1326 type = rl_type(left_ranges);
1327 if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
1328 type = rl_type(right_ranges);
1329 if (type_positive_bits(type) < 31)
1330 type = &int_ctype;
1332 left_ranges = cast_rl(type, left_ranges);
1333 right_ranges = cast_rl(type, right_ranges);
1335 FOR_EACH_PTR(left_ranges, left_tmp) {
1336 FOR_EACH_PTR(right_ranges, right_tmp) {
1337 if (false_comparison_range_sval(left_tmp, comparison, right_tmp))
1338 return 1;
1339 } END_FOR_EACH_PTR(right_tmp);
1340 } END_FOR_EACH_PTR(left_tmp);
1341 return 0;
1344 /* FIXME: the _rl here stands for right left so really it should be _lr */
1345 int possibly_true_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left)
1347 if (left)
1348 return possibly_true_rl(a, comparison, b);
1349 else
1350 return possibly_true_rl(b, comparison, a);
1353 int possibly_false_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left)
1355 if (left)
1356 return possibly_false_rl(a, comparison, b);
1357 else
1358 return possibly_false_rl(b, comparison, a);
1361 int rl_has_sval(struct range_list *rl, sval_t sval)
1363 struct data_range *tmp;
1365 FOR_EACH_PTR(rl, tmp) {
1366 if (sval_cmp(tmp->min, sval) <= 0 &&
1367 sval_cmp(tmp->max, sval) >= 0)
1368 return 1;
1369 } END_FOR_EACH_PTR(tmp);
1370 return 0;
1373 void tack_on(struct range_list **list, struct data_range *drange)
1375 add_ptr_list(list, drange);
1378 void push_rl(struct range_list_stack **rl_stack, struct range_list *rl)
1380 add_ptr_list(rl_stack, rl);
1383 struct range_list *pop_rl(struct range_list_stack **rl_stack)
1385 struct range_list *rl;
1387 rl = last_ptr_list((struct ptr_list *)*rl_stack);
1388 delete_ptr_list_last((struct ptr_list **)rl_stack);
1389 return rl;
1392 struct range_list *top_rl(struct range_list_stack *rl_stack)
1394 struct range_list *rl;
1396 rl = last_ptr_list((struct ptr_list *)rl_stack);
1397 return rl;
1400 void filter_top_rl(struct range_list_stack **rl_stack, struct range_list *filter)
1402 struct range_list *rl;
1404 rl = pop_rl(rl_stack);
1405 rl = rl_filter(rl, filter);
1406 push_rl(rl_stack, rl);
1409 struct range_list *rl_truncate_cast(struct symbol *type, struct range_list *rl)
1411 struct data_range *tmp;
1412 struct range_list *ret = NULL;
1413 sval_t min, max;
1415 if (!rl)
1416 return NULL;
1418 if (!type || type == rl_type(rl))
1419 return rl;
1421 FOR_EACH_PTR(rl, tmp) {
1422 min = tmp->min;
1423 max = tmp->max;
1424 if (type_bits(type) < type_bits(rl_type(rl))) {
1425 min.uvalue = tmp->min.uvalue & ((1ULL << type_bits(type)) - 1);
1426 max.uvalue = tmp->max.uvalue & ((1ULL << type_bits(type)) - 1);
1428 if (sval_cmp(min, max) > 0) {
1429 min = sval_cast(type, min);
1430 max = sval_cast(type, max);
1432 add_range_t(type, &ret, min, max);
1433 } END_FOR_EACH_PTR(tmp);
1435 return ret;
1438 int rl_fits_in_type(struct range_list *rl, struct symbol *type)
1440 if (type_bits(rl_type(rl)) <= type_bits(type))
1441 return 1;
1442 if (sval_cmp(rl_max(rl), sval_type_max(type)) > 0)
1443 return 0;
1444 if (sval_is_negative(rl_min(rl)) &&
1445 sval_cmp(rl_min(rl), sval_type_min(type)) < 0)
1446 return 0;
1447 return 1;
1450 static int rl_type_consistent(struct range_list *rl)
1452 struct data_range *tmp;
1453 struct symbol *type;
1455 type = rl_type(rl);
1456 FOR_EACH_PTR(rl, tmp) {
1457 if (type != tmp->min.type || type != tmp->max.type)
1458 return 0;
1459 } END_FOR_EACH_PTR(tmp);
1460 return 1;
1463 static struct range_list *cast_to_bool(struct range_list *rl)
1465 struct data_range *tmp;
1466 struct range_list *ret = NULL;
1467 int has_one = 0;
1468 int has_zero = 0;
1469 sval_t min = { .type = &bool_ctype };
1470 sval_t max = { .type = &bool_ctype };
1472 FOR_EACH_PTR(rl, tmp) {
1473 if (tmp->min.value || tmp->max.value)
1474 has_one = 1;
1475 if (sval_is_negative(tmp->min) &&
1476 sval_is_negative(tmp->max))
1477 continue;
1478 if (tmp->min.value == 0 ||
1479 tmp->max.value == 0)
1480 has_zero = 1;
1481 if (sval_is_negative(tmp->min) &&
1482 tmp->max.value > 0)
1483 has_zero = 1;
1484 } END_FOR_EACH_PTR(tmp);
1486 if (!has_zero)
1487 min.value = 1;
1488 if (has_one)
1489 max.value = 1;
1491 add_range(&ret, min, max);
1492 return ret;
1495 struct range_list *cast_rl(struct symbol *type, struct range_list *rl)
1497 struct data_range *tmp;
1498 struct range_list *ret = NULL;
1500 if (!rl)
1501 return NULL;
1503 if (!type)
1504 return rl;
1505 if (!rl_is_sane(rl))
1506 return alloc_whole_rl(type);
1507 if (type == rl_type(rl) && rl_type_consistent(rl))
1508 return rl;
1510 if (type == &bool_ctype)
1511 return cast_to_bool(rl);
1513 FOR_EACH_PTR(rl, tmp) {
1514 add_range_t(type, &ret, tmp->min, tmp->max);
1515 } END_FOR_EACH_PTR(tmp);
1517 if (!ret)
1518 return alloc_whole_rl(type);
1520 return ret;
1523 struct range_list *rl_filter(struct range_list *rl, struct range_list *filter)
1525 struct data_range *tmp;
1527 FOR_EACH_PTR(filter, tmp) {
1528 rl = remove_range(rl, tmp->min, tmp->max);
1529 } END_FOR_EACH_PTR(tmp);
1531 return rl;
1534 struct range_list *do_intersection(struct range_list *one_rl, struct range_list *two_rl)
1536 struct data_range *one, *two;
1537 struct range_list *ret = NULL;
1540 PREPARE_PTR_LIST(one_rl, one);
1541 PREPARE_PTR_LIST(two_rl, two);
1543 while (true) {
1544 if (!one || !two)
1545 break;
1546 if (sval_cmp(one->max, two->min) < 0) {
1547 NEXT_PTR_LIST(one);
1548 continue;
1550 if (sval_cmp(one->min, two->min) < 0 && sval_cmp(one->max, two->max) <= 0) {
1551 add_range(&ret, two->min, one->max);
1552 NEXT_PTR_LIST(one);
1553 continue;
1555 if (sval_cmp(one->min, two->min) >= 0 && sval_cmp(one->max, two->max) <= 0) {
1556 add_range(&ret, one->min, one->max);
1557 NEXT_PTR_LIST(one);
1558 continue;
1560 if (sval_cmp(one->min, two->min) < 0 && sval_cmp(one->max, two->max) > 0) {
1561 add_range(&ret, two->min, two->max);
1562 NEXT_PTR_LIST(two);
1563 continue;
1565 if (sval_cmp(one->min, two->max) <= 0 && sval_cmp(one->max, two->max) > 0) {
1566 add_range(&ret, one->min, two->max);
1567 NEXT_PTR_LIST(two);
1568 continue;
1570 if (sval_cmp(one->min, two->max) <= 0) {
1571 sm_fatal("error calculating intersection of '%s' and '%s'", show_rl(one_rl), show_rl(two_rl));
1572 return NULL;
1574 NEXT_PTR_LIST(two);
1577 FINISH_PTR_LIST(two);
1578 FINISH_PTR_LIST(one);
1580 return ret;
1583 struct range_list *rl_intersection(struct range_list *one, struct range_list *two)
1585 struct range_list *ret;
1586 struct symbol *ret_type;
1587 struct symbol *small_type;
1588 struct symbol *large_type;
1590 if (!one || !two)
1591 return NULL;
1593 ret_type = rl_type(one);
1594 small_type = rl_type(one);
1595 large_type = rl_type(two);
1597 if (type_bits(rl_type(two)) < type_bits(small_type)) {
1598 small_type = rl_type(two);
1599 large_type = rl_type(one);
1602 one = cast_rl(large_type, one);
1603 two = cast_rl(large_type, two);
1605 ret = do_intersection(one, two);
1606 return cast_rl(ret_type, ret);
1609 static struct range_list *handle_mod_rl(struct range_list *left, struct range_list *right)
1611 sval_t zero;
1612 sval_t max;
1614 max = rl_max(right);
1615 if (sval_is_max(max))
1616 return left;
1617 if (max.value == 0)
1618 return NULL;
1619 max.value--;
1620 if (sval_is_negative(max))
1621 return NULL;
1622 if (sval_cmp(rl_max(left), max) < 0)
1623 return left;
1624 zero = max;
1625 zero.value = 0;
1626 return alloc_rl(zero, max);
1629 static struct range_list *get_neg_rl(struct range_list *rl)
1631 struct data_range *tmp;
1632 struct data_range *new;
1633 struct range_list *ret = NULL;
1635 if (!rl)
1636 return NULL;
1637 if (sval_is_positive(rl_min(rl)))
1638 return NULL;
1640 FOR_EACH_PTR(rl, tmp) {
1641 if (sval_is_positive(tmp->min))
1642 break;
1643 if (sval_is_positive(tmp->max)) {
1644 new = alloc_range(tmp->min, tmp->max);
1645 new->max.value = -1;
1646 add_range(&ret, new->min, new->max);
1647 break;
1649 add_range(&ret, tmp->min, tmp->max);
1650 } END_FOR_EACH_PTR(tmp);
1652 return ret;
1655 static struct range_list *get_pos_rl(struct range_list *rl)
1657 struct data_range *tmp;
1658 struct data_range *new;
1659 struct range_list *ret = NULL;
1661 if (!rl)
1662 return NULL;
1663 if (sval_is_negative(rl_max(rl)))
1664 return NULL;
1666 FOR_EACH_PTR(rl, tmp) {
1667 if (sval_is_negative(tmp->max))
1668 continue;
1669 if (sval_is_positive(tmp->min)) {
1670 add_range(&ret, tmp->min, tmp->max);
1671 continue;
1673 new = alloc_range(tmp->min, tmp->max);
1674 new->min.value = 0;
1675 add_range(&ret, new->min, new->max);
1676 } END_FOR_EACH_PTR(tmp);
1678 return ret;
1681 static struct range_list *divide_rl_helper(struct range_list *left, struct range_list *right)
1683 sval_t right_min, right_max;
1684 sval_t min, max;
1686 if (!left || !right)
1687 return NULL;
1689 /* let's assume we never divide by zero */
1690 right_min = rl_min(right);
1691 right_max = rl_max(right);
1692 if (right_min.value == 0 && right_max.value == 0)
1693 return NULL;
1694 if (right_min.value == 0)
1695 right_min.value = 1;
1696 if (right_max.value == 0)
1697 right_max.value = -1;
1699 max = sval_binop(rl_max(left), '/', right_min);
1700 min = sval_binop(rl_min(left), '/', right_max);
1702 return alloc_rl(min, max);
1705 static struct range_list *handle_divide_rl(struct range_list *left, struct range_list *right)
1707 struct range_list *left_neg, *left_pos, *right_neg, *right_pos;
1708 struct range_list *neg_neg, *neg_pos, *pos_neg, *pos_pos;
1709 struct range_list *ret;
1711 if (is_whole_rl(right))
1712 return NULL;
1714 left_neg = get_neg_rl(left);
1715 left_pos = get_pos_rl(left);
1716 right_neg = get_neg_rl(right);
1717 right_pos = get_pos_rl(right);
1719 neg_neg = divide_rl_helper(left_neg, right_neg);
1720 neg_pos = divide_rl_helper(left_neg, right_pos);
1721 pos_neg = divide_rl_helper(left_pos, right_neg);
1722 pos_pos = divide_rl_helper(left_pos, right_pos);
1724 ret = rl_union(neg_neg, neg_pos);
1725 ret = rl_union(ret, pos_neg);
1726 return rl_union(ret, pos_pos);
1729 static struct range_list *ptr_add_mult(struct range_list *left, int op, struct range_list *right)
1731 struct range_list *ret;
1732 sval_t l_sval, r_sval, res;
1735 * This function is sort of the wrong API because it takes two pointer
1736 * and adds them together. The caller is expected to figure out
1737 * alignment. Neither of those are the correct things to do.
1739 * Really this function is quite bogus...
1742 if (rl_to_sval(left, &l_sval) && rl_to_sval(right, &r_sval)) {
1743 res = sval_binop(l_sval, op, r_sval);
1744 return alloc_rl(res, res);
1747 if (rl_min(left).value != 0 || rl_max(right).value != 0) {
1748 ret = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
1749 return cast_rl(rl_type(left), ret);
1752 return alloc_whole_rl(rl_type(left));
1755 static struct range_list *handle_add_mult_rl(struct range_list *left, int op, struct range_list *right)
1757 sval_t min, max;
1759 if (type_is_ptr(rl_type(left)) || type_is_ptr(rl_type(right)))
1760 return ptr_add_mult(left, op, right);
1762 if (sval_binop_overflows(rl_min(left), op, rl_min(right)))
1763 return NULL;
1764 min = sval_binop(rl_min(left), op, rl_min(right));
1766 if (sval_binop_overflows(rl_max(left), op, rl_max(right)))
1767 return NULL;
1768 max = sval_binop(rl_max(left), op, rl_max(right));
1770 return alloc_rl(min, max);
1773 static struct range_list *handle_sub_rl(struct range_list *left_orig, struct range_list *right_orig)
1775 struct range_list *left_rl, *right_rl;
1776 struct symbol *type;
1777 sval_t min, max;
1778 sval_t min_ll, max_ll, res_ll;
1779 sval_t tmp;
1781 /* TODO: These things should totally be using dranges where possible */
1783 if (!left_orig || !right_orig)
1784 return NULL;
1786 type = &int_ctype;
1787 if (type_positive_bits(rl_type(left_orig)) > type_positive_bits(type))
1788 type = rl_type(left_orig);
1789 if (type_positive_bits(rl_type(right_orig)) > type_positive_bits(type))
1790 type = rl_type(right_orig);
1792 left_rl = cast_rl(type, left_orig);
1793 right_rl = cast_rl(type, right_orig);
1795 max = rl_max(left_rl);
1796 min = sval_type_min(type);
1798 min_ll = rl_min(left_rl);
1799 min_ll.type = &llong_ctype;
1800 max_ll = rl_max(right_rl);
1801 max_ll.type = &llong_ctype;
1802 res_ll = min_ll;
1803 res_ll.value = min_ll.value - max_ll.value;
1805 if (!sval_binop_overflows(rl_min(left_rl), '-', rl_max(right_rl))) {
1806 tmp = sval_binop(rl_min(left_rl), '-', rl_max(right_rl));
1807 if (sval_cmp(tmp, min) > 0)
1808 min = tmp;
1809 } else if (type_positive_bits(type) < 63 &&
1810 !sval_binop_overflows(min_ll, '-', max_ll) &&
1811 (min.value != 0 && sval_cmp(res_ll, min) >= 0)) {
1812 struct range_list *left_casted, *right_casted, *result;
1814 left_casted = cast_rl(&llong_ctype, left_orig);
1815 right_casted = cast_rl(&llong_ctype, right_orig);
1816 result = handle_sub_rl(left_casted, right_casted);
1817 return cast_rl(type, result);
1820 if (!sval_is_max(rl_max(left_rl))) {
1821 tmp = sval_binop(rl_max(left_rl), '-', rl_min(right_rl));
1822 if (sval_cmp(tmp, max) < 0)
1823 max = tmp;
1826 if (sval_is_min(min) && sval_is_max(max))
1827 return NULL;
1829 return alloc_rl(min, max);
1832 static unsigned long long rl_bits_always_set(struct range_list *rl)
1834 return sval_fls_mask(rl_min(rl));
1837 static unsigned long long rl_bits_maybe_set(struct range_list *rl)
1839 return sval_fls_mask(rl_max(rl));
1842 static struct range_list *handle_OR_rl(struct range_list *left, struct range_list *right)
1844 unsigned long long left_min, left_max, right_min, right_max;
1845 sval_t min, max;
1846 sval_t sval;
1848 if ((rl_to_sval(left, &sval) || rl_to_sval(right, &sval)) &&
1849 !sval_binop_overflows(rl_max(left), '+', rl_max(right)))
1850 return rl_binop(left, '+', right);
1852 left_min = rl_bits_always_set(left);
1853 left_max = rl_bits_maybe_set(left);
1854 right_min = rl_bits_always_set(right);
1855 right_max = rl_bits_maybe_set(right);
1857 min.type = max.type = &ullong_ctype;
1858 min.uvalue = left_min | right_min;
1859 max.uvalue = left_max | right_max;
1861 return cast_rl(rl_type(left), alloc_rl(min, max));
1864 static struct range_list *handle_XOR_rl(struct range_list *left, struct range_list *right)
1866 unsigned long long left_set, left_maybe;
1867 unsigned long long right_set, right_maybe;
1868 sval_t zero, max;
1870 left_set = rl_bits_always_set(left);
1871 left_maybe = rl_bits_maybe_set(left);
1873 right_set = rl_bits_always_set(right);
1874 right_maybe = rl_bits_maybe_set(right);
1876 zero = max = rl_min(left);
1877 zero.uvalue = 0;
1878 max.uvalue = fls_mask((left_maybe | right_maybe) ^ (left_set & right_set));
1880 return cast_rl(rl_type(left), alloc_rl(zero, max));
1883 static sval_t sval_lowest_set_bit(sval_t sval)
1885 sval_t ret = { .type = sval.type };
1886 int i;
1888 for (i = 0; i < 64; i++) {
1889 if (sval.uvalue & 1ULL << i) {
1890 ret.uvalue = (1ULL << i);
1891 return ret;
1894 return ret;
1897 static struct range_list *handle_AND_rl(struct range_list *left, struct range_list *right)
1899 struct bit_info *one, *two;
1900 struct range_list *rl;
1901 sval_t min, max, zero;
1902 unsigned long long bits;
1904 one = rl_to_binfo(left);
1905 two = rl_to_binfo(right);
1906 bits = one->possible & two->possible;
1908 max = rl_max(left);
1909 max.uvalue = bits;
1910 min = sval_lowest_set_bit(max);
1912 rl = alloc_rl(min, max);
1914 zero = rl_min(rl);
1915 zero.value = 0;
1916 add_range(&rl, zero, zero);
1918 return rl;
1921 static struct range_list *handle_lshift(struct range_list *left_orig, struct range_list *right_orig)
1923 struct range_list *left;
1924 struct data_range *tmp;
1925 struct range_list *ret = NULL;
1926 sval_t zero = { .type = rl_type(left_orig), };
1927 sval_t shift, min, max;
1928 bool add_zero = false;
1930 if (!rl_to_sval(right_orig, &shift) || sval_is_negative(shift))
1931 return NULL;
1932 if (shift.value == 0)
1933 return left_orig;
1935 /* Cast to unsigned for easier left shift math */
1936 if (type_positive_bits(rl_type(left_orig)) < 32)
1937 left = cast_rl(&uint_ctype, left_orig);
1938 else if(type_positive_bits(rl_type(left_orig)) == 63)
1939 left = cast_rl(&ullong_ctype, left_orig);
1940 else
1941 left = left_orig;
1943 FOR_EACH_PTR(left, tmp) {
1944 min = tmp->min;
1945 max = tmp->max;
1947 if (min.value == 0 || max.value > sval_type_max(max.type).uvalue >> shift.uvalue)
1948 add_zero = true;
1949 if (min.value == 0 && max.value == 0)
1950 continue;
1951 if (min.value == 0)
1952 min.value = 1;
1953 min = sval_binop(min, SPECIAL_LEFTSHIFT, shift);
1954 max = sval_binop(max, SPECIAL_LEFTSHIFT, shift);
1955 add_range(&ret, min, max);
1956 } END_FOR_EACH_PTR(tmp);
1958 if (!rl_fits_in_type(ret, rl_type(left_orig)))
1959 add_zero = true;
1960 ret = cast_rl(rl_type(left_orig), ret);
1961 if (add_zero)
1962 add_range(&ret, zero, zero);
1964 return ret;
1967 static struct range_list *handle_rshift(struct range_list *left_orig, struct range_list *right_orig)
1969 struct data_range *tmp;
1970 struct range_list *ret = NULL;
1971 sval_t shift, min, max;
1973 if (!rl_to_sval(right_orig, &shift) || sval_is_negative(shift))
1974 return NULL;
1975 if (shift.value == 0)
1976 return left_orig;
1978 FOR_EACH_PTR(left_orig, tmp) {
1979 min = sval_binop(tmp->min, SPECIAL_RIGHTSHIFT, shift);
1980 max = sval_binop(tmp->max, SPECIAL_RIGHTSHIFT, shift);
1981 add_range(&ret, min, max);
1982 } END_FOR_EACH_PTR(tmp);
1984 return ret;
1987 struct range_list *rl_binop(struct range_list *left, int op, struct range_list *right)
1989 struct symbol *cast_type;
1990 sval_t left_sval, right_sval;
1991 struct range_list *ret = NULL;
1993 cast_type = rl_type(left);
1994 if (sval_type_max(rl_type(left)).uvalue < sval_type_max(rl_type(right)).uvalue)
1995 cast_type = rl_type(right);
1996 if (sval_type_max(cast_type).uvalue < INT_MAX)
1997 cast_type = &int_ctype;
1999 left = cast_rl(cast_type, left);
2000 right = cast_rl(cast_type, right);
2002 if (!left && !right)
2003 return NULL;
2005 if (rl_to_sval(left, &left_sval) && rl_to_sval(right, &right_sval)) {
2006 sval_t val = sval_binop(left_sval, op, right_sval);
2007 return alloc_rl(val, val);
2010 switch (op) {
2011 case '%':
2012 ret = handle_mod_rl(left, right);
2013 break;
2014 case '/':
2015 ret = handle_divide_rl(left, right);
2016 break;
2017 case '*':
2018 case '+':
2019 ret = handle_add_mult_rl(left, op, right);
2020 break;
2021 case '|':
2022 ret = handle_OR_rl(left, right);
2023 break;
2024 case '^':
2025 ret = handle_XOR_rl(left, right);
2026 break;
2027 case '&':
2028 ret = handle_AND_rl(left, right);
2029 break;
2030 case '-':
2031 ret = handle_sub_rl(left, right);
2032 break;
2033 case SPECIAL_RIGHTSHIFT:
2034 return handle_rshift(left, right);
2035 case SPECIAL_LEFTSHIFT:
2036 return handle_lshift(left, right);
2039 return ret;
2042 void free_data_info_allocs(void)
2044 struct allocator_struct *desc = &data_info_allocator;
2045 struct allocation_blob *blob = desc->blobs;
2047 free_all_rl();
2048 clear_math_cache();
2050 desc->blobs = NULL;
2051 desc->allocations = 0;
2052 desc->total_bytes = 0;
2053 desc->useful_bytes = 0;
2054 desc->freelist = NULL;
2055 while (blob) {
2056 struct allocation_blob *next = blob->next;
2057 blob_free(blob, desc->chunking);
2058 blob = next;
2060 clear_data_range_alloc();
2063 void split_comparison_rl(struct range_list *left_orig, int op, struct range_list *right_orig,
2064 struct range_list **left_true_rl, struct range_list **left_false_rl,
2065 struct range_list **right_true_rl, struct range_list **right_false_rl)
2067 struct range_list *left_true, *left_false;
2068 struct range_list *right_true, *right_false;
2069 sval_t min, max;
2071 min = sval_type_min(rl_type(left_orig));
2072 max = sval_type_max(rl_type(left_orig));
2074 left_true = clone_rl(left_orig);
2075 left_false = clone_rl(left_orig);
2076 right_true = clone_rl(right_orig);
2077 right_false = clone_rl(right_orig);
2079 switch (op) {
2080 case '<':
2081 case SPECIAL_UNSIGNED_LT:
2082 left_true = remove_range(left_orig, rl_max(right_orig), max);
2083 if (!sval_is_min(rl_min(right_orig))) {
2084 left_false = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
2087 right_true = remove_range(right_orig, min, rl_min(left_orig));
2088 if (!sval_is_max(rl_max(left_orig)))
2089 right_false = remove_range(right_orig, add_one(rl_max(left_orig)), max);
2090 break;
2091 case SPECIAL_UNSIGNED_LTE:
2092 case SPECIAL_LTE:
2093 if (!sval_is_max(rl_max(right_orig)))
2094 left_true = remove_range(left_orig, add_one(rl_max(right_orig)), max);
2095 left_false = remove_range(left_orig, min, rl_min(right_orig));
2097 if (!sval_is_min(rl_min(left_orig)))
2098 right_true = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
2099 right_false = remove_range(right_orig, rl_max(left_orig), max);
2101 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
2102 left_false = remove_range(left_false, rl_min(left_orig), rl_min(left_orig));
2103 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
2104 right_false = remove_range(right_false, rl_max(left_orig), rl_max(left_orig));
2105 break;
2106 case SPECIAL_EQUAL:
2107 left_true = rl_intersection(left_orig, right_orig);
2108 right_true = clone_rl(left_true);
2110 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
2111 left_false = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
2112 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
2113 right_false = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
2114 break;
2115 case SPECIAL_UNSIGNED_GTE:
2116 case SPECIAL_GTE:
2117 if (!sval_is_min(rl_min(right_orig)))
2118 left_true = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
2119 left_false = remove_range(left_orig, rl_max(right_orig), max);
2121 if (!sval_is_max(rl_max(left_orig)))
2122 right_true = remove_range(right_orig, add_one(rl_max(left_orig)), max);
2123 right_false = remove_range(right_orig, min, rl_min(left_orig));
2125 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
2126 right_false = remove_range(right_false, rl_min(left_orig), rl_min(left_orig));
2127 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
2128 left_false = remove_range(left_false, rl_max(left_orig), rl_max(left_orig));
2129 break;
2130 case '>':
2131 case SPECIAL_UNSIGNED_GT:
2132 left_true = remove_range(left_orig, min, rl_min(right_orig));
2133 if (!sval_is_max(rl_max(right_orig)))
2134 left_false = remove_range(left_orig, add_one(rl_max(right_orig)), max);
2136 right_true = remove_range(right_orig, rl_max(left_orig), max);
2137 if (!sval_is_min(rl_min(left_orig)))
2138 right_false = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
2139 break;
2140 case SPECIAL_NOTEQUAL:
2141 left_false = rl_intersection(left_orig, right_orig);
2142 right_false = clone_rl(left_false);
2144 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
2145 left_true = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
2146 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
2147 right_true = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
2148 break;
2149 default:
2150 sm_perror(" unhandled comparison %d", op);
2153 if (left_true_rl) {
2154 *left_true_rl = left_true;
2155 *left_false_rl = left_false;
2157 if (right_true_rl) {
2158 *right_true_rl = right_true;
2159 *right_false_rl = right_false;