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