Skip to content

Commit ede8dc3

Browse files
committed
REP: move the computation of the buffer size and spare instruction back to the reportcmds
And pass them in to the to_json_result method. Instead of passing in an AppAccess object. Per Henny's code review, doing all that work inside of the LibraryCallSideEffect class creates undesirable dependencies.
1 parent e46f7c0 commit ede8dc3

File tree

2 files changed

+41
-50
lines changed

2 files changed

+41
-50
lines changed

chb/buffer/LibraryCallCallsites.py

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,10 @@
4040
from chb.api.CallTarget import StubTarget
4141
from chb.api.FunctionStub import SOFunction
4242
from chb.app.Instruction import Instruction
43-
from chb.app.AppAccess import AppAccess
44-
from chb.app.Function import Function
4543
from chb.models.BTerm import BTerm, BTermArithmetic
4644
from chb.models.FunctionSummary import FunctionSummary
4745
from chb.models.FunctionPrecondition import (
4846
FunctionPrecondition, PreDerefWrite)
49-
from chb.mips.MIPSInstruction import MIPSInstruction
5047

5148

5249
class LibraryCallSideeffect:
@@ -236,56 +233,16 @@ def lentype(self) -> str:
236233
else:
237234
return lenterm
238235

239-
@property
240-
def dstoffset(self) -> Optional[int]:
241-
"""Returns the stack offset for our destination buffer"""
242-
if self.dstarg is None:
243-
return None
244-
return self.dstarg.stack_address_offset()
245-
246-
def find_spare_instruction(self,
247-
app: 'AppAccess',
248-
fn: 'Function',
249-
) -> Optional[str]:
250-
if app.is_mips:
251-
block = fn.block(self.baddr)
252-
found = None
253-
for (addr, instr) in block.instructions.items():
254-
instr = cast("MIPSInstruction", instr)
255-
if instr.iaddr > self.instr.iaddr:
256-
break
257-
if instr.is_load_instruction:
258-
if str(instr.operands[0]) == "t9":
259-
found = instr.iaddr
260-
return found
261-
return None
262-
263-
def to_json_result(self, app: 'AppAccess') -> JSONResult:
236+
def to_json_result(self,
237+
dstoffset: int,
238+
buffersize: int,
239+
spare: Optional[str],
240+
) -> JSONResult:
264241
if self.dstarg is None:
265242
chklogger.logger.warning(
266243
"No expression found for destination argument: %s", self)
267244
return JSONResult("librarycallsideeffect", {}, "fail",
268245
"No expression found for destination argument")
269-
dstoffset = self.dstoffset
270-
if dstoffset is None:
271-
chklogger.logger.warning(
272-
"No value found for destination stack offset : %s", self)
273-
return JSONResult("librarycallsideeffect", {}, "fail",
274-
"No value found for destination stack offset")
275-
276-
fn = app.function(self.faddr)
277-
stackframe = fn.stackframe
278-
stackbuffer = stackframe.get_stack_buffer(dstoffset)
279-
if stackbuffer is None:
280-
chklogger.logger.warning(
281-
"No stackbuffer found for %s at offset %s", self.instr, dstoffset)
282-
return JSONResult("librarycallsideeffect", {}, "fail",
283-
"No stackbuffer found for %s at offset %s" %
284-
(self.instr, dstoffset))
285-
286-
buffersize = stackbuffer.size
287-
spare = self.find_spare_instruction(app, fn)
288-
289246
content: Dict[str, Any] = {}
290247
content["annotation"] = self.instr.annotation
291248
content["faddr"] = self.faddr

chb/cmdline/reportcmds.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ def report_buffer_bounds(args: argparse.Namespace) -> NoReturn:
10651065
if libcallsresult.is_ok:
10661066
content["bounds"] = libcallsresult.content
10671067
else:
1068-
write_json_result(xoutput, libcallsresult,"bufferboundsassessment" )
1068+
write_json_result(xoutput, libcallsresult, "bufferboundsassessment" )
10691069

10701070
write_json_result(xoutput, JSONResult(
10711071
"libcboundsanalysis", content, "ok"), "bufferboundsassessment")
@@ -1156,6 +1156,20 @@ def report_patch_candidates(args: argparse.Namespace) -> NoReturn:
11561156
xinfo = XI.XInfo()
11571157
xinfo.load(path, xfile)
11581158

1159+
def find_spare_instruction(
1160+
block: "BasicBlock", iaddr: str) -> Optional[str]:
1161+
if xinfo.is_mips:
1162+
found = None
1163+
for (addr, instr) in block.instructions.items():
1164+
instr = cast("MIPSInstruction", instr)
1165+
if instr.iaddr > iaddr:
1166+
break
1167+
if instr.is_load_instruction:
1168+
if str(instr.operands[0]) == "t9":
1169+
found = instr.iaddr
1170+
return found
1171+
return None
1172+
11591173
app = UC.get_app(path, xfile, xinfo)
11601174

11611175
n_calls: int = 0
@@ -1191,7 +1205,27 @@ def include_target(target: 'CallTarget') -> bool:
11911205
patch_records = []
11921206

11931207
for pc in sorted(patchcallsites, key=lambda pc:pc.faddr):
1194-
jresult = pc.to_json_result(app)
1208+
instr = pc.instr
1209+
dstarg = pc.dstarg
1210+
if dstarg is None:
1211+
chklogger.logger.warning(
1212+
"No expression found for destination argument: %s",
1213+
str(instr))
1214+
continue
1215+
dstoffset = dstarg.stack_address_offset()
1216+
fn = app.function(pc.faddr)
1217+
stackframe = fn.stackframe
1218+
stackbuffer = stackframe.get_stack_buffer(dstoffset)
1219+
if stackbuffer is None:
1220+
chklogger.logger.warning(
1221+
"No stackbuffer found for %s at offset %s",
1222+
str(instr), str(dstoffset))
1223+
continue
1224+
buffersize = stackbuffer.size
1225+
basicblock = fn.block(pc.baddr)
1226+
spare = find_spare_instruction(basicblock, instr.iaddr)
1227+
1228+
jresult = pc.to_json_result(dstoffset, buffersize, spare)
11951229
if not jresult.is_ok:
11961230
chklogger.logger.warning("Couldn't process patch callsite %s", pc)
11971231
continue

0 commit comments

Comments
 (0)