summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/tools/smatch/Makefile3
-rw-r--r--usr/src/tools/smatch/src/Makefile2
-rw-r--r--usr/src/tools/smatch/src/check_all_func_returns.c2
-rw-r--r--usr/src/tools/smatch/src/check_allocating_enough_data.c6
-rw-r--r--usr/src/tools/smatch/src/check_atomic_inc_dec.c165
-rw-r--r--usr/src/tools/smatch/src/check_debug.c65
-rw-r--r--usr/src/tools/smatch/src/check_debug.h5
-rw-r--r--usr/src/tools/smatch/src/check_err_ptr.c1
-rw-r--r--usr/src/tools/smatch/src/check_kernel.c43
-rw-r--r--usr/src/tools/smatch/src/check_shift_to_zero.c4
-rw-r--r--usr/src/tools/smatch/src/expression.h5
-rw-r--r--usr/src/tools/smatch/src/smatch.c1
-rw-r--r--usr/src/tools/smatch/src/smatch.h38
-rw-r--r--usr/src/tools/smatch/src/smatch_bits.c79
-rw-r--r--usr/src/tools/smatch/src/smatch_buf_size.c49
-rw-r--r--usr/src/tools/smatch/src/smatch_capped.c8
-rw-r--r--usr/src/tools/smatch/src/smatch_comparison.c4
-rw-r--r--usr/src/tools/smatch/src/smatch_container_of.c6
-rwxr-xr-xusr/src/tools/smatch/src/smatch_data/db/create_db.sh4
-rw-r--r--usr/src/tools/smatch/src/smatch_data/db/kernel.return_fixes11
-rwxr-xr-xusr/src/tools/smatch/src/smatch_data/db/mark_function_ptrs_searchable.pl11
-rw-r--r--usr/src/tools/smatch/src/smatch_data/db/mtag_about.schema11
-rw-r--r--usr/src/tools/smatch/src/smatch_data/db/mtag_info.schema1
-rw-r--r--usr/src/tools/smatch/src/smatch_data/db/mtag_map.schema2
-rw-r--r--usr/src/tools/smatch/src/smatch_data/db/return_states.schema2
-rwxr-xr-xusr/src/tools/smatch/src/smatch_data/db/smdb.py7
-rw-r--r--usr/src/tools/smatch/src/smatch_db.c191
-rw-r--r--usr/src/tools/smatch/src/smatch_estate.c22
-rw-r--r--usr/src/tools/smatch/src/smatch_expressions.c4
-rw-r--r--usr/src/tools/smatch/src/smatch_extra.c44
-rw-r--r--usr/src/tools/smatch/src/smatch_extra.h4
-rw-r--r--usr/src/tools/smatch/src/smatch_flow.c16
-rw-r--r--usr/src/tools/smatch/src/smatch_fresh_alloc.c24
-rw-r--r--usr/src/tools/smatch/src/smatch_function_hooks.c49
-rw-r--r--usr/src/tools/smatch/src/smatch_function_ptrs.c2
-rw-r--r--usr/src/tools/smatch/src/smatch_helper.c90
-rw-r--r--usr/src/tools/smatch/src/smatch_implied.c106
-rw-r--r--usr/src/tools/smatch/src/smatch_kernel_user_data.c15
-rw-r--r--usr/src/tools/smatch/src/smatch_math.c26
-rw-r--r--usr/src/tools/smatch/src/smatch_mtag.c92
-rw-r--r--usr/src/tools/smatch/src/smatch_mtag_data.c59
-rw-r--r--usr/src/tools/smatch/src/smatch_mtag_map.c13
-rw-r--r--usr/src/tools/smatch/src/smatch_param_to_mtag_data.c5
-rw-r--r--usr/src/tools/smatch/src/smatch_real_absolute.c5
-rw-r--r--usr/src/tools/smatch/src/smatch_return_to_param.c1
-rwxr-xr-xusr/src/tools/smatch/src/smatch_scripts/build_kernel_data.sh1
-rwxr-xr-xusr/src/tools/smatch/src/smatch_scripts/summarize_errs.sh6
-rw-r--r--usr/src/tools/smatch/src/smatch_slist.c3
-rw-r--r--usr/src/tools/smatch/src/smatch_states.c59
-rw-r--r--usr/src/tools/smatch/src/smatch_struct_assignment.c7
-rw-r--r--usr/src/tools/smatch/src/smatch_type.c48
-rw-r--r--usr/src/tools/smatch/src/smatch_type_val.c2
-rw-r--r--usr/src/tools/smatch/src/token.h1
-rw-r--r--usr/src/tools/smatch/src/tokenize.c2
-rw-r--r--usr/src/tools/smatch/src/validation/sm_impossible1.c2
-rw-r--r--usr/src/tools/smatch/src/validation/sm_impossible2.c2
-rw-r--r--usr/src/uts/sun4u/ics951601/Makefile15
-rw-r--r--usr/src/uts/sun4u/io/i2c/clients/ics951601.c20
-rw-r--r--usr/src/uts/sun4u/io/i2c/clients/pca9556.c22
-rw-r--r--usr/src/uts/sun4u/io/i2c/clients/seeprom.c2
-rw-r--r--usr/src/uts/sun4u/pca9556/Makefile20
-rw-r--r--usr/src/uts/sun4u/seeprom/Makefile20
62 files changed, 1153 insertions, 382 deletions
diff --git a/usr/src/tools/smatch/Makefile b/usr/src/tools/smatch/Makefile
index bc92591526..4b2c909785 100644
--- a/usr/src/tools/smatch/Makefile
+++ b/usr/src/tools/smatch/Makefile
@@ -20,7 +20,7 @@
#
PROG = smatch
-SPARSE_VERSION = 0.6.1-rc1-il-4
+SPARSE_VERSION = 0.6.1-rc1-il-5
include ../Makefile.tools
@@ -230,6 +230,7 @@ SMATCH_DB_DATA += mtag_alias.schema
SMATCH_DB_DATA += type_size.schema
SMATCH_DB_DATA += fn_ptr_data_link.schema
SMATCH_DB_DATA += mtag_data.schema
+SMATCH_DB_DATA += mtag_info.schema
SMATCH_DB_DATA += type_value.schema
ROOTONBLDDATAFILES = $(SMATCH_DATA:%=$(SMATCHDATADIR)/smatch_data/%)
diff --git a/usr/src/tools/smatch/src/Makefile b/usr/src/tools/smatch/src/Makefile
index bc8b3071a1..7cd1db3039 100644
--- a/usr/src/tools/smatch/src/Makefile
+++ b/usr/src/tools/smatch/src/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.6.1-rc1-il-4
+VERSION=0.6.1-rc1-il-5
########################################################################
# The following variables can be overwritten from the command line
diff --git a/usr/src/tools/smatch/src/check_all_func_returns.c b/usr/src/tools/smatch/src/check_all_func_returns.c
index f9d774499c..1ff50433d5 100644
--- a/usr/src/tools/smatch/src/check_all_func_returns.c
+++ b/usr/src/tools/smatch/src/check_all_func_returns.c
@@ -74,7 +74,7 @@ static void check_func_return(struct expression *expr)
stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
- if (stmt->type == STMT_EXPRESSION && stmt->expression == expr)
+ if (stmt && stmt->type == STMT_EXPRESSION && stmt->expression == expr)
sm_error("unchecked function return '%s'", expr_to_str(expr->fn));
}
diff --git a/usr/src/tools/smatch/src/check_allocating_enough_data.c b/usr/src/tools/smatch/src/check_allocating_enough_data.c
index 12cb72bf23..79b3295195 100644
--- a/usr/src/tools/smatch/src/check_allocating_enough_data.c
+++ b/usr/src/tools/smatch/src/check_allocating_enough_data.c
@@ -23,6 +23,7 @@ static void db_returns_buf_size(struct expression *expr, int param, char *unused
struct symbol *left_type, *right_type;
int bytes;
sval_t sval;
+ char *str;
if (expr->type != EXPR_ASSIGNMENT)
return;
@@ -42,7 +43,10 @@ static void db_returns_buf_size(struct expression *expr, int param, char *unused
return;
if (sval.uvalue >= bytes)
return;
- sm_error("not allocating enough data %d vs %s", bytes, sval_to_str(sval));
+
+ str = expr_to_str(expr->left);
+ sm_error("not allocating enough for = '%s' %d vs %s", str, bytes, sval_to_str(sval));
+ free_string(str);
}
void check_allocating_enough_data(int id)
diff --git a/usr/src/tools/smatch/src/check_atomic_inc_dec.c b/usr/src/tools/smatch/src/check_atomic_inc_dec.c
index 6474323eac..c83dc893b2 100644
--- a/usr/src/tools/smatch/src/check_atomic_inc_dec.c
+++ b/usr/src/tools/smatch/src/check_atomic_inc_dec.c
@@ -15,6 +15,8 @@
* along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
*/
+#include <ctype.h>
+
#include "smatch.h"
#include "smatch_extra.h"
#include "smatch_slist.h"
@@ -25,12 +27,72 @@ STATE(inc);
STATE(orig);
STATE(dec);
+static struct smatch_state *unmatched_state(struct sm_state *sm)
+{
+ if (parent_is_gone_var_sym(sm->name, sm->sym))
+ return sm->state;
+ return &undefined;
+}
+
+static struct stree *start_states;
+static struct stree_stack *saved_stack;
+static void set_start_state(const char *name, struct symbol *sym, struct smatch_state *start)
+{
+ struct smatch_state *orig;
+
+ orig = get_state_stree(start_states, my_id, name, sym);
+ if (!orig)
+ set_state_stree(&start_states, my_id, name, sym, start);
+ else if (orig != start)
+ set_state_stree(&start_states, my_id, name, sym, &undefined);
+}
+
+static struct sm_state *get_best_match(const char *key)
+{
+ struct sm_state *sm;
+ struct sm_state *match;
+ int cnt = 0;
+ int start_pos, state_len, key_len, chunks, i;
+
+ if (strncmp(key, "$->", 3) == 0)
+ key += 3;
+
+ key_len = strlen(key);
+ chunks = 0;
+ for (i = key_len - 1; i > 0; i--) {
+ if (key[i] == '>' || key[i] == '.')
+ chunks++;
+ if (chunks == 2) {
+ key += (i + 1);
+ key_len = strlen(key);
+ break;
+ }
+ }
+
+ FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
+ state_len = strlen(sm->name);
+ if (state_len < key_len)
+ continue;
+ start_pos = state_len - key_len;
+ if ((start_pos == 0 || !isalnum(sm->name[start_pos - 1])) &&
+ strcmp(sm->name + start_pos, key) == 0) {
+ cnt++;
+ match = sm;
+ }
+ } END_FOR_EACH_SM(sm);
+
+ if (cnt == 1)
+ return match;
+ return NULL;
+}
+
static void db_inc_dec(struct expression *expr, int param, const char *key, const char *value, int inc_dec)
{
- struct smatch_state *start_state;
+ struct sm_state *start_sm;
struct expression *arg;
char *name;
struct symbol *sym;
+ bool free_at_end = true;
while (expr->type == EXPR_ASSIGNMENT)
expr = strip_expr(expr->right);
@@ -45,23 +107,36 @@ static void db_inc_dec(struct expression *expr, int param, const char *key, cons
if (!name || !sym)
goto free;
- start_state = get_state(my_id, name, sym);
+ start_sm = get_sm_state(my_id, name, sym);
+ if (!start_sm && inc_dec == ATOMIC_DEC) {
+ start_sm = get_best_match(key);
+ if (start_sm) {
+ free_string(name);
+ free_at_end = false;
+ name = (char *)start_sm->name;
+ sym = start_sm->sym;
+ }
+ }
if (inc_dec == ATOMIC_INC) {
-// if (start_state == &inc)
-// sm_error("XXX double increment '%s'", name);
+ if (!start_sm)
+ set_start_state(name, sym, &dec);
+// set_refcount_inc(name, sym);
set_state(my_id, name, sym, &inc);
} else {
-// if (start_state == &dec)
-// sm_error("XXX double decrement '%s'", name);
- if (start_state == &inc)
+// set_refcount_dec(name, sym);
+ if (!start_sm)
+ set_start_state(name, sym, &inc);
+
+ if (start_sm && start_sm->state == &inc)
set_state(my_id, name, sym, &orig);
else
set_state(my_id, name, sym, &dec);
}
free:
- free_string(name);
+ if (free_at_end)
+ free_string(name);
}
static void db_inc(struct expression *expr, int param, char *key, char *value)
@@ -123,6 +198,8 @@ static void match_return_info(int return_id, char *return_ranges, struct express
if (sm->state != &inc &&
sm->state != &dec)
continue;
+ if (parent_is_gone_var_sym(sm->name, sm->sym))
+ continue;
param = get_param_num_from_sym(sm->sym);
if (param < 0)
continue;
@@ -136,13 +213,13 @@ static void match_return_info(int return_id, char *return_ranges, struct express
}
enum {
- NEGATIVE, ZERO, POSITIVE,
+ EMPTY, NEGATIVE, ZERO, POSITIVE, NUM_BUCKETS
};
static int success_fail_positive(struct range_list *rl)
{
if (!rl)
- return ZERO;
+ return EMPTY;
if (sval_is_negative(rl_min(rl)))
return NEGATIVE;
@@ -157,31 +234,49 @@ static void check_counter(const char *name, struct symbol *sym)
{
struct range_list *inc_lines = NULL;
struct range_list *dec_lines = NULL;
- int inc_buckets[3] = {};
- struct stree *stree;
+ int inc_buckets[NUM_BUCKETS] = {};
+ int dec_buckets[NUM_BUCKETS] = {};
+ struct stree *stree, *orig_stree;
struct sm_state *return_sm;
struct sm_state *sm;
sval_t line = sval_type_val(&int_ctype, 0);
+ int bucket;
FOR_EACH_PTR(get_all_return_strees(), stree) {
- return_sm = get_sm_state_stree(stree, RETURN_ID, "return_ranges", NULL);
+ orig_stree = __swap_cur_stree(stree);
+
+ return_sm = get_sm_state(RETURN_ID, "return_ranges", NULL);
if (!return_sm)
- continue;
+ goto swap_stree;
line.value = return_sm->line;
- sm = get_sm_state_stree(stree, my_id, name, sym);
+ if (get_state_stree(start_states, my_id, name, sym) == &inc)
+ goto swap_stree;
+
+ if (parent_is_gone_var_sym(name, sym))
+ goto swap_stree;
+
+ sm = get_sm_state(my_id, name, sym);
if (!sm)
- continue;
+ goto swap_stree;
- if (sm->state != &inc && sm->state != &dec)
- continue;
+ if (sm->state != &inc &&
+ sm->state != &dec &&
+ sm->state != &orig)
+ goto swap_stree;
+
+ bucket = success_fail_positive(estate_rl(return_sm->state));
if (sm->state == &inc) {
add_range(&inc_lines, line, line);
- inc_buckets[success_fail_positive(estate_rl(return_sm->state))] = 1;
+ inc_buckets[bucket] = true;
}
- if (sm->state == &dec)
+ if (sm->state == &dec || sm->state == &orig) {
add_range(&dec_lines, line, line);
+ dec_buckets[bucket] = true;
+ }
+swap_stree:
+ __swap_cur_stree(orig_stree);
} END_FOR_EACH_PTR(stree);
if (inc_buckets[NEGATIVE] &&
@@ -217,6 +312,22 @@ int was_inced(const char *name, struct symbol *sym)
return get_state(my_id, name, sym) == &inc;
}
+static void match_save_states(struct expression *expr)
+{
+ push_stree(&saved_stack, start_states);
+ start_states = NULL;
+}
+
+static void match_restore_states(struct expression *expr)
+{
+ start_states = pop_stree(&saved_stack);
+}
+
+static void match_after_func(struct symbol *sym)
+{
+ free_stree(&start_states);
+}
+
void check_atomic_inc_dec(int id)
{
my_id = id;
@@ -224,8 +335,12 @@ void check_atomic_inc_dec(int id)
if (option_project != PROJ_KERNEL)
return;
+ add_unmatched_state_hook(my_id, &unmatched_state);
+
+ add_split_return_callback(match_return_info);
select_return_states_hook(ATOMIC_INC, &db_inc);
select_return_states_hook(ATOMIC_DEC, &db_dec);
+
add_function_hook("atomic_inc_return", &match_atomic_inc, NULL);
add_function_hook("atomic_add_return", &match_atomic_add, NULL);
add_function_hook("atomic_sub_return", &match_atomic_sub, NULL);
@@ -237,12 +352,18 @@ void check_atomic_inc_dec(int id)
add_function_hook("atomic_long_dec", &match_atomic_dec, NULL);
add_function_hook("atomic_inc", &match_atomic_inc, NULL);
add_function_hook("atomic_sub", &match_atomic_sub, NULL);
- add_split_return_callback(match_return_info);
+ add_function_hook("refcount_inc", &refcount_inc, INT_PTR(0));
+ add_function_hook("refcount_dec", &refcount_dec, INT_PTR(0));
+ add_function_hook("refcount_add", &refcount_inc, INT_PTR(1));
add_function_hook("refcount_add_not_zero", &refcount_inc, INT_PTR(1));
add_function_hook("refcount_inc_not_zero", &refcount_inc, INT_PTR(0));
add_function_hook("refcount_sub_and_test", &refcount_dec, INT_PTR(1));
- add_function_hook("refcount_dec_and_test", &refcount_dec, INT_PTR(1));
+ add_function_hook("refcount_dec_and_test", &refcount_dec, INT_PTR(0));
add_hook(&match_check_missed, END_FUNC_HOOK);
+
+ add_hook(&match_after_func, AFTER_FUNC_HOOK);
+ add_hook(&match_save_states, INLINE_FN_START);
+ add_hook(&match_restore_states, INLINE_FN_END);
}
diff --git a/usr/src/tools/smatch/src/check_debug.c b/usr/src/tools/smatch/src/check_debug.c
index abe98b72db..8f283dbac9 100644
--- a/usr/src/tools/smatch/src/check_debug.c
+++ b/usr/src/tools/smatch/src/check_debug.c
@@ -78,8 +78,6 @@ static void match_state(const char *fn, struct expression *expr, void *info)
static void match_states(const char *fn, struct expression *expr, void *info)
{
struct expression *check_arg;
- struct sm_state *sm;
- int found = 0;
check_arg = get_argument_from_call_expr(expr->args, 0);
if (check_arg->type != EXPR_STRING) {
@@ -87,14 +85,7 @@ static void match_states(const char *fn, struct expression *expr, void *info)
return;
}
- FOR_EACH_SM(__get_cur_stree(), sm) {
- if (!strstr(check_name(sm->owner), check_arg->string->data))
- continue;
- sm_msg("%s", show_sm(sm));
- found = 1;
- } END_FOR_EACH_SM(sm);
-
- if (found)
+ if (__print_states(check_arg->string->data))
return;
if (!id_from_name(check_arg->string->data))
@@ -210,6 +201,9 @@ static void match_user_rl(const char *fn, struct expression *expr, void *info)
bool capped = false;
char *name;
+ if (option_project != PROJ_KERNEL)
+ sm_msg("no user data for project = '%s'", option_project_str);
+
arg = get_argument_from_call_expr(expr->args, 0);
name = expr_to_str(arg);
@@ -526,6 +520,17 @@ static void match_debug_db_off(const char *fn, struct expression *expr, void *in
debug_db = 0;
}
+static void mtag_info(struct expression *expr)
+{
+ mtag_t tag = 0;
+ int offset = 0;
+ struct range_list *rl = NULL;
+
+ expr_to_mtag_offset(expr, &tag, &offset);
+ get_mtag_rl(expr, &rl);
+ sm_msg("mtag = %llu offset = %d rl = '%s'", tag, offset, show_rl(rl));
+}
+
static void match_about(const char *fn, struct expression *expr, void *info)
{
struct expression *arg;
@@ -537,6 +542,7 @@ static void match_about(const char *fn, struct expression *expr, void *info)
match_buf_size(fn, expr, NULL);
match_strlen(fn, expr, NULL);
match_real_absolute(fn, expr, NULL);
+ mtag_info(expr);
arg = get_argument_from_call_expr(expr->args, 0);
name = expr_to_str(arg);
@@ -651,6 +657,21 @@ static void match_print_stree_id(const char *fn, struct expression *expr, void *
sm_msg("stree_id %d", __stree_id);
}
+static void match_bits(const char *fn, struct expression *expr, void *_unused)
+{
+ struct expression *arg;
+ struct bit_info *info;
+ char *name;
+
+ arg = get_argument_from_call_expr(expr->args, 0);
+ name = expr_to_str(arg);
+
+ info = get_bit_info(arg);
+
+ sm_msg("bit info '%s': definitely set 0x%llx. possibly set 0x%llx.",
+ name, info->set, info->possible);
+}
+
static void match_mtag(const char *fn, struct expression *expr, void *info)
{
struct expression *arg;
@@ -695,6 +716,28 @@ static void match_container(const char *fn, struct expression *expr, void *info)
free_string(name);
}
+static void match_expr(const char *fn, struct expression *expr, void *info)
+{
+ struct expression *arg, *str, *new;
+ char *name, *new_name;
+
+ str = get_argument_from_call_expr(expr->args, 0);
+ arg = get_argument_from_call_expr(expr->args, 1);
+ if (!arg || !str)
+ return;
+
+ if (str->type != EXPR_STRING)
+ return;
+
+ new = gen_expression_from_key(arg, str->string->data);
+ name = expr_to_str(arg);
+ new_name = expr_to_str(new);
+
+ sm_msg("str = '%s', arg = '%s' expr = '%s'", str->string->data, name, new_name);
+
+ free_string(new_name);
+ free_string(name);
+}
static void match_state_count(const char *fn, struct expression *expr, void *info)
{
sm_msg("state_count = %d\n", sm_state_counter);
@@ -792,8 +835,10 @@ void check_debug(int id)
add_implied_return_hook("__smatch_type_rl_helper", &match_type_rl_return, NULL);
add_function_hook("__smatch_merge_tree", &match_print_merge_tree, NULL);
add_function_hook("__smatch_stree_id", &match_print_stree_id, NULL);
+ add_function_hook("__smatch_bits", &match_bits, NULL);
add_function_hook("__smatch_mtag", &match_mtag, NULL);
add_function_hook("__smatch_mtag_data", &match_mtag_data_offset, NULL);
+ add_function_hook("__smatch_expr", &match_expr, NULL);
add_function_hook("__smatch_state_count", &match_state_count, NULL);
add_function_hook("__smatch_mem", &match_mem, NULL);
add_function_hook("__smatch_exit", &match_exit, NULL);
diff --git a/usr/src/tools/smatch/src/check_debug.h b/usr/src/tools/smatch/src/check_debug.h
index 823fca2003..f89b52dfef 100644
--- a/usr/src/tools/smatch/src/check_debug.h
+++ b/usr/src/tools/smatch/src/check_debug.h
@@ -63,7 +63,7 @@ static inline long long __smatch_type_rl_helper(long long type, const char *str,
#define __smatch_type_rl(type, fmt...) __smatch_type_rl_helper((type)0, fmt)
#define __smatch_rl(fmt...) __smatch_type_rl(long long, fmt)
-static inline void __smatch_bit_info(long long expr){}
+static inline void __smatch_bits(long long expr){}
static inline void __smatch_oops(unsigned long null_val){}
@@ -75,8 +75,11 @@ static inline void __smatch_mtag(void *p){}
static inline void __smatch_mtag_data(long long arg){}
static inline void __smatch_exit(void){}
+static inline void __smatch_expr(const char *str, void *p){}
+
static inline void __smatch_state_count(void){}
static inline void __smatch_mem(void){}
static inline void __smatch_container(long long container, long long x){}
+
#endif
diff --git a/usr/src/tools/smatch/src/check_err_ptr.c b/usr/src/tools/smatch/src/check_err_ptr.c
index c3d0f7e9ae..60b8ff2c58 100644
--- a/usr/src/tools/smatch/src/check_err_ptr.c
+++ b/usr/src/tools/smatch/src/check_err_ptr.c
@@ -37,7 +37,6 @@ static void match_err_ptr(struct expression *expr)
err_ptr = 1;
}
-extern int check_assigned_expr_id;
static void match_return(struct expression *ret_value)
{
struct state_list *slist;
diff --git a/usr/src/tools/smatch/src/check_kernel.c b/usr/src/tools/smatch/src/check_kernel.c
index a67511ef43..50c884b1a6 100644
--- a/usr/src/tools/smatch/src/check_kernel.c
+++ b/usr/src/tools/smatch/src/check_kernel.c
@@ -32,10 +32,10 @@ static int implied_err_cast_return(struct expression *call, void *unused, struct
struct expression *arg;
arg = get_argument_from_call_expr(call->args, 0);
- if (!get_implied_rl(arg, rl)) {
+ if (!get_implied_rl(arg, rl))
*rl = alloc_rl(err_ptr_min, err_ptr_max);
- *rl = cast_rl(get_type(arg), *rl);
- }
+
+ *rl = cast_rl(get_type(call), *rl);
return 1;
}
@@ -130,12 +130,9 @@ static void match_not_err(const char *fn, struct expression *call_expr,
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
- 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);
- }
+ if (pre_state)
+ return;
+ 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));
}
@@ -154,6 +151,14 @@ static void match_err(const char *fn, struct expression *call_expr,
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);
+ if (pre_state && rl) {
+ /*
+ * Ideally this would all be handled by smatch_implied.c
+ * but it doesn't work very well for impossible paths.
+ *
+ */
+ return;
+ }
set_extra_expr_nomod(arg, alloc_estate_rl(rl));
}
@@ -257,8 +262,6 @@ static int match_fls(struct expression *call, void *unused, struct range_list **
return 1;
}
-
-
static void find_module_init_exit(struct symbol_list *sym_list)
{
struct symbol *sym;
@@ -406,6 +409,22 @@ static void match__read_once_size(const char *fn, struct expression *call,
__in_fake_assign--;
}
+static void match_closure_call(const char *name, struct expression *call,
+ void *unused)
+{
+ struct expression *cl, *fn, *fake_call;
+ struct expression_list *args = NULL;
+
+ cl = get_argument_from_call_expr(call->args, 0);
+ fn = get_argument_from_call_expr(call->args, 1);
+ if (!fn || !cl)
+ return;
+
+ add_ptr_list(&args, cl);
+ fake_call = call_expression(fn, args);
+ __split_expr(fake_call);
+}
+
bool is_ignored_kernel_data(const char *name)
{
if (option_project != PROJ_KERNEL)
@@ -463,6 +482,8 @@ void check_kernel(int id)
add_function_hook("__read_once_size", &match__read_once_size, NULL);
add_function_hook("__read_once_size_nocheck", &match__read_once_size, NULL);
+ add_function_hook("closure_call", &match_closure_call, NULL);
+
if (option_info)
add_hook(match_end_file, END_FILE_HOOK);
}
diff --git a/usr/src/tools/smatch/src/check_shift_to_zero.c b/usr/src/tools/smatch/src/check_shift_to_zero.c
index 019b06fb75..a6f227d974 100644
--- a/usr/src/tools/smatch/src/check_shift_to_zero.c
+++ b/usr/src/tools/smatch/src/check_shift_to_zero.c
@@ -56,9 +56,9 @@ static void match_binop2(struct expression *expr)
if (left->type != EXPR_BINOP || left->op != '&')
return;
- if (!get_implied_value(expr->right, &shift))
+ if (!get_value(expr->right, &shift))
return;
- if (!get_implied_value(left->right, &mask))
+ if (!get_value(left->right, &mask))
return;
if (mask.uvalue >> shift.uvalue)
diff --git a/usr/src/tools/smatch/src/expression.h b/usr/src/tools/smatch/src/expression.h
index f90f8d65ef..59c781bb30 100644
--- a/usr/src/tools/smatch/src/expression.h
+++ b/usr/src/tools/smatch/src/expression.h
@@ -134,8 +134,9 @@ enum constexpr_flag {
enum {
Handled = 1 << 0,
- Fake = 1 << 1,
-}; /* for expr->flags */
+ Tmp = 1 << 1,
+ Fake = 1 << 2,
+}; /* for expr->smatch_flags */
enum {
Taint_comma = 1,
diff --git a/usr/src/tools/smatch/src/smatch.c b/usr/src/tools/smatch/src/smatch.c
index b6963a0016..c18c2f6e54 100644
--- a/usr/src/tools/smatch/src/smatch.c
+++ b/usr/src/tools/smatch/src/smatch.c
@@ -340,6 +340,7 @@ int main(int argc, char **argv)
allocate_hook_memory();
allocate_dynamic_states_array(num_checks);
+ allocate_tracker_array(num_checks);
create_function_hook_hash();
open_smatch_db(option_db_file);
sparse_initialize(argc, argv, &filelist);
diff --git a/usr/src/tools/smatch/src/smatch.h b/usr/src/tools/smatch/src/smatch.h
index 6e0698085e..6df9c529e4 100644
--- a/usr/src/tools/smatch/src/smatch.h
+++ b/usr/src/tools/smatch/src/smatch.h
@@ -196,6 +196,7 @@ void select_return_states_before(void (*fn)(void));
void select_return_states_after(void (*fn)(void));
int get_implied_return(struct expression *expr, struct range_list **rl);
void allocate_hook_memory(void);
+void allocate_tracker_array(int num_checks);
struct modification_data {
struct smatch_state *prev;
@@ -388,6 +389,7 @@ struct smatch_state *merge_str_state(struct smatch_state *s1, struct smatch_stat
struct smatch_state *alloc_state_expr(struct expression *expr);
struct expression *get_argument_from_call_expr(struct expression_list *args,
int num);
+struct expression *get_array_expr(struct expression *expr);
char *expr_to_var(struct expression *expr);
struct symbol *expr_to_sym(struct expression *expr);
@@ -446,9 +448,16 @@ int positions_eq(struct position pos1, struct position pos2);
struct statement *get_current_statement(void);
struct statement *get_prev_statement(void);
struct expression *get_last_expr_from_expression_stmt(struct expression *expr);
+
+#define RETURN_VAR -1
+#define LOCAL_SCOPE -2
+#define FILE_SCOPE -3
+#define GLOBAL_SCOPE -4
+#define UNKNOWN_SCOPE -5
int get_param_num_from_sym(struct symbol *sym);
int get_param_num(struct expression *expr);
struct symbol *get_param_sym_from_num(int num);
+
int ms_since(struct timeval *start);
int parent_is_gone_var_sym(const char *name, struct symbol *sym);
int parent_is_gone(struct expression *expr);
@@ -478,9 +487,11 @@ int nr_bits(struct expression *expr);
int is_void_pointer(struct expression *expr);
int is_char_pointer(struct expression *expr);
int is_string(struct expression *expr);
+bool is_struct_ptr(struct symbol *type);
int is_static(struct expression *expr);
bool is_local_variable(struct expression *expr);
int types_equiv(struct symbol *one, struct symbol *two);
+bool type_fits(struct symbol *type, struct symbol *test);
int fn_static(void);
const char *global_static();
struct symbol *cur_func_return_type(void);
@@ -581,7 +592,7 @@ int __handle_expr_statement_assigns(struct expression *expr);
/* smatch_implied.c */
struct range_list_stack;
-void param_limit_implications(struct expression *expr, int param, char *key, char *value);
+void param_limit_implications(struct expression *expr, int param, char *key, char *value, struct stree **implied);
struct stree *__implied_case_stree(struct expression *switch_expr,
struct range_list *case_rl,
struct range_list_stack **remaining_cases,
@@ -780,6 +791,9 @@ void __save_gotos(const char *name, struct symbol *sym);
void __merge_gotos(const char *name, struct symbol *sym);
void __print_cur_stree(void);
+bool __print_states(const char *owner);
+typedef void (check_tracker_hook)(int owner, const char *name, struct symbol *sym, struct smatch_state *state);
+void add_check_tracker(const char *check_name, check_tracker_hook *fn);
/* smatch_hooks.c */
void __pass_to_client(void *data, enum hook_type type);
@@ -847,6 +861,7 @@ enum info_type {
STMT_CNT = 1037,
TERMINATED = 1038,
FRESH_ALLOC = 1044,
+ ALLOCATOR = 1045,
/* put random temporary stuff in the 7000-7999 range for testing */
USER_DATA = 8017,
@@ -862,6 +877,7 @@ enum info_type {
SET_FS = 8022,
ATOMIC_INC = 8023,
ATOMIC_DEC = 8024,
+ REFCOUNT = 9025,
NO_SIDE_EFFECT = 8025,
FN_ARG_LINK = 8028,
DATA_VALUE = 8029,
@@ -885,6 +901,7 @@ extern struct sqlite3 *cache_db;
void db_ignore_states(int id);
void select_caller_info_hook(void (*callback)(const char *name, struct symbol *sym, char *key, char *value), int type);
void add_member_info_callback(int owner, void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm));
+void add_caller_info_callback(int owner, void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm));
void add_split_return_callback(void (*fn)(int return_id, char *return_ranges, struct expression *returned_expr));
void add_returned_member_callback(int owner, void (*callback)(int return_id, char *return_ranges, struct expression *expr, char *printed_name, struct smatch_state *state));
void select_call_implies_hook(int type, void (*callback)(struct expression *call, struct expression *arg, char *key, char *value));
@@ -996,11 +1013,12 @@ void sql_copy_constraint_required(const char *new_limit, const char *old_limit);
void sql_insert_fn_ptr_data_link(const char *ptr, const char *data);
void sql_insert_fn_data_link(struct expression *fn, int type, int param, const char *key, const char *value);
void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name);
-void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container);
+void sql_insert_mtag_info(mtag_t tag, int type, const char *value);
+void sql_insert_mtag_map(mtag_t container, int container_offset, mtag_t tag, int tag_offset);
void sql_insert_mtag_alias(mtag_t orig, mtag_t alias);
-int mtag_map_select_container(mtag_t tag, int offset, mtag_t *container);
+int mtag_map_select_container(mtag_t tag, int container_offset, mtag_t *container);
int mtag_map_select_tag(mtag_t container, int offset, mtag_t *tag);
-struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_state *state);
+struct smatch_state *get_mtag_return(struct expression *expr, struct smatch_state *state);
struct range_list *swap_mtag_seed(struct expression *expr, struct range_list *rl);
void sql_select_return_states(const char *cols, struct expression *call,
@@ -1069,6 +1087,7 @@ struct range_list *var_user_rl(struct expression *expr);
void print_held_locks();
/* check_assigned_expr.c */
+extern int check_assigned_expr_id;
struct expression *get_assigned_expr(struct expression *expr);
struct expression *get_assigned_expr_name_sym(const char *name, struct symbol *sym);
/* smatch_return_to_param.c */
@@ -1119,9 +1138,6 @@ int negate_comparison(int op);
int remove_unsigned_from_comparison(int op);
int param_compare_limit_is_impossible(struct expression *expr, int left_param, char *left_key, char *value);
void filter_by_comparison(struct range_list **rl, int comparison, struct range_list *right);
-struct sm_state *comparison_implication_hook(struct expression *expr,
- struct state_list **true_stack,
- struct state_list **false_stack);
void __compare_param_limit_hook(struct expression *left_expr, struct expression *right_expr,
const char *state_name,
struct smatch_state *true_state, struct smatch_state *false_state);
@@ -1193,6 +1209,10 @@ struct sm_state *stored_condition_implication_hook(struct expression *expr,
struct sm_state *parsed_condition_implication_hook(struct expression *expr,
struct state_list **true_stack,
struct state_list **false_stack);
+/* smatch_comparison.c */
+struct sm_state *comparison_implication_hook(struct expression *expr,
+ struct state_list **true_stack,
+ struct state_list **false_stack);
/* check_string_len.c */
int get_formatted_string_size(struct expression *call, int arg);
@@ -1240,10 +1260,14 @@ void __get_state_hook(int owner, const char *name, struct symbol *sym);
/* smatch_buf_comparison.c */
int db_var_is_array_limit(struct expression *array, const char *name, struct var_sym_list *vsl);
+struct range_list *get_fs(void);
+
struct stree *get_all_return_states(void);
struct stree_stack *get_all_return_strees(void);
int on_atomic_dec_path(void);
int was_inced(const char *name, struct symbol *sym);
+void set_refcount_inc(char *name, struct symbol *sym);
+void set_refcount_dec(char *name, struct symbol *sym);
/* smatch_constraints.c */
char *get_constraint_str(struct expression *expr);
diff --git a/usr/src/tools/smatch/src/smatch_bits.c b/usr/src/tools/smatch/src/smatch_bits.c
index 2fcd5e8f60..5e310a13f7 100644
--- a/usr/src/tools/smatch/src/smatch_bits.c
+++ b/usr/src/tools/smatch/src/smatch_bits.c
@@ -111,10 +111,46 @@ static struct smatch_state *unmatched_state(struct sm_state *sm)
return alloc_bstate(0, possible);
}
+static bool is_loop_iterator(struct expression *expr)
+{
+ struct statement *pre_stmt, *loop_stmt;
+
+ pre_stmt = expr_get_parent_stmt(expr);
+ if (!pre_stmt || pre_stmt->type != STMT_EXPRESSION)
+ return false;
+
+ loop_stmt = stmt_get_parent_stmt(pre_stmt);
+ if (!loop_stmt || loop_stmt->type != STMT_ITERATOR)
+ return false;
+ if (loop_stmt->iterator_pre_statement != pre_stmt)
+ return false;
+
+ return true;
+}
+
+static bool handled_by_assign_hook(struct expression *expr)
+{
+ if (!expr || expr->type != EXPR_ASSIGNMENT)
+ return false;
+ if (__in_fake_assign)
+ return false;
+ if (is_loop_iterator(expr))
+ return false;
+
+ if (expr->op == '=' ||
+ expr->op == SPECIAL_OR_ASSIGN ||
+ expr->op == SPECIAL_AND_ASSIGN)
+ return true;
+
+ return false;
+}
+
static void match_modify(struct sm_state *sm, struct expression *mod_expr)
{
// FIXME: we really need to store the type
+ if (handled_by_assign_hook(mod_expr))
+ return;
set_state(my_id, sm->name, sm->sym, alloc_bstate(0, -1ULL));
}
@@ -283,40 +319,31 @@ static void match_compare(struct expression *expr)
(expr->op == SPECIAL_EQUAL) ? NULL : alloc_bstate(val.uvalue, val.uvalue));
}
-static bool is_loop_iterator(struct expression *expr)
-{
- struct statement *pre_stmt, *loop_stmt;
-
- pre_stmt = expr_get_parent_stmt(expr);
- if (!pre_stmt || pre_stmt->type != STMT_EXPRESSION)
- return false;
-
- loop_stmt = stmt_get_parent_stmt(pre_stmt);
- if (!loop_stmt || loop_stmt->type != STMT_ITERATOR)
- return false;
- if (loop_stmt->iterator_pre_statement != pre_stmt)
- return false;
-
- return true;
-}
-
static void match_assign(struct expression *expr)
{
- struct bit_info *binfo;
+ struct bit_info *start, *binfo;
+ struct smatch_state *new;
- if (expr->op != '=')
- return;
- if (__in_fake_assign)
- return;
- if (is_loop_iterator(expr))
+ if (!handled_by_assign_hook(expr))
return;
binfo = get_bit_info(expr->right);
if (!binfo)
return;
- if (is_unknown_binfo(get_type(expr->left), binfo))
- return;
- set_state_expr(my_id, expr->left, alloc_bstate(binfo->set, binfo->possible));
+ if (expr->op == '=') {
+ if (is_unknown_binfo(get_type(expr->left), binfo))
+ return;
+
+ set_state_expr(my_id, expr->left, alloc_bstate(binfo->set, binfo->possible));
+ } else if (expr->op == SPECIAL_OR_ASSIGN) {
+ start = get_bit_info(expr->left);
+ new = alloc_bstate(start->set | binfo->set, start->possible | binfo->possible);
+ set_state_expr(my_id, expr->left, new);
+ } else if (expr->op == SPECIAL_AND_ASSIGN) {
+ start = get_bit_info(expr->left);
+ new = alloc_bstate(start->set & binfo->set, start->possible & binfo->possible);
+ set_state_expr(my_id, expr->left, new);
+ }
}
static void match_condition(struct expression *expr)
diff --git a/usr/src/tools/smatch/src/smatch_buf_size.c b/usr/src/tools/smatch/src/smatch_buf_size.c
index 1a2dd87d01..b98d97f193 100644
--- a/usr/src/tools/smatch/src/smatch_buf_size.c
+++ b/usr/src/tools/smatch/src/smatch_buf_size.c
@@ -269,6 +269,7 @@ static void db_returns_buf_size(struct expression *expr, int param, char *unused
{
struct expression *call;
struct range_list *rl;
+ sval_t sval;
if (expr->type != EXPR_ASSIGNMENT)
return;
@@ -276,6 +277,8 @@ static void db_returns_buf_size(struct expression *expr, int param, char *unused
call_results_to_rl(call, &int_ctype, math, &rl);
rl = cast_rl(&int_ctype, rl);
+ if (rl_to_sval(rl, &sval) && sval.value == 0)
+ return;
set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
}
@@ -451,7 +454,7 @@ static int get_stored_size_end_struct_bytes(struct expression *expr)
return 0;
state = get_state(my_size_id, sym->ident->name, sym);
- if (!estate_to_size(state))
+ if (!estate_to_size(state) || estate_to_size(state) == -1)
return 0;
return estate_to_size(state) - type_bytes(base_sym) + type_bytes(get_type(expr));
@@ -504,6 +507,11 @@ struct range_list *get_array_size_bytes_rl(struct expression *expr)
return alloc_int_rl(size - offset.value);
}
+ /* buf = malloc(1024); */
+ ret = get_stored_size_bytes(expr);
+ if (ret)
+ return ret;
+
size = get_stored_size_end_struct_bytes(expr);
if (size)
return alloc_int_rl(size);
@@ -513,11 +521,6 @@ struct range_list *get_array_size_bytes_rl(struct expression *expr)
if (size)
return alloc_int_rl(elements_to_bytes(expr, size));
- /* buf = malloc(1024); */
- ret = get_stored_size_bytes(expr);
- if (ret)
- return ret;
-
/* char *foo = "BAR" */
size = get_size_from_initializer(expr);
if (size)
@@ -636,7 +639,11 @@ static void store_alloc(struct expression *expr, struct range_list *rl)
rl = clone_rl(rl); // FIXME!!!
if (!rl)
rl = size_to_rl(UNKNOWN_SIZE);
- set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
+
+ if (rl_min(rl).value != UNKNOWN_SIZE ||
+ rl_max(rl).value != UNKNOWN_SIZE ||
+ get_state_expr(my_size_id, expr))
+ set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
type = get_type(expr);
if (!type)
@@ -654,6 +661,16 @@ static void store_alloc(struct expression *expr, struct range_list *rl)
info_record_alloction(expr, rl);
}
+static bool is_array_base(struct expression *expr)
+{
+ struct symbol *type;
+
+ type = get_type(expr);
+ if (type && type->type == SYM_ARRAY)
+ return true;
+ return false;
+}
+
static void match_array_assignment(struct expression *expr)
{
struct expression *left;
@@ -664,12 +681,16 @@ static void match_array_assignment(struct expression *expr)
if (expr->op != '=')
return;
+
left = strip_expr(expr->left);
right = strip_expr(expr->right);
right = strip_ampersands(right);
if (!is_pointer(left))
return;
+ /* char buf[24] = "str"; */
+ if (is_array_base(left))
+ return;
if (is_allocation_function(right))
return;
@@ -710,15 +731,16 @@ static void match_alloc(const char *fn, struct expression *expr, void *_size_arg
store_alloc(expr->left, rl);
}
-static void match_calloc(const char *fn, struct expression *expr, void *unused)
+static void match_calloc(const char *fn, struct expression *expr, void *_param)
{
struct expression *right;
struct expression *size, *nr, *mult;
struct range_list *rl;
+ int param = PTR_INT(_param);
right = strip_expr(expr->right);
- nr = get_argument_from_call_expr(right->args, 0);
- size = get_argument_from_call_expr(right->args, 1);
+ nr = get_argument_from_call_expr(right->args, param);
+ size = get_argument_from_call_expr(right->args, param + 1);
mult = binop_expression(nr, '*', size);
if (get_implied_rl(mult, &rl))
store_alloc(expr->left, rl);
@@ -812,6 +834,9 @@ static void match_call(struct expression *expr)
rl = get_array_size_bytes_rl(arg);
if (!rl)
continue;
+ if (rl_min(rl).value == UNKNOWN_SIZE &&
+ rl_max(rl).value == UNKNOWN_SIZE)
+ continue;
if (is_whole_rl(rl))
continue;
if (is_type_bytes(rl, arg))
@@ -909,12 +934,12 @@ void register_buf_size(int id)
add_allocation_function("kzalloc", &match_alloc, 0);
add_allocation_function("kzalloc_node", &match_alloc, 0);
add_allocation_function("vmalloc", &match_alloc, 0);
+ add_allocation_function("vzalloc", &match_alloc, 0);
add_allocation_function("__vmalloc", &match_alloc, 0);
add_allocation_function("kvmalloc", &match_alloc, 0);
add_allocation_function("kcalloc", &match_calloc, 0);
add_allocation_function("kmalloc_array", &match_calloc, 0);
- add_allocation_function("drm_malloc_ab", &match_calloc, 0);
- add_allocation_function("drm_calloc_large", &match_calloc, 0);
+ add_allocation_function("devm_kmalloc_array", &match_calloc, 1);
add_allocation_function("sock_kmalloc", &match_alloc, 1);
add_allocation_function("kmemdup", &match_alloc, 1);
add_allocation_function("kmemdup_user", &match_alloc, 1);
diff --git a/usr/src/tools/smatch/src/smatch_capped.c b/usr/src/tools/smatch/src/smatch_capped.c
index 1b25c4795e..ce290b9630 100644
--- a/usr/src/tools/smatch/src/smatch_capped.c
+++ b/usr/src/tools/smatch/src/smatch_capped.c
@@ -94,12 +94,14 @@ int is_capped(struct expression *expr)
if (expr->type == EXPR_BINOP) {
struct range_list *left_rl, *right_rl;
+ sval_t sval;
- if (expr->op == '&')
+ if (expr->op == '&' && !get_value(expr->right, &sval))
return 1;
if (expr->op == SPECIAL_RIGHTSHIFT)
- return 1;
- if (expr->op == '%' && is_capped(expr->right))
+ return 0;
+ if (expr->op == '%' &&
+ !get_value(expr->right, &sval) && is_capped(expr->right))
return 1;
if (!is_capped(expr->left))
return 0;
diff --git a/usr/src/tools/smatch/src/smatch_comparison.c b/usr/src/tools/smatch/src/smatch_comparison.c
index 78724c2339..8267555e14 100644
--- a/usr/src/tools/smatch/src/smatch_comparison.c
+++ b/usr/src/tools/smatch/src/smatch_comparison.c
@@ -2748,8 +2748,8 @@ split:
}
struct sm_state *comparison_implication_hook(struct expression *expr,
- struct state_list **true_stack,
- struct state_list **false_stack)
+ struct state_list **true_stack,
+ struct state_list **false_stack)
{
struct sm_state *sm;
char *left, *right;
diff --git a/usr/src/tools/smatch/src/smatch_container_of.c b/usr/src/tools/smatch/src/smatch_container_of.c
index 65d4a8d8ac..098885be7d 100644
--- a/usr/src/tools/smatch/src/smatch_container_of.c
+++ b/usr/src/tools/smatch/src/smatch_container_of.c
@@ -528,7 +528,7 @@ static struct stree *load_tag_info_sym(mtag_t tag, struct symbol *arg, int arg_o
tag, arg_offset, DATA_VALUE);
} else { /* presumably the parameter is a struct pointer */
run_sql(save_vals, &db_info,
- "select offset, value from mtag_data where tag = %lld and type = %d;",
+ "select offset, value from mtag_data where tag = %lld and type = %d order by offset;",
tag, DATA_VALUE);
}
@@ -579,7 +579,7 @@ static void load_container_data(struct symbol *arg, const char *info)
if (local_debug)
sm_msg("%s: cur_tag = %llu container_offset = %d",
__func__, cur_tag, container_offset);
- if (!mtag_map_select_container(cur_tag, container_offset, &container_tag))
+ if (!mtag_map_select_container(cur_tag, -container_offset, &container_tag))
return;
cur_tag = container_tag;
if (local_debug)
@@ -603,7 +603,7 @@ static void load_container_data(struct symbol *arg, const char *info)
if (!arg_offset || star) {
arg_tag = container_tag;
} else {
- if (!mtag_map_select_tag(container_tag, -arg_offset, &arg_tag))
+ if (!mtag_map_select_tag(container_tag, arg_offset, &arg_tag))
return;
}
diff --git a/usr/src/tools/smatch/src/smatch_data/db/create_db.sh b/usr/src/tools/smatch/src/smatch_data/db/create_db.sh
index 313ba59133..4d80242727 100755
--- a/usr/src/tools/smatch/src/smatch_data/db/create_db.sh
+++ b/usr/src/tools/smatch/src/smatch_data/db/create_db.sh
@@ -52,6 +52,8 @@ ${bin_dir}/mark_function_ptrs_searchable.pl $db_file
echo "delete from function_ptr where rowid not in (select min(rowid) from function_ptr group by file, function, ptr, searchable);" | sqlite3 $db_file
${bin_dir}/apply_return_fixes.sh -p=${PROJ} $db_file
-${bin_dir}/insert_manual_states.pl ${PROJ} $db_file
+if [ "$PROJ" != "" ] ; then
+ ${bin_dir}/insert_manual_states.pl ${PROJ} $db_file
+fi
mv $db_file smatch_db.sqlite
diff --git a/usr/src/tools/smatch/src/smatch_data/db/kernel.return_fixes b/usr/src/tools/smatch/src/smatch_data/db/kernel.return_fixes
index d6b8f8e5d1..d75b3f3a06 100644
--- a/usr/src/tools/smatch/src/smatch_data/db/kernel.return_fixes
+++ b/usr/src/tools/smatch/src/smatch_data/db/kernel.return_fixes
@@ -20,6 +20,7 @@ nilfs_mdt_insert_new_block s32min-(-23),(-21)-(-1),1-s32max (-4095)-(-23),(-21)-
simple_write_to_buffer s64min-s64max 0-s32max[<=$1]
atomic_read s32min-s32max s32min-s32max[==$0->counter]
notifier_to_errno (-2147483646)-(-1) (-4095)-(-1)
+notifier_to_errno (-2147450878)-(-1) (-4095)-(-1)
mc_status_to_error s32min-s32max (-4095)-0
fls s32min-s32max 0-32
fls64 s64min-s64max 0-64
@@ -57,3 +58,13 @@ __rounddown_pow_of_two 0-u64max 0-u64max[<=$0]
__roundup_pow_of_two 0-u64max 0-u64max[>=$0]
kthread_probe_data 0 0-u64max
bus_for_each_dev (-4095)-1 (-4095)-1[r\ $3]
+ahd_probe_stack_size 0 0-s32max
+mutex_lock_interruptible_nested (-35),(-4) (-4)
+dlfb_get_urb 0-u64max 4096-ptr_max
+bitmap_find_free_region 0 0-s32max
+mutex_lock_interruptible (-35),(-4) (-4)
+mutex_lock_interruptible_nested (-35),(-4) (-4)
+mutex_lock_killable (-35),(-4) (-4)
+mutex_lock_killable_nested (-35),(-4) (-4)
+ww_mutex_lock_interruptible (-35),(-4) (-4)
+ww_mutex_lock (-35),(-4) (-35)
diff --git a/usr/src/tools/smatch/src/smatch_data/db/mark_function_ptrs_searchable.pl b/usr/src/tools/smatch/src/smatch_data/db/mark_function_ptrs_searchable.pl
index a35148febc..017d21149f 100755
--- a/usr/src/tools/smatch/src/smatch_data/db/mark_function_ptrs_searchable.pl
+++ b/usr/src/tools/smatch/src/smatch_data/db/mark_function_ptrs_searchable.pl
@@ -22,17 +22,6 @@ $sth = $db->prepare('select distinct(ptr) from function_ptr;');
$sth->execute();
while ($fn_ptr = $sth->fetchrow_array()) {
-
- # following a pointer to pointer chain is too complicated for now
- $ptr_to_ptr = $db->selectrow_array("select function from function_ptr where ptr = '$fn_ptr' and function like '% %';");
- if ($ptr_to_ptr) {
- next;
- }
- $ptr_to_ptr = $db->selectrow_array("select function from function_ptr where ptr = '$fn_ptr' and function like '%[]';");
- if ($ptr_to_ptr) {
- next;
- }
-
$count = $db->selectrow_array("select count(*) from return_states join function_ptr where return_states.function == function_ptr.function and ptr = '$fn_ptr';");
# if there are too many states then bail
if ($count > 1000) {
diff --git a/usr/src/tools/smatch/src/smatch_data/db/mtag_about.schema b/usr/src/tools/smatch/src/smatch_data/db/mtag_about.schema
index 775764fedf..74939582ef 100644
--- a/usr/src/tools/smatch/src/smatch_data/db/mtag_about.schema
+++ b/usr/src/tools/smatch/src/smatch_data/db/mtag_about.schema
@@ -1 +1,10 @@
-CREATE TABLE mtag_about (tag big int, file varchar(80), function varchar(80), line integer, left_name varchar(80), right_name varchar(80));
+CREATE TABLE mtag_about (
+ tag big int,
+ file varchar(80),
+ function varchar(80),
+ line integer,
+ left_name varchar(80),
+ right_name varchar(80),
+
+ CONSTRAINT mtag_about_row UNIQUE (tag, file, function, line, left_name, right_name)
+);
diff --git a/usr/src/tools/smatch/src/smatch_data/db/mtag_info.schema b/usr/src/tools/smatch/src/smatch_data/db/mtag_info.schema
new file mode 100644
index 0000000000..85e437b027
--- /dev/null
+++ b/usr/src/tools/smatch/src/smatch_data/db/mtag_info.schema
@@ -0,0 +1 @@
+CREATE TABLE mtag_info (file varchar(80), tag big int, type integer, value varchar(80));
diff --git a/usr/src/tools/smatch/src/smatch_data/db/mtag_map.schema b/usr/src/tools/smatch/src/smatch_data/db/mtag_map.schema
index 3eb892d3ac..5e254e2eb6 100644
--- a/usr/src/tools/smatch/src/smatch_data/db/mtag_map.schema
+++ b/usr/src/tools/smatch/src/smatch_data/db/mtag_map.schema
@@ -1 +1 @@
-CREATE TABLE mtag_map (tag big int, offset integer, container big int);
+CREATE TABLE mtag_map (container big int, container_offset int, tag big int, tag_offset int);
diff --git a/usr/src/tools/smatch/src/smatch_data/db/return_states.schema b/usr/src/tools/smatch/src/smatch_data/db/return_states.schema
index a222eac9b7..d6f0bbe36c 100644
--- a/usr/src/tools/smatch/src/smatch_data/db/return_states.schema
+++ b/usr/src/tools/smatch/src/smatch_data/db/return_states.schema
@@ -1 +1 @@
-CREATE TABLE return_states (file varchar(128), function varchar(64), call_id integer, return_id integer, return varchar(256), static boolean, type integer, parameter integer, key varchar(256), value varchar(256));
+CREATE TABLE return_states (file varchar(128), function varchar(64), call_id big int, return_id integer, return varchar(256), static boolean, type integer, parameter integer, key varchar(256), value varchar(256));
diff --git a/usr/src/tools/smatch/src/smatch_data/db/smdb.py b/usr/src/tools/smatch/src/smatch_data/db/smdb.py
index 04bff00be4..2d8256373b 100755
--- a/usr/src/tools/smatch/src/smatch_data/db/smdb.py
+++ b/usr/src/tools/smatch/src/smatch_data/db/smdb.py
@@ -74,6 +74,7 @@ db_types = { 0: "INTERNAL",
1017: "ARRAY_LEN",
1018: "CAPABLE",
1019: "NS_CAPABLE",
+ 1020: "CONTAINER",
1022: "TYPE_LINK",
1023: "UNTRACKED_PARAM",
1024: "CULL_PATH",
@@ -92,7 +93,7 @@ db_types = { 0: "INTERNAL",
1037: "STMT_CNT",
1038: "TERMINATED",
1039: "SLEEP",
- 1040: "NO_SLEEP_CNT",
+ 1040: "PREEMPT_CNT",
1041: "SMALLISH",
1042: "FRESH_MTAG",
@@ -102,6 +103,10 @@ db_types = { 0: "INTERNAL",
8019: "NO_OVERFLOW_SIMPLE",
8020: "LOCKED",
8021: "UNLOCKED",
+ 9022: "HALF_LOCKED",
+ 9023: "LOCK_RESTORED",
+ 9024: "KNOWN_LOCKED",
+ 9025: "KNOWN_UNLOCKED",
8023: "ATOMIC_INC",
8024: "ATOMIC_DEC",
};
diff --git a/usr/src/tools/smatch/src/smatch_db.c b/usr/src/tools/smatch/src/smatch_db.c
index 70be64093d..d31c3a17cf 100644
--- a/usr/src/tools/smatch/src/smatch_db.c
+++ b/usr/src/tools/smatch/src/smatch_db.c
@@ -50,6 +50,7 @@ struct member_info_callback {
ALLOCATOR(member_info_callback, "caller_info callbacks");
DECLARE_PTR_LIST(member_info_cb_list, struct member_info_callback);
static struct member_info_cb_list *member_callbacks;
+static struct member_info_cb_list *member_callbacks_new;
struct returned_state_callback {
void (*callback)(int return_id, char *return_ranges, struct expression *return_expr);
@@ -178,15 +179,36 @@ void db_ignore_states(int id)
use_states[id] = 0;
}
+unsigned long long __fn_mtag;
+static void set_fn_mtag(struct symbol *sym)
+{
+ char buf[128];
+
+ if (cur_func_sym->ctype.modifiers & MOD_STATIC)
+ snprintf(buf, sizeof(buf), "%s %s", get_base_file(), get_function());
+ else
+ snprintf(buf, sizeof(buf), "extern %s", get_function());
+
+ __fn_mtag = str_to_mtag(buf);
+}
+
void sql_insert_return_states(int return_id, const char *return_ranges,
int type, int param, const char *key, const char *value)
{
+ unsigned long long id;
+
+
if (key && strlen(key) >= 80)
return;
+ if (__inline_fn)
+ id = (unsigned long)__inline_fn;
+ else
+ id = __fn_mtag;
+
return_ranges = replace_return_ranges(return_ranges);
- sql_insert(return_states, "'%s', '%s', %lu, %d, '%s', %d, %d, %d, '%s', '%s'",
- get_base_file(), get_function(), (unsigned long)__inline_fn,
- return_id, return_ranges, fn_static(), type, param, key, value);
+ sql_insert(return_states, "'%s', '%s', %llu, %d, '%s', %d, %d, %d, '%s', '%s'",
+ get_base_file(), get_function(), id, return_id,
+ return_ranges, fn_static(), type, param, key, value);
}
static struct string_list *common_funcs;
@@ -372,13 +394,19 @@ void sql_insert_fn_data_link(struct expression *fn, int type, int param, const c
void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name)
{
- sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
- tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
+ sql_insert_cache(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
+ tag, get_filename(), get_function(), get_lineno(),
+ left_name, right_name);
}
-void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
+void sql_insert_mtag_info(mtag_t tag, int type, const char *value)
{
- sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
+ sql_insert_cache(mtag_info, "'%s', %lld, %d, '%s'", get_filename(), tag, type, value);
+}
+
+void sql_insert_mtag_map(mtag_t container, int container_offset, mtag_t tag, int tag_offset)
+{
+ sql_insert(mtag_map, "%lld, %d, %lld, %d", container, container_offset, tag, tag_offset);
}
void sql_insert_mtag_alias(mtag_t orig, mtag_t alias)
@@ -401,13 +429,13 @@ static int save_mtag(void *_tag, int argc, char **argv, char **azColName)
return 0;
}
-int mtag_map_select_container(mtag_t tag, int offset, mtag_t *container)
+int mtag_map_select_container(mtag_t tag, int container_offset, mtag_t *container)
{
mtag_t tmp = 0;
run_sql(save_mtag, &tmp,
- "select container from mtag_map where tag = %lld and offset = %d;",
- tag, offset);
+ "select container from mtag_map where tag = %lld and container_offset = %d and tag_offset = 0;",
+ tag, container_offset);
if (tmp == 0 || tmp == -1ULL)
return 0;
@@ -420,7 +448,7 @@ int mtag_map_select_tag(mtag_t container, int offset, mtag_t *tag)
mtag_t tmp = 0;
run_sql(save_mtag, &tmp,
- "select tag from mtag_map where container = %lld and offset = %d;",
+ "select tag from mtag_map where container = %lld and container_offset = %d;",
container, offset);
if (tmp == 0 || tmp == -1ULL)
@@ -622,6 +650,15 @@ void add_member_info_callback(int owner, void (*callback)(struct expression *cal
add_ptr_list(&member_callbacks, member_callback);
}
+void add_caller_info_callback(int owner, void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
+{
+ struct member_info_callback *member_callback = __alloc_member_info_callback(0);
+
+ member_callback->owner = owner;
+ member_callback->callback = callback;
+ add_ptr_list(&member_callbacks_new, member_callback);
+}
+
void add_split_return_callback(void (*fn)(int return_id, char *return_ranges, struct expression *returned_expr))
{
struct returned_state_callback *callback = __alloc_returned_state_callback(0);
@@ -851,7 +888,8 @@ free:
}
static void print_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
- void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
+ void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm),
+ bool new)
{
struct sm_state *sm;
const char *sm_name;
@@ -891,24 +929,33 @@ static void print_struct_members(struct expression *call, struct expression *exp
}
// FIXME: simplify?
if (!add_star && strcmp(name, sm_name) == 0) {
- if (is_address)
+ if (is_address) {
snprintf(printed_name, sizeof(printed_name), "*$");
- else /* these are already handled. fixme: handle them here */
- continue;
+ } else {
+ if (new)
+ snprintf(printed_name, sizeof(printed_name), "$");
+ else
+ continue;
+ }
} else if (add_star && strcmp(name, sm_name) == 0) {
snprintf(printed_name, sizeof(printed_name), "%s*$",
is_address ? "*" : "");
} else if (strncmp(name, sm_name, len) == 0) {
if (sm_name[len] != '.' && sm_name[len] != '-')
continue;
- if (is_address)
+ if (is_address && sm_name[len] == '.') {
snprintf(printed_name, sizeof(printed_name),
"%s$->%s", add_star ? "*" : "",
sm_name + len + 1);
- else
+ } else if (is_address && sm_name[len] == '-') {
+ snprintf(printed_name, sizeof(printed_name),
+ "%s(*$)%s", add_star ? "*" : "",
+ sm_name + len);
+ } else {
snprintf(printed_name, sizeof(printed_name),
"%s$%s", add_star ? "*" : "",
sm_name + len);
+ }
} else {
continue;
}
@@ -936,7 +983,32 @@ static void match_call_info(struct expression *call)
stree = get_all_states_stree(cb->owner);
i = 0;
FOR_EACH_PTR(call->args, arg) {
- print_struct_members(call, arg, i, stree, cb->callback);
+ print_struct_members(call, arg, i, stree, cb->callback, 0);
+ i++;
+ } END_FOR_EACH_PTR(arg);
+ free_stree(&stree);
+ } END_FOR_EACH_PTR(cb);
+
+ free_string(name);
+}
+
+static void match_call_info_new(struct expression *call)
+{
+ struct member_info_callback *cb;
+ struct expression *arg;
+ struct stree *stree;
+ char *name;
+ int i;
+
+ name = get_fnptr_name(call->fn);
+ if (!name)
+ return;
+
+ FOR_EACH_PTR(member_callbacks_new, cb) {
+ stree = get_all_states_stree(cb->owner);
+ i = 0;
+ FOR_EACH_PTR(call->args, arg) {
+ print_struct_members(call, arg, i, stree, cb->callback, 1);
i++;
} END_FOR_EACH_PTR(arg);
free_stree(&stree);
@@ -1106,6 +1178,7 @@ static void match_data_from_db(struct symbol *sym)
if (!sym || !sym->ident)
return;
+ set_fn_mtag(sym);
gettimeofday(&data.start_time, NULL);
__push_fake_cur_stree();
@@ -1569,7 +1642,7 @@ static int call_return_state_hooks_split_possible(struct expression *expr)
{
struct sm_state *sm;
- if (!expr || expr_equal_to_param(expr, -1))
+ if (!expr)
return 0;
sm = get_sm_state_expr(SMATCH_EXTRA, expr);
@@ -1707,6 +1780,8 @@ static int call_return_state_hooks_split_null_non_null_zero(struct expression *e
return 0;
if (estate_min(state).value == 0 && estate_max(state).value == 0)
return 0;
+ if (has_possible_negative(sm))
+ return 0;
if (!has_separate_zero_null(sm))
return 0;
@@ -2020,6 +2095,24 @@ struct expression *strip_expr_statement(struct expression *expr)
return strip_expr(last_stmt->expression);
}
+static bool is_kernel_error_path(struct expression *expr)
+{
+ struct range_list *rl;
+
+ /*
+ * Splitting up returns requires resources. It also requires resources
+ * for the caller. It doesn't seem worth it to split anything up.
+ */
+ if (!get_implied_rl(expr, &rl))
+ return false;
+ if (rl_type(rl) != &int_ctype)
+ return false;
+ if (rl_min(rl).value >= -4095 &&
+ rl_max(rl).value < 0)
+ return true;
+ return false;
+}
+
static void call_return_state_hooks(struct expression *expr)
{
struct returned_state_callback *cb;
@@ -2044,6 +2137,8 @@ static void call_return_state_hooks(struct expression *expr)
return;
} else if (call_return_state_hooks_conditional(expr)) {
return;
+ } else if (is_kernel_error_path(expr)) {
+ goto vanilla;
} else if (call_return_state_hooks_split_possible(expr)) {
return;
} else if (split_positive_from_negative(expr)) {
@@ -2165,6 +2260,7 @@ static void init_memdb(void)
"db/fn_ptr_data_link.schema",
"db/fn_data_link.schema",
"db/mtag_about.schema",
+ "db/mtag_info.schema",
"db/mtag_map.schema",
"db/mtag_data.schema",
"db/mtag_alias.schema",
@@ -2212,7 +2308,9 @@ static void init_cachedb(void)
"db/call_implies.schema",
"db/return_implies.schema",
"db/type_info.schema",
+ "db/mtag_about.schema",
"db/mtag_data.schema",
+ "db/mtag_info.schema",
"db/sink_info.schema",
};
static char buf[4096];
@@ -2277,13 +2375,20 @@ static int save_cache_data(void *_table, int argc, char **argv, char **azColName
static void dump_cache(struct symbol_list *sym_list)
{
+ const char *cache_tables[] = {
+ "type_info", "return_implies", "call_implies", "mtag_data",
+ "mtag_info", "mtag_about", "sink_info",
+ };
+ char buf[64];
+ int i;
+
if (!option_info)
return;
- cache_sql(&save_cache_data, (char *)"type_info", "select * from type_info;");
- cache_sql(&save_cache_data, (char *)"return_implies", "select * from return_implies;");
- cache_sql(&save_cache_data, (char *)"call_implies", "select * from call_implies;");
- cache_sql(&save_cache_data, (char *)"mtag_data", "select * from mtag_data;");
- cache_sql(&save_cache_data, (char *)"sink_info", "select * from sink_info;");
+
+ for (i = 0; i < ARRAY_SIZE(cache_tables); i++) {
+ snprintf(buf, sizeof(buf), "select * from %s;", cache_tables[i]);
+ cache_sql(&save_cache_data, (char *)cache_tables[i], buf);
+ }
}
void open_smatch_db(char *db_file)
@@ -2429,6 +2534,7 @@ static void register_return_replacements(void)
void register_definition_db_callbacks(int id)
{
add_hook(&match_call_info, FUNCTION_CALL_HOOK);
+ add_hook(&match_call_info_new, FUNCTION_CALL_HOOK);
add_split_return_callback(match_return_info);
add_split_return_callback(print_returned_struct_members);
add_hook(&call_return_state_hooks, RETURN_HOOK);
@@ -2493,9 +2599,11 @@ char *return_state_to_var_sym(struct expression *expr, int param, const char *ke
char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
{
+ struct symbol *type;
char buf[256];
char *tmp;
int star_cnt = 0;
+ bool add_dot = false;
if (!arg)
return NULL;
@@ -2519,12 +2627,37 @@ char *get_variable_from_key(struct expression *arg, const char *key, struct symb
}
}
+ if (strncmp(key, "(*$)", 4) == 0) {
+ char buf[64];
+
+ if (arg->type == EXPR_PREOP && arg->op == '&') {
+ arg = strip_expr(arg->unop);
+ snprintf(buf, sizeof(buf), "$%s", key + 4);
+ return get_variable_from_key(arg, buf, sym);
+ } else {
+ tmp = expr_to_var_sym(arg, sym);
+ if (!tmp)
+ return NULL;
+ snprintf(buf, sizeof(buf), "(*%s)%s", tmp, key + 4);
+ free_string(tmp);
+ return alloc_string(buf);
+ }
+ }
+
while (key[0] == '*') {
star_cnt++;
key++;
}
- if (arg->type == EXPR_PREOP && arg->op == '&' && star_cnt) {
+ /*
+ * FIXME: This is a hack.
+ * We should be able to parse expressions like (*$)->foo and *$->foo.
+ */
+ type = get_type(arg);
+ if (is_struct_ptr(type))
+ add_dot = true;
+
+ if (arg->type == EXPR_PREOP && arg->op == '&' && star_cnt && !add_dot) {
arg = strip_expr(arg->unop);
star_cnt--;
}
@@ -2573,6 +2706,14 @@ const char *state_name_to_param_name(const char *state_name, const char *param_n
if (star_cnt > 10)
return NULL;
+ if (strncmp(state_name, "(*", 2) == 0 &&
+ strncmp(state_name + 2, param_name, name_len) == 0 &&
+ state_name[name_len + 2] == ')') {
+ snprintf(buf, sizeof(buf), "%.*s(*$)%s", star_cnt, "**********",
+ state_name + name_len + 3);
+ return alloc_sname(buf);
+ }
+
if (strcmp(state_name, param_name) == 0) {
snprintf(buf, sizeof(buf), "%.*s$", star_cnt, "**********");
return alloc_sname(buf);
diff --git a/usr/src/tools/smatch/src/smatch_estate.c b/usr/src/tools/smatch/src/smatch_estate.c
index 4882347776..c8cc4b76b0 100644
--- a/usr/src/tools/smatch/src/smatch_estate.c
+++ b/usr/src/tools/smatch/src/smatch_estate.c
@@ -56,6 +56,9 @@ struct smatch_state *merge_estates(struct smatch_state *s1, struct smatch_state
if (estate_treat_untagged(s1) && estate_treat_untagged(s2))
estate_set_treat_untagged(tmp);
+ if (estate_new(s1) || estate_new(s2))
+ estate_set_new(tmp);
+
return tmp;
}
@@ -126,6 +129,9 @@ int estate_has_hard_max(struct smatch_state *state)
void estate_set_hard_max(struct smatch_state *state)
{
+ /* pointers don't have a hard max */
+ if (is_ptr_type(estate_type(state)))
+ return;
get_dinfo(state)->hard_max = 1;
}
@@ -174,6 +180,18 @@ void estate_set_treat_untagged(struct smatch_state *state)
get_dinfo(state)->treat_untagged = true;
}
+bool estate_new(struct smatch_state *state)
+{
+ if (!estate_rl(state))
+ return false;
+ return get_dinfo(state)->set;
+}
+
+void estate_set_new(struct smatch_state *state)
+{
+ get_dinfo(state)->set = true;
+}
+
sval_t estate_min(struct smatch_state *state)
{
return rl_min(estate_rl(state));
@@ -226,6 +244,10 @@ int estates_equiv(struct smatch_state *one, struct smatch_state *two)
return 0;
if (estate_treat_untagged(one) != estate_treat_untagged(two))
return 0;
+ if (estate_has_hard_max(one) != estate_has_hard_max(two))
+ return 0;
+ if (estate_new(one) != estate_new(two))
+ return 0;
if (strcmp(one->name, two->name) == 0)
return 1;
return 0;
diff --git a/usr/src/tools/smatch/src/smatch_expressions.c b/usr/src/tools/smatch/src/smatch_expressions.c
index 97f3c98ff6..c185b89b4f 100644
--- a/usr/src/tools/smatch/src/smatch_expressions.c
+++ b/usr/src/tools/smatch/src/smatch_expressions.c
@@ -27,7 +27,7 @@ struct expression *alloc_tmp_expression(struct position pos, int type)
struct expression *expr;
expr = __alloc_tmp_expression(0);
- expr->smatch_flags |= Fake;
+ expr->smatch_flags |= Tmp;
expr->type = type;
expr->pos = pos;
return expr;
@@ -300,7 +300,7 @@ void expr_set_parent_expr(struct expression *expr, struct expression *parent)
{
if (!expr)
return;
- if (parent->smatch_flags & Fake)
+ if (parent && parent->smatch_flags & Tmp)
return;
expr->parent = (unsigned long)parent | 0x1UL;
diff --git a/usr/src/tools/smatch/src/smatch_extra.c b/usr/src/tools/smatch/src/smatch_extra.c
index 9d7744d97c..5d34a5d7ee 100644
--- a/usr/src/tools/smatch/src/smatch_extra.c
+++ b/usr/src/tools/smatch/src/smatch_extra.c
@@ -36,7 +36,6 @@
static int my_id;
static int link_id;
-extern int check_assigned_expr_id;
static void match_link_modify(struct sm_state *sm, struct expression *mod_expr);
@@ -172,12 +171,17 @@ done:
static bool in_param_set;
void set_extra_mod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
{
+ struct expression *faked;
+
if (!expr)
expr = gen_expression_from_name_sym(name, sym);
remove_from_equiv(name, sym);
set_union_info(name, sym, expr, state);
call_extra_mod_hooks(name, sym, expr, state);
- update_mtag_data(expr, state);
+ faked = get_faked_expression();
+ if (!faked ||
+ (faked->type == EXPR_ASSIGNMENT && is_fresh_alloc(faked->right)))
+ update_mtag_data(expr, state);
if (in_param_set &&
estate_is_unknown(state) && !get_state(SMATCH_EXTRA, name, sym))
return;
@@ -2800,19 +2804,15 @@ static void set_param_value(const char *name, struct symbol *sym, char *key, cha
struct range_list *rl = NULL;
struct smatch_state *state;
struct symbol *type;
- char fullname[256];
char *key_orig = key;
- bool add_star = false;
+ char *fullname;
sval_t dummy;
- if (key[0] == '*') {
- add_star = true;
- key++;
- }
-
- snprintf(fullname, 256, "%s%s%s", add_star ? "*" : "", name, key + 1);
-
expr = symbol_expression(sym);
+ fullname = get_variable_from_key(expr, key, NULL);
+ if (!fullname)
+ return;
+
type = get_member_type_from_key(expr, key_orig);
str_to_rl(type, value, &rl);
state = alloc_estate_rl(rl);
@@ -2823,17 +2823,16 @@ static void set_param_value(const char *name, struct symbol *sym, char *key, cha
static void set_param_fuzzy_max(const char *name, struct symbol *sym, char *key, char *value)
{
+ struct expression *expr;
struct range_list *rl = NULL;
struct smatch_state *state;
struct symbol *type;
- char fullname[256];
+ char *fullname;
sval_t max;
- if (strcmp(key, "*$") == 0)
- snprintf(fullname, sizeof(fullname), "*%s", name);
- else if (strncmp(key, "$", 1) == 0)
- snprintf(fullname, 256, "%s%s", name, key + 1);
- else
+ expr = symbol_expression(sym);
+ fullname = get_variable_from_key(expr, key, NULL);
+ if (!fullname)
return;
state = get_state(SMATCH_EXTRA, fullname, sym);
@@ -2849,13 +2848,12 @@ static void set_param_fuzzy_max(const char *name, struct symbol *sym, char *key,
static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
{
struct smatch_state *state;
- char fullname[256];
+ struct expression *expr;
+ char *fullname;
- if (strcmp(key, "*$") == 0)
- snprintf(fullname, sizeof(fullname), "*%s", name);
- else if (strncmp(key, "$", 1) == 0)
- snprintf(fullname, 256, "%s%s", name, key + 1);
- else
+ expr = symbol_expression(sym);
+ fullname = get_variable_from_key(expr, key, NULL);
+ if (!fullname)
return;
state = get_state(SMATCH_EXTRA, fullname, sym);
diff --git a/usr/src/tools/smatch/src/smatch_extra.h b/usr/src/tools/smatch/src/smatch_extra.h
index 3fb917a5ea..222be0f29c 100644
--- a/usr/src/tools/smatch/src/smatch_extra.h
+++ b/usr/src/tools/smatch/src/smatch_extra.h
@@ -32,6 +32,7 @@ struct data_info {
unsigned int hard_max:1;
unsigned int capped:1;
unsigned int treat_untagged:1;
+ unsigned int set:1;
};
DECLARE_ALLOCATOR(data_info);
@@ -101,6 +102,7 @@ struct range_list *rl_truncate_cast(struct symbol *type, struct range_list *rl);
struct range_list *cast_rl(struct symbol *type, struct range_list *rl);
int get_implied_rl(struct expression *expr, struct range_list **rl);
int get_absolute_rl(struct expression *expr, struct range_list **rl);
+void set_real_absolute(struct expression *expr, struct smatch_state *state);
int get_real_absolute_rl(struct expression *expr, struct range_list **rl);
struct range_list *var_to_absolute_rl(struct expression *expr);
int custom_get_absolute_rl(struct expression *expr,
@@ -151,6 +153,8 @@ bool estate_capped(struct smatch_state *state);
void estate_set_capped(struct smatch_state *state);
bool estate_treat_untagged(struct smatch_state *state);
void estate_set_treat_untagged(struct smatch_state *state);
+bool estate_new(struct smatch_state *state);
+void estate_set_new(struct smatch_state *state);
int estate_get_single_value(struct smatch_state *state, sval_t *sval);
struct smatch_state *get_implied_estate(struct expression *expr);
diff --git a/usr/src/tools/smatch/src/smatch_flow.c b/usr/src/tools/smatch/src/smatch_flow.c
index 4a842027e3..1971599bbb 100644
--- a/usr/src/tools/smatch/src/smatch_flow.c
+++ b/usr/src/tools/smatch/src/smatch_flow.c
@@ -438,20 +438,20 @@ void __split_expr(struct expression *expr)
/* foo = !bar() */
if (__handle_condition_assigns(expr))
- break;
+ goto after_assign;
/* foo = (x < 5 ? foo : 5); */
if (__handle_select_assigns(expr))
- break;
+ goto after_assign;
/* foo = ({frob(); frob(); frob(); 1;}) */
if (__handle_expr_statement_assigns(expr))
- break;
+ break; // FIXME: got after
/* foo = (3, 4); */
if (handle_comma_assigns(expr))
- break;
- if (handle_postop_assigns(expr))
- break;
+ goto after_assign;
if (handle__builtin_choose_expr_assigns(expr))
- break;
+ goto after_assign;
+ if (handle_postop_assigns(expr))
+ break; /* no need to goto after_assign */
__split_expr(expr->right);
if (outside_of_function())
@@ -470,8 +470,8 @@ void __split_expr(struct expression *expr)
get_macro_name(expr->pos) != get_macro_name(right->pos))
__pass_to_client(expr, MACRO_ASSIGNMENT_HOOK);
+after_assign:
__pass_to_client(expr, ASSIGNMENT_HOOK_AFTER);
-
__split_expr(expr->left);
break;
}
diff --git a/usr/src/tools/smatch/src/smatch_fresh_alloc.c b/usr/src/tools/smatch/src/smatch_fresh_alloc.c
index d7104f6b53..cec6b62c9e 100644
--- a/usr/src/tools/smatch/src/smatch_fresh_alloc.c
+++ b/usr/src/tools/smatch/src/smatch_fresh_alloc.c
@@ -23,6 +23,7 @@
*/
#include "smatch.h"
+#include "smatch_extra.h"
#include "smatch_slist.h"
static int my_id;
@@ -65,6 +66,16 @@ struct alloc_info general_allocation_funcs[] = {
{},
};
+static void pre_merge_hook(struct sm_state *cur, struct sm_state *other)
+{
+ struct smatch_state *state;
+ sval_t sval;
+
+ state = get_state(SMATCH_EXTRA, cur->name, cur->sym);
+ if (estate_get_single_value(state, &sval) && sval.value == 0)
+ set_state(my_id, cur->name, cur->sym, &undefined);
+}
+
static int fresh_callback(void *fresh, int argc, char **argv, char **azColName)
{
*(int *)fresh = 1;
@@ -150,12 +161,23 @@ static void match_call(struct expression *expr)
} END_FOR_EACH_PTR(arg);
}
+static struct expression *handled;
static void set_fresh(struct expression *expr)
{
+ struct range_list *rl;
+
expr = strip_expr(expr);
if (expr->type != EXPR_SYMBOL)
return;
+ if (expr == handled)
+ return;
+
+ get_absolute_rl(expr, &rl);
+ rl = rl_intersection(rl, valid_ptr_rl);
+ if (!rl)
+ return;
set_state_expr(my_id, expr, &fresh);
+ handled = expr;
}
static void returns_fresh_alloc(struct expression *expr, int param, char *key, char *value)
@@ -192,4 +214,6 @@ void register_fresh_alloc(int id)
select_return_states_hook(FRESH_ALLOC, &returns_fresh_alloc);
add_hook(&match_assign, ASSIGNMENT_HOOK);
add_hook(&match_call, FUNCTION_CALL_HOOK);
+
+ add_pre_merge_hook(my_id, &pre_merge_hook);
}
diff --git a/usr/src/tools/smatch/src/smatch_function_hooks.c b/usr/src/tools/smatch/src/smatch_function_hooks.c
index d38cff1936..f821d62189 100644
--- a/usr/src/tools/smatch/src/smatch_function_hooks.c
+++ b/usr/src/tools/smatch/src/smatch_function_hooks.c
@@ -357,6 +357,7 @@ struct db_callback_info {
struct range_list *rl;
int left;
struct stree *stree;
+ struct stree *implied;
struct db_implies_list *callbacks;
int prev_return_id;
int cull;
@@ -367,6 +368,17 @@ struct db_callback_info {
int handled;
};
+static void set_implied_states(struct db_callback_info *db_info)
+{
+ struct sm_state *sm;
+
+ FOR_EACH_SM(db_info->implied, sm) {
+ __set_sm(sm);
+ } END_FOR_EACH_SM(sm);
+
+ free_stree(&db_info->implied);
+}
+
static void store_return_state(struct db_callback_info *db_info, const char *ret_str, struct smatch_state *state)
{
db_info->ret_str = alloc_sname(ret_str),
@@ -460,6 +472,26 @@ static bool fake_a_param_assignment(struct expression *expr, const char *return_
return true;
}
+static void set_fresh_mtag_returns(struct db_callback_info *db_info)
+{
+ struct expression *expr = db_info->expr->left;
+ struct smatch_state *state;
+
+ if (!db_info->ret_state)
+ return;
+
+ state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
+ state = get_mtag_return(db_info->expr, state);
+ if (!state)
+ return;
+
+ set_real_absolute(expr, state);
+ set_extra_expr_mod(expr, state);
+
+ db_info->ret_state = NULL;
+ db_info->ret_str = NULL;
+}
+
static void set_return_assign_state(struct db_callback_info *db_info)
{
struct expression *expr = db_info->expr->left;
@@ -635,8 +667,8 @@ static int db_compare_callback(void *_info, int argc, char **argv, char **azColN
db_info->has_states = 1;
if (db_info->prev_return_id != -1 && type == INTERNAL) {
set_other_side_state(db_info);
+ set_implied_states(db_info);
stree = __pop_fake_cur_stree();
-
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
free_stree(&stree);
@@ -672,14 +704,14 @@ static int db_compare_callback(void *_info, int argc, char **argv, char **azColN
if (!possibly_true_rl(var_rl, comparison, ret_range))
return 0;
if (type == PARAM_LIMIT)
- param_limit_implications(db_info->expr, param, key, value);
+ param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
filter_by_comparison(&var_rl, comparison, ret_range);
filter_by_comparison(&ret_range, flip_comparison(comparison), var_rl);
} else {
if (!possibly_false_rl(var_rl, comparison, ret_range))
return 0;
if (type == PARAM_LIMIT)
- param_limit_implications(db_info->expr, param, key, value);
+ param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
filter_by_comparison(&var_rl, negate_comparison(comparison), ret_range);
filter_by_comparison(&ret_range, flip_comparison(negate_comparison(comparison)), var_rl);
}
@@ -744,6 +776,7 @@ static void compare_db_return_states_callbacks(struct expression *left, int comp
sql_select_return_states("return_id, return, type, parameter, key, value",
call_expr, db_compare_callback, &db_info);
set_other_side_state(&db_info);
+ set_implied_states(&db_info);
stree = __pop_fake_cur_stree();
if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
@@ -769,6 +802,7 @@ static void compare_db_return_states_callbacks(struct expression *left, int comp
sql_select_return_states("return_id, return, type, parameter, key, value", call_expr,
db_compare_callback, &db_info);
set_other_side_state(&db_info);
+ set_implied_states(&db_info);
stree = __pop_fake_cur_stree();
if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
@@ -893,6 +927,7 @@ static int db_assign_return_states_callback(void *_info, int argc, char **argv,
if (db_info->prev_return_id != -1 && type == INTERNAL) {
call_ranged_return_hooks(db_info);
set_return_assign_state(db_info);
+ set_implied_states(db_info);
stree = __pop_fake_cur_stree();
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
@@ -916,7 +951,7 @@ static int db_assign_return_states_callback(void *_info, int argc, char **argv,
}
if (type == PARAM_LIMIT)
- param_limit_implications(db_info->expr, param, key, value);
+ param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
db_info->handled = 1;
call_results_to_rl(db_info->expr->right, get_type(strip_expr(db_info->expr->right)), ret_str, &ret_range);
@@ -930,6 +965,7 @@ static int db_assign_return_states_callback(void *_info, int argc, char **argv,
__add_comparison_info(db_info->expr->left, strip_expr(db_info->expr->right), ret_str);
__add_return_to_param_mapping(db_info->expr, ret_str);
store_return_state(db_info, ret_str, alloc_estate_rl(ret_range));
+ set_fresh_mtag_returns(db_info);
}
FOR_EACH_PTR(db_return_states_list, tmp) {
@@ -968,6 +1004,7 @@ static int db_return_states_assign(struct expression *expr)
if (db_info.handled)
call_ranged_return_hooks(&db_info);
set_return_assign_state(&db_info);
+ set_implied_states(&db_info);
stree = __pop_fake_cur_stree();
if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
@@ -1079,6 +1116,7 @@ static int db_return_states_callback(void *_info, int argc, char **argv, char **
if (db_info->prev_return_id != -1 && type == INTERNAL) {
call_ranged_return_hooks(db_info);
+ set_implied_states(db_info);
stree = __pop_fake_cur_stree();
if (!db_info->cull)
merge_fake_stree(&db_info->stree, stree);
@@ -1103,7 +1141,7 @@ static int db_return_states_callback(void *_info, int argc, char **argv, char **
}
if (type == PARAM_LIMIT)
- param_limit_implications(db_info->expr, param, key, value);
+ param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
ret_range = cast_rl(get_type(db_info->expr), ret_range);
@@ -1154,6 +1192,7 @@ static void db_return_states(struct expression *expr)
sql_select_return_states("return_id, return, type, parameter, key, value",
expr, db_return_states_callback, &db_info);
call_ranged_return_hooks(&db_info);
+ set_implied_states(&db_info);
stree = __pop_fake_cur_stree();
if (!db_info.cull)
merge_fake_stree(&db_info.stree, stree);
diff --git a/usr/src/tools/smatch/src/smatch_function_ptrs.c b/usr/src/tools/smatch/src/smatch_function_ptrs.c
index fc9c51b6a6..f728337e99 100644
--- a/usr/src/tools/smatch/src/smatch_function_ptrs.c
+++ b/usr/src/tools/smatch/src/smatch_function_ptrs.c
@@ -218,7 +218,7 @@ char *get_fnptr_name(struct expression *expr)
return alloc_string(buf);
}
- name = expr_to_var_sym(expr, &sym);
+ name = expr_to_var_sym(expr, &sym);
if (!name)
return NULL;
type = get_type(expr);
diff --git a/usr/src/tools/smatch/src/smatch_helper.c b/usr/src/tools/smatch/src/smatch_helper.c
index 485f041123..812b65e8fe 100644
--- a/usr/src/tools/smatch/src/smatch_helper.c
+++ b/usr/src/tools/smatch/src/smatch_helper.c
@@ -147,7 +147,7 @@ struct expression *get_argument_from_call_expr(struct expression_list *args,
return NULL;
}
-static struct expression *get_array_expr(struct expression *expr)
+struct expression *get_array_expr(struct expression *expr)
{
struct expression *parent;
struct symbol *type;
@@ -174,10 +174,8 @@ static struct expression *get_array_expr(struct expression *expr)
static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
struct expression *expr, int len,
- int *complicated, int no_parens)
+ int *complicated)
{
-
-
if (!expr) {
/* can't happen on valid code */
*complicated = 1;
@@ -204,7 +202,7 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
}
}
- __get_variable_from_expr(sym_ptr, buf, deref, len, complicated, no_parens);
+ __get_variable_from_expr(sym_ptr, buf, deref, len, complicated);
if (op == '*')
append(buf, "->", len);
@@ -236,20 +234,20 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
}
if (expr->op == '(') {
- if (!no_parens && expr->unop->type != EXPR_SYMBOL)
+ if (expr->unop->type != EXPR_SYMBOL)
append(buf, "(", len);
} else if (expr->op != '*' || !get_array_expr(expr->unop)) {
tmp = show_special(expr->op);
append(buf, tmp, len);
}
__get_variable_from_expr(sym_ptr, buf, expr->unop,
- len, complicated, no_parens);
+ len, complicated);
- if (expr->op == '(' && !no_parens && expr->unop->type != EXPR_SYMBOL)
+ if (expr->op == '(' && expr->unop->type != EXPR_SYMBOL)
append(buf, ")", len);
if (expr->op == SPECIAL_DECREMENT ||
- expr->op == SPECIAL_INCREMENT)
+ expr->op == SPECIAL_INCREMENT)
*complicated = 1;
return;
@@ -258,7 +256,7 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
const char *tmp;
__get_variable_from_expr(sym_ptr, buf, expr->unop,
- len, complicated, no_parens);
+ len, complicated);
tmp = show_special(expr->op);
append(buf, tmp, len);
@@ -276,14 +274,14 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
*complicated = 1;
array_expr = get_array_expr(expr);
if (array_expr) {
- __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated, no_parens);
+ __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated);
append(buf, "[", len);
} else {
- __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated, no_parens);
+ __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated);
snprintf(tmp, sizeof(tmp), " %s ", show_special(expr->op));
append(buf, tmp, len);
}
- __get_variable_from_expr(NULL, buf, expr->right, len, complicated, no_parens);
+ __get_variable_from_expr(NULL, buf, expr->right, len, complicated);
if (array_expr)
append(buf, "]", len);
return;
@@ -321,13 +319,13 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
int i;
*complicated = 1;
- __get_variable_from_expr(NULL, buf, expr->fn, len, complicated, no_parens);
+ __get_variable_from_expr(NULL, buf, expr->fn, len, complicated);
append(buf, "(", len);
i = 0;
FOR_EACH_PTR(expr->args, tmp) {
if (i++)
append(buf, ", ", len);
- __get_variable_from_expr(NULL, buf, tmp, len, complicated, no_parens);
+ __get_variable_from_expr(NULL, buf, tmp, len, complicated);
} END_FOR_EACH_PTR(tmp);
append(buf, ")", len);
return;
@@ -336,7 +334,7 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
case EXPR_FORCE_CAST:
__get_variable_from_expr(sym_ptr, buf,
expr->cast_expression, len,
- complicated, no_parens);
+ complicated);
return;
case EXPR_SIZEOF: {
sval_t sval;
@@ -358,16 +356,30 @@ static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
if (expr->expr_ident)
append(buf, expr->expr_ident->name, len);
return;
- default:
+ case EXPR_SELECT:
+ case EXPR_CONDITIONAL:
*complicated = 1;
- //printf("unknown type = %d\n", expr->type);
+ append(buf, "(", len);
+ __get_variable_from_expr(NULL, buf, expr->conditional, len, complicated);
+ append(buf, ") ?", len);
+ if (expr->cond_true)
+ __get_variable_from_expr(NULL, buf, expr->cond_true, len, complicated);
+ append(buf, ":", len);
+ __get_variable_from_expr(NULL, buf, expr->cond_false, len, complicated);
+ return;
+ default: {
+ char tmp[64];
+
+ snprintf(tmp, sizeof(tmp), "$expr_%p(%d)", expr, expr->type);
+ append(buf, tmp, len);
+ *complicated = 1;
+ }
return;
}
}
struct expr_str_cache_results {
struct expression *expr;
- int no_parens;
char str[VAR_LEN];
struct symbol *sym;
int complicated;
@@ -375,7 +387,7 @@ struct expr_str_cache_results {
static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
struct expression *expr, int len,
- int *complicated, int no_parens)
+ int *complicated)
{
static struct expr_str_cache_results cached[8];
struct symbol *tmp_sym = NULL;
@@ -383,8 +395,7 @@ static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
int i;
for (i = 0; i < ARRAY_SIZE(cached); i++) {
- if (expr == cached[i].expr &&
- no_parens == cached[i].no_parens) {
+ if (expr == cached[i].expr) {
strncpy(buf, cached[i].str, len);
if (sym_ptr)
*sym_ptr = cached[i].sym;
@@ -393,12 +404,14 @@ static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
}
}
- __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated, no_parens);
+ __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated);
if (sym_ptr)
*sym_ptr = tmp_sym;
+ if (expr->smatch_flags & Tmp)
+ return;
+
cached[idx].expr = expr;
- cached[idx].no_parens = no_parens;
strncpy(cached[idx].str, buf, VAR_LEN);
cached[idx].sym = tmp_sym;
cached[idx].complicated = *complicated;
@@ -427,7 +440,7 @@ char *expr_to_str_sym(struct expression *expr, struct symbol **sym_ptr)
if (!expr)
return NULL;
get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
- &complicated, 0);
+ &complicated);
if (complicated < 2)
return alloc_string(var_name);
else
@@ -458,7 +471,7 @@ char *expr_to_var_sym(struct expression *expr,
return NULL;
expr = strip_expr(expr);
get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
- &complicated, 1);
+ &complicated);
if (complicated) {
if (sym_ptr)
@@ -1051,8 +1064,23 @@ int get_param_num_from_sym(struct symbol *sym)
struct symbol *tmp;
int i;
- if (!cur_func_sym)
- return -1;
+ if (!sym)
+ return UNKNOWN_SCOPE;
+
+ if (sym->ctype.modifiers & MOD_TOPLEVEL) {
+ if (sym->ctype.modifiers & MOD_STATIC)
+ return FILE_SCOPE;
+ return GLOBAL_SCOPE;
+ }
+
+ if (!cur_func_sym) {
+ if (!parse_error) {
+ sm_msg("warn: internal. problem with scope: %s",
+ sym->ident ? sym->ident->name : "<anon var>");
+ }
+ return GLOBAL_SCOPE;
+ }
+
i = 0;
FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, tmp) {
@@ -1060,7 +1088,7 @@ int get_param_num_from_sym(struct symbol *sym)
return i;
i++;
} END_FOR_EACH_PTR(tmp);
- return -1;
+ return LOCAL_SCOPE;
}
int get_param_num(struct expression *expr)
@@ -1069,11 +1097,11 @@ int get_param_num(struct expression *expr)
char *name;
if (!cur_func_sym)
- return -1;
+ return UNKNOWN_SCOPE;
name = expr_to_var_sym(expr, &sym);
free_string(name);
if (!sym)
- return -1;
+ return UNKNOWN_SCOPE;
return get_param_num_from_sym(sym);
}
diff --git a/usr/src/tools/smatch/src/smatch_implied.c b/usr/src/tools/smatch/src/smatch_implied.c
index b498c8e71f..477dab791d 100644
--- a/usr/src/tools/smatch/src/smatch_implied.c
+++ b/usr/src/tools/smatch/src/smatch_implied.c
@@ -72,6 +72,8 @@ bool implications_off;
bool debug_implied(void)
{
+ if (option_debug)
+ return true;
return implied_debug;
}
@@ -91,6 +93,13 @@ static struct range_list *tmp_range_list(struct symbol *type, long long num)
return my_list;
}
+static const char *show_comparison(int op)
+{
+ if (op == PARAM_LIMIT)
+ return "<lim>";
+ return show_special(op);
+}
+
static void print_debug_tf(struct sm_state *sm, int istrue, int isfalse)
{
if (!implied_debug && !option_debug)
@@ -115,6 +124,18 @@ static void print_debug_tf(struct sm_state *sm, int istrue, int isfalse)
}
}
+void split_comparison_helper(struct range_list *left_orig, int op, struct range_list *right_orig,
+ struct range_list **left_true_rl, struct range_list **left_false_rl)
+{
+ if (op == PARAM_LIMIT) {
+ *left_true_rl = rl_intersection(left_orig, right_orig);
+ *left_false_rl = rl_filter(left_orig, right_orig);
+ return;
+ }
+
+ split_comparison_rl(left_orig, op, right_orig, left_true_rl, left_false_rl, NULL, NULL);
+}
+
static int create_fake_history(struct sm_state *sm, int comparison, struct range_list *rl)
{
struct range_list *orig_rl;
@@ -131,7 +152,7 @@ static int create_fake_history(struct sm_state *sm, int comparison, struct range
return 0;
orig_rl = cast_rl(rl_type(rl), estate_rl(sm->state));
- split_comparison_rl(orig_rl, comparison, rl, &true_rl, &false_rl, NULL, NULL);
+ split_comparison_helper(orig_rl, comparison, rl, &true_rl, &false_rl);
true_rl = rl_truncate_cast(estate_type(sm->state), true_rl);
false_rl = rl_truncate_cast(estate_type(sm->state), false_rl);
@@ -154,7 +175,7 @@ static int create_fake_history(struct sm_state *sm, int comparison, struct range
if (implied_debug)
sm_msg("fake_history: %s vs %s. %s %s %s. --> T: %s F: %s",
- sm->name, show_rl(rl), sm->state->name, show_special(comparison), show_rl(rl),
+ sm->name, show_rl(rl), sm->state->name, show_comparison(comparison), show_rl(rl),
show_rl(true_rl), show_rl(false_rl));
true_sm = clone_sm(sm);
@@ -233,6 +254,32 @@ static int remove_pool(struct state_list **pools, struct stree *remove)
return ret;
}
+static bool possibly_true_helper(struct range_list *var_rl, int comparison, struct range_list *rl)
+{
+ if (comparison == PARAM_LIMIT) {
+ struct range_list *intersect;
+
+ intersect = rl_intersection(var_rl, rl);
+ if (intersect)
+ return true;
+ return false;
+ }
+ return possibly_true_rl(var_rl, comparison, rl);
+}
+
+static bool possibly_false_helper(struct range_list *var_rl, int comparison, struct range_list *rl)
+{
+ if (comparison == PARAM_LIMIT) {
+ struct range_list *intersect;
+
+ intersect = rl_intersection(var_rl, rl);
+ if (!rl_equiv(var_rl, intersect))
+ return true;
+ return false;
+ }
+ return possibly_false_rl(var_rl, comparison, rl);
+}
+
/*
* If 'foo' == 99 add it that pool to the true pools. If it's false, add it to
* the false pools. If we're not sure, then we don't add it to either.
@@ -252,8 +299,8 @@ static void do_compare(struct sm_state *sm, int comparison, struct range_list *r
var_rl = cast_rl(rl_type(rl), estate_rl(sm->state));
- istrue = !possibly_false_rl(var_rl, comparison, rl);
- isfalse = !possibly_true_rl(var_rl, comparison, rl);
+ istrue = !possibly_false_helper(var_rl, comparison, rl);
+ isfalse = !possibly_true_helper(var_rl, comparison, rl);
print_debug_tf(sm, istrue, isfalse);
@@ -315,7 +362,7 @@ static void __separate_pools(struct sm_state *sm, int comparison, struct range_l
if (diff.tv_sec >= 1) {
if (implied_debug) {
sm_msg("debug: %s: implications taking too long. (%s %s %s)",
- __func__, sm->state->name, show_special(comparison), show_rl(rl));
+ __func__, sm->state->name, show_comparison(comparison), show_rl(rl));
}
if (mixed)
*mixed = 1;
@@ -538,9 +585,9 @@ struct sm_state *filter_pools(struct sm_state *sm,
}
static struct stree *filter_stack(struct sm_state *gate_sm,
- struct stree *pre_stree,
- const struct state_list *remove_stack,
- const struct state_list *keep_stack)
+ struct stree *pre_stree,
+ const struct state_list *remove_stack,
+ const struct state_list *keep_stack)
{
struct stree *ret = NULL;
struct sm_state *tmp;
@@ -593,7 +640,7 @@ static void separate_and_filter(struct sm_state *sm, int comparison, struct rang
gettimeofday(&time_before, NULL);
DIMPLIED("checking implications: (%s (%s) %s %s)\n",
- sm->name, sm->state->name, show_special(comparison), show_rl(rl));
+ sm->name, sm->state->name, show_comparison(comparison), show_rl(rl));
if (!is_merged(sm)) {
DIMPLIED("%d '%s' from line %d is not merged.\n", get_lineno(), sm->name, sm->line);
@@ -752,7 +799,7 @@ static int handle_zero_comparison(struct expression *expr,
if (!name || !sym)
goto free;
sm = get_sm_state(SMATCH_EXTRA, name, sym);
- if (!sm)
+ if (!sm || !sm->merged)
goto free;
separate_and_filter(sm, SPECIAL_NOTEQUAL, tmp_range_list(estate_type(sm->state), 0), __get_cur_stree(), implied_true, implied_false, &mixed);
@@ -770,13 +817,13 @@ free:
}
static int handled_by_comparison_hook(struct expression *expr,
- struct stree **implied_true,
- struct stree **implied_false)
+ struct stree **implied_true,
+ struct stree **implied_false)
{
+ struct sm_state *sm, *true_sm, *false_sm;
struct state_list *true_stack = NULL;
struct state_list *false_stack = NULL;
struct stree *pre_stree;
- struct sm_state *sm;
sm = comparison_implication_hook(expr, &true_stack, &false_stack);
if (!sm)
@@ -787,6 +834,13 @@ static int handled_by_comparison_hook(struct expression *expr,
*implied_true = filter_stack(sm, pre_stree, false_stack, true_stack);
*implied_false = filter_stack(sm, pre_stree, true_stack, false_stack);
+ true_sm = get_sm_state_stree(*implied_true, sm->owner, sm->name, sm->sym);
+ false_sm = get_sm_state_stree(*implied_false, sm->owner, sm->name, sm->sym);
+ if (true_sm && strcmp(true_sm->state->name, "unknown") == 0)
+ delete_state_stree(implied_true, sm->owner, sm->name, sm->sym);
+ if (false_sm && strcmp(false_sm->state->name, "unknown") == 0)
+ delete_state_stree(implied_false, sm->owner, sm->name, sm->sym);
+
free_stree(&pre_stree);
free_slist(&true_stack);
free_slist(&false_stack);
@@ -953,9 +1007,9 @@ static void set_extra_implied_states(struct expression *expr)
set_implied_states(NULL);
}
-void param_limit_implications(struct expression *expr, int param, char *key, char *value)
+void param_limit_implications(struct expression *expr, int param, char *key, char *value, struct stree **implied)
{
- struct expression *arg;
+ struct expression *orig_expr, *arg;
struct symbol *compare_type;
char *name;
struct symbol *sym;
@@ -964,10 +1018,14 @@ void param_limit_implications(struct expression *expr, int param, char *key, cha
struct stree *implied_true = NULL;
struct stree *implied_false = NULL;
struct range_list *orig, *limit;
+ char *left_name = NULL;
+ struct symbol *left_sym = NULL;
+ int mixed = 0;
if (time_parsing_function() > 40)
return;
+ orig_expr = expr;
while (expr->type == EXPR_ASSIGNMENT)
expr = strip_expr(expr->right);
if (expr->type != EXPR_CALL)
@@ -999,9 +1057,25 @@ void param_limit_implications(struct expression *expr, int param, char *key, cha
call_results_to_rl(expr, compare_type, value, &limit);
- separate_and_filter(sm, SPECIAL_EQUAL, limit, __get_cur_stree(), &implied_true, &implied_false, NULL);
+ separate_and_filter(sm, PARAM_LIMIT, limit, __get_cur_stree(), &implied_true, &implied_false, &mixed);
+
+ if (orig_expr->type == EXPR_ASSIGNMENT)
+ left_name = expr_to_var_sym(orig_expr->left, &left_sym);
FOR_EACH_SM(implied_true, tmp) {
+ /*
+ * What we're trying to do here is preserve the sm state so that
+ * smatch extra doesn't create a new sm state when it parses the
+ * PARAM_LIMIT.
+ */
+ if (!mixed && tmp->sym == sym &&
+ strcmp(tmp->name, name) == 0 &&
+ (!left_name || strcmp(left_name, name) != 0)) {
+ overwrite_sm_state_stree(implied, tmp);
+ continue;
+ }
+
+ // TODO why can't this just be __set_sm()?
__set_sm_fake_stree(tmp);
} END_FOR_EACH_SM(tmp);
diff --git a/usr/src/tools/smatch/src/smatch_kernel_user_data.c b/usr/src/tools/smatch/src/smatch_kernel_user_data.c
index cda3b58d9d..0ed3a84577 100644
--- a/usr/src/tools/smatch/src/smatch_kernel_user_data.c
+++ b/usr/src/tools/smatch/src/smatch_kernel_user_data.c
@@ -1067,21 +1067,6 @@ static void match_call_info(struct expression *expr)
} END_FOR_EACH_PTR(arg);
}
-static int is_struct_ptr(struct symbol *sym)
-{
- struct symbol *type;
-
- if (!sym)
- return 0;
- type = get_real_base_type(sym);
- if (!type || type->type != SYM_PTR)
- return 0;
- type = get_real_base_type(type);
- if (!type || type->type != SYM_STRUCT)
- return 0;
- return 1;
-}
-
static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
{
struct smatch_state *state;
diff --git a/usr/src/tools/smatch/src/smatch_math.c b/usr/src/tools/smatch/src/smatch_math.c
index e6e033172f..bfb698e67c 100644
--- a/usr/src/tools/smatch/src/smatch_math.c
+++ b/usr/src/tools/smatch/src/smatch_math.c
@@ -335,6 +335,27 @@ static int handle_offset_subtraction(struct expression *expr)
return left_offset - right_offset;
}
+static bool max_is_unknown_max(struct range_list *rl)
+{
+ /*
+ * The issue with this code is that we had:
+ * if (foo > 1) return 1 - foo;
+ * Ideally we would say that returns s32min-(-1) but what Smatch
+ * was saying was that the lowest possible value was "1 - INT_MAX"
+ *
+ * My solution is to ignore max values for int or larger. I keep
+ * the max for shorts etc, because those might be worthwhile.
+ *
+ * The problem with just returning 1 - INT_MAX is that that is
+ * treated as useful information but s32min is treated as basically
+ * unknown.
+ */
+
+ if (type_bits(rl_type(rl)) < 31)
+ return false;
+ return sval_is_max(rl_max(rl));
+}
+
static bool handle_subtract_rl(struct expression *expr, int implied, int *recurse_cnt, struct range_list **res)
{
struct symbol *type;
@@ -409,7 +430,8 @@ static bool handle_subtract_rl(struct expression *expr, int implied, int *recurs
return true;
}
- if (!sval_binop_overflows(rl_min(left_rl), '-', rl_max(right_rl))) {
+ if (!max_is_unknown_max(right_rl) &&
+ !sval_binop_overflows(rl_min(left_rl), '-', rl_max(right_rl))) {
tmp = sval_binop(rl_min(left_rl), '-', rl_max(right_rl));
if (sval_cmp(tmp, min) > 0)
min = tmp;
@@ -1215,7 +1237,7 @@ static bool handle_call_rl(struct expression *expr, int implied, int *recurse_cn
if (sym_name_is("strlen", expr->fn))
return handle_strlen(expr, implied, recurse_cnt, res, res_sval);
- if (implied == RL_EXACT || implied == RL_HARD || implied == RL_FUZZY)
+ if (implied == RL_EXACT || implied == RL_HARD)
return false;
if (custom_handle_variable) {
diff --git a/usr/src/tools/smatch/src/smatch_mtag.c b/usr/src/tools/smatch/src/smatch_mtag.c
index 607ede688b..fc20107140 100644
--- a/usr/src/tools/smatch/src/smatch_mtag.c
+++ b/usr/src/tools/smatch/src/smatch_mtag.c
@@ -68,42 +68,64 @@ mtag_t str_to_mtag(const char *str)
return *tag;
}
-const struct {
- const char *name;
- int size_arg;
-} allocator_info[] = {
- { "kmalloc", 0 },
- { "kzalloc", 0 },
- { "devm_kmalloc", 1},
- { "devm_kzalloc", 1},
-};
-
-static bool is_mtag_call(struct expression *expr)
+static int save_allocator(void *_allocator, int argc, char **argv, char **azColName)
+{
+ char **allocator = _allocator;
+
+ if (*allocator) {
+ if (strcmp(*allocator, argv[0]) == 0)
+ return 0;
+ /* should be impossible */
+ free_string(*allocator);
+ *allocator = alloc_string("unknown");
+ return 0;
+ }
+ *allocator = alloc_string(argv[0]);
+ return 0;
+}
+
+char *get_allocator_info_from_tag(mtag_t tag)
+{
+ char *allocator = NULL;
+
+ run_sql(save_allocator, &allocator,
+ "select value from mtag_info where tag = %lld and type = %d;",
+ tag, ALLOCATOR);
+
+ return allocator;
+}
+
+static char *get_allocator_info(struct expression *expr, struct smatch_state *state)
{
- struct expression *arg;
- int i;
sval_t sval;
+ if (expr->type != EXPR_ASSIGNMENT)
+ return NULL;
+ if (estate_get_single_value(state, &sval))
+ return get_allocator_info_from_tag(sval.value);
+
+ expr = strip_expr(expr->right);
if (expr->type != EXPR_CALL ||
- expr->fn->type != EXPR_SYMBOL ||
- !expr->fn->symbol)
- return false;
+ !expr->fn ||
+ expr->fn->type != EXPR_SYMBOL)
+ return NULL;
+ return expr_to_str(expr->fn);
+}
- for (i = 0; i < ARRAY_SIZE(allocator_info); i++) {
- if (strcmp(expr->fn->symbol->ident->name, allocator_info[i].name) == 0)
- break;
- }
- if (i == ARRAY_SIZE(allocator_info))
- return false;
+static void update_mtag_info(struct expression *expr, mtag_t tag,
+ const char *left_name, const char *tag_info,
+ struct smatch_state *state)
+{
+ char *allocator;
- arg = get_argument_from_call_expr(expr->args, allocator_info[i].size_arg);
- if (!get_implied_value(arg, &sval))
- return false;
+ sql_insert_mtag_about(tag, left_name, tag_info);
- return true;
+ allocator = get_allocator_info(expr, state);
+ if (allocator)
+ sql_insert_mtag_info(tag, ALLOCATOR, allocator);
}
-struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_state *state)
+struct smatch_state *get_mtag_return(struct expression *expr, struct smatch_state *state)
{
struct expression *left, *right;
char *left_name, *right_name;
@@ -114,20 +136,18 @@ struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_sta
sval_t tag_sval;
if (!expr || expr->type != EXPR_ASSIGNMENT || expr->op != '=')
- return state;
-
- if (!estate_rl(state) || strcmp(state->name, "0,4096-ptr_max") != 0)
- return state;
+ return NULL;
+ if (!is_fresh_alloc(expr->right))
+ return NULL;
+ if (!rl_intersection(estate_rl(state), valid_ptr_rl))
+ return NULL;
left = strip_expr(expr->left);
right = strip_expr(expr->right);
- if (!is_mtag_call(right))
- return state;
-
left_name = expr_to_str_sym(left, &left_sym);
if (!left_name || !left_sym)
- return state;
+ return NULL;
right_name = expr_to_str(right);
snprintf(buf, sizeof(buf), "%s %s %s %s", get_filename(), get_function(),
@@ -140,7 +160,7 @@ struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_sta
rl = clone_rl(rl);
add_range(&rl, tag_sval, tag_sval);
- sql_insert_mtag_about(tag, left_name, buf);
+ update_mtag_info(expr, tag, left_name, buf, state);
free_string(left_name);
free_string(right_name);
diff --git a/usr/src/tools/smatch/src/smatch_mtag_data.c b/usr/src/tools/smatch/src/smatch_mtag_data.c
index c18a2e9725..7c690bb95b 100644
--- a/usr/src/tools/smatch/src/smatch_mtag_data.c
+++ b/usr/src/tools/smatch/src/smatch_mtag_data.c
@@ -81,8 +81,47 @@ static bool is_ignored_macro(struct expression *expr)
return false;
}
+static bool is_head_next(struct expression *expr)
+{
+ struct symbol *type;
+
+ /* Smatch thinks head->next == head is always true. *sad face* */
+
+ if (option_project != PROJ_KERNEL)
+ return false;
+
+ if (expr->type != EXPR_DEREF)
+ return false;
+ if (!expr->member || !expr->member->name ||
+ strcmp(expr->member->name, "next") != 0)
+ return false;
+
+ type = get_type(expr->deref);
+ if (!type)
+ return false;
+ if (type->type == SYM_PTR)
+ type = get_real_base_type(type);
+ if (type->type != SYM_STRUCT)
+ return false;
+ if (!type->ident || !type->ident->name ||
+ strcmp(type->ident->name, "list_head") != 0)
+ return false;
+ return true;
+}
+
+mtag_t ignored_mtag;
+static bool is_ignored_tag(mtag_t tag)
+{
+ if (tag == ignored_mtag)
+ return true;
+ return false;
+}
+
static void insert_mtag_data(mtag_t tag, int offset, struct range_list *rl)
{
+ if (is_ignored_tag(tag))
+ return;
+
rl = clone_rl_permanent(rl);
mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",
@@ -104,6 +143,16 @@ static bool invalid_type(struct symbol *type)
return false;
}
+static bool parent_is_fresh_alloc(struct expression *expr)
+{
+ struct symbol *sym;
+
+ sym = expr_to_sym(expr);
+ if (!sym || !sym->ident)
+ return false;
+ return is_fresh_alloc_var_sym(sym->ident->name, sym);
+}
+
void update_mtag_data(struct expression *expr, struct smatch_state *state)
{
struct range_list *orig, *new;
@@ -118,6 +167,8 @@ void update_mtag_data(struct expression *expr, struct smatch_state *state)
return;
if (is_ignored_macro(expr))
return;
+ if (is_head_next(expr))
+ return;
name = expr_to_var(expr);
if (is_kernel_param(name)) {
free_string(name);
@@ -132,7 +183,10 @@ void update_mtag_data(struct expression *expr, struct smatch_state *state)
if (offset == 0 && invalid_type(type))
return;
- orig = select_orig(tag, offset);
+ if (parent_is_fresh_alloc(expr))
+ orig = NULL;
+ else
+ orig = select_orig(tag, offset);
new = rl_union(orig, estate_rl(state));
insert_mtag_data(tag, offset, new);
}
@@ -146,6 +200,8 @@ static void match_global_assign(struct expression *expr)
if (is_ignored_macro(expr))
return;
+ if (is_head_next(expr->left))
+ return;
name = expr_to_var(expr->left);
if (is_kernel_param(name)) {
free_string(name);
@@ -278,6 +334,7 @@ void register_mtag_data(int id)
{
my_id = id;
+ ignored_mtag = str_to_mtag("extern boot_params");
add_hook(&clear_cache, FUNC_DEF_HOOK);
// if (!option_info)
diff --git a/usr/src/tools/smatch/src/smatch_mtag_map.c b/usr/src/tools/smatch/src/smatch_mtag_map.c
index 4ca0e00c08..5e3fab9ad1 100644
--- a/usr/src/tools/smatch/src/smatch_mtag_map.c
+++ b/usr/src/tools/smatch/src/smatch_mtag_map.c
@@ -29,8 +29,8 @@ static int my_id;
static void match_assign(struct expression *expr)
{
struct expression *left, *right;
- mtag_t left_tag;
- int offset;
+ mtag_t right_tag, left_tag;
+ int right_offset, left_offset;
sval_t sval;
if (expr->op != '=')
@@ -46,13 +46,14 @@ static void match_assign(struct expression *expr)
if (sval_cmp(sval, valid_ptr_min_sval) < 0 ||
sval_cmp(sval, valid_ptr_max_sval) > 0)
return;
- if (sval.uvalue & MTAG_OFFSET_MASK)
- return;
+ right_tag = sval.uvalue & ~MTAG_OFFSET_MASK;
+ right_offset = sval.uvalue & MTAG_OFFSET_MASK;
- if (!expr_to_mtag_offset(left, &left_tag, &offset))
+ if (!expr_to_mtag_offset(left, &left_tag, &left_offset) ||
+ left_offset >= MTAG_OFFSET_MASK)
return;
- sql_insert_mtag_map(sval.uvalue, -offset, left_tag);
+ sql_insert_mtag_map(left_tag, left_offset, right_tag, right_offset);
}
void register_mtag_map(int id)
diff --git a/usr/src/tools/smatch/src/smatch_param_to_mtag_data.c b/usr/src/tools/smatch/src/smatch_param_to_mtag_data.c
index cd50dc7554..454c512e9c 100644
--- a/usr/src/tools/smatch/src/smatch_param_to_mtag_data.c
+++ b/usr/src/tools/smatch/src/smatch_param_to_mtag_data.c
@@ -156,8 +156,9 @@ static void assign_to_alias(struct expression *expr, int param, mtag_t tag, int
// insert_mtag_data(alias, offset, rl);
// FIXME: is arg_offset handled correctly?
- if (expr_to_mtag_offset(gen_expr, &arg_tag, &arg_offset) && arg_offset == 0)
- sql_insert_mtag_map(arg_tag, -offset, alias);
+ if (expr_to_mtag_offset(gen_expr, &arg_tag, &arg_offset) &&
+ arg_offset < MTAG_OFFSET_MASK)
+ sql_insert_mtag_map(alias, offset, arg_tag, arg_offset);
}
static void call_does_mtag_assign(struct expression *expr, int param, char *key, char *value)
diff --git a/usr/src/tools/smatch/src/smatch_real_absolute.c b/usr/src/tools/smatch/src/smatch_real_absolute.c
index 3d98ee6356..8ea60bfba5 100644
--- a/usr/src/tools/smatch/src/smatch_real_absolute.c
+++ b/usr/src/tools/smatch/src/smatch_real_absolute.c
@@ -36,6 +36,11 @@
static int my_id;
+void set_real_absolute(struct expression *expr, struct smatch_state *state)
+{
+ set_state_expr(my_id, expr, clone_estate(state));
+}
+
static void extra_mod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
{
struct smatch_state *abs;
diff --git a/usr/src/tools/smatch/src/smatch_return_to_param.c b/usr/src/tools/smatch/src/smatch_return_to_param.c
index ec8e3a9cc5..9d9d777ffa 100644
--- a/usr/src/tools/smatch/src/smatch_return_to_param.c
+++ b/usr/src/tools/smatch/src/smatch_return_to_param.c
@@ -28,7 +28,6 @@
#include "smatch_slist.h"
#include "smatch_extra.h"
-extern int check_assigned_expr_id;
static int my_id;
static int link_id;
diff --git a/usr/src/tools/smatch/src/smatch_scripts/build_kernel_data.sh b/usr/src/tools/smatch/src/smatch_scripts/build_kernel_data.sh
index 1dd9616688..4fdf9ab0f8 100755
--- a/usr/src/tools/smatch/src/smatch_scripts/build_kernel_data.sh
+++ b/usr/src/tools/smatch/src/smatch_scripts/build_kernel_data.sh
@@ -37,6 +37,7 @@ fi
BUILD_STATUS=0
$SCRIPT_DIR/test_kernel.sh --call-tree --info --spammy --data=$DATA_DIR || BUILD_STATUS=$?
+echo "smatch_warns.txt built."
for i in $SCRIPT_DIR/gen_* ; do
$i smatch_warns.txt -p=kernel
diff --git a/usr/src/tools/smatch/src/smatch_scripts/summarize_errs.sh b/usr/src/tools/smatch/src/smatch_scripts/summarize_errs.sh
index 58cf82201f..4c1fe031be 100755
--- a/usr/src/tools/smatch/src/smatch_scripts/summarize_errs.sh
+++ b/usr/src/tools/smatch/src/smatch_scripts/summarize_errs.sh
@@ -29,7 +29,7 @@ save_thoughts()
read ans
if echo $ans | grep ^$ > /dev/null ; then
return
- fi
+ fi
#store the result
echo $sm_err >> summary
@@ -76,7 +76,7 @@ for sm_err in $TXT ; do
set_title $sm_err
- #grep -A1 "$file $line" *summary* 2> /dev/null
+ #grep -A1 "$file $line" *summary* 2> /dev/null
grep -A1 -F "$last" *summary* 2> /dev/null
ans="?"
@@ -102,5 +102,5 @@ for sm_err in $TXT ; do
vim $file +${line}
save_thoughts
-done
+done
IFS=
diff --git a/usr/src/tools/smatch/src/smatch_slist.c b/usr/src/tools/smatch/src/smatch_slist.c
index c95133f282..cdee9bcfe1 100644
--- a/usr/src/tools/smatch/src/smatch_slist.c
+++ b/usr/src/tools/smatch/src/smatch_slist.c
@@ -456,6 +456,9 @@ struct sm_state *merge_sm_states(struct sm_state *one, struct sm_state *two)
struct sm_state *result;
static int warned;
+ if (one->state->data && !has_dynamic_states(one->owner))
+ sm_msg("dynamic state: %s", show_sm(one));
+
if (one == two)
return one;
if (out_of_memory()) {
diff --git a/usr/src/tools/smatch/src/smatch_states.c b/usr/src/tools/smatch/src/smatch_states.c
index 7ae8f4a02b..f099b30307 100644
--- a/usr/src/tools/smatch/src/smatch_states.c
+++ b/usr/src/tools/smatch/src/smatch_states.c
@@ -74,6 +74,24 @@ void __print_cur_stree(void)
__print_stree(cur_stree);
}
+bool __print_states(const char *owner)
+{
+ struct sm_state *sm;
+ bool found = false;
+
+ if (!owner)
+ return false;
+
+ FOR_EACH_SM(__get_cur_stree(), sm) {
+ if (!strstr(check_name(sm->owner), owner))
+ continue;
+ sm_msg("%s", show_sm(sm));
+ found = true;
+ } END_FOR_EACH_SM(sm);
+
+ return found;
+}
+
int unreachable(void)
{
if (!cur_stree)
@@ -91,6 +109,45 @@ void __set_cur_stree_writable(void)
read_only--;
}
+DECLARE_PTR_LIST(check_tracker_list, check_tracker_hook *);
+static struct check_tracker_list **tracker_hooks;
+
+void add_check_tracker(const char *check_name, check_tracker_hook *fn)
+{
+ check_tracker_hook **p;
+ int owner;
+
+ owner = id_from_name(check_name);
+ if (!owner) {
+ printf("check not found. '%s'\n", check_name);
+ return;
+ }
+
+ p = malloc(sizeof(check_tracker_hook *));
+ *p = fn;
+ add_ptr_list(&tracker_hooks[owner], p);
+}
+
+static void call_tracker_hooks(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
+{
+ struct check_tracker_list *hooks;
+ check_tracker_hook **fn;
+
+ if ((unsigned short)owner == USHRT_MAX)
+ return;
+
+ hooks = tracker_hooks[owner];
+ FOR_EACH_PTR(hooks, fn) {
+ (*fn)(owner, name, sym, state);
+ } END_FOR_EACH_PTR(fn);
+}
+
+void allocate_tracker_array(int num_checks)
+{
+ tracker_hooks = malloc(num_checks * sizeof(void *));
+ memset(tracker_hooks, 0, num_checks * sizeof(void *));
+}
+
struct sm_state *set_state(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
{
struct sm_state *ret;
@@ -114,6 +171,8 @@ struct sm_state *set_state(int owner, const char *name, struct symbol *sym, stru
show_state(state));
}
+ call_tracker_hooks(owner, name, sym, state);
+
if (owner != -1 && unreachable())
return NULL;
diff --git a/usr/src/tools/smatch/src/smatch_struct_assignment.c b/usr/src/tools/smatch/src/smatch_struct_assignment.c
index 2670eca445..d82122018e 100644
--- a/usr/src/tools/smatch/src/smatch_struct_assignment.c
+++ b/usr/src/tools/smatch/src/smatch_struct_assignment.c
@@ -151,6 +151,9 @@ static void handle_non_struct_assignments(struct expression *left, struct expres
struct symbol *type;
struct expression *assign;
+ while (right && right->type == EXPR_ASSIGNMENT)
+ right = strip_parens(right->left);
+
type = get_type(left);
if (!type)
return;
@@ -234,7 +237,6 @@ static void __struct_members_copy(int mode, struct expression *faked,
struct expression *assign;
int op = '.';
-
if (__in_fake_assign)
return;
faked_expression = faked;
@@ -242,6 +244,9 @@ static void __struct_members_copy(int mode, struct expression *faked,
left = strip_expr(left);
right = strip_expr(right);
+ if (left->type == EXPR_PREOP && left->op == '*' && is_pointer(left))
+ left = preop_expression(left, '(');
+
struct_type = get_struct_type(left);
if (!struct_type) {
/*
diff --git a/usr/src/tools/smatch/src/smatch_type.c b/usr/src/tools/smatch/src/smatch_type.c
index be54ced235..c1cc6df19f 100644
--- a/usr/src/tools/smatch/src/smatch_type.c
+++ b/usr/src/tools/smatch/src/smatch_type.c
@@ -551,6 +551,16 @@ int is_string(struct expression *expr)
return 0;
}
+bool is_struct_ptr(struct symbol *type)
+{
+ if (!type || type->type != SYM_PTR)
+ return false;
+ type = get_real_base_type(type);
+ if (!type || type->type != SYM_STRUCT)
+ return false;
+ return true;
+}
+
int is_static(struct expression *expr)
{
char *name;
@@ -595,6 +605,23 @@ int types_equiv(struct symbol *one, struct symbol *two)
return 1;
}
+bool type_fits(struct symbol *type, struct symbol *test)
+{
+ if (!type || !test)
+ return false;
+
+ if (type == test)
+ return true;
+
+ if (type_bits(test) > type_bits(type))
+ return false;
+ if (type_signed(test) && !type_signed(type))
+ return false;
+ if (type_positive_bits(test) > type_positive_bits(type))
+ return false;
+ return true;
+}
+
int fn_static(void)
{
return !!(cur_func_sym->ctype.modifiers & MOD_STATIC);
@@ -685,6 +712,8 @@ static struct symbol *get_member_from_string(struct symbol_list *symbol_list, co
struct symbol *get_member_type_from_key(struct expression *expr, const char *key)
{
struct symbol *sym;
+ int star = 0;
+ int i;
if (strcmp(key, "$") == 0)
return get_type(expr);
@@ -702,11 +731,26 @@ struct symbol *get_member_type_from_key(struct expression *expr, const char *key
if (sym->type == SYM_PTR)
sym = get_real_base_type(sym);
- key = key + 1;
+ while (*key == '*') {
+ key++;
+ star++;
+ }
+
+ if (*key != '$')
+ return NULL;
+ key++;
+
sym = get_member_from_string(sym->symbol_list, key);
if (!sym)
return NULL;
- return get_real_base_type(sym);
+ if (sym->type == SYM_RESTRICT || sym->type == SYM_NODE)
+ sym = get_real_base_type(sym);
+ for (i = 0; i < star; i++) {
+ if (!sym || sym->type != SYM_PTR)
+ return NULL;
+ sym = get_real_base_type(sym);
+ }
+ return sym;
}
struct symbol *get_arg_type_from_key(struct expression *fn, int param, struct expression *arg, const char *key)
diff --git a/usr/src/tools/smatch/src/smatch_type_val.c b/usr/src/tools/smatch/src/smatch_type_val.c
index 16445eccdb..3c9f649272 100644
--- a/usr/src/tools/smatch/src/smatch_type_val.c
+++ b/usr/src/tools/smatch/src/smatch_type_val.c
@@ -337,6 +337,8 @@ static int is_ignored_function(void)
return 1;
if (sym_name_is("i2c_get_clientdata", expr->fn))
return 1;
+ if (sym_name_is("idr_find", expr->fn))
+ return 1;
return 0;
}
diff --git a/usr/src/tools/smatch/src/token.h b/usr/src/tools/smatch/src/token.h
index 88f60db597..55f922f4ab 100644
--- a/usr/src/tools/smatch/src/token.h
+++ b/usr/src/tools/smatch/src/token.h
@@ -218,6 +218,7 @@ extern struct token eof_token_entry;
extern int init_stream(const char *, int fd, const char **next_path);
extern const char *stream_name(int stream);
+struct ident *alloc_ident(const char *name, int len);
extern struct ident *hash_ident(struct ident *);
extern struct ident *built_in_ident(const char *);
extern struct token *built_in_token(int, struct ident *);
diff --git a/usr/src/tools/smatch/src/tokenize.c b/usr/src/tools/smatch/src/tokenize.c
index aefd333b48..0021fa7049 100644
--- a/usr/src/tools/smatch/src/tokenize.c
+++ b/usr/src/tools/smatch/src/tokenize.c
@@ -829,7 +829,7 @@ void show_identifier_stats(void)
}
}
-static struct ident *alloc_ident(const char *name, int len)
+struct ident *alloc_ident(const char *name, int len)
{
struct ident *ident = __alloc_ident(len);
ident->symbols = NULL;
diff --git a/usr/src/tools/smatch/src/validation/sm_impossible1.c b/usr/src/tools/smatch/src/validation/sm_impossible1.c
index a81cbcd0a8..cc06a496cf 100644
--- a/usr/src/tools/smatch/src/validation/sm_impossible1.c
+++ b/usr/src/tools/smatch/src/validation/sm_impossible1.c
@@ -19,7 +19,7 @@ int main(unsigned int x, unsigned int y)
* check-command: smatch -I.. sm_impossible1.c
*
* check-output-start
-sm_impossible1.c:12 main() [register_impossible_return] 'impossible' = 'impossible'
+sm_impossible1.c:12 main() [register_impossible_return] impossible = 'impossible'
sm_impossible1.c:14 main() register_impossible_return: no states
* check-output-end
*/
diff --git a/usr/src/tools/smatch/src/validation/sm_impossible2.c b/usr/src/tools/smatch/src/validation/sm_impossible2.c
index 905bec5f46..1893ba5e83 100644
--- a/usr/src/tools/smatch/src/validation/sm_impossible2.c
+++ b/usr/src/tools/smatch/src/validation/sm_impossible2.c
@@ -20,6 +20,6 @@ int main(unsigned int x, unsigned int y)
*
* check-output-start
sm_impossible2.c:12 main() register_impossible_return: no states
-sm_impossible2.c:14 main() [register_impossible_return] 'impossible' = 'impossible'
+sm_impossible2.c:14 main() [register_impossible_return] impossible = 'impossible'
* check-output-end
*/
diff --git a/usr/src/uts/sun4u/ics951601/Makefile b/usr/src/uts/sun4u/ics951601/Makefile
index eb6443593c..aa6de449e8 100644
--- a/usr/src/uts/sun4u/ics951601/Makefile
+++ b/usr/src/uts/sun4u/ics951601/Makefile
@@ -23,8 +23,6 @@
# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# This makefile drives the ics951601 build.
#
# Path to the base of the uts directory tree (usually /usr/src/uts).
@@ -36,7 +34,6 @@ UTSBASE = ../..
#
MODULE = ics951601
OBJECTS = $(ICS951601_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(ICS951601_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
@@ -44,18 +41,12 @@ ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
include $(UTSBASE)/sun4u/Makefile.sun4u
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
LDFLAGS += -dy -N misc/i2c_svc
#
# Define targets
#
ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
.KEEP_STATE:
@@ -68,12 +59,6 @@ clean: $(CLEAN_DEPS)
clobber: $(CLOBBER_DEPS)
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
install: $(INSTALL_DEPS)
#
diff --git a/usr/src/uts/sun4u/io/i2c/clients/ics951601.c b/usr/src/uts/sun4u/io/i2c/clients/ics951601.c
index 5ed6a41b49..6d316c574a 100644
--- a/usr/src/uts/sun4u/io/i2c/clients/ics951601.c
+++ b/usr/src/uts/sun4u/io/i2c/clients/ics951601.c
@@ -222,10 +222,10 @@ ics951601_close(dev_t dev, int flags, int otyp, cred_t *credp)
_NOTE(ARGUNUSED(flags, credp))
int instance;
- ics951601_unit_t *icsp;
+ ics951601_unit_t *icsp;
/*
- * Make sure the close is for the right file type
+ * Make sure the close is for the right file type
*/
if (otyp != OTYP_CHR) {
return (EINVAL);
@@ -247,8 +247,8 @@ ics951601_close(dev_t dev, int flags, int otyp, cred_t *credp)
static int
ics951601_attach(dev_info_t *dip)
{
- ics951601_unit_t *icsp;
- int instance = ddi_get_instance(dip);
+ ics951601_unit_t *icsp;
+ int instance = ddi_get_instance(dip);
if (ddi_soft_state_zalloc(ics951601_soft_statep, instance) != 0) {
cmn_err(CE_WARN, "%s%d failed to zalloc softstate",
@@ -270,7 +270,7 @@ ics951601_attach(dev_info_t *dip)
if (ddi_create_minor_node(dip, icsp->ics951601_name, S_IFCHR,
- instance, ICS951601_NODE_TYPE, NULL) == DDI_FAILURE) {
+ instance, ICS951601_NODE_TYPE, 0) == DDI_FAILURE) {
cmn_err(CE_WARN, "%s ddi_create_minor_node failed",
icsp->ics951601_name);
goto ATTACH_ERR;
@@ -333,7 +333,7 @@ static void
ics951601_detach(dev_info_t *dip)
{
ics951601_unit_t *icsp;
- int instance;
+ int instance;
instance = ddi_get_instance(dip);
icsp = ddi_get_soft_state(ics951601_soft_statep, instance);
@@ -374,7 +374,7 @@ ics951601_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
static int
ics951601_suspend(dev_info_t *dip)
{
- ics951601_unit_t *icsp;
+ ics951601_unit_t *icsp;
int instance = ddi_get_instance(dip);
icsp = ddi_get_soft_state(ics951601_soft_statep, instance);
@@ -413,9 +413,9 @@ ics951601_suspend(dev_info_t *dip)
static int
ics951601_resume(dev_info_t *dip)
{
- int instance = ddi_get_instance(dip);
+ int instance = ddi_get_instance(dip);
ics951601_unit_t *icsp;
- int err = DDI_SUCCESS;
+ int err = DDI_SUCCESS;
icsp = (ics951601_unit_t *)
ddi_get_soft_state(ics951601_soft_statep, instance);
@@ -479,7 +479,7 @@ ics951601_s_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
static int
ics951601_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
- int *rvalp)
+ int *rvalp)
{
_NOTE(ARGUNUSED(credp, rvalp))
diff --git a/usr/src/uts/sun4u/io/i2c/clients/pca9556.c b/usr/src/uts/sun4u/io/i2c/clients/pca9556.c
index 1b972ca6d7..7fe812e0ac 100644
--- a/usr/src/uts/sun4u/io/i2c/clients/pca9556.c
+++ b/usr/src/uts/sun4u/io/i2c/clients/pca9556.c
@@ -177,9 +177,9 @@ _info(struct modinfo *modinfop)
static int
pca9556_resume(dev_info_t *dip)
{
- int instance = ddi_get_instance(dip);
+ int instance = ddi_get_instance(dip);
pca9556_unit_t *pcap;
- int err = DDI_SUCCESS;
+ int err = DDI_SUCCESS;
int reg_offset, num_of_ports;
int i, j;
uint8_t reg, reg_num = 0;
@@ -257,7 +257,7 @@ static void
pca9556_detach(dev_info_t *dip)
{
pca9556_unit_t *pcap;
- int instance = ddi_get_instance(dip);
+ int instance = ddi_get_instance(dip);
pcap = ddi_get_soft_state(pca9556_soft_statep, instance);
@@ -279,11 +279,11 @@ pca9556_detach(dev_info_t *dip)
static int
pca9556_attach(dev_info_t *dip)
{
- pca9556_unit_t *pcap;
- int instance = ddi_get_instance(dip);
+ pca9556_unit_t *pcap;
+ int instance = ddi_get_instance(dip);
char name[MAXNAMELEN];
char *device_name;
- minor_t minor;
+ minor_t minor;
int i, num_ports;
if (ddi_soft_state_zalloc(pca9556_soft_statep, instance) != 0) {
@@ -328,7 +328,7 @@ pca9556_attach(dev_info_t *dip)
}
if (ddi_create_minor_node(dip, name, S_IFCHR, minor,
- PCA9556_NODE_TYPE, NULL) == DDI_FAILURE) {
+ PCA9556_NODE_TYPE, 0) == DDI_FAILURE) {
cmn_err(CE_WARN, "%s: failed to create node for %s",
pcap->pca9556_name, name);
pca9556_detach(dip);
@@ -414,8 +414,8 @@ pca9556_s_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
static int
pca9556_suspend(dev_info_t *dip)
{
- pca9556_unit_t *pcap;
- int instance = ddi_get_instance(dip);
+ pca9556_unit_t *pcap;
+ int instance = ddi_get_instance(dip);
int err = DDI_SUCCESS;
int reg_offset, num_of_ports;
int i, j;
@@ -574,7 +574,7 @@ static int
pca9556_close(dev_t dev, int flags, int otyp, cred_t *credp)
{
int instance;
- pca9556_unit_t *pcap;
+ pca9556_unit_t *pcap;
_NOTE(ARGUNUSED(flags, credp))
@@ -599,7 +599,7 @@ pca9556_close(dev_t dev, int flags, int otyp, cred_t *credp)
static int
pca9556_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
- int *rvalp)
+ int *rvalp)
{
pca9556_unit_t *pcap;
int err = 0;
diff --git a/usr/src/uts/sun4u/io/i2c/clients/seeprom.c b/usr/src/uts/sun4u/io/i2c/clients/seeprom.c
index 176051db4c..ece73f2863 100644
--- a/usr/src/uts/sun4u/io/i2c/clients/seeprom.c
+++ b/usr/src/uts/sun4u/io/i2c/clients/seeprom.c
@@ -167,7 +167,7 @@ seeprom_do_attach(dev_info_t *dip)
"%s%d", ddi_driver_name(dip), instance);
if (ddi_create_minor_node(dip, ddi_node_name(dip), S_IFCHR,
- instance, SEEPROM_NODE_TYPE, NULL) == DDI_FAILURE) {
+ instance, SEEPROM_NODE_TYPE, 0) == DDI_FAILURE) {
cmn_err(CE_WARN, "%s ddi_create_minor_node failed for '%s'",
unitp->seeprom_name, ddi_node_name(dip));
ddi_soft_state_free(seepromsoft_statep, instance);
diff --git a/usr/src/uts/sun4u/pca9556/Makefile b/usr/src/uts/sun4u/pca9556/Makefile
index 182a32f4e1..0ffc4a3320 100644
--- a/usr/src/uts/sun4u/pca9556/Makefile
+++ b/usr/src/uts/sun4u/pca9556/Makefile
@@ -34,7 +34,6 @@ UTSBASE = ../..
#
MODULE = pca9556
OBJECTS = $(PCA9556_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(PCA9556_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
@@ -42,27 +41,14 @@ ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
include $(UTSBASE)/sun4u/Makefile.sun4u
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
LDFLAGS += -dy -N misc/i2c_svc
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-
CERRWARN += $(CNOWARN_UNINIT)
#
# Define targets
#
ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
.KEEP_STATE:
@@ -75,12 +61,6 @@ clean: $(CLEAN_DEPS)
clobber: $(CLOBBER_DEPS)
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
install: $(INSTALL_DEPS)
#
diff --git a/usr/src/uts/sun4u/seeprom/Makefile b/usr/src/uts/sun4u/seeprom/Makefile
index 92b51e0417..b4d887a3bc 100644
--- a/usr/src/uts/sun4u/seeprom/Makefile
+++ b/usr/src/uts/sun4u/seeprom/Makefile
@@ -35,7 +35,6 @@ UTSBASE = ../..
#
MODULE = seeprom
OBJECTS = $(SEEPROM_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SEEPROM_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
@@ -43,27 +42,14 @@ ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
include $(UTSBASE)/sun4u/Makefile.sun4u
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
LDFLAGS += -dy -N misc/i2c_svc
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
-
CERRWARN += $(CNOWARN_UNINIT)
#
# Define targets
#
ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
.KEEP_STATE:
@@ -76,12 +62,6 @@ clean: $(CLEAN_DEPS)
clobber: $(CLOBBER_DEPS)
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
install: $(INSTALL_DEPS)
#