def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str, xdata: InstrXData) -> List[AST.ASTInstruction]: regsop = self.operands[1] if not regsop.is_register_list: raise UF.CHBError("Argument to push is not a register list") (splval, _, _) = self.operands[0].ast_lvalue(astree) (sprval, _, _) = self.operands[0].ast_rvalue(astree) instrs: List[AST.ASTInstruction] = [] registers = regsop.registers sp_decr = 4 * len(registers) sp_offset = sp_decr for r in registers: sp_offset_c = astree.mk_integer_constant(sp_offset) addr = astree.mk_binary_op("minus", sprval, sp_offset_c) lhs = astree.mk_memref_lval(addr) rhs = astree.mk_register_variable_expr(r) instrs.append(astree.mk_assign(lhs, rhs)) sp_offset -= 4 sp_decr_c = astree.mk_integer_constant(sp_decr) sp_rhs = astree.mk_binary_op("minus", sprval, sp_decr_c) instrs.append(astree.mk_assign(splval, sp_rhs)) astree.add_instruction_span(instrs[0].id, iaddr, bytestring) return instrs
def basevar_variable_to_ast_lval(basevar: "X.XVariable", offset: "VMemoryOffset", astree: AbstractSyntaxTree) -> AST.ASTLval: if offset.is_constant_value_offset: offsetvalue = offset.offsetvalue() baselval = xvariable_to_ast_lval(basevar, astree) basetype = baselval.ctype if basetype is not None: if basetype.is_array: elttype = cast("BCTypArray", basetype).tgttyp eltsize = elttype.byte_size() index = offsetvalue // eltsize indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) elif basetype.is_pointer: tgttype = cast("BCTypPtr", basetype).tgttyp basexpr = astree.mk_lval_expr(baselval) if tgttype.is_scalar: tgtsize = tgttype.byte_size() index = offsetvalue // tgtsize indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) elif tgttype.is_struct: compinfo = cast("BCTypComp", tgttype).compinfo fieldoffset = field_at_offset(compinfo, offsetvalue, astree) return astree.mk_memref_lval(basexpr, fieldoffset) elif tgttype.is_void: index = offsetvalue indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) elif offsetvalue == 0: return astree.mk_memref_lval(basexpr) else: print(" -> Basevar with basetype") else: index = offsetvalue indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) print("Basevar_variable: " + str(basevar) + "; offset: " + str(offset)) return astree.mk_variable_lval(str(basevar) + str(offset))
def ast_lvalue( self, astree: AbstractSyntaxTree ) -> Tuple[AST.ASTLval, List[AST.ASTInstruction], List[AST.ASTInstruction]]: offset = self.memory_offset.ast_rvalue(astree) if not self.is_add: offset = astree.mk_unary_op("minus", offset) xreg = astree.mk_register_variable_expr(self.register) xindex = astree.mk_binary_op("plus", xreg, offset) if self.is_write_back: reglv = astree.mk_variable_lval(self.register) assign = astree.mk_assign(reglv, xindex) if self.is_index: memexp = astree.mk_memref_lval(xindex) return (memexp, [], [assign]) else: memexp = astree.mk_memref_lval(xreg) return (memexp, [], [assign]) else: memexp = astree.mk_memref_lval(xindex) return (memexp, [], [])
def xtyped_expr_to_ast_expr(op: str, op1: AST.ASTExpr, op2: AST.ASTExpr, astree: AbstractSyntaxTree) -> AST.ASTExpr: """Determine if expression needs different representation based on type.""" if op1.ctype is None: raise UF.CHBError("Expression is not typed: " + str(op1)) if op1.ctype.is_pointer and op2.is_integer_constant: op2 = cast(AST.ASTIntegerConstant, op2) tgttype = cast("BCTypPtr", op1.ctype).tgttyp if tgttype.is_struct: compinfo = cast("BCTypComp", tgttype).compinfo fieldoffset = field_at_offset(compinfo, op2.cvalue, astree) lval = astree.mk_memref_lval(op1, fieldoffset) return astree.mk_address_of(lval) return astree.mk_binary_op(op, op1, op2)