Implemented verification for float/double/long comparison instructions

git-svn-id: https://smali.googlecode.com/svn/trunk@582 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2010-01-24 19:54:01 +00:00
parent b7e7811527
commit f1a74cea19

View File

@ -477,6 +477,13 @@ public class MethodAnalyzer {
return handleSwitch(analyzedInstruction, Format.PackedSwitchData); return handleSwitch(analyzedInstruction, Format.PackedSwitchData);
case SPARSE_SWITCH: case SPARSE_SWITCH:
return handleSwitch(analyzedInstruction, Format.SparseSwitchData); 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; assert false;
return false; return false;
@ -1197,6 +1204,50 @@ public class MethodAnalyzer {
return true; 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) { private static void checkRegister(RegisterType registerType, EnumSet validCategories) {
if (!validCategories.contains(registerType.category)) { if (!validCategories.contains(registerType.category)) {
//TODO: add expected categories to error message //TODO: add expected categories to error message