private void analyzeWideConst(@Nonnull AnalyzedInstruction analyzedInstruction) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); }
private void analyzeArrayLength(@Nonnull AnalyzedInstruction analyzedInstruction) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.INTEGER_TYPE); }
private void analyzeFloatWideCmp(@Nonnull AnalyzedInstruction analyzedInstruction) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.BYTE_TYPE); }
private void analyzeInstanceOf(@Nonnull AnalyzedInstruction analyzedInstruction) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.BOOLEAN_TYPE); }
private void analyze32BitPrimitiveAget(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType registerType) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, registerType); }
private void analyze32BitPrimitiveIgetSget(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType registerType) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, registerType); }
private void analyzeUnaryOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType) { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
private void analyzeConst(@Nonnull AnalyzedInstruction analyzedInstruction) { NarrowLiteralInstruction instruction = (NarrowLiteralInstruction)analyzedInstruction.instruction; //we assume that the literal value is a valid value for the given instruction type, because it's impossible //to store an invalid literal with the instruction. so we don't need to check the type of the literal setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterTypeForLiteral(instruction.getNarrowLiteral())); }
private void analyzeMove(@Nonnull AnalyzedInstruction analyzedInstruction) { TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, sourceRegisterType); }
private void analyzeConstString(@Nonnull AnalyzedInstruction analyzedInstruction) { TypeProto stringClass = classPath.getClass("Ljava/lang/String;"); RegisterType stringType = RegisterType.getRegisterType(RegisterType.REFERENCE, stringClass); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, stringType); }
private void analyzeCheckCast(@Nonnull AnalyzedInstruction analyzedInstruction) { ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction; TypeReference reference = (TypeReference)instruction.getReference(); RegisterType castRegisterType = RegisterType.getRegisterType(classPath, reference); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, castRegisterType); }
private void analyzeConstClass(@Nonnull AnalyzedInstruction analyzedInstruction) { TypeProto classClass = classPath.getClass("Ljava/lang/Class;"); RegisterType classType = RegisterType.getRegisterType(RegisterType.REFERENCE, classClass); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, classType); }
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); }
private void analyzeBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType, boolean checkForBoolean) { if (checkForBoolean) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType source1RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); RegisterType source2RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); if (BooleanCategories.get(source1RegisterType.category) && BooleanCategories.get(source2RegisterType.category)) { destRegisterType = RegisterType.BOOLEAN_TYPE; } } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
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 analyzeIgetSgetWideObject(@Nonnull AnalyzedInstruction analyzedInstruction) { ReferenceInstruction referenceInstruction = (ReferenceInstruction)analyzedInstruction.instruction; FieldReference fieldReference = (FieldReference)referenceInstruction.getReference(); RegisterType fieldType = RegisterType.getRegisterType(classPath, fieldReference.getType()); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType); }
private void analyzeNewArray(@Nonnull AnalyzedInstruction analyzedInstruction) { ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction; TypeReference type = (TypeReference)instruction.getReference(); if (type.getType().charAt(0) != '[') { throw new AnalysisException("new-array used with non-array type"); } RegisterType arrayType = RegisterType.getRegisterType(classPath, type); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, arrayType); }
private void analyzeAgetObject(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-object used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; String elementType = arrayProto.getImmediateElementType(); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(elementType))); } else { // If the array register is null, we can assume that the destination register was meant to be a reference // type, so we set the destination to NULL. This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.NULL_TYPE); } }
private void analyzeNewInstance(@Nonnull AnalyzedInstruction analyzedInstruction) { ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction; int register = ((OneRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); RegisterType destRegisterType = analyzedInstruction.getPostInstructionRegisterType(register); if (destRegisterType.category != RegisterType.UNKNOWN) { //the post-instruction destination register will only be set if we have already analyzed this instruction //at least once. If this is the case, then the uninit reference has already been propagated to all //successors and nothing else needs to be done. assert destRegisterType.category == RegisterType.UNINIT_REF; return; } TypeReference typeReference = (TypeReference)instruction.getReference(); RegisterType classType = RegisterType.getRegisterType(classPath, typeReference); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterType(RegisterType.UNINIT_REF, classType.type)); }
private void analyzeMoveResult(@Nonnull AnalyzedInstruction analyzedInstruction) { AnalyzedInstruction previousInstruction = null; if (analyzedInstruction.instructionIndex > 0) { previousInstruction = analyzedInstructions.valueAt(analyzedInstruction.instructionIndex-1); } if (previousInstruction == null || !previousInstruction.instruction.getOpcode().setsResult()) { throw new AnalysisException(analyzedInstruction.instruction.getOpcode().name + " must occur after an " + "invoke-*/fill-new-array instruction"); } RegisterType resultRegisterType; ReferenceInstruction invokeInstruction = (ReferenceInstruction)previousInstruction.instruction; Reference reference = invokeInstruction.getReference(); if (reference instanceof MethodReference) { resultRegisterType = RegisterType.getRegisterType(classPath, ((MethodReference)reference).getReturnType()); } else { resultRegisterType = RegisterType.getRegisterType(classPath, (TypeReference)reference); } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, resultRegisterType); }