Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion chb/app/CHVersion.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
chbversion: str = "0.3.0-20250309"
chbversion: str = "0.3.0-20250312"
78 changes: 76 additions & 2 deletions chb/arm/opcodes/ARMMultiply.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,19 @@
# SOFTWARE.
# ------------------------------------------------------------------------------

from typing import List, TYPE_CHECKING
from typing import List, Tuple, TYPE_CHECKING

from chb.app.InstrXData import InstrXData

from chb.arm.ARMDictionaryRecord import armregistry
from chb.arm.ARMOpcode import ARMOpcode, ARMOpcodeXData, simplify_result
from chb.arm.ARMOperand import ARMOperand

import chb.ast.ASTNode as AST
from chb.astinterface.ASTInterface import ASTInterface

import chb.invariants.XXprUtil as XU

import chb.util.fileutil as UF
from chb.util.IndexedTable import IndexedTableValue
from chb.util.loggingutil import chklogger
Expand Down Expand Up @@ -67,7 +72,7 @@ def result(self) -> "XXpr":

@property
def rresult(self) -> "XXpr":
return self.xpr(3, "result")
return self.xpr(3, "rresult")

@property
def result_simplified(self) -> str:
Expand Down Expand Up @@ -101,9 +106,78 @@ def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
def operands(self) -> List[ARMOperand]:
return [self.armd.arm_operand(i) for i in self.args[1:]]

@property
def opargs(self) -> List[ARMOperand]:
return [self.armd.arm_operand(i) for i in self.args[1:]]

def annotation(self, xdata: InstrXData) -> str:
xd = ARMMultiplyXData(xdata)
if xd.is_ok:
return xd.annotation
else:
return "Error value"

def ast_prov(
self,
astree: ASTInterface,
iaddr: str,
bytestring: str,
xdata: InstrXData) -> Tuple[
List[AST.ASTInstruction], List[AST.ASTInstruction]]:

annotations: List[str] = [iaddr, "MUL"]

# low-level assignment

(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
(ll_op1, _, _) = self.opargs[1].ast_rvalue(astree)
(ll_op2, _, _) = self.opargs[2].ast_rvalue(astree)
ll_rhs = astree.mk_binary_op("mult", ll_op1, ll_op2)

ll_assign = astree.mk_assign(
ll_lhs,
ll_rhs,
iaddr=iaddr,
bytestring=bytestring,
annotations=annotations)

rdefs = xdata.reachingdefs

astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])

# high-level assignment

xd = ARMMultiplyXData(xdata)
if not xd.is_ok:
chklogger.logger.error("Error value encountered at %s", iaddr)
return ([], [])

lhs = xd.vrd
rhs1 = xd.xrn
rhs2 = xd.xrm
rhs3 = xd.rresult

defuses = xdata.defuses
defuseshigh = xdata.defuseshigh

hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
hl_rhs = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)

hl_assign = astree.mk_assign(
hl_lhs,
hl_rhs,
iaddr=iaddr,
bytestring=bytestring,
annotations=annotations)

astree.add_instr_mapping(hl_assign, ll_assign)
astree.add_instr_address(hl_assign, [iaddr])
astree.add_expr_mapping(hl_rhs, ll_rhs)
astree.add_lval_mapping(hl_lhs, ll_lhs)
astree.add_expr_reachingdefs(hl_rhs, rdefs[2:])
astree.add_expr_reachingdefs(ll_rhs, rdefs[:2])
astree.add_lval_defuses(hl_lhs, defuses[0])
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])

return ([hl_assign], [ll_assign])
6 changes: 6 additions & 0 deletions chb/arm/opcodes/ARMStoreMultipleIncrementAfter.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,12 @@ def ast_prov(
if xdata.instruction_subsumes():
return self.ast_prov_ldmstmcopy(astree, iaddr, bytestring, xdata)

else:
chklogger.logger.error(
"AST conversion of STM not yet supported at address %s",
iaddr)
return ([], [])

regcount = len(xdata.reachingdefs) - 1
baselhs = xdata.vars[0]
memlhss = xdata.vars[1:]
Expand Down
51 changes: 42 additions & 9 deletions chb/ast/ASTCPrettyPrinter.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def write_local_declarations(self, referenced: Set[str]) -> None:
and not self.localsymboltable.is_formal(vinfo.vname)):
self.ccode.newline(indent=self.indent)
if vinfo.vtype is None:
self.ccode.write("? " + vinfo.vname)
self.ccode.write("? " + vinfo.vname + ";")
continue

if vinfo.vtype.is_array:
Expand Down Expand Up @@ -185,14 +185,19 @@ def write_global_declarations(self) -> None:
continue
self.ccode.newline(indent=self.indent)
if vinfo.vtype is None:
self.ccode.write("? " + vinfo.vname)
self.ccode.write("? " + vinfo.vname + ";")
continue

if vinfo.vtype.is_function:
ftype = cast(AST.ASTTypFun, vinfo.vtype)
ftype.returntyp.accept(self)
self.ccode.write(" ")
self.ccode.write(vinfo.vname)
if ftype.returntyp.is_function_pointer:
returntyp = cast(AST.ASTTypPtr, ftype.returntyp)
fnptr = cast(AST.ASTTypFun, returntyp.tgttyp)
self.funtypptr_with_name(fnptr, vinfo.vname)
else:
ftype.returntyp.accept(self)
self.ccode.write(" ")
self.ccode.write(vinfo.vname)
self.ccode.write("(")
if ftype.argtypes is not None:
ftype.argtypes.accept(self)
Expand Down Expand Up @@ -608,20 +613,43 @@ def visit_fun_typ(self, t: AST.ASTTypFun) -> None:
t.argtypes.accept(self)
self.ccode.write(")")

def funtypptr_with_name(self, t: AST.ASTTypFun, name: str) -> None:
if t.returntyp.is_function_pointer:
returntyp = cast(AST.ASTTypPtr, t.returntyp)
retty = cast(AST.ASTTypFun, returntyp.tgttyp)
self.funtypptr_with_name(retty, name)
self.ccode.write("(")
if t.argtypes is not None:
t.argtypes.accept(self)
self.ccode.write(")")
else:
t.returntyp.accept(self)
self.ccode.write(" (*")
self.ccode.write(name)
self.ccode.write(")(")
if t.argtypes is not None:
t.argtypes.accept(self)
self.ccode.write(")")

def visit_funargs(self, funargs: AST.ASTFunArgs) -> None:
args = funargs.funargs
if len(args) == 0:
pass
self.ccode.write("void")
else:
for arg in args[:-1]:
arg.accept(self)
self.ccode.write(", ")
args[-1].accept(self)

def visit_funarg(self, funarg: AST.ASTFunArg) -> None:
funarg.argtyp.accept(self)
self.ccode.write(" ")
self.ccode.write(funarg.argname)
if funarg.argtyp.is_function_pointer:
argtyp = cast(AST.ASTTypPtr, funarg.argtyp)
fnptr = cast(AST.ASTTypFun, argtyp.tgttyp)
self.funtypptr_with_name(fnptr, funarg.argname)
else:
funarg.argtyp.accept(self)
self.ccode.write(" ")
self.ccode.write(funarg.argname)

def visit_named_typ(self, t: AST.ASTTypNamed) -> None:
self.ccode.write("typedef ")
Expand Down Expand Up @@ -649,6 +677,11 @@ def visit_compinfo(self, cinfo: AST.ASTCompInfo) -> None:
if atype.size_expr is not None:
atype.size_expr.accept(self)
self.ccode.write("];")
elif finfo.fieldtype.is_function_pointer:
fieldtyp = cast(AST.ASTTypPtr, finfo.fieldtype)
funtyp = cast(AST.ASTTypFun, fieldtyp.tgttyp)
self.funtypptr_with_name(funtyp, finfo.fieldname)
self.ccode.write(";")
else:
finfo.fieldtype.accept(self)
self.ccode.write(" ")
Expand Down
8 changes: 8 additions & 0 deletions chb/ast/ASTNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,10 @@ def is_pointer(self) -> bool:
def is_void_pointer(self) -> bool:
return False

@property
def is_function_pointer(self) -> bool:
return False

@property
def is_scalar(self) -> bool:
return (
Expand Down Expand Up @@ -2394,6 +2398,10 @@ def is_pointer(self) -> bool:
def is_void_pointer(self) -> bool:
return self.tgttyp.is_void

@property
def is_function_pointer(self) -> bool:
return self.tgttyp.is_function

def accept(self, visitor: "ASTVisitor") -> None:
return visitor.visit_pointer_typ(self)

Expand Down
6 changes: 2 additions & 4 deletions chb/ast/astutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# ------------------------------------------------------------------------------
# The MIT License (MIT)
#
# Copyright (c) 2023 Aarno Labs LLC
# Copyright (c) 2023-2025 Aarno Labs LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -358,7 +358,7 @@ def parsecmd(args: argparse.Namespace) -> NoReturn:
parsemanager.parse_ifile(ifile)

for (faddr, dfn) in functions.items():
fname = faddr.replace("0x", "sub_")
fname = faddr
xpath = os.path.join(cname, "functions")
xpath = os.path.join(xpath, fname)
xfile = os.path.join(xpath, cname + "_" + fname + "_cfun.xml")
Expand All @@ -381,6 +381,4 @@ def parsecmd(args: argparse.Namespace) -> NoReturn:

xsbody = rootnode.find("sbody")



exit(0)