3 # Copyright (C) 2013 Oracle.
5 # Licensed under the Open Software License version 1.1
12 con
= sqlite3
.connect('smatch_db.sqlite')
13 except sqlite3
.Error
, e
:
14 print "Error %s:" % e
.args
[0]
18 print "%s <function> [table] [type] [parameter]" %(sys
.argv
[0])
23 def get_function_pointers_helper(func
):
25 cur
.execute("select distinct ptr from function_ptr where function = '%s';" %(func))
28 if ptr
in function_ptrs
:
30 function_ptrs
.append(ptr
)
31 if not ptr
in searched_ptrs
:
32 searched_ptrs
.append(ptr
)
33 get_function_pointers_helper(ptr
)
35 def get_function_pointers(func
):
38 function_ptrs
= [func
]
39 searched_ptrs
= [func
]
40 get_function_pointers_helper(func
)
43 db_types
= [ "INTERNAL", "PARAM_VALUE", "BUF_SIZE", "USER_DATA", "CAPPED_DATA",
44 "RETURN_VALUE", "DEREFERENCE", "RANGE_CAP", "LOCK_HELD",
45 "LOCK_RELEASED", "ABSOLUTE_LIMITS", "LIMITED_VALUE",
46 "ADDED_VALUE", "FILTER_VALUE", "PARAM_CLEARED",
49 def type_to_str(type_int
):
56 def type_to_int(type_string
):
57 for i
in range(len(db_types
)):
58 if db_types
[i
] == type_string
:
62 def display_caller_info(printed
, cur
):
65 print "file | caller | function | type | parameter | key | value |"
67 print "%20s | %20s | %20s |" %(txt
[0], txt
[1], txt
[2]),
68 print " %10s |" %(type_to_str(txt
[5])),
69 print " %d | %s | %s" %(txt
[6], txt
[7], txt
[8])
72 def get_caller_info(ptrs
, my_type
):
77 type_filter
= "and type = %d" %(type_to_int(my_type
))
79 cur
.execute("select * from caller_info where function = '%s' %s;" %(ptr
, type_filter
))
80 printed
= display_caller_info(printed
, cur
)
82 def print_caller_info(func
, my_type
= ""):
83 ptrs
= get_function_pointers(func
)
84 get_caller_info(ptrs
, my_type
)
86 def print_return_states(func
):
88 cur
.execute("select * from return_states where function = '%s';" %(func))
93 print "file | function | return_id | return_value | type | param | key | value |"
95 print "%s | %s | %2s | %13s" %(txt
[0], txt
[1], txt
[3], txt
[4]),
96 print "| %13s |" %(type_to_str(txt
[6])),
97 print " %2d | %20s | %20s |" %(txt
[7], txt
[8], txt
[9])
99 def print_call_implies(func
):
101 cur
.execute("select * from call_implies where function = '%s';" %(func))
105 print "file | function | type | param | key | value |"
107 print "%15s | %15s" %(txt
[0], txt
[1]),
108 print "| %15s" %(type_to_str(txt
[4])),
109 print "| %3d | %15s |" %(txt
[5], txt
[6])
111 def print_type_size(var
):
113 if not re
.search("^\(struct ", var
):
114 m
= re
.search('(?<=->)\w+', var
)
117 print "Can't determine type for %s" %(var)
119 var
= "%->" + m
.group(0)
120 cur
.execute("select * from type_size where type like '%s';" %(var))
121 print "file | type | size"
124 print "%15s | %15s | %d" %(txt
[0], txt
[1], txt
[2])
126 def print_fn_ptrs(func
):
127 ptrs
= get_function_pointers(func
)
130 print "%s = " %(func),
139 def get_callers(func
):
142 ptrs
= get_function_pointers(func
)
144 cur
.execute("select distinct caller from caller_info where function = '%s';" %(ptr))
150 def call_tree_helper(func
, indent
= 0):
152 if func
in printed_funcs
:
154 print "%s%s()" %(" " * indent
, func
)
155 if func
== "too common":
159 printed_funcs
.append(func
)
160 callers
= get_callers(func
)
161 if len(callers
) >= 20:
162 print "Over 20 callers for %s()" %(func)
164 for caller
in callers
:
165 call_tree_helper(caller
, indent
+ 2)
167 def print_call_tree(func
):
170 call_tree_helper(func
)
172 if len(sys
.argv
) < 2:
175 if len(sys
.argv
) == 2:
177 print_caller_info(func
)
178 elif sys
.argv
[1] == "user_data":
180 print_caller_info(func
, "USER_DATA")
181 elif sys
.argv
[1] == "param_value":
183 print_caller_info(func
, "PARAM_VALUE")
184 elif sys
.argv
[1] == "function_ptr" or sys
.argv
[1] == "fn_ptr":
187 elif sys
.argv
[1] == "return_states":
189 print_return_states(func
)
190 elif sys
.argv
[1] == "call_implies":
192 print_call_implies(func
)
193 elif sys
.argv
[1] == "type_size":
196 elif sys
.argv
[1] == "call_tree":
198 print_call_tree(func
)