11 argp
= argparse
.ArgumentParser(description
="Perform various transformations on a function database")
12 argp
.add_argument("file", help="function database file (YAML)")
13 argp
.add_argument("command", help="transformation to perform")
14 argp
.add_argument("args", nargs
="*", help="transformation arguments (optional)")
15 args
= argp
.parse_args()
17 with
open(args
.file) as f
:
18 FUNC_DB
= yaml
.load(f
)
22 for addr
, props
in FUNC_DB
.items():
23 label2addr
[props
["label"]] = addr
26 if args
.command
== "label2addr":
28 for addr
, props
in FUNC_DB
.items():
29 props
["calls_addr"] = [label2addr
.get(x
, x
) for x
in props
["calls"]]
31 elif args
.command
== "addr2label":
32 for addr
, props
in FUNC_DB
.items():
34 props
["calls"] = [FUNC_DB
[x
]["label"] if x
in FUNC_DB
else x
for x
in props
["calls_addr"]]
36 elif args
.command
== "called_by":
39 for addr
, props
in FUNC_DB
.items():
42 for callee
in props
.get("calls", []):
43 called
.setdefault(callee
, set()).add(name
)
44 if callee
not in label2addr
:
45 calls_unk
.append(callee
)
47 props
["calls_unk"] = calls_unk
49 for addr
, props
in FUNC_DB
.items():
52 props
["called_by"] = called
[name
]
54 elif args
.command
== "returns":
55 for addr
, props
in FUNC_DB
.items():
56 if "modifieds" in props
and "callsites_live_out" in props
:
57 props
["returns"] = set(props
["modifieds"]) & set(props
["callsites_live_out"])
59 elif args
.command
== "select-subgraph":
60 if len(args
.args
) > 1:
61 dirname
= args
.args
[1]
63 dirname
= args
.args
[0] + ".subgraph"
64 if not os
.path
.isdir(dirname
):
67 print("Warning: already exists:", dirname
)
69 queue
= [args
.args
[0]]
76 addr
= label2addr
[func
]
77 funcinfo
= FUNC_DB
[addr
]
80 queue
.extend(funcinfo
["calls"])
81 fname
= "%s-%s.lst" % (addr
, func
)
83 os
.symlink("../funcs/" + fname
, dirname
+ "/" + fname
)
84 except FileExistsError
as e
:
88 argp
.error("Unknown command: " + args
.command
)
90 os
.rename(args
.file, args
.file + ".bak")
92 with
open(args
.file, "w") as f
: