Print this page
new smatch


 113         array = get_array_base(expr->left);
 114         offset = get_array_offset(expr->left);
 115 
 116         /* These are handled by extra_mod_hook() */
 117         if (get_value(offset, &sval))
 118                 return;
 119         name = expr_to_var_sym(array, &sym);
 120         if (!name || !sym)
 121                 goto free;
 122         if (get_param_num_from_sym(sym) < 0)
 123                 goto free;
 124         get_absolute_rl(expr->right, &rl);
 125         rl = cast_rl(get_type(expr->left), rl);
 126 
 127         snprintf(buf, sizeof(buf), "*%s", name);
 128         set_state(my_id, buf, sym, alloc_estate_rl(rl));
 129 free:
 130         free_string(name);
 131 }
 132 


















 133 /*
 134  * This relies on the fact that these states are stored so that
 135  * foo->bar is before foo->bar->baz.
 136  */
 137 static int parent_set(struct string_list *list, const char *name)
 138 {
 139         char *tmp;
 140         int len;
 141         int ret;
 142 
 143         FOR_EACH_PTR(list, tmp) {
 144                 len = strlen(tmp);
 145                 ret = strncmp(tmp, name, len);
 146                 if (ret < 0)
 147                         continue;
 148                 if (ret > 0)
 149                         return 0;
 150                 if (name[len] == '-')
 151                         return 1;
 152         } END_FOR_EACH_PTR(tmp);
 153 
 154         return 0;
 155 }
 156 
 157 static void print_return_value_param(int return_id, char *return_ranges, struct expression *expr)
 158 {
 159         struct sm_state *sm;
 160         struct smatch_state *extra;
 161         int param;
 162         struct range_list *rl;
 163         const char *param_name;
 164         struct string_list *set_list = NULL;
 165         char *math_str;
 166         char buf[256];


 167 
 168         FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
 169                 if (!estate_rl(sm->state))
 170                         continue;
 171                 extra = get_state(SMATCH_EXTRA, sm->name, sm->sym);
 172                 if (extra) {
 173                         rl = rl_intersection(estate_rl(sm->state), estate_rl(extra));
 174                         if (!rl)
 175                                 continue;
 176                 } else {
 177                         rl = estate_rl(sm->state);
 178                 }
 179 
 180                 param = get_param_num_from_sym(sm->sym);
 181                 if (param < 0)
 182                         continue;
 183                 param_name = get_param_name(sm);
 184                 if (!param_name)
 185                         continue;
 186                 if (strcmp(param_name, "$") == 0) {
 187                         insert_string(&set_list, (char *)sm->name);
 188                         continue;
 189                 }
 190                 if (is_recursive_member(param_name)) {
 191                         insert_string(&set_list, (char *)sm->name);
 192                         continue;
 193                 }
 194 
 195                 if (is_ignored_kernel_data(param_name)) {
 196                         insert_string(&set_list, (char *)sm->name);
 197                         continue;
 198                 }


 199 










 200                 math_str = get_value_in_terms_of_parameter_math_var_sym(sm->name, sm->sym);
 201                 if (math_str) {
 202                         snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), math_str);
 203                         insert_string(&set_list, (char *)sm->name);
 204                         sql_insert_return_states(return_id, return_ranges,
 205                                         param_has_filter_data(sm) ? PARAM_ADD : PARAM_SET,
 206                                         param, param_name, buf);
 207                         continue;
 208                 }
 209 
 210                 /* no useful information here. */
 211                 if (is_whole_rl(rl) && parent_set(set_list, sm->name))
 212                         continue;
 213                 insert_string(&set_list, (char *)sm->name);
 214 
 215                 sql_insert_return_states(return_id, return_ranges,
 216                                          param_has_filter_data(sm) ? PARAM_ADD : PARAM_SET,
 217                                          param, param_name, show_rl(rl));


 218 
 219         } END_FOR_EACH_SM(sm);
 220 
 221         free_ptr_list((struct ptr_list **)&set_list);
 222 }
 223 





















 224 int param_was_set_var_sym(const char *name, struct symbol *sym)
 225 {
 226         struct sm_state *sm;
 227         int len;

 228 
 229         FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
 230                 if (sm->sym != sym)







 231                         continue;
 232                 len = strlen(sm->name);
 233                 if (strncmp(sm->name, name, len) != 0)




 234                         continue;
 235                 if (name[len] == '\0' ||
 236                     name[len] == '-')
 237                         return 1;
 238         } END_FOR_EACH_SM(sm);
 239 



 240         return 0;
 241 }
 242 
 243 int param_was_set(struct expression *expr)
 244 {
 245         char *name;
 246         struct symbol *sym;
 247         int ret = 0;
 248 
 249         name = expr_to_var_sym(expr, &sym);
 250         if (!name || !sym)
 251                 goto free;
 252 
 253         ret = param_was_set_var_sym(name, sym);
 254 free:
 255         free_string(name);
 256         return ret;
 257 }
 258 
 259 void register_param_set(int id)


 113         array = get_array_base(expr->left);
 114         offset = get_array_offset(expr->left);
 115 
 116         /* These are handled by extra_mod_hook() */
 117         if (get_value(offset, &sval))
 118                 return;
 119         name = expr_to_var_sym(array, &sym);
 120         if (!name || !sym)
 121                 goto free;
 122         if (get_param_num_from_sym(sym) < 0)
 123                 goto free;
 124         get_absolute_rl(expr->right, &rl);
 125         rl = cast_rl(get_type(expr->left), rl);
 126 
 127         snprintf(buf, sizeof(buf), "*%s", name);
 128         set_state(my_id, buf, sym, alloc_estate_rl(rl));
 129 free:
 130         free_string(name);
 131 }
 132 
 133 static char *get_two_dots(const char *name)
 134 {
 135         static char buf[80];
 136         int i, cnt = 0;
 137 
 138         for (i = 0; i < sizeof(buf); i++) {
 139                 if (name[i] == '.') {
 140                         cnt++;
 141                         if (cnt >= 2) {
 142                                 buf[i] = '\0';
 143                                 return buf;
 144                         }
 145                 }
 146                 buf[i] = name[i];
 147         }
 148         return NULL;
 149 }
 150 
 151 /*
 152  * This relies on the fact that these states are stored so that
 153  * foo->bar is before foo->bar->baz.
 154  */
 155 static int parent_set(struct string_list *list, const char *name)
 156 {
 157         char *tmp;
 158         int len;
 159         int ret;
 160 
 161         FOR_EACH_PTR(list, tmp) {
 162                 len = strlen(tmp);
 163                 ret = strncmp(tmp, name, len);
 164                 if (ret < 0)
 165                         continue;
 166                 if (ret > 0)
 167                         return 0;
 168                 if (name[len] == '-')
 169                         return 1;
 170         } END_FOR_EACH_PTR(tmp);
 171 
 172         return 0;
 173 }
 174 
 175 static void print_return_value_param_helper(int return_id, char *return_ranges, struct expression *expr, int limit)
 176 {
 177         struct sm_state *sm;
 178         struct smatch_state *extra;
 179         int param;
 180         struct range_list *rl;
 181         const char *param_name;
 182         struct string_list *set_list = NULL;
 183         char *math_str;
 184         char buf[256];
 185         char two_dot[80] = "";
 186         int count = 0;
 187 
 188         FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
 189                 if (!estate_rl(sm->state))
 190                         continue;
 191                 extra = __get_state(SMATCH_EXTRA, sm->name, sm->sym);
 192                 if (extra) {
 193                         rl = rl_intersection(estate_rl(sm->state), estate_rl(extra));
 194                         if (!rl)
 195                                 continue;
 196                 } else {
 197                         rl = estate_rl(sm->state);
 198                 }
 199 
 200                 param = get_param_num_from_sym(sm->sym);
 201                 if (param < 0)
 202                         continue;
 203                 param_name = get_param_name(sm);
 204                 if (!param_name)
 205                         continue;
 206                 if (strcmp(param_name, "$") == 0) {
 207                         insert_string(&set_list, (char *)sm->name);
 208                         continue;
 209                 }
 210                 if (is_recursive_member(param_name)) {
 211                         insert_string(&set_list, (char *)sm->name);
 212                         continue;
 213                 }
 214 
 215                 if (is_ignored_kernel_data(param_name)) {
 216                         insert_string(&set_list, (char *)sm->name);
 217                         continue;
 218                 }
 219                 if (limit) {
 220                         char *new = get_two_dots(param_name);
 221 
 222                         if (new) {
 223                                 if (strcmp(new, two_dot) == 0)
 224                                         continue;
 225                                 strncpy(two_dot, new, sizeof(two_dot));
 226                                 sql_insert_return_states(return_id, return_ranges,
 227                                          PARAM_SET, param, new, "s64min-s64max");
 228                                 continue;
 229                         }
 230                 }
 231 
 232                 math_str = get_value_in_terms_of_parameter_math_var_sym(sm->name, sm->sym);
 233                 if (math_str) {
 234                         snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), math_str);
 235                         insert_string(&set_list, (char *)sm->name);
 236                         sql_insert_return_states(return_id, return_ranges,
 237                                         param_has_filter_data(sm) ? PARAM_ADD : PARAM_SET,
 238                                         param, param_name, buf);
 239                         continue;
 240                 }
 241 
 242                 /* no useful information here. */
 243                 if (is_whole_rl(rl) && parent_set(set_list, sm->name))
 244                         continue;
 245                 insert_string(&set_list, (char *)sm->name);
 246 
 247                 sql_insert_return_states(return_id, return_ranges,
 248                                          param_has_filter_data(sm) ? PARAM_ADD : PARAM_SET,
 249                                          param, param_name, show_rl(rl));
 250                 if (limit && ++count > limit)
 251                         break;
 252 
 253         } END_FOR_EACH_SM(sm);
 254 
 255         free_ptr_list((struct ptr_list **)&set_list);
 256 }
 257 
 258 static void print_return_value_param(int return_id, char *return_ranges, struct expression *expr)
 259 {
 260         print_return_value_param_helper(return_id, return_ranges, expr, 0);
 261 }
 262 
 263 void print_limited_param_set(int return_id, char *return_ranges, struct expression *expr)
 264 {
 265         print_return_value_param_helper(return_id, return_ranges, expr, 1000);
 266 }
 267 
 268 static int possibly_empty(struct sm_state *sm)
 269 {
 270         struct sm_state *tmp;
 271 
 272         FOR_EACH_PTR(sm->possible, tmp) {
 273                 if (strcmp(tmp->name, "") == 0)
 274                         return 1;
 275         } END_FOR_EACH_PTR(tmp);
 276         return 0;
 277 }
 278 
 279 int param_was_set_var_sym(const char *name, struct symbol *sym)
 280 {
 281         struct sm_state *sm;
 282         char buf[80];
 283         int len, i;
 284 
 285         if (!name)
 286                 return 0;
 287 
 288         len = strlen(name);
 289         if (len >= sizeof(buf))
 290                 len = sizeof(buf) - 1;
 291 
 292         for (i = 0; i <= len; i++) {
 293                 if (name[i] != '-' && name[i] != '\0')
 294                         continue;
 295 
 296                 memcpy(buf, name, i);
 297                 buf[i] = '\0';
 298 
 299                 sm = get_sm_state(my_id, buf, sym);
 300                 if (!sm)
 301                         continue;
 302                 if (possibly_empty(sm))
 303                         continue;
 304                 return 1;
 305         }
 306 
 307         if (name[0] == '*')
 308                 return param_was_set_var_sym(name + 1, sym);
 309 
 310         return 0;
 311 }
 312 
 313 int param_was_set(struct expression *expr)
 314 {
 315         char *name;
 316         struct symbol *sym;
 317         int ret = 0;
 318 
 319         name = expr_to_var_sym(expr, &sym);
 320         if (!name || !sym)
 321                 goto free;
 322 
 323         ret = param_was_set_var_sym(name, sym);
 324 free:
 325         free_string(name);
 326         return ret;
 327 }
 328 
 329 void register_param_set(int id)