1 /* 2 * Copyright (C) 2009 Dan Carpenter. 3 * 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. 8 * 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. 13 * 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 16 */ 17 18 #include "parse.h" 19 #include "smatch.h" 20 #include "smatch_extra.h" 21 #include "smatch_slist.h" 22 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); 28 29 bool is_err_ptr(sval_t sval) 30 { 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; 38 } 39 40 static char *get_err_pointer_str(struct data_range *drange) 41 { 42 static char buf[20]; 43 44 /* 45 * The kernel has error pointers where you do essentially: 46 * 47 * return (void *)(unsigned long)-12; 48 * 49 * But what I want here is to print -12 instead of the unsigned version 50 * of that. 51 * 52 */ 53 if (!is_err_ptr(drange->min)) 54 return NULL; 55 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; 61 } 62 63 char *show_rl(struct range_list *list) 64 { 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; 73 74 full[0] = '\0'; 75 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; 83 } 84 prev_drange = tmp; 85 prev = p; 86 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)); 97 } 98 } END_FOR_EACH_PTR(tmp); 99 100 return alloc_sname(full); 101 } 102 103 void free_all_rl(void) 104 { 105 clear_rl_ptrlist_alloc(); 106 } 107 108 static int sval_too_big(struct symbol *type, sval_t sval) 109 { 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; 120 } 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; 126 } 127 if (sval.uvalue > sval_type_max(type).uvalue) 128 return 1; 129 return 0; 130 } 131 132 static int truncates_nicely(struct symbol *type, sval_t min, sval_t max) 133 { 134 unsigned long long mask; 135 int bits = type_bits(type); 136 137 if (type_is_fp(min.type) && !type_is_fp(type)) 138 return 0; 139 140 if (bits >= type_bits(min.type)) 141 return 0; 142 143 mask = -1ULL << bits; 144 return (min.uvalue & mask) == (max.uvalue & mask); 145 } 146 147 static void add_range_t(struct symbol *type, struct range_list **rl, sval_t min, sval_t max) 148 { 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; 153 } 154 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; 159 } 160 161 if (truncates_nicely(type, min, max)) { 162 add_range(rl, sval_cast(type, min), sval_cast(type, max)); 163 return; 164 } 165 166 /* 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 170 * 171 */ 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; 175 } 176 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; 183 } 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); 188 } 189 min = sval_cast(type, min); 190 add_range(rl, min, max); 191 } 192 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); 200 } 201 max = sval_cast(type, max); 202 add_range(rl, min, max); 203 } 204 205 add_range(rl, sval_cast(type, min), sval_cast(type, max)); 206 return; 207 } 208 209 static int str_to_comparison_arg_helper(const char *str, 210 struct expression *call, int *comparison, 211 struct expression **arg, const char **endp) 212 { 213 int param; 214 const char *c = str; 215 216 if (*c != '[') 217 return 0; 218 c++; 219 220 if (*c == '<') { 221 c++; 222 if (*c == '=') { 223 *comparison = SPECIAL_LTE; 224 c++; 225 } else { 226 *comparison = '<'; 227 } 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 = '>'; 239 } 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; 248 } 249 250 if (*c != '$') 251 return 0; 252 c++; 253 254 param = strtoll(c, (char **)&c, 10); 255 /* 256 * FIXME: handle parameter math. [==$1 + 100] 257 * 258 */ 259 if (*c == ' ') 260 return 0; 261 262 if (*c == ',' || *c == ']') 263 c++; /* skip the ']' character */ 264 if (endp) 265 *endp = (char *)c; 266 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; 275 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++; 284 } 285 return 1; 286 } 287 288 int str_to_comparison_arg(const char *str, struct expression *call, int *comparison, struct expression **arg) 289 { 290 while (1) { 291 if (!*str) 292 return 0; 293 if (*str == '[') 294 break; 295 str++; 296 } 297 return str_to_comparison_arg_helper(str, call, comparison, arg, NULL); 298 } 299 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) 301 { 302 struct expression *arg; 303 int comparison; 304 sval_t ret, tmp; 305 306 if (use_max) 307 ret = sval_type_max(type); 308 else 309 ret = sval_type_min(type); 310 311 if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp)) { 312 *sval = ret; 313 return 0; 314 } 315 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); 321 } 322 } 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); 328 } 329 } 330 331 *sval = ret; 332 return 1; 333 } 334 335 static sval_t add_one(sval_t sval) 336 { 337 sval.value++; 338 return sval; 339 } 340 341 static sval_t sub_one(sval_t sval) 342 { 343 sval.value--; 344 return sval; 345 } 346 347 void filter_by_comparison(struct range_list **rl, int comparison, struct range_list *right) 348 { 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; 354 355 if (comparison == UNKNOWN_COMPARISON) 356 return; 357 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; 363 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); 368 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; 398 } 399 400 *rl = cast_rl(rl_type(*rl), ret_rl); 401 } 402 403 static struct range_list *filter_by_comparison_call(const char *c, struct expression *call, const char **endp, struct range_list *start_rl) 404 { 405 struct symbol *type; 406 struct expression *arg; 407 struct range_list *casted_start, *right_orig; 408 int comparison; 409 410 /* For when we have a function that takes a function pointer. */ 411 if (!call || call->type != EXPR_CALL) 412 return start_rl; 413 414 if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp)) 415 return start_rl; 416 417 if (!get_implied_rl(arg, &right_orig)) 418 return start_rl; 419 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); 425 426 casted_start = cast_rl(type, start_rl); 427 right_orig = cast_rl(type, right_orig); 428 429 filter_by_comparison(&casted_start, comparison, right_orig); 430 return cast_rl(rl_type(start_rl), casted_start); 431 } 432 433 static sval_t parse_val(int use_max, struct expression *call, struct symbol *type, const char *c, const char **endp) 434 { 435 const char *start = c; 436 sval_t ret; 437 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)); 444 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)); 497 } 498 *endp = c; 499 return ret; 500 } 501 502 static const char *jump_to_call_math(const char *value) 503 { 504 const char *c = value; 505 506 while (*c && *c != '[') 507 c++; 508 509 if (!*c) 510 return NULL; 511 c++; 512 if (*c == '<' || *c == '=' || *c == '>' || *c == '!') 513 return NULL; 514 515 return c; 516 } 517 518 static struct range_list *get_param_return_rl(struct expression *call, const char *call_math) 519 { 520 struct expression *arg; 521 int param; 522 523 call_math += 3; 524 param = atoi(call_math); 525 526 arg = get_argument_from_call_expr(call->args, param); 527 if (!arg) 528 return NULL; 529 530 return db_return_vals_no_args(arg); 531 } 532 533 static void str_to_rl_helper(struct expression *call, struct symbol *type, const char *str, const char **endp, struct range_list **rl) 534 { 535 struct range_list *rl_tmp = NULL; 536 sval_t prev_min, min, max; 537 const char *c; 538 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; 550 } 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; 562 } 563 if (*c == ',') { 564 add_range_t(type, &rl_tmp, min, min); 565 c++; 566 continue; 567 } 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; 575 } 576 if (*c != '-') { 577 sm_debug("XXX: trouble parsing %s c = %s", str, c); 578 break; 579 } 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; 592 } 593 prev_min = max; 594 add_range_t(type, &rl_tmp, min, max); 595 if (*c == ')') 596 c++; 597 if (*c == ',') 598 c++; 599 } 600 601 *rl = rl_tmp; 602 *endp = c; 603 } 604 605 static void str_to_dinfo(struct expression *call, struct symbol *type, const char *value, struct data_info *dinfo) 606 { 607 struct range_list *math_rl; 608 const char *call_math; 609 const char *c; 610 struct range_list *rl = NULL; 611 612 if (!type) 613 type = &llong_ctype; 614 615 if (strcmp(value, "empty") == 0) 616 return; 617 618 if (strncmp(value, "[==$", 4) == 0) { 619 struct expression *arg; 620 int comparison; 621 622 if (!str_to_comparison_arg(value, call, &comparison, &arg)) 623 return; 624 if (!get_implied_rl(arg, &rl)) 625 return; 626 goto cast; 627 } 628 629 str_to_rl_helper(call, type, value, &c, &rl); 630 if (*c == '\0') 631 goto cast; 632 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; 639 } 640 if (call_math && parse_call_math_rl(call, call_math, &math_rl)) { 641 rl = rl_intersection(rl, math_rl); 642 goto cast; 643 } 644 645 /* 646 * For now if we already tried to handle the call math and couldn't 647 * figure it out then bail. 648 */ 649 if (jump_to_call_math(c) == c + 1) 650 goto cast; 651 652 rl = filter_by_comparison_call(c, call, &c, rl); 653 654 cast: 655 rl = cast_rl(type, rl); 656 dinfo->value_ranges = rl; 657 } 658 659 static int rl_is_sane(struct range_list *rl) 660 { 661 struct data_range *tmp; 662 struct symbol *type; 663 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); 673 674 return 1; 675 } 676 677 void str_to_rl(struct symbol *type, char *value, struct range_list **rl) 678 { 679 struct data_info dinfo = {}; 680 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; 685 } 686 687 void call_results_to_rl(struct expression *expr, struct symbol *type, const char *value, struct range_list **rl) 688 { 689 struct data_info dinfo = {}; 690 691 str_to_dinfo(strip_expr(expr), type, value, &dinfo); 692 *rl = dinfo.value_ranges; 693 } 694 695 int is_whole_rl(struct range_list *rl) 696 { 697 struct data_range *drange; 698 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; 705 } 706 707 int is_unknown_ptr(struct range_list *rl) 708 { 709 struct data_range *drange; 710 int cnt = 0; 711 712 if (is_whole_rl(rl)) 713 return 1; 714 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); 722 723 return 0; 724 } 725 726 int is_whole_rl_non_zero(struct range_list *rl) 727 { 728 struct data_range *drange; 729 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; 743 } 744 745 sval_t rl_min(struct range_list *rl) 746 { 747 struct data_range *drange; 748 sval_t ret; 749 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; 756 } 757 758 sval_t rl_max(struct range_list *rl) 759 { 760 struct data_range *drange; 761 sval_t ret; 762 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; 769 } 770 771 int rl_to_sval(struct range_list *rl, sval_t *sval) 772 { 773 sval_t min, max; 774 775 if (!rl) 776 return 0; 777 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; 784 } 785 786 struct symbol *rl_type(struct range_list *rl) 787 { 788 if (!rl) 789 return NULL; 790 return rl_min(rl).type; 791 } 792 793 static struct data_range *alloc_range_helper_sval(sval_t min, sval_t max, int perm) 794 { 795 struct data_range *ret; 796 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; 804 } 805 806 struct data_range *alloc_range(sval_t min, sval_t max) 807 { 808 return alloc_range_helper_sval(min, max, 0); 809 } 810 811 struct data_range *alloc_range_perm(sval_t min, sval_t max) 812 { 813 return alloc_range_helper_sval(min, max, 1); 814 } 815 816 struct range_list *alloc_rl(sval_t min, sval_t max) 817 { 818 struct range_list *rl = NULL; 819 820 if (sval_cmp(min, max) > 0) 821 return alloc_whole_rl(min.type); 822 823 add_range(&rl, min, max); 824 return rl; 825 } 826 827 struct range_list *alloc_whole_rl(struct symbol *type) 828 { 829 if (!type || type_positive_bits(type) < 0) 830 type = &llong_ctype; 831 if (type->type == SYM_ARRAY) 832 type = &ptr_ctype; 833 834 return alloc_rl(sval_type_min(type), sval_type_max(type)); 835 } 836 837 static bool collapse_pointer_rl(struct range_list **rl, sval_t min, sval_t max) 838 { 839 struct range_list *new_rl = NULL; 840 struct data_range *tmp; 841 static bool recurse; 842 bool ret = false; 843 int cnt = 0; 844 845 /* 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. 851 * 852 */ 853 854 if (recurse) 855 return false; 856 recurse = true; 857 if (!type_is_ptr(min.type)) 858 goto out; 859 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; 868 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); 876 877 add_range(&new_rl, min, max); 878 879 *rl = new_rl; 880 ret = true; 881 out: 882 recurse = false; 883 return ret; 884 } 885 886 extern int rl_ptrlist_hack; 887 void add_range(struct range_list **list, sval_t min, sval_t max) 888 { 889 struct data_range *tmp; 890 struct data_range *new = NULL; 891 int check_next = 0; 892 893 /* 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. 898 * 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. 902 * 903 * But this hack works for both cases, I think. We cast it to pointers 904 * or we use the bigger size. 905 * 906 */ 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); 918 } 919 } 920 921 if (sval_cmp(min, max) > 0) { 922 min = sval_type_min(min.type); 923 max = sval_type_max(min.type); 924 } 925 926 if (collapse_pointer_rl(list, min, max)) 927 return; 928 929 /* 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. 933 */ 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; 943 } 944 945 /* Doesn't overlap with the next one. */ 946 if (sval_cmp(max, tmp->min) < 0) 947 return; 948 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; 959 } 960 } 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; 966 } 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; 971 } 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; 982 } 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; 991 } 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; 998 } 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); 1004 1005 rl_ptrlist_hack = 1; 1006 add_ptr_list(list, new); 1007 rl_ptrlist_hack = 0; 1008 } 1009 1010 struct range_list *clone_rl(struct range_list *list) 1011 { 1012 struct data_range *tmp; 1013 struct range_list *ret = NULL; 1014 1015 FOR_EACH_PTR(list, tmp) { 1016 add_ptr_list(&ret, tmp); 1017 } END_FOR_EACH_PTR(tmp); 1018 return ret; 1019 } 1020 1021 struct range_list *clone_rl_permanent(struct range_list *list) 1022 { 1023 struct data_range *tmp; 1024 struct data_range *new; 1025 struct range_list *ret = NULL; 1026 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; 1032 } 1033 1034 struct range_list *rl_union(struct range_list *one, struct range_list *two) 1035 { 1036 struct data_range *tmp; 1037 struct range_list *ret = NULL; 1038 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; 1046 } 1047 1048 struct range_list *remove_range(struct range_list *list, sval_t min, sval_t max) 1049 { 1050 struct data_range *tmp; 1051 struct range_list *ret = NULL; 1052 1053 if (!list) 1054 return NULL; 1055 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; 1062 } 1063 1064 FOR_EACH_PTR(list, tmp) { 1065 if (sval_cmp(tmp->max, min) < 0) { 1066 add_range(&ret, tmp->min, tmp->max); 1067 continue; 1068 } 1069 if (sval_cmp(tmp->min, max) > 0) { 1070 add_range(&ret, tmp->min, tmp->max); 1071 continue; 1072 } 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); 1086 } 1087 } END_FOR_EACH_PTR(tmp); 1088 return ret; 1089 } 1090 1091 int ranges_equiv(struct data_range *one, struct data_range *two) 1092 { 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; 1102 } 1103 1104 int rl_equiv(struct range_list *one, struct range_list *two) 1105 { 1106 struct data_range *one_range; 1107 struct data_range *two_range; 1108 1109 if (one == two) 1110 return 1; 1111 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); 1121 } 1122 FINISH_PTR_LIST(two_range); 1123 FINISH_PTR_LIST(one_range); 1124 1125 return 1; 1126 } 1127 1128 int true_comparison_range(struct data_range *left, int comparison, struct data_range *right) 1129 { 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; 1168 } 1169 return 0; 1170 } 1171 1172 int true_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left) 1173 { 1174 if (left) 1175 return true_comparison_range(var, comparison, val); 1176 else 1177 return true_comparison_range(val, comparison, var); 1178 } 1179 1180 static int false_comparison_range_sval(struct data_range *left, int comparison, struct data_range *right) 1181 { 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; 1220 } 1221 return 0; 1222 } 1223 1224 int false_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left) 1225 { 1226 if (left) 1227 return false_comparison_range_sval(var, comparison, val); 1228 else 1229 return false_comparison_range_sval(val, comparison, var); 1230 } 1231 1232 int possibly_true(struct expression *left, int comparison, struct expression *right) 1233 { 1234 struct range_list *rl_left, *rl_right; 1235 struct data_range *tmp_left, *tmp_right; 1236 struct symbol *type; 1237 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; 1244 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; 1250 1251 rl_left = cast_rl(type, rl_left); 1252 rl_right = cast_rl(type, rl_right); 1253 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; 1261 } 1262 1263 int possibly_false(struct expression *left, int comparison, struct expression *right) 1264 { 1265 struct range_list *rl_left, *rl_right; 1266 struct data_range *tmp_left, *tmp_right; 1267 struct symbol *type; 1268 1269 if (!get_implied_rl(left, &rl_left)) 1270 return 1; 1271 if (!get_implied_rl(right, &rl_right)) 1272 return 1; 1273 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; 1279 1280 rl_left = cast_rl(type, rl_left); 1281 rl_right = cast_rl(type, rl_right); 1282 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; 1290 } 1291 1292 int possibly_true_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges) 1293 { 1294 struct data_range *left_tmp, *right_tmp; 1295 struct symbol *type; 1296 1297 if (!left_ranges || !right_ranges || comparison == UNKNOWN_COMPARISON) 1298 return 1; 1299 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; 1305 1306 left_ranges = cast_rl(type, left_ranges); 1307 right_ranges = cast_rl(type, right_ranges); 1308 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; 1316 } 1317 1318 int possibly_false_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges) 1319 { 1320 struct data_range *left_tmp, *right_tmp; 1321 struct symbol *type; 1322 1323 if (!left_ranges || !right_ranges || comparison == UNKNOWN_COMPARISON) 1324 return 1; 1325 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; 1331 1332 left_ranges = cast_rl(type, left_ranges); 1333 right_ranges = cast_rl(type, right_ranges); 1334 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; 1342 } 1343 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) 1346 { 1347 if (left) 1348 return possibly_true_rl(a, comparison, b); 1349 else 1350 return possibly_true_rl(b, comparison, a); 1351 } 1352 1353 int possibly_false_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left) 1354 { 1355 if (left) 1356 return possibly_false_rl(a, comparison, b); 1357 else 1358 return possibly_false_rl(b, comparison, a); 1359 } 1360 1361 int rl_has_sval(struct range_list *rl, sval_t sval) 1362 { 1363 struct data_range *tmp; 1364 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; 1371 } 1372 1373 void tack_on(struct range_list **list, struct data_range *drange) 1374 { 1375 add_ptr_list(list, drange); 1376 } 1377 1378 void push_rl(struct range_list_stack **rl_stack, struct range_list *rl) 1379 { 1380 add_ptr_list(rl_stack, rl); 1381 } 1382 1383 struct range_list *pop_rl(struct range_list_stack **rl_stack) 1384 { 1385 struct range_list *rl; 1386 1387 rl = last_ptr_list((struct ptr_list *)*rl_stack); 1388 delete_ptr_list_last((struct ptr_list **)rl_stack); 1389 return rl; 1390 } 1391 1392 struct range_list *top_rl(struct range_list_stack *rl_stack) 1393 { 1394 struct range_list *rl; 1395 1396 rl = last_ptr_list((struct ptr_list *)rl_stack); 1397 return rl; 1398 } 1399 1400 void filter_top_rl(struct range_list_stack **rl_stack, struct range_list *filter) 1401 { 1402 struct range_list *rl; 1403 1404 rl = pop_rl(rl_stack); 1405 rl = rl_filter(rl, filter); 1406 push_rl(rl_stack, rl); 1407 } 1408 1409 struct range_list *rl_truncate_cast(struct symbol *type, struct range_list *rl) 1410 { 1411 struct data_range *tmp; 1412 struct range_list *ret = NULL; 1413 sval_t min, max; 1414 1415 if (!rl) 1416 return NULL; 1417 1418 if (!type || type == rl_type(rl)) 1419 return rl; 1420 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); 1427 } 1428 if (sval_cmp(min, max) > 0) { 1429 min = sval_cast(type, min); 1430 max = sval_cast(type, max); 1431 } 1432 add_range_t(type, &ret, min, max); 1433 } END_FOR_EACH_PTR(tmp); 1434 1435 return ret; 1436 } 1437 1438 int rl_fits_in_type(struct range_list *rl, struct symbol *type) 1439 { 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; 1448 } 1449 1450 static int rl_type_consistent(struct range_list *rl) 1451 { 1452 struct data_range *tmp; 1453 struct symbol *type; 1454 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; 1461 } 1462 1463 static struct range_list *cast_to_bool(struct range_list *rl) 1464 { 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 }; 1471 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); 1485 1486 if (!has_zero) 1487 min.value = 1; 1488 if (has_one) 1489 max.value = 1; 1490 1491 add_range(&ret, min, max); 1492 return ret; 1493 } 1494 1495 struct range_list *cast_rl(struct symbol *type, struct range_list *rl) 1496 { 1497 struct data_range *tmp; 1498 struct range_list *ret = NULL; 1499 1500 if (!rl) 1501 return NULL; 1502 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; 1509 1510 if (type == &bool_ctype) 1511 return cast_to_bool(rl); 1512 1513 FOR_EACH_PTR(rl, tmp) { 1514 add_range_t(type, &ret, tmp->min, tmp->max); 1515 } END_FOR_EACH_PTR(tmp); 1516 1517 if (!ret) 1518 return alloc_whole_rl(type); 1519 1520 return ret; 1521 } 1522 1523 struct range_list *rl_filter(struct range_list *rl, struct range_list *filter) 1524 { 1525 struct data_range *tmp; 1526 1527 FOR_EACH_PTR(filter, tmp) { 1528 rl = remove_range(rl, tmp->min, tmp->max); 1529 } END_FOR_EACH_PTR(tmp); 1530 1531 return rl; 1532 } 1533 1534 struct range_list *do_intersection(struct range_list *one_rl, struct range_list *two_rl) 1535 { 1536 struct data_range *one, *two; 1537 struct range_list *ret = NULL; 1538 1539 1540 PREPARE_PTR_LIST(one_rl, one); 1541 PREPARE_PTR_LIST(two_rl, two); 1542 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; 1549 } 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; 1554 } 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; 1559 } 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; 1564 } 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; 1569 } 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; 1573 } 1574 NEXT_PTR_LIST(two); 1575 } 1576 1577 FINISH_PTR_LIST(two); 1578 FINISH_PTR_LIST(one); 1579 1580 return ret; 1581 } 1582 1583 struct range_list *rl_intersection(struct range_list *one, struct range_list *two) 1584 { 1585 struct range_list *ret; 1586 struct symbol *ret_type; 1587 struct symbol *small_type; 1588 struct symbol *large_type; 1589 1590 if (!one || !two) 1591 return NULL; 1592 1593 ret_type = rl_type(one); 1594 small_type = rl_type(one); 1595 large_type = rl_type(two); 1596 1597 if (type_bits(rl_type(two)) < type_bits(small_type)) { 1598 small_type = rl_type(two); 1599 large_type = rl_type(one); 1600 } 1601 1602 one = cast_rl(large_type, one); 1603 two = cast_rl(large_type, two); 1604 1605 ret = do_intersection(one, two); 1606 return cast_rl(ret_type, ret); 1607 } 1608 1609 static struct range_list *handle_mod_rl(struct range_list *left, struct range_list *right) 1610 { 1611 sval_t zero; 1612 sval_t max; 1613 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); 1627 } 1628 1629 static struct range_list *get_neg_rl(struct range_list *rl) 1630 { 1631 struct data_range *tmp; 1632 struct data_range *new; 1633 struct range_list *ret = NULL; 1634 1635 if (!rl) 1636 return NULL; 1637 if (sval_is_positive(rl_min(rl))) 1638 return NULL; 1639 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; 1648 } 1649 add_range(&ret, tmp->min, tmp->max); 1650 } END_FOR_EACH_PTR(tmp); 1651 1652 return ret; 1653 } 1654 1655 static struct range_list *get_pos_rl(struct range_list *rl) 1656 { 1657 struct data_range *tmp; 1658 struct data_range *new; 1659 struct range_list *ret = NULL; 1660 1661 if (!rl) 1662 return NULL; 1663 if (sval_is_negative(rl_max(rl))) 1664 return NULL; 1665 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; 1672 } 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); 1677 1678 return ret; 1679 } 1680 1681 static struct range_list *divide_rl_helper(struct range_list *left, struct range_list *right) 1682 { 1683 sval_t right_min, right_max; 1684 sval_t min, max; 1685 1686 if (!left || !right) 1687 return NULL; 1688 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; 1698 1699 max = sval_binop(rl_max(left), '/', right_min); 1700 min = sval_binop(rl_min(left), '/', right_max); 1701 1702 return alloc_rl(min, max); 1703 } 1704 1705 static struct range_list *handle_divide_rl(struct range_list *left, struct range_list *right) 1706 { 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; 1710 1711 if (is_whole_rl(right)) 1712 return NULL; 1713 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); 1718 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); 1723 1724 ret = rl_union(neg_neg, neg_pos); 1725 ret = rl_union(ret, pos_neg); 1726 return rl_union(ret, pos_pos); 1727 } 1728 1729 static struct range_list *ptr_add_mult(struct range_list *left, int op, struct range_list *right) 1730 { 1731 struct range_list *ret; 1732 sval_t l_sval, r_sval, res; 1733 1734 /* 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. 1738 * 1739 * Really this function is quite bogus... 1740 */ 1741 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); 1745 } 1746 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); 1750 } 1751 1752 return alloc_whole_rl(rl_type(left)); 1753 } 1754 1755 static struct range_list *handle_add_mult_rl(struct range_list *left, int op, struct range_list *right) 1756 { 1757 sval_t min, max; 1758 1759 if (type_is_ptr(rl_type(left)) || type_is_ptr(rl_type(right))) 1760 return ptr_add_mult(left, op, right); 1761 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)); 1765 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)); 1769 1770 return alloc_rl(min, max); 1771 } 1772 1773 static struct range_list *handle_sub_rl(struct range_list *left_orig, struct range_list *right_orig) 1774 { 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; 1780 1781 /* TODO: These things should totally be using dranges where possible */ 1782 1783 if (!left_orig || !right_orig) 1784 return NULL; 1785 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); 1791 1792 left_rl = cast_rl(type, left_orig); 1793 right_rl = cast_rl(type, right_orig); 1794 1795 max = rl_max(left_rl); 1796 min = sval_type_min(type); 1797 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; 1804 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; 1813 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); 1818 } 1819 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; 1824 } 1825 1826 if (sval_is_min(min) && sval_is_max(max)) 1827 return NULL; 1828 1829 return alloc_rl(min, max); 1830 } 1831 1832 static unsigned long long rl_bits_always_set(struct range_list *rl) 1833 { 1834 return sval_fls_mask(rl_min(rl)); 1835 } 1836 1837 static unsigned long long rl_bits_maybe_set(struct range_list *rl) 1838 { 1839 return sval_fls_mask(rl_max(rl)); 1840 } 1841 1842 static struct range_list *handle_OR_rl(struct range_list *left, struct range_list *right) 1843 { 1844 unsigned long long left_min, left_max, right_min, right_max; 1845 sval_t min, max; 1846 sval_t sval; 1847 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); 1851 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); 1856 1857 min.type = max.type = &ullong_ctype; 1858 min.uvalue = left_min | right_min; 1859 max.uvalue = left_max | right_max; 1860 1861 return cast_rl(rl_type(left), alloc_rl(min, max)); 1862 } 1863 1864 static struct range_list *handle_XOR_rl(struct range_list *left, struct range_list *right) 1865 { 1866 unsigned long long left_set, left_maybe; 1867 unsigned long long right_set, right_maybe; 1868 sval_t zero, max; 1869 1870 left_set = rl_bits_always_set(left); 1871 left_maybe = rl_bits_maybe_set(left); 1872 1873 right_set = rl_bits_always_set(right); 1874 right_maybe = rl_bits_maybe_set(right); 1875 1876 zero = max = rl_min(left); 1877 zero.uvalue = 0; 1878 max.uvalue = fls_mask((left_maybe | right_maybe) ^ (left_set & right_set)); 1879 1880 return cast_rl(rl_type(left), alloc_rl(zero, max)); 1881 } 1882 1883 static sval_t sval_lowest_set_bit(sval_t sval) 1884 { 1885 sval_t ret = { .type = sval.type }; 1886 int i; 1887 1888 for (i = 0; i < 64; i++) { 1889 if (sval.uvalue & 1ULL << i) { 1890 ret.uvalue = (1ULL << i); 1891 return ret; 1892 } 1893 } 1894 return ret; 1895 } 1896 1897 static struct range_list *handle_AND_rl(struct range_list *left, struct range_list *right) 1898 { 1899 struct bit_info *one, *two; 1900 struct range_list *rl; 1901 sval_t min, max, zero; 1902 unsigned long long bits; 1903 1904 one = rl_to_binfo(left); 1905 two = rl_to_binfo(right); 1906 bits = one->possible & two->possible; 1907 1908 max = rl_max(left); 1909 max.uvalue = bits; 1910 min = sval_lowest_set_bit(max); 1911 1912 rl = alloc_rl(min, max); 1913 1914 zero = rl_min(rl); 1915 zero.value = 0; 1916 add_range(&rl, zero, zero); 1917 1918 return rl; 1919 } 1920 1921 static struct range_list *handle_lshift(struct range_list *left_orig, struct range_list *right_orig) 1922 { 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; 1929 1930 if (!rl_to_sval(right_orig, &shift) || sval_is_negative(shift)) 1931 return NULL; 1932 if (shift.value == 0) 1933 return left_orig; 1934 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; 1942 1943 FOR_EACH_PTR(left, tmp) { 1944 min = tmp->min; 1945 max = tmp->max; 1946 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); 1957 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); 1963 1964 return ret; 1965 } 1966 1967 static struct range_list *handle_rshift(struct range_list *left_orig, struct range_list *right_orig) 1968 { 1969 struct data_range *tmp; 1970 struct range_list *ret = NULL; 1971 sval_t shift, min, max; 1972 1973 if (!rl_to_sval(right_orig, &shift) || sval_is_negative(shift)) 1974 return NULL; 1975 if (shift.value == 0) 1976 return left_orig; 1977 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); 1983 1984 return ret; 1985 } 1986 1987 struct range_list *rl_binop(struct range_list *left, int op, struct range_list *right) 1988 { 1989 struct symbol *cast_type; 1990 sval_t left_sval, right_sval; 1991 struct range_list *ret = NULL; 1992 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; 1998 1999 left = cast_rl(cast_type, left); 2000 right = cast_rl(cast_type, right); 2001 2002 if (!left && !right) 2003 return NULL; 2004 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); 2008 } 2009 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); 2037 } 2038 2039 return ret; 2040 } 2041 2042 void free_data_info_allocs(void) 2043 { 2044 struct allocator_struct *desc = &data_info_allocator; 2045 struct allocation_blob *blob = desc->blobs; 2046 2047 free_all_rl(); 2048 clear_math_cache(); 2049 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; 2059 } 2060 clear_data_range_alloc(); 2061 } 2062 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) 2066 { 2067 struct range_list *left_true, *left_false; 2068 struct range_list *right_true, *right_false; 2069 sval_t min, max; 2070 2071 min = sval_type_min(rl_type(left_orig)); 2072 max = sval_type_max(rl_type(left_orig)); 2073 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); 2078 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))); 2085 } 2086 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)); 2096 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); 2100 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); 2109 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); 2120 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)); 2124 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); 2135 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); 2143 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); 2151 } 2152 2153 if (left_true_rl) { 2154 *left_true_rl = left_true; 2155 *left_false_rl = left_false; 2156 } 2157 if (right_true_rl) { 2158 *right_true_rl = right_true; 2159 *right_false_rl = right_false; 2160 } 2161 }