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-20250210"
chbversion: str = "0.3.0-20250308"
7 changes: 6 additions & 1 deletion chb/arm/ARMCallOpcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,12 @@ def ast_call_prov(
ctinfo = finfo.call_target_info(iaddr)
ftype = ctinfo.target_interface.bctype
if ftype is not None:
astfntype = ftype.convert(astree.typconverter)
try:
astfntype = ftype.convert(astree.typconverter)
except UF.CHBError as e:
chklogger.logger.warning(
"Type conversion of function type was unsuccessful: %s",
str(e))

if xdata.is_bx_call:
# indirect call
Expand Down
46 changes: 24 additions & 22 deletions chb/arm/opcodes/ARMAdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ def ast_prov(

# high-level assignment

def has_cast() -> bool:
return (
astree.has_register_variable_intro(iaddr)
and astree.get_register_variable_intro(iaddr).has_cast())

xd = ARMAddXData(xdata)
if not xdata.is_ok:
chklogger.logger.error("Error value encountered at %s", iaddr)
Expand All @@ -252,16 +257,10 @@ def ast_prov(
defuses = xdata.defuses
defuseshigh = xdata.defuseshigh

if rhs3.is_string_reference:
ctype = astree.astree.mk_pointer_type(astree.astree.char_type)
hl_lhs = XU.xvariable_to_ast_lvals(
lhs,
xdata,
astree,
ispointer=True,
ctype=ctype)[0]
else:
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)

def hl_rhs_default () -> AST.ASTExpr:
return XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)

if str(lhs) == "PC":
chklogger.logger.info(
Expand All @@ -276,11 +275,11 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
hl_rhs2_type = hl_rhs2.ctype(astree.ctyper)

if hl_rhs1_type is None and hl_rhs2_type is None:
chklogger.logger.error(
chklogger.logger.info(
"Unable to lift pointer arithmetic without type for "
+ "%s at address %s",
str(rhs3), iaddr)
return astree.mk_temp_lval_expression()
return hl_rhs_default()

if hl_rhs2_type is not None and hl_rhs2_type.is_pointer:
rhs2tgttyp = cast(AST.ASTTypPtr, hl_rhs2_type).tgttyp
Expand All @@ -290,7 +289,6 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
"Unable to lift pointer arithmetic without size for "
+ "%s at address %s; set type size to 1",
str(hl_rhs2_type), iaddr)
# return astree.mk_temp_lval_expression()
tgttypsize = 1

if tgttypsize == 1:
Expand All @@ -311,11 +309,11 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
rhs1tgttyp = cast(AST.ASTTypPtr, hl_rhs1_type).tgttyp
tgttypsize = astree.type_size_in_bytes(rhs1tgttyp)
if tgttypsize is None:
chklogger.logger.error(
chklogger.logger.info(
"Unable to lift pointer arithmetic without size for "
+ "%s at address %s",
str(hl_rhs1_type), iaddr)
return astree.mk_temp_lval_expression()
return hl_rhs_default()

if hl_rhs1.is_ast_startof:
arraylval = cast(AST.ASTStartOf, hl_rhs1).lval
Expand Down Expand Up @@ -345,13 +343,13 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
return astree.mk_binary_op("plus", hl_rhs1, scaled)

if hl_rhs2_type is None:
chklogger.logger.error(
chklogger.logger.info(
"Unable to lift pointer arithmetic without type for "
+ "%s at address %s",
str(rhs2), iaddr)
return astree.mk_temp_lval_expression()
return hl_rhs_default()

chklogger.logger.error(
chklogger.logger.info(
"Second operand pointer variable not yet supported for %s at "
+ "address %s; rrhs1: %s; hl_rhs1: %s; hl_rhs2: %s; hl_rhs1_type: %s;"
+ " hl_rhs2_type: %s",
Expand All @@ -362,8 +360,7 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
str(hl_rhs2),
str(hl_rhs1_type),
str(hl_rhs2_type))
return astree.mk_temp_lval_expression()

return hl_rhs_default()

# resulting expression is a stack address
if (
Expand Down Expand Up @@ -397,7 +394,7 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
if rhs3.is_constant_expression:
astree.set_ssa_value(str(hl_lhs), hl_rhs)

elif (hl_lhs_type is not None and hl_lhs_type.is_pointer):
elif (hl_lhs_type is not None and hl_lhs_type.is_pointer and not has_cast()):
hl_rhs = pointer_arithmetic_expr()
if str(hl_rhs).startswith("astmem_tmp"):
chklogger.logger.error(
Expand All @@ -408,7 +405,7 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
if rhs3.is_constant_expression:
astree.set_ssa_value(str(hl_lhs), hl_rhs)
else:
hl_rhs = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
hl_rhs = hl_rhs_default ()

hl_assign = astree.mk_assign(
hl_lhs,
Expand All @@ -435,4 +432,9 @@ def pointer_arithmetic_expr() -> AST.ASTExpr:
astree.add_lval_defuses(hl_lhs, defuses[0])
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])

if astree.has_register_variable_intro(iaddr):
rvintro = astree.get_register_variable_intro(iaddr)
if rvintro.has_cast():
astree.add_expose_instruction(hl_assign.instrid)

return ([hl_assign], [ll_assign])
67 changes: 46 additions & 21 deletions chb/arm/opcodes/ARMBitFieldInsert.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# ------------------------------------------------------------------------------
# The MIT License (MIT)
#
# Copyright (c) 2021-2024 Aarno Labs LLC
# Copyright (c) 2021-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 All @@ -30,7 +30,7 @@
from chb.app.InstrXData import InstrXData

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

import chb.arm.ARMPseudoCode as APC
Expand All @@ -46,6 +46,27 @@

if TYPE_CHECKING:
from chb.arm.ARMDictionary import ARMDictionary
from chb.invariants.XVariable import XVariable
from chb.invariants.XXpr import XXpr


class ARMBitFieldInsertXData(ARMOpcodeXData):
"""BFI <rd> <rn>"""

def __init__(self, xdata: InstrXData) -> None:
ARMOpcodeXData.__init__(self, xdata)

@property
def vrd(self) -> "XVariable":
return self.var(0, "vrd")

@property
def xrd(self) -> "XXpr":
return self.xpr(0, "xrd")

@property
def xrn(self) -> "XXpr":
return self.xpr(1, "xrn")


@armregistry.register_tag("BFI", ARMOpcode)
Expand Down Expand Up @@ -102,26 +123,30 @@ def width(self) -> int:
return self.args[2]

def annotation(self, xdata: InstrXData) -> str:
lhs = str(xdata.vars[0])
rhs1 = str(xdata.xprs[0])
rhs2 = str(xdata.xprs[1])
assignment = (
lhs
+ " := bit-field-insert("
+ rhs1
+ ", "
+ rhs2
+ ", lsb:"
+ str(self.lsb)
+ ", width:"
+ str(self.width))
if xdata.has_unknown_instruction_condition():
return "if ? then " + assignment
elif xdata.has_instruction_condition():
c = str(xdata.xprs[1])
return "if " + c + " then " + assignment
xd = ARMBitFieldInsertXData(xdata)
if xd.is_ok:
lhs = str(xd.vrd)
rhs1 = str(xd.xrd)
rhs2 = str(xd.xrn)
assignment = (
lhs
+ " := bit-field-insert("
+ rhs1
+ ", "
+ rhs2
+ ", lsb:"
+ str(self.lsb)
+ ", width:"
+ str(self.width))
if xdata.has_unknown_instruction_condition():
return "if ? then " + assignment
elif xdata.has_instruction_condition():
c = str(xdata.xprs[1])
return "if " + c + " then " + assignment
else:
return assignment
else:
return assignment
return "Error value"

def ast_prov(
self,
Expand Down
34 changes: 27 additions & 7 deletions chb/arm/opcodes/ARMBranch.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,29 @@ def xtgt(self) -> "XXpr":
index = 1 if self.is_unconditional else 4
return self.xpr(index, "xtgt")

@property
def is_xtgt_known(self) -> bool:
index = 1 if self.is_unconditional else 4
return self.xdata.xprs_r[index] is not None

@property
def annotation(self) -> str:
if self._xdata.has_branch_conditions():
return "if " + str(self.tcond) + " then goto " + str(self.xtgt)
elif self.is_unconditional:
return "goto " + str(self.xtgt)
if self.is_ok:
if self._xdata.has_branch_conditions():
return "if " + str(self.tcond) + " then goto " + str(self.xtgt)
elif self.is_unconditional:
return "goto " + str(self.xtgt)
else:
return "?"
elif self.is_xtgt_known:
if self._xdata.has_branch_conditions():
return "if " + str(self.txpr) + " then goto " + str(self.xtgt)
elif self.is_unconditional:
return "goto " + str(self.xtgt)
else:
return "?"
else:
return "?"
return "Error value"


@armregistry.register_tag("B", ARMOpcode)
Expand Down Expand Up @@ -151,7 +166,10 @@ def ft_conditions_basic(self, xdata: InstrXData) -> Sequence[XXpr]:
def ft_conditions(self, xdata: InstrXData) -> Sequence[XXpr]:
xd = ARMBranchXData(xdata)
if xdata.has_branch_conditions():
return [xd.fcond, xd.tcond]
if xd.is_ok:
return [xd.fcond, xd.tcond]
else:
return [xd.fxpr, xd.txpr]
else:
return []

Expand Down Expand Up @@ -191,7 +209,7 @@ def annotation(self, xdata: InstrXData) -> str:
else:
return xd.annotation
else:
return "Error value"
return xd.annotation

def target_expr_ast(
self,
Expand Down Expand Up @@ -264,6 +282,8 @@ def default(condition: XXpr) -> AST.ASTExpr:
# case there are no rewritten variables, but this still has to be
# validated with more instances.

xd = ARMBranchXData(xdata)

ftconds_basic = self.ft_conditions(xdata)
ftconds = self.ft_conditions(xdata)

Expand Down
42 changes: 31 additions & 11 deletions chb/arm/opcodes/ARMByteReverseWord.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# ------------------------------------------------------------------------------
# The MIT License (MIT)
#
# Copyright (c) 2021-2023 Aarno Labs LLC
# Copyright (c) 2021-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 All @@ -30,7 +30,7 @@
from chb.app.InstrXData import InstrXData

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

import chb.ast.ASTNode as AST
Expand All @@ -44,6 +44,28 @@

if TYPE_CHECKING:
from chb.arm.ARMDictionary import ARMDictionary
from chb.invariants.XVariable import XVariable
from chb.invariants.XXpr import XXpr


class ARMByteReverseWordXData(ARMOpcodeXData):
"""REV <rd> <rn>"""

def __init__(self, xdata: InstrXData) -> None:
ARMOpcodeXData.__init__(self, xdata)

@property
def vrd(self) -> "XVariable":
return self.var(0, "vrd")

@property
def xrn(self) -> "XXpr":
return self.xpr(0, "xrn")

@property
def xxrn(self) -> "XXpr":
return self.xpr(1, "xxrn")



@armregistry.register_tag("REV", ARMOpcode)
Expand Down Expand Up @@ -89,16 +111,14 @@ def opargs(self) -> List[ARMOperand]:
return [self.armd.arm_operand(i) for i in self.args[:-1]]

def annotation(self, xdata: InstrXData) -> str:
lhs = str(xdata.vars[0])
rhs = str(xdata.xprs[1])
assignment = lhs + " := __rev(" + str(rhs) + ") intrinsic"
if xdata.has_unknown_instruction_condition():
return "if ? then " + assignment
elif xdata.has_instruction_condition():
c = str(xdata.xprs[1])
return "if " + c + " then " + assignment
else:
xd = ARMByteReverseWordXData(xdata)
if xd.is_ok:
lhs = str(xd.vrd)
rhs = str(xd.xxrn)
assignment = lhs + " := __rev(" + str(rhs) + ") intrinsic"
return assignment
else:
return "Error value"

# --------------------------------------------------------------------------
# Operation
Expand Down
Loading
Loading