mirror of
https://github.com/revanced/smali.git
synced 2025-05-14 21:27:06 +02:00
Add support for dex version 39 in dexlib2
This commit is contained in:
parent
69d004cbfd
commit
2db1dec703
@ -299,7 +299,7 @@ public enum Opcode
|
|||||||
|
|
||||||
IPUT_OBJECT_VOLATILE(firstApi(0xfc, 9), "iput-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_OBJECT_VOLATILE(firstApi(0xfc, 9), "iput-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
SGET_OBJECT_VOLATILE(firstApi(0xfd, 9), "sget-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.STATIC_FIELD_ACCESSOR),
|
SGET_OBJECT_VOLATILE(firstApi(0xfd, 9), "sget-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.STATIC_FIELD_ACCESSOR),
|
||||||
SPUT_OBJECT_VOLATILE(firstApi(0xfe, 9), "sput-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.STATIC_FIELD_ACCESSOR),
|
SPUT_OBJECT_VOLATILE(betweenApi(0xfe, 9, 19), "sput-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.STATIC_FIELD_ACCESSOR),
|
||||||
|
|
||||||
PACKED_SWITCH_PAYLOAD(0x100, "packed-switch-payload", ReferenceType.NONE, Format.PackedSwitchPayload, 0),
|
PACKED_SWITCH_PAYLOAD(0x100, "packed-switch-payload", ReferenceType.NONE, Format.PackedSwitchPayload, 0),
|
||||||
SPARSE_SWITCH_PAYLOAD(0x200, "sparse-switch-payload", ReferenceType.NONE, Format.SparseSwitchPayload, 0),
|
SPARSE_SWITCH_PAYLOAD(0x200, "sparse-switch-payload", ReferenceType.NONE, Format.SparseSwitchPayload, 0),
|
||||||
@ -309,7 +309,10 @@ public enum Opcode
|
|||||||
INVOKE_POLYMORPHIC_RANGE(firstArtVersion(0xfb, 87), "invoke-polymorphic/range", ReferenceType.METHOD, ReferenceType.METHOD_PROTO, Format.Format4rcc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_POLYMORPHIC_RANGE(firstArtVersion(0xfb, 87), "invoke-polymorphic/range", ReferenceType.METHOD, ReferenceType.METHOD_PROTO, Format.Format4rcc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
|
|
||||||
INVOKE_CUSTOM(firstArtVersion(0xfc, 111), "invoke-custom", ReferenceType.CALL_SITE, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_CUSTOM(firstArtVersion(0xfc, 111), "invoke-custom", ReferenceType.CALL_SITE, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
INVOKE_CUSTOM_RANGE(firstArtVersion(0xfd, 111), "invoke-custom/range", ReferenceType.CALL_SITE, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT);
|
INVOKE_CUSTOM_RANGE(firstArtVersion(0xfd, 111), "invoke-custom/range", ReferenceType.CALL_SITE, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
|
|
||||||
|
CONST_METHOD_HANDLE(firstArtVersion(0xfe, 134), "const-method-handle", ReferenceType.METHOD_HANDLE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
|
CONST_METHOD_TYPE(firstArtVersion(0xff, 134), "const-method-type", ReferenceType.METHOD_PROTO, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER);
|
||||||
|
|
||||||
//if the instruction can throw an exception
|
//if the instruction can throw an exception
|
||||||
public static final int CAN_THROW = 0x1;
|
public static final int CAN_THROW = 0x1;
|
||||||
@ -398,6 +401,11 @@ public enum Opcode
|
|||||||
return Lists.newArrayList(new VersionConstraint(Range.atMost(api), Range.openClosed(0, 0), opcodeValue));
|
return Lists.newArrayList(new VersionConstraint(Range.atMost(api), Range.openClosed(0, 0), opcodeValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<VersionConstraint> betweenApi(int opcodeValue, int minApi, int maxApi) {
|
||||||
|
return Lists.newArrayList(new VersionConstraint(Range.closed(minApi, maxApi), Range.openClosed(0, 0),
|
||||||
|
opcodeValue));
|
||||||
|
}
|
||||||
|
|
||||||
private static List<VersionConstraint> firstArtVersion(int opcodeValue, int artVersion) {
|
private static List<VersionConstraint> firstArtVersion(int opcodeValue, int artVersion) {
|
||||||
return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atLeast(artVersion), opcodeValue));
|
return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atLeast(artVersion), opcodeValue));
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class Opcodes {
|
|||||||
*/
|
*/
|
||||||
public final int api;
|
public final int api;
|
||||||
public final int artVersion;
|
public final int artVersion;
|
||||||
@Nonnull private final Opcode[] opcodesByValue = new Opcode[255];
|
@Nonnull private final Opcode[] opcodesByValue = new Opcode[256];
|
||||||
@Nonnull private final EnumMap<Opcode, Short> opcodeValues;
|
@Nonnull private final EnumMap<Opcode, Short> opcodeValues;
|
||||||
@Nonnull private final HashMap<String, Opcode> opcodesByName;
|
@Nonnull private final HashMap<String, Opcode> opcodesByName;
|
||||||
|
|
||||||
@ -79,8 +79,6 @@ public class Opcodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Opcodes(int api, int artVersion) {
|
private Opcodes(int api, int artVersion) {
|
||||||
|
|
||||||
|
|
||||||
if (api >= 21) {
|
if (api >= 21) {
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.artVersion = mapApiToArtVersion(api);
|
this.artVersion = mapApiToArtVersion(api);
|
||||||
|
@ -44,10 +44,20 @@ public class VersionMap {
|
|||||||
if (dexVersion == 38) {
|
if (dexVersion == 38) {
|
||||||
return 27;
|
return 27;
|
||||||
}
|
}
|
||||||
|
if (dexVersion == 39) {
|
||||||
|
return 28;
|
||||||
|
}
|
||||||
throw new RuntimeException("Unsupported dex version " + dexVersion);
|
throw new RuntimeException("Unsupported dex version " + dexVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int mapArtVersionToApi(int artVersion) {
|
public static int mapArtVersionToApi(int artVersion) {
|
||||||
|
// 144 is the current version in the master branch of AOSP as of 2018-05-22
|
||||||
|
if (artVersion >= 144) {
|
||||||
|
return 28;
|
||||||
|
}
|
||||||
|
if (artVersion >= 131) {
|
||||||
|
return 27;
|
||||||
|
}
|
||||||
if (artVersion >= 124) {
|
if (artVersion >= 124) {
|
||||||
return 26;
|
return 26;
|
||||||
}
|
}
|
||||||
@ -82,6 +92,11 @@ public class VersionMap {
|
|||||||
return 79;
|
return 79;
|
||||||
case 26:
|
case 26:
|
||||||
return 124;
|
return 124;
|
||||||
|
case 27:
|
||||||
|
return 131;
|
||||||
|
case 28:
|
||||||
|
// 144 is the current version in the master branch of AOSP as of 2018-05-22
|
||||||
|
return 144;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Art version 143 and api level 27 do not correspond to any
|
// NOTE: Art version 143 and api level 27 do not correspond to any
|
||||||
|
@ -43,7 +43,7 @@ public class HeaderItem {
|
|||||||
public static final int ITEM_SIZE = 0x70;
|
public static final int ITEM_SIZE = 0x70;
|
||||||
|
|
||||||
private static final byte[] MAGIC_VALUE = new byte[] { 0x64, 0x65, 0x78, 0x0a, 0x00, 0x00, 0x00, 0x00 };
|
private static final byte[] MAGIC_VALUE = new byte[] { 0x64, 0x65, 0x78, 0x0a, 0x00, 0x00, 0x00, 0x00 };
|
||||||
private static final int[] SUPPORTED_DEX_VERSIONS = new int[] { 35, 37, 38 };
|
private static final int[] SUPPORTED_DEX_VERSIONS = new int[] { 35, 37, 38, 39 };
|
||||||
|
|
||||||
public static final int LITTLE_ENDIAN_TAG = 0x12345678;
|
public static final int LITTLE_ENDIAN_TAG = 0x12345678;
|
||||||
public static final int BIG_ENDIAN_TAG = 0x78563412;
|
public static final int BIG_ENDIAN_TAG = 0x78563412;
|
||||||
@ -235,8 +235,10 @@ public class HeaderItem {
|
|||||||
} if (api < 26) {
|
} if (api < 26) {
|
||||||
// On android N and later we support dex version 037.
|
// On android N and later we support dex version 037.
|
||||||
return getMagicForDexVersion(37);
|
return getMagicForDexVersion(37);
|
||||||
} else {
|
} else if (api < 28) {
|
||||||
return getMagicForDexVersion(38);
|
return getMagicForDexVersion(38);
|
||||||
|
} else {
|
||||||
|
return getMagicForDexVersion(39);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ public abstract class DexBackedReference {
|
|||||||
return new DexBackedFieldReference(dexFile, referenceIndex);
|
return new DexBackedFieldReference(dexFile, referenceIndex);
|
||||||
case ReferenceType.METHOD_PROTO:
|
case ReferenceType.METHOD_PROTO:
|
||||||
return new DexBackedMethodProtoReference(dexFile, referenceIndex);
|
return new DexBackedMethodProtoReference(dexFile, referenceIndex);
|
||||||
|
case ReferenceType.METHOD_HANDLE:
|
||||||
|
return new DexBackedMethodHandleReference(dexFile, referenceIndex);
|
||||||
case ReferenceType.CALL_SITE:
|
case ReferenceType.CALL_SITE:
|
||||||
return new DexBackedCallSiteReference(dexFile, referenceIndex);
|
return new DexBackedCallSiteReference(dexFile, referenceIndex);
|
||||||
default:
|
default:
|
||||||
|
@ -1036,7 +1036,7 @@ public abstract class DexWriter<
|
|||||||
|
|
||||||
InstructionWriter instructionWriter =
|
InstructionWriter instructionWriter =
|
||||||
InstructionWriter.makeInstructionWriter(opcodes, writer, stringSection, typeSection, fieldSection,
|
InstructionWriter.makeInstructionWriter(opcodes, writer, stringSection, typeSection, fieldSection,
|
||||||
methodSection, protoSection, callSiteSection);
|
methodSection, protoSection, methodHandleSection, callSiteSection);
|
||||||
|
|
||||||
writer.writeInt(codeUnitCount);
|
writer.writeInt(codeUnitCount);
|
||||||
int codeOffset = 0;
|
int codeOffset = 0;
|
||||||
|
@ -50,7 +50,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class InstructionWriter<StringRef extends StringReference, TypeRef extends TypeReference,
|
public class InstructionWriter<StringRef extends StringReference, TypeRef extends TypeReference,
|
||||||
FieldRefKey extends FieldReference, MethodRefKey extends MethodReference,
|
FieldRefKey extends FieldReference, MethodRefKey extends MethodReference,
|
||||||
ProtoRefKey extends MethodProtoReference, CallSiteKey extends CallSiteReference> {
|
ProtoRefKey extends MethodProtoReference, MethodHandleKey extends MethodHandleReference,
|
||||||
|
CallSiteKey extends CallSiteReference> {
|
||||||
@Nonnull private final Opcodes opcodes;
|
@Nonnull private final Opcodes opcodes;
|
||||||
@Nonnull private final DexDataWriter writer;
|
@Nonnull private final DexDataWriter writer;
|
||||||
@Nonnull private final StringSection<?, StringRef> stringSection;
|
@Nonnull private final StringSection<?, StringRef> stringSection;
|
||||||
@ -58,12 +59,14 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
|
|||||||
@Nonnull private final FieldSection<?, ?, FieldRefKey, ?> fieldSection;
|
@Nonnull private final FieldSection<?, ?, FieldRefKey, ?> fieldSection;
|
||||||
@Nonnull private final MethodSection<?, ?, ?, MethodRefKey, ?> methodSection;
|
@Nonnull private final MethodSection<?, ?, ?, MethodRefKey, ?> methodSection;
|
||||||
@Nonnull private final ProtoSection<?, ?, ProtoRefKey, ?> protoSection;
|
@Nonnull private final ProtoSection<?, ?, ProtoRefKey, ?> protoSection;
|
||||||
|
@Nonnull private final MethodHandleSection<MethodHandleKey, ?, ?> methodHandleSection;
|
||||||
@Nonnull private final CallSiteSection<CallSiteKey, ?> callSiteSection;
|
@Nonnull private final CallSiteSection<CallSiteKey, ?> callSiteSection;
|
||||||
|
|
||||||
@Nonnull static <StringRef extends StringReference, TypeRef extends TypeReference,
|
@Nonnull static <StringRef extends StringReference, TypeRef extends TypeReference,
|
||||||
FieldRefKey extends FieldReference, MethodRefKey extends MethodReference,
|
FieldRefKey extends FieldReference, MethodRefKey extends MethodReference,
|
||||||
ProtoRefKey extends MethodProtoReference, CallSiteKey extends CallSiteReference>
|
ProtoRefKey extends MethodProtoReference, MethodHandleKey extends MethodHandleReference,
|
||||||
InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey, ProtoRefKey, CallSiteKey>
|
CallSiteKey extends CallSiteReference>
|
||||||
|
InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey, ProtoRefKey, MethodHandleKey, CallSiteKey>
|
||||||
makeInstructionWriter(
|
makeInstructionWriter(
|
||||||
@Nonnull Opcodes opcodes,
|
@Nonnull Opcodes opcodes,
|
||||||
@Nonnull DexDataWriter writer,
|
@Nonnull DexDataWriter writer,
|
||||||
@ -72,9 +75,12 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
|
|||||||
@Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
|
@Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
|
||||||
@Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
|
@Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
|
||||||
@Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection,
|
@Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection,
|
||||||
|
@Nonnull MethodHandleSection<MethodHandleKey, ?, ?> methodHandleSection,
|
||||||
@Nonnull CallSiteSection<CallSiteKey, ?> callSiteSection) {
|
@Nonnull CallSiteSection<CallSiteKey, ?> callSiteSection) {
|
||||||
return new InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey, ProtoRefKey, CallSiteKey>(
|
return new InstructionWriter<
|
||||||
opcodes, writer, stringSection, typeSection, fieldSection, methodSection, protoSection, callSiteSection);
|
StringRef, TypeRef, FieldRefKey, MethodRefKey, ProtoRefKey, MethodHandleKey,CallSiteKey>(
|
||||||
|
opcodes, writer, stringSection, typeSection, fieldSection, methodSection, protoSection,
|
||||||
|
methodHandleSection, callSiteSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionWriter(@Nonnull Opcodes opcodes,
|
InstructionWriter(@Nonnull Opcodes opcodes,
|
||||||
@ -84,6 +90,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
|
|||||||
@Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
|
@Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
|
||||||
@Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
|
@Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
|
||||||
@Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection,
|
@Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection,
|
||||||
|
@Nonnull MethodHandleSection<MethodHandleKey, ?, ?> methodHandleSection,
|
||||||
@Nonnull CallSiteSection<CallSiteKey, ?> callSiteSection) {
|
@Nonnull CallSiteSection<CallSiteKey, ?> callSiteSection) {
|
||||||
this.opcodes = opcodes;
|
this.opcodes = opcodes;
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
@ -92,6 +99,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
|
|||||||
this.fieldSection = fieldSection;
|
this.fieldSection = fieldSection;
|
||||||
this.methodSection = methodSection;
|
this.methodSection = methodSection;
|
||||||
this.protoSection = protoSection;
|
this.protoSection = protoSection;
|
||||||
|
this.methodHandleSection = methodHandleSection;
|
||||||
this.callSiteSection = callSiteSection;
|
this.callSiteSection = callSiteSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,6 +559,8 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
|
|||||||
return typeSection.getItemIndex((TypeRef) reference);
|
return typeSection.getItemIndex((TypeRef) reference);
|
||||||
case ReferenceType.METHOD_PROTO:
|
case ReferenceType.METHOD_PROTO:
|
||||||
return protoSection.getItemIndex((ProtoRefKey) reference);
|
return protoSection.getItemIndex((ProtoRefKey) reference);
|
||||||
|
case ReferenceType.METHOD_HANDLE:
|
||||||
|
return methodHandleSection.getItemIndex((MethodHandleKey) reference);
|
||||||
case ReferenceType.CALL_SITE:
|
case ReferenceType.CALL_SITE:
|
||||||
return callSiteSection.getItemIndex((CallSiteKey) reference);
|
return callSiteSection.getItemIndex((CallSiteKey) reference);
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user