diff options
author | John Levon <john.levon@joyent.com> | 2020-01-22 16:05:13 -0800 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2020-02-03 07:14:33 -0800 |
commit | 31ad075e90bf5afda8ab4b8cc4d3ca3e89946115 (patch) | |
tree | e90e74541c7d3050613b2a614c184c572582223e | |
parent | 2d85dedb8eaa3ba69c85560030efe4cbc815efb8 (diff) | |
download | illumos-joyent-31ad075e90bf5afda8ab4b8cc4d3ca3e89946115.tar.gz |
12257 resync smatch to 0.6.1-rc1-il-4
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Approved by: Dan McDonald <danmcd@joyent.com>
21 files changed, 353 insertions, 171 deletions
diff --git a/usr/src/tools/smatch/Makefile b/usr/src/tools/smatch/Makefile index c8f3c74f78..902c874624 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-3 +SPARSE_VERSION = 0.6.1-rc1-il-4 include ../Makefile.tools @@ -123,6 +123,7 @@ SMATCH_OBJS += smatch_expression_stacks.o SMATCH_OBJS += smatch_extra.o SMATCH_OBJS += smatch_files.o SMATCH_OBJS += smatch_flow.o +SMATCH_OBJS += smatch_fresh_alloc.o SMATCH_OBJS += smatch_fn_arg_link.o SMATCH_OBJS += smatch_function_hooks.o SMATCH_OBJS += smatch_function_info.o diff --git a/usr/src/tools/smatch/src/Makefile b/usr/src/tools/smatch/src/Makefile index e9fb252972..bc8b3071a1 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-3 +VERSION=0.6.1-rc1-il-4 ######################################################################## # The following variables can be overwritten from the command line @@ -226,6 +226,7 @@ SMATCH_OBJS += smatch_extra.o SMATCH_OBJS += smatch_files.o SMATCH_OBJS += smatch_flow.o SMATCH_OBJS += smatch_fn_arg_link.o +SMATCH_OBJS += smatch_fresh_alloc.o SMATCH_OBJS += smatch_function_hooks.o SMATCH_OBJS += smatch_function_info.o SMATCH_OBJS += smatch_function_ptrs.o diff --git a/usr/src/tools/smatch/src/check_list.h b/usr/src/tools/smatch/src/check_list.h index b687018e48..1841676ce3 100644 --- a/usr/src/tools/smatch/src/check_list.h +++ b/usr/src/tools/smatch/src/check_list.h @@ -72,6 +72,7 @@ CK(register_array_values) CK(register_nul_terminator) CK(register_nul_terminator_param_set) CK(register_statement_count) +CK(register_fresh_alloc) CK(register_kernel_user_data) CK(register_kernel_user_data2) diff --git a/usr/src/tools/smatch/src/check_locking.c b/usr/src/tools/smatch/src/check_locking.c index 285a52cedf..9af6b46c46 100644 --- a/usr/src/tools/smatch/src/check_locking.c +++ b/usr/src/tools/smatch/src/check_locking.c @@ -1021,10 +1021,13 @@ static void check_lock(char *name, struct symbol *sym) if (parent_is_gone_var_sym(sm->name, sm->sym)) goto swap_stree; - if (sm->state != &locked && sm->state != &unlocked) + if (sm->state != &locked && + sm->state != &unlocked && + sm->state != &restore) goto swap_stree; - if (sm->state == &unlocked && is_EINTR(estate_rl(return_sm->state))) + if ((sm->state == &unlocked || sm->state == &restore) && + is_EINTR(estate_rl(return_sm->state))) goto swap_stree; bucket = success_fail_positive(estate_rl(return_sm->state)); @@ -1032,7 +1035,7 @@ static void check_lock(char *name, struct symbol *sym) add_range(&locked_lines, line, line); locked_buckets[bucket] = true; } - if (sm->state == &unlocked) { + if (sm->state == &unlocked || sm->state == &restore) { add_range(&unlocked_lines, line, line); unlocked_buckets[bucket] = true; } diff --git a/usr/src/tools/smatch/src/lib.c b/usr/src/tools/smatch/src/lib.c index bc80001d55..50241937b5 100644 --- a/usr/src/tools/smatch/src/lib.c +++ b/usr/src/tools/smatch/src/lib.c @@ -318,13 +318,7 @@ int funsigned_char = UNSIGNED_CHAR; int preprocess_only; -static enum { STANDARD_C89, - STANDARD_C94, - STANDARD_C99, - STANDARD_C11, - STANDARD_GNU11, - STANDARD_GNU89, - STANDARD_GNU99, } standard = STANDARD_GNU89; +enum standard standard = STANDARD_GNU89; int arch_m64 = ARCH_M64_DEFAULT; int arch_msize_long = 0; @@ -1313,6 +1307,8 @@ static void predefined_macros(void) if (optimize_size) predefine("__OPTIMIZE_SIZE__", 0, "1"); + predefine("__PRAGMA_REDEFINE_EXTNAME", 1, "1"); + // Temporary hacks predefine("__extension__", 0, NULL); predefine("__pragma__", 0, NULL); @@ -1326,7 +1322,6 @@ static void predefined_macros(void) break; case ARCH_LP64: predefine("__LP64__", 1, "1"); - predefine("__LP64", 1, "1"); predefine("_LP64", 1, "1"); break; case ARCH_LLP64: @@ -1389,32 +1384,38 @@ static void predefined_macros(void) case MACH_SPARC32: predefine("__sparc__", 1, "1"); predefine("__sparc", 1, "1"); + predefine_nostd("sparc"); break; case MACH_X86_64: if (arch_m64 != ARCH_LP32) { predefine("__x86_64__", 1, "1"); predefine("__x86_64", 1, "1"); + predefine("__amd64__", 1, "1"); + predefine("__amd64", 1, "1"); break; } /* fall-through */ case MACH_I386: predefine("__i386__", 1, "1"); predefine("__i386", 1, "1"); - predefine("i386", 1, "1"); + predefine_nostd("i386"); break; } - predefine("__PRAGMA_REDEFINE_EXTNAME", 1, "1"); - -#ifdef __sun +#if defined(__unix__) predefine("__unix__", 1, "1"); predefine("__unix", 1, "1"); - predefine("unix", 1, "1"); + predefine_nostd("unix"); +#endif + + +#if defined(__sun__) || defined(__sun) predefine("__sun__", 1, "1"); predefine("__sun", 1, "1"); - predefine("sun", 1, "1"); + predefine_nostd("sun"); predefine("__svr4__", 1, "1"); #endif + } static void create_builtin_stream(void) diff --git a/usr/src/tools/smatch/src/lib.h b/usr/src/tools/smatch/src/lib.h index de8f1132fa..70b2ba3928 100644 --- a/usr/src/tools/smatch/src/lib.h +++ b/usr/src/tools/smatch/src/lib.h @@ -134,6 +134,7 @@ enum phase { extern void add_pre_buffer(const char *fmt, ...) FORMAT_ATTR(1); extern void predefine(const char *name, int weak, const char *fmt, ...) FORMAT_ATTR(3); +extern void predefine_nostd(const char *name); extern int preprocess_only; @@ -206,6 +207,20 @@ extern int arch_msize_long; extern int arch_big_endian; extern int arch_mach; +enum standard { + STANDARD_NONE, + STANDARD_GNU, + STANDARD_C89, + STANDARD_GNU89 = STANDARD_C89 | STANDARD_GNU, + STANDARD_C94, + STANDARD_GNU94 = STANDARD_C94 | STANDARD_GNU, + STANDARD_C99, + STANDARD_GNU99 = STANDARD_C99 | STANDARD_GNU, + STANDARD_C11, + STANDARD_GNU11 = STANDARD_C11 | STANDARD_GNU, +}; +extern enum standard standard; + extern void dump_macro_definitions(void); extern struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **files); extern struct symbol_list *__sparse(char *filename); diff --git a/usr/src/tools/smatch/src/machine.h b/usr/src/tools/smatch/src/machine.h index b46383ac1d..af5c96f16f 100644 --- a/usr/src/tools/smatch/src/machine.h +++ b/usr/src/tools/smatch/src/machine.h @@ -62,7 +62,7 @@ enum machine { #define MACH_NATIVE MACH_RISCV64 #elif defined(__riscv) && (__riscv_xlen == 32) #define MACH_NATIVE MACH_RISCV32 -#elif defined(__sparc_v9__) +#elif defined(__sparc_v9__) || defined(__sparcv9) #define MACH_NATIVE MACH_SPARC64 #elif defined(__sparc__) || defined(__sparc) #define MACH_NATIVE MACH_SPARC32 diff --git a/usr/src/tools/smatch/src/pre-process.c b/usr/src/tools/smatch/src/pre-process.c index c35cbcfb3c..5a9313a358 100644 --- a/usr/src/tools/smatch/src/pre-process.c +++ b/usr/src/tools/smatch/src/pre-process.c @@ -1568,6 +1568,14 @@ void predefine(const char *name, int weak, const char *fmt, ...) do_define(value->pos, NULL, ident, NULL, value, attr); } +/// +// like predefine() but only if one of the non-standard dialect is chosen +void predefine_nostd(const char *name) +{ + if ((standard & STANDARD_GNU) || (standard == STANDARD_NONE)) + predefine(name, 1, "1"); +} + static int do_handle_define(struct stream *stream, struct token **line, struct token *token, int attr) { struct token *arglist, *expansion; diff --git a/usr/src/tools/smatch/src/smatch.h b/usr/src/tools/smatch/src/smatch.h index 062dffc9d2..6e0698085e 100644 --- a/usr/src/tools/smatch/src/smatch.h +++ b/usr/src/tools/smatch/src/smatch.h @@ -104,6 +104,12 @@ struct constraint { }; DECLARE_PTR_LIST(constraint_list, struct constraint); +struct alloc_info { + const char *fn; + int size_param, nr; +}; +extern struct alloc_info *alloc_funcs; + struct bit_info { unsigned long long set; unsigned long long possible; @@ -398,6 +404,7 @@ int sym_name_is(const char *name, struct expression *expr); int get_const_value(struct expression *expr, sval_t *sval); int get_value(struct expression *expr, sval_t *val); int get_implied_value(struct expression *expr, sval_t *val); +int get_implied_value_fast(struct expression *expr, sval_t *sval); int get_implied_min(struct expression *expr, sval_t *sval); int get_implied_max(struct expression *expr, sval_t *val); int get_hard_max(struct expression *expr, sval_t *sval); @@ -839,6 +846,7 @@ enum info_type { NOSPEC_WB = 1036, STMT_CNT = 1037, TERMINATED = 1038, + FRESH_ALLOC = 1044, /* put random temporary stuff in the 7000-7999 range for testing */ USER_DATA = 8017, @@ -1249,6 +1257,7 @@ int get_offset_from_container_of(struct expression *expr); char *get_container_name(struct expression *container, struct expression *expr); /* smatch_mtag.c */ +mtag_t str_to_mtag(const char *str); int get_string_mtag(struct expression *expr, mtag_t *tag); int get_toplevel_mtag(struct symbol *sym, mtag_t *tag); int create_mtag_alias(mtag_t tag, struct expression *expr, mtag_t *new); @@ -1278,6 +1287,8 @@ bool is_nul_terminated(struct expression *expr); /* check_kernel.c */ bool is_ignored_kernel_data(const char *name); +bool is_fresh_alloc_var_sym(const char *var, struct symbol *sym); +bool is_fresh_alloc(struct expression *expr); static inline bool type_is_ptr(struct symbol *type) { return type && diff --git a/usr/src/tools/smatch/src/smatch_container_of.c b/usr/src/tools/smatch/src/smatch_container_of.c index bd9039cf75..65d4a8d8ac 100644 --- a/usr/src/tools/smatch/src/smatch_container_of.c +++ b/usr/src/tools/smatch/src/smatch_container_of.c @@ -215,17 +215,17 @@ static char *get_stored_container_name(struct expression *container, return NULL; } -char *get_container_name(struct expression *container, struct expression *expr) +static char *get_container_name_helper(struct expression *container, struct expression *expr) { struct symbol *container_sym, *sym; - struct expression *tmp; static char buf[64]; char *ret, *shared; bool star; - int cnt; expr = strip_expr(expr); container = strip_expr(container); + if (!expr || !container) + return NULL; ret = get_stored_container_name(container, expr); if (ret) @@ -233,24 +233,10 @@ char *get_container_name(struct expression *container, struct expression *expr) sym = expr_to_sym(expr); container_sym = expr_to_sym(container); - if (sym && sym == container_sym) - goto found; - - cnt = 0; - while ((tmp = get_assigned_expr(container))) { - container = strip_expr(tmp); - if (cnt++ > 3) - break; - } - - cnt = 0; - while ((tmp = get_assigned_expr(expr))) { - expr = strip_expr(tmp); - if (cnt++ > 3) - break; - } - -found: + if (!sym || !container_sym) + return NULL; + if (sym != container_sym) + return NULL; if (container->type == EXPR_DEREF) star = true; @@ -262,13 +248,6 @@ found: if (expr->type == EXPR_PREOP && expr->op == '&') expr = strip_expr(expr->unop); - sym = expr_to_sym(expr); - if (!sym) - return NULL; - container_sym = expr_to_sym(container); - if (!container_sym || sym != container_sym) - return NULL; - shared = get_shared_str(expr, container); if (!shared) return NULL; @@ -280,6 +259,30 @@ found: return buf; } +char *get_container_name(struct expression *container, struct expression *expr) +{ + char *ret; + + ret = get_container_name_helper(container, expr); + if (ret) + return ret; + + ret = get_container_name_helper(get_assigned_expr(container), expr); + if (ret) + return ret; + + ret = get_container_name_helper(container, get_assigned_expr(expr)); + if (ret) + return ret; + + ret = get_container_name_helper(get_assigned_expr(container), + get_assigned_expr(expr)); + if (ret) + return ret; + + return NULL; +} + static bool is_fn_ptr(struct expression *expr) { struct symbol *type; diff --git a/usr/src/tools/smatch/src/smatch_db.c b/usr/src/tools/smatch/src/smatch_db.c index e932d315ab..70be64093d 100644 --- a/usr/src/tools/smatch/src/smatch_db.c +++ b/usr/src/tools/smatch/src/smatch_db.c @@ -768,16 +768,6 @@ static void match_call_marker(struct expression *expr) sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type)); } -static char *show_offset(int offset) -{ - static char buf[64]; - - buf[0] = '\0'; - if (offset != -1) - snprintf(buf, sizeof(buf), "(-%d)", offset); - return buf; -} - int is_recursive_member(const char *name) { char buf[256]; @@ -860,7 +850,7 @@ free: return ret; } -static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree, +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)) { struct sm_state *sm; @@ -902,23 +892,23 @@ static void print_struct_members(struct expression *call, struct expression *exp // FIXME: simplify? if (!add_star && strcmp(name, sm_name) == 0) { if (is_address) - snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset)); + snprintf(printed_name, sizeof(printed_name), "*$"); else /* these are already handled. fixme: handle them here */ continue; } else if (add_star && strcmp(name, sm_name) == 0) { - snprintf(printed_name, sizeof(printed_name), "%s*$%s", - is_address ? "*" : "", show_offset(offset)); + 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) snprintf(printed_name, sizeof(printed_name), - "%s$%s->%s", add_star ? "*" : "", - show_offset(offset), sm_name + len + 1); + "%s$->%s", add_star ? "*" : "", + sm_name + len + 1); else snprintf(printed_name, sizeof(printed_name), - "%s$%s%s", add_star ? "*" : "", - show_offset(offset), sm_name + len); + "%s$%s", add_star ? "*" : "", + sm_name + len); } else { continue; } @@ -930,67 +920,6 @@ free: free_string(name); } -static int param_used_callback(void *_container, int argc, char **argv, char **azColName) -{ - char **container = _container; - static char buf[256]; - - snprintf(buf, sizeof(buf), "%s", argv[0]); - *container = buf; - return 0; -} - -static void print_container_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)) -{ - struct expression *tmp; - char *container = NULL; - int offset; - int holder_offset; - char *p; - - if (!call->fn || call->fn->type != EXPR_SYMBOL || !call->fn->symbol) - return; - - /* - * We can't use the in-mem DB because we have to parse the function - * first, then we know if it takes a container, then we know to pass it - * the container data. - * - */ - run_sql(¶m_used_callback, &container, - "select key from return_implies where %s and type = %d and key like '%%$(%%' and parameter = %d limit 1;", - get_static_filter(call->fn->symbol), CONTAINER, param); - if (!container) - return; - - p = strchr(container, '-'); - if (!p) - return; - offset = atoi(p); - p = strchr(p, ')'); - if (!p) - return; - p++; - - tmp = get_assigned_expr(expr); - if (tmp) - expr = tmp; - - if (expr->type != EXPR_PREOP || expr->op != '&') - return; - expr = strip_expr(expr->unop); - holder_offset = get_member_offset_from_deref(expr); - if (-holder_offset != offset) - return; - - expr = strip_expr(expr->deref); - if (expr->type == EXPR_PREOP && expr->op == '*') - expr = strip_expr(expr->unop); - - print_struct_members(call, expr, param, holder_offset, stree, callback); -} - static void match_call_info(struct expression *call) { struct member_info_callback *cb; @@ -1007,8 +936,7 @@ 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, -1, stree, cb->callback); - print_container_struct_members(call, arg, i, stree, cb->callback); + print_struct_members(call, arg, i, stree, cb->callback); i++; } END_FOR_EACH_PTR(arg); free_stree(&stree); diff --git a/usr/src/tools/smatch/src/smatch_fresh_alloc.c b/usr/src/tools/smatch/src/smatch_fresh_alloc.c new file mode 100644 index 0000000000..d7104f6b53 --- /dev/null +++ b/usr/src/tools/smatch/src/smatch_fresh_alloc.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2019 Oracle. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt + */ + +/* + * There are a bunch of allocation functions where we allocate some memory, + * set up some struct members and then return the allocated memory. One + * nice thing about this is that we just one pointer to the allocated memory + * so what we can do is we can generate a mtag alias for it in the caller. + */ + +#include "smatch.h" +#include "smatch_slist.h" + +static int my_id; + +STATE(fresh); + +struct alloc_info *alloc_funcs; + +struct alloc_info kernel_allocation_funcs[] = { + {"kmalloc", 0}, + {"kmalloc_node", 0}, + {"kzalloc", 0}, + {"kzalloc_node", 0}, + {"vmalloc", 0}, + {"__vmalloc", 0}, + {"kvmalloc", 0}, + {"kcalloc", 0, 1}, + {"kmalloc_array", 0, 1}, + {"sock_kmalloc", 1}, + {"kmemdup", 1}, + {"kmemdup_user", 1}, + {"dma_alloc_attrs", 1}, + {"pci_alloc_consistent", 1}, + {"pci_alloc_coherent", 1}, + {"devm_kmalloc", 1}, + {"devm_kzalloc", 1}, + {"krealloc", 1}, + {"__alloc_bootmem", 0}, + {"alloc_bootmem", 0}, + {"dma_alloc_contiguous", 1}, + {"dma_alloc_coherent", 1}, + {}, +}; + +struct alloc_info general_allocation_funcs[] = { + {"malloc", 0}, + {"calloc", 0, 1}, + {"memdup", 1}, + {"realloc", 1}, + {}, +}; + +static int fresh_callback(void *fresh, int argc, char **argv, char **azColName) +{ + *(int *)fresh = 1; + return 0; +} + +static int fresh_from_db(struct expression *call) +{ + int fresh = 0; + + /* for function pointers assume everything is used */ + if (call->fn->type != EXPR_SYMBOL) + return 0; + + run_sql(&fresh_callback, &fresh, + "select * from return_states where %s and type = %d and parameter = -1 and key = '$' limit 1;", + get_static_filter(call->fn->symbol), FRESH_ALLOC); + return fresh; +} + +bool is_fresh_alloc_var_sym(const char *var, struct symbol *sym) +{ + return get_state(my_id, var, sym) == &fresh; +} + +bool is_fresh_alloc(struct expression *expr) +{ + sval_t sval; + int i; + + if (!expr) + return false; + + if (get_implied_value_fast(expr, &sval) && sval.value == 0) + return false; + + if (get_state_expr(my_id, expr) == &fresh) + return true; + + if (expr->type != EXPR_CALL) + return false; + if (fresh_from_db(expr)) + return true; + i = -1; + while (alloc_funcs[++i].fn) { + if (sym_name_is(kernel_allocation_funcs[i].fn, expr->fn)) + return true; + } + return false; +} + +static void record_alloc_func(int return_id, char *return_ranges, struct expression *expr) +{ + if (!is_fresh_alloc(expr)) + return; + sql_insert_return_states(return_id, return_ranges, FRESH_ALLOC, -1, "$", ""); +} + +static void set_unfresh(struct expression *expr) +{ + struct sm_state *sm; + + sm = get_sm_state_expr(my_id, expr); + if (!sm) + return; + if (!slist_has_state(sm->possible, &fresh)) + return; + // TODO call unfresh hooks + set_state_expr(my_id, expr, &undefined); +} + +static void match_assign(struct expression *expr) +{ + set_unfresh(expr->right); +} + +static void match_call(struct expression *expr) +{ + struct expression *arg; + + FOR_EACH_PTR(expr->args, arg) { + set_unfresh(arg); + } END_FOR_EACH_PTR(arg); +} + +static void set_fresh(struct expression *expr) +{ + expr = strip_expr(expr); + if (expr->type != EXPR_SYMBOL) + return; + set_state_expr(my_id, expr, &fresh); +} + +static void returns_fresh_alloc(struct expression *expr, int param, char *key, char *value) +{ + if (param != -1 || !key || strcmp(key, "$") != 0) + return; + if (expr->type != EXPR_ASSIGNMENT) + return; + + set_fresh(expr->left); +} + +static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) +{ + set_fresh(expr->left); +} + +void register_fresh_alloc(int id) +{ + int i; + + my_id = id; + + if (option_project == PROJ_KERNEL) + alloc_funcs = kernel_allocation_funcs; + else + alloc_funcs = general_allocation_funcs; + + i = -1; + while (alloc_funcs[++i].fn) + add_function_assign_hook(alloc_funcs[i].fn, &match_alloc, 0); + + add_split_return_callback(&record_alloc_func); + select_return_states_hook(FRESH_ALLOC, &returns_fresh_alloc); + add_hook(&match_assign, ASSIGNMENT_HOOK); + add_hook(&match_call, FUNCTION_CALL_HOOK); +} diff --git a/usr/src/tools/smatch/src/smatch_math.c b/usr/src/tools/smatch/src/smatch_math.c index 68ca445619..e6e033172f 100644 --- a/usr/src/tools/smatch/src/smatch_math.c +++ b/usr/src/tools/smatch/src/smatch_math.c @@ -1606,6 +1606,26 @@ int get_implied_value(struct expression *expr, sval_t *sval) return 1; } +int get_implied_value_fast(struct expression *expr, sval_t *sval) +{ + struct range_list *rl; + static int recurse; + int ret = 0; + + if (recurse) + return 0; + + recurse = 1; + set_fast_math_only(); + if (get_rl_helper(expr, RL_IMPLIED, &rl) && + rl_to_sval(rl, sval)) + ret = 1; + clear_fast_math_only(); + recurse = 0; + + return ret; +} + int get_implied_min(struct expression *expr, sval_t *sval) { struct range_list *rl; diff --git a/usr/src/tools/smatch/src/smatch_mtag.c b/usr/src/tools/smatch/src/smatch_mtag.c index 37d1f18579..607ede688b 100644 --- a/usr/src/tools/smatch/src/smatch_mtag.c +++ b/usr/src/tools/smatch/src/smatch_mtag.c @@ -50,7 +50,7 @@ static int my_id; -static mtag_t str_to_tag(const char *str) +mtag_t str_to_mtag(const char *str) { unsigned char c[MD5_DIGEST_LENGTH]; unsigned long long *tag = (unsigned long long *)&c; @@ -132,7 +132,7 @@ struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_sta snprintf(buf, sizeof(buf), "%s %s %s %s", get_filename(), get_function(), left_name, right_name); - tag = str_to_tag(buf); + tag = str_to_mtag(buf); tag_sval.type = estate_type(state); tag_sval.uvalue = tag; @@ -156,8 +156,8 @@ int get_string_mtag(struct expression *expr, mtag_t *tag) return 0; /* I was worried about collisions so I added a xor */ - xor = str_to_tag("__smatch string"); - *tag = str_to_tag(expr->string->data); + xor = str_to_mtag("__smatch string"); + *tag = str_to_mtag(expr->string->data); *tag = *tag ^ xor; return 1; @@ -177,7 +177,7 @@ int get_toplevel_mtag(struct symbol *sym, mtag_t *tag) snprintf(buf, sizeof(buf), "%s %s", (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern", sym->ident->name); - *tag = str_to_tag(buf); + *tag = str_to_mtag(buf); return 1; } @@ -196,7 +196,7 @@ bool get_symbol_mtag(struct symbol *sym, mtag_t *tag) snprintf(buf, sizeof(buf), "%s %s %s", get_filename(), get_function(), sym->ident->name); - *tag = str_to_tag(buf); + *tag = str_to_mtag(buf); return true; } @@ -258,7 +258,7 @@ struct range_list *swap_mtag_seed(struct expression *expr, struct range_list *rl name = expr_to_str(expr); snprintf(buf, sizeof(buf), "%s %s %s", get_filename(), get_function(), name); free_string(name); - tag = str_to_tag(buf); + tag = str_to_mtag(buf); sval.value = tag; return alloc_rl(sval, sval); } @@ -284,7 +284,7 @@ int create_mtag_alias(mtag_t tag, struct expression *expr, mtag_t *new) snprintf(buf, sizeof(buf), "%lld %d %s", tag, lines_from_start, str); free_string(str); - *new = str_to_tag(buf); + *new = str_to_mtag(buf); sql_insert_mtag_alias(tag, *new); return 1; diff --git a/usr/src/tools/smatch/src/smatch_slist.c b/usr/src/tools/smatch/src/smatch_slist.c index 5c20dd739c..c95133f282 100644 --- a/usr/src/tools/smatch/src/smatch_slist.c +++ b/usr/src/tools/smatch/src/smatch_slist.c @@ -78,11 +78,13 @@ void __print_stree(struct stree *stree) { struct sm_state *sm; - printf("dumping stree at %d [%ld states]\n", get_lineno(), stree_count(stree)); + option_debug++; + sm_msg("dumping stree [%ld states]", stree_count(stree)); FOR_EACH_SM(stree, sm) { - printf("%s\n", show_sm(sm)); + sm_printf("%s\n", show_sm(sm)); } END_FOR_EACH_SM(sm); - printf("---\n"); + sm_printf("---\n"); + option_debug--; } /* NULL states go at the end to simplify merge_slist */ diff --git a/usr/src/tools/smatch/src/smatch_type.c b/usr/src/tools/smatch/src/smatch_type.c index 7e2e29ade5..be54ced235 100644 --- a/usr/src/tools/smatch/src/smatch_type.c +++ b/usr/src/tools/smatch/src/smatch_type.c @@ -789,7 +789,7 @@ static int type_str_helper(char *buf, int size, struct symbol *type) int n; if (!type) - return snprintf(buf, size, "<unknown>"); + return snprintf(buf, size, "<null type>"); if (type->type == SYM_BASETYPE) { return snprintf(buf, size, "%s", base_type_str(type)); diff --git a/usr/src/tools/smatch/src/validation/sm_locking2.c b/usr/src/tools/smatch/src/validation/sm_locking2.c index 37ce24869d..23294b07a1 100644 --- a/usr/src/tools/smatch/src/validation/sm_locking2.c +++ b/usr/src/tools/smatch/src/validation/sm_locking2.c @@ -30,10 +30,9 @@ int func (void) * check-command: smatch --project=kernel sm_locking2.c * * check-output-start -sm_locking2.c:21 func() error: double unlock 'spin_lock:mylock' -sm_locking2.c:26 func() warn: inconsistent returns 'spin_lock:mylock3'. - Locked on: line 26 - Unlocked on: line 14 - line 25 +sm_locking2.c:21 func() error: double unlocked 'mylock' (orig line 17) +sm_locking2.c:26 func() warn: inconsistent returns 'mylock3'. + Locked on : 26 + Unlocked on: 25 * check-output-end */ diff --git a/usr/src/tools/smatch/src/validation/sm_locking3.c b/usr/src/tools/smatch/src/validation/sm_locking3.c index c63ec5cab2..d69f005214 100644 --- a/usr/src/tools/smatch/src/validation/sm_locking3.c +++ b/usr/src/tools/smatch/src/validation/sm_locking3.c @@ -24,10 +24,9 @@ int func (void) * check-command: smatch --project=kernel sm_locking3.c * * check-output-start -sm_locking3.c:18 func() error: double unlock 'spin_lock:mylock' -sm_locking3.c:20 func() warn: inconsistent returns 'spin_lock:mylock'. - Locked on: line 16 - Unlocked on: line 10 - line 20 +sm_locking3.c:18 func() error: double unlocked 'mylock' (orig line 15) +sm_locking3.c:20 func() warn: inconsistent returns 'mylock'. + Locked on : 16 + Unlocked on: 10,20 * check-output-end */ diff --git a/usr/src/tools/smatch/src/validation/sm_locking4.c b/usr/src/tools/smatch/src/validation/sm_locking4.c index 301fac7086..6c44a269ad 100644 --- a/usr/src/tools/smatch/src/validation/sm_locking4.c +++ b/usr/src/tools/smatch/src/validation/sm_locking4.c @@ -28,9 +28,8 @@ void func (void) * check-command: smatch --project=kernel sm_locking4.c * * check-output-start -sm_locking4.c:23 func() warn: inconsistent returns 'spin_lock:mylock'. - Locked on: line 22 - line 23 - Unlocked on: line 16 +sm_locking4.c:23 func() warn: inconsistent returns 'mylock'. + Locked on : 22-23 + Unlocked on: 16 * check-output-end */ diff --git a/usr/src/tools/smatch/src/validation/sm_locking6.c b/usr/src/tools/smatch/src/validation/sm_locking6.c index 9366c2c11f..b59fb1321a 100644 --- a/usr/src/tools/smatch/src/validation/sm_locking6.c +++ b/usr/src/tools/smatch/src/validation/sm_locking6.c @@ -31,15 +31,11 @@ void func (void) * check-command: smatch -p=kernel sm_locking6.c * * check-output-start -sm_locking6.c:27 func() warn: inconsistent returns 'irqsave:flags'. - Locked on: line 26 - Unlocked on: line 21 - line 24 - line 27 -sm_locking6.c:27 func() warn: inconsistent returns 'spin_lock:lock'. - Locked on: line 26 - Unlocked on: line 21 - line 24 - line 27 +sm_locking6.c:27 func() warn: inconsistent returns 'flags'. + Locked on : 26 + Unlocked on: 21,24,27 +sm_locking6.c:27 func() warn: inconsistent returns 'lock'. + Locked on : 26 + Unlocked on: 21,24,27 * check-output-end */ diff --git a/usr/src/tools/smatch/src/validation/sm_locking7.c b/usr/src/tools/smatch/src/validation/sm_locking7.c index f2177ff3e0..ca96bb6867 100644 --- a/usr/src/tools/smatch/src/validation/sm_locking7.c +++ b/usr/src/tools/smatch/src/validation/sm_locking7.c @@ -27,11 +27,11 @@ void func(int *y) * check-command: smatch -p=kernel -I.. sm_locking7.c * * check-output-start -sm_locking7.c:22 func() warn: inconsistent returns 'irqsave:flags'. - Locked on: line 21 - Unlocked on: line 22 -sm_locking7.c:22 func() warn: inconsistent returns 'spin_lock:&lock'. - Locked on: line 21 - Unlocked on: line 22 +sm_locking7.c:22 func() warn: inconsistent returns 'flags'. + Locked on : 21 + Unlocked on: 22 +sm_locking7.c:22 func() warn: inconsistent returns 'lock'. + Locked on : 21 + Unlocked on: 22 * check-output-end */ |