15fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver/* 25fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * Copyright 2013, Google Inc. 35fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * All rights reserved. 45fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * 55fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * Redistribution and use in source and binary forms, with or without 65fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * modification, are permitted provided that the following conditions are 75fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * met: 85fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * 95fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * * Redistributions of source code must retain the above copyright 105fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * notice, this list of conditions and the following disclaimer. 115fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * * Redistributions in binary form must reproduce the above 125fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * copyright notice, this list of conditions and the following disclaimer 135fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * in the documentation and/or other materials provided with the 145fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * distribution. 155fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * * Neither the name of Google Inc. nor the names of its 165fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * contributors may be used to endorse or promote products derived from 175fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * this software without specific prior written permission. 185fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * 195fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver */ 315fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 325fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverpackage org.jf.dexlib2.analysis; 335fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 345fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport com.google.common.collect.ImmutableList; 355fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport com.google.common.collect.Lists; 365fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.AccessFlags; 375fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.Opcode; 38e202aeede5fb5fcc8de22601157b212eabb5f1c6Ben Gruverimport org.jf.dexlib2.Opcodes; 395fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.iface.ClassDef; 405fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.iface.DexFile; 415fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.iface.instruction.Instruction; 425fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.iface.instruction.formats.Instruction35c; 435fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.iface.reference.MethodReference; 445fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.ImmutableClassDef; 455fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.ImmutableDexFile; 465fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.ImmutableMethod; 475fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.ImmutableMethodImplementation; 485fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.instruction.ImmutableInstruction; 495fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.instruction.ImmutableInstruction10x; 505fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.jf.dexlib2.immutable.instruction.ImmutableInstruction35mi; 515fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.junit.Assert; 525fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport org.junit.Test; 535fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 54e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruverimport java.io.IOException; 555fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverimport java.util.List; 565fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 575fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruverpublic class CustomMethodInlineTableTest { 585fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver @Test 59e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruver public void testCustomMethodInlineTable_Virtual() throws IOException { 605fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver List<ImmutableInstruction> instructions = Lists.newArrayList( 615fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), 625fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver new ImmutableInstruction10x(Opcode.RETURN_VOID)); 635fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 645fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); 655fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PUBLIC.getValue(), null, 665fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver methodImpl); 675fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 685fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, 690a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver null, null, null, null, null, ImmutableList.of(method)); 705fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 718f27f45fb1d621a6cc5ca01e1eb5cc7dc67cc994Ben Gruver DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); 725fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 7331ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), 7431ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); 7531ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); 76e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruver 775fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); 78827e2db34dc3b8b5504c148a09d594b5c0ddbd64Ben Gruver MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); 795fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 805fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); 815fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Assert.assertEquals(Opcode.INVOKE_VIRTUAL, deodexedInstruction.getOpcode()); 825fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 835fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); 845fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Assert.assertEquals(method, methodReference); 855fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver } 865fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 875fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver @Test 88e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruver public void testCustomMethodInlineTable_Static() throws IOException { 895fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver List<ImmutableInstruction> instructions = Lists.newArrayList( 905fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), 915fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver new ImmutableInstruction10x(Opcode.RETURN_VOID)); 925fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 935fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); 945fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.STATIC.getValue(), null, 955fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver methodImpl); 965fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 975fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, 980a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver null, null, null, null, ImmutableList.of(method), null); 995fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1008f27f45fb1d621a6cc5ca01e1eb5cc7dc67cc994Ben Gruver DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); 1015fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 10231ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), 10331ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); 10431ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); 10531ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver 1065fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); 107827e2db34dc3b8b5504c148a09d594b5c0ddbd64Ben Gruver MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); 1085fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1095fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); 1105fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Assert.assertEquals(Opcode.INVOKE_STATIC, deodexedInstruction.getOpcode()); 1115fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1125fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); 1135fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Assert.assertEquals(method, methodReference); 1145fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver } 1155fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1165fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver @Test 117e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruver public void testCustomMethodInlineTable_Direct() throws IOException { 1185fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver List<ImmutableInstruction> instructions = Lists.newArrayList( 1195fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), 1205fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver new ImmutableInstruction10x(Opcode.RETURN_VOID)); 1215fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1225fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); 1235fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PRIVATE.getValue(), null, 1245fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver methodImpl); 1255fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1265fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, 1270a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver null, null, null, null, ImmutableList.of(method), null); 1285fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1298f27f45fb1d621a6cc5ca01e1eb5cc7dc67cc994Ben Gruver DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); 1305fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 13131ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), 13231ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); 13331ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); 13431ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver 1355fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); 136827e2db34dc3b8b5504c148a09d594b5c0ddbd64Ben Gruver MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); 1375fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1385fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); 1395fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Assert.assertEquals(Opcode.INVOKE_DIRECT, deodexedInstruction.getOpcode()); 1405fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver 1415fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); 1425fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver Assert.assertEquals(method, methodReference); 1435fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver } 1445fa302678ce3a8e08fa8d2e8dbc5424781e751a6Ben Gruver} 145