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
}
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);
}
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;
}
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;
}
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;
}
Aggregations