2 * sparse/check_kernel.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * This is kernel specific stuff for smatch_extra.
15 #include "smatch_extra.h"
17 static void match_err_cast(const char *fn
, struct expression
*expr
, void *unused
)
19 struct expression
*arg
;
20 struct expression
*right
;
21 struct range_list
*rl
;
23 right
= strip_expr(expr
->right
);
24 arg
= get_argument_from_call_expr(right
->args
, 0);
26 if (get_implied_range_list(arg
, &rl
))
27 set_extra_expr_mod(expr
->left
, alloc_estate_range_list(rl
));
29 set_extra_expr_mod(expr
->left
, alloc_estate_range(-4095, -1));
32 static void match_param_nonnull(const char *fn
, struct expression
*call_expr
,
33 struct expression
*assign_expr
, void *_param
)
35 int param
= PTR_INT(_param
);
36 struct expression
*arg
;
37 struct smatch_state
*pre_state
;
38 struct smatch_state
*true_state
;
40 arg
= get_argument_from_call_expr(call_expr
->args
, param
);
41 pre_state
= get_state_expr(SMATCH_EXTRA
, arg
);
42 true_state
= add_filter(pre_state
, 0);
43 set_extra_expr_nomod(arg
, true_state
);
46 static void match_not_err(const char *fn
, struct expression
*call_expr
,
47 struct expression
*assign_expr
, void *unused
)
49 struct expression
*arg
;
50 struct smatch_state
*pre_state
;
51 struct smatch_state
*new_state
;
53 arg
= get_argument_from_call_expr(call_expr
->args
, 0);
54 pre_state
= get_state_expr(SMATCH_EXTRA
, arg
);
55 new_state
= filter_range(pre_state
, whole_range
.min
, -1);
56 set_extra_expr_nomod(arg
, new_state
);
59 static void match_err(const char *fn
, struct expression
*call_expr
,
60 struct expression
*assign_expr
, void *unused
)
62 struct expression
*arg
;
63 struct smatch_state
*pre_state
;
64 struct smatch_state
*new_state
;
66 arg
= get_argument_from_call_expr(call_expr
->args
, 0);
67 pre_state
= get_state_expr(SMATCH_EXTRA
, arg
);
68 new_state
= filter_range(pre_state
, whole_range
.min
, -4097);
69 new_state
= filter_range(new_state
, 0, whole_range
.max
);
70 set_extra_expr_nomod(arg
, new_state
);
73 static void match_container_of(const char *fn
, struct expression
*expr
, void *unused
)
75 set_extra_expr_mod(expr
->left
, alloc_estate_range(valid_ptr_min
, valid_ptr_max
));
78 void check_kernel(int id
)
80 if (option_project
!= PROJ_KERNEL
)
83 add_function_assign_hook_extra("ERR_PTR", &match_err_cast
, NULL
);
84 add_function_assign_hook_extra("ERR_CAST", &match_err_cast
, NULL
);
85 add_function_assign_hook_extra("PTR_ERR", &match_err_cast
, NULL
);
86 return_implies_state("IS_ERR_OR_NULL", 0, 0, &match_param_nonnull
, (void *)0);
87 return_implies_state("IS_ERR", 0, 0, &match_not_err
, NULL
);
88 return_implies_state("IS_ERR", 1, 1, &match_err
, NULL
);
89 return_implies_state("tomoyo_memory_ok", 1, 1, &match_param_nonnull
, (void *)0);
90 add_macro_assign_hook_extra("container_of", &match_container_of
, NULL
);