Print this page
11506 smatch resync


  39         state = __alloc_smatch_state(0);
  40         state->name = alloc_sname(name);
  41         state->data = sym;
  42         return state;
  43 }
  44 
  45 static void undef(struct sm_state *sm, struct expression *mod_expr)
  46 {
  47         if (__in_fake_parameter_assign)
  48                 return;
  49         set_state(my_id, sm->name, sm->sym, &undefined);
  50 }
  51 
  52 char *map_call_to_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
  53 {
  54         struct smatch_state *state;
  55         int skip;
  56         char buf[256];
  57 
  58         /* skip 'foo->'.  This was checked in the caller. */
  59         skip = strlen(sym->ident->name) + 2;
  60 
  61         state = get_state(my_id, sym->ident->name, sym);
  62         if (!state || !state->data)
  63                 return NULL;
  64 
  65         snprintf(buf, sizeof(buf), "%s->%s", state->name, name + skip);
  66         *new_sym = state->data;
  67         return alloc_string(buf);
  68 }
  69 
  70 static char *map_my_state_long_to_short(struct sm_state *sm, const char *name, struct symbol *sym, struct symbol **new_sym, bool stack)
  71 {
  72         int len;
  73         char buf[256];
  74 
  75         if (sm->state->data != sym)
  76                 return NULL;
  77         len = strlen(sm->state->name);
  78         if (strncmp(name, sm->state->name, len) != 0)
  79                 return NULL;
  80 
  81         if (name[len] == '.')
  82                 return NULL;
  83         if (!stack && name[len] != '-')
  84                 return NULL;
  85         snprintf(buf, sizeof(buf), "%s%s", sm->name, name + len);
  86         *new_sym = sm->sym;
  87         return alloc_string(buf);
  88 }
  89 
  90 static char *map_assignment_long_to_short(struct sm_state *sm, const char *name, struct symbol *sym, struct symbol **new_sym, bool stack)
  91 {
  92         struct expression *orig_expr;
  93         struct symbol *orig_sym;
  94         int len;
  95         char buf[256];
  96 
  97         orig_expr = sm->state->data;
  98         if (!orig_expr)
  99                 return NULL;
 100 
 101         /*
 102          * Say we have an assignment like:
 103          *     foo->bar->my_ptr = my_ptr;
 104          * We still expect the function to carry on using "my_ptr" as the
 105          * shorter name.  That's not a long to short mapping.
 106          *
 107          */
 108         if (orig_expr->type == EXPR_SYMBOL)
 109                 return NULL;
 110 
 111         orig_sym = expr_to_sym(orig_expr);
 112         if (!orig_sym)
 113                 return NULL;
 114         if (sym != orig_sym)
 115                 return NULL;
 116 
 117         len = strlen(sm->state->name);
 118         if (strncmp(name, sm->state->name, len) != 0)
 119                 return NULL;
 120 
 121         if (name[len] == '.')
 122                 return NULL;
 123         if (!stack && name[len] != '-')
 124                 return NULL;
 125         snprintf(buf, sizeof(buf), "%s%s", sm->name, name + len);
 126         *new_sym = sm->sym;
 127         return alloc_string(buf);
 128 }
 129 
 130 /*
 131  * Normally, we expect people to consistently refer to variables by the shortest
 132  * name.  So they use "b->a" instead of "foo->bar.a" when both point to the
 133  * same memory location.  However, when we're dealing across function boundaries
 134  * then sometimes we pass frob(foo) which sets foo->bar.a.  In that case, we
 135  * translate it to the shorter name.  Smatch extra updates the shorter name,
 136  * which in turn updates the longer name.
 137  *
 138  */
 139 static char *map_long_to_short_name_sym_helper(const char *name, struct symbol *sym, struct symbol **new_sym, bool stack)
 140 {
 141         char *ret;
 142         struct sm_state *sm;
 143 
 144         *new_sym = NULL;
 145 
 146         FOR_EACH_SM(__get_cur_stree(), sm) {
 147                 if (sm->owner == my_id) {
 148                         ret = map_my_state_long_to_short(sm, name, sym, new_sym, stack);
 149                         if (ret)



 150                                 return ret;
 151                         continue;
 152                 }
 153                 if (sm->owner == check_assigned_expr_id) {
 154                         ret = map_assignment_long_to_short(sm, name, sym, new_sym, stack);
 155                         if (ret)
 156                                 return ret;
 157                         continue;
 158                 }
 159         } END_FOR_EACH_SM(sm);
 160 
 161         return NULL;
 162 }
 163 
 164 char *map_long_to_short_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
 165 {
 166         return map_long_to_short_name_sym_helper(name, sym, new_sym, 1);
 167 }
 168 
 169 char *map_long_to_short_name_sym_nostack(const char *name, struct symbol *sym, struct symbol **new_sym)
 170 {
 171         return map_long_to_short_name_sym_helper(name, sym, new_sym, 0);
 172 }
 173 
 174 char *map_call_to_param_name_sym(struct expression *expr, struct symbol **sym)
 175 {
 176         char *name;
 177         struct symbol *start_sym;
 178         struct smatch_state *state;
 179 
 180         *sym = NULL;
 181 
 182         name = expr_to_str_sym(expr, &start_sym);
 183         if (!name)
 184                 return NULL;
 185         if (expr->type == EXPR_CALL)
 186                 start_sym = expr_to_sym(expr->fn);
 187 
 188         state = get_state(my_id, name, start_sym);
 189         free_string(name);
 190         if (!state || !state->data)
 191                 return NULL;
 192 
 193         *sym = state->data;


 263                 call = strip_expr(expr);
 264                 left_sym = expr_to_sym(call->fn);
 265                 if (!left_sym)
 266                         return;
 267                 left_name = expr_to_str(call);
 268                 if (!left_name)
 269                         return;
 270 
 271                 store_mapping_helper(left_name, left_sym, call, return_string);
 272                 goto free;
 273 
 274         }
 275 
 276 free:
 277         free_string(left_name);
 278 }
 279 
 280 void register_return_to_param(int id)
 281 {
 282         my_id = id;

 283         add_modification_hook(my_id, &undef);
 284 }
 285 
 286 void register_return_to_param_links(int id)
 287 {
 288         link_id = id;
 289         set_up_link_functions(my_id, link_id);
 290 }
 291 


  39         state = __alloc_smatch_state(0);
  40         state->name = alloc_sname(name);
  41         state->data = sym;
  42         return state;
  43 }
  44 
  45 static void undef(struct sm_state *sm, struct expression *mod_expr)
  46 {
  47         if (__in_fake_parameter_assign)
  48                 return;
  49         set_state(my_id, sm->name, sm->sym, &undefined);
  50 }
  51 
  52 char *map_call_to_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
  53 {
  54         struct smatch_state *state;
  55         int skip;
  56         char buf[256];
  57 
  58         /* skip 'foo->'.  This was checked in the caller. */
  59         skip = sym->ident->len + 2;
  60 
  61         state = get_state(my_id, sym->ident->name, sym);
  62         if (!state || !state->data)
  63                 return NULL;
  64 
  65         snprintf(buf, sizeof(buf), "%s->%s", state->name, name + skip);
  66         *new_sym = state->data;
  67         return alloc_string(buf);
  68 }
  69 
  70 static char *map_my_state_long_to_short(struct sm_state *sm, const char *name, struct symbol *sym, struct symbol **new_sym, bool stack)
  71 {
  72         int len;
  73         char buf[256];
  74 
  75         if (sm->state->data != sym)
  76                 return NULL;
  77         len = strlen(sm->state->name);
  78         if (strncmp(name, sm->state->name, len) != 0)
  79                 return NULL;
  80 
  81         if (name[len] == '.')
  82                 return NULL;
  83         if (!stack && name[len] != '-')
  84                 return NULL;
  85         snprintf(buf, sizeof(buf), "%s%s", sm->name, name + len);
  86         *new_sym = sm->sym;
  87         return alloc_string(buf);
  88 }
  89 








































  90 /*
  91  * Normally, we expect people to consistently refer to variables by the shortest
  92  * name.  So they use "b->a" instead of "foo->bar.a" when both point to the
  93  * same memory location.  However, when we're dealing across function boundaries
  94  * then sometimes we pass frob(foo) which sets foo->bar.a.  In that case, we
  95  * translate it to the shorter name.  Smatch extra updates the shorter name,
  96  * which in turn updates the longer name.
  97  *
  98  */
  99 char *map_long_to_short_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym, bool use_stack)
 100 {
 101         char *ret;
 102         struct sm_state *sm;
 103 
 104         *new_sym = NULL;
 105 
 106         FOR_EACH_SM(__get_cur_stree(), sm) {
 107                 if (sm->owner == my_id) {
 108                         ret = map_my_state_long_to_short(sm, name, sym, new_sym, use_stack);
 109                         if (ret) {
 110                                 if (local_debug)
 111                                         sm_msg("%s: my_state: name = '%s' sm = '%s'",
 112                                                __func__, name, show_sm(sm));
 113                                 return ret;

 114                         }




 115                         continue;
 116                 }
 117         } END_FOR_EACH_SM(sm);
 118 
 119         return NULL;
 120 }
 121 










 122 char *map_call_to_param_name_sym(struct expression *expr, struct symbol **sym)
 123 {
 124         char *name;
 125         struct symbol *start_sym;
 126         struct smatch_state *state;
 127 
 128         *sym = NULL;
 129 
 130         name = expr_to_str_sym(expr, &start_sym);
 131         if (!name)
 132                 return NULL;
 133         if (expr->type == EXPR_CALL)
 134                 start_sym = expr_to_sym(expr->fn);
 135 
 136         state = get_state(my_id, name, start_sym);
 137         free_string(name);
 138         if (!state || !state->data)
 139                 return NULL;
 140 
 141         *sym = state->data;


 211                 call = strip_expr(expr);
 212                 left_sym = expr_to_sym(call->fn);
 213                 if (!left_sym)
 214                         return;
 215                 left_name = expr_to_str(call);
 216                 if (!left_name)
 217                         return;
 218 
 219                 store_mapping_helper(left_name, left_sym, call, return_string);
 220                 goto free;
 221 
 222         }
 223 
 224 free:
 225         free_string(left_name);
 226 }
 227 
 228 void register_return_to_param(int id)
 229 {
 230         my_id = id;
 231         set_dynamic_states(my_id);
 232         add_modification_hook(my_id, &undef);
 233 }
 234 
 235 void register_return_to_param_links(int id)
 236 {
 237         link_id = id;
 238         set_up_link_functions(my_id, link_id);
 239 }
 240