6969 from chb .api .CallTarget import StubTarget
7070 from chb .api .FunctionStub import SOFunction
7171 from chb .app .AppAccess import AppAccess
72+ from chb .app .BasicBlock import BasicBlock
7273 from chb .app .Instruction import Instruction
74+ from chb .mips .MIPSInstruction import MIPSInstruction
7375 from chb .models .BTerm import BTerm , BTermArithmetic
7476 from chb .models .FunctionSummary import FunctionSummary
7577 from chb .models .FunctionPrecondition import (
@@ -1019,7 +1021,7 @@ def report_buffer_bounds(args: argparse.Namespace) -> NoReturn:
10191021 n_calls += 1
10201022 calltgt = instr .call_target
10211023 if calltgt .is_so_target :
1022- libcalls .add_library_callsite (faddr , instr )
1024+ libcalls .add_library_callsite (faddr , baddr , instr )
10231025
10241026 def write_json_result (
10251027 xfilename : Optional [str ], jresult : JSONResult ) -> None :
@@ -1151,6 +1153,20 @@ def report_patch_candidates(args: argparse.Namespace) -> NoReturn:
11511153 xinfo = XI .XInfo ()
11521154 xinfo .load (path , xfile )
11531155
1156+ def find_spare_instruction (
1157+ block : "BasicBlock" , iaddr : str ) -> Optional [str ]:
1158+ if xinfo .is_mips :
1159+ found = None
1160+ for (addr , instr ) in block .instructions .items ():
1161+ instr = cast ("MIPSInstruction" , instr )
1162+ if instr .iaddr > iaddr :
1163+ break
1164+ if instr .is_load_instruction :
1165+ if str (instr .operands [0 ]) == "t9" :
1166+ found = instr .iaddr
1167+ return found
1168+ return None
1169+
11541170 app = UC .get_app (path , xfile , xinfo )
11551171
11561172 n_calls : int = 0
@@ -1164,22 +1180,22 @@ def report_patch_candidates(args: argparse.Namespace) -> NoReturn:
11641180 n_calls += 1
11651181 calltgt = instr .call_target
11661182 if calltgt .is_so_target and calltgt .name in xtargets :
1167- libcalls .add_library_callsite (faddr , instr )
1183+ libcalls .add_library_callsite (faddr , baddr , instr )
11681184
11691185 print ("Number of calls: " + str (n_calls ))
11701186
11711187 patchcallsites = libcalls .patch_callsites ()
11721188
11731189 for pc in sorted (patchcallsites , key = lambda pc :pc .faddr ):
1174- instr = cast ( "ARMInstruction" , pc .instr )
1190+ instr = pc .instr
11751191 dstarg = pc .dstarg
11761192 if dstarg is None :
11771193 chklogger .logger .warning (
11781194 "No expression found for destination argument: %s" ,
11791195 str (instr ))
11801196 continue
11811197 dstoffset = dstarg .stack_address_offset ()
1182- fn = instr . armfunction
1198+ fn = app . function ( pc . faddr )
11831199 stackframe = fn .stackframe
11841200 stackbuffer = stackframe .get_stack_buffer (dstoffset )
11851201 if stackbuffer is None :
@@ -1188,6 +1204,8 @@ def report_patch_candidates(args: argparse.Namespace) -> NoReturn:
11881204 str (instr ), str (dstoffset ))
11891205 continue
11901206 buffersize = stackbuffer .size
1207+ basicblock = fn .block (pc .baddr )
1208+ spare = find_spare_instruction (basicblock , instr .iaddr )
11911209
11921210 print (" " + pc .instr .iaddr + " " + pc .instr .annotation )
11931211 print (" - faddr: " + pc .faddr )
@@ -1196,6 +1214,7 @@ def report_patch_candidates(args: argparse.Namespace) -> NoReturn:
11961214 print (" - stack offset: " + str (dstoffset ))
11971215 print (" - length argument: " + str (pc .lenarg ))
11981216 print (" - buffersize: " + str (buffersize ))
1217+ print (" - spare: " + str (spare ))
11991218 print ("" )
12001219
12011220 print ("Number of patch callsites: " + str (len (patchcallsites )))
0 commit comments