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         sval_t sval;
 273 
 274         if (expr->type != EXPR_ASSIGNMENT)
 275                 return;
 276         call = strip_expr(expr->right);
 277 
 278         call_results_to_rl(call, &int_ctype, math, &rl);
 279         rl = cast_rl(&int_ctype, rl);
 280         if (rl_to_sval(rl, &sval) && sval.value == 0)
 281                 return;
 282         set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
 283 }
 284 
 285 static int get_real_array_size_from_type(struct symbol *type)
 286 {
 287         sval_t sval;
 288 
 289         if (!type)
 290                 return 0;
 291         if (!type || type->type != SYM_ARRAY)
 292                 return 0;
 293 
 294         if (!get_implied_value(type->array_size, &sval))
 295                 return 0;
 296 
 297         return sval.value;
 298 }
 299 
 300 int get_real_array_size(struct expression *expr)
 301 {
 302         if (!expr)
 303                 return 0;
 304         if (expr->type == EXPR_PREOP && expr->op == '&')
 305                 expr = expr->unop;
 306         if (expr->type == EXPR_BINOP) /* array elements foo[5] */
 307                 return 0;
 308         return get_real_array_size_from_type(get_type(expr));
 309 }
 310 
 311 static int get_size_from_initializer(struct expression *expr)
 312 {
 313         if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->initializer)
 314                 return 0;
 315         if (expr->symbol->initializer == expr) /* int a = a; */
 316                 return 0;
 317         return get_initializer_size(expr->symbol->initializer);
 318 }
 319 
 320 static struct range_list *get_stored_size_bytes(struct expression *expr)
 321 {
 322         struct smatch_state *state;
 323 
 324         state = get_state_expr(my_size_id, expr);
 325         if (!state)
 326                 return NULL;
 327         return estate_rl(state);
 328 }
 329 
 330 static int get_bytes_from_address(struct expression *expr)
 331 {
 332         struct symbol *type;
 333         int ret;
 334 
 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) || estate_to_size(state) == -1)
 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         sval_t sval;
 477         int size;
 478 
 479         expr = remove_addr_fluff(expr);
 480         if (!expr)
 481                 return NULL;
 482 
 483         /* "BAR" */
 484         if (expr->type == EXPR_STRING)
 485                 return alloc_int_rl(expr->string->length);
 486 
 487         if (expr->type == EXPR_BINOP && expr->op == '+') {
 488                 sval_t offset;
 489                 struct symbol *type;
 490                 int bytes;
 491 
 492                 if (!get_implied_value(expr->right, &offset))
 493                         return NULL;
 494                 type = get_type(expr->left);
 495                 if (!type)
 496                         return NULL;
 497                 if (type->type != SYM_ARRAY && type->type != SYM_PTR)
 498                         return NULL;
 499                 type = get_real_base_type(type);
 500                 bytes = type_bytes(type);
 501                 if (bytes == 0)
 502                         return NULL;
 503                 offset.value *= bytes;
 504                 size = get_array_size_bytes(expr->left);
 505                 if (size <= 0)
 506                         return NULL;
 507                 return alloc_int_rl(size - offset.value);
 508         }
 509 
 510         /* buf = malloc(1024); */
 511         ret = get_stored_size_bytes(expr);
 512         if (ret)
 513                 return ret;
 514 
 515         size = get_stored_size_end_struct_bytes(expr);
 516         if (size)
 517                 return alloc_int_rl(size);
 518 
 519         /* buf[4] */
 520         size = get_real_array_size(expr);
 521         if (size)
 522                 return alloc_int_rl(elements_to_bytes(expr, size));
 523 
 524         /* char *foo = "BAR" */
 525         size = get_size_from_initializer(expr);
 526         if (size)
 527                 return alloc_int_rl(elements_to_bytes(expr, size));
 528 
 529         size = get_bytes_from_address(expr);
 530         if (size)
 531                 return alloc_int_rl(size);
 532 
 533         ret = size_from_db(expr);
 534         if (rl_to_sval(ret, &sval) && sval.value == -1)
 535                 return NULL;
 536         if (ret)
 537                 return ret;
 538 
 539         return NULL;
 540 }
 541 
 542 int get_array_size_bytes(struct expression *expr)
 543 {
 544         struct range_list *rl;
 545         sval_t sval;
 546 
 547         rl = get_array_size_bytes_rl(expr);
 548         if (!rl_to_sval(rl, &sval))
 549                 return 0;
 550         if (sval.uvalue >= INT_MAX)
 551                 return 0;
 552         return sval.value;
 553 }
 554 
 555 int get_array_size_bytes_max(struct expression *expr)
 556 {
 557         struct range_list *rl;
 558         sval_t bytes;
 559 
 560         rl = get_array_size_bytes_rl(expr);
 561         if (!rl)
 562                 return 0;
 563         bytes = rl_min(rl);
 564         if (bytes.value < 0)
 565                 return 0;
 566         bytes = rl_max(rl);
 567         if (bytes.uvalue >= INT_MAX)
 568                 return 0;
 569         return bytes.value;
 570 }
 571 
 572 int get_array_size_bytes_min(struct expression *expr)
 573 {
 574         struct range_list *rl;
 575         struct data_range *range;
 576 
 577         rl = get_array_size_bytes_rl(expr);
 578         if (!rl)
 579                 return 0;
 580 
 581         FOR_EACH_PTR(rl, range) {
 582                 if (range->min.value <= 0)
 583                         return 0;
 584                 if (range->max.value <= 0)
 585                         return 0;
 586                 if (range->min.uvalue >= INT_MAX)
 587                         return 0;
 588                 return range->min.value;
 589         } END_FOR_EACH_PTR(range);
 590 
 591         return 0;
 592 }
 593 
 594 int get_array_size(struct expression *expr)
 595 {
 596         if (!expr)
 597                 return 0;
 598         return bytes_to_elements(expr, get_array_size_bytes_max(expr));
 599 }
 600 
 601 static struct expression *strip_ampersands(struct expression *expr)
 602 {
 603         struct symbol *type;
 604 
 605         if (expr->type != EXPR_PREOP)
 606                 return expr;
 607         if (expr->op != '&')
 608                 return expr;
 609         type = get_type(expr->unop);
 610         if (!type || type->type != SYM_ARRAY)
 611                 return expr;
 612         return expr->unop;
 613 }
 614 
 615 static void info_record_alloction(struct expression *buffer, struct range_list *rl)
 616 {
 617         char *name;
 618 
 619         if (!option_info)
 620                 return;
 621 
 622         name = get_member_name(buffer);
 623         if (!name && is_static(buffer))
 624                 name = expr_to_var(buffer);
 625         if (!name)
 626                 return;
 627         if (rl && !is_whole_rl(rl))
 628                 sql_insert_function_type_size(name, show_rl(rl));
 629         else
 630                 sql_insert_function_type_size(name, "(-1)");
 631 
 632         free_string(name);
 633 }
 634 
 635 static void store_alloc(struct expression *expr, struct range_list *rl)
 636 {
 637         struct symbol *type;
 638 
 639         rl = clone_rl(rl); // FIXME!!!
 640         if (!rl)
 641                 rl = size_to_rl(UNKNOWN_SIZE);
 642 
 643         if (rl_min(rl).value != UNKNOWN_SIZE ||
 644             rl_max(rl).value != UNKNOWN_SIZE ||
 645             get_state_expr(my_size_id, expr))
 646                 set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
 647 
 648         type = get_type(expr);
 649         if (!type)
 650                 return;
 651         if (type->type != SYM_PTR)
 652                 return;
 653         type = get_real_base_type(type);
 654         if (!type)
 655                 return;
 656         if (type == &void_ctype)
 657                 return;
 658         if (type->type != SYM_BASETYPE && type->type != SYM_PTR)
 659                 return;
 660 
 661         info_record_alloction(expr, rl);
 662 }
 663 
 664 static bool is_array_base(struct expression *expr)
 665 {
 666         struct symbol *type;
 667 
 668         type = get_type(expr);
 669         if (type && type->type == SYM_ARRAY)
 670                 return true;
 671         return false;
 672 }
 673 
 674 static void match_array_assignment(struct expression *expr)
 675 {
 676         struct expression *left;
 677         struct expression *right;
 678         char *left_member, *right_member;
 679         struct range_list *rl;
 680         sval_t sval;
 681 
 682         if (expr->op != '=')
 683                 return;
 684 
 685         left = strip_expr(expr->left);
 686         right = strip_expr(expr->right);
 687         right = strip_ampersands(right);
 688 
 689         if (!is_pointer(left))
 690                 return;
 691         /* char buf[24] = "str"; */
 692         if (is_array_base(left))
 693                 return;
 694         if (is_allocation_function(right))
 695                 return;
 696 
 697         left_member = get_member_name(left);
 698         right_member = get_member_name(right);
 699         if (left_member && right_member && strcmp(left_member, right_member) == 0) {
 700                 free_string(left_member);
 701                 free_string(right_member);
 702                 return;
 703         }
 704         free_string(left_member);
 705         free_string(right_member);
 706 
 707         if (get_implied_value(right, &sval) && sval.value == 0) {
 708                 rl = alloc_int_rl(0);
 709                 goto store;
 710         }
 711 
 712         rl = get_array_size_bytes_rl(right);
 713         if (!rl && __in_fake_assign)
 714                 return;
 715 
 716 store:
 717         store_alloc(left, rl);
 718 }
 719 
 720 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg)
 721 {
 722         int size_arg = PTR_INT(_size_arg);
 723         struct expression *right;
 724         struct expression *arg;
 725         struct range_list *rl;
 726 
 727         right = strip_expr(expr->right);
 728         arg = get_argument_from_call_expr(right->args, size_arg);
 729         get_absolute_rl(arg, &rl);
 730         rl = cast_rl(&int_ctype, rl);
 731         store_alloc(expr->left, rl);
 732 }
 733 
 734 static void match_calloc(const char *fn, struct expression *expr, void *_param)
 735 {
 736         struct expression *right;
 737         struct expression *size, *nr, *mult;
 738         struct range_list *rl;
 739         int param = PTR_INT(_param);
 740 
 741         right = strip_expr(expr->right);
 742         nr = get_argument_from_call_expr(right->args, param);
 743         size = get_argument_from_call_expr(right->args, param + 1);
 744         mult = binop_expression(nr, '*', size);
 745         if (get_implied_rl(mult, &rl))
 746                 store_alloc(expr->left, rl);
 747         else
 748                 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
 749 }
 750 
 751 static void match_page(const char *fn, struct expression *expr, void *_unused)
 752 {
 753         sval_t page_size = {
 754                 .type = &int_ctype,
 755                 {.value = 4096},
 756         };
 757 
 758         store_alloc(expr->left, alloc_rl(page_size, page_size));
 759 }
 760 
 761 static void match_strndup(const char *fn, struct expression *expr, void *unused)
 762 {
 763         struct expression *fn_expr;
 764         struct expression *size_expr;
 765         sval_t size;
 766 
 767         fn_expr = strip_expr(expr->right);
 768         size_expr = get_argument_from_call_expr(fn_expr->args, 1);
 769         if (get_implied_max(size_expr, &size)) {
 770                 size.value++;
 771                 store_alloc(expr->left, size_to_rl(size.value));
 772         } else {
 773                 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
 774         }
 775 
 776 }
 777 
 778 static void match_alloc_pages(const char *fn, struct expression *expr, void *_order_arg)
 779 {
 780         int order_arg = PTR_INT(_order_arg);
 781         struct expression *right;
 782         struct expression *arg;
 783         sval_t sval;
 784 
 785         right = strip_expr(expr->right);
 786         arg = get_argument_from_call_expr(right->args, order_arg);
 787         if (!get_implied_value(arg, &sval))
 788                 return;
 789         if (sval.value < 0 || sval.value > 10)
 790                 return;
 791 
 792         sval.type = &int_ctype;
 793         sval.value = 1 << sval.value;
 794         sval.value *= 4096;
 795 
 796         store_alloc(expr->left, alloc_rl(sval, sval));
 797 }
 798 
 799 static int is_type_bytes(struct range_list *rl, struct expression *arg)
 800 {
 801         struct symbol *type;
 802         sval_t sval;
 803 
 804         if (!rl_to_sval(rl, &sval))
 805                 return 0;
 806 
 807         type = get_type(arg);
 808         if (!type)
 809                 return 0;
 810         if (type->type != SYM_PTR)
 811                 return 0;
 812         type = get_real_base_type(type);
 813         if (type->type != SYM_STRUCT &&
 814             type->type != SYM_UNION)
 815                 return 0;
 816         if (sval.value != type_bytes(type))
 817                 return 0;
 818         return 1;
 819 }
 820 
 821 static void match_call(struct expression *expr)
 822 {
 823         struct expression *arg;
 824         struct symbol *type;
 825         struct range_list *rl;
 826         int i;
 827 
 828         i = -1;
 829         FOR_EACH_PTR(expr->args, arg) {
 830                 i++;
 831                 type = get_type(arg);
 832                 if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY))
 833                         continue;
 834                 rl = get_array_size_bytes_rl(arg);
 835                 if (!rl)
 836                         continue;
 837                 if (rl_min(rl).value == UNKNOWN_SIZE &&
 838                     rl_max(rl).value == UNKNOWN_SIZE)
 839                         continue;
 840                 if (is_whole_rl(rl))
 841                         continue;
 842                 if (is_type_bytes(rl, arg))
 843                         continue;
 844                 sql_insert_caller_info(expr, BUF_SIZE, i, "$", show_rl(rl));
 845         } END_FOR_EACH_PTR(arg);
 846 }
 847 
 848 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
 849 {
 850         sval_t sval;
 851 
 852         if (!estate_rl(sm->state) ||
 853             (estate_get_single_value(sm->state, &sval) &&
 854              (sval.value == -1 || sval.value == 0)))
 855                 return;
 856 
 857         sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name);
 858 }
 859 
 860 /*
 861  * This is slightly (very) weird because half of this stuff is handled in
 862  * smatch_parse_call_math.c which is poorly named.  But anyway, add some buf
 863  * sizes here.
 864  *
 865  */
 866 static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr)
 867 {
 868         const char *param_math;
 869         struct range_list *rl;
 870         char buf[64];
 871         sval_t sval;
 872 
 873         rl = get_array_size_bytes_rl(expr);
 874         param_math = get_allocation_math(expr);
 875         if (!rl && !param_math)
 876                 return;
 877 
 878         if (!param_math &&
 879             rl_to_sval(rl, &sval) &&
 880             (sval.value == -1 || sval.value == 0))
 881                 return;
 882 
 883         if (param_math)
 884                 snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), param_math);
 885         else
 886                 snprintf(buf, sizeof(buf), "%s", show_rl(rl));
 887 
 888         // FIXME: don't store if you can guess the size from the type
 889         // FIXME: return if we allocate a parameter $0->bar
 890         sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf);
 891 }
 892 
 893 static void record_global_size(struct symbol *sym)
 894 {
 895         int bytes;
 896         char buf[16];
 897 
 898         if (!sym->ident)
 899                 return;
 900 
 901         if (!(sym->ctype.modifiers & MOD_TOPLEVEL) ||
 902             sym->ctype.modifiers & MOD_STATIC)
 903                 return;
 904 
 905         bytes = get_array_size_bytes(symbol_expression(sym));
 906         if (bytes <= 1)
 907                 return;
 908 
 909         snprintf(buf, sizeof(buf), "%d", bytes);
 910         sql_insert_data_info_var_sym(sym->ident->name, sym, BUF_SIZE, buf);
 911 }
 912 
 913 void register_buf_size(int id)
 914 {
 915         my_size_id = id;
 916 
 917         set_dynamic_states(my_size_id);
 918 
 919         add_unmatched_state_hook(my_size_id, &unmatched_size_state);
 920         add_merge_hook(my_size_id, &merge_estates);
 921 
 922         select_caller_info_hook(set_param_buf_size, BUF_SIZE);
 923         select_return_states_hook(BUF_SIZE, &db_returns_buf_size);
 924         add_split_return_callback(print_returned_allocations);
 925 
 926         allocation_funcs = create_function_hashtable(100);
 927         add_allocation_function("malloc", &match_alloc, 0);
 928         add_allocation_function("calloc", &match_calloc, 0);
 929         add_allocation_function("memdup", &match_alloc, 1);
 930         add_allocation_function("realloc", &match_alloc, 1);
 931         if (option_project == PROJ_KERNEL) {
 932                 add_allocation_function("kmalloc", &match_alloc, 0);
 933                 add_allocation_function("kmalloc_node", &match_alloc, 0);
 934                 add_allocation_function("kzalloc", &match_alloc, 0);
 935                 add_allocation_function("kzalloc_node", &match_alloc, 0);
 936                 add_allocation_function("vmalloc", &match_alloc, 0);
 937                 add_allocation_function("vzalloc", &match_alloc, 0);
 938                 add_allocation_function("__vmalloc", &match_alloc, 0);
 939                 add_allocation_function("kvmalloc", &match_alloc, 0);
 940                 add_allocation_function("kcalloc", &match_calloc, 0);
 941                 add_allocation_function("kmalloc_array", &match_calloc, 0);
 942                 add_allocation_function("devm_kmalloc_array", &match_calloc, 1);
 943                 add_allocation_function("sock_kmalloc", &match_alloc, 1);
 944                 add_allocation_function("kmemdup", &match_alloc, 1);
 945                 add_allocation_function("kmemdup_user", &match_alloc, 1);
 946                 add_allocation_function("dma_alloc_attrs", &match_alloc, 1);
 947                 add_allocation_function("pci_alloc_consistent", &match_alloc, 1);
 948                 add_allocation_function("pci_alloc_coherent", &match_alloc, 1);
 949                 add_allocation_function("devm_kmalloc", &match_alloc, 1);
 950                 add_allocation_function("devm_kzalloc", &match_alloc, 1);
 951                 add_allocation_function("krealloc", &match_alloc, 1);
 952                 add_allocation_function("__alloc_bootmem", &match_alloc, 0);
 953                 add_allocation_function("alloc_bootmem", &match_alloc, 0);
 954                 add_allocation_function("kmap", &match_page, 0);
 955                 add_allocation_function("kmap_atomic", &match_page, 0);
 956                 add_allocation_function("get_zeroed_page", &match_page, 0);
 957                 add_allocation_function("alloc_page", &match_page, 0);
 958                 add_allocation_function("alloc_pages", &match_alloc_pages, 1);
 959                 add_allocation_function("alloc_pages_current", &match_alloc_pages, 1);
 960                 add_allocation_function("__get_free_pages", &match_alloc_pages, 1);
 961                 add_allocation_function("dma_alloc_contiguous", &match_alloc, 1);
 962                 add_allocation_function("dma_alloc_coherent", &match_alloc, 1);
 963         }
 964 
 965         add_allocation_function("strndup", match_strndup, 0);
 966         if (option_project == PROJ_KERNEL)
 967                 add_allocation_function("kstrndup", match_strndup, 0);
 968 
 969         add_modification_hook(my_size_id, &set_size_undefined);
 970 
 971         add_merge_hook(my_size_id, &merge_size_func);
 972 
 973         if (option_info)
 974                 add_hook(record_global_size, BASE_HOOK);
 975 }
 976 
 977 void register_buf_size_late(int id)
 978 {
 979         /* has to happen after match_alloc() */
 980         add_hook(&match_array_assignment, ASSIGNMENT_HOOK);
 981 
 982         add_hook(&match_call, FUNCTION_CALL_HOOK);
 983         add_member_info_callback(my_size_id, struct_member_callback);
 984 }