@Override protected BuilderInstruction getRealInsn0(LabelAssigner assigner) { return new BuilderInstruction10x(opc); } }
@Nonnull private BuilderInstruction10x newBuilderInstruction10x(@Nonnull Instruction10x instruction) { return new BuilderInstruction10x( instruction.getOpcode()); }
BuilderInstruction replacement; if (nextAddresses.contains(address)) { replacement = new BuilderInstruction10x(Opcode.NOP); } else { BuilderOffsetInstruction original = (BuilderOffsetInstruction) manipulator.getInstruction(address);
index--; } else { addInstruction(location.index, new BuilderInstruction10x(Opcode.NOP)); index++;
@Test public void addingManyNopsAfterGotoModifiesStateCorrectly() { int nops_to_insert = 127; Object[][] expected = new Object[3 + nops_to_insert][]; expected[0] = new Object[] { 0, Opcode.GOTO_16, new Object[][][] { { { 2 + 1 + 127, Opcode.RETURN_VOID } } } }; // No children, no node pile, these nops are dead code and never get executed expected[1] = new Object[] { 2, Opcode.NOP, new Object[0][0][0] }; for (int i = 0; i < nops_to_insert; i++) { int index = i + 2; expected[index] = new Object[] { index + 1, Opcode.NOP, new Object[0][0][0] }; } expected[129] = new Object[] { 130, Opcode.RETURN_VOID, new Object[1][0][0] }; manipulator = OptimizerTester.getGraphManipulator(CLASS_NAME, "hasGotoAndOneNop()V"); // Adding 126 bytes (nop) between goto and target offset causes dexlib to "fix" goto into goto/16 for (int i = 0; i < nops_to_insert - 1; i++) { manipulator.addInstruction(1, new BuilderInstruction10x(Opcode.NOP)); } // Addresses 0 and 1 are now goto/16, need to insert at 2 manipulator.addInstruction(2, new BuilderInstruction10x(Opcode.NOP)); test(expected, manipulator); }
public final void insn_format10x() throws RecognitionException { CommonTree INSTRUCTION_FORMAT10x116=null; try { // smaliTreeWalker.g:818:3: ( ^( I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x ) ) // smaliTreeWalker.g:819:5: ^( I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x ) { match(input,I_STATEMENT_FORMAT10x,FOLLOW_I_STATEMENT_FORMAT10x_in_insn_format10x2244); match(input, Token.DOWN, null); INSTRUCTION_FORMAT10x116=(CommonTree)match(input,INSTRUCTION_FORMAT10x,FOLLOW_INSTRUCTION_FORMAT10x_in_insn_format10x2246); match(input, Token.UP, null); Opcode opcode = opcodes.getOpcodeByName((INSTRUCTION_FORMAT10x116!=null?INSTRUCTION_FORMAT10x116.getText():null)); method_stack.peek().methodBuilder.addInstruction(new BuilderInstruction10x(opcode)); } } catch (RecognitionException re) { reportError(re); recover(input,re); } finally { // do for sure before leaving } } // $ANTLR end "insn_format10x"
@Test public void addingThenRemovingManyNopsAfterGotoModifiesStateCorrectly() { Object[][] expected = new Object[3][]; expected[0] = new Object[] { 0, Opcode.GOTO_16, new Object[][][] { { { 3, Opcode.RETURN_VOID } } } }; expected[1] = new Object[] { 2, Opcode.NOP, new Object[0][0][0] }; expected[2] = new Object[] { 3, Opcode.RETURN_VOID, new Object[1][0][0] }; int nops_to_insert = 127; manipulator = OptimizerTester.getGraphManipulator(CLASS_NAME, "hasGotoAndOneNop()V"); // Adding 126 bytes (nop) between goto and target offset causes dexlib to "fix" goto into goto/16 for (int i = 0; i < nops_to_insert - 1; i++) { manipulator.addInstruction(1, new BuilderInstruction10x(Opcode.NOP)); } // Addresses 0 and 1 are now goto/16, need to insert at 2 manipulator.addInstruction(2, new BuilderInstruction10x(Opcode.NOP)); List<Integer> removeList = new LinkedList<Integer>(); // for (int removeAddress = 2, i = 0; i < nops_to_insert; removeAddress++, i++) { for (int i = 1; i < nops_to_insert; i++) { int removeAddress = i + 2; removeList.add(removeAddress); } manipulator.removeInstructions(removeList); manipulator.removeInstruction(2); test(expected, manipulator); }
@Test public void addingInstructionModifiesStateCorrectly() { //@formatter:off Object[][] expected = new Object[][] { { 0, Opcode.NOP, new Object[][][] { { { 1, Opcode.CONST_4 } } } }, { 1, Opcode.CONST_4, new Object[][][] { { { 2, Opcode.CONST_4 } } } }, { 2, Opcode.CONST_4, new Object[][][] { { { 3, Opcode.CONST_4 } } } }, { 3, Opcode.CONST_4, new Object[][][] { { { 4, Opcode.CONST_4 } } } }, { 4, Opcode.CONST_4, new Object[][][] { { { 5, Opcode.CONST_4 } } } }, { 5, Opcode.CONST_4, new Object[][][] { { { 6, Opcode.RETURN_VOID } } } }, { 6, Opcode.RETURN_VOID, new Object[1][0][0] }, }; //@formatter:on manipulator = OptimizerTester.getGraphManipulator(CLASS_NAME, "verySimple()V"); BuilderInstruction addition = new BuilderInstruction10x(Opcode.NOP); manipulator.addInstruction(0, addition); test(expected, manipulator); testHeritage(manipulator, 0); testHeritage(manipulator, 1); }
@Test public void addingInstructionThatCausesNopPaddingToBeAddedModifiesStateCorrectly() { //@formatter:off Object[][] expected = new Object[][] { { 0, Opcode.CONST_16, new Object[][][] { { { 2, Opcode.NEW_ARRAY } } } }, { 2, Opcode.NEW_ARRAY, new Object[][][] { { { 4, Opcode.NOP } } } }, { 4, Opcode.NOP, new Object[][][] { { { 5, Opcode.FILL_ARRAY_DATA } } } }, { 5, Opcode.FILL_ARRAY_DATA, new Object[][][] { { { 0xa, Opcode.ARRAY_PAYLOAD } } } }, { 8, Opcode.RETURN_VOID, new Object[1][0][0] }, { 9, Opcode.NOP, new Object[0][0][0] }, { 0xa, Opcode.ARRAY_PAYLOAD, new Object[][][] { { { 8, Opcode.RETURN_VOID } }, } }, }; //@formatter:on manipulator = OptimizerTester.getGraphManipulator(CLASS_NAME, "hasNoNopPadding()V"); BuilderInstruction addition = new BuilderInstruction10x(Opcode.NOP); manipulator.addInstruction(4, addition); test(expected, manipulator); testHeritage(manipulator, 2); testHeritage(manipulator, 4); testHeritage(manipulator, 5); }
@Nonnull private BuilderInstruction10x newBuilderInstruction10x(@Nonnull Instruction10x instruction) { return new BuilderInstruction10x( instruction.getOpcode()); }
@Nonnull private BuilderInstruction10x newBuilderInstruction10x(@Nonnull Instruction10x instruction) { return new BuilderInstruction10x( instruction.getOpcode()); }
@Nonnull private BuilderInstruction10x newBuilderInstruction10x(@Nonnull Instruction10x instruction) { return new BuilderInstruction10x( instruction.getOpcode()); }
@Nonnull private BuilderInstruction10x newBuilderInstruction10x(@Nonnull Instruction10x instruction) { return new BuilderInstruction10x( instruction.getOpcode()); }
@Test public void testFixGotoToGoto16() { MethodImplementationBuilder builder = new MethodImplementationBuilder(1); Label gotoTarget = builder.getLabel("gotoTarget"); builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, gotoTarget)); for (int i=0; i<500; i++) { builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); } builder.addLabel("gotoTarget"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation impl = builder.getMethodImplementation(); List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions()); Assert.assertEquals(502, instructions.size()); Assert.assertEquals(Opcode.GOTO_16, instructions.get(0).getOpcode()); Assert.assertEquals(502, ((OffsetInstruction)instructions.get(0)).getCodeOffset()); }
@Test public void testFixGotoToGoto32() { MethodImplementationBuilder builder = new MethodImplementationBuilder(1); Label gotoTarget = builder.getLabel("gotoTarget"); builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, gotoTarget)); for (int i=0; i<70000; i++) { builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); } builder.addLabel("gotoTarget"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation impl = builder.getMethodImplementation(); List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions()); Assert.assertEquals(70002, instructions.size()); Assert.assertEquals(Opcode.GOTO_32, instructions.get(0).getOpcode()); Assert.assertEquals(70003, ((OffsetInstruction)instructions.get(0)).getCodeOffset()); }
@Test public void testFixGoto16ToGoto32() { MethodImplementationBuilder builder = new MethodImplementationBuilder(1); Label gotoTarget = builder.getLabel("gotoTarget"); builder.addInstruction(new BuilderInstruction20t(Opcode.GOTO_16, gotoTarget)); for (int i=0; i<70000; i++) { builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); } builder.addLabel("gotoTarget"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation impl = builder.getMethodImplementation(); List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions()); Assert.assertEquals(70002, instructions.size()); Assert.assertEquals(Opcode.GOTO_32, instructions.get(0).getOpcode()); Assert.assertEquals(70003, ((OffsetInstruction)instructions.get(0)).getCodeOffset()); }
public final void insn_format10x() throws RecognitionException { CommonTree INSTRUCTION_FORMAT10x106=null; try { // D:\\decomplier_tools\\smali\\smali\\smali\\src\\main\\antlr3\\smaliTreeWalker.g:755:3: ( ^( I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x ) ) // D:\\decomplier_tools\\smali\\smali\\smali\\src\\main\\antlr3\\smaliTreeWalker.g:756:5: ^( I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x ) { match(input,I_STATEMENT_FORMAT10x,FOLLOW_I_STATEMENT_FORMAT10x_in_insn_format10x2053); match(input, Token.DOWN, null); INSTRUCTION_FORMAT10x106=(CommonTree)match(input,INSTRUCTION_FORMAT10x,FOLLOW_INSTRUCTION_FORMAT10x_in_insn_format10x2055); match(input, Token.UP, null); Opcode opcode = opcodes.getOpcodeByName((INSTRUCTION_FORMAT10x106!=null?INSTRUCTION_FORMAT10x106.getText():null)); method_stack.peek().methodBuilder.addInstruction(new BuilderInstruction10x(opcode)); } } catch (RecognitionException re) { reportError(re); recover(input,re); } finally { // do for sure before leaving } } // $ANTLR end "insn_format10x"
public final void insn_format10x() throws RecognitionException { CommonTree INSTRUCTION_FORMAT10x116=null; try { // smaliTreeWalker.g:818:3: ( ^( I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x ) ) // smaliTreeWalker.g:819:5: ^( I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x ) { match(input,I_STATEMENT_FORMAT10x,FOLLOW_I_STATEMENT_FORMAT10x_in_insn_format10x2244); match(input, Token.DOWN, null); INSTRUCTION_FORMAT10x116=(CommonTree)match(input,INSTRUCTION_FORMAT10x,FOLLOW_INSTRUCTION_FORMAT10x_in_insn_format10x2246); match(input, Token.UP, null); Opcode opcode = opcodes.getOpcodeByName((INSTRUCTION_FORMAT10x116!=null?INSTRUCTION_FORMAT10x116.getText():null)); method_stack.peek().methodBuilder.addInstruction(new BuilderInstruction10x(opcode)); } } catch (RecognitionException re) { reportError(re); recover(input,re); } finally { // do for sure before leaving } } // $ANTLR end "insn_format10x"
index--; } else { addInstruction(location.index, new BuilderInstruction10x(Opcode.NOP)); index++;
index--; } else { addInstruction(location.index, new BuilderInstruction10x(Opcode.NOP)); index++;