Beispiel #1
0
    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
Beispiel #2
0
def xcompound_to_ast_expr(xc: X.XprCompound,
                          astree: AbstractSyntaxTree) -> AST.ASTExpr:
    """Convert a compound expression to an AST Expr node."""

    op = xc.operator
    operands = xc.operands

    if len(operands) == 1:
        op1 = xxpr_to_ast_expr(operands[0], astree)
        return astree.mk_unary_op(op, op1)

    elif len(operands) == 2:
        if xc.is_stack_address:
            stackoffset = xc.stack_address_offset()
            rhslval = astree.mk_stack_variable_lval(stackoffset)
            return astree.mk_address_of(rhslval)
        else:
            op1 = xxpr_to_ast_expr(operands[0], astree)
            op2 = xxpr_to_ast_expr(operands[1], astree)
            if op1.ctype is not None and op in ["plus", "minus"]:
                return xtyped_expr_to_ast_expr(op, op1, op2, astree)
            else:
                return astree.mk_binary_op(op, op1, op2)

    else:
        raise UF.CHBError("AST conversion of compound expression " + str(xc) +
                          " not yet supported")
Beispiel #3
0
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[AST.ASTInstruction]:
     (rhs1, preinstrs1, postinstrs1) = self.operands[1].ast_rvalue(astree)
     (rhs2, preinstrs2, postinstrs2) = self.operands[2].ast_rvalue(astree)
     (lhs, _, _) = self.operands[0].ast_lvalue(astree)
     binop = astree.mk_binary_op("band", rhs1, rhs2)
     assign = astree.mk_assign(lhs, binop)
     astree.add_instruction_span(assign.id, iaddr, bytestring)
     return preinstrs1 + preinstrs2 + [assign] + postinstrs1 + postinstrs2
Beispiel #4
0
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[ASTInstruction]:
     (lhs, _, _) = self.operands[0].ast_lvalue(astree)
     (op1, _, _) = self.operands[1].ast_rvalue(astree)
     (op2, _, _) = self.operands[2].ast_rvalue(astree)
     binop = astree.mk_binary_op("minus", op1, op2)
     result = astree.mk_assign(lhs, binop)
     astree.add_instruction_span(result.id, iaddr, bytestring)
     return [result]
Beispiel #5
0
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)
    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, [], [])