Print this page
11506 smatch resync
@@ -21,17 +21,23 @@
#include "scope.h"
#include "smatch.h"
#include "smatch_extra.h"
+static sval_t err_ptr_min;
+static sval_t err_ptr_max;
+static sval_t null_ptr;
+
static int implied_err_cast_return(struct expression *call, void *unused, struct range_list **rl)
{
struct expression *arg;
arg = get_argument_from_call_expr(call->args, 0);
- if (!get_implied_rl(arg, rl))
- *rl = alloc_rl(ll_to_sval(-4095), ll_to_sval(-1));
+ if (!get_implied_rl(arg, rl)) {
+ *rl = alloc_rl(err_ptr_min, err_ptr_max);
+ *rl = cast_rl(get_type(arg), *rl);
+ }
return 1;
}
static void hack_ERR_PTR(struct symbol *sym)
{
@@ -76,14 +82,22 @@
{
int param = PTR_INT(_param);
struct expression *arg;
struct smatch_state *pre_state;
struct smatch_state *end_state;
+ struct range_list *rl;
arg = get_argument_from_call_expr(call_expr->args, param);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
- end_state = estate_filter_range(pre_state, ll_to_sval(-4095), ll_to_sval(0));
+ if (estate_rl(pre_state)) {
+ rl = estate_rl(pre_state);
+ rl = remove_range(rl, null_ptr, null_ptr);
+ rl = remove_range(rl, err_ptr_min, err_ptr_max);
+ } else {
+ rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
+ }
+ end_state = alloc_estate_rl(rl);
set_extra_expr_nomod(arg, end_state);
}
static void match_param_err_or_null(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *_param)
@@ -94,42 +108,51 @@
struct smatch_state *pre_state;
struct smatch_state *end_state;
arg = get_argument_from_call_expr(call_expr->args, param);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
- rl = alloc_rl(ll_to_sval(-4095), ll_to_sval(0));
+ call_results_to_rl(call_expr, &ptr_ctype, "0,(-4095)-(-1)", &rl);
rl = rl_intersection(estate_rl(pre_state), rl);
- rl = cast_rl(estate_type(pre_state), rl);
+ rl = cast_rl(get_type(arg), rl);
end_state = alloc_estate_rl(rl);
set_extra_expr_nomod(arg, end_state);
}
static void match_not_err(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *unused)
{
struct expression *arg;
struct smatch_state *pre_state;
- struct smatch_state *new_state;
+ struct range_list *rl;
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
- new_state = estate_filter_range(pre_state, sval_type_min(&long_ctype), ll_to_sval(-1));
- set_extra_expr_nomod(arg, new_state);
+ if (estate_rl(pre_state)) {
+ rl = estate_rl(pre_state);
+ rl = remove_range(rl, err_ptr_min, err_ptr_max);
+ } else {
+ rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
+ }
+ rl = cast_rl(get_type(arg), rl);
+ set_extra_expr_nomod(arg, alloc_estate_rl(rl));
}
static void match_err(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *unused)
{
struct expression *arg;
struct smatch_state *pre_state;
- struct smatch_state *new_state;
+ struct range_list *rl;
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
- new_state = estate_filter_range(pre_state, sval_type_min(&long_ctype), ll_to_sval(-4096));
- new_state = estate_filter_range(new_state, ll_to_sval(0), sval_type_max(&long_ctype));
- set_extra_expr_nomod(arg, new_state);
+ rl = estate_rl(pre_state);
+ if (!rl)
+ rl = alloc_rl(err_ptr_min, err_ptr_max);
+ rl = rl_intersection(rl, alloc_rl(err_ptr_min, err_ptr_max));
+ rl = cast_rl(get_type(arg), rl);
+ set_extra_expr_nomod(arg, alloc_estate_rl(rl));
}
static void match_container_of_macro(const char *fn, struct expression *expr, void *unused)
{
set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
@@ -377,15 +400,40 @@
__in_fake_assign++;
__split_expr(assign);
__in_fake_assign--;
}
+bool is_ignored_kernel_data(const char *name)
+{
+ if (option_project != PROJ_KERNEL)
+ return false;
+
+ /*
+ * On the file I was looking at lockdep was 25% of the DB.
+ */
+ if (strstr(name, ".dep_map."))
+ return true;
+ if (strstr(name, ".lockdep_map."))
+ return true;
+ return false;
+}
+
void check_kernel(int id)
{
if (option_project != PROJ_KERNEL)
return;
+ err_ptr_min.type = &ptr_ctype;
+ err_ptr_min.value = -4095;
+ err_ptr_max.type = &ptr_ctype;
+ err_ptr_max.value = -1l;
+ null_ptr.type = &ptr_ctype;
+ null_ptr.value = 0;
+
+ err_ptr_min = sval_cast(&ptr_ctype, err_ptr_min);
+ err_ptr_max = sval_cast(&ptr_ctype, err_ptr_max);
+
add_implied_return_hook("ERR_PTR", &implied_err_cast_return, NULL);
add_implied_return_hook("ERR_CAST", &implied_err_cast_return, NULL);
add_implied_return_hook("PTR_ERR", &implied_err_cast_return, NULL);
add_hook(hack_ERR_PTR, AFTER_DEF_HOOK);
return_implies_state("IS_ERR_OR_NULL", 0, 0, &match_param_valid_ptr, (void *)0);