Pass in the Opcodes to use for SyntheticAccessorFSM

This commit is contained in:
Ben Gruver 2015-10-17 13:50:26 -07:00
parent 4c66761aea
commit e202aeede5
14 changed files with 148 additions and 96 deletions

View File

@ -135,7 +135,7 @@ public class baksmali {
List<? extends ClassDef> classDefs = Ordering.natural().sortedCopy(dexFile.getClasses()); List<? extends ClassDef> classDefs = Ordering.natural().sortedCopy(dexFile.getClasses());
if (!options.noAccessorComments) { if (!options.noAccessorComments) {
options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs); options.syntheticAccessorResolver = new SyntheticAccessorResolver(dexFile.getOpcodes(), classDefs);
} }
final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali"); final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");

View File

@ -40,6 +40,7 @@ import com.google.common.collect.*;
import org.jf.dexlib2.DexFileFactory; import org.jf.dexlib2.DexFileFactory;
import org.jf.dexlib2.DexFileFactory.DexFileNotFound; import org.jf.dexlib2.DexFileFactory.DexFileNotFound;
import org.jf.dexlib2.DexFileFactory.MultipleDexFilesException; import org.jf.dexlib2.DexFileFactory.MultipleDexFilesException;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.analysis.reflection.ReflectionClassDef; import org.jf.dexlib2.analysis.reflection.ReflectionClassDef;
import org.jf.dexlib2.dexbacked.OatFile.OatDexFile; import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.ClassDef;
@ -139,13 +140,14 @@ public class ClassPath {
private static DexFile getBasicClasses() { private static DexFile getBasicClasses() {
// fallbacks for some special classes that we assume are present // fallbacks for some special classes that we assume are present
return new ImmutableDexFile(ImmutableSet.of( return new ImmutableDexFile(Opcodes.forApi(19),
new ReflectionClassDef(Class.class), ImmutableSet.of(
new ReflectionClassDef(Cloneable.class), new ReflectionClassDef(Class.class),
new ReflectionClassDef(Object.class), new ReflectionClassDef(Cloneable.class),
new ReflectionClassDef(Serializable.class), new ReflectionClassDef(Object.class),
new ReflectionClassDef(String.class), new ReflectionClassDef(Serializable.class),
new ReflectionClassDef(Throwable.class))); new ReflectionClassDef(String.class),
new ReflectionClassDef(Throwable.class)));
} }
public boolean isArt() { public boolean isArt() {

View File

@ -46,7 +46,7 @@ import java.io.InputStream;
import java.util.Set; import java.util.Set;
public class DexBackedDexFile extends BaseDexBuffer implements DexFile { public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
private final Opcodes opcodes; @Nonnull private final Opcodes opcodes;
private final int stringCount; private final int stringCount;
private final int stringStartOffset; private final int stringStartOffset;
@ -61,7 +61,7 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
private final int classCount; private final int classCount;
private final int classStartOffset; private final int classStartOffset;
private DexBackedDexFile(Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) { private DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) {
super(buf, offset); super(buf, offset);
this.opcodes = opcodes; this.opcodes = opcodes;
@ -117,7 +117,7 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
return new DexBackedDexFile(opcodes, buf, 0, false); return new DexBackedDexFile(opcodes, buf, 0, false);
} }
public Opcodes getOpcodes() { @Override @Nonnull public Opcodes getOpcodes() {
return opcodes; return opcodes;
} }

View File

@ -31,6 +31,8 @@
package org.jf.dexlib2.iface; package org.jf.dexlib2.iface;
import org.jf.dexlib2.Opcodes;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Set; import java.util.Set;
@ -46,4 +48,11 @@ public interface DexFile {
* @return A set of the classes defined in this dex file * @return A set of the classes defined in this dex file
*/ */
@Nonnull Set<? extends ClassDef> getClasses(); @Nonnull Set<? extends ClassDef> getClasses();
/**
* Get the Opcodes associated with this dex file
*
* @return The Opcodes instance representing the possible opcodes that can be encountered in this dex file
*/
@Nonnull Opcodes getOpcodes();
} }

View File

@ -32,6 +32,7 @@
package org.jf.dexlib2.immutable; package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile; import org.jf.dexlib2.iface.DexFile;
import org.jf.util.ImmutableUtils; import org.jf.util.ImmutableUtils;
@ -42,21 +43,37 @@ import java.util.Collection;
public class ImmutableDexFile implements DexFile { public class ImmutableDexFile implements DexFile {
@Nonnull protected final ImmutableSet<? extends ImmutableClassDef> classes; @Nonnull protected final ImmutableSet<? extends ImmutableClassDef> classes;
@Nonnull private final Opcodes opcodes;
@Deprecated
public ImmutableDexFile(@Nullable Collection<? extends ClassDef> classes) { public ImmutableDexFile(@Nullable Collection<? extends ClassDef> classes) {
this.classes = ImmutableClassDef.immutableSetOf(classes); this.classes = ImmutableClassDef.immutableSetOf(classes);
this.opcodes = Opcodes.forApi(19);
} }
@Deprecated
public ImmutableDexFile(@Nullable ImmutableSet<? extends ImmutableClassDef> classes) { public ImmutableDexFile(@Nullable ImmutableSet<? extends ImmutableClassDef> classes) {
this.classes = ImmutableUtils.nullToEmptySet(classes); this.classes = ImmutableUtils.nullToEmptySet(classes);
this.opcodes = Opcodes.forApi(19);
}
public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable Collection<? extends ClassDef> classes) {
this.classes = ImmutableClassDef.immutableSetOf(classes);
this.opcodes = opcodes;
}
public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable ImmutableSet<? extends ImmutableClassDef> classes) {
this.classes = ImmutableUtils.nullToEmptySet(classes);
this.opcodes = opcodes;
} }
public static ImmutableDexFile of(DexFile dexFile) { public static ImmutableDexFile of(DexFile dexFile) {
if (dexFile instanceof ImmutableDexFile) { if (dexFile instanceof ImmutableDexFile) {
return (ImmutableDexFile)dexFile; return (ImmutableDexFile)dexFile;
} }
return new ImmutableDexFile(dexFile.getClasses()); return new ImmutableDexFile(dexFile.getOpcodes(), dexFile.getClasses());
} }
@Nonnull @Override public ImmutableSet<? extends ImmutableClassDef> getClasses() { return classes; } @Nonnull @Override public ImmutableSet<? extends ImmutableClassDef> getClasses() { return classes; }
@Nonnull @Override public Opcodes getOpcodes() { return opcodes; }
} }

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.rewriter; package org.jf.dexlib2.rewriter;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.*; import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.debug.DebugItem; import org.jf.dexlib2.iface.debug.DebugItem;
import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.Instruction;
@ -116,6 +117,10 @@ public class DexRewriter implements Rewriters {
@Override @Nonnull public Set<? extends ClassDef> getClasses() { @Override @Nonnull public Set<? extends ClassDef> getClasses() {
return RewriterUtils.rewriteSet(getClassDefRewriter(), dexFile.getClasses()); return RewriterUtils.rewriteSet(getClassDefRewriter(), dexFile.getClasses());
} }
@Nonnull @Override public Opcodes getOpcodes() {
return dexFile.getOpcodes();
}
} }
@Nonnull @Override public Rewriter<ClassDef> getClassDefRewriter() { return classDefRewriter; } @Nonnull @Override public Rewriter<ClassDef> getClassDefRewriter() { return classDefRewriter; }

View File

@ -33,11 +33,12 @@
package org.jf.dexlib2.util; package org.jf.dexlib2.util;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction; import org.jf.dexlib2.iface.instruction.OneRegisterInstruction;
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction; import org.jf.dexlib2.iface.instruction.WideLiteralInstruction;
import org.jf.dexlib2.Opcodes;
import javax.annotation.Nonnull;
import java.util.List; import java.util.List;
public class SyntheticAccessorFSM { public class SyntheticAccessorFSM {
@ -212,7 +213,13 @@ static final int SyntheticAccessorFSM_en_main = 1;
public static final int NEGATIVE_ONE = -1; public static final int NEGATIVE_ONE = -1;
public static final int OTHER = 0; public static final int OTHER = 0;
public static int test(List<? extends Instruction> instructions) { @Nonnull private final Opcodes opcodes;
public SyntheticAccessorFSM(@Nonnull Opcodes opcodes) {
this.opcodes = opcodes;
}
public int test(List<? extends Instruction> instructions) {
int accessorType = -1; int accessorType = -1;
int cs, p = 0; int cs, p = 0;
int pe = instructions.size(); int pe = instructions.size();
@ -231,15 +238,13 @@ static final int SyntheticAccessorFSM_en_main = 1;
// The return register; // The return register;
int returnRegister = -1; int returnRegister = -1;
Opcodes opcodes = Opcodes.forApi(20);
// line 238 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" // line 242 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
{ {
cs = SyntheticAccessorFSM_start; cs = SyntheticAccessorFSM_start;
} }
// line 243 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" // line 247 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
{ {
int _klen; int _klen;
int _trans = 0; int _trans = 0;
@ -320,19 +325,19 @@ case 1:
switch ( _SyntheticAccessorFSM_actions[_acts++] ) switch ( _SyntheticAccessorFSM_actions[_acts++] )
{ {
case 0: case 0:
// line 96 "SyntheticAccessorFSM.rl" // line 100 "SyntheticAccessorFSM.rl"
{ {
putRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA(); putRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA();
} }
break; break;
case 1: case 1:
// line 103 "SyntheticAccessorFSM.rl" // line 107 "SyntheticAccessorFSM.rl"
{ {
constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral(); constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral();
} }
break; break;
case 2: case 2:
// line 107 "SyntheticAccessorFSM.rl" // line 111 "SyntheticAccessorFSM.rl"
{ {
mathType = INT; mathType = INT;
mathOp = ADD; mathOp = ADD;
@ -340,146 +345,146 @@ case 1:
} }
break; break;
case 3: case 3:
// line 113 "SyntheticAccessorFSM.rl" // line 117 "SyntheticAccessorFSM.rl"
{ mathType = INT; } { mathType = INT; }
break; break;
case 4: case 4:
// line 114 "SyntheticAccessorFSM.rl" // line 118 "SyntheticAccessorFSM.rl"
{ mathType = LONG; } { mathType = LONG; }
break; break;
case 5: case 5:
// line 115 "SyntheticAccessorFSM.rl" // line 119 "SyntheticAccessorFSM.rl"
{ mathType = FLOAT; } { mathType = FLOAT; }
break; break;
case 6: case 6:
// line 116 "SyntheticAccessorFSM.rl" // line 120 "SyntheticAccessorFSM.rl"
{mathType = DOUBLE; } {mathType = DOUBLE; }
break; break;
case 7: case 7:
// line 116 "SyntheticAccessorFSM.rl" // line 120 "SyntheticAccessorFSM.rl"
{ {
mathOp = ADD; mathOp = ADD;
} }
break; break;
case 8: case 8:
// line 119 "SyntheticAccessorFSM.rl" // line 123 "SyntheticAccessorFSM.rl"
{ mathType = INT; } { mathType = INT; }
break; break;
case 9: case 9:
// line 120 "SyntheticAccessorFSM.rl" // line 124 "SyntheticAccessorFSM.rl"
{ mathType = LONG; } { mathType = LONG; }
break; break;
case 10: case 10:
// line 121 "SyntheticAccessorFSM.rl" // line 125 "SyntheticAccessorFSM.rl"
{ mathType = FLOAT; } { mathType = FLOAT; }
break; break;
case 11: case 11:
// line 122 "SyntheticAccessorFSM.rl" // line 126 "SyntheticAccessorFSM.rl"
{mathType = DOUBLE; } {mathType = DOUBLE; }
break; break;
case 12: case 12:
// line 122 "SyntheticAccessorFSM.rl" // line 126 "SyntheticAccessorFSM.rl"
{ {
mathOp = SUB; mathOp = SUB;
} }
break; break;
case 13: case 13:
// line 126 "SyntheticAccessorFSM.rl" // line 130 "SyntheticAccessorFSM.rl"
{ {
mathOp = MUL; mathOp = MUL;
} }
break; break;
case 14: case 14:
// line 130 "SyntheticAccessorFSM.rl" // line 134 "SyntheticAccessorFSM.rl"
{ {
mathOp = DIV; mathOp = DIV;
} }
break; break;
case 15: case 15:
// line 134 "SyntheticAccessorFSM.rl" // line 138 "SyntheticAccessorFSM.rl"
{ {
mathOp = REM; mathOp = REM;
} }
break; break;
case 16: case 16:
// line 137 "SyntheticAccessorFSM.rl" // line 141 "SyntheticAccessorFSM.rl"
{ {
mathOp = AND; mathOp = AND;
} }
break; break;
case 17: case 17:
// line 140 "SyntheticAccessorFSM.rl" // line 144 "SyntheticAccessorFSM.rl"
{ {
mathOp = OR; mathOp = OR;
} }
break; break;
case 18: case 18:
// line 143 "SyntheticAccessorFSM.rl" // line 147 "SyntheticAccessorFSM.rl"
{ {
mathOp = XOR; mathOp = XOR;
} }
break; break;
case 19: case 19:
// line 146 "SyntheticAccessorFSM.rl" // line 150 "SyntheticAccessorFSM.rl"
{ {
mathOp = SHL; mathOp = SHL;
} }
break; break;
case 20: case 20:
// line 149 "SyntheticAccessorFSM.rl" // line 153 "SyntheticAccessorFSM.rl"
{ {
mathOp = SHR; mathOp = SHR;
} }
break; break;
case 21: case 21:
// line 152 "SyntheticAccessorFSM.rl" // line 156 "SyntheticAccessorFSM.rl"
{ {
mathOp = USHR; mathOp = USHR;
} }
break; break;
case 22: case 22:
// line 158 "SyntheticAccessorFSM.rl" // line 162 "SyntheticAccessorFSM.rl"
{ {
returnRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA(); returnRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA();
} }
break; break;
case 23: case 23:
// line 164 "SyntheticAccessorFSM.rl" // line 168 "SyntheticAccessorFSM.rl"
{ {
accessorType = SyntheticAccessorResolver.GETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;} accessorType = SyntheticAccessorResolver.GETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;}
} }
break; break;
case 24: case 24:
// line 168 "SyntheticAccessorFSM.rl" // line 172 "SyntheticAccessorFSM.rl"
{ {
accessorType = SyntheticAccessorResolver.SETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;} accessorType = SyntheticAccessorResolver.SETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;}
} }
break; break;
case 25: case 25:
// line 172 "SyntheticAccessorFSM.rl" // line 176 "SyntheticAccessorFSM.rl"
{ {
accessorType = SyntheticAccessorResolver.METHOD; { p += 1; _goto_targ = 5; if (true) continue _goto;} accessorType = SyntheticAccessorResolver.METHOD; { p += 1; _goto_targ = 5; if (true) continue _goto;}
} }
break; break;
case 26: case 26:
// line 176 "SyntheticAccessorFSM.rl"
{
accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
}
break;
case 27:
// line 180 "SyntheticAccessorFSM.rl" // line 180 "SyntheticAccessorFSM.rl"
{
accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
}
break;
case 27:
// line 184 "SyntheticAccessorFSM.rl"
{ {
accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister); accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
} }
break; break;
case 28: case 28:
// line 188 "SyntheticAccessorFSM.rl" // line 192 "SyntheticAccessorFSM.rl"
{ {
accessorType = mathOp; { p += 1; _goto_targ = 5; if (true) continue _goto;} accessorType = mathOp; { p += 1; _goto_targ = 5; if (true) continue _goto;}
} }
break; break;
// line 483 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" // line 487 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
} }
} }
} }
@ -499,7 +504,7 @@ case 5:
break; } break; }
} }
// line 201 "SyntheticAccessorFSM.rl" // line 205 "SyntheticAccessorFSM.rl"
return accessorType; return accessorType;

View File

@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.iface.MethodImplementation; import org.jf.dexlib2.iface.MethodImplementation;
@ -68,10 +69,12 @@ public class SyntheticAccessorResolver {
public static final int SHR_ASSIGNMENT = 16; public static final int SHR_ASSIGNMENT = 16;
public static final int USHR_ASSIGNMENT = 17; public static final int USHR_ASSIGNMENT = 17;
private final SyntheticAccessorFSM syntheticAccessorFSM;
private final Map<String, ClassDef> classDefMap; private final Map<String, ClassDef> classDefMap;
private final Map<String, AccessedMember> resolvedAccessors = Maps.newConcurrentMap(); private final Map<String, AccessedMember> resolvedAccessors = Maps.newConcurrentMap();
public SyntheticAccessorResolver(Iterable<? extends ClassDef> classDefs) { public SyntheticAccessorResolver(@Nonnull Opcodes opcodes, @Nonnull Iterable<? extends ClassDef> classDefs) {
this.syntheticAccessorFSM = new SyntheticAccessorFSM(opcodes);
ImmutableMap.Builder<String, ClassDef> builder = ImmutableMap.builder(); ImmutableMap.Builder<String, ClassDef> builder = ImmutableMap.builder();
for (ClassDef classDef: classDefs) { for (ClassDef classDef: classDefs) {
@ -124,7 +127,8 @@ public class SyntheticAccessorResolver {
List<Instruction> instructions = ImmutableList.copyOf(matchedMethodImpl.getInstructions()); List<Instruction> instructions = ImmutableList.copyOf(matchedMethodImpl.getInstructions());
int accessType = SyntheticAccessorFSM.test(instructions);
int accessType = syntheticAccessorFSM.test(instructions);
if (accessType >= 0) { if (accessType >= 0) {
AccessedMember member = AccessedMember member =

View File

@ -64,7 +64,13 @@ public class SyntheticAccessorFSM {
public static final int NEGATIVE_ONE = -1; public static final int NEGATIVE_ONE = -1;
public static final int OTHER = 0; public static final int OTHER = 0;
public static int test(List<? extends Instruction> instructions) { @Nonnull private final Opcodes opcodes;
public SyntheticAccessorFSM(@Nonnull Opcodes opcodes) {
this.opcodes = opcodes;
}
public int test(List<? extends Instruction> instructions) {
int accessorType = -1; int accessorType = -1;
int cs, p = 0; int cs, p = 0;
int pe = instructions.size(); int pe = instructions.size();
@ -83,8 +89,6 @@ public class SyntheticAccessorFSM {
// The return register; // The return register;
int returnRegister = -1; int returnRegister = -1;
Opcodes opcodes = Opcodes.forApi(20);
%%{ %%{
import "Opcodes.rl"; import "Opcodes.rl";
alphtype short; alphtype short;

View File

@ -81,7 +81,7 @@ public class AccessorTest {
Assert.assertNotNull(url); Assert.assertNotNull(url);
DexFile f = DexFileFactory.loadDexFile(url.getFile(), 15, false); DexFile f = DexFileFactory.loadDexFile(url.getFile(), 15, false);
SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getClasses()); SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getOpcodes(), f.getClasses());
ClassDef accessorTypesClass = null; ClassDef accessorTypesClass = null;
ClassDef accessorsClass = null; ClassDef accessorsClass = null;

View File

@ -33,6 +33,7 @@ package org.jf.dexlib2.analysis;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import junit.framework.Assert; import junit.framework.Assert;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.immutable.ImmutableDexFile; import org.jf.dexlib2.immutable.ImmutableDexFile;
import org.junit.Test; import org.junit.Test;
@ -53,38 +54,41 @@ public class CommonSuperclassTest {
private final ClassPath classPath; private final ClassPath classPath;
public CommonSuperclassTest() throws IOException { public CommonSuperclassTest() throws IOException {
classPath = new ClassPath(new ImmutableDexFile(ImmutableSet.of( classPath = new ClassPath(new ImmutableDexFile(Opcodes.forApi(19),
TestUtils.makeClassDef("Ljava/lang/Object;", null), ImmutableSet.of(
TestUtils.makeClassDef("Ltest/one;", "Ljava/lang/Object;"), TestUtils.makeClassDef("Ljava/lang/Object;", null),
TestUtils.makeClassDef("Ltest/two;", "Ljava/lang/Object;"), TestUtils.makeClassDef("Ltest/one;", "Ljava/lang/Object;"),
TestUtils.makeClassDef("Ltest/onetwo;", "Ltest/one;"), TestUtils.makeClassDef("Ltest/two;", "Ljava/lang/Object;"),
TestUtils.makeClassDef("Ltest/onetwothree;", "Ltest/onetwo;"), TestUtils.makeClassDef("Ltest/onetwo;", "Ltest/one;"),
TestUtils.makeClassDef("Ltest/onethree;", "Ltest/one;"), TestUtils.makeClassDef("Ltest/onetwothree;", "Ltest/onetwo;"),
TestUtils.makeClassDef("Ltest/fivetwo;", "Ltest/five;"), TestUtils.makeClassDef("Ltest/onethree;", "Ltest/one;"),
TestUtils.makeClassDef("Ltest/fivetwothree;", "Ltest/fivetwo;"), TestUtils.makeClassDef("Ltest/fivetwo;", "Ltest/five;"),
TestUtils.makeClassDef("Ltest/fivethree;", "Ltest/five;"), TestUtils.makeClassDef("Ltest/fivetwothree;", "Ltest/fivetwo;"),
TestUtils.makeInterfaceDef("Ljava/lang/Cloneable;"), TestUtils.makeClassDef("Ltest/fivethree;", "Ltest/five;"),
TestUtils.makeInterfaceDef("Ljava/io/Serializable;"), TestUtils.makeInterfaceDef("Ljava/lang/Cloneable;"),
TestUtils.makeInterfaceDef("Ljava/io/Serializable;"),
// basic class and interface // basic class and interface
TestUtils.makeClassDef("Liface/classiface1;", "Ljava/lang/Object;", "Liface/iface1;"), TestUtils.makeClassDef("Liface/classiface1;", "Ljava/lang/Object;", "Liface/iface1;"),
TestUtils.makeInterfaceDef("Liface/iface1;"), TestUtils.makeInterfaceDef("Liface/iface1;"),
// a more complex interface tree // a more complex interface tree
TestUtils.makeInterfaceDef("Liface/base1;"), TestUtils.makeInterfaceDef("Liface/base1;"),
// implements undefined interface // implements undefined interface
TestUtils.makeInterfaceDef("Liface/sub1;", "Liface/base1;", "Liface/base2;"), TestUtils.makeInterfaceDef("Liface/sub1;", "Liface/base1;", "Liface/base2;"),
// this implements sub1, so that its interfaces can't be fully resolved either // this implements sub1, so that its interfaces can't be fully resolved either
TestUtils.makeInterfaceDef("Liface/sub2;", "Liface/base1;", "Liface/sub1;"), TestUtils.makeInterfaceDef("Liface/sub2;", "Liface/base1;", "Liface/sub1;"),
TestUtils.makeInterfaceDef("Liface/sub3;", "Liface/base1;"), TestUtils.makeInterfaceDef("Liface/sub3;", "Liface/base1;"),
TestUtils.makeInterfaceDef("Liface/sub4;", "Liface/base1;", "Liface/sub3;"), TestUtils.makeInterfaceDef("Liface/sub4;", "Liface/base1;", "Liface/sub3;"),
TestUtils.makeClassDef("Liface/classsub1;", "Ljava/lang/Object;", "Liface/sub1;"), TestUtils.makeClassDef("Liface/classsub1;", "Ljava/lang/Object;", "Liface/sub1;"),
TestUtils.makeClassDef("Liface/classsub2;", "Ljava/lang/Object;", "Liface/sub2;"), TestUtils.makeClassDef("Liface/classsub2;", "Ljava/lang/Object;", "Liface/sub2;"),
TestUtils.makeClassDef("Liface/classsub3;", "Ljava/lang/Object;", "Liface/sub3;", "Liface/base;"), TestUtils.makeClassDef("Liface/classsub3;", "Ljava/lang/Object;", "Liface/sub3;",
TestUtils.makeClassDef("Liface/classsub4;", "Ljava/lang/Object;", "Liface/sub3;", "Liface/sub4;"), "Liface/base;"),
TestUtils.makeClassDef("Liface/classsubsub4;", "Liface/classsub4;"), TestUtils.makeClassDef("Liface/classsub4;", "Ljava/lang/Object;", "Liface/sub3;",
TestUtils.makeClassDef("Liface/classsub1234;", "Ljava/lang/Object;", "Liface/sub1;", "Liface/sub2;", "Liface/sub4;"),
"Liface/sub3;", "Liface/sub4;") TestUtils.makeClassDef("Liface/classsubsub4;", "Liface/classsub4;"),
TestUtils.makeClassDef("Liface/classsub1234;", "Ljava/lang/Object;", "Liface/sub1;",
"Liface/sub2;", "Liface/sub3;", "Liface/sub4;")
))); )));
} }

View File

@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile; import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.Instruction;
@ -66,7 +67,7 @@ public class CustomMethodInlineTableTest {
ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, null, null, ImmutableList.of(method)); null, null, null, null, null, ImmutableList.of(method));
DexFile dexFile = new ImmutableDexFile(ImmutableList.of(classDef)); DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile,
15, false); 15, false);
@ -93,7 +94,7 @@ public class CustomMethodInlineTableTest {
ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, null, ImmutableList.of(method), null); null, null, null, null, ImmutableList.of(method), null);
DexFile dexFile = new ImmutableDexFile(ImmutableList.of(classDef)); DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile,
15, false); 15, false);
@ -120,7 +121,7 @@ public class CustomMethodInlineTableTest {
ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null,
null, null, null, null, ImmutableList.of(method), null); null, null, null, null, ImmutableList.of(method), null);
DexFile dexFile = new ImmutableDexFile(ImmutableList.of(classDef)); DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), ImmutableList.of(classDef));
ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile,
15, false); 15, false);

View File

@ -34,6 +34,7 @@ package org.jf.dexlib2.analysis.util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import junit.framework.Assert; import junit.framework.Assert;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.analysis.ClassPath; import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.TestUtils; import org.jf.dexlib2.analysis.TestUtils;
import org.jf.dexlib2.analysis.TypeProto; import org.jf.dexlib2.analysis.TypeProto;
@ -56,7 +57,7 @@ public class SuperclassChainTest {
ImmutableSet<ClassDef> classes = ImmutableSet.<ClassDef>of( ImmutableSet<ClassDef> classes = ImmutableSet.<ClassDef>of(
objectClassDef, oneClassDef, twoClassDef, threeClassDef); objectClassDef, oneClassDef, twoClassDef, threeClassDef);
ClassPath classPath = new ClassPath(new ImmutableDexFile(classes)); ClassPath classPath = new ClassPath(new ImmutableDexFile(Opcodes.forApi(19), classes));
TypeProto objectClassProto = classPath.getClass("Ljava/lang/Object;"); TypeProto objectClassProto = classPath.getClass("Ljava/lang/Object;");
TypeProto oneClassProto = classPath.getClass("Ltest/one;"); TypeProto oneClassProto = classPath.getClass("Ltest/one;");
@ -87,7 +88,7 @@ public class SuperclassChainTest {
ClassDef twoClassDef = TestUtils.makeClassDef("Ltest/two;", "Ltest/one;"); ClassDef twoClassDef = TestUtils.makeClassDef("Ltest/two;", "Ltest/one;");
ClassDef threeClassDef = TestUtils.makeClassDef("Ltest/three;", "Ltest/two;"); ClassDef threeClassDef = TestUtils.makeClassDef("Ltest/three;", "Ltest/two;");
ImmutableSet<ClassDef> classes = ImmutableSet.<ClassDef>of(twoClassDef, threeClassDef); ImmutableSet<ClassDef> classes = ImmutableSet.<ClassDef>of(twoClassDef, threeClassDef);
ClassPath classPath = new ClassPath(new ImmutableDexFile(classes)); ClassPath classPath = new ClassPath(new ImmutableDexFile(Opcodes.forApi(19), classes));
TypeProto unknownClassProto = classPath.getUnknownClass(); TypeProto unknownClassProto = classPath.getUnknownClass();
TypeProto oneClassProto = classPath.getClass("Ltest/one;"); TypeProto oneClassProto = classPath.getClass("Ltest/one;");

View File

@ -72,7 +72,7 @@ public class DexWriterTest {
MemoryDataStore dataStore = new MemoryDataStore(); MemoryDataStore dataStore = new MemoryDataStore();
try { try {
DexPool.writeTo(dataStore, new ImmutableDexFile(ImmutableSet.of(classDef))); DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.forApi(19), ImmutableSet.of(classDef)));
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
@ -112,7 +112,7 @@ public class DexWriterTest {
MemoryDataStore dataStore = new MemoryDataStore(); MemoryDataStore dataStore = new MemoryDataStore();
try { try {
DexPool.writeTo(dataStore, new ImmutableDexFile(ImmutableSet.of(classDef))); DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.forApi(19), ImmutableSet.of(classDef)));
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }