Search in sources :

Example 6 with Insn

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

the class RegisterAssigner method renumParamRegsToHigh.

private void renumParamRegsToHigh(List<Insn> insns, List<LocalRegisterAssignmentInformation> parameterInstructionsList) {
    int regCount = regAlloc.getRegCount();
    int paramRegCount = regAlloc.getParamRegCount();
    if (paramRegCount == 0 || paramRegCount == regCount) {
        // no params or no locals -> nothing to do
        return;
    }
    for (Insn insn : insns) {
        for (Register r : insn.getRegs()) {
            renumParamRegToHigh(r, regCount, paramRegCount);
        }
    }
    for (LocalRegisterAssignmentInformation parameter : parameterInstructionsList) {
        renumParamRegToHigh(parameter.getRegister(), regCount, paramRegCount);
    }
}
Also used : Insn(soot.toDex.instructions.Insn) TwoRegInsn(soot.toDex.instructions.TwoRegInsn) AddressInsn(soot.toDex.instructions.AddressInsn)

Example 7 with Insn

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

the class RegisterAssigner method reserveRegisters.

/**
 * Reserves low registers in case we later find an instruction that has
 * short operands. We can then move the real operands into the reserved low
 * ones and use those instead.
 *
 * @param insns
 * @param insnsStmtMap
 * @param parameterInstructionsList
 */
private void reserveRegisters(List<Insn> insns, Map<Insn, Stmt> insnsStmtMap, List<LocalRegisterAssignmentInformation> parameterInstructionsList) {
    // reserve registers as long as new ones are needed
    int reservedRegs = 0;
    while (true) {
        int regsNeeded = getRegsNeeded(reservedRegs, insns, insnsStmtMap);
        int regsToReserve = regsNeeded - reservedRegs;
        if (regsToReserve <= 0) {
            break;
        }
        regAlloc.increaseRegCount(regsToReserve);
        // "reservation": shift the old regs to higher numbers
        for (Insn insn : insns) {
            shiftRegs(insn, regsToReserve);
        }
        for (LocalRegisterAssignmentInformation info : parameterInstructionsList) {
            Register r = info.getRegister();
            r.setNumber(r.getNumber() + regsToReserve);
        }
        reservedRegs += regsToReserve;
    }
}
Also used : Insn(soot.toDex.instructions.Insn) TwoRegInsn(soot.toDex.instructions.TwoRegInsn) AddressInsn(soot.toDex.instructions.AddressInsn)

Example 8 with Insn

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

the class RegisterAssigner method getRegsNeeded.

/**
 * Gets the maximum number of registers needed by a single instruction in
 * the given list of instructions.
 *
 * @param regsAlreadyReserved
 * @param insns
 * @param insnsStmtMap
 * @return
 */
private int getRegsNeeded(int regsAlreadyReserved, List<Insn> insns, Map<Insn, Stmt> insnsStmtMap) {
    // we only need regs that weren't
    int regsNeeded = regsAlreadyReserved;
    // reserved yet
    for (int i = 0; i < insns.size(); i++) {
        Insn insn = insns.get(i);
        if (insn instanceof AddressInsn) {
            // needs no regs/fitting
            continue;
        }
        // first try to find a better opcode
        Insn fittingInsn = findFittingInsn(insn);
        if (fittingInsn != null) {
            // use the fitting instruction and continue with next one
            insns.set(i, fittingInsn);
            insnsStmtMap.put(fittingInsn, insnsStmtMap.get(insn));
            insnsStmtMap.remove(insn);
            continue;
        }
        // no fitting instruction -> save if we need more registers
        int newRegsNeeded = insn.getMinimumRegsNeeded();
        if (newRegsNeeded > regsNeeded) {
            regsNeeded = newRegsNeeded;
        }
    }
    return regsNeeded;
}
Also used : Insn(soot.toDex.instructions.Insn) TwoRegInsn(soot.toDex.instructions.TwoRegInsn) AddressInsn(soot.toDex.instructions.AddressInsn) AddressInsn(soot.toDex.instructions.AddressInsn)

Example 9 with Insn

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

the class StmtVisitor method reduceInstructions.

/**
 * Reduces the instruction list by removing unnecessary instruction pairs
 * such as move v0 v1; move v1 v0;
 * @param trapReferences
 */
private void reduceInstructions(Set<Unit> trapReferences) {
    for (int i = 0; i < this.insns.size() - 1; i++) {
        Insn curInsn = this.insns.get(i);
        // Only consider real instructions
        if (curInsn instanceof AddressInsn)
            continue;
        if (!isReducableMoveInstruction(curInsn.getOpcode()))
            continue;
        // Skip over following address instructions
        Insn nextInsn = null;
        int nextIndex = -1;
        for (int j = i + 1; j < this.insns.size(); j++) {
            Insn candidate = this.insns.get(j);
            if (candidate instanceof AddressInsn)
                continue;
            nextInsn = candidate;
            nextIndex = j;
            break;
        }
        if (nextInsn == null || !isReducableMoveInstruction(nextInsn.getOpcode()))
            continue;
        // jump targets to the successor
        if (nextIndex == this.insns.size() - 1)
            continue;
        // Check if we have a <- b; b <- a;
        Register firstTarget = curInsn.getRegs().get(0);
        Register firstSource = curInsn.getRegs().get(1);
        Register secondTarget = nextInsn.getRegs().get(0);
        Register secondSource = nextInsn.getRegs().get(1);
        if (firstTarget.equals(secondSource) && secondTarget.equals(firstSource)) {
            Stmt nextStmt = insnStmtMap.get(nextInsn);
            // instructions may depend on the register being set.
            if (nextStmt == null || (!isJumpTarget(nextStmt) && !trapReferences.contains(nextStmt))) {
                insns.remove(nextIndex);
                if (nextStmt != null) {
                    Insn nextInst = this.insns.get(nextIndex + 1);
                    insnStmtMap.remove(nextInsn);
                    insnStmtMap.put(nextInst, nextStmt);
                }
            }
        }
    }
}
Also used : AddressInsn(soot.toDex.instructions.AddressInsn) Insn(soot.toDex.instructions.Insn) AddressInsn(soot.toDex.instructions.AddressInsn) BreakpointStmt(soot.jimple.BreakpointStmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) NopStmt(soot.jimple.NopStmt) GotoStmt(soot.jimple.GotoStmt) RetStmt(soot.jimple.RetStmt) AssignStmt(soot.jimple.AssignStmt) ThrowStmt(soot.jimple.ThrowStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) TableSwitchStmt(soot.jimple.TableSwitchStmt) MonitorStmt(soot.jimple.MonitorStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) ReturnStmt(soot.jimple.ReturnStmt) ExitMonitorStmt(soot.jimple.ExitMonitorStmt) Stmt(soot.jimple.Stmt)

Example 10 with Insn

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

the class StmtVisitor method caseAssignStmt.

@Override
public void caseAssignStmt(AssignStmt stmt) {
    // If this is the beginning of an array initialization, we shortcut the
    // normal translation process
    List<Value> arrayValues = arrayInitDetector.getValuesForArrayInit(stmt);
    if (arrayValues != null) {
        Insn insn = buildArrayFillInsn((ArrayRef) stmt.getLeftOp(), arrayValues);
        if (insn != null) {
            addInsn(insn, stmt);
            return;
        }
    }
    if (arrayInitDetector.getIgnoreUnits().contains(stmt)) {
        return;
    }
    constantV.setOrigStmt(stmt);
    exprV.setOrigStmt(stmt);
    Value lhs = stmt.getLeftOp();
    if (lhs instanceof ConcreteRef) {
        // special cases that lead to *put* opcodes
        Value source = stmt.getRightOp();
        addInsn(buildPutInsn((ConcreteRef) lhs, source), stmt);
        return;
    }
    // other cases, where lhs is a local
    if (!(lhs instanceof Local)) {
        throw new Error("left-hand side of AssignStmt is not a Local: " + lhs.getClass());
    }
    Local lhsLocal = (Local) lhs;
    final Insn newInsn;
    Register lhsReg = regAlloc.asLocal(lhsLocal);
    Value rhs = stmt.getRightOp();
    if (rhs instanceof Local) {
        // move rhs local to lhs local, if different
        Local rhsLocal = (Local) rhs;
        if (lhsLocal == rhsLocal) {
            return;
        }
        Register sourceReg = regAlloc.asLocal(rhsLocal);
        newInsn = buildMoveInsn(lhsReg, sourceReg);
        addInsn(newInsn, stmt);
    } else if (rhs instanceof Constant) {
        // move rhs constant into the lhs local
        constantV.setDestination(lhsReg);
        rhs.apply(constantV);
        newInsn = insns.get(insns.size() - 1);
    } else if (rhs instanceof ConcreteRef) {
        newInsn = buildGetInsn((ConcreteRef) rhs, lhsReg);
        addInsn(newInsn, stmt);
    } else {
        // evaluate rhs expression, saving the result in the lhs local
        exprV.setDestinationReg(lhsReg);
        rhs.apply(exprV);
        if (rhs instanceof InvokeExpr) {
            // do the actual "assignment" for an invocation: move its result
            // to the lhs reg (it was not used yet)
            Insn moveResultInsn = buildMoveResultInsn(lhsReg);
            int invokeInsnIndex = exprV.getLastInvokeInstructionPosition();
            insns.add(invokeInsnIndex + 1, moveResultInsn);
        }
        newInsn = insns.get(insns.size() - 1);
    }
    this.insnRegisterMap.put(newInsn, LocalRegisterAssignmentInformation.v(lhsReg, lhsLocal));
}
Also used : AddressInsn(soot.toDex.instructions.AddressInsn) Insn(soot.toDex.instructions.Insn) InvokeExpr(soot.jimple.InvokeExpr) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) IntConstant(soot.jimple.IntConstant) ClassConstant(soot.jimple.ClassConstant) FloatConstant(soot.jimple.FloatConstant) Value(soot.Value) Local(soot.Local) ConcreteRef(soot.jimple.ConcreteRef)

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