Search in sources :

Example 1 with Insn

use of soot.toDex.instructions.Insn in project soot by Sable.

the class RegisterAssigner method addMovesForIncompatRegs.

/**
 * Adds move instructions to put values into lower registers before using
 * them in an instruction. This assumes that enough registers have been
 * reserved at 0...n.
 *
 * @param curInsn
 * @param insns
 * @param regs
 * @param incompatRegs
 */
private void addMovesForIncompatRegs(Insn curInsn, InstructionIterator insns, List<Register> regs, BitSet incompatRegs) {
    Register newRegister = null;
    final Register resultReg = regs.get(0);
    final boolean hasResultReg = curInsn.getOpcode().setsRegister() || curInsn.getOpcode().setsWideRegister();
    Insn moveResultInsn = null;
    // extra MOVEs are added _before_ the current insn
    insns.previous();
    int nextNewDestination = 0;
    for (int regIdx = 0; regIdx < regs.size(); regIdx++) {
        if (incompatRegs.get(regIdx)) {
            // reg is incompatible -> add extra MOVE
            Register incompatReg = regs.get(regIdx);
            if (incompatReg.isEmptyReg()) {
                /*
					 * second half of a wide reg: do not add a move, since the
					 * empty reg is only considered incompatible to reserve the
					 * subsequent reg number
					 */
                continue;
            }
            Register source = incompatReg.clone();
            Register destination = new Register(source.getType(), nextNewDestination);
            nextNewDestination += SootToDexUtils.getDexWords(source.getType());
            if (source.getNumber() != destination.getNumber()) {
                Insn extraMove = StmtVisitor.buildMoveInsn(destination, source);
                // advances the cursor,
                insns.add(extraMove, curInsn, null);
                // so no next()
                // needed
                // finally patch the original, incompatible reg
                incompatReg.setNumber(destination.getNumber());
                // result as well
                if (hasResultReg && regIdx == resultReg.getNumber()) {
                    moveResultInsn = StmtVisitor.buildMoveInsn(source, destination);
                    newRegister = destination;
                }
            }
        }
    }
    // get past current insn again
    insns.next();
    if (moveResultInsn != null)
        // advances the
        insns.add(moveResultInsn, curInsn, newRegister);
// cursor, so no
// next() needed
}
Also used : Insn(soot.toDex.instructions.Insn) TwoRegInsn(soot.toDex.instructions.TwoRegInsn) AddressInsn(soot.toDex.instructions.AddressInsn)

Example 2 with Insn

use of soot.toDex.instructions.Insn in project soot by Sable.

the class RegisterAssigner method addMoveForIncompatResultReg.

private void addMoveForIncompatResultReg(InstructionIterator insns, Register destReg, Register origResultReg, Insn curInsn) {
    if (destReg.getNumber() == 0) {
        // destination reg is already where we want it: avoid "move r0, r0"
        return;
    }
    // fix reg in original insn
    origResultReg.setNumber(0);
    Register sourceReg = new Register(destReg.getType(), 0);
    Insn extraMove = StmtVisitor.buildMoveInsn(destReg, sourceReg);
    insns.add(extraMove, curInsn, destReg);
}
Also used : Insn(soot.toDex.instructions.Insn) TwoRegInsn(soot.toDex.instructions.TwoRegInsn) AddressInsn(soot.toDex.instructions.AddressInsn)

Example 3 with Insn

use of soot.toDex.instructions.Insn in project soot by Sable.

the class StmtVisitor method getRealInsns.

public List<BuilderInstruction> getRealInsns(LabelAssigner labelAssigner) {
    List<BuilderInstruction> finalInsns = new ArrayList<BuilderInstruction>();
    for (Insn i : insns) {
        if (i instanceof AddressInsn) {
            // skip non-insns
            continue;
        }
        BuilderInstruction realInsn = i.getRealInsn(labelAssigner);
        finalInsns.add(realInsn);
        if (insnStmtMap.containsKey(i)) {
            // get tags
            instructionInsnMap.put(realInsn, i);
        }
        LocalRegisterAssignmentInformation assignmentInfo = insnRegisterMap.get(i);
        if (assignmentInfo != null)
            instructionRegisterMap.put(realInsn, assignmentInfo);
        if (i instanceof AbstractPayload)
            instructionPayloadMap.put(realInsn, (AbstractPayload) i);
    }
    return finalInsns;
}
Also used : AddressInsn(soot.toDex.instructions.AddressInsn) Insn(soot.toDex.instructions.Insn) BuilderInstruction(org.jf.dexlib2.builder.BuilderInstruction) ArrayList(java.util.ArrayList) AddressInsn(soot.toDex.instructions.AddressInsn) AbstractPayload(soot.toDex.instructions.AbstractPayload)

Example 4 with Insn

use of soot.toDex.instructions.Insn in project soot by Sable.

the class ExprVisitor method buildInvokeInsn.

private Insn buildInvokeInsn(String invokeOpcode, MethodReference method, List<Register> argumentRegs) {
    Insn invokeInsn;
    int regCountForArguments = SootToDexUtils.getRealRegCount(argumentRegs);
    if (regCountForArguments <= 5) {
        Register[] paddedArray = pad35cRegs(argumentRegs);
        Opcode opc = Opcode.valueOf(invokeOpcode);
        invokeInsn = new Insn35c(opc, regCountForArguments, paddedArray[0], paddedArray[1], paddedArray[2], paddedArray[3], paddedArray[4], method);
    } else if (regCountForArguments <= 255) {
        Opcode opc = Opcode.valueOf(invokeOpcode + "_RANGE");
        invokeInsn = new Insn3rc(opc, argumentRegs, (short) regCountForArguments, method);
    } else {
        throw new Error("too many parameter registers for invoke-* (> 255): " + regCountForArguments + " or registers too big (> 4 bits)");
    }
    // save the return type for the move-result insn
    stmtV.setLastReturnTypeDescriptor(method.getReturnType());
    return invokeInsn;
}
Also used : Insn(soot.toDex.instructions.Insn) Insn35c(soot.toDex.instructions.Insn35c) Insn3rc(soot.toDex.instructions.Insn3rc) Opcode(org.jf.dexlib2.Opcode)

Example 5 with Insn

use of soot.toDex.instructions.Insn in project soot by Sable.

the class RegisterAssigner method finishRegs.

public List<Insn> finishRegs(List<Insn> insns, Map<Insn, Stmt> insnsStmtMap, Map<Insn, LocalRegisterAssignmentInformation> instructionRegisterMap, List<LocalRegisterAssignmentInformation> parameterInstructionsList) {
    renumParamRegsToHigh(insns, parameterInstructionsList);
    reserveRegisters(insns, insnsStmtMap, parameterInstructionsList);
    InstructionIterator insnIter = new InstructionIterator(insns, insnsStmtMap, instructionRegisterMap);
    while (insnIter.hasNext()) {
        Insn oldInsn = insnIter.next();
        if (oldInsn.hasIncompatibleRegs()) {
            Insn fittingInsn = findFittingInsn(oldInsn);
            if (fittingInsn != null) {
                insnIter.set(fittingInsn, oldInsn);
            } else {
                fixIncompatRegs(oldInsn, insnIter);
            }
        }
    }
    return insns;
}
Also used : Insn(soot.toDex.instructions.Insn) TwoRegInsn(soot.toDex.instructions.TwoRegInsn) AddressInsn(soot.toDex.instructions.AddressInsn)

Aggregations

Insn (soot.toDex.instructions.Insn)12 AddressInsn (soot.toDex.instructions.AddressInsn)9 TwoRegInsn (soot.toDex.instructions.TwoRegInsn)6 BuilderInstruction (org.jf.dexlib2.builder.BuilderInstruction)3 IdentityStmt (soot.jimple.IdentityStmt)3 MonitorStmt (soot.jimple.MonitorStmt)3 NopStmt (soot.jimple.NopStmt)3 Stmt (soot.jimple.Stmt)3 ArrayList (java.util.ArrayList)2 InsnWithOffset (soot.toDex.instructions.InsnWithOffset)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Opcode (org.jf.dexlib2.Opcode)1 BuilderOffsetInstruction (org.jf.dexlib2.builder.BuilderOffsetInstruction)1 Label (org.jf.dexlib2.builder.Label)1 Instruction (org.jf.dexlib2.iface.instruction.Instruction)1 Local (soot.Local)1 Value (soot.Value)1 AssignStmt (soot.jimple.AssignStmt)1 BreakpointStmt (soot.jimple.BreakpointStmt)1