From 37d14becd11e86c3e634055d0cfe011b51ef5622 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Wed, 14 Oct 2015 21:57:23 -0700 Subject: [PATCH] Fix register propagation when overriding a register type from a predecessor --- .../jf/dexlib2/analysis/AnalyzedInstruction.java | 11 +++++++++-- .../org/jf/dexlib2/analysis/MethodAnalyzer.java | 15 +++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedInstruction.java index 1f600835..ac17db3f 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedInstruction.java @@ -189,12 +189,19 @@ public class AnalyzedInstruction implements Comparable { * register is a destination register for this instruction, or if the pre-instruction register type didn't change * after merging in the given register type */ - protected boolean mergeRegister(int registerNumber, RegisterType registerType, BitSet verifiedInstructions) { + protected boolean mergeRegister(int registerNumber, RegisterType registerType, BitSet verifiedInstructions, + boolean override) { assert registerNumber >= 0 && registerNumber < postRegisterMap.length; assert registerType != null; RegisterType oldRegisterType = preRegisterMap[registerNumber]; - RegisterType mergedRegisterType = oldRegisterType.merge(registerType); + + RegisterType mergedRegisterType; + if (override) { + mergedRegisterType = getMergedPreRegisterTypeFromPredecessors(registerNumber); + } else { + mergedRegisterType = oldRegisterType.merge(registerType); + } if (mergedRegisterType.equals(oldRegisterType)) { return false; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java index e634297f..856060b1 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java @@ -336,8 +336,7 @@ public class MethodAnalyzer { registerType); } - private void propagateChanges(@Nonnull BitSet changedInstructions, int registerNumber, - @Nonnull RegisterType registerType) { + private void propagateChanges(@Nonnull BitSet changedInstructions, int registerNumber, boolean override) { //Using a for loop inside the while loop optimizes for the common case of the successors of an instruction //occurring after the instruction. Any successors that occur prior to the instruction will be picked up on //the next iteration of the while loop. @@ -350,7 +349,7 @@ public class MethodAnalyzer { changedInstructions.clear(instructionIndex); propagateRegisterToSuccessors(analyzedInstructions.valueAt(instructionIndex), registerNumber, - changedInstructions); + changedInstructions, override); } } } @@ -366,7 +365,7 @@ public class MethodAnalyzer { } changedInstructions.set(analyzedInstruction.instructionIndex); - propagateChanges(changedInstructions, registerNumber, registerType); + propagateChanges(changedInstructions, registerNumber, true); if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); @@ -388,9 +387,9 @@ public class MethodAnalyzer { return; } - propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions); + propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions, false); - propagateChanges(changedInstructions, registerNumber, registerType); + propagateChanges(changedInstructions, registerNumber, false); if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); @@ -402,10 +401,10 @@ public class MethodAnalyzer { } private void propagateRegisterToSuccessors(@Nonnull AnalyzedInstruction instruction, int registerNumber, - @Nonnull BitSet changedInstructions) { + @Nonnull BitSet changedInstructions, boolean override) { RegisterType postRegisterType = instruction.getPostInstructionRegisterType(registerNumber); for (AnalyzedInstruction successor: instruction.successors) { - if (successor.mergeRegister(registerNumber, postRegisterType, analyzedState)) { + if (successor.mergeRegister(registerNumber, postRegisterType, analyzedState, override)) { changedInstructions.set(successor.instructionIndex); } }