7b846e335755bf3ccc1891b22d53df3840d8a9df
[smatch.git] / smatch_scripts / db / fill_db_caller_info.pl
blob7b846e335755bf3ccc1891b22d53df3840d8a9df
1 #!/usr/bin/perl -w
3 use strict;
4 use DBI;
5 use Scalar::Util qw(looks_like_number);
7 sub usage()
9 print "usage: $0 <warns.txt>\n";
10 exit(1);
13 my %too_common_funcs;
14 sub get_too_common_functions($)
16 my $warns = shift;
18 open(FUNCS, "cat $warns | grep 'info: call_marker ' | cut -d \"'\" -f 2 | sort | uniq -c | ");
20 while (<FUNCS>) {
21 if ($_ =~ /(\d+) (.*)/) {
22 if (int($1) > 200) {
23 $too_common_funcs{$2} = 1;
28 close(FUNCS);
31 my $warns = shift;
33 if (!defined($warns)) {
34 usage();
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");
44 my $prev_fn = "";
45 my $prev_line = "+0";
46 my $prev_param = 0;
47 my $func_id = 1;
48 my $type;
50 $db->do("delete from caller_info");
52 open(WARNS, "<$warns");
53 while (<WARNS>) {
54 if (!($_ =~ /info:/)) {
55 next;
57 if ($_ =~ /__builtin_/) {
58 next;
60 if ($_ =~ /(printk|memset|memcpy|kfree|printf|dev_err|writel)/) {
61 next;
64 s/\n//;
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
70 $type = 0; # INTERNAL
71 ($file_and_line, $caller, $dummy, $dummy, $func, $gs) = split(/ /, $_);
72 ($file, $line) = split(/:/, $file_and_line);
73 $param = -1;
74 $key = "";
75 $value = "";
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
85 $type = 1; # PARAM_VALUE
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
97 $type = 2; # BUF_SIZE
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
108 $type = 3; # USER_DATA
109 $value = 1;
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
121 $type = 4; # CAPPED_DATA
122 $value = 1;
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";
132 } else {
133 next;
136 if (!looks_like_number($param)) {
137 next;
140 $caller =~ s/\(\)//;
141 $func =~ s/'//g;
142 $key =~ s/'//g;
143 $value =~ s/'//g;
145 if (defined($too_common_funcs{$func})) {
146 next;
149 if ($prev_fn ne $func || $prev_line ne $line) {
150 $prev_fn = $func;
151 $prev_line = $line;
152 $prev_param = $param;
153 $func_id++;
156 my $static = 0;
157 if ($gs =~ /static/) {
158 $static = 1;
161 # print "insert into caller_info values ('$file', '$caller', '$func', $func_id, $type, $param, '$key', '$value')\n";
162 $db->do("insert into caller_info values ('$file', '$caller', '$func', $func_id, $static, $type, $param, '$key', '$value')");
164 $db->commit();
165 $db->disconnect();