Print this page
11972 resync smatch
@@ -21,11 +21,11 @@
#include "smatch.h"
#include "smatch_slist.h"
#include "smatch_extra.h"
#include "smatch_function_hashtable.h"
-#define UNKNOWN_SIZE (-1)
+#define UNKNOWN_SIZE -1
static int my_size_id;
static DEFINE_HASHTABLE_INSERT(insert_func, char, int);
static DEFINE_HASHTABLE_SEARCH(search_func, char, int);
@@ -272,12 +272,11 @@
if (expr->type != EXPR_ASSIGNMENT)
return;
call = strip_expr(expr->right);
- if (!parse_call_math_rl(call, math, &rl))
- return;
+ call_results_to_rl(call, &int_ctype, math, &rl);
rl = cast_rl(&int_ctype, rl);
set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
}
static int get_real_array_size_from_type(struct symbol *type)
@@ -469,10 +468,11 @@
}
struct range_list *get_array_size_bytes_rl(struct expression *expr)
{
struct range_list *ret = NULL;
+ sval_t sval;
int size;
expr = remove_addr_fluff(expr);
if (!expr)
return NULL;
@@ -526,10 +526,12 @@
size = get_bytes_from_address(expr);
if (size)
return alloc_int_rl(size);
ret = size_from_db(expr);
+ if (rl_to_sval(ret, &sval) && sval.value == -1)
+ return NULL;
if (ret)
return ret;
return NULL;
}
@@ -630,10 +632,12 @@
static void store_alloc(struct expression *expr, struct range_list *rl)
{
struct symbol *type;
rl = clone_rl(rl); // FIXME!!!
+ if (!rl)
+ rl = size_to_rl(UNKNOWN_SIZE);
set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
type = get_type(expr);
if (!type)
return;
@@ -717,11 +721,11 @@
size = get_argument_from_call_expr(right->args, 1);
mult = binop_expression(nr, '*', size);
if (get_implied_rl(mult, &rl))
store_alloc(expr->left, rl);
else
- store_alloc(expr->left, size_to_rl(-1));
+ store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
}
static void match_page(const char *fn, struct expression *expr, void *_unused)
{
sval_t page_size = {
@@ -742,11 +746,11 @@
size_expr = get_argument_from_call_expr(fn_expr->args, 1);
if (get_implied_max(size_expr, &size)) {
size.value++;
store_alloc(expr->left, size_to_rl(size.value));
} else {
- store_alloc(expr->left, size_to_rl(-1));
+ store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));
}
}
static void match_alloc_pages(const char *fn, struct expression *expr, void *_order_arg)
@@ -816,15 +820,17 @@
} END_FOR_EACH_PTR(arg);
}
static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
{
- if (sm->state == &merged ||
- strcmp(sm->state->name, "(-1)") == 0 ||
- strcmp(sm->state->name, "empty") == 0 ||
- strcmp(sm->state->name, "0") == 0)
+ sval_t sval;
+
+ if (!estate_rl(sm->state) ||
+ (estate_get_single_value(sm->state, &sval) &&
+ (sval.value == -1 || sval.value == 0)))
return;
+
sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name);
}
/*
* This is slightly (very) weird because half of this stuff is handled in
@@ -832,18 +838,32 @@
* sizes here.
*
*/
static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr)
{
- char buf[16];
- int size;
+ const char *param_math;
+ struct range_list *rl;
+ char buf[64];
+ sval_t sval;
- size = get_array_size_bytes(expr);
- if (!size)
+ rl = get_array_size_bytes_rl(expr);
+ param_math = get_allocation_math(expr);
+ if (!rl && !param_math)
return;
- snprintf(buf, sizeof(buf), "%d", size);
+ if (!param_math &&
+ rl_to_sval(rl, &sval) &&
+ (sval.value == -1 || sval.value == 0))
+ return;
+
+ if (param_math)
+ snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), param_math);
+ else
+ snprintf(buf, sizeof(buf), "%s", show_rl(rl));
+
+ // FIXME: don't store if you can guess the size from the type
+ // FIXME: return if we allocate a parameter $0->bar
sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf);
}
static void record_global_size(struct symbol *sym)
{
@@ -870,10 +890,11 @@
my_size_id = id;
set_dynamic_states(my_size_id);
add_unmatched_state_hook(my_size_id, &unmatched_size_state);
+ add_merge_hook(my_size_id, &merge_estates);
select_caller_info_hook(set_param_buf_size, BUF_SIZE);
select_return_states_hook(BUF_SIZE, &db_returns_buf_size);
add_split_return_callback(print_returned_allocations);
@@ -903,17 +924,18 @@
add_allocation_function("devm_kzalloc", &match_alloc, 1);
add_allocation_function("krealloc", &match_alloc, 1);
add_allocation_function("__alloc_bootmem", &match_alloc, 0);
add_allocation_function("alloc_bootmem", &match_alloc, 0);
add_allocation_function("kmap", &match_page, 0);
+ add_allocation_function("kmap_atomic", &match_page, 0);
add_allocation_function("get_zeroed_page", &match_page, 0);
add_allocation_function("alloc_page", &match_page, 0);
- add_allocation_function("page_address", &match_page, 0);
- add_allocation_function("lowmem_page_address", &match_page, 0);
add_allocation_function("alloc_pages", &match_alloc_pages, 1);
add_allocation_function("alloc_pages_current", &match_alloc_pages, 1);
add_allocation_function("__get_free_pages", &match_alloc_pages, 1);
+ add_allocation_function("dma_alloc_contiguous", &match_alloc, 1);
+ add_allocation_function("dma_alloc_coherent", &match_alloc, 1);
}
add_allocation_function("strndup", match_strndup, 0);
if (option_project == PROJ_KERNEL)
add_allocation_function("kstrndup", match_strndup, 0);