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 if (!parse_call_math_rl(call, math, &rl)) 278 return; 279 rl = cast_rl(&int_ctype, rl); 280 set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl)); 281 } 282 283 static int get_real_array_size_from_type(struct symbol *type) 284 { 285 sval_t sval; 286 287 if (!type) 288 return 0; 289 if (!type || type->type != SYM_ARRAY) 290 return 0; 291 292 if (!get_implied_value(type->array_size, &sval)) 293 return 0; 294 295 return sval.value; 296 } 297 298 int get_real_array_size(struct expression *expr) 299 { 300 if (!expr) 301 return 0; 302 if (expr->type == EXPR_PREOP && expr->op == '&') 303 expr = expr->unop; 304 if (expr->type == EXPR_BINOP) /* array elements foo[5] */ 305 return 0; 306 return get_real_array_size_from_type(get_type(expr)); 307 } 308 309 static int get_size_from_initializer(struct expression *expr) 310 { 311 if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->initializer) 312 return 0; 313 if (expr->symbol->initializer == expr) /* int a = a; */ 314 return 0; 315 return get_initializer_size(expr->symbol->initializer); 316 } 317 318 static struct range_list *get_stored_size_bytes(struct expression *expr) 319 { 320 struct smatch_state *state; 321 322 state = get_state_expr(my_size_id, expr); 323 if (!state) 324 return NULL; 325 return estate_rl(state); 326 } 327 328 static int get_bytes_from_address(struct expression *expr) 329 { 330 struct symbol *type; 331 int ret; 332 333 if (!option_spammy) 334 return 0; 335 if (expr->type != EXPR_PREOP || expr->op != '&') 336 return 0; 337 type = get_type(expr); 338 if (!type) 339 return 0; 340 341 if (type->type == SYM_PTR) 342 type = get_base_type(type); 343 344 ret = type_bytes(type); 345 if (ret == 1) 346 return 0; /* ignore char pointers */ 347 348 return ret; 349 } 350 351 static struct expression *remove_addr_fluff(struct expression *expr) 352 { 353 struct expression *tmp; 354 sval_t sval; 355 356 expr = strip_expr(expr); 357 358 /* remove '&' and '*' operations that cancel */ 359 while (expr && expr->type == EXPR_PREOP && expr->op == '&') { 360 tmp = strip_expr(expr->unop); 361 if (tmp->type != EXPR_PREOP) 362 break; 363 if (tmp->op != '*') 364 break; 365 expr = strip_expr(tmp->unop); 366 } 367 368 if (!expr) 369 return NULL; 370 371 /* "foo + 0" is just "foo" */ 372 if (expr->type == EXPR_BINOP && expr->op == '+' && 373 get_value(expr->right, &sval) && sval.value == 0) 374 return expr->left; 375 376 return expr; 377 } 378 379 static int is_last_member_of_struct(struct symbol *sym, struct ident *member) 380 { 381 struct symbol *tmp; 382 int i; 383 384 i = 0; 385 FOR_EACH_PTR_REVERSE(sym->symbol_list, tmp) { 386 if (i++ || !tmp->ident) 387 return 0; 388 if (tmp->ident == member) 389 return 1; 390 return 0; 391 } END_FOR_EACH_PTR_REVERSE(tmp); 392 393 return 0; 394 } 395 396 int last_member_is_resizable(struct symbol *sym) 397 { 398 struct symbol *last_member; 399 struct symbol *type; 400 sval_t sval; 401 402 if (!sym || sym->type != SYM_STRUCT) 403 return 0; 404 405 last_member = last_ptr_list((struct ptr_list *)sym->symbol_list); 406 if (!last_member || !last_member->ident) 407 return 0; 408 409 type = get_real_base_type(last_member); 410 if (type->type == SYM_STRUCT) 411 return last_member_is_resizable(type); 412 if (type->type != SYM_ARRAY) 413 return 0; 414 415 if (!get_implied_value(type->array_size, &sval)) 416 return 0; 417 418 if (sval.value != 0 && sval.value != 1) 419 return 0; 420 421 return 1; 422 } 423 424 static int get_stored_size_end_struct_bytes(struct expression *expr) 425 { 426 struct symbol *sym; 427 struct symbol *base_sym; 428 struct smatch_state *state; 429 430 if (expr->type == EXPR_BINOP) /* array elements foo[5] */ 431 return 0; 432 433 if (expr->type == EXPR_PREOP && expr->op == '&') 434 expr = strip_parens(expr->unop); 435 436 sym = expr_to_sym(expr); 437 if (!sym || !sym->ident) 438 return 0; 439 if (!type_bytes(sym)) 440 return 0; 441 if (sym->type != SYM_NODE) 442 return 0; 443 444 base_sym = get_real_base_type(sym); 445 if (!base_sym || base_sym->type != SYM_PTR) 446 return 0; 447 base_sym = get_real_base_type(base_sym); 448 if (!base_sym || base_sym->type != SYM_STRUCT) 449 return 0; 450 451 if (!is_last_member_of_struct(base_sym, expr->member)) 452 return 0; 453 if (!last_member_is_resizable(base_sym)) 454 return 0; 455 456 state = get_state(my_size_id, sym->ident->name, sym); 457 if (!estate_to_size(state)) 458 return 0; 459 460 return estate_to_size(state) - type_bytes(base_sym) + type_bytes(get_type(expr)); 461 } 462 463 static struct range_list *alloc_int_rl(int value) 464 { 465 sval_t sval = { 466 .type = &int_ctype, 467 {.value = value}, 468 }; 469 470 return alloc_rl(sval, sval); 471 } 472 473 struct range_list *get_array_size_bytes_rl(struct expression *expr) 474 { 475 struct range_list *ret = NULL; 476 int size; 477 478 expr = remove_addr_fluff(expr); 479 if (!expr) 480 return NULL; 481 482 /* "BAR" */ 483 if (expr->type == EXPR_STRING) 484 return alloc_int_rl(expr->string->length); 485 486 if (expr->type == EXPR_BINOP && expr->op == '+') { 487 sval_t offset; 488 struct symbol *type; 489 int bytes; 490 491 if (!get_implied_value(expr->right, &offset)) 492 return NULL; 493 type = get_type(expr->left); 494 if (!type) 495 return NULL; 496 if (type->type != SYM_ARRAY && type->type != SYM_PTR) 497 return NULL; 498 type = get_real_base_type(type); 499 bytes = type_bytes(type); 500 if (bytes == 0) 501 return NULL; 502 offset.value *= bytes; 503 size = get_array_size_bytes(expr->left); 504 if (size <= 0) 505 return NULL; 506 return alloc_int_rl(size - offset.value); 507 } 508 509 /* buf[4] */ 510 size = get_real_array_size(expr); 511 if (size) 512 return alloc_int_rl(elements_to_bytes(expr, size)); 513 514 /* buf = malloc(1024); */ 515 ret = get_stored_size_bytes(expr); 516 if (ret) 517 return ret; 518 519 size = get_stored_size_end_struct_bytes(expr); 520 if (size) 521 return alloc_int_rl(size); 522 523 /* char *foo = "BAR" */ 524 size = get_size_from_initializer(expr); 525 if (size) 526 return alloc_int_rl(elements_to_bytes(expr, size)); 527 528 size = get_bytes_from_address(expr); 529 if (size) 530 return alloc_int_rl(size); 531 532 ret = size_from_db(expr); 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 set_state_expr(my_size_id, expr, alloc_estate_rl(rl)); 638 639 type = get_type(expr); 640 if (!type) 641 return; 642 if (type->type != SYM_PTR) 643 return; 644 type = get_real_base_type(type); 645 if (!type) 646 return; 647 if (type == &void_ctype) 648 return; 649 if (type->type != SYM_BASETYPE && type->type != SYM_PTR) 650 return; 651 652 info_record_alloction(expr, rl); 653 } 654 655 static void match_array_assignment(struct expression *expr) 656 { 657 struct expression *left; 658 struct expression *right; 659 char *left_member, *right_member; 660 struct range_list *rl; 661 sval_t sval; 662 663 if (expr->op != '=') 664 return; 665 left = strip_expr(expr->left); 666 right = strip_expr(expr->right); 667 right = strip_ampersands(right); 668 669 if (!is_pointer(left)) 670 return; 671 if (is_allocation_function(right)) 672 return; 673 674 left_member = get_member_name(left); 675 right_member = get_member_name(right); 676 if (left_member && right_member && strcmp(left_member, right_member) == 0) { 677 free_string(left_member); 678 free_string(right_member); 679 return; 680 } 681 free_string(left_member); 682 free_string(right_member); 683 684 if (get_implied_value(right, &sval) && sval.value == 0) { 685 rl = alloc_int_rl(0); 686 goto store; 687 } 688 689 rl = get_array_size_bytes_rl(right); 690 if (!rl && __in_fake_assign) 691 return; 692 693 store: 694 store_alloc(left, rl); 695 } 696 697 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) 698 { 699 int size_arg = PTR_INT(_size_arg); 700 struct expression *right; 701 struct expression *arg; 702 struct range_list *rl; 703 704 right = strip_expr(expr->right); 705 arg = get_argument_from_call_expr(right->args, size_arg); 706 get_absolute_rl(arg, &rl); 707 rl = cast_rl(&int_ctype, rl); 708 store_alloc(expr->left, rl); 709 } 710 711 static void match_calloc(const char *fn, struct expression *expr, void *unused) 712 { 713 struct expression *right; 714 struct expression *arg; 715 sval_t elements; 716 sval_t size; 717 718 right = strip_expr(expr->right); 719 arg = get_argument_from_call_expr(right->args, 0); 720 if (!get_implied_value(arg, &elements)) 721 return; // FIXME!!! 722 arg = get_argument_from_call_expr(right->args, 1); 723 if (get_implied_value(arg, &size)) 724 store_alloc(expr->left, size_to_rl(elements.value * size.value)); 725 else 726 store_alloc(expr->left, size_to_rl(-1)); 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(-1)); 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 if (sm->state == &merged || 826 strcmp(sm->state->name, "(-1)") == 0 || 827 strcmp(sm->state->name, "empty") == 0 || 828 strcmp(sm->state->name, "0") == 0) 829 return; 830 sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name); 831 } 832 833 /* 834 * This is slightly (very) weird because half of this stuff is handled in 835 * smatch_parse_call_math.c which is poorly named. But anyway, add some buf 836 * sizes here. 837 * 838 */ 839 static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr) 840 { 841 char buf[16]; 842 int size; 843 844 size = get_array_size_bytes(expr); 845 if (!size) 846 return; 847 848 snprintf(buf, sizeof(buf), "%d", size); 849 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf); 850 } 851 852 static void record_global_size(struct symbol *sym) 853 { 854 int bytes; 855 char buf[16]; 856 857 if (!sym->ident) 858 return; 859 860 if (!(sym->ctype.modifiers & MOD_TOPLEVEL) || 861 sym->ctype.modifiers & MOD_STATIC) 862 return; 863 864 bytes = get_array_size_bytes(symbol_expression(sym)); 865 if (bytes <= 1) 866 return; 867 868 snprintf(buf, sizeof(buf), "%d", bytes); 869 sql_insert_data_info_var_sym(sym->ident->name, sym, BUF_SIZE, buf); 870 } 871 872 void register_buf_size(int id) 873 { 874 my_size_id = id; 875 876 add_unmatched_state_hook(my_size_id, &unmatched_size_state); 877 878 select_caller_info_hook(set_param_buf_size, BUF_SIZE); 879 select_return_states_hook(BUF_SIZE, &db_returns_buf_size); 880 add_split_return_callback(print_returned_allocations); 881 882 allocation_funcs = create_function_hashtable(100); 883 add_allocation_function("malloc", &match_alloc, 0); 884 add_allocation_function("calloc", &match_calloc, 0); 885 add_allocation_function("memdup", &match_alloc, 1); 886 add_allocation_function("realloc", &match_alloc, 1); 887 if (option_project == PROJ_KERNEL) { 888 add_allocation_function("kmalloc", &match_alloc, 0); 889 add_allocation_function("kmalloc_node", &match_alloc, 0); 890 add_allocation_function("kzalloc", &match_alloc, 0); 891 add_allocation_function("kzalloc_node", &match_alloc, 0); 892 add_allocation_function("vmalloc", &match_alloc, 0); 893 add_allocation_function("__vmalloc", &match_alloc, 0); 894 add_allocation_function("kcalloc", &match_calloc, 0); 895 add_allocation_function("kmalloc_array", &match_calloc, 0); 896 add_allocation_function("drm_malloc_ab", &match_calloc, 0); 897 add_allocation_function("drm_calloc_large", &match_calloc, 0); 898 add_allocation_function("sock_kmalloc", &match_alloc, 1); 899 add_allocation_function("kmemdup", &match_alloc, 1); 900 add_allocation_function("kmemdup_user", &match_alloc, 1); 901 add_allocation_function("dma_alloc_attrs", &match_alloc, 1); 902 add_allocation_function("pci_alloc_consistent", &match_alloc, 1); 903 add_allocation_function("pci_alloc_coherent", &match_alloc, 1); 904 add_allocation_function("devm_kmalloc", &match_alloc, 1); 905 add_allocation_function("devm_kzalloc", &match_alloc, 1); 906 add_allocation_function("krealloc", &match_alloc, 1); 907 add_allocation_function("__alloc_bootmem", &match_alloc, 0); 908 add_allocation_function("alloc_bootmem", &match_alloc, 0); 909 add_allocation_function("kmap", &match_page, 0); 910 add_allocation_function("get_zeroed_page", &match_page, 0); 911 add_allocation_function("alloc_pages", &match_alloc_pages, 1); 912 add_allocation_function("alloc_pages_current", &match_alloc_pages, 1); 913 add_allocation_function("__get_free_pages", &match_alloc_pages, 1); 914 } 915 916 add_allocation_function("strndup", match_strndup, 0); 917 if (option_project == PROJ_KERNEL) 918 add_allocation_function("kstrndup", match_strndup, 0); 919 920 add_modification_hook(my_size_id, &set_size_undefined); 921 922 add_merge_hook(my_size_id, &merge_size_func); 923 924 if (option_info) 925 add_hook(record_global_size, BASE_HOOK); 926 } 927 928 void register_buf_size_late(int id) 929 { 930 /* has to happen after match_alloc() */ 931 add_hook(&match_array_assignment, ASSIGNMENT_HOOK); 932 933 add_hook(&match_call, FUNCTION_CALL_HOOK); 934 add_member_info_callback(my_size_id, struct_member_callback); 935 }