bool
SgAsmMipsInstruction::get_branch_target(rose_addr_t *target)
{
    SgAsmExpressionPtrList &args = get_operandList()->get_operands();
    switch (get_kind()) {
        case mips_j:
        case mips_jal:
        case mips_jalx: {
            // target address stored in first argument
            assert(args.size()>=1);
            if (target) {
                SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[0]);
                assert(ival!=NULL);
                *target = ival->get_absolute_value();
            }
            return true;
        }

        case mips_bgez:
        case mips_bgezal:
        case mips_bgezall:
        case mips_bgezl:
        case mips_bgtz:
        case mips_bgtzl:
        case mips_blez:
        case mips_blezl:
        case mips_bltz:
        case mips_bltzal:
        case mips_bltzall:
        case mips_bltzl: {
            // target address stored in the second argument
            assert(args.size()>=2);
            if (target) {
                SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[1]);
                assert(ival!=NULL);
                *target = ival->get_absolute_value();
            }
            return true;
        }

        case mips_beq:
        case mips_beql:
        case mips_bne:
        case mips_bnel: {
            // target address stored in the third argument
            assert(args.size()>=3);
            if (target) {
                SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[2]);
                assert(ival!=NULL);
                *target = ival->get_absolute_value();
            }
            return true;
        }

        default:
            // no known target; do not modify *target
            return false;
    }
}
Exemple #2
0
/** Return control flow successors. See base class for full documentation. */
Disassembler::AddressSet
SgAsmArmInstruction::get_successors(bool *complete) {
    Disassembler::AddressSet retval;
    const std::vector<SgAsmExpression*> &exprs = get_operandList()->get_operands();
    *complete = true; /*assume retval is the complete set of successors for now*/

    switch (get_kind()) {
        case arm_b:
        case arm_bl:
        case arm_blx:
        case arm_bx: {
            /* Branch target */
            ROSE_ASSERT(exprs.size()==1);
            SgAsmExpression *dest = exprs[0];
            if (isSgAsmValueExpression(dest)) {
                rose_addr_t target_va = SageInterface::getAsmConstant(isSgAsmValueExpression(dest));
                retval.insert(target_va);
            } else {
                /* Could also be a register reference expression, but we don't know the successor in that case. */
                *complete = false;
            }
            
            /* Fall-through address */
            if (get_condition()!=arm_cond_al)
                retval.insert(get_address()+4);
            break;
        }

        case arm_bxj: {
            /* First argument is the register that holds the next instruction pointer value to use in the case that Jazelle is
             * not available. We only know the successor if the register is the instruction pointer, in which case the
             * successor is the fall-through address. */
            ROSE_ASSERT(exprs.size()==1);
            SgAsmArmRegisterReferenceExpression *rre = isSgAsmArmRegisterReferenceExpression(exprs[0]);
            ROSE_ASSERT(rre);
            if (rre->get_descriptor().get_major()==arm_regclass_gpr && rre->get_descriptor().get_minor()==15) {
                retval.insert(get_address()+4);
            } else {
                *complete = false;
            }
            break;
        }
            
        case arm_cmn:
        case arm_cmp:
        case arm_teq:
        case arm_tst:
            /* Comparison and test instructions don't ever affect the instruction pointer; they only fall through */
            retval.insert(get_address()+4);
            break;

        case arm_bkpt:
        case arm_swi:
        case arm_undefined:
        case arm_unknown_instruction:
            /* No known successors for interrupt-generating instructions */
            break;

        default:
            if (!modifies_ip(this) || get_condition()!=arm_cond_al) {
                retval.insert(get_address()+4);
            } else {
                *complete = false;
            }
            break;
    }
    return retval;
}