Skip to content

Commit f378330

Browse files
committed
AST: use untyped registers as argument for show_reachingdefs
1 parent 63cca43 commit f378330

File tree

3 files changed

+57
-26
lines changed

3 files changed

+57
-26
lines changed

chb/astinterface/ASTInterface.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ def introduce_ssa_variables(
970970
self,
971971
rdeflocs: Dict[str, List[List[str]]],
972972
ftypes: Dict[str, Dict[str, "BCTyp"]],
973-
ssanames: Dict[str, str] = {}) -> None:
973+
ssanames: Dict[str, str] = {}) -> Dict[str, Dict[str, List[str]]]:
974974
"""Creates ssa variables based on reaching definition locations.
975975
976976
Lists with multiple locations will give rise to a single variable
@@ -985,10 +985,10 @@ def introduce_ssa_variables(
985985
where <reg> is the name of the register being assigned.
986986
"""
987987

988+
untyped: Dict[str, Dict[str, List[str]]] = {}
988989
for (reg, locs) in rdeflocs.items():
989990
for lst in locs:
990991
if len(lst) > 0:
991-
# print("DEBUG: " + str(reg) + ": [" + ", ".join(str(loc) for loc in lst) + "]")
992992
loc1 = lst[0]
993993
vtype = None
994994
if loc1 in ftypes:
@@ -997,11 +997,16 @@ def introduce_ssa_variables(
997997
vtype = vbctype.convert(self.typconverter)
998998
vinfo = self.mk_ssa_register_varinfo(
999999
reg, loc1, vtype=vtype, prefix=ssanames.get(loc1))
1000+
if vtype is None:
1001+
untyped.setdefault(reg, {})
1002+
untyped[reg].setdefault(vinfo.vname, [])
1003+
untyped[reg][vinfo.vname].append(loc1)
10001004
self._ssa_addresses.setdefault(vinfo.vname, set([]))
10011005
for loc in lst:
10021006
self._ssa_intros.setdefault(loc, {})
10031007
self._ssa_intros[loc][reg] = vinfo
10041008
self._ssa_addresses[vinfo.vname].add(loc)
1009+
return untyped
10051010

10061011
def introduce_stack_variables(
10071012
self,

chb/cmdline/astcmds.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ def buildast(args: argparse.Namespace) -> NoReturn:
150150
xpatchresultsfile = args.patch_results_file
151151
hide_globals: bool = args.hide_globals
152152
hide_annotations: bool = args.hide_annotations
153-
show_reachingdefs: str = args.show_reachingdefs
153+
show_reachingdefs: bool = args.show_reachingdefs
154+
reachingdefs_registers: List[str] = args.reachingdefs_registers
154155
output_reachingdefs: str = args.output_reachingdefs
155156
fileformat: str = args.format
156157
verbose: bool = args.verbose
@@ -349,13 +350,26 @@ def buildast(args: argparse.Namespace) -> NoReturn:
349350
# Introduce ssa variables for all reaching definitions referenced in
350351
# xdata records for all instructions in the function. Locations that
351352
# have a common user are merged. Types are provided by lhs_types.
352-
astinterface.introduce_ssa_variables(
353+
untyped = astinterface.introduce_ssa_variables(
353354
f.rdef_location_partition(), f.register_lhs_types, f.lhs_names)
354355

355356
# Introduce stack variables for all stack buffers with types
356357
astinterface.introduce_stack_variables(
357358
f.stackframe, f.stack_variable_types)
358359

360+
regsuntyped: List[str] = []
361+
for (reg, varlocs) in untyped.items():
362+
for (var, locs) in varlocs.items():
363+
if len(locs) == 1 and locs[0] == "init":
364+
continue
365+
if "_spill" in var:
366+
continue
367+
if reg == "SP":
368+
continue
369+
# print(" Untyped: " + reg + ": " + var + " [" + ",".join(locs) + "]")
370+
if not reg in regsuntyped:
371+
regsuntyped.append(reg)
372+
359373
astfunction = ASTInterfaceFunction(
360374
faddr, fname, f, astinterface, patchevents=patchevents)
361375

@@ -396,14 +410,18 @@ def buildast(args: argparse.Namespace) -> NoReturn:
396410
UC.print_error("\nSpecify a file to save the reaching defs")
397411
continue
398412

399-
register = show_reachingdefs
400-
if not register in f.rdef_location_partition():
401-
UC.print_status_update(
402-
"Register " + register + " not found in rdeflocations")
403-
continue
413+
if len(reachingdefs_registers) == 0:
414+
reachingdefs_registers = regsuntyped
404415

405-
print_reachingdefs(
406-
app, astinterface, output_reachingdefs, fileformat, f, register)
416+
for register in reachingdefs_registers:
417+
if not register in f.rdef_location_partition():
418+
UC.print_status_update(
419+
"Register " + register + " not found in rdeflocations")
420+
continue
421+
422+
for reg in reachingdefs_registers:
423+
print_reachingdefs(
424+
app, astinterface, output_reachingdefs + "__" + reg, fileformat, f, reg)
407425

408426
else:
409427
UC.print_error("Unable to find function " + faddr)
@@ -510,21 +528,23 @@ def print_reachingdefs(
510528
else:
511529
printgraphs.append(dg)
512530

513-
pdffilename = UD.print_dot_subgraphs(
514-
app.path,
515-
"paths",
516-
filename,
517-
fileformat,
518-
printgraphs)
519-
520-
UC.print_status_update("Printed " + pdffilename)
521-
if len(possibly_spurious_rdefs) > 0:
522-
print("Possibly spurious reachingdefs to be removed: ")
523-
print("~" * 80)
524-
for (rdef, iaddr) in set(possibly_spurious_rdefs):
525-
if not (rdef, iaddr) in legitimate_rdefs:
526-
print(" rdefloc: " + rdef + "; useloc: " + iaddr)
527-
print("~" * 80)
531+
if len(printgraphs) > 0:
532+
pdffilename = UD.print_dot_subgraphs(
533+
app.path,
534+
"paths",
535+
filename,
536+
fileformat,
537+
printgraphs)
538+
539+
UC.print_status_update("Printed " + pdffilename)
540+
if len(possibly_spurious_rdefs) > 0:
541+
print("\nPossibly spurious reachingdefs to be removed for register "
542+
+ register + ": ")
543+
print("~" * 80)
544+
for (rdef, iaddr) in set(possibly_spurious_rdefs):
545+
if not (rdef, iaddr) in legitimate_rdefs:
546+
print(" rdefloc: " + rdef + "; useloc: " + iaddr)
547+
print("~" * 80)
528548

529549
# print("\nLegitimate reaching defs:")
530550
# for (rdef, iaddr) in set(legitimate_rdefs):

chb/cmdline/chkx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,16 @@ def parse() -> argparse.Namespace:
744744
action="store_true")
745745
buildast.add_argument(
746746
"--show_reachingdefs",
747+
action="store_true",
747748
help="create a dot file for the reaching defs of <reg>")
748749
buildast.add_argument(
749750
"--output_reachingdefs",
750751
help="name of output file (without extension) to store dot/pdf file of reachingdefs")
752+
buildast.add_argument(
753+
"--reachingdefs_registers",
754+
help="show reachingdefs for these registers only (default: generate automatically)",
755+
nargs="*",
756+
default=[])
751757
buildast.add_argument(
752758
"--format",
753759
choices=["pdf", "png"],

0 commit comments

Comments
 (0)