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