From f1a74cea19f10e9059e05f1cee6ae45baf118108 Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Sun, 24 Jan 2010 19:54:01 +0000 Subject: [PATCH] Implemented verification for float/double/long comparison instructions git-svn-id: https://smali.googlecode.com/svn/trunk@582 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../dexlib/Code/Analysis/MethodAnalyzer.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java index f16f32e7..a8054772 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java @@ -477,6 +477,13 @@ public class MethodAnalyzer { return handleSwitch(analyzedInstruction, Format.PackedSwitchData); case SPARSE_SWITCH: return handleSwitch(analyzedInstruction, Format.SparseSwitchData); + case CMPL_FLOAT: + case CMPG_FLOAT: + return handleFloatCmp(analyzedInstruction); + case CMPL_DOUBLE: + case CMPG_DOUBLE: + case CMP_LONG: + return handleWideCmp(analyzedInstruction); } assert false; return false; @@ -1197,6 +1204,50 @@ public class MethodAnalyzer { return true; } + private boolean handleFloatCmp(AnalyzedInstruction analyzedInstruction) { + ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; + + RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); + assert registerType != null; + + if (registerType.category == RegisterType.Category.Unknown) { + return false; + } + checkRegister(registerType, Primitive32BitCategories); + + registerType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); + assert registerType != null; + + if (registerType.category == RegisterType.Category.Unknown) { + return false; + } + checkRegister(registerType, Primitive32BitCategories); + + setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, + RegisterType.getRegisterType(RegisterType.Category.Byte, null)); + return true; + } + + private boolean handleWideCmp(AnalyzedInstruction analyzedInstruction) { + ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; + + RegisterType registerType = getAndCheckWideSourcePair(analyzedInstruction, instruction.getRegisterB()); + assert registerType != null; + if (registerType.category == RegisterType.Category.Unknown) { + return false; + } + + registerType = getAndCheckWideSourcePair(analyzedInstruction, instruction.getRegisterC()); + assert registerType != null; + if (registerType.category == RegisterType.Category.Unknown) { + return false; + } + + setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, + RegisterType.getRegisterType(RegisterType.Category.Byte, null)); + return true; + } + private static void checkRegister(RegisterType registerType, EnumSet validCategories) { if (!validCategories.contains(registerType.category)) { //TODO: add expected categories to error message