5 use Scalar
::Util
qw(looks_like_number);
9 print "usage: $0 <warns.txt>\n";
14 sub get_too_common_functions
($)
18 open(FUNCS
, "cat $warns | grep 'info: call_marker ' | cut -d \"'\" -f 2 | sort | uniq -c | ");
21 if ($_ =~ /(\d+) (.*)/) {
23 $too_common_funcs{$2} = 1;
33 if (!defined($warns)) {
37 get_too_common_functions
($warns);
39 my $db = DBI
->connect("dbi:SQLite:smatch_db.sqlite", "", "", {RaiseError
=> 1, AutoCommit
=> 0});
40 $db->do("PRAGMA synchronous = OFF");
41 $db->do("PRAGMA cache_size = 800000");
42 $db->do("PRAGMA journal_mode = OFF");
50 $db->do("delete from caller_info");
52 open(WARNS
, "<$warns");
54 if (!($_ =~ /info:/)) {
57 if ($_ =~ /__builtin_/) {
60 if ($_ =~ /(printk|memset|memcpy|kfree|printf|dev_err|writel)/) {
66 my ($file_and_line, $file, $line, $caller, $dummy, $func, $param, $key, $value, $gs);
68 if ($_ =~ /info: call_marker /) {
69 # crypto/zlib.c:50 zlib_comp_exit() info: call_marker 'zlib_deflateEnd' global
71 ($file_and_line, $caller, $dummy, $dummy, $func, $gs) = split(/ /, $_);
72 ($file, $line) = split(/:/, $file_and_line);
77 if ($func eq "'(struct") {
78 ($file_and_line, $dummy, $dummy, $dummy, $dummy, $func, $gs) = split(/ /, $_);
79 ($file, $line) = split(/:/, $file_and_line);
80 $func = "$dummy $func";
83 } elsif ($_ =~ /info: passes param_value /) {
84 # init/main.c +165 obsolete_checksetup(7) info: passes param_value strlen 0 min-max static
86 ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_);
87 ($file, $line) = split(/:/, $file_and_line);
89 if ($func eq "'(struct") {
90 ($file_and_line, $dummy, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_);
91 ($file, $line) = split(/:/, $file_and_line);
92 $func = "$dummy $func";
95 } elsif ($_ =~ /info: passes_buffer /) {
96 # init/main.c +175 obsolete_checksetup(17) info: passes_buffer 'printk' 0 '$$' 38 global
98 ($file_and_line, $caller, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_);
99 ($file, $line) = split(/:/, $file_and_line);
101 if ($func eq "'(struct") {
102 ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $value, $gs) = split(/ /, $_);
103 ($file, $line) = split(/:/, $file_and_line);
104 $func = "$dummy $func";
106 } elsif ($_ =~ /info: passes user_data /) {
107 # test.c +24 func(11) info: passes user_data 'frob' 2 '$$->data' global
110 ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_);
111 ($file, $line) = split(/:/, $file_and_line);
113 if ($func eq "'(struct") {
114 ($file_and_line, $caller, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_);
115 ($file, $line) = split(/:/, $file_and_line);
116 $func = "$dummy $func";
119 } elsif ($_ =~ /info: passes capped_data /) {
120 # test.c +24 func(11) info: passes capped_data 'frob' 2 '$$->data' static
123 ($file_and_line, $caller, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_);
124 ($file, $line) = split(/:/, $file_and_line);
126 if ($func eq "'(struct") {
127 ($file_and_line, $caller, $dummy, $dummy, $dummy, $dummy, $func, $param, $key, $gs) = split(/ /, $_);
128 ($file, $line) = split(/:/, $file_and_line);
129 $func = "$dummy $func";
136 if (!looks_like_number
($param)) {
145 if (defined($too_common_funcs{$func})) {
149 if ($prev_fn ne $func || $prev_line ne $line) {
152 $prev_param = $param;
157 if ($gs =~ /static/) {
161 # print "insert into caller_info values ('$file', '$func', $func_id, $type, $param, '$key', '$value')\n";
162 $db->do("insert into caller_info values ('$file', '$func', $func_id, $static, $type, $param, '$key', '$value')");
164 # print "insert into caller_info values ('$file', '$caller', '$func', $func_id, $type, $param, '$key', '$value')\n";
165 $db->do("insert into caller_info values ('$file', '$caller', '$func', $func_id, $static, $type, $param, '$key', '$value')");