1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#!/usr/bin/env python3
from __future__ import print_function
from pycparser import c_parser, c_ast, parse_file
import sys
ignore_callee = set(['mutex_acquire', 'mutex_release'])
ignore_caller = set(['caller_reinstates_queue_predicate'])
proven = [
'prvCopyDataFromQueue',
'prvCopyDataToQueue',
'prvInitialiseNewQueue',
'prvIsQueueEmpty',
'prvIsQueueFull',
'prvLockQueue',
'prvUnlockQueue',
'uxQueueMessagesWaiting',
'uxQueueSpacesAvailable',
'vQueueDelete',
'xQueueGenericCreate',
'xQueueGenericReset',
'xQueueGenericSend',
'xQueueGenericSendFromISR',
'xQueueIsQueueEmptyFromISR',
'xQueueIsQueueFullFromISR',
'xQueuePeek',
'xQueuePeekFromISR',
'xQueueReceive',
'xQueueReceiveFromISR',
]
modeled = [
'setInterruptMask',
'clearInterruptMask',
'setInterruptMaskFromISR',
'clearInterruptMaskFromISR',
'vTaskSuspendAll',
'xTaskResumeAll',
]
CALLMAP = set()
class FuncCallVisitor(c_ast.NodeVisitor):
def __init__(self, caller):
self.caller = caller
def visit_FuncCall(self, node):
callee = node.name.name
if callee not in ignore_callee:
CALLMAP.add((node.name.name, self.caller))
class FuncDefVisitor(c_ast.NodeVisitor):
def visit_FuncDef(self, node):
caller = node.decl.name
if caller in ignore_caller:
return
if caller.startswith('wrapper_'):
caller = caller[8:]
v = FuncCallVisitor(caller)
v.visit(node)
def show_func_calls(filename):
ast = parse_file(filename, use_cpp=False)
v = FuncDefVisitor()
v.visit(ast)
if __name__ == "__main__":
filename = 'out.pp'
show_func_calls(filename)
print('digraph G {')
print(' rankdir=LR;')
print(' node [style = filled, colorscheme = set13;];')
for f in proven:
print(' %s [fillcolor = 3];' % f)
for f in modeled:
print(' %s [fillcolor = 2];' % f)
for (callee, caller) in CALLMAP:
print(' %s -> %s;' % (callee, caller))
print('}')
|