mirror of
https://github.com/revanced/smali.git
synced 2025-06-12 04:17:36 +02:00
Add support for an --api-level parameter
This commit is contained in:
@ -73,7 +73,12 @@ public class Instruction21c extends InstructionWithReference implements SingleRe
|
||||
|
||||
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||
if(getReferencedItem().getIndex() > 0xFFFF) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s/jumbo instruction instead.", opcode.referenceType.name(), opcode.name));
|
||||
if (opcode.hasJumboOpcode()) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.",
|
||||
opcode.referenceType.name(), opcode.getJumboOpcode().name));
|
||||
} else {
|
||||
throw new RuntimeException(String.format("%s index is too large", opcode.referenceType.name()));
|
||||
}
|
||||
}
|
||||
|
||||
out.writeByte(opcode.value);
|
||||
|
@ -64,7 +64,12 @@ public class Instruction22c extends InstructionWithReference implements TwoRegis
|
||||
|
||||
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||
if(getReferencedItem().getIndex() > 0xFFFF) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s/jumbo instruction instead.", opcode.referenceType.name(), opcode.name));
|
||||
if (opcode.hasJumboOpcode()) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.",
|
||||
opcode.referenceType.name(), opcode.getJumboOpcode().name));
|
||||
} else {
|
||||
throw new RuntimeException(String.format("%s index is too large.", opcode.referenceType.name()));
|
||||
}
|
||||
}
|
||||
|
||||
out.writeByte(opcode.value);
|
||||
|
@ -95,7 +95,12 @@ public class Instruction35c extends InstructionWithReference implements FiveRegi
|
||||
|
||||
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||
if(getReferencedItem().getIndex() > 0xFFFF) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s/jumbo instruction instead.", opcode.referenceType.name(), opcode.name));
|
||||
if (opcode.hasJumboOpcode()) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.",
|
||||
opcode.referenceType.name(), opcode.getJumboOpcode().name));
|
||||
} else {
|
||||
throw new RuntimeException(String.format("%s index is too large.", opcode.referenceType.name()));
|
||||
}
|
||||
}
|
||||
|
||||
out.writeByte(opcode.value);
|
||||
|
@ -81,7 +81,12 @@ public class Instruction3rc extends InstructionWithReference implements Register
|
||||
|
||||
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||
if(getReferencedItem().getIndex() > 0xFFFF) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the jumbo variant of the instruction instead.", opcode.referenceType.name()));
|
||||
if (opcode.hasJumboOpcode()) {
|
||||
throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.",
|
||||
opcode.referenceType.name(), opcode.getJumboOpcode().name));
|
||||
} else {
|
||||
throw new RuntimeException(String.format("%s index is too large.", opcode.referenceType.name()));
|
||||
}
|
||||
}
|
||||
|
||||
out.writeByte(opcode.value);
|
||||
|
@ -374,6 +374,47 @@ public enum Opcode
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeOpcodes(Opcode... toRemove) {
|
||||
for (Opcode opcode: toRemove) {
|
||||
opcodesByName.remove(opcode.name.toLowerCase().hashCode());
|
||||
|
||||
if (((opcode.value >> 8) & 0xFF) == 0x00) {
|
||||
opcodesByValue[opcode.value] = null;
|
||||
} else {
|
||||
expandedOpcodesByValue[opcode.value & 0xFF] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will add/remove/replace various opcodes in the value/name maps as needed,
|
||||
* based on the idiosyncrasies of that api level
|
||||
* @param apiLevel
|
||||
*/
|
||||
public static void updateMapsForApiLevel(int apiLevel) {
|
||||
if (apiLevel < 5) {
|
||||
removeOpcodes(THROW_VERIFICATION_ERROR);
|
||||
}
|
||||
if (apiLevel < 8) {
|
||||
removeOpcodes(EXECUTE_INLINE_RANGE);
|
||||
}
|
||||
if (apiLevel < 9) {
|
||||
removeOpcodes(IGET_VOLATILE, IPUT_VOLATILE, SGET_VOLATILE, SPUT_VOLATILE, IGET_OBJECT_VOLATILE,
|
||||
IGET_WIDE_VOLATILE, IPUT_WIDE_VOLATILE, SGET_WIDE_VOLATILE, SPUT_WIDE_VOLATILE,
|
||||
IPUT_OBJECT_VOLATILE, SGET_OBJECT_VOLATILE, SPUT_OBJECT_VOLATILE);
|
||||
}
|
||||
if (apiLevel < 14) {
|
||||
removeOpcodes(CONST_CLASS_JUMBO, CHECK_CAST_JUMBO, INSTANCE_OF_JUMBO, NEW_INSTANCE_JUMBO,
|
||||
NEW_ARRAY_JUMBO, FILLED_NEW_ARRAY_JUMBO, IGET_JUMBO, IGET_WIDE_JUMBO, IGET_OBJECT_JUMBO,
|
||||
IGET_BOOLEAN_JUMBO, IGET_BYTE_JUMBO, IGET_CHAR_JUMBO, IGET_SHORT_JUMBO, IPUT_JUMBO, IPUT_WIDE_JUMBO,
|
||||
IPUT_OBJECT_JUMBO, IPUT_BOOLEAN_JUMBO, IPUT_BYTE_JUMBO, IPUT_CHAR_JUMBO, IPUT_SHORT_JUMBO,
|
||||
SGET_JUMBO, SGET_WIDE_JUMBO, SGET_OBJECT_JUMBO, SGET_BOOLEAN_JUMBO, SGET_BYTE_JUMBO,
|
||||
SGET_CHAR_JUMBO, SGET_SHORT_JUMBO, SPUT_JUMBO, SPUT_WIDE_JUMBO, SPUT_OBJECT_JUMBO,
|
||||
SPUT_BOOLEAN_JUMBO, SPUT_BYTE_JUMBO, SPUT_CHAR_JUMBO, SPUT_SHORT_JUMBO, INVOKE_VIRTUAL_JUMBO,
|
||||
INVOKE_SUPER_JUMBO, INVOKE_DIRECT_JUMBO, INVOKE_STATIC_JUMBO, INVOKE_INTERFACE_JUMBO);
|
||||
}
|
||||
}
|
||||
|
||||
public final short value;
|
||||
public final String name;
|
||||
public final ReferenceType referenceType;
|
||||
@ -435,7 +476,7 @@ public enum Opcode
|
||||
}
|
||||
|
||||
public final boolean hasJumboOpcode() {
|
||||
return jumboOpcode != -1;
|
||||
return jumboOpcode != -1 && Opcode.getOpcodeByValue(jumboOpcode) != null;
|
||||
}
|
||||
|
||||
public final Opcode getJumboOpcode() {
|
||||
|
@ -458,10 +458,13 @@ public class CodeItem extends Item<CodeItem> {
|
||||
InstructionWithJumboVariant instructionWithJumboVariant =
|
||||
(InstructionWithJumboVariant)referenceInstruction;
|
||||
|
||||
replaceInstructionAtAddress(currentCodeAddress,
|
||||
instructionWithJumboVariant.makeJumbo());
|
||||
didSomething = true;
|
||||
break;
|
||||
Instruction jumboInstruction = instructionWithJumboVariant.makeJumbo();
|
||||
if (jumboInstruction != null) {
|
||||
replaceInstructionAtAddress(currentCodeAddress,
|
||||
instructionWithJumboVariant.makeJumbo());
|
||||
didSomething = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user