Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_buf_size.c
          +++ new/usr/src/tools/smatch/src/smatch_buf_size.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   */
  17   17  
  18   18  #include <stdlib.h>
  19   19  #include <errno.h>
  20   20  #include "parse.h"
  21   21  #include "smatch.h"
  22   22  #include "smatch_slist.h"
  23   23  #include "smatch_extra.h"
  24   24  #include "smatch_function_hashtable.h"
  25   25  
  26      -#define UNKNOWN_SIZE (-1)
       26 +#define UNKNOWN_SIZE -1
  27   27  
  28   28  static int my_size_id;
  29   29  
  30   30  static DEFINE_HASHTABLE_INSERT(insert_func, char, int);
  31   31  static DEFINE_HASHTABLE_SEARCH(search_func, char, int);
  32   32  static struct hashtable *allocation_funcs;
  33   33  
  34   34  static char *get_fn_name(struct expression *expr)
  35   35  {
  36   36          if (expr->type != EXPR_CALL)
↓ open down ↓ 230 lines elided ↑ open up ↑
 267  267  
 268  268  static void db_returns_buf_size(struct expression *expr, int param, char *unused, char *math)
 269  269  {
 270  270          struct expression *call;
 271  271          struct range_list *rl;
 272  272  
 273  273          if (expr->type != EXPR_ASSIGNMENT)
 274  274                  return;
 275  275          call = strip_expr(expr->right);
 276  276  
 277      -        if (!parse_call_math_rl(call, math, &rl))
 278      -                return;
      277 +        call_results_to_rl(call, &int_ctype, math, &rl);
 279  278          rl = cast_rl(&int_ctype, rl);
 280  279          set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
 281  280  }
 282  281  
 283  282  static int get_real_array_size_from_type(struct symbol *type)
 284  283  {
 285  284          sval_t sval;
 286  285  
 287  286          if (!type)
 288  287                  return 0;
↓ open down ↓ 175 lines elided ↑ open up ↑
 464  463                  .type = &int_ctype,
 465  464                  {.value = value},
 466  465          };
 467  466  
 468  467          return alloc_rl(sval, sval);
 469  468  }
 470  469  
 471  470  struct range_list *get_array_size_bytes_rl(struct expression *expr)
 472  471  {
 473  472          struct range_list *ret = NULL;
      473 +        sval_t sval;
 474  474          int size;
 475  475  
 476  476          expr = remove_addr_fluff(expr);
 477  477          if (!expr)
 478  478                  return NULL;
 479  479  
 480  480          /* "BAR" */
 481  481          if (expr->type == EXPR_STRING)
 482  482                  return alloc_int_rl(expr->string->length);
 483  483  
↓ open down ↓ 37 lines elided ↑ open up ↑
 521  521          /* char *foo = "BAR" */
 522  522          size = get_size_from_initializer(expr);
 523  523          if (size)
 524  524                  return alloc_int_rl(elements_to_bytes(expr, size));
 525  525  
 526  526          size = get_bytes_from_address(expr);
 527  527          if (size)
 528  528                  return alloc_int_rl(size);
 529  529  
 530  530          ret = size_from_db(expr);
      531 +        if (rl_to_sval(ret, &sval) && sval.value == -1)
      532 +                return NULL;
 531  533          if (ret)
 532  534                  return ret;
 533  535  
 534  536          return NULL;
 535  537  }
 536  538  
 537  539  int get_array_size_bytes(struct expression *expr)
 538  540  {
 539  541          struct range_list *rl;
 540  542          sval_t sval;
↓ open down ↓ 84 lines elided ↑ open up ↑
 625  627                  sql_insert_function_type_size(name, "(-1)");
 626  628  
 627  629          free_string(name);
 628  630  }
 629  631  
 630  632  static void store_alloc(struct expression *expr, struct range_list *rl)
 631  633  {
 632  634          struct symbol *type;
 633  635  
 634  636          rl = clone_rl(rl); // FIXME!!!
      637 +        if (!rl)
      638 +                rl = size_to_rl(UNKNOWN_SIZE);
 635  639          set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
 636  640  
 637  641          type = get_type(expr);
 638  642          if (!type)
 639  643                  return;
 640  644          if (type->type != SYM_PTR)
 641  645                  return;
 642  646          type = get_real_base_type(type);
 643  647          if (!type)
 644  648                  return;
↓ open down ↓ 67 lines elided ↑ open up ↑
 712  716          struct expression *size, *nr, *mult;
 713  717          struct range_list *rl;
 714  718  
 715  719          right = strip_expr(expr->right);
 716  720          nr = get_argument_from_call_expr(right->args, 0);
 717  721          size = get_argument_from_call_expr(right->args, 1);
 718  722          mult = binop_expression(nr, '*', size);
 719  723          if (get_implied_rl(mult, &rl))
 720  724                  store_alloc(expr->left, rl);
 721  725          else
 722      -                store_alloc(expr->left, size_to_rl(-1));
      726 +                store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
 723  727  }
 724  728  
 725  729  static void match_page(const char *fn, struct expression *expr, void *_unused)
 726  730  {
 727  731          sval_t page_size = {
 728  732                  .type = &int_ctype,
 729  733                  {.value = 4096},
 730  734          };
 731  735  
 732  736          store_alloc(expr->left, alloc_rl(page_size, page_size));
↓ open down ↓ 4 lines elided ↑ open up ↑
 737  741          struct expression *fn_expr;
 738  742          struct expression *size_expr;
 739  743          sval_t size;
 740  744  
 741  745          fn_expr = strip_expr(expr->right);
 742  746          size_expr = get_argument_from_call_expr(fn_expr->args, 1);
 743  747          if (get_implied_max(size_expr, &size)) {
 744  748                  size.value++;
 745  749                  store_alloc(expr->left, size_to_rl(size.value));
 746  750          } else {
 747      -                store_alloc(expr->left, size_to_rl(-1));
      751 +                store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
 748  752          }
 749  753  
 750  754  }
 751  755  
 752  756  static void match_alloc_pages(const char *fn, struct expression *expr, void *_order_arg)
 753  757  {
 754  758          int order_arg = PTR_INT(_order_arg);
 755  759          struct expression *right;
 756  760          struct expression *arg;
 757  761          sval_t sval;
↓ open down ↓ 53 lines elided ↑ open up ↑
 811  815                  if (is_whole_rl(rl))
 812  816                          continue;
 813  817                  if (is_type_bytes(rl, arg))
 814  818                          continue;
 815  819                  sql_insert_caller_info(expr, BUF_SIZE, i, "$", show_rl(rl));
 816  820          } END_FOR_EACH_PTR(arg);
 817  821  }
 818  822  
 819  823  static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
 820  824  {
 821      -        if (sm->state == &merged ||
 822      -            strcmp(sm->state->name, "(-1)") == 0 ||
 823      -            strcmp(sm->state->name, "empty") == 0 ||
 824      -            strcmp(sm->state->name, "0") == 0)
      825 +        sval_t sval;
      826 +
      827 +        if (!estate_rl(sm->state) ||
      828 +            (estate_get_single_value(sm->state, &sval) &&
      829 +             (sval.value == -1 || sval.value == 0)))
 825  830                  return;
      831 +
 826  832          sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name);
 827  833  }
 828  834  
 829  835  /*
 830  836   * This is slightly (very) weird because half of this stuff is handled in
 831  837   * smatch_parse_call_math.c which is poorly named.  But anyway, add some buf
 832  838   * sizes here.
 833  839   *
 834  840   */
 835  841  static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr)
 836  842  {
 837      -        char buf[16];
 838      -        int size;
      843 +        const char *param_math;
      844 +        struct range_list *rl;
      845 +        char buf[64];
      846 +        sval_t sval;
 839  847  
 840      -        size = get_array_size_bytes(expr);
 841      -        if (!size)
      848 +        rl = get_array_size_bytes_rl(expr);
      849 +        param_math = get_allocation_math(expr);
      850 +        if (!rl && !param_math)
 842  851                  return;
 843  852  
 844      -        snprintf(buf, sizeof(buf), "%d", size);
      853 +        if (!param_math &&
      854 +            rl_to_sval(rl, &sval) &&
      855 +            (sval.value == -1 || sval.value == 0))
      856 +                return;
      857 +
      858 +        if (param_math)
      859 +                snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), param_math);
      860 +        else
      861 +                snprintf(buf, sizeof(buf), "%s", show_rl(rl));
      862 +
      863 +        // FIXME: don't store if you can guess the size from the type
      864 +        // FIXME: return if we allocate a parameter $0->bar
 845  865          sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf);
 846  866  }
 847  867  
 848  868  static void record_global_size(struct symbol *sym)
 849  869  {
 850  870          int bytes;
 851  871          char buf[16];
 852  872  
 853  873          if (!sym->ident)
 854  874                  return;
↓ open down ↓ 10 lines elided ↑ open up ↑
 865  885          sql_insert_data_info_var_sym(sym->ident->name, sym, BUF_SIZE, buf);
 866  886  }
 867  887  
 868  888  void register_buf_size(int id)
 869  889  {
 870  890          my_size_id = id;
 871  891  
 872  892          set_dynamic_states(my_size_id);
 873  893  
 874  894          add_unmatched_state_hook(my_size_id, &unmatched_size_state);
      895 +        add_merge_hook(my_size_id, &merge_estates);
 875  896  
 876  897          select_caller_info_hook(set_param_buf_size, BUF_SIZE);
 877  898          select_return_states_hook(BUF_SIZE, &db_returns_buf_size);
 878  899          add_split_return_callback(print_returned_allocations);
 879  900  
 880  901          allocation_funcs = create_function_hashtable(100);
 881  902          add_allocation_function("malloc", &match_alloc, 0);
 882  903          add_allocation_function("calloc", &match_calloc, 0);
 883  904          add_allocation_function("memdup", &match_alloc, 1);
 884  905          add_allocation_function("realloc", &match_alloc, 1);
↓ open down ↓ 13 lines elided ↑ open up ↑
 898  919                  add_allocation_function("kmemdup_user", &match_alloc, 1);
 899  920                  add_allocation_function("dma_alloc_attrs", &match_alloc, 1);
 900  921                  add_allocation_function("pci_alloc_consistent", &match_alloc, 1);
 901  922                  add_allocation_function("pci_alloc_coherent", &match_alloc, 1);
 902  923                  add_allocation_function("devm_kmalloc", &match_alloc, 1);
 903  924                  add_allocation_function("devm_kzalloc", &match_alloc, 1);
 904  925                  add_allocation_function("krealloc", &match_alloc, 1);
 905  926                  add_allocation_function("__alloc_bootmem", &match_alloc, 0);
 906  927                  add_allocation_function("alloc_bootmem", &match_alloc, 0);
 907  928                  add_allocation_function("kmap", &match_page, 0);
      929 +                add_allocation_function("kmap_atomic", &match_page, 0);
 908  930                  add_allocation_function("get_zeroed_page", &match_page, 0);
 909  931                  add_allocation_function("alloc_page", &match_page, 0);
 910      -                add_allocation_function("page_address", &match_page, 0);
 911      -                add_allocation_function("lowmem_page_address", &match_page, 0);
 912  932                  add_allocation_function("alloc_pages", &match_alloc_pages, 1);
 913  933                  add_allocation_function("alloc_pages_current", &match_alloc_pages, 1);
 914  934                  add_allocation_function("__get_free_pages", &match_alloc_pages, 1);
      935 +                add_allocation_function("dma_alloc_contiguous", &match_alloc, 1);
      936 +                add_allocation_function("dma_alloc_coherent", &match_alloc, 1);
 915  937          }
 916  938  
 917  939          add_allocation_function("strndup", match_strndup, 0);
 918  940          if (option_project == PROJ_KERNEL)
 919  941                  add_allocation_function("kstrndup", match_strndup, 0);
 920  942  
 921  943          add_modification_hook(my_size_id, &set_size_undefined);
 922  944  
 923  945          add_merge_hook(my_size_id, &merge_size_func);
 924  946  
↓ open down ↓ 12 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX