Skip to content

Commit 3574f21

Browse files
committed
REP: add spare instruction to patch candidates report
1 parent add139d commit 3574f21

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

chb/buffer/LibraryCallCallsites.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ def __init__(
5252
self,
5353
summary: "FunctionSummary",
5454
faddr: str,
55+
baddr: str,
5556
instr: "Instruction",
5657
pre: "PreDerefWrite") -> None:
5758
self._summary = summary
5859
self._faddr = faddr
60+
self._baddr = baddr
5961
self._instr = instr
6062
self._pre = pre
6163

@@ -67,6 +69,10 @@ def summary(self) -> "FunctionSummary":
6769
def faddr(self) -> str:
6870
return self._faddr
6971

72+
@property
73+
def baddr(self) -> str:
74+
return self._baddr
75+
7076
@property
7177
def instr(self) -> "Instruction":
7278
return self._instr
@@ -234,15 +240,23 @@ def __str__(self) -> str:
234240
class LibraryCallCallsite:
235241

236242
def __init__(
237-
self, faddr: str, iaddr: str, callinstr: "Instruction") -> None:
243+
self, faddr: str,
244+
baddr: str,
245+
iaddr: str,
246+
callinstr: "Instruction") -> None:
238247
self._faddr = faddr
248+
self._baddr = baddr
239249
self._iaddr = iaddr
240250
self._instr = callinstr
241251

242252
@property
243253
def faddr(self) -> str:
244254
return self._faddr
245255

256+
@property
257+
def baddr(self) -> str:
258+
return self._baddr
259+
246260
@property
247261
def iaddr(self) -> str:
248262
return self._iaddr
@@ -293,7 +307,7 @@ def derefwrites(self) -> List[LibraryCallSideeffect]:
293307
if pre.is_deref_write:
294308
pre = cast("PreDerefWrite", pre)
295309
lcwrite = LibraryCallSideeffect(
296-
self.summary, self.faddr, self.instr, pre)
310+
self.summary, self.faddr, self.baddr, self.instr, pre)
297311
result.append(lcwrite)
298312
return result
299313

@@ -369,9 +383,9 @@ def duplicates(self) -> Dict[str, Dict[str, List[LibraryCallCallsite]]]:
369383
return self._duplicates
370384

371385
def add_library_callsite(
372-
self, faddr: str, callinstr: "Instruction") -> None:
386+
self, faddr: str, baddr: str, callinstr: "Instruction") -> None:
373387
iaddr = callinstr.iaddr
374-
lccs = LibraryCallCallsite(faddr, iaddr, callinstr)
388+
lccs = LibraryCallCallsite(faddr, baddr, iaddr, callinstr)
375389
self._callsites.setdefault(faddr, {})
376390
if iaddr in self._callsites[faddr]:
377391
chklogger.logger.warning(

chb/cmdline/reportcmds.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@
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

Comments
 (0)