comparison: select the caller_info
[smatch.git] / smatch_buf_size.c
blobab70627c0e45f25f4b529cfc35a2abafe96b23bd
1 /*
2 * Copyright (C) 2010 Dan Carpenter.
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.
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.
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
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"
26 #define UNKNOWN_SIZE -1
28 static int my_size_id;
30 static DEFINE_HASHTABLE_INSERT(insert_func, char, int);
31 static DEFINE_HASHTABLE_SEARCH(search_func, char, int);
32 static struct hashtable *allocation_funcs;
34 static char *get_fn_name(struct expression *expr)
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);
43 static int is_allocation_function(struct expression *expr)
45 char *func;
46 int ret = 0;
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;
57 static void add_allocation_function(const char *func, void *call_back, int param)
59 insert_func(allocation_funcs, (char *)func, (int *)1);
60 add_function_assign_hook(func, call_back, INT_PTR(param));
63 static struct smatch_state *size_to_estate(int size)
65 sval_t sval;
67 sval.type = &int_ctype;
68 sval.value = size;
70 return alloc_estate_sval(sval);
73 static struct range_list *size_to_rl(int size)
75 sval_t sval;
77 sval.type = &int_ctype;
78 sval.value = size;
80 return alloc_rl(sval, sval);
83 static struct smatch_state *unmatched_size_state(struct sm_state *sm)
85 return size_to_estate(UNKNOWN_SIZE);
88 static void set_size_undefined(struct sm_state *sm, struct expression *mod_expr)
90 set_state(sm->owner, sm->name, sm->sym, size_to_estate(UNKNOWN_SIZE));
93 static struct smatch_state *merge_size_func(struct smatch_state *s1, struct smatch_state *s2)
95 return merge_estates(s1, s2);
98 void set_param_buf_size(const char *name, struct symbol *sym, char *key, char *value)
100 struct range_list *rl = NULL;
101 struct smatch_state *state;
102 char fullname[256];
104 if (strncmp(key, "$", 1) != 0)
105 return;
107 snprintf(fullname, 256, "%s%s", name, key + 1);
109 str_to_rl(&int_ctype, value, &rl);
110 if (!rl || is_whole_rl(rl))
111 return;
112 state = alloc_estate_rl(rl);
113 set_state(my_size_id, fullname, sym, state);
116 static int bytes_per_element(struct expression *expr)
118 struct symbol *type;
120 if (!expr)
121 return 0;
122 if (expr->type == EXPR_STRING)
123 return 1;
124 if (expr->type == EXPR_PREOP && expr->op == '&') {
125 type = get_type(expr->unop);
126 if (type && type->type == SYM_ARRAY)
127 expr = expr->unop;
129 type = get_type(expr);
130 if (!type)
131 return 0;
133 if (type->type != SYM_PTR && type->type != SYM_ARRAY)
134 return 0;
136 type = get_base_type(type);
137 return type_bytes(type);
140 static int bytes_to_elements(struct expression *expr, int bytes)
142 int bpe;
144 bpe = bytes_per_element(expr);
145 if (bpe == 0)
146 return 0;
147 return bytes / bpe;
150 static int elements_to_bytes(struct expression *expr, int elements)
152 int bpe;
154 bpe = bytes_per_element(expr);
155 return elements * bpe;
158 static int get_initializer_size(struct expression *expr)
160 switch (expr->type) {
161 case EXPR_STRING:
162 return expr->string->length;
163 case EXPR_INITIALIZER: {
164 struct expression *tmp;
165 int i = 0;
167 FOR_EACH_PTR(expr->expr_list, tmp) {
168 if (tmp->type == EXPR_INDEX) {
169 if (tmp->idx_to >= i)
170 i = tmp->idx_to;
171 else
172 continue;
175 i++;
176 } END_FOR_EACH_PTR(tmp);
177 return i;
179 case EXPR_SYMBOL:
180 return get_array_size(expr);
182 return 0;
185 static struct range_list *db_size_rl;
186 static int db_size_callback(void *unused, int argc, char **argv, char **azColName)
188 struct range_list *tmp = NULL;
190 if (!db_size_rl) {
191 str_to_rl(&int_ctype, argv[0], &db_size_rl);
192 } else {
193 str_to_rl(&int_ctype, argv[0], &tmp);
194 db_size_rl = rl_union(db_size_rl, tmp);
196 return 0;
199 static struct range_list *size_from_db_type(struct expression *expr)
201 int this_file_only = 0;
202 char *name;
204 name = get_member_name(expr);
205 if (!name && is_static(expr)) {
206 name = expr_to_var(expr);
207 this_file_only = 1;
209 if (!name)
210 return NULL;
212 if (this_file_only) {
213 db_size_rl = NULL;
214 run_sql(db_size_callback, NULL,
215 "select size from function_type_size where type = '%s' and file = '%s';",
216 name, get_filename());
217 if (db_size_rl)
218 return db_size_rl;
219 return NULL;
222 db_size_rl = NULL;
223 run_sql(db_size_callback, NULL,
224 "select size from type_size where type = '%s';",
225 name);
226 return db_size_rl;
229 static struct range_list *size_from_db_symbol(struct expression *expr)
231 struct symbol *sym;
233 if (expr->type != EXPR_SYMBOL)
234 return NULL;
235 sym = expr->symbol;
236 if (!sym || !sym->ident ||
237 !(sym->ctype.modifiers & MOD_TOPLEVEL) ||
238 sym->ctype.modifiers & MOD_STATIC)
239 return NULL;
241 db_size_rl = NULL;
242 run_sql(db_size_callback, NULL,
243 "select value from data_info where file = 'extern' and data = '%s' and type = %d;",
244 sym->ident->name, BUF_SIZE);
245 return db_size_rl;
248 static struct range_list *size_from_db(struct expression *expr)
250 struct range_list *rl;
252 rl = size_from_db_symbol(expr);
253 if (rl)
254 return rl;
255 return size_from_db_type(expr);
258 static void db_returns_buf_size(struct expression *expr, int param, char *unused, char *math)
260 struct expression *call;
261 struct range_list *rl;
262 sval_t sval;
264 if (expr->type != EXPR_ASSIGNMENT)
265 return;
266 call = strip_expr(expr->right);
268 call_results_to_rl(call, &int_ctype, math, &rl);
269 rl = cast_rl(&int_ctype, rl);
270 if (rl_to_sval(rl, &sval) && sval.value == 0)
271 return;
272 set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
275 static int get_real_array_size_from_type(struct symbol *type)
277 sval_t sval;
279 if (!type)
280 return 0;
281 if (!type || type->type != SYM_ARRAY)
282 return 0;
284 if (!get_implied_value(type->array_size, &sval))
285 return 0;
287 return sval.value;
290 int get_real_array_size(struct expression *expr)
292 if (!expr)
293 return 0;
294 if (expr->type == EXPR_PREOP && expr->op == '&')
295 expr = expr->unop;
296 if (expr->type == EXPR_BINOP) /* array elements foo[5] */
297 return 0;
298 return get_real_array_size_from_type(get_type(expr));
301 static int get_size_from_initializer(struct expression *expr)
303 if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->initializer)
304 return 0;
305 if (expr->symbol->initializer == expr) /* int a = a; */
306 return 0;
307 return get_initializer_size(expr->symbol->initializer);
310 static struct range_list *get_stored_size_bytes(struct expression *expr)
312 struct smatch_state *state;
314 state = get_state_expr(my_size_id, expr);
315 if (!state)
316 return NULL;
317 return estate_rl(state);
320 static int get_bytes_from_address(struct expression *expr)
322 struct symbol *type;
323 int ret;
325 if (expr->type != EXPR_PREOP || expr->op != '&')
326 return 0;
327 type = get_type(expr);
328 if (!type)
329 return 0;
331 if (type->type == SYM_PTR)
332 type = get_base_type(type);
334 ret = type_bytes(type);
335 if (ret == 1)
336 return 0; /* ignore char pointers */
338 return ret;
341 static struct expression *remove_addr_fluff(struct expression *expr)
343 struct expression *tmp;
344 sval_t sval;
346 expr = strip_expr(expr);
348 /* remove '&' and '*' operations that cancel */
349 while (expr && expr->type == EXPR_PREOP && expr->op == '&') {
350 tmp = strip_expr(expr->unop);
351 if (tmp->type != EXPR_PREOP)
352 break;
353 if (tmp->op != '*')
354 break;
355 expr = strip_expr(tmp->unop);
358 if (!expr)
359 return NULL;
361 /* "foo + 0" is just "foo" */
362 if (expr->type == EXPR_BINOP && expr->op == '+' &&
363 get_value(expr->right, &sval) && sval.value == 0)
364 return expr->left;
366 return expr;
369 static int is_last_member_of_struct(struct symbol *sym, struct ident *member)
371 struct symbol *tmp;
372 int i;
374 if (sym->type != SYM_STRUCT)
375 return false;
377 i = 0;
378 FOR_EACH_PTR_REVERSE(sym->symbol_list, tmp) {
379 if (i++ || !tmp->ident)
380 return 0;
381 if (tmp->ident == member)
382 return 1;
383 return 0;
384 } END_FOR_EACH_PTR_REVERSE(tmp);
386 return 0;
389 int last_member_is_resizable(struct symbol *sym)
391 struct symbol *last_member;
392 struct symbol *type;
393 sval_t sval;
395 if (!sym || sym->type != SYM_STRUCT)
396 return 0;
398 last_member = last_ptr_list((struct ptr_list *)sym->symbol_list);
399 if (!last_member || !last_member->ident)
400 return 0;
402 type = get_real_base_type(last_member);
403 if (type->type == SYM_STRUCT)
404 return last_member_is_resizable(type);
405 if (type->type != SYM_ARRAY)
406 return 0;
408 if (!type->array_size)
409 return 1;
411 if (!get_implied_value(type->array_size, &sval))
412 return 0;
414 if (sval.value != 0 && sval.value != 1)
415 return 0;
417 return 1;
420 static struct range_list *get_stored_size_end_struct_bytes(struct expression *expr)
422 struct symbol *sym;
423 struct symbol *base_sym;
424 struct smatch_state *state;
425 sval_t base_size = {
426 .type = &int_ctype,
429 if (expr->type == EXPR_BINOP) /* array elements foo[5] */
430 return NULL;
432 if (expr->type == EXPR_PREOP && expr->op == '&')
433 expr = strip_parens(expr->unop);
435 sym = expr_to_sym(expr);
436 if (!sym || !sym->ident)
437 return NULL;
438 if (!type_bytes(sym))
439 return NULL;
440 if (sym->type != SYM_NODE)
441 return NULL;
443 base_sym = get_real_base_type(sym);
444 if (!base_sym || base_sym->type != SYM_PTR)
445 return NULL;
446 base_sym = get_real_base_type(base_sym);
447 if (!base_sym || base_sym->type != SYM_STRUCT)
448 return NULL;
450 if (!is_last_member_of_struct(base_sym, expr->member))
451 return NULL;
452 if (!last_member_is_resizable(base_sym))
453 return NULL;
455 state = get_state(my_size_id, sym->ident->name, sym);
456 if (!estate_rl(state))
457 return NULL;
458 base_size.value = type_bytes(base_sym) - type_bytes(get_type(expr));
459 if (sval_cmp(estate_min(state), base_size) < 0)
460 return NULL;
462 return rl_binop(estate_rl(state), '-', alloc_rl(base_size, base_size));
465 static int get_last_element_bytes(struct expression *expr)
467 struct symbol *type, *member, *member_type;
469 type = get_type(expr);
470 if (!type || type->type != SYM_STRUCT)
471 return 0;
472 member = last_ptr_list((struct ptr_list *)type->symbol_list);
473 if (!member)
474 return 0;
475 member_type = get_real_base_type(member);
476 if (!member_type)
477 return 0;
478 return type_bytes(member_type);
481 static struct range_list *get_outer_end_struct_bytes(struct expression *expr)
483 struct expression *outer;
484 int last_element_size;
485 struct symbol *type;
486 sval_t bytes = {
487 .type = &int_ctype,
491 * What we're checking here is for when "u.bar.baz" is a zero element
492 * array and "u" has a buffer to determine the space for baz. Like
493 * this:
494 * struct { struct bar bar; char buf[256]; } u;
498 if (expr->type == EXPR_PREOP && expr->op == '&')
499 expr = strip_parens(expr->unop);
500 if (expr->type != EXPR_DEREF)
501 return NULL;
502 outer = expr->deref;
503 if (outer->type != EXPR_DEREF)
504 return NULL;
505 type = get_type(outer);
506 if (!type)
507 return NULL;
509 if (!is_last_member_of_struct(type, expr->member))
510 return NULL;
511 if (!last_member_is_resizable(type))
512 return NULL;
514 last_element_size = get_last_element_bytes(outer->deref);
515 if (last_element_size == 0)
516 return NULL;
517 if (type_bytes(get_type(outer)) + last_element_size !=
518 type_bytes(get_type(outer->deref)))
519 return NULL;
521 bytes.value = last_element_size;
522 return alloc_rl(bytes, bytes);
525 static struct range_list *alloc_int_rl(int value)
527 sval_t sval = {
528 .type = &int_ctype,
529 {.value = value},
532 return alloc_rl(sval, sval);
535 struct range_list *get_array_size_bytes_rl(struct expression *expr)
537 struct range_list *ret = NULL;
538 sval_t sval;
539 int size;
541 if (is_fake_call(expr))
542 return NULL;
544 expr = remove_addr_fluff(expr);
545 if (!expr)
546 return NULL;
548 /* "BAR" */
549 if (expr->type == EXPR_STRING)
550 return alloc_int_rl(expr->string->length);
552 if (expr->type == EXPR_BINOP && expr->op == '+') {
553 sval_t offset;
554 struct symbol *type;
555 int bytes;
557 if (!get_implied_value(expr->right, &offset))
558 return NULL;
559 type = get_type(expr->left);
560 if (!type)
561 return NULL;
562 if (type->type != SYM_ARRAY && type->type != SYM_PTR)
563 return NULL;
564 type = get_real_base_type(type);
565 bytes = type_bytes(type);
566 if (bytes == 0)
567 return NULL;
568 offset.value *= bytes;
569 size = get_array_size_bytes(expr->left);
570 if (size <= 0)
571 return NULL;
572 return alloc_int_rl(size - offset.value);
575 /* buf = malloc(1024); */
576 ret = get_stored_size_bytes(expr);
577 if (ret)
578 return ret;
580 ret = get_stored_size_end_struct_bytes(expr);
581 if (ret)
582 return ret;
584 ret = get_outer_end_struct_bytes(expr);
585 if (ret)
586 return ret;
588 /* buf[4] */
589 size = get_real_array_size(expr);
590 if (size)
591 return alloc_int_rl(elements_to_bytes(expr, size));
593 /* char *foo = "BAR" */
594 size = get_size_from_initializer(expr);
595 if (size)
596 return alloc_int_rl(elements_to_bytes(expr, size));
598 size = get_bytes_from_address(expr);
599 if (size)
600 return alloc_int_rl(size);
602 ret = size_from_db(expr);
603 if (rl_to_sval(ret, &sval) && sval.value == -1)
604 return NULL;
605 if (ret)
606 return ret;
608 return NULL;
611 int get_array_size_bytes(struct expression *expr)
613 struct range_list *rl;
614 sval_t sval;
616 rl = get_array_size_bytes_rl(expr);
617 if (!rl_to_sval(rl, &sval))
618 return 0;
619 if (sval.uvalue >= INT_MAX)
620 return 0;
621 return sval.value;
624 int get_array_size_bytes_max(struct expression *expr)
626 struct range_list *rl;
627 sval_t bytes;
629 rl = get_array_size_bytes_rl(expr);
630 if (!rl)
631 return 0;
632 bytes = rl_min(rl);
633 if (bytes.value < 0)
634 return 0;
635 bytes = rl_max(rl);
636 if (bytes.uvalue >= INT_MAX)
637 return 0;
638 return bytes.value;
641 int get_array_size_bytes_min(struct expression *expr)
643 struct range_list *rl;
644 struct data_range *range;
646 rl = get_array_size_bytes_rl(expr);
647 if (!rl)
648 return 0;
650 FOR_EACH_PTR(rl, range) {
651 if (range->min.value <= 0)
652 return 0;
653 if (range->max.value <= 0)
654 return 0;
655 if (range->min.uvalue >= INT_MAX)
656 return 0;
657 return range->min.value;
658 } END_FOR_EACH_PTR(range);
660 return 0;
663 int get_array_size(struct expression *expr)
665 if (!expr)
666 return 0;
667 return bytes_to_elements(expr, get_array_size_bytes_max(expr));
670 static struct expression *strip_ampersands(struct expression *expr)
672 struct symbol *type;
674 if (expr->type != EXPR_PREOP)
675 return expr;
676 if (expr->op != '&')
677 return expr;
678 type = get_type(expr->unop);
679 if (!type || type->type != SYM_ARRAY)
680 return expr;
681 return expr->unop;
684 static void info_record_alloction(struct expression *buffer, struct range_list *rl)
686 char *name;
688 if (!option_info)
689 return;
691 name = get_member_name(buffer);
692 if (!name && is_static(buffer))
693 name = expr_to_var(buffer);
694 if (!name)
695 return;
696 if (rl && !is_whole_rl(rl))
697 sql_insert_function_type_size(name, show_rl(rl));
698 else
699 sql_insert_function_type_size(name, "(-1)");
701 free_string(name);
704 static void store_alloc(struct expression *expr, struct range_list *rl)
706 struct symbol *type;
708 rl = clone_rl(rl); // FIXME!!!
709 if (!rl)
710 rl = size_to_rl(UNKNOWN_SIZE);
712 if (rl_min(rl).value != UNKNOWN_SIZE ||
713 rl_max(rl).value != UNKNOWN_SIZE ||
714 get_state_expr(my_size_id, expr))
715 set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
717 type = get_type(expr);
718 if (!type)
719 return;
720 if (type->type != SYM_PTR)
721 return;
722 type = get_real_base_type(type);
723 if (!type)
724 return;
725 if (type == &void_ctype)
726 return;
727 if (type->type != SYM_BASETYPE && type->type != SYM_PTR)
728 return;
730 info_record_alloction(expr, rl);
733 static bool is_array_base(struct expression *expr)
735 struct symbol *type;
737 type = get_type(expr);
738 if (type && type->type == SYM_ARRAY)
739 return true;
740 return false;
743 static void match_array_assignment(struct expression *expr)
745 struct expression *left;
746 struct expression *right;
747 char *left_member, *right_member;
748 struct range_list *rl;
749 sval_t sval;
751 if (expr->op != '=')
752 return;
754 left = strip_expr(expr->left);
755 right = strip_expr(expr->right);
756 right = strip_ampersands(right);
758 if (!is_pointer(left))
759 return;
760 /* char buf[24] = "str"; */
761 if (is_array_base(left))
762 return;
763 if (is_allocation_function(right))
764 return;
766 left_member = get_member_name(left);
767 right_member = get_member_name(right);
768 if (left_member && right_member && strcmp(left_member, right_member) == 0) {
769 free_string(left_member);
770 free_string(right_member);
771 return;
773 free_string(left_member);
774 free_string(right_member);
776 if (get_implied_value(right, &sval) && sval.value == 0) {
777 rl = alloc_int_rl(0);
778 goto store;
781 rl = get_array_size_bytes_rl(right);
782 if (!rl && __in_fake_assign)
783 return;
785 store:
786 store_alloc(left, rl);
789 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg)
791 int size_arg = PTR_INT(_size_arg);
792 struct expression *right;
793 struct expression *arg;
794 struct range_list *rl;
796 right = strip_expr(expr->right);
797 arg = get_argument_from_call_expr(right->args, size_arg);
798 get_absolute_rl(arg, &rl);
799 rl = cast_rl(&int_ctype, rl);
800 store_alloc(expr->left, rl);
803 static void match_calloc(const char *fn, struct expression *expr, void *_param)
805 struct expression *right;
806 struct expression *size, *nr, *mult;
807 struct range_list *rl;
808 int param = PTR_INT(_param);
810 right = strip_expr(expr->right);
811 nr = get_argument_from_call_expr(right->args, param);
812 size = get_argument_from_call_expr(right->args, param + 1);
813 mult = binop_expression(nr, '*', size);
814 if (get_implied_rl(mult, &rl))
815 store_alloc(expr->left, rl);
816 else
817 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
820 static void match_page(const char *fn, struct expression *expr, void *_unused)
822 sval_t page_size = {
823 .type = &int_ctype,
824 {.value = 4096},
827 store_alloc(expr->left, alloc_rl(page_size, page_size));
830 static void match_strndup(const char *fn, struct expression *expr, void *unused)
832 struct expression *fn_expr;
833 struct expression *size_expr;
834 sval_t size;
836 fn_expr = strip_expr(expr->right);
837 size_expr = get_argument_from_call_expr(fn_expr->args, 1);
838 if (get_implied_max(size_expr, &size)) {
839 size.value++;
840 store_alloc(expr->left, size_to_rl(size.value));
841 } else {
842 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
847 static void match_alloc_pages(const char *fn, struct expression *expr, void *_order_arg)
849 int order_arg = PTR_INT(_order_arg);
850 struct expression *right;
851 struct expression *arg;
852 sval_t sval;
854 right = strip_expr(expr->right);
855 arg = get_argument_from_call_expr(right->args, order_arg);
856 if (!get_implied_value(arg, &sval))
857 return;
858 if (sval.value < 0 || sval.value > 10)
859 return;
861 sval.type = &int_ctype;
862 sval.value = 1 << sval.value;
863 sval.value *= 4096;
865 store_alloc(expr->left, alloc_rl(sval, sval));
868 static int is_type_bytes(struct range_list *rl, struct expression *call, int nr)
870 struct symbol *type;
871 sval_t sval;
873 if (!rl_to_sval(rl, &sval))
874 return 0;
876 type = get_arg_type(call->fn, nr);
877 if (!type)
878 return 0;
879 if (type->type != SYM_PTR)
880 return 0;
881 type = get_real_base_type(type);
882 if (sval.value != type_bytes(type))
883 return 0;
884 return 1;
887 static void match_call(struct expression *expr)
889 struct expression *arg;
890 struct symbol *type;
891 struct range_list *rl;
892 int i;
894 i = -1;
895 FOR_EACH_PTR(expr->args, arg) {
896 i++;
897 type = get_type(arg);
898 if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY))
899 continue;
900 rl = get_array_size_bytes_rl(arg);
901 if (!rl)
902 continue;
903 if (rl_min(rl).value == UNKNOWN_SIZE &&
904 rl_max(rl).value == UNKNOWN_SIZE)
905 continue;
906 if (is_whole_rl(rl))
907 continue;
908 if (is_type_bytes(rl, expr, i))
909 continue;
910 sql_insert_caller_info(expr, BUF_SIZE, i, "$", show_rl(rl));
911 } END_FOR_EACH_PTR(arg);
914 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
916 sval_t sval;
918 if (!estate_rl(sm->state) ||
919 (estate_get_single_value(sm->state, &sval) &&
920 (sval.value == -1 || sval.value == 0)))
921 return;
923 sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name);
927 * This is slightly (very) weird because half of this stuff is handled in
928 * smatch_parse_call_math.c which is poorly named. But anyway, add some buf
929 * sizes here.
932 static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr)
934 const char *param_math;
935 struct range_list *rl;
936 char buf[64];
937 sval_t sval;
939 rl = get_array_size_bytes_rl(expr);
940 param_math = get_allocation_math(expr);
941 if (!rl && !param_math)
942 return;
944 if (!param_math &&
945 rl_to_sval(rl, &sval) &&
946 (sval.value == -1 || sval.value == 0))
947 return;
949 if (param_math)
950 snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), param_math);
951 else
952 snprintf(buf, sizeof(buf), "%s", show_rl(rl));
954 // FIXME: don't store if you can guess the size from the type
955 // FIXME: return if we allocate a parameter $0->bar
956 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf);
959 static void record_global_size(struct symbol *sym)
961 int bytes;
962 char buf[16];
964 if (!sym->ident)
965 return;
967 if (!(sym->ctype.modifiers & MOD_TOPLEVEL) ||
968 sym->ctype.modifiers & MOD_STATIC)
969 return;
971 bytes = get_array_size_bytes(symbol_expression(sym));
972 if (bytes <= 1)
973 return;
975 snprintf(buf, sizeof(buf), "%d", bytes);
976 sql_insert_data_info_var_sym(sym->ident->name, sym, BUF_SIZE, buf);
979 void register_buf_size(int id)
981 my_size_id = id;
983 set_dynamic_states(my_size_id);
985 add_unmatched_state_hook(my_size_id, &unmatched_size_state);
986 add_merge_hook(my_size_id, &merge_estates);
988 select_caller_info_hook(set_param_buf_size, BUF_SIZE);
989 select_return_states_hook(BUF_SIZE, &db_returns_buf_size);
990 add_split_return_callback(print_returned_allocations);
992 allocation_funcs = create_function_hashtable(100);
993 add_allocation_function("malloc", &match_alloc, 0);
994 add_allocation_function("calloc", &match_calloc, 0);
995 add_allocation_function("memdup", &match_alloc, 1);
996 add_allocation_function("realloc", &match_alloc, 1);
997 if (option_project == PROJ_KERNEL) {
998 add_allocation_function("kmalloc", &match_alloc, 0);
999 add_allocation_function("kmalloc_node", &match_alloc, 0);
1000 add_allocation_function("kzalloc", &match_alloc, 0);
1001 add_allocation_function("kzalloc_node", &match_alloc, 0);
1002 add_allocation_function("vmalloc", &match_alloc, 0);
1003 add_allocation_function("vzalloc", &match_alloc, 0);
1004 add_allocation_function("__vmalloc", &match_alloc, 0);
1005 add_allocation_function("kvmalloc", &match_alloc, 0);
1006 add_allocation_function("kcalloc", &match_calloc, 0);
1007 add_allocation_function("kvcalloc", &match_calloc, 0);
1008 add_allocation_function("kmalloc_array", &match_calloc, 0);
1009 add_allocation_function("devm_kmalloc_array", &match_calloc, 1);
1010 add_allocation_function("sock_kmalloc", &match_alloc, 1);
1011 add_allocation_function("kmemdup", &match_alloc, 1);
1012 add_allocation_function("kmemdup_user", &match_alloc, 1);
1013 add_allocation_function("dma_alloc_attrs", &match_alloc, 1);
1014 add_allocation_function("pci_alloc_consistent", &match_alloc, 1);
1015 add_allocation_function("pci_alloc_coherent", &match_alloc, 1);
1016 add_allocation_function("devm_kmalloc", &match_alloc, 1);
1017 add_allocation_function("devm_kzalloc", &match_alloc, 1);
1018 add_allocation_function("krealloc", &match_alloc, 1);
1019 add_allocation_function("__alloc_bootmem", &match_alloc, 0);
1020 add_allocation_function("alloc_bootmem", &match_alloc, 0);
1021 add_allocation_function("kmap", &match_page, 0);
1022 add_allocation_function("kmap_atomic", &match_page, 0);
1023 add_allocation_function("get_zeroed_page", &match_page, 0);
1024 add_allocation_function("alloc_page", &match_page, 0);
1025 add_allocation_function("alloc_pages", &match_alloc_pages, 1);
1026 add_allocation_function("alloc_pages_current", &match_alloc_pages, 1);
1027 add_allocation_function("__get_free_pages", &match_alloc_pages, 1);
1028 add_allocation_function("dma_alloc_contiguous", &match_alloc, 1);
1029 add_allocation_function("dma_alloc_coherent", &match_alloc, 1);
1032 add_allocation_function("strndup", match_strndup, 0);
1033 if (option_project == PROJ_KERNEL)
1034 add_allocation_function("kstrndup", match_strndup, 0);
1036 add_modification_hook(my_size_id, &set_size_undefined);
1038 add_merge_hook(my_size_id, &merge_size_func);
1040 if (option_info)
1041 add_hook(record_global_size, BASE_HOOK);
1044 void register_buf_size_late(int id)
1046 /* has to happen after match_alloc() */
1047 add_hook(&match_array_assignment, ASSIGNMENT_HOOK);
1049 add_hook(&match_call, FUNCTION_CALL_HOOK);
1050 add_member_info_callback(my_size_id, struct_member_callback);