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