1 /*
   2  * Copyright (C) 2010 Dan Carpenter.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 #include <string.h>
  19 #include <errno.h>
  20 #include <unistd.h>
  21 #include <ctype.h>
  22 #include "smatch.h"
  23 #include "smatch_slist.h"
  24 #include "smatch_extra.h"
  25 
  26 struct sqlite3 *smatch_db;
  27 struct sqlite3 *mem_db;
  28 struct sqlite3 *cache_db;
  29 
  30 static int return_id;
  31 
  32 #define SQLITE_CACHE_PAGES 1000
  33 
  34 struct def_callback {
  35         int hook_type;
  36         void (*callback)(const char *name, struct symbol *sym, char *key, char *value);
  37 };
  38 ALLOCATOR(def_callback, "definition db hook callbacks");
  39 DECLARE_PTR_LIST(callback_list, struct def_callback);
  40 static struct callback_list *select_caller_info_callbacks;
  41 
  42 struct member_info_callback {
  43         int owner;
  44         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm);
  45 };
  46 ALLOCATOR(member_info_callback, "caller_info callbacks");
  47 DECLARE_PTR_LIST(member_info_cb_list, struct member_info_callback);
  48 static struct member_info_cb_list *member_callbacks;
  49 
  50 struct returned_state_callback {
  51         void (*callback)(int return_id, char *return_ranges, struct expression *return_expr);
  52 };
  53 ALLOCATOR(returned_state_callback, "returned state callbacks");
  54 DECLARE_PTR_LIST(returned_state_cb_list, struct returned_state_callback);
  55 static struct returned_state_cb_list *returned_state_callbacks;
  56 
  57 struct returned_member_callback {
  58         int owner;
  59         void (*callback)(int return_id, char *return_ranges, struct expression *expr, char *printed_name, struct smatch_state *state);
  60 };
  61 ALLOCATOR(returned_member_callback, "returned member callbacks");
  62 DECLARE_PTR_LIST(returned_member_cb_list, struct returned_member_callback);
  63 static struct returned_member_cb_list *returned_member_callbacks;
  64 
  65 struct db_implies_callback {
  66         int type;
  67         void (*callback)(struct expression *call, struct expression *arg, char *key, char *value);
  68 };
  69 ALLOCATOR(db_implies_callback, "return_implies callbacks");
  70 DECLARE_PTR_LIST(db_implies_cb_list, struct db_implies_callback);
  71 static struct db_implies_cb_list *return_implies_cb_list;
  72 static struct db_implies_cb_list *call_implies_cb_list;
  73 
  74 /* silently truncates if needed. */
  75 char *escape_newlines(const char *str)
  76 {
  77         char buf[1024] = "";
  78         bool found = false;
  79         int i, j;
  80 
  81         for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
  82                 if (str[i] != '\n') {
  83                         buf[j] = str[i];
  84                         continue;
  85                 }
  86 
  87                 found = true;
  88                 buf[j++] = '\\';
  89                 if (j == sizeof(buf))
  90                          break;
  91                 buf[j] = 'n';
  92         }
  93 
  94         if (!found)
  95                 return alloc_sname(str);
  96 
  97         if (j == sizeof(buf))
  98                 buf[j - 1] = '\0';
  99         return alloc_sname(buf);
 100 }
 101 
 102 static int print_sql_output(void *unused, int argc, char **argv, char **azColName)
 103 {
 104         int i;
 105 
 106         for (i = 0; i < argc; i++) {
 107                 if (i != 0)
 108                         printf(", ");
 109                 sm_printf("%s", argv[i]);
 110         }
 111         sm_printf("\n");
 112         return 0;
 113 }
 114 
 115 void sql_exec(struct sqlite3 *db, int (*callback)(void*, int, char**, char**), void *data, const char *sql)
 116 {
 117         char *err = NULL;
 118         int rc;
 119 
 120         if (!db)
 121                 return;
 122 
 123         if (option_debug) {
 124                 sm_msg("%s", sql);
 125                 if (strncasecmp(sql, "select", strlen("select")) == 0)
 126                         sqlite3_exec(db, sql, print_sql_output, NULL, NULL);
 127         }
 128 
 129         rc = sqlite3_exec(db, sql, callback, data, &err);
 130         if (rc != SQLITE_OK && !parse_error) {
 131                 sm_ierror("%s:%d SQL error #2: %s\n", get_filename(), get_lineno(), err);
 132                 sm_ierror("%s:%d SQL: '%s'\n", get_filename(), get_lineno(), sql);
 133                 parse_error = 1;
 134         }
 135 }
 136 
 137 static int replace_count;
 138 static char **replace_table;
 139 static const char *replace_return_ranges(const char *return_ranges)
 140 {
 141         int i;
 142 
 143         if (!get_function()) {
 144                 /* I have no idea why EXPORT_SYMBOL() is here */
 145                 return return_ranges;
 146         }
 147         for (i = 0; i < replace_count; i += 3) {
 148                 if (strcmp(replace_table[i + 0], get_function()) == 0) {
 149                         if (strcmp(replace_table[i + 1], return_ranges) == 0)
 150                                 return replace_table[i + 2];
 151                 }
 152         }
 153         return return_ranges;
 154 }
 155 
 156 
 157 static char *use_states;
 158 static int get_db_state_count(void)
 159 {
 160         struct sm_state *sm;
 161         int count = 0;
 162 
 163         FOR_EACH_SM(__get_cur_stree(), sm) {
 164                 if (sm->owner == USHRT_MAX)
 165                         continue;
 166                 if (use_states[sm->owner])
 167                         count++;
 168         } END_FOR_EACH_SM(sm);
 169         return count;
 170 }
 171 
 172 void db_ignore_states(int id)
 173 {
 174         use_states[id] = 0;
 175 }
 176 
 177 void sql_insert_return_states(int return_id, const char *return_ranges,
 178                 int type, int param, const char *key, const char *value)
 179 {
 180         if (key && strlen(key) >= 80)
 181                 return;
 182         return_ranges = replace_return_ranges(return_ranges);
 183         sql_insert(return_states, "'%s', '%s', %lu, %d, '%s', %d, %d, %d, '%s', '%s'",
 184                    get_base_file(), get_function(), (unsigned long)__inline_fn,
 185                    return_id, return_ranges, fn_static(), type, param, key, value);
 186 }
 187 
 188 static struct string_list *common_funcs;
 189 static int is_common_function(const char *fn)
 190 {
 191         char *tmp;
 192 
 193         if (!fn)
 194                 return 0;
 195 
 196         if (strncmp(fn, "__builtin_", 10) == 0)
 197                 return 1;
 198 
 199         FOR_EACH_PTR(common_funcs, tmp) {
 200                 if (strcmp(tmp, fn) == 0)
 201                         return 1;
 202         } END_FOR_EACH_PTR(tmp);
 203 
 204         return 0;
 205 }
 206 
 207 static char *function_signature(void)
 208 {
 209         return type_to_str(get_real_base_type(cur_func_sym));
 210 }
 211 
 212 void sql_insert_caller_info(struct expression *call, int type,
 213                 int param, const char *key, const char *value)
 214 {
 215         FILE *tmp_fd = sm_outfd;
 216         char *fn;
 217 
 218         if (!option_info && !__inline_call)
 219                 return;
 220 
 221         if (key && strlen(key) >= 80)
 222                 return;
 223 
 224         fn = get_fnptr_name(call->fn);
 225         if (!fn)
 226                 return;
 227 
 228         if (__inline_call) {
 229                 mem_sql(NULL, NULL,
 230                         "insert into caller_info values ('%s', '%s', '%s', %lu, %d, %d, %d, '%s', '%s');",
 231                         get_base_file(), get_function(), fn, (unsigned long)call,
 232                         is_static(call->fn), type, param, key, value);
 233         }
 234 
 235         if (!option_info)
 236                 return;
 237 
 238         if (strncmp(fn, "__builtin_", 10) == 0)
 239                 return;
 240         if (type != INTERNAL && is_common_function(fn))
 241                 return;
 242 
 243         sm_outfd = caller_info_fd;
 244         sm_msg("SQL_caller_info: insert into caller_info values ("
 245                "'%s', '%s', '%s', %%CALL_ID%%, %d, %d, %d, '%s', '%s');",
 246                get_base_file(), get_function(), fn, is_static(call->fn),
 247                type, param, key, value);
 248         sm_outfd = tmp_fd;
 249 
 250         free_string(fn);
 251 }
 252 
 253 void sql_insert_function_ptr(const char *fn, const char *struct_name)
 254 {
 255         sql_insert(function_ptr, "'%s', '%s', '%s', 0", get_base_file(), fn,
 256                    struct_name);
 257 }
 258 
 259 void sql_insert_return_implies(int type, int param, const char *key, const char *value)
 260 {
 261         sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 262                 get_base_file(), get_function(), (unsigned long)__inline_fn,
 263                 fn_static(), type, param, key, value);
 264 }
 265 
 266 void sql_insert_call_implies(int type, int param, const char *key, const char *value)
 267 {
 268         sql_insert_or_ignore(call_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 269                 get_base_file(), get_function(), (unsigned long)__inline_fn,
 270                 fn_static(), type, param, key, value);
 271 }
 272 
 273 void sql_insert_function_type_size(const char *member, const char *ranges)
 274 {
 275         sql_insert(function_type_size, "'%s', '%s', '%s', '%s'", get_base_file(), get_function(), member, ranges);
 276 }
 277 
 278 void sql_insert_function_type_info(int type, const char *struct_type, const char *member, const char *value)
 279 {
 280         sql_insert(function_type_info, "'%s', '%s', %d, '%s', '%s', '%s'", get_base_file(), get_function(), type, struct_type, member, value);
 281 }
 282 
 283 void sql_insert_type_info(int type, const char *member, const char *value)
 284 {
 285         sql_insert_cache(type_info, "'%s', %d, '%s', '%s'", get_base_file(), type, member, value);
 286 }
 287 
 288 void sql_insert_local_values(const char *name, const char *value)
 289 {
 290         sql_insert(local_values, "'%s', '%s', '%s'", get_base_file(), name, value);
 291 }
 292 
 293 void sql_insert_function_type_value(const char *type, const char *value)
 294 {
 295         sql_insert(function_type_value, "'%s', '%s', '%s', '%s'", get_base_file(), get_function(), type, value);
 296 }
 297 
 298 void sql_insert_function_type(int param, const char *value)
 299 {
 300         sql_insert(function_type, "'%s', '%s', %d, %d, '%s'",
 301                    get_base_file(), get_function(), fn_static(), param, value);
 302 }
 303 
 304 void sql_insert_parameter_name(int param, const char *value)
 305 {
 306         sql_insert(parameter_name, "'%s', '%s', %d, %d, '%s'",
 307                    get_base_file(), get_function(), fn_static(), param, value);
 308 }
 309 
 310 void sql_insert_data_info(struct expression *data, int type, const char *value)
 311 {
 312         char *data_name;
 313 
 314         data_name = get_data_info_name(data);
 315         if (!data_name)
 316                 return;
 317         sql_insert(data_info, "'%s', '%s', %d, '%s'",
 318                    is_static(data) ? get_base_file() : "extern",
 319                    data_name, type, value);
 320 }
 321 
 322 void sql_insert_data_info_var_sym(const char *var, struct symbol *sym, int type, const char *value)
 323 {
 324         sql_insert(data_info, "'%s', '%s', %d, '%s'",
 325                    (sym->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 326                    var, type, value);
 327 }
 328 
 329 void sql_save_constraint(const char *con)
 330 {
 331         if (!option_info)
 332                 return;
 333 
 334         sm_msg("SQL: insert or ignore into constraints (str) values('%s');", con);
 335 }
 336 
 337 void sql_save_constraint_required(const char *data, int op, const char *limit)
 338 {
 339         sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
 340 }
 341 
 342 void sql_copy_constraint_required(const char *new_limit, const char *old_limit)
 343 {
 344         if (!option_info)
 345                 return;
 346 
 347         sm_msg("SQL_late: insert or ignore into constraints_required (data, op, bound) "
 348                 "select constraints_required.data, constraints_required.op, '%s' from "
 349                 "constraints_required where bound = '%s';", new_limit, old_limit);
 350 }
 351 
 352 void sql_insert_fn_ptr_data_link(const char *ptr, const char *data)
 353 {
 354         sql_insert_or_ignore(fn_ptr_data_link, "'%s', '%s'", ptr, data);
 355 }
 356 
 357 void sql_insert_fn_data_link(struct expression *fn, int type, int param, const char *key, const char *value)
 358 {
 359         if (fn->type != EXPR_SYMBOL || !fn->symbol->ident)
 360                 return;
 361 
 362         sql_insert(fn_data_link, "'%s', '%s', %d, %d, %d, '%s', '%s'",
 363                    (fn->symbol->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 364                    fn->symbol->ident->name,
 365                    !!(fn->symbol->ctype.modifiers & MOD_STATIC),
 366                    type, param, key, value);
 367 }
 368 
 369 void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name)
 370 {
 371         sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
 372                    tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
 373 }
 374 
 375 void sql_insert_mtag_data(mtag_t tag, const char *var, int offset, int type, const char *value)
 376 {
 377         sql_insert(mtag_data, "%lld, '%s', %d, %d, '%s'", tag, var, offset, type, value);
 378 }
 379 
 380 void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
 381 {
 382         sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
 383 }
 384 
 385 void sql_insert_mtag_alias(mtag_t orig, mtag_t alias)
 386 {
 387         sql_insert(mtag_alias, "%lld, %lld", orig, alias);
 388 }
 389 
 390 static int save_mtag(void *_tag, int argc, char **argv, char **azColName)
 391 {
 392         mtag_t *saved_tag = _tag;
 393         mtag_t new_tag;
 394 
 395         new_tag = strtoll(argv[0], NULL, 10);
 396 
 397         if (!*saved_tag)
 398                 *saved_tag = new_tag;
 399         else if (*saved_tag != new_tag)
 400                 *saved_tag = -1ULL;
 401 
 402         return 0;
 403 }
 404 
 405 int mtag_map_select_container(mtag_t tag, int offset, mtag_t *container)
 406 {
 407         mtag_t tmp = 0;
 408 
 409         run_sql(save_mtag, &tmp,
 410                 "select container from mtag_map where tag = %lld and offset = %d;",
 411                 tag, offset);
 412 
 413         if (tmp == 0 || tmp == -1ULL)
 414                 return 0;
 415         *container = tmp;
 416         return 1;
 417 }
 418 
 419 int mtag_map_select_tag(mtag_t container, int offset, mtag_t *tag)
 420 {
 421         mtag_t tmp = 0;
 422 
 423         run_sql(save_mtag, &tmp,
 424                 "select tag from mtag_map where container = %lld and offset = %d;",
 425                 container, offset);
 426 
 427         if (tmp == 0 || tmp == -1ULL)
 428                 return 0;
 429         *tag = tmp;
 430         return 1;
 431 }
 432 
 433 char *get_static_filter(struct symbol *sym)
 434 {
 435         static char sql_filter[1024];
 436 
 437         /* This can only happen on buggy code.  Return invalid SQL. */
 438         if (!sym) {
 439                 sql_filter[0] = '\0';
 440                 return sql_filter;
 441         }
 442 
 443         if (sym->ctype.modifiers & MOD_STATIC) {
 444                 snprintf(sql_filter, sizeof(sql_filter),
 445                          "file = '%s' and function = '%s' and static = '1'",
 446                          get_base_file(), sym->ident->name);
 447         } else {
 448                 snprintf(sql_filter, sizeof(sql_filter),
 449                          "function = '%s' and static = '0'", sym->ident->name);
 450         }
 451 
 452         return sql_filter;
 453 }
 454 
 455 static int get_row_count(void *_row_count, int argc, char **argv, char **azColName)
 456 {
 457         int *row_count = _row_count;
 458 
 459         *row_count = 0;
 460         if (argc != 1)
 461                 return 0;
 462         *row_count = atoi(argv[0]);
 463         return 0;
 464 }
 465 
 466 static void mark_call_params_untracked(struct expression *call)
 467 {
 468         struct expression *arg;
 469         int i = 0;
 470 
 471         FOR_EACH_PTR(call->args, arg) {
 472                 mark_untracked(call, i++, "$", NULL);
 473         } END_FOR_EACH_PTR(arg);
 474 }
 475 
 476 static void sql_select_return_states_pointer(const char *cols,
 477         struct expression *call, int (*callback)(void*, int, char**, char**), void *info)
 478 {
 479         char *ptr;
 480         int return_count = 0;
 481 
 482         ptr = get_fnptr_name(call->fn);
 483         if (!ptr)
 484                 return;
 485 
 486         run_sql(get_row_count, &return_count,
 487                 "select count(*) from return_states join function_ptr "
 488                 "where return_states.function == function_ptr.function and "
 489                 "ptr = '%s' and searchable = 1 and type = %d;", ptr, INTERNAL);
 490         /* The magic number 100 is just from testing on the kernel. */
 491         if (return_count > 100) {
 492                 mark_call_params_untracked(call);
 493                 return;
 494         }
 495 
 496         run_sql(callback, info,
 497                 "select %s from return_states join function_ptr where "
 498                 "return_states.function == function_ptr.function and ptr = '%s' "
 499                 "and searchable = 1 "
 500                 "order by function_ptr.file, return_states.file, return_id, type;",
 501                 cols, ptr);
 502 }
 503 
 504 static int is_local_symbol(struct expression *expr)
 505 {
 506         if (expr->type != EXPR_SYMBOL)
 507                 return 0;
 508         if (expr->symbol->ctype.modifiers & (MOD_NONLOCAL | MOD_STATIC | MOD_ADDRESSABLE))
 509                 return 0;
 510         return 1;
 511 }
 512 
 513 void sql_select_return_states(const char *cols, struct expression *call,
 514         int (*callback)(void*, int, char**, char**), void *info)
 515 {
 516         int row_count = 0;
 517 
 518         if (is_fake_call(call))
 519                 return;
 520 
 521         if (call->fn->type != EXPR_SYMBOL || !call->fn->symbol || is_local_symbol(call->fn)) {
 522                 sql_select_return_states_pointer(cols, call, callback, info);
 523                 return;
 524         }
 525 
 526         if (inlinable(call->fn)) {
 527                 mem_sql(callback, info,
 528                         "select %s from return_states where call_id = '%lu' order by return_id, type;",
 529                         cols, (unsigned long)call);
 530                 return;
 531         }
 532 
 533         run_sql(get_row_count, &row_count, "select count(*) from return_states where %s;",
 534                 get_static_filter(call->fn->symbol));
 535         if (row_count > 3000)
 536                 return;
 537 
 538         run_sql(callback, info, "select %s from return_states where %s order by file, return_id, type;",
 539                 cols, get_static_filter(call->fn->symbol));
 540 }
 541 
 542 #define CALL_IMPLIES 0
 543 #define RETURN_IMPLIES 1
 544 
 545 struct implies_info {
 546         int type;
 547         struct db_implies_cb_list *cb_list;
 548         struct expression *expr;
 549         struct symbol *sym;
 550 };
 551 
 552 void sql_select_implies(const char *cols, struct implies_info *info,
 553         int (*callback)(void*, int, char**, char**))
 554 {
 555         if (info->type == RETURN_IMPLIES && inlinable(info->expr->fn)) {
 556                 mem_sql(callback, info,
 557                         "select %s from return_implies where call_id = '%lu';",
 558                         cols, (unsigned long)info->expr);
 559                 return;
 560         }
 561 
 562         run_sql(callback, info, "select %s from %s_implies where %s;",
 563                 cols,
 564                 info->type == CALL_IMPLIES ? "call" : "return",
 565                 get_static_filter(info->sym));
 566 }
 567 
 568 struct select_caller_info_data {
 569         struct stree *final_states;
 570         struct timeval start_time;
 571         int prev_func_id;
 572         int ignore;
 573         int results;
 574 };
 575 
 576 static int caller_info_callback(void *_data, int argc, char **argv, char **azColName);
 577 
 578 static void sql_select_caller_info(struct select_caller_info_data *data,
 579         const char *cols, struct symbol *sym)
 580 {
 581         if (__inline_fn) {
 582                 mem_sql(caller_info_callback, data,
 583                         "select %s from caller_info where call_id = %lu;",
 584                         cols, (unsigned long)__inline_fn);
 585                 return;
 586         }
 587 
 588         if (sym->ident->name && is_common_function(sym->ident->name))
 589                 return;
 590         run_sql(caller_info_callback, data,
 591                 "select %s from common_caller_info where %s order by call_id;",
 592                 cols, get_static_filter(sym));
 593         if (data->results)
 594                 return;
 595 
 596         run_sql(caller_info_callback, data,
 597                 "select %s from caller_info where %s order by call_id;",
 598                 cols, get_static_filter(sym));
 599 }
 600 
 601 void select_caller_info_hook(void (*callback)(const char *name, struct symbol *sym, char *key, char *value), int type)
 602 {
 603         struct def_callback *def_callback = __alloc_def_callback(0);
 604 
 605         def_callback->hook_type = type;
 606         def_callback->callback = callback;
 607         add_ptr_list(&select_caller_info_callbacks, def_callback);
 608 }
 609 
 610 /*
 611  * These call backs are used when the --info option is turned on to print struct
 612  * member information.  For example foo->bar could have a state in
 613  * smatch_extra.c and also check_user.c.
 614  */
 615 void add_member_info_callback(int owner, void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 616 {
 617         struct member_info_callback *member_callback = __alloc_member_info_callback(0);
 618 
 619         member_callback->owner = owner;
 620         member_callback->callback = callback;
 621         add_ptr_list(&member_callbacks, member_callback);
 622 }
 623 
 624 void add_split_return_callback(void (*fn)(int return_id, char *return_ranges, struct expression *returned_expr))
 625 {
 626         struct returned_state_callback *callback = __alloc_returned_state_callback(0);
 627 
 628         callback->callback = fn;
 629         add_ptr_list(&returned_state_callbacks, callback);
 630 }
 631 
 632 void add_returned_member_callback(int owner, void (*callback)(int return_id, char *return_ranges, struct expression *expr, char *printed_name, struct smatch_state *state))
 633 {
 634         struct returned_member_callback *member_callback = __alloc_returned_member_callback(0);
 635 
 636         member_callback->owner = owner;
 637         member_callback->callback = callback;
 638         add_ptr_list(&returned_member_callbacks, member_callback);
 639 }
 640 
 641 void select_call_implies_hook(int type, void (*callback)(struct expression *call, struct expression *arg, char *key, char *value))
 642 {
 643         struct db_implies_callback *cb = __alloc_db_implies_callback(0);
 644 
 645         cb->type = type;
 646         cb->callback = callback;
 647         add_ptr_list(&call_implies_cb_list, cb);
 648 }
 649 
 650 void select_return_implies_hook(int type, void (*callback)(struct expression *call, struct expression *arg, char *key, char *value))
 651 {
 652         struct db_implies_callback *cb = __alloc_db_implies_callback(0);
 653 
 654         cb->type = type;
 655         cb->callback = callback;
 656         add_ptr_list(&return_implies_cb_list, cb);
 657 }
 658 
 659 struct return_info {
 660         struct expression *static_returns_call;
 661         struct symbol *return_type;
 662         struct range_list *return_range_list;
 663 };
 664 
 665 static int db_return_callback(void *_ret_info, int argc, char **argv, char **azColName)
 666 {
 667         struct return_info *ret_info = _ret_info;
 668         struct range_list *rl;
 669         struct expression *call_expr = ret_info->static_returns_call;
 670 
 671         if (argc != 1)
 672                 return 0;
 673         call_results_to_rl(call_expr, ret_info->return_type, argv[0], &rl);
 674         ret_info->return_range_list = rl_union(ret_info->return_range_list, rl);
 675         return 0;
 676 }
 677 
 678 struct range_list *db_return_vals(struct expression *expr)
 679 {
 680         struct return_info ret_info = {};
 681         char buf[64];
 682         struct sm_state *sm;
 683 
 684         if (is_fake_call(expr))
 685                 return NULL;
 686 
 687         snprintf(buf, sizeof(buf), "return %p", expr);
 688         sm = get_sm_state(SMATCH_EXTRA, buf, NULL);
 689         if (sm)
 690                 return clone_rl(estate_rl(sm->state));
 691         ret_info.static_returns_call = expr;
 692         ret_info.return_type = get_type(expr);
 693         if (!ret_info.return_type)
 694                 return NULL;
 695 
 696         if (expr->fn->type != EXPR_SYMBOL || !expr->fn->symbol)
 697                 return NULL;
 698 
 699         ret_info.return_range_list = NULL;
 700         if (inlinable(expr->fn)) {
 701                 mem_sql(db_return_callback, &ret_info,
 702                         "select distinct return from return_states where call_id = '%lu';",
 703                         (unsigned long)expr);
 704         } else {
 705                 run_sql(db_return_callback, &ret_info,
 706                         "select distinct return from return_states where %s;",
 707                         get_static_filter(expr->fn->symbol));
 708         }
 709         return ret_info.return_range_list;
 710 }
 711 
 712 struct range_list *db_return_vals_from_str(const char *fn_name)
 713 {
 714         struct return_info ret_info;
 715 
 716         ret_info.static_returns_call = NULL;
 717         ret_info.return_type = &llong_ctype;
 718         ret_info.return_range_list = NULL;
 719 
 720         run_sql(db_return_callback, &ret_info,
 721                 "select distinct return from return_states where function = '%s';",
 722                 fn_name);
 723         return ret_info.return_range_list;
 724 }
 725 
 726 static void match_call_marker(struct expression *expr)
 727 {
 728         struct symbol *type;
 729 
 730         type = get_type(expr->fn);
 731         if (type && type->type == SYM_PTR)
 732                 type = get_real_base_type(type);
 733 
 734         /*
 735          * we just want to record something in the database so that if we have
 736          * two calls like:  frob(4); frob(some_unkown); then on the receiving
 737          * side we know that sometimes frob is called with unknown parameters.
 738          */
 739 
 740         sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type));
 741 }
 742 
 743 static char *show_offset(int offset)
 744 {
 745         static char buf[64];
 746 
 747         buf[0] = '\0';
 748         if (offset != -1)
 749                 snprintf(buf, sizeof(buf), "(-%d)", offset);
 750         return buf;
 751 }
 752 
 753 static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
 754         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 755 {
 756         struct sm_state *sm;
 757         char *name;
 758         struct symbol *sym;
 759         int len;
 760         char printed_name[256];
 761         int is_address = 0;
 762         struct symbol *type;
 763 
 764         expr = strip_expr(expr);
 765         if (!expr)
 766                 return;
 767         if (expr->type == EXPR_PREOP && expr->op == '&') {
 768                 expr = strip_expr(expr->unop);
 769                 is_address = 1;
 770         }
 771 
 772         type = get_type(expr);
 773         if (type && type_bits(type) < type_bits(&ulong_ctype))
 774                 return;
 775 
 776         name = expr_to_var_sym(expr, &sym);
 777         if (!name || !sym)
 778                 goto free;
 779 
 780         len = strlen(name);
 781         FOR_EACH_SM(stree, sm) {
 782                 if (sm->sym != sym)
 783                         continue;
 784                 if (strcmp(name, sm->name) == 0) {
 785                         if (is_address)
 786                                 snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 787                         else /* these are already handled. fixme: handle them here */
 788                                 continue;
 789                 } else if (sm->name[0] == '*' && strcmp(name, sm->name + 1) == 0) {
 790                         snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 791                 } else if (strncmp(name, sm->name, len) == 0) {
 792                         if (isalnum(sm->name[len]))
 793                                 continue;
 794                         if (is_address)
 795                                 snprintf(printed_name, sizeof(printed_name), "$%s->%s", show_offset(offset), sm->name + len + 1);
 796                         else
 797                                 snprintf(printed_name, sizeof(printed_name), "$%s%s", show_offset(offset), sm->name + len);
 798                 } else {
 799                         continue;
 800                 }
 801                 callback(call, param, printed_name, sm);
 802         } END_FOR_EACH_SM(sm);
 803 free:
 804         free_string(name);
 805 }
 806 
 807 static int param_used_callback(void *_container, int argc, char **argv, char **azColName)
 808 {
 809         char **container = _container;
 810         static char buf[256];
 811 
 812         snprintf(buf, sizeof(buf), "%s", argv[0]);
 813         *container = buf;
 814         return 0;
 815 }
 816 
 817 static void print_container_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
 818         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 819 {
 820         struct expression *tmp;
 821         char *container = NULL;
 822         int offset;
 823         int holder_offset;
 824         char *p;
 825 
 826         if (!call->fn || call->fn->type != EXPR_SYMBOL || !call->fn->symbol)
 827                 return;
 828 
 829         /*
 830          * We can't use the in-mem DB because we have to parse the function
 831          * first, then we know if it takes a container, then we know to pass it
 832          * the container data.
 833          *
 834          */
 835         run_sql(&param_used_callback, &container,
 836                 "select key from return_implies where %s and type = %d and key like '%%$(%%' and parameter = %d limit 1;",
 837                 get_static_filter(call->fn->symbol), CONTAINER, param);
 838         if (!container)
 839                 return;
 840 
 841         p = strchr(container, '-');
 842         if (!p)
 843                 return;
 844         offset = atoi(p);
 845         p = strchr(p, ')');
 846         if (!p)
 847                 return;
 848         p++;
 849 
 850         tmp = get_assigned_expr(expr);
 851         if (tmp)
 852                 expr = tmp;
 853 
 854         if (expr->type != EXPR_PREOP || expr->op != '&')
 855                 return;
 856         expr = strip_expr(expr->unop);
 857         holder_offset = get_member_offset_from_deref(expr);
 858         if (-holder_offset != offset)
 859                 return;
 860 
 861         expr = strip_expr(expr->deref);
 862         if (expr->type == EXPR_PREOP && expr->op == '*')
 863                 expr = strip_expr(expr->unop);
 864 
 865         print_struct_members(call, expr, param, holder_offset, stree, callback);
 866 }
 867 
 868 static void match_call_info(struct expression *call)
 869 {
 870         struct member_info_callback *cb;
 871         struct expression *arg;
 872         struct stree *stree;
 873         char *name;
 874         int i;
 875 
 876         name = get_fnptr_name(call->fn);
 877         if (!name)
 878                 return;
 879 
 880         FOR_EACH_PTR(member_callbacks, cb) {
 881                 stree = get_all_states_stree(cb->owner);
 882                 i = 0;
 883                 FOR_EACH_PTR(call->args, arg) {
 884                         print_struct_members(call, arg, i, -1, stree, cb->callback);
 885                         print_container_struct_members(call, arg, i, stree, cb->callback);
 886                         i++;
 887                 } END_FOR_EACH_PTR(arg);
 888                 free_stree(&stree);
 889         } END_FOR_EACH_PTR(cb);
 890 
 891         free_string(name);
 892 }
 893 
 894 static int get_param(int param, char **name, struct symbol **sym)
 895 {
 896         struct symbol *arg;
 897         int i;
 898 
 899         i = 0;
 900         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
 901                 /*
 902                  * this is a temporary hack to work around a bug (I think in sparse?)
 903                  * 2.6.37-rc1:fs/reiserfs/journal.o
 904                  * If there is a function definition without parameter name found
 905                  * after a function implementation then it causes a crash.
 906                  * int foo() {}
 907                  * int bar(char *);
 908                  */
 909                 if (arg->ident->name < (char *)100)
 910                         continue;
 911                 if (i == param) {
 912                         *name = arg->ident->name;
 913                         *sym = arg;
 914                         return TRUE;
 915                 }
 916                 i++;
 917         } END_FOR_EACH_PTR(arg);
 918 
 919         return FALSE;
 920 }
 921 
 922 static int function_signature_matches(const char *sig)
 923 {
 924         char *my_sig;
 925 
 926         my_sig = function_signature();
 927         if (!sig || !my_sig)
 928                 return 1;  /* default to matching */
 929         if (strcmp(my_sig, sig) == 0)
 930                   return 1;
 931         return 0;
 932 }
 933 
 934 static int caller_info_callback(void *_data, int argc, char **argv, char **azColName)
 935 {
 936         struct select_caller_info_data *data = _data;
 937         int func_id;
 938         long type;
 939         long param;
 940         char *key;
 941         char *value;
 942         char *name = NULL;
 943         struct symbol *sym = NULL;
 944         struct def_callback *def_callback;
 945         struct stree *stree;
 946         struct timeval cur_time;
 947 
 948         data->results = 1;
 949 
 950         if (argc != 5)
 951                 return 0;
 952 
 953         gettimeofday(&cur_time, NULL);
 954         if (cur_time.tv_sec - data->start_time.tv_sec > 10)
 955                 return 0;
 956 
 957         func_id = atoi(argv[0]);
 958         errno = 0;
 959         type = strtol(argv[1], NULL, 10);
 960         param = strtol(argv[2], NULL, 10);
 961         if (errno)
 962                 return 0;
 963         key = argv[3];
 964         value = argv[4];
 965 
 966         if (data->prev_func_id == -1)
 967                 data->prev_func_id = func_id;
 968         if (func_id != data->prev_func_id) {
 969                 stree = __pop_fake_cur_stree();
 970                 if (!data->ignore)
 971                         merge_stree(&data->final_states, stree);
 972                 free_stree(&stree);
 973                 __push_fake_cur_stree();
 974                 __unnullify_path();
 975                 data->prev_func_id = func_id;
 976                 data->ignore = 0;
 977         }
 978 
 979         if (data->ignore)
 980                 return 0;
 981         if (type == INTERNAL &&
 982             !function_signature_matches(value)) {
 983                 data->ignore = 1;
 984                 return 0;
 985         }
 986 
 987         if (param >= 0 && !get_param(param, &name, &sym))
 988                 return 0;
 989 
 990         FOR_EACH_PTR(select_caller_info_callbacks, def_callback) {
 991                 if (def_callback->hook_type == type)
 992                         def_callback->callback(name, sym, key, value);
 993         } END_FOR_EACH_PTR(def_callback);
 994 
 995         return 0;
 996 }
 997 
 998 static struct string_list *ptr_names_done;
 999 static struct string_list *ptr_names;
1000 
1001 static int get_ptr_name(void *unused, int argc, char **argv, char **azColName)
1002 {
1003         insert_string(&ptr_names, alloc_string(argv[0]));
1004         return 0;
1005 }
1006 
1007 static char *get_next_ptr_name(void)
1008 {
1009         char *ptr;
1010 
1011         FOR_EACH_PTR(ptr_names, ptr) {
1012                 if (list_has_string(ptr_names_done, ptr))
1013                         continue;
1014                 insert_string(&ptr_names_done, ptr);
1015                 return ptr;
1016         } END_FOR_EACH_PTR(ptr);
1017         return NULL;
1018 }
1019 
1020 static void get_ptr_names(const char *file, const char *name)
1021 {
1022         char sql_filter[1024];
1023         int before, after;
1024 
1025         if (file) {
1026                 snprintf(sql_filter, 1024, "file = '%s' and function = '%s';",
1027                          file, name);
1028         } else {
1029                 snprintf(sql_filter, 1024, "function = '%s';", name);
1030         }
1031 
1032         before = ptr_list_size((struct ptr_list *)ptr_names);
1033 
1034         run_sql(get_ptr_name, NULL,
1035                 "select distinct ptr from function_ptr where %s",
1036                 sql_filter);
1037 
1038         after = ptr_list_size((struct ptr_list *)ptr_names);
1039         if (before == after)
1040                 return;
1041 
1042         while ((name = get_next_ptr_name()))
1043                 get_ptr_names(NULL, name);
1044 }
1045 
1046 static void match_data_from_db(struct symbol *sym)
1047 {
1048         struct select_caller_info_data data = { .prev_func_id = -1 };
1049         struct sm_state *sm;
1050         struct stree *stree;
1051         struct timeval end_time;
1052 
1053         if (!sym || !sym->ident)
1054                 return;
1055 
1056         gettimeofday(&data.start_time, NULL);
1057 
1058         __push_fake_cur_stree();
1059         __unnullify_path();
1060 
1061         if (!__inline_fn) {
1062                 char *ptr;
1063 
1064                 if (sym->ctype.modifiers & MOD_STATIC)
1065                         get_ptr_names(get_base_file(), sym->ident->name);
1066                 else
1067                         get_ptr_names(NULL, sym->ident->name);
1068 
1069                 if (ptr_list_size((struct ptr_list *)ptr_names) > 20) {
1070                         __free_ptr_list((struct ptr_list **)&ptr_names);
1071                         __free_ptr_list((struct ptr_list **)&ptr_names_done);
1072                         stree = __pop_fake_cur_stree();
1073                         free_stree(&stree);
1074                         return;
1075                 }
1076 
1077                 sql_select_caller_info(&data,
1078                                        "call_id, type, parameter, key, value",
1079                                        sym);
1080 
1081 
1082                 stree = __pop_fake_cur_stree();
1083                 if (!data.ignore)
1084                         merge_stree(&data.final_states, stree);
1085                 free_stree(&stree);
1086                 __push_fake_cur_stree();
1087                 __unnullify_path();
1088                 data.prev_func_id = -1;
1089                 data.ignore = 0;
1090 
1091                 FOR_EACH_PTR(ptr_names, ptr) {
1092                         run_sql(caller_info_callback, &data,
1093                                 "select call_id, type, parameter, key, value"
1094                                 " from common_caller_info where function = '%s' order by call_id",
1095                                 ptr);
1096                 } END_FOR_EACH_PTR(ptr);
1097 
1098                 if (data.results) {
1099                         FOR_EACH_PTR(ptr_names, ptr) {
1100                                 free_string(ptr);
1101                         } END_FOR_EACH_PTR(ptr);
1102                         goto free_ptr_names;
1103                 }
1104 
1105                 FOR_EACH_PTR(ptr_names, ptr) {
1106                         run_sql(caller_info_callback, &data,
1107                                 "select call_id, type, parameter, key, value"
1108                                 " from caller_info where function = '%s' order by call_id",
1109                                 ptr);
1110                         free_string(ptr);
1111                 } END_FOR_EACH_PTR(ptr);
1112 
1113 free_ptr_names:
1114                 __free_ptr_list((struct ptr_list **)&ptr_names);
1115                 __free_ptr_list((struct ptr_list **)&ptr_names_done);
1116         } else {
1117                 sql_select_caller_info(&data,
1118                                        "call_id, type, parameter, key, value",
1119                                        sym);
1120         }
1121 
1122         stree = __pop_fake_cur_stree();
1123         if (!data.ignore)
1124                 merge_stree(&data.final_states, stree);
1125         free_stree(&stree);
1126 
1127         gettimeofday(&end_time, NULL);
1128         if (end_time.tv_sec - data.start_time.tv_sec <= 10) {
1129                 FOR_EACH_SM(data.final_states, sm) {
1130                         __set_sm(sm);
1131                 } END_FOR_EACH_SM(sm);
1132         }
1133 
1134         free_stree(&data.final_states);
1135 }
1136 
1137 static int return_implies_callbacks(void *_info, int argc, char **argv, char **azColName)
1138 {
1139         struct implies_info *info = _info;
1140         struct db_implies_callback *cb;
1141         struct expression *arg = NULL;
1142         int type;
1143         int param;
1144 
1145         if (argc != 5)
1146                 return 0;
1147 
1148         type = atoi(argv[1]);
1149         param = atoi(argv[2]);
1150 
1151         FOR_EACH_PTR(info->cb_list, cb) {
1152                 if (cb->type != type)
1153                         continue;
1154                 if (param != -1) {
1155                         arg = get_argument_from_call_expr(info->expr->args, param);
1156                         if (!arg)
1157                                 continue;
1158                 }
1159                 cb->callback(info->expr, arg, argv[3], argv[4]);
1160         } END_FOR_EACH_PTR(cb);
1161 
1162         return 0;
1163 }
1164 
1165 static int call_implies_callbacks(void *_info, int argc, char **argv, char **azColName)
1166 {
1167         struct implies_info *info = _info;
1168         struct db_implies_callback *cb;
1169         struct expression *arg;
1170         struct symbol *sym;
1171         char *name;
1172         int type;
1173         int param;
1174 
1175         if (argc != 5)
1176                 return 0;
1177 
1178         type = atoi(argv[1]);
1179         param = atoi(argv[2]);
1180 
1181         if (!get_param(param, &name, &sym))
1182                 return 0;
1183         arg = symbol_expression(sym);
1184         if (!arg)
1185                 return 0;
1186 
1187         FOR_EACH_PTR(info->cb_list, cb) {
1188                 if (cb->type != type)
1189                         continue;
1190                 cb->callback(info->expr, arg, argv[3], argv[4]);
1191         } END_FOR_EACH_PTR(cb);
1192 
1193         return 0;
1194 }
1195 
1196 static void match_return_implies(struct expression *expr)
1197 {
1198         struct implies_info info = {
1199                 .type = RETURN_IMPLIES,
1200                 .cb_list = return_implies_cb_list,
1201         };
1202 
1203         if (expr->fn->type != EXPR_SYMBOL ||
1204             !expr->fn->symbol)
1205                 return;
1206         info.expr = expr;
1207         info.sym = expr->fn->symbol;
1208         sql_select_implies("function, type, parameter, key, value", &info,
1209                            return_implies_callbacks);
1210 }
1211 
1212 static void match_call_implies(struct symbol *sym)
1213 {
1214         struct implies_info info = {
1215                 .type = CALL_IMPLIES,
1216                 .cb_list = call_implies_cb_list,
1217         };
1218 
1219         if (!sym || !sym->ident)
1220                 return;
1221 
1222         info.sym = sym;
1223         sql_select_implies("function, type, parameter, key, value", &info,
1224                            call_implies_callbacks);
1225 }
1226 
1227 static void print_initializer_list(struct expression_list *expr_list,
1228                 struct symbol *struct_type)
1229 {
1230         struct expression *expr;
1231         struct symbol *base_type;
1232         char struct_name[256];
1233 
1234         FOR_EACH_PTR(expr_list, expr) {
1235                 if (expr->type == EXPR_INDEX && expr->idx_expression && expr->idx_expression->type == EXPR_INITIALIZER) {
1236                         print_initializer_list(expr->idx_expression->expr_list, struct_type);
1237                         continue;
1238                 }
1239                 if (expr->type != EXPR_IDENTIFIER)
1240                         continue;
1241                 if (!expr->expr_ident)
1242                         continue;
1243                 if (!expr->ident_expression || !expr->ident_expression->symbol_name)
1244                         continue;
1245                 base_type = get_type(expr->ident_expression);
1246                 if (!base_type || base_type->type != SYM_FN)
1247                         continue;
1248                 snprintf(struct_name, sizeof(struct_name), "(struct %s)->%s",
1249                          struct_type->ident->name, expr->expr_ident->name);
1250                 sql_insert_function_ptr(expr->ident_expression->symbol_name->name,
1251                                         struct_name);
1252         } END_FOR_EACH_PTR(expr);
1253 }
1254 
1255 static void global_variable(struct symbol *sym)
1256 {
1257         struct symbol *struct_type;
1258 
1259         if (!sym->ident)
1260                 return;
1261         if (!sym->initializer || sym->initializer->type != EXPR_INITIALIZER)
1262                 return;
1263         struct_type = get_base_type(sym);
1264         if (!struct_type)
1265                 return;
1266         if (struct_type->type == SYM_ARRAY) {
1267                 struct_type = get_base_type(struct_type);
1268                 if (!struct_type)
1269                         return;
1270         }
1271         if (struct_type->type != SYM_STRUCT || !struct_type->ident)
1272                 return;
1273         print_initializer_list(sym->initializer->expr_list, struct_type);
1274 }
1275 
1276 static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
1277 {
1278         sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
1279 }
1280 
1281 static void call_return_state_hooks_conditional(struct expression *expr)
1282 {
1283         struct returned_state_callback *cb;
1284         struct range_list *rl;
1285         char *return_ranges;
1286         int final_pass_orig = final_pass;
1287 
1288         __push_fake_cur_stree();
1289 
1290         final_pass = 0;
1291         __split_whole_condition(expr->conditional);
1292         final_pass = final_pass_orig;
1293 
1294         if (get_implied_rl(expr->cond_true, &rl))
1295                 rl = cast_rl(cur_func_return_type(), rl);
1296         else
1297                 rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_true)));
1298         return_ranges = show_rl(rl);
1299         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1300 
1301         return_id++;
1302         FOR_EACH_PTR(returned_state_callbacks, cb) {
1303                 cb->callback(return_id, return_ranges, expr->cond_true);
1304         } END_FOR_EACH_PTR(cb);
1305 
1306         __push_true_states();
1307         __use_false_states();
1308 
1309         if (get_implied_rl(expr->cond_false, &rl))
1310                 rl = cast_rl(cur_func_return_type(), rl);
1311         else
1312                 rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_false)));
1313         return_ranges = show_rl(rl);
1314         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1315 
1316         return_id++;
1317         FOR_EACH_PTR(returned_state_callbacks, cb) {
1318                 cb->callback(return_id, return_ranges, expr->cond_false);
1319         } END_FOR_EACH_PTR(cb);
1320 
1321         __merge_true_states();
1322         __free_fake_cur_stree();
1323 }
1324 
1325 static void call_return_state_hooks_compare(struct expression *expr)
1326 {
1327         struct returned_state_callback *cb;
1328         char *return_ranges;
1329         int final_pass_orig = final_pass;
1330         sval_t sval = { .type = &int_ctype };
1331         sval_t ret;
1332 
1333         if (!get_implied_value(expr, &ret))
1334                 ret.value = -1;
1335 
1336         __push_fake_cur_stree();
1337 
1338         final_pass = 0;
1339         __split_whole_condition(expr);
1340         final_pass = final_pass_orig;
1341 
1342         if (ret.value != 0) {
1343                 return_ranges = alloc_sname("1");
1344                 sval.value = 1;
1345                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_sval(sval));
1346 
1347                 return_id++;
1348                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1349                         cb->callback(return_id, return_ranges, expr);
1350                 } END_FOR_EACH_PTR(cb);
1351         }
1352 
1353         __push_true_states();
1354         __use_false_states();
1355 
1356         if (ret.value != 1) {
1357                 return_ranges = alloc_sname("0");
1358                 sval.value = 0;
1359                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_sval(sval));
1360 
1361                 return_id++;
1362                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1363                         cb->callback(return_id, return_ranges, expr);
1364                 } END_FOR_EACH_PTR(cb);
1365         }
1366 
1367         __merge_true_states();
1368         __free_fake_cur_stree();
1369 }
1370 
1371 static int ptr_in_list(struct sm_state *sm, struct state_list *slist)
1372 {
1373         struct sm_state *tmp;
1374 
1375         FOR_EACH_PTR(slist, tmp) {
1376                 if (strcmp(tmp->state->name, sm->state->name) == 0)
1377                         return 1;
1378         } END_FOR_EACH_PTR(tmp);
1379 
1380         return 0;
1381 }
1382 
1383 static char *get_return_compare_str(struct expression *expr)
1384 {
1385         char *compare_str;
1386         char *var;
1387         char buf[256];
1388         int comparison;
1389         int param;
1390 
1391         compare_str = expr_lte_to_param(expr, -1);
1392         if (compare_str)
1393                 return compare_str;
1394         param = get_param_num(expr);
1395         if (param < 0)
1396                 return NULL;
1397 
1398         var = expr_to_var(expr);
1399         if (!var)
1400                 return NULL;
1401         snprintf(buf, sizeof(buf), "%s orig", var);
1402         comparison = get_comparison_strings(var, buf);
1403         free_string(var);
1404 
1405         if (!comparison)
1406                 return NULL;
1407 
1408         snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
1409         return alloc_sname(buf);
1410 }
1411 
1412 static int split_possible_helper(struct sm_state *sm, struct expression *expr)
1413 {
1414         struct returned_state_callback *cb;
1415         struct range_list *rl;
1416         char *return_ranges;
1417         struct sm_state *tmp;
1418         int ret = 0;
1419         int nr_possible, nr_states;
1420         char *compare_str = NULL;
1421         char buf[128];
1422         struct state_list *already_handled = NULL;
1423 
1424         if (!sm || !sm->merged)
1425                 return 0;
1426 
1427         if (too_many_possible(sm))
1428                 return 0;
1429 
1430         /* bail if it gets too complicated */
1431         nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
1432         nr_states = get_db_state_count();
1433         if (nr_states * nr_possible >= 2000)
1434                 return 0;
1435 
1436         FOR_EACH_PTR(sm->possible, tmp) {
1437                 if (tmp->merged)
1438                         continue;
1439                 if (ptr_in_list(tmp, already_handled))
1440                         continue;
1441                 add_ptr_list(&already_handled, tmp);
1442 
1443                 ret = 1;
1444                 __push_fake_cur_stree();
1445 
1446                 overwrite_states_using_pool(sm, tmp);
1447 
1448                 rl = cast_rl(cur_func_return_type(), estate_rl(tmp->state));
1449                 return_ranges = show_rl(rl);
1450                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(clone_rl(rl)));
1451                 compare_str = get_return_compare_str(expr);
1452                 if (compare_str) {
1453                         snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1454                         return_ranges = alloc_sname(buf);
1455                 }
1456 
1457                 return_id++;
1458                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1459                         cb->callback(return_id, return_ranges, expr);
1460                 } END_FOR_EACH_PTR(cb);
1461 
1462                 __free_fake_cur_stree();
1463         } END_FOR_EACH_PTR(tmp);
1464 
1465         free_slist(&already_handled);
1466 
1467         return ret;
1468 }
1469 
1470 static int call_return_state_hooks_split_possible(struct expression *expr)
1471 {
1472         struct sm_state *sm;
1473 
1474         if (!expr || expr_equal_to_param(expr, -1))
1475                 return 0;
1476 
1477         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1478         return split_possible_helper(sm, expr);
1479 }
1480 
1481 static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
1482 {
1483         struct range_list *rl;
1484         char *return_ranges;
1485         sval_t sval;
1486         char *compare_str;
1487         char *math_str;
1488         char buf[128];
1489 
1490         *rl_p = NULL;
1491 
1492         if (!expr)
1493                 return alloc_sname("");
1494 
1495         if (get_implied_value(expr, &sval)) {
1496                 sval = sval_cast(cur_func_return_type(), sval);
1497                 *rl_p = alloc_rl(sval, sval);
1498                 return sval_to_str(sval);
1499         }
1500 
1501         compare_str = expr_equal_to_param(expr, -1);
1502         math_str = get_value_in_terms_of_parameter_math(expr);
1503 
1504         if (get_implied_rl(expr, &rl)) {
1505                 rl = cast_rl(cur_func_return_type(), rl);
1506                 return_ranges = show_rl(rl);
1507         } else if (get_imaginary_absolute(expr, &rl)){
1508                 rl = cast_rl(cur_func_return_type(), rl);
1509                 return alloc_sname(show_rl(rl));
1510         } else {
1511                 rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr)));
1512                 return_ranges = show_rl(rl);
1513         }
1514         *rl_p = rl;
1515 
1516         if (compare_str) {
1517                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1518                 return alloc_sname(buf);
1519         }
1520         if (math_str) {
1521                 snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
1522                 return alloc_sname(buf);
1523         }
1524         compare_str = get_return_compare_str(expr);
1525         if (compare_str) {
1526                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1527                 return alloc_sname(buf);
1528         }
1529 
1530         return return_ranges;
1531 }
1532 
1533 static bool has_possible_negative(struct sm_state *sm)
1534 {
1535         struct sm_state *tmp;
1536 
1537         FOR_EACH_PTR(sm->possible, tmp) {
1538                 if (!estate_rl(tmp->state))
1539                         continue;
1540                 if (sval_is_negative(estate_min(tmp->state)) &&
1541                     sval_is_negative(estate_max(tmp->state)))
1542                         return true;
1543         } END_FOR_EACH_PTR(tmp);
1544 
1545         return false;
1546 }
1547 
1548 static bool has_possible_zero_null(struct sm_state *sm)
1549 {
1550         struct sm_state *tmp;
1551         sval_t sval;
1552 
1553         FOR_EACH_PTR(sm->possible, tmp) {
1554                 if (!estate_get_single_value(tmp->state, &sval))
1555                         continue;
1556                 if (sval.value == 0)
1557                         return true;
1558         } END_FOR_EACH_PTR(tmp);
1559 
1560         return false;
1561 }
1562 
1563 static int split_positive_from_negative(struct expression *expr)
1564 {
1565         struct sm_state *sm;
1566         struct returned_state_callback *cb;
1567         struct range_list *rl;
1568         const char *return_ranges;
1569         struct range_list *ret_rl;
1570         int undo;
1571 
1572         /* We're going to print the states 3 times */
1573         if (get_db_state_count() > 10000 / 3)
1574                 return 0;
1575 
1576         if (!get_implied_rl(expr, &rl) || !rl)
1577                 return 0;
1578         if (is_whole_rl(rl) || is_whole_rl_non_zero(rl))
1579                 return 0;
1580         /* Forget about INT_MAX and larger */
1581         if (rl_max(rl).value <= 0)
1582                 return 0;
1583         if (!sval_is_negative(rl_min(rl)))
1584                 return 0;
1585 
1586         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1587         if (!sm)
1588                 return 0;
1589         if (!has_possible_negative(sm))
1590                 return 0;
1591 
1592         if (!assume(compare_expression(expr, '>', zero_expr())))
1593                 return 0;
1594 
1595         return_id++;
1596         return_ranges = get_return_ranges_str(expr, &ret_rl);
1597         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1598         FOR_EACH_PTR(returned_state_callbacks, cb) {
1599                 cb->callback(return_id, (char *)return_ranges, expr);
1600         } END_FOR_EACH_PTR(cb);
1601 
1602         end_assume();
1603 
1604         if (rl_has_sval(rl, sval_type_val(rl_type(rl), 0))) {
1605                 undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
1606 
1607                 return_id++;
1608                 return_ranges = get_return_ranges_str(expr, &ret_rl);
1609                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1610                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1611                         cb->callback(return_id, (char *)return_ranges, expr);
1612                 } END_FOR_EACH_PTR(cb);
1613 
1614                 if (undo)
1615                         end_assume();
1616         }
1617 
1618         undo = assume(compare_expression(expr, '<', zero_expr()));
1619 
1620         return_id++;
1621         return_ranges = get_return_ranges_str(expr, &ret_rl);
1622         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1623         FOR_EACH_PTR(returned_state_callbacks, cb) {
1624                 cb->callback(return_id, (char *)return_ranges, expr);
1625         } END_FOR_EACH_PTR(cb);
1626 
1627         if (undo)
1628                 end_assume();
1629 
1630         return 1;
1631 }
1632 
1633 static int call_return_state_hooks_split_null_non_null(struct expression *expr)
1634 {
1635         struct returned_state_callback *cb;
1636         struct range_list *rl;
1637         struct range_list *nonnull_rl;
1638         sval_t null_sval;
1639         struct range_list *null_rl = NULL;
1640         char *return_ranges;
1641         struct sm_state *sm;
1642         struct smatch_state *state;
1643         int nr_states;
1644         int final_pass_orig = final_pass;
1645 
1646         if (!expr || expr_equal_to_param(expr, -1))
1647                 return 0;
1648         if (expr->type == EXPR_CALL)
1649                 return 0;
1650         if (!is_pointer(expr))
1651                 return 0;
1652 
1653         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1654         if (!sm)
1655                 return 0;
1656         if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1657                 return 0;
1658         state = sm->state;
1659         if (!estate_rl(state))
1660                 return 0;
1661         if (estate_min(state).value == 0 && estate_max(state).value == 0)
1662                 return 0;
1663         if (!has_possible_zero_null(sm))
1664                 return 0;
1665 
1666         nr_states = get_db_state_count();
1667         if (option_info && nr_states >= 1500)
1668                 return 0;
1669 
1670         rl = estate_rl(state);
1671 
1672         __push_fake_cur_stree();
1673 
1674         final_pass = 0;
1675         __split_whole_condition(expr);
1676         final_pass = final_pass_orig;
1677 
1678         nonnull_rl = rl_filter(rl, rl_zero());
1679         return_ranges = show_rl(nonnull_rl);
1680         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(nonnull_rl));
1681 
1682         return_id++;
1683         FOR_EACH_PTR(returned_state_callbacks, cb) {
1684                 cb->callback(return_id, return_ranges, expr);
1685         } END_FOR_EACH_PTR(cb);
1686 
1687         __push_true_states();
1688         __use_false_states();
1689 
1690         return_ranges = alloc_sname("0");
1691         null_sval = sval_type_val(rl_type(rl), 0);
1692         add_range(&null_rl, null_sval, null_sval);
1693         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(null_rl));
1694         return_id++;
1695         FOR_EACH_PTR(returned_state_callbacks, cb) {
1696                 cb->callback(return_id, return_ranges, expr);
1697         } END_FOR_EACH_PTR(cb);
1698 
1699         __merge_true_states();
1700         __free_fake_cur_stree();
1701 
1702         return 1;
1703 }
1704 
1705 static int call_return_state_hooks_split_success_fail(struct expression *expr)
1706 {
1707         struct sm_state *sm;
1708         struct range_list *rl;
1709         struct range_list *nonzero_rl;
1710         sval_t zero_sval;
1711         struct range_list *zero_rl = NULL;
1712         int nr_states;
1713         struct returned_state_callback *cb;
1714         char *return_ranges;
1715         int final_pass_orig = final_pass;
1716 
1717         if (option_project != PROJ_KERNEL)
1718                 return 0;
1719 
1720         nr_states = get_db_state_count();
1721         if (nr_states > 1500)
1722                 return 0;
1723 
1724         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1725         if (!sm)
1726                 return 0;
1727         if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1728                 return 0;
1729 
1730         rl = estate_rl(sm->state);
1731         if (!rl)
1732                 return 0;
1733 
1734         if (rl_min(rl).value < -4095 || rl_min(rl).value >= 0)
1735                 return 0;
1736         if (rl_max(rl).value != 0)
1737                 return 0;
1738         if (!has_possible_zero_null(sm))
1739                 return 0;
1740 
1741         __push_fake_cur_stree();
1742 
1743         final_pass = 0;
1744         __split_whole_condition(expr);
1745         final_pass = final_pass_orig;
1746 
1747         nonzero_rl = rl_filter(rl, rl_zero());
1748         nonzero_rl = cast_rl(cur_func_return_type(), nonzero_rl);
1749         return_ranges = show_rl(nonzero_rl);
1750         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(nonzero_rl));
1751 
1752         return_id++;
1753         FOR_EACH_PTR(returned_state_callbacks, cb) {
1754                 cb->callback(return_id, return_ranges, expr);
1755         } END_FOR_EACH_PTR(cb);
1756 
1757         __push_true_states();
1758         __use_false_states();
1759 
1760         return_ranges = alloc_sname("0");
1761         zero_sval = sval_type_val(rl_type(rl), 0);
1762         add_range(&zero_rl, zero_sval, zero_sval);
1763         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(zero_rl));
1764         return_id++;
1765         FOR_EACH_PTR(returned_state_callbacks, cb) {
1766                 cb->callback(return_id, return_ranges, expr);
1767         } END_FOR_EACH_PTR(cb);
1768 
1769         __merge_true_states();
1770         __free_fake_cur_stree();
1771 
1772         return 1;
1773 }
1774 
1775 static int is_boolean(struct expression *expr)
1776 {
1777         struct range_list *rl;
1778 
1779         if (!get_implied_rl(expr, &rl))
1780                 return 0;
1781         if (rl_min(rl).value == 0 && rl_max(rl).value == 1)
1782                 return 1;
1783         return 0;
1784 }
1785 
1786 static int is_conditional(struct expression *expr)
1787 {
1788         if (!expr)
1789                 return 0;
1790         if (expr->type == EXPR_CONDITIONAL || expr->type == EXPR_SELECT)
1791                 return 1;
1792         return 0;
1793 }
1794 
1795 static int splitable_function_call(struct expression *expr)
1796 {
1797         struct sm_state *sm;
1798         char buf[64];
1799 
1800         if (!expr || expr->type != EXPR_CALL)
1801                 return 0;
1802         snprintf(buf, sizeof(buf), "return %p", expr);
1803         sm = get_sm_state(SMATCH_EXTRA, buf, NULL);
1804         return split_possible_helper(sm, expr);
1805 }
1806 
1807 static struct sm_state *find_bool_param(void)
1808 {
1809         struct stree *start_states;
1810         struct symbol *arg;
1811         struct sm_state *sm, *tmp;
1812         sval_t sval;
1813 
1814         start_states = get_start_states();
1815 
1816         FOR_EACH_PTR_REVERSE(cur_func_sym->ctype.base_type->arguments, arg) {
1817                 if (!arg->ident)
1818                         continue;
1819                 sm = get_sm_state_stree(start_states, SMATCH_EXTRA, arg->ident->name, arg);
1820                 if (!sm)
1821                         continue;
1822                 if (rl_min(estate_rl(sm->state)).value != 0 ||
1823                     rl_max(estate_rl(sm->state)).value != 1)
1824                         continue;
1825                 goto found;
1826         } END_FOR_EACH_PTR_REVERSE(arg);
1827 
1828         return NULL;
1829 
1830 found:
1831         /*
1832          * Check if it's splitable.  If not, then splitting it up is likely not
1833          * useful for the callers.
1834          */
1835         FOR_EACH_PTR(sm->possible, tmp) {
1836                 if (is_merged(tmp))
1837                         continue;
1838                 if (!estate_get_single_value(tmp->state, &sval))
1839                         return NULL;
1840         } END_FOR_EACH_PTR(tmp);
1841 
1842         return sm;
1843 }
1844 
1845 static int split_on_bool_sm(struct sm_state *sm, struct expression *expr)
1846 {
1847         struct returned_state_callback *cb;
1848         struct range_list *ret_rl;
1849         const char *return_ranges;
1850         struct sm_state *tmp;
1851         int ret = 0;
1852         int nr_possible, nr_states;
1853         char *compare_str = NULL;
1854         char buf[128];
1855         struct state_list *already_handled = NULL;
1856 
1857         if (!sm || !sm->merged)
1858                 return 0;
1859 
1860         if (too_many_possible(sm))
1861                 return 0;
1862 
1863         /* bail if it gets too complicated */
1864         nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
1865         nr_states = get_db_state_count();
1866         if (nr_states * nr_possible >= 2000)
1867                 return 0;
1868 
1869         FOR_EACH_PTR(sm->possible, tmp) {
1870                 if (tmp->merged)
1871                         continue;
1872                 if (ptr_in_list(tmp, already_handled))
1873                         continue;
1874                 add_ptr_list(&already_handled, tmp);
1875 
1876                 ret = 1;
1877                 __push_fake_cur_stree();
1878 
1879                 overwrite_states_using_pool(sm, tmp);
1880 
1881                 return_ranges = get_return_ranges_str(expr, &ret_rl);
1882                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1883                 compare_str = get_return_compare_str(expr);
1884                 if (compare_str) {
1885                         snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1886                         return_ranges = alloc_sname(buf);
1887                 }
1888 
1889                 return_id++;
1890                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1891                         cb->callback(return_id, (char *)return_ranges, expr);
1892                 } END_FOR_EACH_PTR(cb);
1893 
1894                 __free_fake_cur_stree();
1895         } END_FOR_EACH_PTR(tmp);
1896 
1897         free_slist(&already_handled);
1898 
1899         return ret;
1900 }
1901 
1902 static int split_by_bool_param(struct expression *expr)
1903 {
1904         struct sm_state *start_sm, *sm;
1905         sval_t sval;
1906 
1907         start_sm = find_bool_param();
1908         if (!start_sm)
1909                 return 0;
1910         sm = get_sm_state(SMATCH_EXTRA, start_sm->name, start_sm->sym);
1911         if (!sm || estate_get_single_value(sm->state, &sval))
1912                 return 0;
1913         return split_on_bool_sm(sm, expr);
1914 }
1915 
1916 static int split_by_null_nonnull_param(struct expression *expr)
1917 {
1918         struct symbol *arg;
1919         struct sm_state *sm;
1920         sval_t zero = {
1921                 .type = &ulong_ctype,
1922         };
1923 
1924         /* function must only take one pointer */
1925         if (ptr_list_size((struct ptr_list *)cur_func_sym->ctype.base_type->arguments) != 1)
1926                 return 0;
1927         arg = first_ptr_list((struct ptr_list *)cur_func_sym->ctype.base_type->arguments);
1928         if (!arg->ident)
1929                 return 0;
1930         if (get_real_base_type(arg)->type != SYM_PTR)
1931                 return 0;
1932 
1933         if (param_was_set_var_sym(arg->ident->name, arg))
1934                 return 0;
1935         sm = get_sm_state(SMATCH_EXTRA, arg->ident->name, arg);
1936         if (!sm)
1937                 return 0;
1938 
1939         if (!rl_has_sval(estate_rl(sm->state), zero))
1940                 return 0;
1941 
1942         return split_on_bool_sm(sm, expr);
1943 }
1944 
1945 struct expression *strip_expr_statement(struct expression *expr)
1946 {
1947         struct expression *orig = expr;
1948         struct statement *stmt, *last_stmt;
1949 
1950         if (!expr)
1951                 return NULL;
1952         if (expr->type == EXPR_PREOP && expr->op == '(')
1953                 expr = expr->unop;
1954         if (expr->type != EXPR_STATEMENT)
1955                 return orig;
1956         stmt = expr->statement;
1957         if (!stmt || stmt->type != STMT_COMPOUND)
1958                 return orig;
1959 
1960         last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1961         if (!last_stmt || last_stmt->type == STMT_LABEL)
1962                 last_stmt = last_stmt->label_statement;
1963         if (!last_stmt || last_stmt->type != STMT_EXPRESSION)
1964                 return orig;
1965         return strip_expr(last_stmt->expression);
1966 }
1967 
1968 static void call_return_state_hooks(struct expression *expr)
1969 {
1970         struct returned_state_callback *cb;
1971         struct range_list *ret_rl;
1972         const char *return_ranges;
1973         int nr_states;
1974         sval_t sval;
1975 
1976         if (__path_is_null())
1977                 return;
1978 
1979         expr = strip_expr(expr);
1980         expr = strip_expr_statement(expr);
1981 
1982         if (is_impossible_path())
1983                 goto vanilla;
1984 
1985         if (expr && (expr->type == EXPR_COMPARE ||
1986                      !get_implied_value(expr, &sval)) &&
1987             (is_condition(expr) || is_boolean(expr))) {
1988                 call_return_state_hooks_compare(expr);
1989                 return;
1990         } else if (is_conditional(expr)) {
1991                 call_return_state_hooks_conditional(expr);
1992                 return;
1993         } else if (call_return_state_hooks_split_possible(expr)) {
1994                 return;
1995         } else if (call_return_state_hooks_split_null_non_null(expr)) {
1996                 return;
1997         } else if (call_return_state_hooks_split_success_fail(expr)) {
1998                 return;
1999         } else if (splitable_function_call(expr)) {
2000                 return;
2001         } else if (split_positive_from_negative(expr)) {
2002                 return;
2003         } else if (split_by_bool_param(expr)) {
2004         } else if (split_by_null_nonnull_param(expr)) {
2005                 return;
2006         }
2007 
2008 vanilla:
2009         return_ranges = get_return_ranges_str(expr, &ret_rl);
2010         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
2011 
2012         return_id++;
2013         nr_states = get_db_state_count();
2014         if (nr_states >= 10000) {
2015                 match_return_info(return_id, (char *)return_ranges, expr);
2016                 mark_all_params_untracked(return_id, (char *)return_ranges, expr);
2017                 return;
2018         }
2019         FOR_EACH_PTR(returned_state_callbacks, cb) {
2020                 cb->callback(return_id, (char *)return_ranges, expr);
2021         } END_FOR_EACH_PTR(cb);
2022 }
2023 
2024 static void print_returned_struct_members(int return_id, char *return_ranges, struct expression *expr)
2025 {
2026         struct returned_member_callback *cb;
2027         struct stree *stree;
2028         struct sm_state *sm;
2029         struct symbol *type;
2030         char *name;
2031         char member_name[256];
2032         int len;
2033 
2034         type = get_type(expr);
2035         if (!type || type->type != SYM_PTR)
2036                 return;
2037         name = expr_to_var(expr);
2038         if (!name)
2039                 return;
2040 
2041         member_name[sizeof(member_name) - 1] = '\0';
2042         strcpy(member_name, "$");
2043 
2044         len = strlen(name);
2045         FOR_EACH_PTR(returned_member_callbacks, cb) {
2046                 stree = __get_cur_stree();
2047                 FOR_EACH_MY_SM(cb->owner, stree, sm) {
2048                         if (sm->name[0] == '*' && strcmp(sm->name + 1, name) == 0) {
2049                                 strcpy(member_name, "*$");
2050                                 cb->callback(return_id, return_ranges, expr, member_name, sm->state);
2051                                 continue;
2052                         }
2053                         if (strncmp(sm->name, name, len) != 0)
2054                                 continue;
2055                         if (strncmp(sm->name + len, "->", 2) != 0)
2056                                 continue;
2057                         snprintf(member_name, sizeof(member_name), "$%s", sm->name + len);
2058                         cb->callback(return_id, return_ranges, expr, member_name, sm->state);
2059                 } END_FOR_EACH_SM(sm);
2060         } END_FOR_EACH_PTR(cb);
2061 
2062         free_string(name);
2063 }
2064 
2065 static void reset_memdb(struct symbol *sym)
2066 {
2067         mem_sql(NULL, NULL, "delete from caller_info;");
2068         mem_sql(NULL, NULL, "delete from return_states;");
2069         mem_sql(NULL, NULL, "delete from call_implies;");
2070         mem_sql(NULL, NULL, "delete from return_implies;");
2071 }
2072 
2073 static void match_end_func_info(struct symbol *sym)
2074 {
2075         if (__path_is_null())
2076                 return;
2077         call_return_state_hooks(NULL);
2078 }
2079 
2080 static void match_after_func(struct symbol *sym)
2081 {
2082         if (!__inline_fn)
2083                 reset_memdb(sym);
2084 }
2085 
2086 static void init_memdb(void)
2087 {
2088         char *err = NULL;
2089         int rc;
2090         const char *schema_files[] = {
2091                 "db/db.schema",
2092                 "db/caller_info.schema",
2093                 "db/common_caller_info.schema",
2094                 "db/return_states.schema",
2095                 "db/function_type_size.schema",
2096                 "db/type_size.schema",
2097                 "db/function_type_info.schema",
2098                 "db/type_info.schema",
2099                 "db/call_implies.schema",
2100                 "db/return_implies.schema",
2101                 "db/function_ptr.schema",
2102                 "db/local_values.schema",
2103                 "db/function_type_value.schema",
2104                 "db/type_value.schema",
2105                 "db/function_type.schema",
2106                 "db/data_info.schema",
2107                 "db/parameter_name.schema",
2108                 "db/constraints.schema",
2109                 "db/constraints_required.schema",
2110                 "db/fn_ptr_data_link.schema",
2111                 "db/fn_data_link.schema",
2112                 "db/mtag_about.schema",
2113                 "db/mtag_map.schema",
2114                 "db/mtag_data.schema",
2115                 "db/mtag_alias.schema",
2116         };
2117         static char buf[4096];
2118         int fd;
2119         int ret;
2120         int i;
2121 
2122         rc = sqlite3_open(":memory:", &mem_db);
2123         if (rc != SQLITE_OK) {
2124                 sm_ierror("starting In-Memory database.");
2125                 return;
2126         }
2127 
2128         for (i = 0; i < ARRAY_SIZE(schema_files); i++) {
2129                 fd = open_schema_file(schema_files[i]);
2130                 if (fd < 0)
2131                         continue;
2132                 ret = read(fd, buf, sizeof(buf));
2133                 if (ret < 0) {
2134                         sm_ierror("failed to read: %s", schema_files[i]);
2135                         continue;
2136                 }
2137                 close(fd);
2138                 if (ret == sizeof(buf)) {
2139                         sm_ierror("Schema file too large:  %s (limit %zd bytes)",
2140                                schema_files[i], sizeof(buf));
2141                         continue;
2142                 }
2143                 buf[ret] = '\0';
2144                 rc = sqlite3_exec(mem_db, buf, NULL, NULL, &err);
2145                 if (rc != SQLITE_OK) {
2146                         sm_ierror("SQL error #2: %s", err);
2147                         sm_ierror("%s", buf);
2148                 }
2149         }
2150 }
2151 
2152 static void init_cachedb(void)
2153 {
2154         char *err = NULL;
2155         int rc;
2156         const char *schema_files[] = {
2157                 "db/call_implies.schema",
2158                 "db/return_implies.schema",
2159                 "db/type_info.schema",
2160                 "db/mtag_data.schema",
2161                 "db/sink_info.schema",
2162         };
2163         static char buf[4096];
2164         int fd;
2165         int ret;
2166         int i;
2167 
2168         rc = sqlite3_open(":memory:", &cache_db);
2169         if (rc != SQLITE_OK) {
2170                 sm_ierror("starting In-Memory database.");
2171                 return;
2172         }
2173 
2174         for (i = 0; i < ARRAY_SIZE(schema_files); i++) {
2175                 fd = open_schema_file(schema_files[i]);
2176                 if (fd < 0)
2177                         continue;
2178                 ret = read(fd, buf, sizeof(buf));
2179                 if (ret < 0) {
2180                         sm_ierror("failed to read: %s", schema_files[i]);
2181                         continue;
2182                 }
2183                 close(fd);
2184                 if (ret == sizeof(buf)) {
2185                         sm_ierror("Schema file too large:  %s (limit %zd bytes)",
2186                                schema_files[i], sizeof(buf));
2187                         continue;
2188                 }
2189                 buf[ret] = '\0';
2190                 rc = sqlite3_exec(cache_db, buf, NULL, NULL, &err);
2191                 if (rc != SQLITE_OK) {
2192                         sm_ierror("SQL error #2: %s", err);
2193                         sm_ierror("%s", buf);
2194                 }
2195         }
2196 }
2197 
2198 static int save_cache_data(void *_table, int argc, char **argv, char **azColName)
2199 {
2200         static char buf[4096];
2201         char tmp[256];
2202         char *p = buf;
2203         char *table = _table;
2204         int i;
2205 
2206 
2207         p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
2208         for (i = 0; i < argc; i++) {
2209                 if (i)
2210                         p += snprintf(p, 4096 - (p - buf), ", ");
2211                 sqlite3_snprintf(sizeof(tmp), tmp, "%q", argv[i]);
2212                 p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
2213 
2214         }
2215         p += snprintf(p, 4096 - (p - buf), ");");
2216         if (p - buf > 4096)
2217                 return 0;
2218 
2219         sm_msg("SQL: %s", buf);
2220         return 0;
2221 }
2222 
2223 static void dump_cache(struct symbol_list *sym_list)
2224 {
2225         if (!option_info)
2226                 return;
2227         cache_sql(&save_cache_data, (char *)"type_info", "select * from type_info;");
2228         cache_sql(&save_cache_data, (char *)"return_implies", "select * from return_implies;");
2229         cache_sql(&save_cache_data, (char *)"call_implies", "select * from call_implies;");
2230         cache_sql(&save_cache_data, (char *)"mtag_data", "select * from mtag_data;");
2231         cache_sql(&save_cache_data, (char *)"sink_info", "select * from sink_info;");
2232 }
2233 
2234 void open_smatch_db(char *db_file)
2235 {
2236         int rc;
2237 
2238         if (option_no_db)
2239                 return;
2240 
2241         use_states = malloc(num_checks + 1);
2242         memset(use_states, 0xff, num_checks + 1);
2243 
2244         init_memdb();
2245         init_cachedb();
2246 
2247         rc = sqlite3_open_v2(db_file, &smatch_db, SQLITE_OPEN_READONLY, NULL);
2248         if (rc != SQLITE_OK) {
2249                 option_no_db = 1;
2250                 return;
2251         }
2252         run_sql(NULL, NULL,
2253                 "PRAGMA cache_size = %d;", SQLITE_CACHE_PAGES);
2254         return;
2255 }
2256 
2257 static void register_common_funcs(void)
2258 {
2259         struct token *token;
2260         char *func;
2261         char filename[256];
2262 
2263         if (option_project == PROJ_NONE)
2264                 strcpy(filename, "common_functions");
2265         else
2266                 snprintf(filename, 256, "%s.common_functions", option_project_str);
2267 
2268         token = get_tokens_file(filename);
2269         if (!token)
2270                 return;
2271         if (token_type(token) != TOKEN_STREAMBEGIN)
2272                 return;
2273         token = token->next;
2274         while (token_type(token) != TOKEN_STREAMEND) {
2275                 if (token_type(token) != TOKEN_IDENT)
2276                         return;
2277                 func = alloc_string(show_ident(token->ident));
2278                 add_ptr_list(&common_funcs, func);
2279                 token = token->next;
2280         }
2281         clear_token_alloc();
2282 }
2283 
2284 static char *get_next_string(char **str)
2285 {
2286         static char string[256];
2287         char *start;
2288         char *p = *str;
2289         int len;
2290 
2291         if (*p == '\0')
2292                 return NULL;
2293         start = p;
2294 
2295         while (*p != '\0' && *p != ' ' && *p != '\n')
2296                 p++;
2297 
2298         len = p - start;
2299         if (len > 256) {
2300                 memcpy(string, start, 255);
2301                 string[255] = '\0';
2302                 sm_ierror("return_fix: '%s' too long", string);
2303                 **str = '\0';
2304                 return NULL;
2305         }
2306         memcpy(string, start, len);
2307         string[len] = '\0';
2308         if (*p != '\0')
2309                 p++;
2310         *str = p;
2311         return string;
2312 }
2313 
2314 static void register_return_replacements(void)
2315 {
2316         char *func, *orig, *new;
2317         char filename[256];
2318         char buf[4096];
2319         int fd, ret, i;
2320         char *p;
2321 
2322         snprintf(filename, 256, "db/%s.return_fixes", option_project_str);
2323         fd = open_schema_file(filename);
2324         if (fd < 0)
2325                 return;
2326         ret = read(fd, buf, sizeof(buf));
2327         close(fd);
2328         if (ret < 0)
2329                 return;
2330         if (ret == sizeof(buf)) {
2331                 sm_ierror("file too large:  %s (limit %zd bytes)",
2332                        filename, sizeof(buf));
2333                 return;
2334         }
2335         buf[ret] = '\0';
2336 
2337         p = buf;
2338         while (*p) {
2339                 get_next_string(&p);
2340                 replace_count++;
2341         }
2342         if (replace_count == 0 || replace_count % 3 != 0) {
2343                 replace_count = 0;
2344                 return;
2345         }
2346         replace_table = malloc(replace_count * sizeof(char *));
2347 
2348         p = buf;
2349         i = 0;
2350         while (*p) {
2351                 func = alloc_string(get_next_string(&p));
2352                 orig = alloc_string(get_next_string(&p));
2353                 new  = alloc_string(get_next_string(&p));
2354 
2355                 replace_table[i++] = func;
2356                 replace_table[i++] = orig;
2357                 replace_table[i++] = new;
2358         }
2359 }
2360 
2361 void register_definition_db_callbacks(int id)
2362 {
2363         add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2364         add_hook(&global_variable, BASE_HOOK);
2365         add_hook(&global_variable, DECLARATION_HOOK);
2366         add_split_return_callback(match_return_info);
2367         add_split_return_callback(print_returned_struct_members);
2368         add_hook(&call_return_state_hooks, RETURN_HOOK);
2369         add_hook(&match_end_func_info, END_FUNC_HOOK);
2370         add_hook(&match_after_func, AFTER_FUNC_HOOK);
2371 
2372         add_hook(&match_data_from_db, FUNC_DEF_HOOK);
2373         add_hook(&match_call_implies, FUNC_DEF_HOOK);
2374         add_hook(&match_return_implies, CALL_HOOK_AFTER_INLINE);
2375 
2376         register_common_funcs();
2377         register_return_replacements();
2378 
2379         add_hook(&dump_cache, END_FILE_HOOK);
2380 }
2381 
2382 void register_db_call_marker(int id)
2383 {
2384         add_hook(&match_call_marker, FUNCTION_CALL_HOOK);
2385 }
2386 
2387 char *return_state_to_var_sym(struct expression *expr, int param, const char *key, struct symbol **sym)
2388 {
2389         struct expression *arg;
2390         char *name = NULL;
2391         char member_name[256];
2392 
2393         *sym = NULL;
2394 
2395         if (param == -1) {
2396                 const char *star = "";
2397 
2398                 if (expr->type != EXPR_ASSIGNMENT)
2399                         return NULL;
2400                 name = expr_to_var_sym(expr->left, sym);
2401                 if (!name)
2402                         return NULL;
2403                 if (key[0] == '*') {
2404                         star = "*";
2405                         key++;
2406                 }
2407                 if (strncmp(key, "$", 1) != 0)
2408                         return name;
2409                 snprintf(member_name, sizeof(member_name), "%s%s%s", star, name, key + 1);
2410                 free_string(name);
2411                 return alloc_string(member_name);
2412         }
2413 
2414         while (expr->type == EXPR_ASSIGNMENT)
2415                 expr = strip_expr(expr->right);
2416         if (expr->type != EXPR_CALL)
2417                 return NULL;
2418 
2419         arg = get_argument_from_call_expr(expr->args, param);
2420         if (!arg)
2421                 return NULL;
2422 
2423         return get_variable_from_key(arg, key, sym);
2424 }
2425 
2426 char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
2427 {
2428         char buf[256];
2429         char *tmp;
2430 
2431         if (!arg)
2432                 return NULL;
2433 
2434         arg = strip_expr(arg);
2435 
2436         if (strcmp(key, "$") == 0)
2437                 return expr_to_var_sym(arg, sym);
2438 
2439         if (strcmp(key, "*$") == 0) {
2440                 if (arg->type == EXPR_PREOP && arg->op == '&') {
2441                         arg = strip_expr(arg->unop);
2442                         return expr_to_var_sym(arg, sym);
2443                 } else {
2444                         tmp = expr_to_var_sym(arg, sym);
2445                         if (!tmp)
2446                                 return NULL;
2447                         snprintf(buf, sizeof(buf), "*%s", tmp);
2448                         free_string(tmp);
2449                         return alloc_string(buf);
2450                 }
2451         }
2452 
2453         if (arg->type == EXPR_PREOP && arg->op == '&') {
2454                 arg = strip_expr(arg->unop);
2455                 tmp = expr_to_var_sym(arg, sym);
2456                 if (!tmp)
2457                         return NULL;
2458                 snprintf(buf, sizeof(buf), "%s.%s", tmp, key + 3);
2459                 return alloc_string(buf);
2460         }
2461 
2462         tmp = expr_to_var_sym(arg, sym);
2463         if (!tmp)
2464                 return NULL;
2465         snprintf(buf, sizeof(buf), "%s%s", tmp, key + 1);
2466         free_string(tmp);
2467         return alloc_string(buf);
2468 }
2469 
2470 char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
2471 {
2472         *vsl = NULL;
2473 
2474         if (strcmp("$", key) == 0)
2475                 return expr_to_chunk_sym_vsl(arg, sym, vsl);
2476         return get_variable_from_key(arg, key, sym);
2477 }
2478 
2479 const char *state_name_to_param_name(const char *state_name, const char *param_name)
2480 {
2481         int name_len;
2482         static char buf[256];
2483 
2484         name_len = strlen(param_name);
2485 
2486         if (strcmp(state_name, param_name) == 0) {
2487                 return "$";
2488         } else if (state_name[name_len] == '-' && /* check for '-' from "->" */
2489             strncmp(state_name, param_name, name_len) == 0) {
2490                 snprintf(buf, sizeof(buf), "$%s", state_name + name_len);
2491                 return buf;
2492         } else if (state_name[0] == '*' && strcmp(state_name + 1, param_name) == 0) {
2493                 return "*$";
2494         }
2495         return NULL;
2496 }
2497 
2498 const char *get_param_name_var_sym(const char *name, struct symbol *sym)
2499 {
2500         if (!sym || !sym->ident)
2501                 return NULL;
2502 
2503         return state_name_to_param_name(name, sym->ident->name);
2504 }
2505 
2506 const char *get_mtag_name_var_sym(const char *state_name, struct symbol *sym)
2507 {
2508         struct symbol *type;
2509         const char *sym_name;
2510         int name_len;
2511         static char buf[256];
2512 
2513         /*
2514          * mtag_name is different from param_name because mtags can be a struct
2515          * instead of a struct pointer.  But we want to treat it like a pointer
2516          * because really an mtag is a pointer.  Or in other words, if you pass
2517          * a struct foo then you want to talk about foo.bar but with an mtag
2518          * you want to refer to it as foo->bar.
2519          *
2520          */
2521 
2522         if (!sym || !sym->ident)
2523                 return NULL;
2524 
2525         type = get_real_base_type(sym);
2526         if (type && type->type == SYM_BASETYPE)
2527                 return "*$";
2528 
2529         sym_name = sym->ident->name;
2530         name_len = strlen(sym_name);
2531 
2532         if (state_name[name_len] == '.' && /* check for '-' from "->" */
2533             strncmp(state_name, sym_name, name_len) == 0) {
2534                 snprintf(buf, sizeof(buf), "$->%s", state_name + name_len + 1);
2535                 return buf;
2536         }
2537 
2538         return state_name_to_param_name(state_name, sym_name);
2539 }
2540 
2541 const char *get_mtag_name_expr(struct expression *expr)
2542 {
2543         char *name;
2544         struct symbol *sym;
2545         const char *ret = NULL;
2546 
2547         name = expr_to_var_sym(expr, &sym);
2548         if (!name || !sym)
2549                 goto free;
2550 
2551         ret = get_mtag_name_var_sym(name, sym);
2552 free:
2553         free_string(name);
2554         return ret;
2555 }
2556 
2557 const char *get_param_name(struct sm_state *sm)
2558 {
2559         return get_param_name_var_sym(sm->name, sm->sym);
2560 }
2561 
2562 char *get_data_info_name(struct expression *expr)
2563 {
2564         struct symbol *sym;
2565         char *name;
2566         char buf[256];
2567         char *ret = NULL;
2568 
2569         expr = strip_expr(expr);
2570         name = get_member_name(expr);
2571         if (name)
2572                 return name;
2573         name = expr_to_var_sym(expr, &sym);
2574         if (!name || !sym)
2575                 goto free;
2576         if (!(sym->ctype.modifiers & MOD_TOPLEVEL))
2577                 goto free;
2578         if (sym->ctype.modifiers & MOD_STATIC)
2579                 snprintf(buf, sizeof(buf), "static %s", name);
2580         else
2581                 snprintf(buf, sizeof(buf), "global %s", name);
2582         ret = alloc_sname(buf);
2583 free:
2584         free_string(name);
2585         return ret;
2586 }