From b1b98c55727735cf67fedc010e9d148a9b09c145 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 14 Aug 2012 09:33:41 +0300 Subject: [PATCH] db: caller_info changes: store the caller, param = -1 is no parameter If this were a kernel patch I would separate the changes, but Smatch has lower standards. :( First I sometimes want to know which function called me with certain states. Next it was using the -1 parameter as an internal value, but I wanted to use that in my scripts. So I've introduced an INTERNAL type instead. Also instead of printing out -1 as the parameter in the --info data, I print a "call_marker" which is cleaner. Signed-off-by: Dan Carpenter --- smatch.h | 3 ++- smatch_db.c | 23 ++++++++--------- smatch_scripts/db/caller_info.schema | 2 +- smatch_scripts/db/fill_db_caller_info.pl | 42 +++++++++++++++++++++++--------- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/smatch.h b/smatch.h index e655dbc7..496790eb 100644 --- a/smatch.h +++ b/smatch.h @@ -403,7 +403,8 @@ void __match_initializer_call(struct symbol *sym); /* smatch_db.c */ enum info_type { - PARAM_VALUE = 1, + INTERNAL = 0, + PARAM_VALUE, BUF_SIZE, USER_DATA, CAPPED_DATA, diff --git a/smatch_db.c b/smatch_db.c index bd7d1d7f..73d38eee 100644 --- a/smatch_db.c +++ b/smatch_db.c @@ -129,10 +129,7 @@ static void match_call_hack(struct expression *expr) name = get_fnptr_name(expr->fn); if (!name) return; - if (ptr_list_empty(expr->args)) - return; - sm_msg("info: passes param_value '%s' -1 '$$' min-max %s", - name, is_static(expr->fn) ? "static" : "global"); + sm_msg("info: call_marker '%s' %s", name, is_static(expr->fn) ? "static" : "global"); free_string(name); } @@ -238,8 +235,8 @@ static int db_callback(void *unused, int argc, char **argv, char **azColName) int func_id; long type; long param; - char *name; - struct symbol *sym; + char *name = NULL; + struct symbol *sym = NULL; struct def_callback *def_callback; if (argc != 5) @@ -261,7 +258,9 @@ static int db_callback(void *unused, int argc, char **argv, char **azColName) prev_func_id = func_id; } - if (param == -1 || !get_param(param, &name, &sym)) + if (type == INTERNAL) + return 0; + if (param >= 0 && !get_param(param, &name, &sym)) return 0; FOR_EACH_PTR(callbacks, def_callback) { @@ -364,7 +363,7 @@ static struct expression *call_implies_call_expr; static int call_implies_callbacks(void *unused, int argc, char **argv, char **azColName) { struct call_implies_callback *cb; - struct expression *arg; + struct expression *arg = NULL; int type; int param; @@ -377,9 +376,11 @@ static int call_implies_callbacks(void *unused, int argc, char **argv, char **az FOR_EACH_PTR(call_implies_cb_list, cb) { if (cb->type != type) continue; - arg = get_argument_from_call_expr(call_implies_call_expr->args, param); - if (!arg) - continue; + if (param != -1) { + arg = get_argument_from_call_expr(call_implies_call_expr->args, param); + if (!arg) + continue; + } cb->callback(arg, argv[3]); } END_FOR_EACH_PTR(cb); diff --git a/smatch_scripts/db/caller_info.schema b/smatch_scripts/db/caller_info.schema index b5264ac9..98217539 100644 --- a/smatch_scripts/db/caller_info.schema +++ b/smatch_scripts/db/caller_info.schema @@ -1,4 +1,4 @@ -CREATE TABLE caller_info (file varchar(256), function varchar(256), function_id integer, static integer, type integer, parameter integer, key varchar(256), value varchar(256)); +CREATE TABLE caller_info (file varchar(256), caller varchar(256), function varchar(256), function_id integer, static integer, type integer, parameter integer, key varchar(256), value varchar(256)); CREATE INDEX caller_fn_idx on caller_info (function, function_id); CREATE INDEX caller_ff_idx on caller_info (file, function, function_id); diff --git a/smatch_scripts/db/fill_db_caller_info.pl b/smatch_scripts/db/fill_db_caller_info.pl index cfd7bada..a7149d0b 100755 --- a/smatch_scripts/db/fill_db_caller_info.pl +++ b/smatch_scripts/db/fill_db_caller_info.pl @@ -2,6 +2,7 @@ use strict; use DBI; +use Scalar::Util qw(looks_like_number); sub usage() { @@ -14,7 +15,7 @@ sub get_too_common_functions($) { my $warns = shift; - open(FUNCS, "cat $warns | grep 'info: passes param_value' | grep \" -1 '\\\$\\\$' min-max\" | cut -d \"'\" -f 2 | sort | uniq -c | "); + open(FUNCS, "cat $warns | grep 'info: call_marker ' | cut -d \"'\" -f 2 | sort | uniq -c | "); while () { if ($_ =~ /(\d+) (.*)/) { @@ -62,12 +63,27 @@ while () { s/\n//; - my ($file_and_line, $file, $line, $dummy, $func, $param, $key, $value, $gs); + my ($file_and_line, $file, $line, $caller, $dummy, $func, $param, $key, $value, $gs); - if ($_ =~ /info: passes param_value /) { + if ($_ =~ /info: call_marker /) { + # crypto/zlib.c:50 zlib_comp_exit() info: call_marker 'zlib_deflateEnd' global + $type = 0; # INTERNAL + ($file_and_line, $caller, $dummy, $dummy, $func, $gs) = split(/ /, $_); + ($file, $line) = split(/:/, $file_and_line); + $param = -1; + $key = ""; + $value = ""; + + if ($func eq "'(struct") { + ($file_and_line, $dummy, $dummy, $dummy, $dummy, $func, $gs) = split(/ /, $_); + ($file, $line) = split(/:/, $file_and_line); + $func = "$dummy $func"; + } + + } elsif ($_ =~ /info: passes param_value /) { # init/main.c +165 obsolete_checksetup(7) info: passes param_value strlen 0 min-max static $type = 1; - ($file_and_line, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); if ($func eq "'(struct") { @@ -79,11 +95,11 @@ while () { } elsif ($_ =~ /info: passes_buffer /) { # init/main.c +175 obsolete_checksetup(17) info: passes_buffer 'printk' 0 '$$' 38 global $type = 2; - ($file_and_line, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); if ($func eq "'(struct") { - ($file_and_line, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); $func = "$dummy $func"; } @@ -91,11 +107,11 @@ while () { # test.c +24 func(11) info: passes user_data 'frob' 2 '$$->data' global $type = 3; $value = 1; - ($file_and_line, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); if ($func eq "'(struct") { - ($file_and_line, $dummy, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); $func = "$dummy $func"; } @@ -104,11 +120,11 @@ while () { # test.c +24 func(11) info: passes capped_data 'frob' 2 '$$->data' static $type = 4; $value = 1; - ($file_and_line, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); if ($func eq "'(struct") { - ($file_and_line, $dummy, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); + ($file_and_line, $caller, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_); ($file, $line) = split(/:/, $file_and_line); $func = "$dummy $func"; } @@ -117,10 +133,11 @@ while () { next; } - if (!defined($gs) || !($param =~ /^-*\d+$/)) { + if (!looks_like_number($param)) { next; } + $caller =~ s/\(\)//; $func =~ s/'//g; $key =~ s/'//g; $value =~ s/'//g; @@ -143,6 +160,9 @@ while () { # print "insert into caller_info values ('$file', '$func', $func_id, $type, $param, '$key', '$value')\n"; $db->do("insert into caller_info values ('$file', '$func', $func_id, $static, $type, $param, '$key', '$value')"); + +# print "insert into caller_info values ('$file', '$caller', '$func', $func_id, $type, $param, '$key', '$value')\n"; + $db->do("insert into caller_info values ('$file', '$caller', '$func', $func_id, $static, $type, $param, '$key', '$value')"); } $db->commit(); $db->disconnect(); -- 2.11.4.GIT