Print this page
11972 resync smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_ranges.c
          +++ new/usr/src/tools/smatch/src/smatch_ranges.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19  #include "smatch.h"
  20   20  #include "smatch_extra.h"
  21   21  #include "smatch_slist.h"
  22   22  
  23   23  ALLOCATOR(data_info, "smatch extra data");
  24   24  ALLOCATOR(data_range, "data range");
  25   25  __DO_ALLOCATOR(struct data_range, sizeof(struct data_range), __alignof__(struct data_range),
  26   26                           "permanent ranges", perm_data_range);
  27   27  __DECLARE_ALLOCATOR(struct ptr_list, rl_ptrlist);
  28   28  
  29      -static bool is_err_ptr(sval_t sval)
       29 +bool is_err_ptr(sval_t sval)
  30   30  {
  31   31          if (option_project != PROJ_KERNEL)
  32   32                  return false;
  33   33          if (!type_is_ptr(sval.type))
  34   34                  return false;
  35   35          if (sval.uvalue < -4095ULL)
  36   36                  return false;
  37   37          return true;
  38   38  }
  39   39  
↓ open down ↓ 202 lines elided ↑ open up ↑
 242  242                  *comparison = SPECIAL_EQUAL;
 243  243          } else {
 244  244                  return 0;
 245  245          }
 246  246  
 247  247          if (*c != '$')
 248  248                  return 0;
 249  249          c++;
 250  250  
 251  251          param = strtoll(c, (char **)&c, 10);
      252 +        /*
      253 +         * FIXME: handle parameter math.  [==$1 + 100]
      254 +         *
      255 +         */
      256 +        if (*c == ' ')
      257 +                return 0;
      258 +
 252  259          if (*c == ',' || *c == ']')
 253  260                  c++; /* skip the ']' character */
 254  261          if (endp)
 255  262                  *endp = (char *)c;
 256  263  
 257  264          if (!call)
 258  265                  return 0;
 259  266          *arg = get_argument_from_call_expr(call->args, param);
 260  267          if (!*arg)
 261  268                  return 0;
↓ open down ↓ 73 lines elided ↑ open up ↑
 335  342  }
 336  343  
 337  344  void filter_by_comparison(struct range_list **rl, int comparison, struct range_list *right)
 338  345  {
 339  346          struct range_list *left_orig = *rl;
 340  347          struct range_list *right_orig = right;
 341  348          struct range_list *ret_rl = *rl;
 342  349          struct symbol *cast_type;
 343  350          sval_t min, max;
 344  351  
      352 +        if (comparison == UNKNOWN_COMPARISON)
      353 +                return;
      354 +
 345  355          cast_type = rl_type(left_orig);
 346  356          if (sval_type_max(rl_type(left_orig)).uvalue < sval_type_max(rl_type(right_orig)).uvalue)
 347  357                  cast_type = rl_type(right_orig);
 348  358          if (sval_type_max(cast_type).uvalue < INT_MAX)
 349  359                  cast_type = &int_ctype;
 350  360  
 351  361          min = sval_type_min(cast_type);
 352  362          max = sval_type_max(cast_type);
 353  363          left_orig = cast_rl(cast_type, left_orig);
 354  364          right_orig = cast_rl(cast_type, right_orig);
↓ open down ↓ 32 lines elided ↑ open up ↑
 387  397          *rl = cast_rl(rl_type(*rl), ret_rl);
 388  398  }
 389  399  
 390  400  static struct range_list *filter_by_comparison_call(const char *c, struct expression *call, const char **endp, struct range_list *start_rl)
 391  401  {
 392  402          struct symbol *type;
 393  403          struct expression *arg;
 394  404          struct range_list *casted_start, *right_orig;
 395  405          int comparison;
 396  406  
      407 +        /* For when we have a function that takes a function pointer. */
      408 +        if (!call || call->type != EXPR_CALL)
      409 +                return start_rl;
      410 +
 397  411          if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp))
 398  412                  return start_rl;
 399  413  
 400  414          if (!get_implied_rl(arg, &right_orig))
 401  415                  return start_rl;
 402  416  
 403  417          type = &int_ctype;
 404  418          if (type_positive_bits(rl_type(start_rl)) > type_positive_bits(type))
 405  419                  type = rl_type(start_rl);
 406  420          if (type_positive_bits(rl_type(right_orig)) > type_positive_bits(type))
↓ open down ↓ 77 lines elided ↑ open up ↑
 484  498  
 485  499          if (!*c)
 486  500                  return NULL;
 487  501          c++;
 488  502          if (*c == '<' || *c == '=' || *c == '>' || *c == '!')
 489  503                  return NULL;
 490  504  
 491  505          return c;
 492  506  }
 493  507  
      508 +static struct range_list *get_param_return_rl(struct expression *call, const char *call_math)
      509 +{
      510 +        struct expression *arg;
      511 +        int param;
      512 +
      513 +        call_math += 3;
      514 +        param = atoi(call_math);
      515 +
      516 +        arg = get_argument_from_call_expr(call->args, param);
      517 +        if (!arg)
      518 +                return NULL;
      519 +
      520 +        return db_return_vals_no_args(arg);
      521 +}
      522 +
 494  523  static void str_to_rl_helper(struct expression *call, struct symbol *type, const char *str, const char **endp, struct range_list **rl)
 495  524  {
 496  525          struct range_list *rl_tmp = NULL;
 497  526          sval_t prev_min, min, max;
 498  527          const char *c;
 499  528  
 500  529          prev_min = sval_type_min(type);
 501  530          min = sval_type_min(type);
 502  531          max = sval_type_max(type);
 503  532          c = str;
↓ open down ↓ 81 lines elided ↑ open up ↑
 585  614                  if (!get_implied_rl(arg, &rl))
 586  615                          return;
 587  616                  goto cast;
 588  617          }
 589  618  
 590  619          str_to_rl_helper(call, type, value, &c, &rl);
 591  620          if (*c == '\0')
 592  621                  goto cast;
 593  622  
 594  623          call_math = jump_to_call_math(value);
      624 +        if (call_math && call_math[0] == 'r') {
      625 +                math_rl = get_param_return_rl(call, call_math);
      626 +                if (math_rl)
      627 +                        rl = rl_intersection(rl, math_rl);
      628 +                goto cast;
      629 +        }
 595  630          if (call_math && parse_call_math_rl(call, call_math, &math_rl)) {
 596  631                  rl = rl_intersection(rl, math_rl);
 597  632                  goto cast;
 598  633          }
 599  634  
 600  635          /*
 601  636           * For now if we already tried to handle the call math and couldn't
 602  637           * figure it out then bail.
 603  638           */
 604  639          if (jump_to_call_math(c) == c + 1)
↓ open down ↓ 39 lines elided ↑ open up ↑
 644  679          struct data_info dinfo = {};
 645  680  
 646  681          str_to_dinfo(strip_expr(expr), type, value, &dinfo);
 647  682          *rl = dinfo.value_ranges;
 648  683  }
 649  684  
 650  685  int is_whole_rl(struct range_list *rl)
 651  686  {
 652  687          struct data_range *drange;
 653  688  
 654      -        if (ptr_list_empty(rl))
      689 +        if (ptr_list_empty((struct ptr_list *)rl))
 655  690                  return 0;
 656  691          drange = first_ptr_list((struct ptr_list *)rl);
 657  692          if (sval_is_min(drange->min) && sval_is_max(drange->max))
 658  693                  return 1;
 659  694          return 0;
 660  695  }
 661  696  
 662  697  int is_unknown_ptr(struct range_list *rl)
 663  698  {
 664  699          struct data_range *drange;
↓ open down ↓ 10 lines elided ↑ open up ↑
 675  710                          return 1;
 676  711          } END_FOR_EACH_PTR(drange);
 677  712  
 678  713          return 0;
 679  714  }
 680  715  
 681  716  int is_whole_rl_non_zero(struct range_list *rl)
 682  717  {
 683  718          struct data_range *drange;
 684  719  
 685      -        if (ptr_list_empty(rl))
      720 +        if (ptr_list_empty((struct ptr_list *)rl))
 686  721                  return 0;
 687  722          drange = first_ptr_list((struct ptr_list *)rl);
 688  723          if (sval_unsigned(drange->min) &&
 689  724              drange->min.value == 1 &&
 690  725              sval_is_max(drange->max))
 691  726                  return 1;
 692  727          if (!sval_is_min(drange->min) || drange->max.value != -1)
 693  728                  return 0;
 694  729          drange = last_ptr_list((struct ptr_list *)rl);
 695  730          if (drange->min.value != 1 || !sval_is_max(drange->max))
↓ open down ↓ 1 lines elided ↑ open up ↑
 697  732          return 1;
 698  733  }
 699  734  
 700  735  sval_t rl_min(struct range_list *rl)
 701  736  {
 702  737          struct data_range *drange;
 703  738          sval_t ret;
 704  739  
 705  740          ret.type = &llong_ctype;
 706  741          ret.value = LLONG_MIN;
 707      -        if (ptr_list_empty(rl))
      742 +        if (ptr_list_empty((struct ptr_list *)rl))
 708  743                  return ret;
 709  744          drange = first_ptr_list((struct ptr_list *)rl);
 710  745          return drange->min;
 711  746  }
 712  747  
 713  748  sval_t rl_max(struct range_list *rl)
 714  749  {
 715  750          struct data_range *drange;
 716  751          sval_t ret;
 717  752  
 718  753          ret.type = &llong_ctype;
 719  754          ret.value = LLONG_MAX;
 720      -        if (ptr_list_empty(rl))
      755 +        if (ptr_list_empty((struct ptr_list *)rl))
 721  756                  return ret;
 722  757          drange = last_ptr_list((struct ptr_list *)rl);
 723  758          return drange->max;
 724  759  }
 725  760  
 726  761  int rl_to_sval(struct range_list *rl, sval_t *sval)
 727  762  {
 728  763          sval_t min, max;
 729  764  
 730  765          if (!rl)
↓ open down ↓ 452 lines elided ↑ open up ↑
1183 1218          else
1184 1219                  return false_comparison_range_sval(val, comparison, var);
1185 1220  }
1186 1221  
1187 1222  int possibly_true(struct expression *left, int comparison, struct expression *right)
1188 1223  {
1189 1224          struct range_list *rl_left, *rl_right;
1190 1225          struct data_range *tmp_left, *tmp_right;
1191 1226          struct symbol *type;
1192 1227  
     1228 +        if (comparison == UNKNOWN_COMPARISON)
     1229 +                return 1;
1193 1230          if (!get_implied_rl(left, &rl_left))
1194 1231                  return 1;
1195 1232          if (!get_implied_rl(right, &rl_right))
1196 1233                  return 1;
1197 1234  
1198 1235          type = rl_type(rl_left);
1199 1236          if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
1200 1237                  type = rl_type(rl_right);
1201 1238          if (type_positive_bits(type) < 31)
1202 1239                  type = &int_ctype;
↓ open down ↓ 37 lines elided ↑ open up ↑
1240 1277                  } END_FOR_EACH_PTR(tmp_right);
1241 1278          } END_FOR_EACH_PTR(tmp_left);
1242 1279          return 0;
1243 1280  }
1244 1281  
1245 1282  int possibly_true_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
1246 1283  {
1247 1284          struct data_range *left_tmp, *right_tmp;
1248 1285          struct symbol *type;
1249 1286  
1250      -        if (!left_ranges || !right_ranges)
     1287 +        if (!left_ranges || !right_ranges || comparison == UNKNOWN_COMPARISON)
1251 1288                  return 1;
1252 1289  
1253 1290          type = rl_type(left_ranges);
1254 1291          if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
1255 1292                  type = rl_type(right_ranges);
1256 1293          if (type_positive_bits(type) < 31)
1257 1294                  type = &int_ctype;
1258 1295  
1259 1296          left_ranges = cast_rl(type, left_ranges);
1260 1297          right_ranges = cast_rl(type, right_ranges);
↓ open down ↓ 5 lines elided ↑ open up ↑
1266 1303                  } END_FOR_EACH_PTR(right_tmp);
1267 1304          } END_FOR_EACH_PTR(left_tmp);
1268 1305          return 0;
1269 1306  }
1270 1307  
1271 1308  int possibly_false_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
1272 1309  {
1273 1310          struct data_range *left_tmp, *right_tmp;
1274 1311          struct symbol *type;
1275 1312  
1276      -        if (!left_ranges || !right_ranges)
     1313 +        if (!left_ranges || !right_ranges || comparison == UNKNOWN_COMPARISON)
1277 1314                  return 1;
1278 1315  
1279 1316          type = rl_type(left_ranges);
1280 1317          if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
1281 1318                  type = rl_type(right_ranges);
1282 1319          if (type_positive_bits(type) < 31)
1283 1320                  type = &int_ctype;
1284 1321  
1285 1322          left_ranges = cast_rl(type, left_ranges);
1286 1323          right_ranges = cast_rl(type, right_ranges);
↓ open down ↓ 553 lines elided ↑ open up ↑
1840 1877  
1841 1878          for (i = 0; i < 64; i++) {
1842 1879                  if (sval.uvalue & 1ULL << i) {
1843 1880                          ret.uvalue = (1ULL << i);
1844 1881                          return ret;
1845 1882                  }
1846 1883          }
1847 1884          return ret;
1848 1885  }
1849 1886  
1850      -static struct range_list *handle_AND_rl_sval(struct range_list *rl, sval_t sval)
1851      -{
1852      -        struct range_list *known_rl;
1853      -        sval_t zero = { 0 };
1854      -        sval_t min;
1855      -
1856      -        zero.type = sval.type;
1857      -        zero.value = 0;
1858      -
1859      -        if (sm_fls64(rl_max(rl).uvalue) < find_first_zero_bit(sval.uvalue) &&
1860      -            sm_fls64(rl_min(rl).uvalue) < find_first_zero_bit(sval.uvalue))
1861      -                return rl;
1862      -
1863      -        min = sval_lowest_set_bit(sval);
1864      -
1865      -        if (min.value != 0) {
1866      -                sval_t max, mod;
1867      -
1868      -                max = rl_max(rl);
1869      -                mod = sval_binop(max, '%', min);
1870      -                if (mod.value) {
1871      -                        max = sval_binop(max, '-', mod);
1872      -                        max.value++;
1873      -                        if (max.value > 0 && sval_cmp(max, rl_max(rl)) < 0)
1874      -                                rl = remove_range(rl, max, rl_max(rl));
1875      -                }
1876      -        }
1877      -
1878      -        known_rl = alloc_rl(min, sval);
1879      -
1880      -        rl = rl_intersection(rl, known_rl);
1881      -        zero = rl_min(rl);
1882      -        zero.value = 0;
1883      -        add_range(&rl, zero, zero);
1884      -
1885      -        return rl;
1886      -}
1887      -
1888      -static struct range_list *fudge_AND_rl(struct range_list *rl)
1889      -{
1890      -        struct range_list *ret;
1891      -        sval_t min;
1892      -
1893      -        min = sval_lowest_set_bit(rl_min(rl));
1894      -        ret = clone_rl(rl);
1895      -        add_range(&ret, min, rl_min(rl));
1896      -
1897      -        return ret;
1898      -}
1899      -
1900 1887  static struct range_list *handle_AND_rl(struct range_list *left, struct range_list *right)
1901 1888  {
1902      -        sval_t sval, zero;
     1889 +        struct bit_info *one, *two;
1903 1890          struct range_list *rl;
     1891 +        sval_t min, max, zero;
     1892 +        unsigned long long bits;
1904 1893  
1905      -        if (rl_to_sval(left, &sval))
1906      -                return handle_AND_rl_sval(right, sval);
1907      -        if (rl_to_sval(right, &sval))
1908      -                return handle_AND_rl_sval(left, sval);
     1894 +        one = rl_to_binfo(left);
     1895 +        two = rl_to_binfo(right);
     1896 +        bits = one->possible & two->possible;
1909 1897  
1910      -        left = fudge_AND_rl(left);
1911      -        right = fudge_AND_rl(right);
     1898 +        max = rl_max(left);
     1899 +        max.uvalue = bits;
     1900 +        min = sval_lowest_set_bit(max);
1912 1901  
1913      -        rl = rl_intersection(left, right);
     1902 +        rl = alloc_rl(min, max);
     1903 +
1914 1904          zero = rl_min(rl);
1915 1905          zero.value = 0;
1916 1906          add_range(&rl, zero, zero);
1917 1907  
1918 1908          return rl;
1919 1909  }
1920 1910  
1921 1911  static struct range_list *handle_lshift(struct range_list *left_orig, struct range_list *right_orig)
1922 1912  {
1923 1913          struct range_list *left;
↓ open down ↓ 217 lines elided ↑ open up ↑
2141 2131                  left_false = rl_intersection(left_orig, right_orig);
2142 2132                  right_false = clone_rl(left_false);
2143 2133  
2144 2134                  if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
2145 2135                          left_true = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
2146 2136                  if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
2147 2137                          right_true = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
2148 2138                  break;
2149 2139          default:
2150 2140                  sm_perror(" unhandled comparison %d", op);
2151      -                return;
2152 2141          }
2153 2142  
2154 2143          if (left_true_rl) {
2155 2144                  *left_true_rl = left_true;
2156 2145                  *left_false_rl = left_false;
2157 2146          }
2158 2147          if (right_true_rl) {
2159 2148                  *right_true_rl = right_true;
2160 2149                  *right_false_rl = right_false;
2161 2150          }
2162 2151  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX