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 <stdlib.h> 19 #include <errno.h> 20 #include "parse.h" 21 #include "smatch.h" 22 #include "smatch_slist.h" 23 #include "smatch_extra.h" 24 #include "smatch_function_hashtable.h" 25 26 #define UNKNOWN_SIZE -1 27 28 static int my_size_id; 29 30 static DEFINE_HASHTABLE_INSERT(insert_func, char, int); 31 static DEFINE_HASHTABLE_SEARCH(search_func, char, int); 32 static struct hashtable *allocation_funcs; 33 34 static char *get_fn_name(struct expression *expr) 35 { 36 if (expr->type != EXPR_CALL) 37 return NULL; 38 if (expr->fn->type != EXPR_SYMBOL) 39 return NULL; 40 return expr_to_var(expr->fn); 41 } 42 43 static int is_allocation_function(struct expression *expr) 44 { 45 char *func; 46 int ret = 0; 47 48 func = get_fn_name(expr); 49 if (!func) 50 return 0; 51 if (search_func(allocation_funcs, func)) 52 ret = 1; 53 free_string(func); 54 return ret; 55 } 56 57 static void add_allocation_function(const char *func, void *call_back, int param) 58 { 59 insert_func(allocation_funcs, (char *)func, (int *)1); 60 add_function_assign_hook(func, call_back, INT_PTR(param)); 61 } 62 63 static int estate_to_size(struct smatch_state *state) 64 { 65 sval_t sval; 66 67 if (!state || !estate_rl(state)) 68 return 0; 69 sval = estate_max(state); 70 return sval.value; 71 } 72 73 static struct smatch_state *size_to_estate(int size) 74 { 75 sval_t sval; 76 77 sval.type = &int_ctype; 78 sval.value = size; 79 80 return alloc_estate_sval(sval); 81 } 82 83 static struct range_list *size_to_rl(int size) 84 { 85 sval_t sval; 86 87 sval.type = &int_ctype; 88 sval.value = size; 89 90 return alloc_rl(sval, sval); 91 } 92 93 static struct smatch_state *unmatched_size_state(struct sm_state *sm) 94 { 95 return size_to_estate(UNKNOWN_SIZE); 96 } 97 98 static void set_size_undefined(struct sm_state *sm, struct expression *mod_expr) 99 { 100 set_state(sm->owner, sm->name, sm->sym, size_to_estate(UNKNOWN_SIZE)); 101 } 102 103 static struct smatch_state *merge_size_func(struct smatch_state *s1, struct smatch_state *s2) 104 { 105 return merge_estates(s1, s2); 106 } 107 108 void set_param_buf_size(const char *name, struct symbol *sym, char *key, char *value) 109 { 110 struct range_list *rl = NULL; 111 struct smatch_state *state; 112 char fullname[256]; 113 114 if (strncmp(key, "$", 1) != 0) 115 return; 116 117 snprintf(fullname, 256, "%s%s", name, key + 1); 118 119 str_to_rl(&int_ctype, value, &rl); 120 if (!rl || is_whole_rl(rl)) 121 return; 122 state = alloc_estate_rl(rl); 123 set_state(my_size_id, fullname, sym, state); 124 } 125 126 static int bytes_per_element(struct expression *expr) 127 { 128 struct symbol *type; 129 130 if (!expr) 131 return 0; 132 if (expr->type == EXPR_STRING) 133 return 1; 134 if (expr->type == EXPR_PREOP && expr->op == '&') { 135 type = get_type(expr->unop); 136 if (type && type->type == SYM_ARRAY) 137 expr = expr->unop; 138 } 139 type = get_type(expr); 140 if (!type) 141 return 0; 142 143 if (type->type != SYM_PTR && type->type != SYM_ARRAY) 144 return 0; 145 146 type = get_base_type(type); 147 return type_bytes(type); 148 } 149 150 static int bytes_to_elements(struct expression *expr, int bytes) 151 { 152 int bpe; 153 154 bpe = bytes_per_element(expr); 155 if (bpe == 0) 156 return 0; 157 return bytes / bpe; 158 } 159 160 static int elements_to_bytes(struct expression *expr, int elements) 161 { 162 int bpe; 163 164 bpe = bytes_per_element(expr); 165 return elements * bpe; 166 } 167 168 static int get_initializer_size(struct expression *expr) 169 { 170 switch (expr->type) { 171 case EXPR_STRING: 172 return expr->string->length; 173 case EXPR_INITIALIZER: { 174 struct expression *tmp; 175 int i = 0; 176 177 FOR_EACH_PTR(expr->expr_list, tmp) { 178 if (tmp->type == EXPR_INDEX) { 179 if (tmp->idx_to >= i) 180 i = tmp->idx_to; 181 else 182 continue; 183 } 184 185 i++; 186 } END_FOR_EACH_PTR(tmp); 187 return i; 188 } 189 case EXPR_SYMBOL: 190 return get_array_size(expr); 191 } 192 return 0; 193 } 194 195 static struct range_list *db_size_rl; 196 static int db_size_callback(void *unused, int argc, char **argv, char **azColName) 197 { 198 struct range_list *tmp = NULL; 199 200 if (!db_size_rl) { 201 str_to_rl(&int_ctype, argv[0], &db_size_rl); 202 } else { 203 str_to_rl(&int_ctype, argv[0], &tmp); 204 db_size_rl = rl_union(db_size_rl, tmp); 205 } 206 return 0; 207 } 208 209 static struct range_list *size_from_db_type(struct expression *expr) 210 { 211 int this_file_only = 0; 212 char *name; 213 214 name = get_member_name(expr); 215 if (!name && is_static(expr)) { 216 name = expr_to_var(expr); 217 this_file_only = 1; 218 } 219 if (!name) 220 return NULL; 221 222 if (this_file_only) { 223 db_size_rl = NULL; 224 run_sql(db_size_callback, NULL, 225 "select size from function_type_size where type = '%s' and file = '%s';", 226 name, get_filename()); 227 if (db_size_rl) 228 return db_size_rl; 229 return NULL; 230 } 231 232 db_size_rl = NULL; 233 run_sql(db_size_callback, NULL, 234 "select size from type_size where type = '%s';", 235 name); 236 return db_size_rl; 237 } 238 239 static struct range_list *size_from_db_symbol(struct expression *expr) 240 { 241 struct symbol *sym; 242 243 if (expr->type != EXPR_SYMBOL) 244 return NULL; 245 sym = expr->symbol; 246 if (!sym || !sym->ident || 247 !(sym->ctype.modifiers & MOD_TOPLEVEL) || 248 sym->ctype.modifiers & MOD_STATIC) 249 return NULL; 250 251 db_size_rl = NULL; 252 run_sql(db_size_callback, NULL, 253 "select value from data_info where file = 'extern' and data = '%s' and type = %d;", 254 sym->ident->name, BUF_SIZE); 255 return db_size_rl; 256 } 257 258 static struct range_list *size_from_db(struct expression *expr) 259 { 260 struct range_list *rl; 261 262 rl = size_from_db_symbol(expr); 263 if (rl) 264 return rl; 265 return size_from_db_type(expr); 266 } 267 268 static void db_returns_buf_size(struct expression *expr, int param, char *unused, char *math) 269 { 270 struct expression *call; 271 struct range_list *rl; 272 273 if (expr->type != EXPR_ASSIGNMENT) 274 return; 275 call = strip_expr(expr->right); 276 277 call_results_to_rl(call, &int_ctype, math, &rl); 278 rl = cast_rl(&int_ctype, rl); 279 set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl)); 280 } 281 282 static int get_real_array_size_from_type(struct symbol *type) 283 { 284 sval_t sval; 285 286 if (!type) 287 return 0; 288 if (!type || type->type != SYM_ARRAY) 289 return 0; 290 291 if (!get_implied_value(type->array_size, &sval)) 292 return 0; 293 294 return sval.value; 295 } 296 297 int get_real_array_size(struct expression *expr) 298 { 299 if (!expr) 300 return 0; 301 if (expr->type == EXPR_PREOP && expr->op == '&') 302 expr = expr->unop; 303 if (expr->type == EXPR_BINOP) /* array elements foo[5] */ 304 return 0; 305 return get_real_array_size_from_type(get_type(expr)); 306 } 307 308 static int get_size_from_initializer(struct expression *expr) 309 { 310 if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->initializer) 311 return 0; 312 if (expr->symbol->initializer == expr) /* int a = a; */ 313 return 0; 314 return get_initializer_size(expr->symbol->initializer); 315 } 316 317 static struct range_list *get_stored_size_bytes(struct expression *expr) 318 { 319 struct smatch_state *state; 320 321 state = get_state_expr(my_size_id, expr); 322 if (!state) 323 return NULL; 324 return estate_rl(state); 325 } 326 327 static int get_bytes_from_address(struct expression *expr) 328 { 329 struct symbol *type; 330 int ret; 331 332 if (expr->type != EXPR_PREOP || expr->op != '&') 333 return 0; 334 type = get_type(expr); 335 if (!type) 336 return 0; 337 338 if (type->type == SYM_PTR) 339 type = get_base_type(type); 340 341 ret = type_bytes(type); 342 if (ret == 1) 343 return 0; /* ignore char pointers */ 344 345 return ret; 346 } 347 348 static struct expression *remove_addr_fluff(struct expression *expr) 349 { 350 struct expression *tmp; 351 sval_t sval; 352 353 expr = strip_expr(expr); 354 355 /* remove '&' and '*' operations that cancel */ 356 while (expr && expr->type == EXPR_PREOP && expr->op == '&') { 357 tmp = strip_expr(expr->unop); 358 if (tmp->type != EXPR_PREOP) 359 break; 360 if (tmp->op != '*') 361 break; 362 expr = strip_expr(tmp->unop); 363 } 364 365 if (!expr) 366 return NULL; 367 368 /* "foo + 0" is just "foo" */ 369 if (expr->type == EXPR_BINOP && expr->op == '+' && 370 get_value(expr->right, &sval) && sval.value == 0) 371 return expr->left; 372 373 return expr; 374 } 375 376 static int is_last_member_of_struct(struct symbol *sym, struct ident *member) 377 { 378 struct symbol *tmp; 379 int i; 380 381 i = 0; 382 FOR_EACH_PTR_REVERSE(sym->symbol_list, tmp) { 383 if (i++ || !tmp->ident) 384 return 0; 385 if (tmp->ident == member) 386 return 1; 387 return 0; 388 } END_FOR_EACH_PTR_REVERSE(tmp); 389 390 return 0; 391 } 392 393 int last_member_is_resizable(struct symbol *sym) 394 { 395 struct symbol *last_member; 396 struct symbol *type; 397 sval_t sval; 398 399 if (!sym || sym->type != SYM_STRUCT) 400 return 0; 401 402 last_member = last_ptr_list((struct ptr_list *)sym->symbol_list); 403 if (!last_member || !last_member->ident) 404 return 0; 405 406 type = get_real_base_type(last_member); 407 if (type->type == SYM_STRUCT) 408 return last_member_is_resizable(type); 409 if (type->type != SYM_ARRAY) 410 return 0; 411 412 if (!get_implied_value(type->array_size, &sval)) 413 return 0; 414 415 if (sval.value != 0 && sval.value != 1) 416 return 0; 417 418 return 1; 419 } 420 421 static int get_stored_size_end_struct_bytes(struct expression *expr) 422 { 423 struct symbol *sym; 424 struct symbol *base_sym; 425 struct smatch_state *state; 426 427 if (expr->type == EXPR_BINOP) /* array elements foo[5] */ 428 return 0; 429 430 if (expr->type == EXPR_PREOP && expr->op == '&') 431 expr = strip_parens(expr->unop); 432 433 sym = expr_to_sym(expr); 434 if (!sym || !sym->ident) 435 return 0; 436 if (!type_bytes(sym)) 437 return 0; 438 if (sym->type != SYM_NODE) 439 return 0; 440 441 base_sym = get_real_base_type(sym); 442 if (!base_sym || base_sym->type != SYM_PTR) 443 return 0; 444 base_sym = get_real_base_type(base_sym); 445 if (!base_sym || base_sym->type != SYM_STRUCT) 446 return 0; 447 448 if (!is_last_member_of_struct(base_sym, expr->member)) 449 return 0; 450 if (!last_member_is_resizable(base_sym)) 451 return 0; 452 453 state = get_state(my_size_id, sym->ident->name, sym); 454 if (!estate_to_size(state)) 455 return 0; 456 457 return estate_to_size(state) - type_bytes(base_sym) + type_bytes(get_type(expr)); 458 } 459 460 static struct range_list *alloc_int_rl(int value) 461 { 462 sval_t sval = { 463 .type = &int_ctype, 464 {.value = value}, 465 }; 466 467 return alloc_rl(sval, sval); 468 } 469 470 struct range_list *get_array_size_bytes_rl(struct expression *expr) 471 { 472 struct range_list *ret = NULL; 473 sval_t sval; 474 int size; 475 476 expr = remove_addr_fluff(expr); 477 if (!expr) 478 return NULL; 479 480 /* "BAR" */ 481 if (expr->type == EXPR_STRING) 482 return alloc_int_rl(expr->string->length); 483 484 if (expr->type == EXPR_BINOP && expr->op == '+') { 485 sval_t offset; 486 struct symbol *type; 487 int bytes; 488 489 if (!get_implied_value(expr->right, &offset)) 490 return NULL; 491 type = get_type(expr->left); 492 if (!type) 493 return NULL; 494 if (type->type != SYM_ARRAY && type->type != SYM_PTR) 495 return NULL; 496 type = get_real_base_type(type); 497 bytes = type_bytes(type); 498 if (bytes == 0) 499 return NULL; 500 offset.value *= bytes; 501 size = get_array_size_bytes(expr->left); 502 if (size <= 0) 503 return NULL; 504 return alloc_int_rl(size - offset.value); 505 } 506 507 size = get_stored_size_end_struct_bytes(expr); 508 if (size) 509 return alloc_int_rl(size); 510 511 /* buf[4] */ 512 size = get_real_array_size(expr); 513 if (size) 514 return alloc_int_rl(elements_to_bytes(expr, size)); 515 516 /* buf = malloc(1024); */ 517 ret = get_stored_size_bytes(expr); 518 if (ret) 519 return ret; 520 521 /* char *foo = "BAR" */ 522 size = get_size_from_initializer(expr); 523 if (size) 524 return alloc_int_rl(elements_to_bytes(expr, size)); 525 526 size = get_bytes_from_address(expr); 527 if (size) 528 return alloc_int_rl(size); 529 530 ret = size_from_db(expr); 531 if (rl_to_sval(ret, &sval) && sval.value == -1) 532 return NULL; 533 if (ret) 534 return ret; 535 536 return NULL; 537 } 538 539 int get_array_size_bytes(struct expression *expr) 540 { 541 struct range_list *rl; 542 sval_t sval; 543 544 rl = get_array_size_bytes_rl(expr); 545 if (!rl_to_sval(rl, &sval)) 546 return 0; 547 if (sval.uvalue >= INT_MAX) 548 return 0; 549 return sval.value; 550 } 551 552 int get_array_size_bytes_max(struct expression *expr) 553 { 554 struct range_list *rl; 555 sval_t bytes; 556 557 rl = get_array_size_bytes_rl(expr); 558 if (!rl) 559 return 0; 560 bytes = rl_min(rl); 561 if (bytes.value < 0) 562 return 0; 563 bytes = rl_max(rl); 564 if (bytes.uvalue >= INT_MAX) 565 return 0; 566 return bytes.value; 567 } 568 569 int get_array_size_bytes_min(struct expression *expr) 570 { 571 struct range_list *rl; 572 struct data_range *range; 573 574 rl = get_array_size_bytes_rl(expr); 575 if (!rl) 576 return 0; 577 578 FOR_EACH_PTR(rl, range) { 579 if (range->min.value <= 0) 580 return 0; 581 if (range->max.value <= 0) 582 return 0; 583 if (range->min.uvalue >= INT_MAX) 584 return 0; 585 return range->min.value; 586 } END_FOR_EACH_PTR(range); 587 588 return 0; 589 } 590 591 int get_array_size(struct expression *expr) 592 { 593 if (!expr) 594 return 0; 595 return bytes_to_elements(expr, get_array_size_bytes_max(expr)); 596 } 597 598 static struct expression *strip_ampersands(struct expression *expr) 599 { 600 struct symbol *type; 601 602 if (expr->type != EXPR_PREOP) 603 return expr; 604 if (expr->op != '&') 605 return expr; 606 type = get_type(expr->unop); 607 if (!type || type->type != SYM_ARRAY) 608 return expr; 609 return expr->unop; 610 } 611 612 static void info_record_alloction(struct expression *buffer, struct range_list *rl) 613 { 614 char *name; 615 616 if (!option_info) 617 return; 618 619 name = get_member_name(buffer); 620 if (!name && is_static(buffer)) 621 name = expr_to_var(buffer); 622 if (!name) 623 return; 624 if (rl && !is_whole_rl(rl)) 625 sql_insert_function_type_size(name, show_rl(rl)); 626 else 627 sql_insert_function_type_size(name, "(-1)"); 628 629 free_string(name); 630 } 631 632 static void store_alloc(struct expression *expr, struct range_list *rl) 633 { 634 struct symbol *type; 635 636 rl = clone_rl(rl); // FIXME!!! 637 if (!rl) 638 rl = size_to_rl(UNKNOWN_SIZE); 639 set_state_expr(my_size_id, expr, alloc_estate_rl(rl)); 640 641 type = get_type(expr); 642 if (!type) 643 return; 644 if (type->type != SYM_PTR) 645 return; 646 type = get_real_base_type(type); 647 if (!type) 648 return; 649 if (type == &void_ctype) 650 return; 651 if (type->type != SYM_BASETYPE && type->type != SYM_PTR) 652 return; 653 654 info_record_alloction(expr, rl); 655 } 656 657 static void match_array_assignment(struct expression *expr) 658 { 659 struct expression *left; 660 struct expression *right; 661 char *left_member, *right_member; 662 struct range_list *rl; 663 sval_t sval; 664 665 if (expr->op != '=') 666 return; 667 left = strip_expr(expr->left); 668 right = strip_expr(expr->right); 669 right = strip_ampersands(right); 670 671 if (!is_pointer(left)) 672 return; 673 if (is_allocation_function(right)) 674 return; 675 676 left_member = get_member_name(left); 677 right_member = get_member_name(right); 678 if (left_member && right_member && strcmp(left_member, right_member) == 0) { 679 free_string(left_member); 680 free_string(right_member); 681 return; 682 } 683 free_string(left_member); 684 free_string(right_member); 685 686 if (get_implied_value(right, &sval) && sval.value == 0) { 687 rl = alloc_int_rl(0); 688 goto store; 689 } 690 691 rl = get_array_size_bytes_rl(right); 692 if (!rl && __in_fake_assign) 693 return; 694 695 store: 696 store_alloc(left, rl); 697 } 698 699 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) 700 { 701 int size_arg = PTR_INT(_size_arg); 702 struct expression *right; 703 struct expression *arg; 704 struct range_list *rl; 705 706 right = strip_expr(expr->right); 707 arg = get_argument_from_call_expr(right->args, size_arg); 708 get_absolute_rl(arg, &rl); 709 rl = cast_rl(&int_ctype, rl); 710 store_alloc(expr->left, rl); 711 } 712 713 static void match_calloc(const char *fn, struct expression *expr, void *unused) 714 { 715 struct expression *right; 716 struct expression *size, *nr, *mult; 717 struct range_list *rl; 718 719 right = strip_expr(expr->right); 720 nr = get_argument_from_call_expr(right->args, 0); 721 size = get_argument_from_call_expr(right->args, 1); 722 mult = binop_expression(nr, '*', size); 723 if (get_implied_rl(mult, &rl)) 724 store_alloc(expr->left, rl); 725 else 726 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE)); 727 } 728 729 static void match_page(const char *fn, struct expression *expr, void *_unused) 730 { 731 sval_t page_size = { 732 .type = &int_ctype, 733 {.value = 4096}, 734 }; 735 736 store_alloc(expr->left, alloc_rl(page_size, page_size)); 737 } 738 739 static void match_strndup(const char *fn, struct expression *expr, void *unused) 740 { 741 struct expression *fn_expr; 742 struct expression *size_expr; 743 sval_t size; 744 745 fn_expr = strip_expr(expr->right); 746 size_expr = get_argument_from_call_expr(fn_expr->args, 1); 747 if (get_implied_max(size_expr, &size)) { 748 size.value++; 749 store_alloc(expr->left, size_to_rl(size.value)); 750 } else { 751 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE)); 752 } 753 754 } 755 756 static void match_alloc_pages(const char *fn, struct expression *expr, void *_order_arg) 757 { 758 int order_arg = PTR_INT(_order_arg); 759 struct expression *right; 760 struct expression *arg; 761 sval_t sval; 762 763 right = strip_expr(expr->right); 764 arg = get_argument_from_call_expr(right->args, order_arg); 765 if (!get_implied_value(arg, &sval)) 766 return; 767 if (sval.value < 0 || sval.value > 10) 768 return; 769 770 sval.type = &int_ctype; 771 sval.value = 1 << sval.value; 772 sval.value *= 4096; 773 774 store_alloc(expr->left, alloc_rl(sval, sval)); 775 } 776 777 static int is_type_bytes(struct range_list *rl, struct expression *arg) 778 { 779 struct symbol *type; 780 sval_t sval; 781 782 if (!rl_to_sval(rl, &sval)) 783 return 0; 784 785 type = get_type(arg); 786 if (!type) 787 return 0; 788 if (type->type != SYM_PTR) 789 return 0; 790 type = get_real_base_type(type); 791 if (type->type != SYM_STRUCT && 792 type->type != SYM_UNION) 793 return 0; 794 if (sval.value != type_bytes(type)) 795 return 0; 796 return 1; 797 } 798 799 static void match_call(struct expression *expr) 800 { 801 struct expression *arg; 802 struct symbol *type; 803 struct range_list *rl; 804 int i; 805 806 i = -1; 807 FOR_EACH_PTR(expr->args, arg) { 808 i++; 809 type = get_type(arg); 810 if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY)) 811 continue; 812 rl = get_array_size_bytes_rl(arg); 813 if (!rl) 814 continue; 815 if (is_whole_rl(rl)) 816 continue; 817 if (is_type_bytes(rl, arg)) 818 continue; 819 sql_insert_caller_info(expr, BUF_SIZE, i, "$", show_rl(rl)); 820 } END_FOR_EACH_PTR(arg); 821 } 822 823 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm) 824 { 825 sval_t sval; 826 827 if (!estate_rl(sm->state) || 828 (estate_get_single_value(sm->state, &sval) && 829 (sval.value == -1 || sval.value == 0))) 830 return; 831 832 sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name); 833 } 834 835 /* 836 * This is slightly (very) weird because half of this stuff is handled in 837 * smatch_parse_call_math.c which is poorly named. But anyway, add some buf 838 * sizes here. 839 * 840 */ 841 static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr) 842 { 843 const char *param_math; 844 struct range_list *rl; 845 char buf[64]; 846 sval_t sval; 847 848 rl = get_array_size_bytes_rl(expr); 849 param_math = get_allocation_math(expr); 850 if (!rl && !param_math) 851 return; 852 853 if (!param_math && 854 rl_to_sval(rl, &sval) && 855 (sval.value == -1 || sval.value == 0)) 856 return; 857 858 if (param_math) 859 snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), param_math); 860 else 861 snprintf(buf, sizeof(buf), "%s", show_rl(rl)); 862 863 // FIXME: don't store if you can guess the size from the type 864 // FIXME: return if we allocate a parameter $0->bar 865 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf); 866 } 867 868 static void record_global_size(struct symbol *sym) 869 { 870 int bytes; 871 char buf[16]; 872 873 if (!sym->ident) 874 return; 875 876 if (!(sym->ctype.modifiers & MOD_TOPLEVEL) || 877 sym->ctype.modifiers & MOD_STATIC) 878 return; 879 880 bytes = get_array_size_bytes(symbol_expression(sym)); 881 if (bytes <= 1) 882 return; 883 884 snprintf(buf, sizeof(buf), "%d", bytes); 885 sql_insert_data_info_var_sym(sym->ident->name, sym, BUF_SIZE, buf); 886 } 887 888 void register_buf_size(int id) 889 { 890 my_size_id = id; 891 892 set_dynamic_states(my_size_id); 893 894 add_unmatched_state_hook(my_size_id, &unmatched_size_state); 895 add_merge_hook(my_size_id, &merge_estates); 896 897 select_caller_info_hook(set_param_buf_size, BUF_SIZE); 898 select_return_states_hook(BUF_SIZE, &db_returns_buf_size); 899 add_split_return_callback(print_returned_allocations); 900 901 allocation_funcs = create_function_hashtable(100); 902 add_allocation_function("malloc", &match_alloc, 0); 903 add_allocation_function("calloc", &match_calloc, 0); 904 add_allocation_function("memdup", &match_alloc, 1); 905 add_allocation_function("realloc", &match_alloc, 1); 906 if (option_project == PROJ_KERNEL) { 907 add_allocation_function("kmalloc", &match_alloc, 0); 908 add_allocation_function("kmalloc_node", &match_alloc, 0); 909 add_allocation_function("kzalloc", &match_alloc, 0); 910 add_allocation_function("kzalloc_node", &match_alloc, 0); 911 add_allocation_function("vmalloc", &match_alloc, 0); 912 add_allocation_function("__vmalloc", &match_alloc, 0); 913 add_allocation_function("kcalloc", &match_calloc, 0); 914 add_allocation_function("kmalloc_array", &match_calloc, 0); 915 add_allocation_function("drm_malloc_ab", &match_calloc, 0); 916 add_allocation_function("drm_calloc_large", &match_calloc, 0); 917 add_allocation_function("sock_kmalloc", &match_alloc, 1); 918 add_allocation_function("kmemdup", &match_alloc, 1); 919 add_allocation_function("kmemdup_user", &match_alloc, 1); 920 add_allocation_function("dma_alloc_attrs", &match_alloc, 1); 921 add_allocation_function("pci_alloc_consistent", &match_alloc, 1); 922 add_allocation_function("pci_alloc_coherent", &match_alloc, 1); 923 add_allocation_function("devm_kmalloc", &match_alloc, 1); 924 add_allocation_function("devm_kzalloc", &match_alloc, 1); 925 add_allocation_function("krealloc", &match_alloc, 1); 926 add_allocation_function("__alloc_bootmem", &match_alloc, 0); 927 add_allocation_function("alloc_bootmem", &match_alloc, 0); 928 add_allocation_function("kmap", &match_page, 0); 929 add_allocation_function("kmap_atomic", &match_page, 0); 930 add_allocation_function("get_zeroed_page", &match_page, 0); 931 add_allocation_function("alloc_page", &match_page, 0); 932 add_allocation_function("alloc_pages", &match_alloc_pages, 1); 933 add_allocation_function("alloc_pages_current", &match_alloc_pages, 1); 934 add_allocation_function("__get_free_pages", &match_alloc_pages, 1); 935 add_allocation_function("dma_alloc_contiguous", &match_alloc, 1); 936 add_allocation_function("dma_alloc_coherent", &match_alloc, 1); 937 } 938 939 add_allocation_function("strndup", match_strndup, 0); 940 if (option_project == PROJ_KERNEL) 941 add_allocation_function("kstrndup", match_strndup, 0); 942 943 add_modification_hook(my_size_id, &set_size_undefined); 944 945 add_merge_hook(my_size_id, &merge_size_func); 946 947 if (option_info) 948 add_hook(record_global_size, BASE_HOOK); 949 } 950 951 void register_buf_size_late(int id) 952 { 953 /* has to happen after match_alloc() */ 954 add_hook(&match_array_assignment, ASSIGNMENT_HOOK); 955 956 add_hook(&match_call, FUNCTION_CALL_HOOK); 957 add_member_info_callback(my_size_id, struct_member_callback); 958 }