|
25 | 25 | # SOFTWARE. |
26 | 26 | # ------------------------------------------------------------------------------ |
27 | 27 |
|
28 | | -from typing import List, TYPE_CHECKING |
| 28 | +from typing import List, Tuple, TYPE_CHECKING |
29 | 29 |
|
30 | 30 | from chb.app.InstrXData import InstrXData |
31 | 31 |
|
32 | 32 | from chb.arm.ARMDictionaryRecord import armregistry |
33 | 33 | from chb.arm.ARMOpcode import ARMOpcode, ARMOpcodeXData, simplify_result |
34 | 34 | from chb.arm.ARMOperand import ARMOperand |
35 | 35 |
|
| 36 | +import chb.ast.ASTNode as AST |
| 37 | +from chb.astinterface.ASTInterface import ASTInterface |
| 38 | + |
| 39 | +import chb.invariants.XXprUtil as XU |
| 40 | + |
36 | 41 | import chb.util.fileutil as UF |
37 | 42 | from chb.util.IndexedTable import IndexedTableValue |
38 | 43 | from chb.util.loggingutil import chklogger |
@@ -119,9 +124,105 @@ def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None: |
119 | 124 | def operands(self) -> List[ARMOperand]: |
120 | 125 | return [self.armd.arm_operand(i) for i in self.args[1:]] |
121 | 126 |
|
| 127 | + @property |
| 128 | + def opargs(self) -> List[ARMOperand]: |
| 129 | + return [self.armd.arm_operand(i) for i in self.args[1:]] |
| 130 | + |
122 | 131 | def annotation(self, xdata: InstrXData) -> str: |
123 | 132 | xd = ARMSignedMultiplyLongXData(xdata) |
124 | 133 | if xd.is_ok: |
125 | 134 | return xd.annotation |
126 | 135 | else: |
127 | 136 | return "Error value" |
| 137 | + |
| 138 | + def ast_prov( |
| 139 | + self, |
| 140 | + astree: ASTInterface, |
| 141 | + iaddr: str, |
| 142 | + bytestring: str, |
| 143 | + xdata: InstrXData) -> Tuple[ |
| 144 | + List[AST.ASTInstruction], List[AST.ASTInstruction]]: |
| 145 | + |
| 146 | + annotations: List[str] = [iaddr, "SMULL"] |
| 147 | + |
| 148 | + # low-level assignment |
| 149 | + |
| 150 | + (ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree) |
| 151 | + (ll_lhs2, _, _) = self.opargs[1].ast_lvalue(astree) |
| 152 | + (ll_op1, _, _) = self.opargs[2].ast_rvalue(astree) |
| 153 | + (ll_op2, _, _) = self.opargs[3].ast_rvalue(astree) |
| 154 | + ll_rhs = astree.mk_binary_op("mult", ll_op1, ll_op2) |
| 155 | + e32 = astree.mk_integer_constant(0x10000000) |
| 156 | + ll_rhs = astree.mk_binary_op("div", ll_rhs, e32) |
| 157 | + ll_rhs2 = astree.mk_binary_op("mod", ll_rhs, e32) |
| 158 | + |
| 159 | + ll_assign1 = astree.mk_assign( |
| 160 | + ll_lhs, |
| 161 | + ll_rhs, |
| 162 | + iaddr=iaddr, |
| 163 | + bytestring=bytestring, |
| 164 | + annotations=annotations) |
| 165 | + ll_assign2 = astree.mk_assign( |
| 166 | + ll_lhs2, |
| 167 | + ll_rhs2, |
| 168 | + iaddr=iaddr, |
| 169 | + bytestring=bytestring, |
| 170 | + annotations=annotations) |
| 171 | + |
| 172 | + rdefs = xdata.reachingdefs |
| 173 | + |
| 174 | + astree.add_expr_reachingdefs(ll_op1, [rdefs[0]]) |
| 175 | + astree.add_expr_reachingdefs(ll_op2, [rdefs[1]]) |
| 176 | + |
| 177 | + # high-level assignment |
| 178 | + |
| 179 | + xd = ARMSignedMultiplyLongXData(xdata) |
| 180 | + if not xd.is_ok: |
| 181 | + chklogger.logger.error( |
| 182 | + "Encountered error value at address %s", iaddr) |
| 183 | + return ([], []) |
| 184 | + |
| 185 | + lhs = xd.vlo |
| 186 | + lhs2 = xd.vhi |
| 187 | + rhs1 = xd.xrn |
| 188 | + rhs2 = xd.xrm |
| 189 | + rhslo = xd.loresult |
| 190 | + rhshi = xd.hiresult |
| 191 | + |
| 192 | + defuses = xdata.defuses |
| 193 | + defuseshigh = xdata.defuseshigh |
| 194 | + |
| 195 | + hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree) |
| 196 | + hl_lhs2 = XU.xvariable_to_ast_lval(lhs2, xdata, iaddr, astree) |
| 197 | + hl_rhs = XU.xxpr_to_ast_def_expr(rhslo, xdata, iaddr, astree) |
| 198 | + hl_rhs2 = XU.xxpr_to_ast_def_expr(rhshi, xdata, iaddr, astree) |
| 199 | + |
| 200 | + hl_assign1 = astree.mk_assign( |
| 201 | + hl_lhs, |
| 202 | + hl_rhs, |
| 203 | + iaddr=iaddr, |
| 204 | + bytestring=bytestring, |
| 205 | + annotations=annotations) |
| 206 | + hl_assign2 = astree.mk_assign( |
| 207 | + hl_lhs2, |
| 208 | + hl_rhs2, |
| 209 | + iaddr=iaddr, |
| 210 | + bytestring=bytestring, |
| 211 | + annotations=annotations) |
| 212 | + |
| 213 | + astree.add_instr_mapping(hl_assign1, ll_assign1) |
| 214 | + astree.add_instr_mapping(hl_assign2, ll_assign2) |
| 215 | + astree.add_instr_address(hl_assign1, [iaddr]) |
| 216 | + astree.add_instr_address(hl_assign2, [iaddr]) |
| 217 | + astree.add_expr_mapping(hl_rhs, ll_rhs) |
| 218 | + astree.add_expr_mapping(hl_rhs2, ll_rhs2) |
| 219 | + astree.add_lval_mapping(hl_lhs, ll_lhs) |
| 220 | + astree.add_lval_mapping(hl_lhs2, ll_lhs2) |
| 221 | + astree.add_expr_reachingdefs(hl_rhs, rdefs[2:]) |
| 222 | + astree.add_expr_reachingdefs(ll_rhs, rdefs[:2]) |
| 223 | + astree.add_lval_defuses(hl_lhs, defuses[0]) |
| 224 | + astree.add_lval_defuses(hl_lhs2, defuses[1]) |
| 225 | + astree.add_lval_defuses_high(hl_lhs, defuseshigh[0]) |
| 226 | + astree.add_lval_defuses_high(hl_lhs2, defuseshigh[1]) |
| 227 | + |
| 228 | + return ([hl_assign1, hl_assign2], [ll_assign1, ll_assign2]) |
0 commit comments