Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_untracked_param.c
          +++ new/usr/src/tools/smatch/src/smatch_untracked_param.c
↓ open down ↓ 31 lines elided ↑ open up ↑
  32   32   */
  33   33  
  34   34  #include "smatch.h"
  35   35  #include "smatch_slist.h"
  36   36  #include "smatch_extra.h"
  37   37  
  38   38  static int my_id;
  39   39  static int tracked;
  40   40  
  41   41  STATE(untracked);
       42 +STATE(lost);
  42   43  
  43   44  typedef void (untracked_hook)(struct expression *call, int param);
  44   45  DECLARE_PTR_LIST(untracked_hook_list, untracked_hook *);
  45   46  static struct untracked_hook_list *untracked_hooks;
       47 +static struct untracked_hook_list *lost_hooks;
  46   48  
  47   49  struct int_stack *tracked_stack;
  48   50  
  49   51  void add_untracked_param_hook(void (func)(struct expression *call, int param))
  50   52  {
  51   53          untracked_hook **p = malloc(sizeof(untracked_hook *));
  52   54          *p = func;
  53   55          add_ptr_list(&untracked_hooks, p);
  54   56  }
  55   57  
  56   58  static void call_untracked_callbacks(struct expression *expr, int param)
  57   59  {
  58   60          untracked_hook **fn;
  59   61  
  60   62          FOR_EACH_PTR(untracked_hooks, fn) {
  61   63                  (*fn)(expr, param);
  62   64          } END_FOR_EACH_PTR(fn);
  63   65  }
  64   66  
       67 +void add_lost_param_hook(void (func)(struct expression *call, int param))
       68 +{
       69 +        untracked_hook **p = malloc(sizeof(untracked_hook *));
       70 +        *p = func;
       71 +        add_ptr_list(&lost_hooks, p);
       72 +}
       73 +
       74 +static void call_lost_callbacks(struct expression *expr, int param)
       75 +{
       76 +        untracked_hook **fn;
       77 +
       78 +        FOR_EACH_PTR(lost_hooks, fn) {
       79 +                (*fn)(expr, param);
       80 +        } END_FOR_EACH_PTR(fn);
       81 +}
       82 +
  65   83  static void assume_tracked(struct expression *call_expr, int param, char *key, char *value)
  66   84  {
  67   85          tracked = 1;
  68   86  }
  69   87  
  70      -void mark_untracked(struct expression *expr, int param, const char *key, const char *value)
       88 +static char *get_array_from_key(struct expression *expr, int param, const char *key, struct symbol **sym)
  71   89  {
       90 +        struct expression *arg;
       91 +
       92 +        arg = get_argument_from_call_expr(expr->args, param);
       93 +        if (!arg)
       94 +                return NULL;
       95 +        if (arg->type != EXPR_PREOP || arg->op != '&')
       96 +                return NULL;
       97 +        arg = arg->unop;
       98 +        if (!is_array(arg))
       99 +                return NULL;
      100 +        arg = get_array_base(arg);
      101 +
      102 +        return expr_to_var_sym(arg, sym);
      103 +}
      104 +
      105 +static void mark_untracked_lost(struct expression *expr, int param, const char *key, int type)
      106 +{
  72  107          char *name;
  73  108          struct symbol *sym;
  74  109  
  75  110          while (expr->type == EXPR_ASSIGNMENT)
  76  111                  expr = strip_expr(expr->right);
  77  112          if (expr->type != EXPR_CALL)
  78  113                  return;
  79  114  
  80  115          name = return_state_to_var_sym(expr, param, key, &sym);
  81      -        if (!name || !sym)
  82      -                goto free;
      116 +        if (!name || !sym) {
      117 +                name = get_array_from_key(expr, param, key, &sym);
      118 +                if (!name || !sym)
      119 +                        goto free;
      120 +        }
  83  121  
      122 +        if (type == LOST_PARAM)
      123 +                call_lost_callbacks(expr, param);
  84  124          call_untracked_callbacks(expr, param);
  85  125          set_state(my_id, name, sym, &untracked);
  86  126  free:
  87  127          free_string(name);
      128 +
  88  129  }
  89  130  
      131 +void mark_untracked(struct expression *expr, int param, const char *key, const char *value)
      132 +{
      133 +        mark_untracked_lost(expr, param, key, UNTRACKED_PARAM);
      134 +}
      135 +
      136 +void mark_lost(struct expression *expr, int param, const char *key, const char *value)
      137 +{
      138 +        mark_untracked_lost(expr, param, key, LOST_PARAM);
      139 +}
      140 +
  90  141  static int lost_in_va_args(struct expression *expr)
  91  142  {
  92  143          struct symbol *fn;
  93  144          char *name;
  94  145          int is_lost;
  95  146  
  96  147          fn = get_type(expr->fn);
  97  148          if (!fn || !fn->variadic)
  98  149                  return 0;
  99  150  
↓ open down ↓ 26 lines elided ↑ open up ↑
 126  177  
 127  178                  type = get_type(arg);
 128  179                  if (!type || type->type != SYM_PTR)
 129  180                          continue;
 130  181  
 131  182                  call_untracked_callbacks(expr, i);
 132  183                  set_state_expr(my_id, arg, &untracked);
 133  184          } END_FOR_EACH_PTR(arg);
 134  185  }
 135  186  
 136      -void mark_all_params_untracked(int return_id, char *return_ranges, struct expression *expr)
      187 +
      188 +static void mark_all_params(int return_id, char *return_ranges, int type)
 137  189  {
 138  190          struct symbol *arg;
 139  191          int param;
 140  192  
 141  193          param = -1;
 142  194          FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
 143  195                  param++;
 144  196  
 145  197                  if (!arg->ident)
 146  198                          continue;
 147  199                  sql_insert_return_states(return_id, return_ranges,
 148      -                                         UNTRACKED_PARAM, param, "$", "");
      200 +                                         type, param, "$", "");
 149  201          } END_FOR_EACH_PTR(arg);
 150  202  }
 151  203  
      204 +
      205 +void mark_all_params_untracked(int return_id, char *return_ranges, struct expression *expr)
      206 +{
      207 +        mark_all_params(return_id, return_ranges, UNTRACKED_PARAM);
      208 +}
      209 +
      210 +void mark_all_params_lost(int return_id, char *return_ranges, struct expression *expr)
      211 +{
      212 +        mark_all_params(return_id, return_ranges, LOST_PARAM);
      213 +}
      214 +
 152  215  static void print_untracked_params(int return_id, char *return_ranges, struct expression *expr)
 153  216  {
      217 +        struct sm_state *sm;
 154  218          struct symbol *arg;
 155  219          int param;
      220 +        int type;
 156  221  
 157  222          param = -1;
 158  223          FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
 159  224                  param++;
 160  225  
 161  226                  if (!arg->ident)
 162  227                          continue;
 163      -                if (!get_state(my_id, arg->ident->name, arg) &&
 164      -                    !__bail_on_rest_of_function)  /* hairy functions are untrackable */
      228 +
      229 +                if (__bail_on_rest_of_function) {
      230 +                        /* hairy functions are lost */
      231 +                        type = LOST_PARAM;
      232 +                } else if ((sm = get_sm_state(my_id, arg->ident->name, arg))) {
      233 +                        if (slist_has_state(sm->possible, &lost))
      234 +                                type = LOST_PARAM;
      235 +                        else
      236 +                                type = UNTRACKED_PARAM;
      237 +                } else {
 165  238                          continue;
      239 +                }
 166  240  
 167  241                  sql_insert_return_states(return_id, return_ranges,
 168      -                                         UNTRACKED_PARAM, param, "$", "");
      242 +                                         type, param, "$", "");
 169  243          } END_FOR_EACH_PTR(arg);
 170  244  }
 171  245  
 172  246  static void match_param_assign(struct expression *expr)
 173  247  {
 174  248          struct expression *right;
 175  249          struct symbol *type;
 176  250          int param;
 177  251  
 178  252          if (__in_fake_assign)
↓ open down ↓ 51 lines elided ↑ open up ↑
 230  304  {
 231  305          tracked = pop_int(&tracked_stack);
 232  306  }
 233  307  
 234  308  void register_untracked_param(int id)
 235  309  {
 236  310          my_id = id;
 237  311  
 238  312          select_return_states_hook(INTERNAL, &assume_tracked);
 239  313          select_return_states_hook(UNTRACKED_PARAM, &mark_untracked);
      314 +        select_return_states_hook(LOST_PARAM, &mark_lost);
 240  315          add_hook(&match_after_call, FUNCTION_CALL_HOOK_AFTER_DB);
 241  316  
 242  317          add_split_return_callback(&print_untracked_params);
 243  318  
 244  319          add_hook(&match_param_assign, ASSIGNMENT_HOOK);
 245  320          add_hook(&match_param_assign_in_asm, ASM_HOOK);
 246  321  
 247  322          add_hook(&match_inline_start, INLINE_FN_START);
 248  323          add_hook(&match_inline_end, INLINE_FN_END);
 249  324  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX