@Override int movesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); int source = i.getRegisterB(); if (register == source) { return dest; } return -1; }
protected void writeSecondRegister(IndentingWriter writer) throws IOException { writeRegister(writer, ((TwoRegisterInstruction)instruction).getRegisterB()); }
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; }
@Override boolean isUsedAsFloatingPoint(DexBody body, int register) { int source = ((TwoRegisterInstruction) instruction).getRegisterB(); Opcode opcode = instruction.getOpcode(); switch (opcode) { case NEG_FLOAT: case NEG_DOUBLE: return source == register; default: return false; } } }
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; } }
@Override int movesToRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); int source = i.getRegisterB(); if (register == dest) { return source; } return -1; }
private void analyzeMove(@Nonnull AnalyzedInstruction analyzedInstruction) { TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, sourceRegisterType); }
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; }
private void analyzeBinary2AddrOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType, boolean checkForBoolean) { if (checkForBoolean) { TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; RegisterType source1RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); RegisterType source2RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (BooleanCategories.get(source1RegisterType.category) && BooleanCategories.get(source2RegisterType.category)) { destRegisterType = RegisterType.BOOLEAN_TYPE; } } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
private void analyzeLiteralBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType, boolean checkForBoolean) { if (checkForBoolean) { TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (BooleanCategories.get(sourceRegisterType.category)) { int literal = ((NarrowLiteralInstruction)analyzedInstruction.instruction).getNarrowLiteral(); if (literal == 0 || literal == 1) { destRegisterType = RegisterType.BOOLEAN_TYPE; } } } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; } }
@Override public void jimplify(DexBody body) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); int source = i.getRegisterB(); AssignStmt assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), body.getRegisterLocal(source)); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { DalvikTyper.v().addConstraint(assign.getLeftOpBox(), assign.getRightOpBox()); } }
private RegisterType getDestTypeForLiteralShiftRight(@Nonnull AnalyzedInstruction analyzedInstruction, boolean signedShift) { TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories); long literalShift = ((NarrowLiteralInstruction)analyzedInstruction.instruction).getNarrowLiteral();
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; }
@Override public BinaryMathOp create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); BuilderInstruction instruction = (BuilderInstruction) location.getInstruction(); TwoRegisterInstruction instr = (TwoRegisterInstruction) location.getInstruction(); int destRegister = instr.getRegisterA(); int arg1Register = instr.getRegisterB(); ExceptionFactory exceptionFactory = vm.getExceptionFactory(); if (instruction instanceof Instruction23x) { // add-int vAA, vBB, vCC int arg2Register = ((Instruction23x) instruction).getRegisterC(); return new BinaryMathOp(location, child, destRegister, arg1Register, arg2Register, false, exceptionFactory); } else if (instruction instanceof Instruction12x) { // add-int/2addr vAA, vBB arg1Register = instr.getRegisterA(); int arg2Register = ((Instruction12x) instruction).getRegisterB(); return new BinaryMathOp(location, child, destRegister, arg1Register, arg2Register, false, exceptionFactory); } else if (instruction instanceof NarrowLiteralInstruction) { // Instruction22b - add-int/lit8 vAA, vBB, #CC // Instruction22s - add-int/lit16 vAA, vBB, #CCCC int arg2Literal = ((NarrowLiteralInstruction) instruction).getNarrowLiteral(); return new BinaryMathOp(location, child, destRegister, arg1Register, arg2Literal, true, exceptionFactory); } else { return null; } }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); BuilderInstruction instruction = (BuilderInstruction) location.getInstruction(); String opName = instruction.getOpcode().name; int toRegister = ((OneRegisterInstruction) instruction).getRegisterA(); MoveType moveType = getMoveType(opName); switch (moveType) { case RESULT: case EXCEPTION: return new MoveOp(location, child, toRegister, moveType); case REGISTER: int targetRegister = ((TwoRegisterInstruction) instruction).getRegisterB(); return new MoveOp(location, child, toRegister, targetRegister); default: return null; } }
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; } }
private boolean analyzePutGetVolatile(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { FieldReference field = (FieldReference)((ReferenceInstruction)analyzedInstruction.instruction).getReference(); String fieldType = field.getType(); Opcode originalOpcode = analyzedInstruction.instruction.getOpcode(); Opcode opcode = classPath.getFieldInstructionMapper().getAndCheckDeodexedOpcode( fieldType, originalOpcode); Instruction deodexedInstruction; if (originalOpcode.isStaticFieldAccessor()) { OneRegisterInstruction instruction = (OneRegisterInstruction)analyzedInstruction.instruction; deodexedInstruction = new ImmutableInstruction21c(opcode, instruction.getRegisterA(), field); } else { TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; deodexedInstruction = new ImmutableInstruction22c(opcode, instruction.getRegisterA(), instruction.getRegisterB(), field); } analyzedInstruction.setDeodexedInstruction(deodexedInstruction); if (analyzeResult) { analyzeInstruction(analyzedInstruction); } return true; }
static boolean canPropagateTypeAfterInstanceOf(AnalyzedInstruction analyzedInstanceOfInstruction, AnalyzedInstruction analyzedIfInstruction, ClassPath classPath) { if (!classPath.isArt()) { return false; } Instruction ifInstruction = analyzedIfInstruction.instruction; if (((Instruction21t)ifInstruction).getRegisterA() == analyzedInstanceOfInstruction.getDestinationRegister()) { Reference reference = ((Instruction22c)analyzedInstanceOfInstruction.getInstruction()).getReference(); RegisterType registerType = RegisterType.getRegisterType(classPath, (TypeReference)reference); try { if (registerType.type != null && !registerType.type.isInterface()) { int objectRegister = ((TwoRegisterInstruction)analyzedInstanceOfInstruction.getInstruction()) .getRegisterB(); RegisterType originalType = analyzedIfInstruction.getPreInstructionRegisterType(objectRegister); return isNotWideningConversion(originalType, registerType); } } catch (UnresolvedClassException ex) { return false; } } return false; }
@Override boolean overridesRegister(int register) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); return register == dest; } }