Skip to content

Commit 7ff0b04

Browse files
committed
AST: add support for BX-call
1 parent 6cd8808 commit 7ff0b04

File tree

7 files changed

+45
-19
lines changed

7 files changed

+45
-19
lines changed

chb/app/AppAccess.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ def callgraph(self) -> Callgraph:
410410
cbttgts = cbtable.tagged_fields_at_offset(cbtgt.offset)
411411
for (tag, cbfaddr) in cbttgts.items():
412412
if self.has_function_name(cbfaddr):
413-
cbfname = tag + ":" + self.function_name(cbfaddr)
413+
cbfname = (
414+
tag + ":" + self.function_name(cbfaddr))
414415
else:
415416
cbfname = tag + ":" + cbfaddr
416417
apptgtnode = mk_tagged_app_callgraph_node(

chb/app/CallbackTables.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ def tag_offset(self) -> int:
7878
return (-1)
7979

8080
@property
81-
def tag(self) -> str:
81+
def tag(self) -> Optional[str]:
8282
if self.tag_offset >= 0:
8383
return self.fields[self.tag_offset][1]
8484
else:
85-
return "?"
85+
return None
8686

8787
def value_at_offset(self, offset: int) -> str:
8888
if offset in self.fields:
@@ -131,8 +131,8 @@ def tagged_fields_at_offset(self, offset: int) -> Dict[str, str]:
131131
for r in self.records:
132132
counter += 1
133133
tag = r.tag
134-
if tag == "?":
135-
tag = "unknown_" + str(counter)
134+
if tag is None:
135+
tag = str(counter)
136136
result[tag] = r.value_at_offset(offset)
137137
return result
138138

chb/app/InstrXData.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ def has_call_target(self) -> bool:
308308
else:
309309
return False
310310

311+
@property
312+
def is_bx_call(self) -> bool:
313+
return "bx-call" in self.tags
314+
311315
def call_target_argument_count(self) -> Optional[int]:
312316
if len(self.tags) >= 3:
313317
if self.tags[1] == "call":

chb/arm/ARMCallOpcode.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,23 +195,28 @@ def ast_call_prov(
195195
finfo = xdata.function.finfo
196196
if finfo.has_call_target_info(iaddr):
197197
ctinfo = finfo.call_target_info(iaddr)
198-
fname = ctinfo.target_interface.name
199198
ftype = ctinfo.target_interface.bctype
200199
if ftype is not None:
201200
astfntype = ftype.convert(astree.typconverter)
202-
if astree.globalsymboltable.has_symbol(fname):
203-
tgtvinfo = astree.globalsymboltable.get_symbol(fname)
204-
hl_tgt = astree.mk_vinfo_lval_expression(tgtvinfo)
201+
202+
if xdata.is_bx_call:
203+
# indirect call
204+
hl_tgt = XU.xxpr_to_ast_def_expr(xprs[-1], xdata, iaddr, astree)
205205
else:
206-
gaddr: int = 0
207-
if fname.startswith("sub_"):
208-
gaddr = int("0x" + fname[4:], 16)
206+
fname = ctinfo.target_interface.name
207+
if astree.globalsymboltable.has_symbol(fname):
208+
tgtvinfo = astree.globalsymboltable.get_symbol(fname)
209+
hl_tgt = astree.mk_vinfo_lval_expression(tgtvinfo)
209210
else:
210-
if tgt.is_absolute:
211-
tgtaddr = cast(ARMAbsoluteOp, tgt.opkind)
212-
gaddr = int(tgtaddr.address.get_hex(), 16)
213-
hl_tgt = astree.mk_global_variable_expr(
214-
fname, globaladdress=gaddr, vtype=astfntype)
211+
gaddr: int = 0
212+
if fname.startswith("sub_"):
213+
gaddr = int("0x" + fname[4:], 16)
214+
else:
215+
if tgt.is_absolute:
216+
tgtaddr = cast(ARMAbsoluteOp, tgt.opkind)
217+
gaddr = int(tgtaddr.address.get_hex(), 16)
218+
hl_tgt = astree.mk_global_variable_expr(
219+
fname, globaladdress=gaddr, vtype=astfntype)
215220

216221
if ftype is not None and ftype.is_function:
217222
ftype = cast("BCTypFun", ftype)

chb/arm/ARMInstruction.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,9 @@ def annotation(self) -> str:
236236
aggaddr = self.xdata.subsumed_by()
237237
return f"subsumed by {aggaddr}"
238238
elif self.subsumes:
239+
ann = self.opcode.annotation(self.xdata)
239240
dependents = self.xdata.subsumes()
240-
return "subsumes [" + ", ".join(dependents) + "]"
241+
return ann + " (subsumes [" + ", ".join(dependents) + "])"
241242
else:
242243
return self.opcode.annotation(self.xdata)
243244

chb/arm/opcodes/ARMBranchExchange.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939

4040
from chb.invariants.XXpr import XXpr
4141

42+
4243
import chb.util.fileutil as UF
44+
from chb.util.loggingutil import chklogger
4345

4446
from chb.util.IndexedTable import IndexedTableValue
4547

@@ -98,8 +100,19 @@ def call_target(self, xdata: InstrXData) -> "CallTarget":
98100
else:
99101
raise UF.CHBError("Instruction is not a call: " + str(self))
100102

103+
def argument_count(self, xdata: InstrXData) -> int:
104+
if self.is_call_instruction(xdata):
105+
argcount = xdata.call_target_argument_count()
106+
if argcount is not None:
107+
return argcount
108+
chklogger.logger.warning(
109+
"Call instruction does not have argument count")
110+
return 0
111+
else:
112+
raise UF.CHBError("Instruction is not a call: " + str(self))
113+
101114
def arguments(self, xdata: InstrXData) -> Sequence[XXpr]:
102-
return xdata.xprs
115+
return xdata.xprs[:self.argument_count(xdata)]
103116

104117
def annotation(self, xdata: InstrXData) -> str:
105118
"""xdata format: a:x .

chb/graphics/DotCallgraph.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ def to_dotgraph(self) -> DotGraph:
103103
('[' in name or ']' in name or '?' in name)
104104
and not name.startswith('"')):
105105
name = '"' + name + '"'
106+
if ":" in name:
107+
continue
106108
if len(name) == 0:
107109
continue
108110
sameranknodes.append(name)

0 commit comments

Comments
 (0)