mirror of
https://github.com/revanced/smali.git
synced 2025-05-09 10:54:29 +02:00
Redid how instructions are handled
git-svn-id: https://smali.googlecode.com/svn/trunk@137 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
0e91ee0cc2
commit
67a4c3cbb2
@ -323,92 +323,92 @@ instruction returns [int size]
|
|||||||
@init {boolean needsNop = false; int targetCount = 0;}
|
@init {boolean needsNop = false; int targetCount = 0;}
|
||||||
: //e.g. goto endloop:
|
: //e.g. goto endloop:
|
||||||
//e.g. goto +3
|
//e.g. goto +3
|
||||||
INSTRUCTION_FORMAT10t (LABEL | OFFSET) {$size = Format10t.Format.getByteCount();}
|
INSTRUCTION_FORMAT10t (LABEL | OFFSET) {$size = Format.Format10t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT10t[$start, "I_STATEMENT_FORMAT10t"] INSTRUCTION_FORMAT10t LABEL? OFFSET?)
|
-> ^(I_STATEMENT_FORMAT10t[$start, "I_STATEMENT_FORMAT10t"] INSTRUCTION_FORMAT10t LABEL? OFFSET?)
|
||||||
| //e.g. return
|
| //e.g. return
|
||||||
INSTRUCTION_FORMAT10x {$size = Format10x.Format.getByteCount();}
|
INSTRUCTION_FORMAT10x {$size = Format.Format10x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT10x[$start, "I_STATEMENT_FORMAT10x"] INSTRUCTION_FORMAT10x)
|
-> ^(I_STATEMENT_FORMAT10x[$start, "I_STATEMENT_FORMAT10x"] INSTRUCTION_FORMAT10x)
|
||||||
| //e.g. const/4 v0, 5
|
| //e.g. const/4 v0, 5
|
||||||
INSTRUCTION_FORMAT11n REGISTER integral_literal {$size = Format11n.Format.getByteCount();}
|
INSTRUCTION_FORMAT11n REGISTER integral_literal {$size = Format.Format11n.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT11n[$start, "I_STARTMENT_FORMAT11n"] INSTRUCTION_FORMAT11n REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT11n[$start, "I_STARTMENT_FORMAT11n"] INSTRUCTION_FORMAT11n REGISTER integral_literal)
|
||||||
| //e.g. move-result-object v1
|
| //e.g. move-result-object v1
|
||||||
INSTRUCTION_FORMAT11x REGISTER {$size = Format11x.Format.getByteCount();}
|
INSTRUCTION_FORMAT11x REGISTER {$size = Format.Format11x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT11x[$start, "I_STATEMENT_FORMAT11x"] INSTRUCTION_FORMAT11x REGISTER)
|
-> ^(I_STATEMENT_FORMAT11x[$start, "I_STATEMENT_FORMAT11x"] INSTRUCTION_FORMAT11x REGISTER)
|
||||||
| //e.g. move v1 v2
|
| //e.g. move v1 v2
|
||||||
INSTRUCTION_FORMAT12x REGISTER REGISTER {$size = Format12x.Format.getByteCount();}
|
INSTRUCTION_FORMAT12x REGISTER REGISTER {$size = Format.Format12x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT12x[$start, "I_STATEMENT_FORMAT12x"] INSTRUCTION_FORMAT12x REGISTER REGISTER)
|
-> ^(I_STATEMENT_FORMAT12x[$start, "I_STATEMENT_FORMAT12x"] INSTRUCTION_FORMAT12x REGISTER REGISTER)
|
||||||
| //e.g. goto/16 endloop:
|
| //e.g. goto/16 endloop:
|
||||||
INSTRUCTION_FORMAT20t (LABEL | OFFSET) {$size = Format20t.Format.getByteCount();}
|
INSTRUCTION_FORMAT20t (LABEL | OFFSET) {$size = Format.Format20t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT20t[$start, "I_STATEMENT_FORMAT20t"] INSTRUCTION_FORMAT20t LABEL? OFFSET?)
|
-> ^(I_STATEMENT_FORMAT20t[$start, "I_STATEMENT_FORMAT20t"] INSTRUCTION_FORMAT20t LABEL? OFFSET?)
|
||||||
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
|
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
|
||||||
INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field {$size = Format21c.Format.getByteCount();}
|
INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field {$size = Format.Format21c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT21c_FIELD[$start, "I_STATEMENT_FORMAT21c_FIELD"] INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field)
|
-> ^(I_STATEMENT_FORMAT21c_FIELD[$start, "I_STATEMENT_FORMAT21c_FIELD"] INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field)
|
||||||
| //e.g. const-string v1 "Hello World!"
|
| //e.g. const-string v1 "Hello World!"
|
||||||
INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL {$size = Format21c.Format.getByteCount();}
|
INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL {$size = Format.Format21c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT21c_STRING[$start, "I_STATEMENT_FORMAT21c_STRING"] INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL)
|
-> ^(I_STATEMENT_FORMAT21c_STRING[$start, "I_STATEMENT_FORMAT21c_STRING"] INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL)
|
||||||
| //e.g. const-class v2 org/jf/HelloWorld2/HelloWorld2
|
| //e.g. const-class v2 org/jf/HelloWorld2/HelloWorld2
|
||||||
INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor {$size = Format21c.Format.getByteCount();}
|
INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor {$size = Format.Format21c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor)
|
-> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor)
|
||||||
| //e.g. const/high16 v1, 1234
|
| //e.g. const/high16 v1, 1234
|
||||||
INSTRUCTION_FORMAT21h REGISTER integral_literal {$size = Format21h.Format.getByteCount();}
|
INSTRUCTION_FORMAT21h REGISTER integral_literal {$size = Format.Format21h.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT21h[$start, "I_STATEMENT_FORMAT21h"] INSTRUCTION_FORMAT21h REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT21h[$start, "I_STATEMENT_FORMAT21h"] INSTRUCTION_FORMAT21h REGISTER integral_literal)
|
||||||
| //e.g. const/16 v1, 1234
|
| //e.g. const/16 v1, 1234
|
||||||
INSTRUCTION_FORMAT21s REGISTER integral_literal {$size = Format21s.Format.getByteCount();}
|
INSTRUCTION_FORMAT21s REGISTER integral_literal {$size = Format.Format21s.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT21s[$start, "I_STATEMENT_FORMAT21s"] INSTRUCTION_FORMAT21s REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT21s[$start, "I_STATEMENT_FORMAT21s"] INSTRUCTION_FORMAT21s REGISTER integral_literal)
|
||||||
| //e.g. if-eqz v0, endloop:
|
| //e.g. if-eqz v0, endloop:
|
||||||
INSTRUCTION_FORMAT21t REGISTER (LABEL | OFFSET) {$size = Format21t.Format.getByteCount();}
|
INSTRUCTION_FORMAT21t REGISTER (LABEL | OFFSET) {$size = Format.Format21t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT21t[$start, "I_STATEMENT_FORMAT21t"] INSTRUCTION_FORMAT21t REGISTER LABEL? OFFSET?)
|
-> ^(I_STATEMENT_FORMAT21t[$start, "I_STATEMENT_FORMAT21t"] INSTRUCTION_FORMAT21t REGISTER LABEL? OFFSET?)
|
||||||
| //e.g. add-int v0, v1, 123
|
| //e.g. add-int v0, v1, 123
|
||||||
INSTRUCTION_FORMAT22b REGISTER REGISTER integral_literal {$size = Format22b.Format.getByteCount();}
|
INSTRUCTION_FORMAT22b REGISTER REGISTER integral_literal {$size = Format.Format22b.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT22b[$start, "I_STATEMENT_FORMAT22b"] INSTRUCTION_FORMAT22b REGISTER REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT22b[$start, "I_STATEMENT_FORMAT22b"] INSTRUCTION_FORMAT22b REGISTER REGISTER integral_literal)
|
||||||
| //e.g. iput-object v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
| //e.g. iput-object v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
||||||
INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field {$size = Format22c.Format.getByteCount();}
|
INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field {$size = Format.Format22c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_STATEMENT_FORMAT22c_FIELD"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field)
|
-> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_STATEMENT_FORMAT22c_FIELD"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field)
|
||||||
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
||||||
INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor {$size = Format22c.Format.getByteCount();}
|
INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor {$size = Format.Format22c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor)
|
-> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor)
|
||||||
| //e.g. add-int/lit16 v0, v1, 12345
|
| //e.g. add-int/lit16 v0, v1, 12345
|
||||||
INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal {$size = Format22s.Format.getByteCount();}
|
INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal {$size = Format.Format22s.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT22s[$start, "I_STATEMENT_FORMAT22s"] INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT22s[$start, "I_STATEMENT_FORMAT22s"] INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal)
|
||||||
| //e.g. if-eq v0, v1, endloop:
|
| //e.g. if-eq v0, v1, endloop:
|
||||||
INSTRUCTION_FORMAT22t REGISTER REGISTER (LABEL | OFFSET) {$size = Format22t.Format.getByteCount();}
|
INSTRUCTION_FORMAT22t REGISTER REGISTER (LABEL | OFFSET) {$size = Format.Format22t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT22t[$start, "I_STATEMENT_FFORMAT22t"] INSTRUCTION_FORMAT22t REGISTER REGISTER LABEL? OFFSET?)
|
-> ^(I_STATEMENT_FORMAT22t[$start, "I_STATEMENT_FFORMAT22t"] INSTRUCTION_FORMAT22t REGISTER REGISTER LABEL? OFFSET?)
|
||||||
| //e.g. move/from16 v1, v1234
|
| //e.g. move/from16 v1, v1234
|
||||||
INSTRUCTION_FORMAT22x REGISTER REGISTER {$size = Format22x.Format.getByteCount();}
|
INSTRUCTION_FORMAT22x REGISTER REGISTER {$size = Format.Format22x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT22x[$start, "I_STATEMENT_FORMAT22x"] INSTRUCTION_FORMAT22x REGISTER REGISTER)
|
-> ^(I_STATEMENT_FORMAT22x[$start, "I_STATEMENT_FORMAT22x"] INSTRUCTION_FORMAT22x REGISTER REGISTER)
|
||||||
| //e.g. add-int v1, v2, v3
|
| //e.g. add-int v1, v2, v3
|
||||||
INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER {$size = Format23x.Format.getByteCount();}
|
INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER {$size = Format.Format23x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT23x[$start, "I_STATEMENT_FORMAT23x"] INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER)
|
-> ^(I_STATEMENT_FORMAT23x[$start, "I_STATEMENT_FORMAT23x"] INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER)
|
||||||
| //e.g. goto/32 endloop:
|
| //e.g. goto/32 endloop:
|
||||||
INSTRUCTION_FORMAT30t (LABEL | OFFSET) {$size = Format30t.Format.getByteCount();}
|
INSTRUCTION_FORMAT30t (LABEL | OFFSET) {$size = Format.Format30t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT30t[$start, "I_STATEMENT_FORMAT30t"] INSTRUCTION_FORMAT30t LABEL? OFFSET?)
|
-> ^(I_STATEMENT_FORMAT30t[$start, "I_STATEMENT_FORMAT30t"] INSTRUCTION_FORMAT30t LABEL? OFFSET?)
|
||||||
| //e.g. const-string/jumbo v1 "Hello World!"
|
| //e.g. const-string/jumbo v1 "Hello World!"
|
||||||
INSTRUCTION_FORMAT31c REGISTER STRING_LITERAL {$size = Format31c.Format.getByteCount();}
|
INSTRUCTION_FORMAT31c REGISTER STRING_LITERAL {$size = Format.Format31c.size;}
|
||||||
->^(I_STATEMENT_FORMAT31c[$start, "I_STATEMENT_FORMAT31c"] INSTRUCTION_FORMAT31c REGISTER STRING_LITERAL)
|
->^(I_STATEMENT_FORMAT31c[$start, "I_STATEMENT_FORMAT31c"] INSTRUCTION_FORMAT31c REGISTER STRING_LITERAL)
|
||||||
| //e.g. const v0, 123456
|
| //e.g. const v0, 123456
|
||||||
INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal {$size = Format31i.Format.getByteCount();}
|
INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal {$size = Format.Format31i.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT31i[$start, "I_STATEMENT_FORMAT31i"] INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal)
|
-> ^(I_STATEMENT_FORMAT31i[$start, "I_STATEMENT_FORMAT31i"] INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal)
|
||||||
| //e.g. fill-array-data v0, ArrayData:
|
| //e.g. fill-array-data v0, ArrayData:
|
||||||
INSTRUCTION_FORMAT31t REGISTER (LABEL | OFFSET) {$size = Format31t.Format.getByteCount();}
|
INSTRUCTION_FORMAT31t REGISTER (LABEL | OFFSET) {$size = Format.Format31t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT31t[$start, "I_STATEMENT_FORMAT31t"] INSTRUCTION_FORMAT31t REGISTER LABEL? OFFSET?)
|
-> ^(I_STATEMENT_FORMAT31t[$start, "I_STATEMENT_FORMAT31t"] INSTRUCTION_FORMAT31t REGISTER LABEL? OFFSET?)
|
||||||
| //e.g. move/16 v4567, v1234
|
| //e.g. move/16 v4567, v1234
|
||||||
INSTRUCTION_FORMAT32x REGISTER REGISTER {$size = Format32x.Format.getByteCount();}
|
INSTRUCTION_FORMAT32x REGISTER REGISTER {$size = Format.Format32x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT32x[$start, "I_STATEMENT_FORMAT32x"] INSTRUCTION_FORMAT32x REGISTER REGISTER)
|
-> ^(I_STATEMENT_FORMAT32x[$start, "I_STATEMENT_FORMAT32x"] INSTRUCTION_FORMAT32x REGISTER REGISTER)
|
||||||
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
||||||
INSTRUCTION_FORMAT35c_METHOD OPEN_BRACKET register_list CLOSE_BRACKET fully_qualified_method {$size = Format35c.Format.getByteCount();}
|
INSTRUCTION_FORMAT35c_METHOD OPEN_BRACKET register_list CLOSE_BRACKET fully_qualified_method {$size = Format.Format35c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT35c_METHOD[$start, "I_STATEMENT_FORMAT35c_METHOD"] INSTRUCTION_FORMAT35c_METHOD register_list fully_qualified_method)
|
-> ^(I_STATEMENT_FORMAT35c_METHOD[$start, "I_STATEMENT_FORMAT35c_METHOD"] INSTRUCTION_FORMAT35c_METHOD register_list fully_qualified_method)
|
||||||
| //e.g. filled-new-array {v0,v1}, I
|
| //e.g. filled-new-array {v0,v1}, I
|
||||||
INSTRUCTION_FORMAT35c_TYPE OPEN_BRACKET register_list CLOSE_BRACKET nonvoid_type_descriptor {$size = Format35c.Format.getByteCount();}
|
INSTRUCTION_FORMAT35c_TYPE OPEN_BRACKET register_list CLOSE_BRACKET nonvoid_type_descriptor {$size = Format.Format35c.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT35c_TYPE[$start, "I_STATEMENT_FORMAT35c_TYPE"] INSTRUCTION_FORMAT35c_TYPE register_list nonvoid_type_descriptor)
|
-> ^(I_STATEMENT_FORMAT35c_TYPE[$start, "I_STATEMENT_FORMAT35c_TYPE"] INSTRUCTION_FORMAT35c_TYPE register_list nonvoid_type_descriptor)
|
||||||
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
INSTRUCTION_FORMAT3rc_METHOD OPEN_BRACKET register_range CLOSE_BRACKET fully_qualified_method {$size = Format3rc.Format.getByteCount();}
|
INSTRUCTION_FORMAT3rc_METHOD OPEN_BRACKET register_range CLOSE_BRACKET fully_qualified_method {$size = Format.Format3rc.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method)
|
-> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method)
|
||||||
| //e.g. filled-new-array/range {v0..v6} I
|
| //e.g. filled-new-array/range {v0..v6} I
|
||||||
INSTRUCTION_FORMAT3rc_TYPE OPEN_BRACKET register_range CLOSE_BRACKET nonvoid_type_descriptor {$size = Format3rc.Format.getByteCount();}
|
INSTRUCTION_FORMAT3rc_TYPE OPEN_BRACKET register_range CLOSE_BRACKET nonvoid_type_descriptor {$size = Format.Format3rc.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT3rc_TYPE[$start, "I_STATEMENT_FORMAT3rc_TYPE"] INSTRUCTION_FORMAT3rc_TYPE register_range nonvoid_type_descriptor)
|
-> ^(I_STATEMENT_FORMAT3rc_TYPE[$start, "I_STATEMENT_FORMAT3rc_TYPE"] INSTRUCTION_FORMAT3rc_TYPE register_range nonvoid_type_descriptor)
|
||||||
| //e.g. const-wide v0, 5000000000L
|
| //e.g. const-wide v0, 5000000000L
|
||||||
INSTRUCTION_FORMAT51l REGISTER fixed_literal {$size = Format51l.Format.getByteCount();}
|
INSTRUCTION_FORMAT51l REGISTER fixed_literal {$size = Format.Format51l.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal)
|
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal)
|
||||||
|
|
|
|
||||||
ARRAY_DATA_DIRECTIVE
|
ARRAY_DATA_DIRECTIVE
|
||||||
{
|
{
|
||||||
|
@ -401,7 +401,7 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod,
|
|||||||
annotations
|
annotations
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ArrayList<Instruction> instructions = $statements.instructions;
|
ArrayList<InstructionField> instructions = $statements.instructions;
|
||||||
|
|
||||||
Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> temp = $method::tryList.encodeTries(dexFile);
|
Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> temp = $method::tryList.encodeTries(dexFile);
|
||||||
List<CodeItem.TryItem> tries = temp.first;
|
List<CodeItem.TryItem> tries = temp.first;
|
||||||
@ -640,16 +640,16 @@ source
|
|||||||
$method::debugInfo.addSetFile($address.address, $string_literal.value);
|
$method::debugInfo.addSetFile($address.address, $string_literal.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
statements[int totalMethodRegisters, int methodParameterRegisters] returns[ArrayList<Instruction> instructions]
|
statements[int totalMethodRegisters, int methodParameterRegisters] returns[ArrayList<InstructionField> instructions]
|
||||||
@init
|
@init
|
||||||
{
|
{
|
||||||
$instructions = new ArrayList<Instruction>();
|
$instructions = new ArrayList<InstructionField>();
|
||||||
}
|
}
|
||||||
: ^(I_STATEMENTS (instruction[$totalMethodRegisters, $methodParameterRegisters]
|
: ^(I_STATEMENTS (instruction[$totalMethodRegisters, $methodParameterRegisters]
|
||||||
{
|
{
|
||||||
if ($instruction.instruction != null) {
|
if ($instruction.instruction != null) {
|
||||||
$instructions.add($instruction.instruction);
|
$instructions.add($instruction.instruction);
|
||||||
$method::currentAddress += $instruction.instruction.getBytes().length/2;
|
$method::currentAddress += $instruction.instruction.getSize($method::currentAddress) / 2;
|
||||||
}
|
}
|
||||||
})*);
|
})*);
|
||||||
|
|
||||||
@ -690,7 +690,7 @@ offset_or_label returns[int offsetValue]
|
|||||||
: offset {$offsetValue = $offset.offsetValue;}
|
: offset {$offsetValue = $offset.offsetValue;}
|
||||||
| label_ref {$offsetValue = $label_ref.labelAddress-$method::currentAddress;};
|
| label_ref {$offsetValue = $label_ref.labelAddress-$method::currentAddress;};
|
||||||
|
|
||||||
instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Instruction instruction]
|
instruction[int totalMethodRegisters, int methodParameterRegisters] returns[InstructionField instruction]
|
||||||
: //e.g. goto endloop:
|
: //e.g. goto endloop:
|
||||||
^(I_STATEMENT_FORMAT10t INSTRUCTION_FORMAT10t offset_or_label)
|
^(I_STATEMENT_FORMAT10t INSTRUCTION_FORMAT10t offset_or_label)
|
||||||
{
|
{
|
||||||
@ -702,13 +702,13 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-128, 127].");
|
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-128, 127].");
|
||||||
}
|
}
|
||||||
|
|
||||||
$instruction = Format10t.Format.make(dexFile, opcode.value, (byte)addressOffset);
|
$instruction = new InstructionField(dexFile, new Instruction10t(dexFile, opcode, (byte)addressOffset));
|
||||||
}
|
}
|
||||||
| //e.g. return
|
| //e.g. return
|
||||||
^(I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x)
|
^(I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x)
|
||||||
{
|
{
|
||||||
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT10x.text);
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT10x.text);
|
||||||
$instruction = Format10x.Format.make(dexFile, opcode.value);
|
$instruction = new InstructionField(dexFile, new Instruction10x(dexFile, opcode));
|
||||||
}
|
}
|
||||||
| //e.g. const/4 v0, 5
|
| //e.g. const/4 v0, 5
|
||||||
^(I_STATEMENT_FORMAT11n INSTRUCTION_FORMAT11n REGISTER short_integral_literal)
|
^(I_STATEMENT_FORMAT11n INSTRUCTION_FORMAT11n REGISTER short_integral_literal)
|
||||||
@ -719,7 +719,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
short litB = $short_integral_literal.value;
|
short litB = $short_integral_literal.value;
|
||||||
literalTools.checkNibble(litB);
|
literalTools.checkNibble(litB);
|
||||||
|
|
||||||
$instruction = Format11n.Format.make(dexFile, opcode.value, regA, (byte)litB);
|
$instruction = new InstructionField(dexFile, new Instruction11n(dexFile, opcode, regA, (byte)litB));
|
||||||
}
|
}
|
||||||
| //e.g. move-result-object v1
|
| //e.g. move-result-object v1
|
||||||
^(I_STATEMENT_FORMAT11x INSTRUCTION_FORMAT11x REGISTER)
|
^(I_STATEMENT_FORMAT11x INSTRUCTION_FORMAT11x REGISTER)
|
||||||
@ -727,7 +727,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT11x.text);
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT11x.text);
|
||||||
short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters);
|
short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
$instruction = Format11x.Format.make(dexFile, opcode.value, regA);
|
$instruction = new InstructionField(dexFile, new Instruction11x(dexFile, opcode, regA));
|
||||||
}
|
}
|
||||||
| //e.g. move v1 v2
|
| //e.g. move v1 v2
|
||||||
^(I_STATEMENT_FORMAT12x INSTRUCTION_FORMAT12x registerA=REGISTER registerB=REGISTER)
|
^(I_STATEMENT_FORMAT12x INSTRUCTION_FORMAT12x registerA=REGISTER registerB=REGISTER)
|
||||||
@ -736,7 +736,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
$instruction = Format12x.Format.make(dexFile, opcode.value, regA, regB);
|
$instruction = new InstructionField(dexFile, new Instruction12x(dexFile, opcode, regA, regB));
|
||||||
}
|
}
|
||||||
| //e.g. goto/16 endloop:
|
| //e.g. goto/16 endloop:
|
||||||
^(I_STATEMENT_FORMAT20t INSTRUCTION_FORMAT20t offset_or_label)
|
^(I_STATEMENT_FORMAT20t INSTRUCTION_FORMAT20t offset_or_label)
|
||||||
@ -749,7 +749,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767].");
|
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767].");
|
||||||
}
|
}
|
||||||
|
|
||||||
$instruction = Format20t.Format.make(dexFile, opcode.value, (short)addressOffset);
|
$instruction = new InstructionField(dexFile, new Instruction20t(dexFile, opcode, (short)addressOffset));
|
||||||
}
|
}
|
||||||
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
|
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
|
||||||
^(I_STATEMENT_FORMAT21c_FIELD INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field)
|
^(I_STATEMENT_FORMAT21c_FIELD INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field)
|
||||||
@ -759,7 +759,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem;
|
FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem;
|
||||||
|
|
||||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, fieldIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction21c(dexFile, opcode, regA, fieldIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. const-string v1 "Hello World!"
|
| //e.g. const-string v1 "Hello World!"
|
||||||
^(I_STATEMENT_FORMAT21c_STRING INSTRUCTION_FORMAT21c_STRING REGISTER string_literal)
|
^(I_STATEMENT_FORMAT21c_STRING INSTRUCTION_FORMAT21c_STRING REGISTER string_literal)
|
||||||
@ -769,7 +769,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
|
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
|
||||||
|
|
||||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, stringIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction21c(dexFile, opcode, regA, stringIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. const-class v2 org/jf/HelloWorld2/HelloWorld2
|
| //e.g. const-class v2 org/jf/HelloWorld2/HelloWorld2
|
||||||
^(I_STATEMENT_FORMAT21c_TYPE INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor)
|
^(I_STATEMENT_FORMAT21c_TYPE INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor)
|
||||||
@ -779,7 +779,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
TypeIdItem typeIdItem = $reference_type_descriptor.type;
|
TypeIdItem typeIdItem = $reference_type_descriptor.type;
|
||||||
|
|
||||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction21c(dexFile, opcode, regA, typeIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. const/high16 v1, 1234
|
| //e.g. const/high16 v1, 1234
|
||||||
^(I_STATEMENT_FORMAT21h INSTRUCTION_FORMAT21h REGISTER short_integral_literal)
|
^(I_STATEMENT_FORMAT21h INSTRUCTION_FORMAT21h REGISTER short_integral_literal)
|
||||||
@ -789,7 +789,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
short litB = $short_integral_literal.value;
|
short litB = $short_integral_literal.value;
|
||||||
|
|
||||||
$instruction = Format21h.Format.make(dexFile, opcode.value, regA, litB);
|
$instruction = new InstructionField(dexFile, new Instruction21h(dexFile, opcode, regA, litB));
|
||||||
}
|
}
|
||||||
| //e.g. const/16 v1, 1234
|
| //e.g. const/16 v1, 1234
|
||||||
^(I_STATEMENT_FORMAT21s INSTRUCTION_FORMAT21s REGISTER short_integral_literal)
|
^(I_STATEMENT_FORMAT21s INSTRUCTION_FORMAT21s REGISTER short_integral_literal)
|
||||||
@ -799,7 +799,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
short litB = $short_integral_literal.value;
|
short litB = $short_integral_literal.value;
|
||||||
|
|
||||||
$instruction = Format21s.Format.make(dexFile, opcode.value, regA, litB);
|
$instruction = new InstructionField(dexFile, new Instruction21s(dexFile, opcode, regA, litB));
|
||||||
}
|
}
|
||||||
| //e.g. if-eqz v0, endloop:
|
| //e.g. if-eqz v0, endloop:
|
||||||
^(I_STATEMENT_FORMAT21t INSTRUCTION_FORMAT21t REGISTER offset_or_label)
|
^(I_STATEMENT_FORMAT21t INSTRUCTION_FORMAT21t REGISTER offset_or_label)
|
||||||
@ -813,7 +813,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767].");
|
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767].");
|
||||||
}
|
}
|
||||||
|
|
||||||
$instruction = Format21t.Format.make(dexFile, opcode.value, regA, (short)addressOffset);
|
$instruction = new InstructionField(dexFile, new Instruction21t(dexFile, opcode, regA, (short)addressOffset));
|
||||||
}
|
}
|
||||||
| //e.g. add-int v0, v1, 123
|
| //e.g. add-int v0, v1, 123
|
||||||
^(I_STATEMENT_FORMAT22b INSTRUCTION_FORMAT22b registerA=REGISTER registerB=REGISTER short_integral_literal)
|
^(I_STATEMENT_FORMAT22b INSTRUCTION_FORMAT22b registerA=REGISTER registerB=REGISTER short_integral_literal)
|
||||||
@ -825,7 +825,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
short litC = $short_integral_literal.value;
|
short litC = $short_integral_literal.value;
|
||||||
literalTools.checkByte(litC);
|
literalTools.checkByte(litC);
|
||||||
|
|
||||||
$instruction = Format22b.Format.make(dexFile, opcode.value, regA, regB, (byte)litC);
|
$instruction = new InstructionField(dexFile, new Instruction22b(dexFile, opcode, regA, regB, (byte)litC));
|
||||||
}
|
}
|
||||||
| //e.g. iput-object v1 v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
| //e.g. iput-object v1 v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
||||||
^(I_STATEMENT_FORMAT22c_FIELD INSTRUCTION_FORMAT22c_FIELD registerA=REGISTER registerB=REGISTER fully_qualified_field)
|
^(I_STATEMENT_FORMAT22c_FIELD INSTRUCTION_FORMAT22c_FIELD registerA=REGISTER registerB=REGISTER fully_qualified_field)
|
||||||
@ -836,7 +836,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem;
|
FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem;
|
||||||
|
|
||||||
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction22c(dexFile, opcode, regA, regB, fieldIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
||||||
^(I_STATEMENT_FORMAT22c_TYPE INSTRUCTION_FORMAT22c_TYPE registerA=REGISTER registerB=REGISTER nonvoid_type_descriptor)
|
^(I_STATEMENT_FORMAT22c_TYPE INSTRUCTION_FORMAT22c_TYPE registerA=REGISTER registerB=REGISTER nonvoid_type_descriptor)
|
||||||
@ -847,7 +847,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, typeIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction22c(dexFile, opcode, regA, regB, typeIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. add-int/lit16 v0, v1, 12345
|
| //e.g. add-int/lit16 v0, v1, 12345
|
||||||
^(I_STATEMENT_FORMAT22s INSTRUCTION_FORMAT22s registerA=REGISTER registerB=REGISTER short_integral_literal)
|
^(I_STATEMENT_FORMAT22s INSTRUCTION_FORMAT22s registerA=REGISTER registerB=REGISTER short_integral_literal)
|
||||||
@ -858,7 +858,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
short litC = $short_integral_literal.value;
|
short litC = $short_integral_literal.value;
|
||||||
|
|
||||||
$instruction = Format22s.Format.make(dexFile, opcode.value, regA, regB, litC);
|
$instruction = new InstructionField(dexFile, new Instruction22s(dexFile, opcode, regA, regB, litC));
|
||||||
}
|
}
|
||||||
| //e.g. if-eq v0, v1, endloop:
|
| //e.g. if-eq v0, v1, endloop:
|
||||||
^(I_STATEMENT_FORMAT22t INSTRUCTION_FORMAT22t registerA=REGISTER registerB=REGISTER offset_or_label)
|
^(I_STATEMENT_FORMAT22t INSTRUCTION_FORMAT22t registerA=REGISTER registerB=REGISTER offset_or_label)
|
||||||
@ -873,7 +873,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767].");
|
throw new SemanticException(input, "The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767].");
|
||||||
}
|
}
|
||||||
|
|
||||||
$instruction = Format22t.Format.make(dexFile, opcode.value, regA, regB, (short)addressOffset);
|
$instruction = new InstructionField(dexFile, new Instruction22t(dexFile, opcode, regA, regB, (short)addressOffset));
|
||||||
}
|
}
|
||||||
| //e.g. move/from16 v1, v1234
|
| //e.g. move/from16 v1, v1234
|
||||||
^(I_STATEMENT_FORMAT22x INSTRUCTION_FORMAT22x registerA=REGISTER registerB=REGISTER)
|
^(I_STATEMENT_FORMAT22x INSTRUCTION_FORMAT22x registerA=REGISTER registerB=REGISTER)
|
||||||
@ -882,7 +882,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
short regA = parseRegister_byte($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
short regA = parseRegister_byte($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
$instruction = Format22x.Format.make(dexFile, opcode.value, regA, regB);
|
$instruction = new InstructionField(dexFile, new Instruction22x(dexFile, opcode, regA, regB));
|
||||||
}
|
}
|
||||||
| //e.g. add-int v1, v2, v3
|
| //e.g. add-int v1, v2, v3
|
||||||
^(I_STATEMENT_FORMAT23x INSTRUCTION_FORMAT23x registerA=REGISTER registerB=REGISTER registerC=REGISTER)
|
^(I_STATEMENT_FORMAT23x INSTRUCTION_FORMAT23x registerA=REGISTER registerB=REGISTER registerC=REGISTER)
|
||||||
@ -892,7 +892,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
short regB = parseRegister_byte($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
short regB = parseRegister_byte($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
short regC = parseRegister_byte($registerC.text, $totalMethodRegisters, $methodParameterRegisters);
|
short regC = parseRegister_byte($registerC.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
$instruction = Format23x.Format.make(dexFile, opcode.value, regA, regB, regC);
|
$instruction = new InstructionField(dexFile, new Instruction23x(dexFile, opcode, regA, regB, regC));
|
||||||
}
|
}
|
||||||
| //e.g. goto/32 endloop:
|
| //e.g. goto/32 endloop:
|
||||||
^(I_STATEMENT_FORMAT30t INSTRUCTION_FORMAT30t offset_or_label)
|
^(I_STATEMENT_FORMAT30t INSTRUCTION_FORMAT30t offset_or_label)
|
||||||
@ -901,7 +901,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
int addressOffset = $offset_or_label.offsetValue;
|
int addressOffset = $offset_or_label.offsetValue;
|
||||||
|
|
||||||
$instruction = Format30t.Format.make(dexFile, opcode.value, addressOffset);
|
$instruction = new InstructionField(dexFile, new Instruction30t(dexFile, opcode, addressOffset));
|
||||||
}
|
}
|
||||||
| //e.g. const-string/jumbo v1 "Hello World!"
|
| //e.g. const-string/jumbo v1 "Hello World!"
|
||||||
^(I_STATEMENT_FORMAT31c INSTRUCTION_FORMAT31c REGISTER string_literal)
|
^(I_STATEMENT_FORMAT31c INSTRUCTION_FORMAT31c REGISTER string_literal)
|
||||||
@ -911,7 +911,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
|
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
|
||||||
|
|
||||||
$instruction = Format31c.Format.make(dexFile, opcode.value, regA, stringIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction31c(dexFile, opcode, regA, stringIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. const v0, 123456
|
| //e.g. const v0, 123456
|
||||||
^(I_STATEMENT_FORMAT31i INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal)
|
^(I_STATEMENT_FORMAT31i INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal)
|
||||||
@ -921,7 +921,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
int litB = $fixed_32bit_literal.value;
|
int litB = $fixed_32bit_literal.value;
|
||||||
|
|
||||||
$instruction = Format31i.Format.make(dexFile, opcode.value, regA, litB);
|
$instruction = new InstructionField(dexFile, new Instruction31i(dexFile, opcode, regA, litB));
|
||||||
}
|
}
|
||||||
| //e.g. fill-array-data v0, ArrayData:
|
| //e.g. fill-array-data v0, ArrayData:
|
||||||
^(I_STATEMENT_FORMAT31t INSTRUCTION_FORMAT31t REGISTER offset_or_label)
|
^(I_STATEMENT_FORMAT31t INSTRUCTION_FORMAT31t REGISTER offset_or_label)
|
||||||
@ -935,7 +935,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
addressOffset++;
|
addressOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$instruction = Format31t.Format.make(dexFile, opcode.value, regA, addressOffset);
|
$instruction = new InstructionField(dexFile, new Instruction31t(dexFile, opcode, regA, addressOffset));
|
||||||
}
|
}
|
||||||
| //e.g. move/16 v5678, v1234
|
| //e.g. move/16 v5678, v1234
|
||||||
^(I_STATEMENT_FORMAT32x INSTRUCTION_FORMAT32x registerA=REGISTER registerB=REGISTER)
|
^(I_STATEMENT_FORMAT32x INSTRUCTION_FORMAT32x registerA=REGISTER registerB=REGISTER)
|
||||||
@ -944,7 +944,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
int regA = parseRegister_short($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
int regA = parseRegister_short($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
|
||||||
|
|
||||||
$instruction = Format32x.Format.make(dexFile, opcode.value, regA, regB);
|
$instruction = new InstructionField(dexFile, new Instruction32x(dexFile, opcode, regA, regB));
|
||||||
}
|
}
|
||||||
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
||||||
^(I_STATEMENT_FORMAT35c_METHOD INSTRUCTION_FORMAT35c_METHOD register_list[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method)
|
^(I_STATEMENT_FORMAT35c_METHOD INSTRUCTION_FORMAT35c_METHOD register_list[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method)
|
||||||
@ -957,7 +957,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
MethodIdItem methodIdItem = $fully_qualified_method.methodIdItem;
|
MethodIdItem methodIdItem = $fully_qualified_method.methodIdItem;
|
||||||
|
|
||||||
$instruction = Format35c.Format.make(dexFile, opcode.value, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], methodIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction35c(dexFile, opcode, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], methodIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. filled-new-array {v0,v1}, I
|
| //e.g. filled-new-array {v0,v1}, I
|
||||||
^(I_STATEMENT_FORMAT35c_TYPE INSTRUCTION_FORMAT35c_TYPE register_list[$totalMethodRegisters, $methodParameterRegisters] nonvoid_type_descriptor)
|
^(I_STATEMENT_FORMAT35c_TYPE INSTRUCTION_FORMAT35c_TYPE register_list[$totalMethodRegisters, $methodParameterRegisters] nonvoid_type_descriptor)
|
||||||
@ -970,7 +970,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
$instruction = Format35c.Format.make(dexFile, opcode.value, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], typeIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction35c(dexFile, opcode, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], typeIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
^(I_STATEMENT_FORMAT3rc_METHOD INSTRUCTION_FORMAT3rc_METHOD register_range[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method)
|
^(I_STATEMENT_FORMAT3rc_METHOD INSTRUCTION_FORMAT3rc_METHOD register_range[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method)
|
||||||
@ -990,7 +990,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
MethodIdItem methodIdItem = $fully_qualified_method.methodIdItem;
|
MethodIdItem methodIdItem = $fully_qualified_method.methodIdItem;
|
||||||
|
|
||||||
//not supported yet
|
//not supported yet
|
||||||
$instruction = Format3rc.Format.make(dexFile, opcode.value, (short)registerCount, startRegister, methodIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction3rc(dexFile, opcode, (short)registerCount, startRegister, methodIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. filled-new-array/range {v0..v6} I
|
| //e.g. filled-new-array/range {v0..v6} I
|
||||||
^(I_STATEMENT_FORMAT3rc_TYPE INSTRUCTION_FORMAT3rc_TYPE register_range[$totalMethodRegisters, $methodParameterRegisters] nonvoid_type_descriptor)
|
^(I_STATEMENT_FORMAT3rc_TYPE INSTRUCTION_FORMAT3rc_TYPE register_range[$totalMethodRegisters, $methodParameterRegisters] nonvoid_type_descriptor)
|
||||||
@ -1010,7 +1010,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
//not supported yet
|
//not supported yet
|
||||||
$instruction = Format3rc.Format.make(dexFile, opcode.value, (short)registerCount, startRegister, typeIdItem);
|
$instruction = new InstructionField(dexFile, new Instruction3rc(dexFile, opcode, (short)registerCount, startRegister, typeIdItem));
|
||||||
}
|
}
|
||||||
| //e.g. const-wide v0, 5000000000L
|
| //e.g. const-wide v0, 5000000000L
|
||||||
^(I_STATEMENT_FORMAT51l INSTRUCTION_FORMAT51l REGISTER fixed_64bit_literal)
|
^(I_STATEMENT_FORMAT51l INSTRUCTION_FORMAT51l REGISTER fixed_64bit_literal)
|
||||||
@ -1020,7 +1020,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
|
|
||||||
long litB = $fixed_64bit_literal.value;
|
long litB = $fixed_64bit_literal.value;
|
||||||
|
|
||||||
$instruction = Format51l.Format.make(dexFile, opcode.value, regA, litB);
|
$instruction = new InstructionField(dexFile, new Instruction51l(dexFile, opcode, regA, litB));
|
||||||
}
|
}
|
||||||
| //e.g. .array-data 4 1000000 .end array-data
|
| //e.g. .array-data 4 1000000 .end array-data
|
||||||
^(I_STATEMENT_ARRAY_DATA ^(I_ARRAY_ELEMENT_SIZE short_integral_literal) array_elements)
|
^(I_STATEMENT_ARRAY_DATA ^(I_ARRAY_ELEMENT_SIZE short_integral_literal) array_elements)
|
||||||
@ -1028,7 +1028,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
int elementWidth = $short_integral_literal.value;
|
int elementWidth = $short_integral_literal.value;
|
||||||
List<byte[]> byteValues = $array_elements.values;
|
List<byte[]> byteValues = $array_elements.values;
|
||||||
|
|
||||||
$instruction = ArrayData.make(dexFile, elementWidth, byteValues);
|
$instruction = new InstructionField(dexFile, new ArrayDataPseudoInstruction(dexFile, elementWidth, byteValues));
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
|
|
||||||
@ -1037,7 +1037,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
int startKey = $fixed_32bit_literal.value;
|
int startKey = $fixed_32bit_literal.value;
|
||||||
int[] targets = $packed_switch_targets.targets;
|
int[] targets = $packed_switch_targets.targets;
|
||||||
|
|
||||||
$instruction = PackedSwitchData.make(dexFile, startKey, targets);
|
$instruction = new InstructionField(dexFile, new PackedSwitchDataPseudoInstruction(dexFile, startKey, targets));
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
^(I_STATEMENT_SPARSE_SWITCH ^(I_SPARSE_SWITCH_BASE_OFFSET base_offset=offset_or_label) sparse_switch_target_count sparse_switch_keys[$sparse_switch_target_count.targetCount] sparse_switch_targets[$base_offset.offsetValue, $sparse_switch_target_count.targetCount])
|
^(I_STATEMENT_SPARSE_SWITCH ^(I_SPARSE_SWITCH_BASE_OFFSET base_offset=offset_or_label) sparse_switch_target_count sparse_switch_keys[$sparse_switch_target_count.targetCount] sparse_switch_targets[$base_offset.offsetValue, $sparse_switch_target_count.targetCount])
|
||||||
@ -1045,7 +1045,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
|
|||||||
int[] keys = $sparse_switch_keys.keys;
|
int[] keys = $sparse_switch_keys.keys;
|
||||||
int[] targets = $sparse_switch_targets.targets;
|
int[] targets = $sparse_switch_targets.targets;
|
||||||
|
|
||||||
$instruction = SparseSwitchData.make(dexFile, keys, targets);
|
$instruction = new InstructionField(dexFile, new SparseSwitchDataPseudoInstruction(dexFile, keys, targets));
|
||||||
};
|
};
|
||||||
catch [Exception ex] {
|
catch [Exception ex] {
|
||||||
reportError(new SemanticException(input, ex));
|
reportError(new SemanticException(input, ex));
|
||||||
|
@ -30,6 +30,7 @@ package org.jf.dexlib;
|
|||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.code.InstructionField;
|
||||||
import org.jf.dexlib.ItemType;
|
import org.jf.dexlib.ItemType;
|
||||||
import org.jf.dexlib.util.Input;
|
import org.jf.dexlib.util.Input;
|
||||||
import org.jf.dexlib.util.AnnotatedOutput;
|
import org.jf.dexlib.util.AnnotatedOutput;
|
||||||
@ -39,7 +40,7 @@ import java.util.List;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class CodeItem extends OffsettedItem<CodeItem> {
|
public class CodeItem extends OffsettedItem<CodeItem> {
|
||||||
private final ArrayList<Instruction> instructionList;
|
private final ArrayList<InstructionField> instructionList;
|
||||||
private final ArrayList<TryItem> tryItems = new ArrayList<TryItem>();
|
private final ArrayList<TryItem> tryItems = new ArrayList<TryItem>();
|
||||||
private final ArrayList<EncodedCatchHandler> catchHandlerList = new ArrayList<EncodedCatchHandler>();
|
private final ArrayList<EncodedCatchHandler> catchHandlerList = new ArrayList<EncodedCatchHandler>();
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
public CodeItem(final DexFile dexFile, int offset) {
|
public CodeItem(final DexFile dexFile, int offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
|
|
||||||
instructionList = new ArrayList<Instruction>();
|
instructionList = new ArrayList<InstructionField>();
|
||||||
|
|
||||||
fields = new Field[] {
|
fields = new Field[] {
|
||||||
registersCountField = new ShortIntegerField("registers_size"),
|
registersCountField = new ShortIntegerField("registers_size"),
|
||||||
@ -82,7 +83,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
public CodeItem(final DexFile dexFile,
|
public CodeItem(final DexFile dexFile,
|
||||||
int registersCount,
|
int registersCount,
|
||||||
int inArguments,
|
int inArguments,
|
||||||
List<Instruction> instructions,
|
List<InstructionField> instructions,
|
||||||
DebugInfoItem debugInfo,
|
DebugInfoItem debugInfo,
|
||||||
List<TryItem> tries,
|
List<TryItem> tries,
|
||||||
List<EncodedCatchHandler> handlers) {
|
List<EncodedCatchHandler> handlers) {
|
||||||
@ -447,7 +448,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
|
|
||||||
public void writeTo(AnnotatedOutput out) {
|
public void writeTo(AnnotatedOutput out) {
|
||||||
int startPosition = out.getCursor();
|
int startPosition = out.getCursor();
|
||||||
for (Instruction instruction: instructionList) {
|
for (InstructionField instruction: instructionList) {
|
||||||
instruction.writeTo(out);
|
instruction.writeTo(out);
|
||||||
}
|
}
|
||||||
if ((out.getCursor() - startPosition) != (instructionsSizeField.getCachedValue() * 2)) {
|
if ((out.getCursor() - startPosition) != (instructionsSizeField.getCachedValue() * 2)) {
|
||||||
@ -460,7 +461,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
int startPosition = in.getCursor();
|
int startPosition = in.getCursor();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
Instruction instruction = new Instruction(dexFile);
|
InstructionField instruction = new InstructionField(dexFile);
|
||||||
instruction.readFrom(in);
|
instruction.readFrom(in);
|
||||||
instructionList.add(instruction);
|
instructionList.add(instruction);
|
||||||
} while (in.getCursor() - startPosition < numBytes);
|
} while (in.getCursor() - startPosition < numBytes);
|
||||||
@ -475,23 +476,23 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void copyTo(DexFile dexFile, InstructionListField copy) {
|
public void copyTo(DexFile dexFile, InstructionListField copy) {
|
||||||
ArrayList<Instruction> copyInstructionList = copy.getInstructionList();
|
ArrayList<InstructionField> copyInstructionList = copy.getInstructionList();
|
||||||
copyInstructionList.clear();
|
copyInstructionList.clear();
|
||||||
for (Instruction instruction: instructionList) {
|
for (InstructionField instruction: instructionList) {
|
||||||
Instruction instructionCopy = new Instruction(dexFile);
|
InstructionField instructionCopy = new InstructionField(dexFile);
|
||||||
instruction.copyTo(dexFile, instructionCopy);
|
instruction.copyTo(dexFile, instructionCopy);
|
||||||
copyInstructionList.add(instructionCopy);
|
copyInstructionList.add(instructionCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Instruction> getInstructionList() {
|
private ArrayList<InstructionField> getInstructionList() {
|
||||||
return instructionList;
|
return instructionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return the word size of the instruction list
|
//return the word size of the instruction list
|
||||||
public int getInstructionWordCount() {
|
public int getInstructionWordCount() {
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
for (Instruction instruction: instructionList) {
|
for (InstructionField instruction: instructionList) {
|
||||||
bytes += instruction.getSize(bytes);
|
bytes += instruction.getSize(bytes);
|
||||||
}
|
}
|
||||||
return bytes/2;
|
return bytes/2;
|
||||||
@ -500,11 +501,11 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
//return the highest parameter word count of any method invokation
|
//return the highest parameter word count of any method invokation
|
||||||
public int getOutArguments() {
|
public int getOutArguments() {
|
||||||
int maxParamWordCount = 0;
|
int maxParamWordCount = 0;
|
||||||
for (Instruction instruction: instructionList) {
|
for (InstructionField instruction: instructionList) {
|
||||||
IndexedItem item = instruction.getReference();
|
IndexedItem item = instruction.getInstruction().getReferencedItem();
|
||||||
if (item instanceof MethodIdItem) {
|
if (item instanceof MethodIdItem) {
|
||||||
MethodIdItem methodIdItem = (MethodIdItem)item;
|
MethodIdItem methodIdItem = (MethodIdItem)item;
|
||||||
Opcode opcode = instruction.getOpcode();
|
Opcode opcode = instruction.getInstruction().getOpcode();
|
||||||
|
|
||||||
boolean isStatic = false;
|
boolean isStatic = false;
|
||||||
if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {
|
if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
|
||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ArrayData
|
|
||||||
{
|
|
||||||
public static Instruction make(DexFile dexFile, int elementWidth, List<byte[]> values) {
|
|
||||||
byte[] bytes;
|
|
||||||
|
|
||||||
int byteCount = 0;
|
|
||||||
|
|
||||||
for (byte[] value: values) {
|
|
||||||
byteCount += value.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (byteCount % elementWidth != 0) {
|
|
||||||
throw new RuntimeException("There are not a whole number of " + ((Integer)elementWidth).toString() + " byte elements");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = new byte[byteCount+8];
|
|
||||||
int position = 8;
|
|
||||||
|
|
||||||
for (byte[] value: values) {
|
|
||||||
for (byte byteValue: value) {
|
|
||||||
bytes[position++] = byteValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//fill-array-data psuedo-opcode
|
|
||||||
bytes[0] = 0x00;
|
|
||||||
bytes[1] = 0x03;
|
|
||||||
|
|
||||||
bytes[2] = (byte)elementWidth;
|
|
||||||
bytes[3] = (byte)(elementWidth >> 8);
|
|
||||||
|
|
||||||
int elementCount = byteCount / elementWidth;
|
|
||||||
|
|
||||||
bytes[4] = (byte)elementCount;
|
|
||||||
bytes[5] = (byte)(elementCount >> 8);
|
|
||||||
bytes[6] = (byte)(elementCount >> 16);
|
|
||||||
bytes[7] = (byte)(elementCount >> 24);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.Input;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class ArrayDataPseudoInstruction extends Instruction
|
||||||
|
{
|
||||||
|
public ArrayDataPseudoInstruction(DexFile dexFile, int elementWidth, List<byte[]> values) {
|
||||||
|
super(dexFile, Opcode.NOP, (IndexedItem)null);
|
||||||
|
|
||||||
|
int byteCount = 0;
|
||||||
|
|
||||||
|
for (byte[] value: values) {
|
||||||
|
byteCount += value.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteCount % elementWidth != 0) {
|
||||||
|
throw new RuntimeException("There are not a whole number of " + ((Integer)elementWidth).toString() + " byte elements");
|
||||||
|
}
|
||||||
|
|
||||||
|
int elementCount = byteCount / elementWidth;
|
||||||
|
|
||||||
|
encodedInstruction = new byte[byteCount+8];
|
||||||
|
encodedInstruction[0] = 0x00;
|
||||||
|
encodedInstruction[1] = 0x03; //fill-array-data psuedo-opcode
|
||||||
|
|
||||||
|
encodedInstruction[2] = (byte)elementWidth;
|
||||||
|
encodedInstruction[3] = (byte)(elementWidth >> 8);
|
||||||
|
|
||||||
|
encodedInstruction[4] = (byte)elementCount;
|
||||||
|
encodedInstruction[5] = (byte)(elementCount >> 8);
|
||||||
|
encodedInstruction[6] = (byte)(elementCount >> 16);
|
||||||
|
encodedInstruction[7] = (byte)(elementCount >> 24);
|
||||||
|
|
||||||
|
int position = 8;
|
||||||
|
|
||||||
|
for (byte[] value: values) {
|
||||||
|
for (byte byteValue: value) {
|
||||||
|
encodedInstruction[position++] = byteValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayDataPseudoInstruction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkFormat(Format format) {
|
||||||
|
//no need to check the format
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayDataPseudoInstruction make(DexFile dexFile, Input input) {
|
||||||
|
byte opcodeByte = input.readByte();
|
||||||
|
if (opcodeByte != 0x00) {
|
||||||
|
throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction");
|
||||||
|
}
|
||||||
|
byte subopcodeByte = input.readByte();
|
||||||
|
if (subopcodeByte != 0x02) {
|
||||||
|
throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
int elementWidth = input.readShort();
|
||||||
|
int size = input.readInt();
|
||||||
|
|
||||||
|
List<byte[]> elementsList = new ArrayList<byte[]>();
|
||||||
|
|
||||||
|
for (int i=0; i<size; i++) {
|
||||||
|
elementsList.add(input.readBytes(elementWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayDataPseudoInstruction(dexFile, elementWidth, elementsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.ArrayData;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new ArrayDataPseudoInstruction();
|
||||||
|
}
|
||||||
|
}
|
@ -28,16 +28,43 @@
|
|||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
|
||||||
public abstract class Format
|
public enum Format
|
||||||
{
|
{
|
||||||
public abstract int getByteCount();
|
Format10t(Instruction10t.Factory, 2),
|
||||||
public abstract String getFormatName();
|
Format10x(Instruction10x.Factory, 2),
|
||||||
|
Format11n(Instruction11n.Factory, 2),
|
||||||
|
Format11x(Instruction11x.Factory, 2),
|
||||||
|
Format12x(Instruction12x.Factory, 2),
|
||||||
|
Format20t(Instruction20t.Factory, 4),
|
||||||
|
Format21c(Instruction21c.Factory, 4),
|
||||||
|
Format21h(Instruction21h.Factory, 4),
|
||||||
|
Format21s(Instruction21s.Factory, 4),
|
||||||
|
Format21t(Instruction21t.Factory, 4),
|
||||||
|
Format22b(Instruction22b.Factory, 4),
|
||||||
|
Format22c(Instruction22c.Factory, 4),
|
||||||
|
Format22s(Instruction22s.Factory, 4),
|
||||||
|
Format22t(Instruction22t.Factory, 4),
|
||||||
|
Format22x(Instruction22x.Factory, 4),
|
||||||
|
Format23x(Instruction23x.Factory, 4),
|
||||||
|
Format30t(Instruction30t.Factory, 6),
|
||||||
|
Format31c(Instruction31c.Factory, 6),
|
||||||
|
Format31i(Instruction31i.Factory, 6),
|
||||||
|
Format31t(Instruction31t.Factory, 6),
|
||||||
|
Format32x(Instruction32x.Factory, 6),
|
||||||
|
Format35c(Instruction35c.Factory, 6),
|
||||||
|
Format3rc(Instruction3rc.Factory, 6),
|
||||||
|
Format51l(Instruction51l.Factory, 10),
|
||||||
|
ArrayData(null, -1),
|
||||||
|
PackedSwitchData(null, -1),
|
||||||
|
SparseSwitchData(null, -1);
|
||||||
|
|
||||||
protected void checkOpcodeFormat(Opcode opcode) {
|
public final Instruction.InstructionFactory Factory;
|
||||||
if (!opcode.format.equals(getFormatName())) {
|
public final int size;
|
||||||
throw new RuntimeException("Opcode " + opcode.name + " does not use format " + getFormatName());
|
|
||||||
}
|
private Format(Instruction.InstructionFactory factory, int size) {
|
||||||
|
this.Factory = factory;
|
||||||
|
this.size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
|
||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
|
||||||
import org.jf.dexlib.code.Opcode;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
|
|
||||||
public class Format10x extends Format
|
|
||||||
{
|
|
||||||
public static final Format10x Format = new Format10x();
|
|
||||||
|
|
||||||
private Format10x() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode) {
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, new byte[]{opcode,0x00}, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getByteCount()
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName()
|
|
||||||
{
|
|
||||||
return "10x";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
|
||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
|
||||||
import org.jf.dexlib.code.Opcode;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
|
|
||||||
public class Format30t extends Format
|
|
||||||
{
|
|
||||||
public static final Format30t Format = new Format30t();
|
|
||||||
|
|
||||||
private Format30t() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, int offA) {
|
|
||||||
byte[] bytes = new byte[6];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
bytes[2] = (byte)offA;
|
|
||||||
bytes[3] = (byte)(offA >> 8);
|
|
||||||
bytes[4] = (byte)(offA >> 16);
|
|
||||||
bytes[5] = (byte)(offA >> 24);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getByteCount()
|
|
||||||
{
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName()
|
|
||||||
{
|
|
||||||
return "30t";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
|
||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
|
||||||
import org.jf.dexlib.code.Opcode;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
|
|
||||||
public class Format31t extends Format
|
|
||||||
{
|
|
||||||
public static final Format31t Format = new Format31t();
|
|
||||||
|
|
||||||
private Format31t() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, int offB) {
|
|
||||||
byte[] bytes = new byte[6];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
bytes[1] = (byte)regA;
|
|
||||||
|
|
||||||
bytes[2] = (byte)offB;
|
|
||||||
bytes[3] = (byte)(offB >> 8);
|
|
||||||
|
|
||||||
bytes[4] = (byte)(offB >> 16);
|
|
||||||
bytes[5] = (byte)(offB >> 24);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getByteCount() {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName() {
|
|
||||||
return "31t";
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,33 +31,51 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
|
||||||
public class Format10t extends Format
|
public class Instruction10t extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format10t Format = new Format10t();
|
public static final InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format10t() {
|
public Instruction10t(DexFile dexFile, Opcode opcode, byte offA) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte offA) {
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (offA == 0) {
|
if (offA == 0) {
|
||||||
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
|
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Instruction(dexFile, new byte[]{opcode,offA}, null);
|
encodedInstruction = new byte[2];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = offA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction10t(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 2;
|
|
||||||
|
if (getOffset() == 0) {
|
||||||
|
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction10t() {
|
||||||
{
|
}
|
||||||
return "10t";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format10t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction10t();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction10t(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getOffset() {
|
||||||
|
return encodedInstruction[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,41 +32,40 @@ import org.jf.dexlib.code.Instruction;
|
|||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
import org.jf.dexlib.IndexedItem;
|
import org.jf.dexlib.IndexedItem;
|
||||||
import org.jf.dexlib.TypeIdItem;
|
|
||||||
|
|
||||||
public class Format21c extends Format
|
public class Instruction10x extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format21c Format = new Format21c();
|
public static final InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
|
public Instruction10x(DexFile dexFile, Opcode opcode) {
|
||||||
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
|
encodedInstruction = new byte[2];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction10x(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
|
||||||
|
if (rest[0] != 0x00) {
|
||||||
|
throw new RuntimeException("The second byte of the instruction must be 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction10x() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format10x;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction10x();
|
||||||
|
}
|
||||||
|
|
||||||
private Format21c() {
|
private static class Factory implements InstructionFactory {
|
||||||
}
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction10x(dexFile, opcode, rest);
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, IndexedItem item) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == Opcode.NEW_INSTANCE.value && ((TypeIdItem)item).getTypeDescriptor().charAt(0) != 'L') {
|
|
||||||
throw new RuntimeException("Only class references can be used with the new-instance opcode");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
bytes[1] = (byte)regA;
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, item);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public int getByteCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName() {
|
|
||||||
return "21c";
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,21 +31,15 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format11n extends Format
|
public class Instruction11n extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format11n Format = new Format11n();
|
public static final InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format11n() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte regA, byte litB) {
|
|
||||||
byte[] bytes = new byte[2];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
|
public Instruction11n(DexFile dexFile, Opcode opcode, byte regA, byte litB) {
|
||||||
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
if (regA >= 1<<4) {
|
if (regA >= 1<<4) {
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
throw new RuntimeException("The register number must be less than v16");
|
||||||
@ -55,21 +49,39 @@ public class Format11n extends Format
|
|||||||
litB >= 1<<3) {
|
litB >= 1<<3) {
|
||||||
throw new RuntimeException("The literal value must be between -8 and 7 inclusive");
|
throw new RuntimeException("The literal value must be between -8 and 7 inclusive");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[2];
|
||||||
bytes[1] = (byte)((litB << 4) | regA);
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)((litB << 4) | regA);
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction11n(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction11n() {
|
||||||
{
|
|
||||||
return "11n";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format11n;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction11n();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction11n(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getRegister() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getLiteral() {
|
||||||
|
return NumberUtils.decodeHighSignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
}
|
@ -32,36 +32,47 @@ import org.jf.dexlib.code.Instruction;
|
|||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
import org.jf.dexlib.IndexedItem;
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format31c extends Format
|
public class Instruction11x extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format31c Format = new Format31c();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format31c() {
|
public Instruction11x(DexFile dexFile, Opcode opcode, short regA) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, IndexedItem item) {
|
|
||||||
byte[] bytes = new byte[6];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[2];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
return new Instruction(dexFile, bytes, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction11x(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 6;
|
super(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction11x() {
|
||||||
return "31c";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format11x;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction11x();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction11x(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,38 +32,52 @@ import org.jf.dexlib.code.Instruction;
|
|||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
import org.jf.dexlib.IndexedItem;
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format22c extends Format
|
public class Instruction12x extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format22c Format = new Format22c();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format22c() {
|
public Instruction12x(DexFile dexFile, Opcode opcode, byte regA, byte regB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB, IndexedItem item) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<4 ||
|
if (regA >= 1<<4 ||
|
||||||
regB >= 1<<4) {
|
regB >= 1<<4) {
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
throw new RuntimeException("The register number must be less than v16");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
encodedInstruction = new byte[2];
|
||||||
bytes[0] = opcode;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[1] = (byte)((regB << 4) | regA);
|
encodedInstruction[1] = (byte)((regB << 4) | regA);
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction12x(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 4;
|
super(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction12x() {
|
||||||
return "22c";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format12x;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction12x();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction12x(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getRegisterA() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterB() {
|
||||||
|
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,39 +31,53 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format20t extends Format
|
public class Instruction20t extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format20t Format = new Format20t();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format20t() {
|
public Instruction20t(DexFile dexFile, Opcode opcode, short offA) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short offA) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (offA == 0) {
|
if (offA == 0) {
|
||||||
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
|
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[2] = (byte)offA;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[3] = (byte)(offA >> 8);
|
encodedInstruction[2] = (byte)offA;
|
||||||
|
encodedInstruction[3] = (byte)(offA>>8);
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction20t(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 4;
|
|
||||||
|
if (getOffset() == 0) {
|
||||||
|
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction20t() {
|
||||||
{
|
}
|
||||||
return "20t";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format20t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction20t();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction20t(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getOffset() {
|
||||||
|
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
88
src/main/java/org/jf/dexlib/code/Format/Instruction21c.java
Normal file
88
src/main/java/org/jf/dexlib/code/Format/Instruction21c.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.TypeIdItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
|
public class Instruction21c extends Instruction
|
||||||
|
{
|
||||||
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
|
public Instruction21c(DexFile dexFile, Opcode opcode, short regA, IndexedItem item) {
|
||||||
|
super(dexFile, opcode, item);
|
||||||
|
|
||||||
|
if (regA >= 1<<8) {
|
||||||
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode == Opcode.NEW_INSTANCE && ((TypeIdItem)item).getTypeDescriptor().charAt(0) != 'L') {
|
||||||
|
throw new RuntimeException("Only class references can be used with the new-instance opcode");
|
||||||
|
}
|
||||||
|
|
||||||
|
encodedInstruction = new byte[4];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
|
//the item index will be set later, during placement/writing
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction21c(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
|
||||||
|
if (opcode == Opcode.NEW_INSTANCE && ((TypeIdItem)this.getReferencedItem()).getTypeDescriptor().charAt(0) != 'L') {
|
||||||
|
throw new RuntimeException("Only class references can be used with the new-instance opcode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction21c() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format21c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction21c();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction21c(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
}
|
@ -31,40 +31,54 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format21h extends Format
|
public class Instruction21h extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format21h Format = new Format21h();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format21h() {
|
public Instruction21h(DexFile dexFile, Opcode opcode, short regA, short litB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, short litB) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[2] = (byte)litB;
|
encodedInstruction[1] = (byte)regA;
|
||||||
bytes[3] = (byte)(litB >> 8);
|
encodedInstruction[2] = (byte)litB;
|
||||||
|
encodedInstruction[3] = (byte)(litB >> 8);
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction21h(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction21h() {
|
||||||
{
|
}
|
||||||
return "21h";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format21h;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction21h();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction21h(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getLiteral() {
|
||||||
|
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,40 +31,54 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format21s extends Format
|
public class Instruction21s extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format21s Format = new Format21s();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format21s() {
|
public Instruction21s(DexFile dexFile, Opcode opcode, short regA, short litB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, short litB) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[2] = (byte)litB;
|
encodedInstruction[1] = (byte)regA;
|
||||||
bytes[3] = (byte)(litB >> 8);
|
encodedInstruction[2] = (byte)litB;
|
||||||
|
encodedInstruction[3] = (byte)(litB >> 8);
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction21s(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction21s() {
|
||||||
{
|
}
|
||||||
return "21s";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format21s;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction21s();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction21s(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getLiteral() {
|
||||||
|
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,44 +31,62 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format21t extends Format
|
public class Instruction21t extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format21t Format = new Format21t();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format21t() {
|
public Instruction21t(DexFile dexFile, Opcode opcode, short regA, short offB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, short offB) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offB == 0) {
|
if (offB == 0) {
|
||||||
throw new RuntimeException("The offset cannot be 0.");
|
throw new RuntimeException("The offset cannot be 0.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[2] = (byte)offB;
|
encodedInstruction[1] = (byte)regA;
|
||||||
bytes[3] = (byte)(offB >> 8);
|
encodedInstruction[2] = (byte)offB;
|
||||||
|
encodedInstruction[3] = (byte)(offB >> 8);
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction21t(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 4;
|
|
||||||
|
if (getOffset() == 0) {
|
||||||
|
throw new RuntimeException("The offset cannot be 0.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction21t() {
|
||||||
{
|
}
|
||||||
return "21t";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format21t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction21t();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction21t(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getOffset() {
|
||||||
|
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
89
src/main/java/org/jf/dexlib/code/Format/Instruction22b.java
Normal file
89
src/main/java/org/jf/dexlib/code/Format/Instruction22b.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
|
public class Instruction22b extends Instruction
|
||||||
|
{
|
||||||
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
|
public Instruction22b(DexFile dexFile, Opcode opcode, short regA, short regB, byte litC) {
|
||||||
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
|
if (regA >= 1<<8 ||
|
||||||
|
regB >= 1<<8) {
|
||||||
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
|
}
|
||||||
|
|
||||||
|
encodedInstruction = new byte[4];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
|
encodedInstruction[2] = (byte)regB;
|
||||||
|
encodedInstruction[3] = litC;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction22b(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction22b() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format22b;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction22b();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction22b(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegisterA() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getRegisterB() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getLiteral() {
|
||||||
|
return encodedInstruction[3];
|
||||||
|
}
|
||||||
|
}
|
@ -31,39 +31,54 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format12x extends Format
|
public class Instruction22c extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format12x Format = new Format12x();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format12x() {
|
public Instruction22c(DexFile dexFile, Opcode opcode, byte regA, byte regB, IndexedItem item) {
|
||||||
}
|
super(dexFile, opcode, item);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB) {
|
|
||||||
byte[] bytes = new byte[2];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<4 ||
|
if (regA >= 1<<4 ||
|
||||||
regB >= 1<<4) {
|
regB >= 1<<4) {
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
throw new RuntimeException("The register number must be less than v16");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[1] = (byte)((regB << 4) | regA);
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)((regB << 4) | regA);
|
||||||
return new Instruction(dexFile, bytes, null);
|
//the item index will be set later, during placement/writing
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction22c(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction22c() {
|
||||||
{
|
}
|
||||||
return "12x";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format22c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction22c();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction22c(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getRegisterA() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterB() {
|
||||||
|
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,44 +31,59 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format22s extends Format
|
public class Instruction22s extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format22s Format = new Format22s();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format22s() {
|
public Instruction22s(DexFile dexFile, Opcode opcode, byte regA, byte regB, short litC) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB, short litC) {
|
if (regA >= 1<<4 ||
|
||||||
byte[] bytes = new byte[4];
|
regB >= 1<<4) {
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<4) {
|
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
throw new RuntimeException("The register number must be less than v16");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regB >= 1<<4) {
|
encodedInstruction = new byte[4];
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)((regB << 4) | regA);
|
||||||
|
encodedInstruction[2] = (byte)litC;
|
||||||
|
encodedInstruction[3] = (byte)(litC >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction22s(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction22s() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format22s;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction22s();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction22s(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
bytes[1] = (byte)((regB << 4) | regA);
|
|
||||||
bytes[2] = (byte)litC;
|
|
||||||
bytes[3] = (byte)(litC >> 8);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
|
||||||
{
|
public byte getRegisterA() {
|
||||||
return 4;
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
public byte getRegisterB() {
|
||||||
{
|
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[1]);
|
||||||
return "22s";
|
}
|
||||||
|
|
||||||
|
public short getLiteral() {
|
||||||
|
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,26 +31,18 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format22t extends Format
|
public class Instruction22t extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format22t Format = new Format22t();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format22t() {
|
public Instruction22t(DexFile dexFile, Opcode opcode, byte regA, byte regB, short offC) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB, short offC) {
|
if (regA >= 1<<4 ||
|
||||||
byte[] bytes = new byte[4];
|
regB >= 1<<4) {
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<4) {
|
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regB >= 1<<4) {
|
|
||||||
throw new RuntimeException("The register number must be less than v16");
|
throw new RuntimeException("The register number must be less than v16");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,19 +50,48 @@ public class Format22t extends Format
|
|||||||
throw new RuntimeException("The offset cannot be 0.");
|
throw new RuntimeException("The offset cannot be 0.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[1] = (byte)((regB << 4) | regA);
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[2] = (byte)offC;
|
encodedInstruction[1] = (byte)((regB << 4) | regA);
|
||||||
bytes[3] = (byte)(offC >> 8);
|
encodedInstruction[2] = (byte)offC;
|
||||||
|
encodedInstruction[3] = (byte)(offC >> 8);
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction22t(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 4;
|
super(dexFile, opcode, rest);
|
||||||
|
|
||||||
|
if (getOffset() == 0) {
|
||||||
|
throw new RuntimeException("The offset cannot be 0.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction22t() {
|
||||||
return "22t";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format22t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction22t();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction22t(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getRegisterA() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterB() {
|
||||||
|
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getOffset() {
|
||||||
|
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,42 +31,58 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format22x extends Format
|
public class Instruction22x extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format22x Format = new Format22x();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format22x() {
|
public Instruction22x(DexFile dexFile, Opcode opcode, short regA, int regB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, int regB) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v16");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regB >= 1<<16) {
|
if (regB >= 1<<16) {
|
||||||
throw new RuntimeException("The register number must be less than v65536");
|
throw new RuntimeException("The register number must be less than v65536");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[4];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[2] = (byte)regB;
|
encodedInstruction[1] = (byte)regA;
|
||||||
bytes[3] = (byte)(regB >> 8);
|
encodedInstruction[2] = (byte)regB;
|
||||||
|
encodedInstruction[3] = (byte)(regB >> 8);
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction22x(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 4;
|
super(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction22x() {
|
||||||
return "22x";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format22x;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction22x();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction22x(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegisterA() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRegisterB() {
|
||||||
|
return NumberUtils.decodeUnsignedShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,46 +31,60 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format23x extends Format
|
public class Instruction23x extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format23x Format = new Format23x();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format23x() {
|
public Instruction23x(DexFile dexFile, Opcode opcode, short regA, short regB, short regC) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, short regB, short regC) {
|
if (regA >= 1<<8 ||
|
||||||
byte[] bytes = new byte[4];
|
regB >= 1<<8 ||
|
||||||
|
regC >= 1<<8) {
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regB >= 1<<8) {
|
encodedInstruction = new byte[4];
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
encodedInstruction[0] = opcode.value;
|
||||||
}
|
encodedInstruction[1] = (byte)regA;
|
||||||
|
encodedInstruction[2] = (byte)regB;
|
||||||
if (regC >= 1<<8) {
|
encodedInstruction[3] = (byte)regC;
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
bytes[1] = (byte)regA;
|
|
||||||
bytes[2] = (byte)regB;
|
|
||||||
bytes[3] = (byte)regC;
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction23x(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 4;
|
super(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction23x() {
|
||||||
return "23x";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format23x;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction23x();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction23x(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegisterA() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getRegisterB() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getRegisterC() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
78
src/main/java/org/jf/dexlib/code/Format/Instruction30t.java
Normal file
78
src/main/java/org/jf/dexlib/code/Format/Instruction30t.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
|
public class Instruction30t extends Instruction
|
||||||
|
{
|
||||||
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
|
public Instruction30t(DexFile dexFile, Opcode opcode, int offA) {
|
||||||
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
|
encodedInstruction = new byte[6];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[2] = (byte)offA;
|
||||||
|
encodedInstruction[3] = (byte)(offA >> 8);
|
||||||
|
encodedInstruction[4] = (byte)(offA >> 16);
|
||||||
|
encodedInstruction[5] = (byte)(offA >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction30t(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction30t() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format30t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction30t();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction30t(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getOffset() {
|
||||||
|
return NumberUtils.decodeInt(encodedInstruction[2], encodedInstruction[3], encodedInstruction[4],
|
||||||
|
encodedInstruction[5]);
|
||||||
|
}
|
||||||
|
}
|
@ -31,42 +31,49 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format22b extends Format
|
public class Instruction31c extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format22b Format = new Format22b();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format22b() {
|
public Instruction31c(DexFile dexFile, Opcode opcode, short regA, IndexedItem item) {
|
||||||
}
|
super(dexFile, opcode, item);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, short regB, byte litC) {
|
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regB >= 1<<8) {
|
encodedInstruction = new byte[6];
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
|
//the item index will be set later, during placement/writing
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction31c(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction31c() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format31c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction31c();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction31c(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
bytes[1] = (byte)regA;
|
|
||||||
bytes[2] = (byte)regB;
|
|
||||||
bytes[3] = litC;
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName() {
|
public short getRegister() {
|
||||||
return "22b";
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,42 +31,57 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format31i extends Format
|
public class Instruction31i extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format31i Format = new Format31i();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format31i() {
|
public Instruction31i(DexFile dexFile, Opcode opcode, short regA, int litB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, int litB) {
|
|
||||||
byte[] bytes = new byte[6];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[6];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
bytes[2] = (byte)litB;
|
encodedInstruction[2] = (byte)litB;
|
||||||
bytes[3] = (byte)(litB >> 8);
|
encodedInstruction[3] = (byte)(litB >> 8);
|
||||||
|
encodedInstruction[4] = (byte)(litB >> 16);
|
||||||
bytes[4] = (byte)(litB >> 16);
|
encodedInstruction[5] = (byte)(litB >> 24);
|
||||||
bytes[5] = (byte)(litB >> 24);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction31i(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 6;
|
super(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction31i() {
|
||||||
return "31i";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format31i;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction31i();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction31i(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLiteral() {
|
||||||
|
return NumberUtils.decodeInt(encodedInstruction[2], encodedInstruction[3], encodedInstruction[4],
|
||||||
|
encodedInstruction[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,33 +31,57 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format11x extends Format
|
public class Instruction31t extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format11x Format = new Format11x();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format11x() {
|
public Instruction31t(DexFile dexFile, Opcode opcode, short regA, int offB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA) {
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Instruction(dexFile, new byte[]{opcode,(byte)regA}, null);
|
encodedInstruction = new byte[6];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
|
encodedInstruction[2] = (byte)offB;
|
||||||
|
encodedInstruction[3] = (byte)(offB >> 8);
|
||||||
|
encodedInstruction[4] = (byte)(offB >> 16);
|
||||||
|
encodedInstruction[5] = (byte)(offB >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount()
|
private Instruction31t(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
{
|
super(dexFile, opcode, rest);
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName()
|
private Instruction31t() {
|
||||||
{
|
}
|
||||||
return "11x";
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format31t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction31t();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction31t(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffset() {
|
||||||
|
return NumberUtils.decodeInt(encodedInstruction[2], encodedInstruction[3], encodedInstruction[4],
|
||||||
|
encodedInstruction[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,45 +31,56 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format32x extends Format
|
public class Instruction32x extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format32x Format = new Format32x();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format32x() {
|
public Instruction32x(DexFile dexFile, Opcode opcode, int regA, int regB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, int regA, int regB) {
|
if (regA >= 1<<16 ||
|
||||||
byte[] bytes = new byte[6];
|
regB >= 1<<16) {
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<16) {
|
|
||||||
throw new RuntimeException("The register number must be less than v65536");
|
throw new RuntimeException("The register number must be less than v65536");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regB >= 1<<16) {
|
encodedInstruction = new byte[6];
|
||||||
throw new RuntimeException("The register number must be less than v65536");
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[2] = (byte)regA;
|
||||||
|
encodedInstruction[3] = (byte)(regA >> 8);
|
||||||
|
encodedInstruction[4] = (byte)regB;
|
||||||
|
encodedInstruction[5] = (byte)(regB >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction32x(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction32x() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format32x;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction32x();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction32x(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
|
||||||
|
|
||||||
bytes[2] = (byte)regA;
|
|
||||||
bytes[3] = (byte)(regA >> 8);
|
|
||||||
|
|
||||||
bytes[4] = (byte)regB;
|
|
||||||
bytes[5] = (byte)(regB >> 8);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
|
||||||
return 6;
|
public int getRegisterA() {
|
||||||
|
return NumberUtils.decodeUnsignedShort(encodedInstruction[2], encodedInstruction[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
public int getRegisterB() {
|
||||||
return "32x";
|
return NumberUtils.decodeUnsignedShort(encodedInstruction[4], encodedInstruction[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,27 +29,23 @@
|
|||||||
package org.jf.dexlib.code.Format;
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
import org.jf.dexlib.*;
|
import org.jf.dexlib.*;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import static org.jf.dexlib.code.Opcode.*;
|
import static org.jf.dexlib.code.Opcode.*;
|
||||||
|
|
||||||
public class Format35c extends Format
|
public class Instruction35c extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format35c Format = new Format35c();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format35c() {
|
public Instruction35c(DexFile dexFile, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG,
|
||||||
}
|
byte regA, IndexedItem item) {
|
||||||
|
super(dexFile, opcode, item);
|
||||||
public Instruction make(DexFile dexFile, byte opcode, byte regCount, byte regD, byte regE, byte regF, byte regG, byte regA, IndexedItem item) {
|
|
||||||
byte[] bytes = new byte[6];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regCount > 5) {
|
if (regCount > 5) {
|
||||||
throw new RuntimeException("regCount cannot be greater than 5");
|
throw new RuntimeException("regCount cannot be greater than 5");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regD >= 1<<4 ||
|
if (regD >= 1<<4 ||
|
||||||
regE >= 1<<4 ||
|
regE >= 1<<4 ||
|
||||||
regF >= 1<<4 ||
|
regF >= 1<<4 ||
|
||||||
@ -58,16 +54,73 @@ public class Format35c extends Format
|
|||||||
throw new RuntimeException("All register args must fit in 4 bits");
|
throw new RuntimeException("All register args must fit in 4 bits");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[6];
|
||||||
bytes[1] = (byte)((regCount << 4) | regA);
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[4] = (byte)((regE << 4) | regD);
|
encodedInstruction[1] = (byte)((regCount << 4) | regA);
|
||||||
bytes[5] = (byte)((regG << 4) | regF);
|
//the item index will be set later, during placement/writing
|
||||||
|
encodedInstruction[4] = (byte)((regE << 4) | regD);
|
||||||
|
encodedInstruction[5] = (byte)((regG << 4) | regF);
|
||||||
|
|
||||||
//go ahead and make the instruction, to verify that item is the correct type. If it isn't,
|
checkItem();
|
||||||
//the construction will throw an exception
|
}
|
||||||
Instruction instruction = new Instruction(dexFile, bytes, item);
|
|
||||||
|
|
||||||
if (opcode == FILLED_NEW_ARRAY.value) {
|
private Instruction35c(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
|
||||||
|
if (getRegCount() > 5) {
|
||||||
|
throw new RuntimeException("regCount cannot be greater than 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
checkItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction35c() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format35c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction35c();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction35c(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getRegisterA() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegCount() {
|
||||||
|
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterD() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterE() {
|
||||||
|
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterF() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getRegisterG() {
|
||||||
|
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkItem() {
|
||||||
|
Opcode opcode = getOpcode();
|
||||||
|
IndexedItem item = getReferencedItem();
|
||||||
|
|
||||||
|
if (opcode == FILLED_NEW_ARRAY) {
|
||||||
//check data for filled-new-array opcode
|
//check data for filled-new-array opcode
|
||||||
String type = ((TypeIdItem)item).getTypeDescriptor();
|
String type = ((TypeIdItem)item).getTypeDescriptor();
|
||||||
if (type.charAt(0) != '[') {
|
if (type.charAt(0) != '[') {
|
||||||
@ -76,39 +129,13 @@ public class Format35c extends Format
|
|||||||
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
||||||
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
||||||
}
|
}
|
||||||
} else if (opcode >= INVOKE_VIRTUAL.value && opcode <= INVOKE_INTERFACE.value) {
|
} else if (opcode.value >= INVOKE_VIRTUAL.value && opcode.value <= INVOKE_INTERFACE.value) {
|
||||||
//check data for invoke-* opcodes
|
//check data for invoke-* opcodes
|
||||||
MethodIdItem methodIdItem = (MethodIdItem)item;
|
MethodIdItem methodIdItem = (MethodIdItem)item;
|
||||||
if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC.value) != regCount) {
|
if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC) != getRegCount()) {
|
||||||
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Opcode " + Integer.toHexString(opcode) + " does not use the 35c format");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return instruction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName() {
|
|
||||||
return "35c";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@Test
|
|
||||||
public void testInvoke() {
|
|
||||||
DexFile dexFile = new DexFile();
|
|
||||||
ArrayList<TypeIdItem> types = new ArrayList<TypeIdItem>();
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
MethodIdItem method = new MethodIdItem(dexFile, new TypeIdItem(dexFile, "test"), "test", new ProtoIdItem(dexFile, new TypeIdItem(dexFile, "V"), types));
|
|
||||||
|
|
||||||
Instruction ins = make(dexFile, (byte)INVOKE_VIRTUAL.value, (byte)5, (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, method);
|
|
||||||
assertTrue("Is everything put in the right place?", java.util.Arrays.equals(ins.getBytes(), new byte[] {0x6e, 0x54, 0x00, 0x00, 0x10, 0x32}));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
@ -29,23 +29,17 @@
|
|||||||
package org.jf.dexlib.code.Format;
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
import org.jf.dexlib.*;
|
import org.jf.dexlib.*;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import static org.jf.dexlib.code.Opcode.*;
|
import static org.jf.dexlib.code.Opcode.*;
|
||||||
|
|
||||||
public class Format3rc extends Format
|
public class Instruction3rc extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format3rc Format = new Format3rc();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
public Format3rc() {
|
public Instruction3rc(DexFile dexFile, Opcode opcode, short regCount, int startReg, IndexedItem item) {
|
||||||
}
|
super(dexFile, opcode, item);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regCount, int startReg, IndexedItem item) {
|
|
||||||
byte[] bytes = new byte[6];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regCount >= 1<<8) {
|
if (regCount >= 1<<8) {
|
||||||
throw new RuntimeException("regCount must be less than 256");
|
throw new RuntimeException("regCount must be less than 256");
|
||||||
@ -61,16 +55,53 @@ public class Format3rc extends Format
|
|||||||
throw new RuntimeException("The beginning register of the range cannot be negative");
|
throw new RuntimeException("The beginning register of the range cannot be negative");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[6];
|
||||||
bytes[1] = (byte)regCount;
|
encodedInstruction[0] = opcode.value;
|
||||||
bytes[4] = (byte)startReg;
|
encodedInstruction[1] = (byte)regCount;
|
||||||
bytes[5] = (byte)(startReg >> 8);
|
//the item index will be set later, during placement/writing
|
||||||
|
encodedInstruction[4] = (byte)startReg;
|
||||||
|
encodedInstruction[5] = (byte)(startReg >> 8);
|
||||||
|
|
||||||
//go ahead and make the instruction now, which will verify that item is the correct type. If it isn't,
|
checkItem();
|
||||||
//the construction will throw an exception
|
}
|
||||||
Instruction instruction = new Instruction(dexFile, bytes, item);
|
|
||||||
|
|
||||||
if (opcode == FILLED_NEW_ARRAY_RANGE.value) {
|
private Instruction3rc(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
super(dexFile, opcode, rest);
|
||||||
|
|
||||||
|
checkItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction3rc() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format3rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction3rc();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction3rc(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegCount() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStartRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedShort(encodedInstruction[4], encodedInstruction[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkItem() {
|
||||||
|
Opcode opcode = getOpcode();
|
||||||
|
IndexedItem item = getReferencedItem();
|
||||||
|
|
||||||
|
if (opcode == FILLED_NEW_ARRAY_RANGE) {
|
||||||
//check data for filled-new-array/range opcode
|
//check data for filled-new-array/range opcode
|
||||||
String type = ((TypeIdItem)item).getTypeDescriptor();
|
String type = ((TypeIdItem)item).getTypeDescriptor();
|
||||||
if (type.charAt(0) != '[') {
|
if (type.charAt(0) != '[') {
|
||||||
@ -79,40 +110,12 @@ public class Format3rc extends Format
|
|||||||
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
||||||
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
||||||
}
|
}
|
||||||
} else if (opcode >= INVOKE_VIRTUAL_RANGE.value && opcode <= INVOKE_INTERFACE_RANGE.value) {
|
} else if (opcode.value >= INVOKE_VIRTUAL_RANGE.value && opcode.value <= INVOKE_INTERFACE_RANGE.value) {
|
||||||
//check data for invoke-*/range opcodes
|
//check data for invoke-*/range opcodes
|
||||||
MethodIdItem methodIdItem = (MethodIdItem)item;
|
MethodIdItem methodIdItem = (MethodIdItem)item;
|
||||||
if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC_RANGE.value) != regCount) {
|
if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC_RANGE) != getRegCount()) {
|
||||||
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Opcode " + Integer.toHexString(opcode) + " does not use the 35c format");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return instruction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatName() {
|
|
||||||
return "3rc";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@Test
|
|
||||||
public void testInvoke() {
|
|
||||||
DexFile dexFile = DexFile.makeBlankDexFile();
|
|
||||||
ArrayList<TypeIdItem> types = new ArrayList<TypeIdItem>();
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
types.add(new TypeIdItem(dexFile, "I"));
|
|
||||||
MethodIdItem method = new MethodIdItem(dexFile, new TypeIdItem(dexFile, "test"), "test", new ProtoIdItem(dexFile, new TypeIdItem(dexFile, "V"), types));
|
|
||||||
|
|
||||||
Instruction ins = Format.make(dexFile, (byte)INVOKE_VIRTUAL_RANGE.value, (short)6, 65500, method);
|
|
||||||
byte[] bytes = new byte[] {0x74, 0x06, 0x00, 0x00, (byte)0xDC, (byte)0xFF};
|
|
||||||
assertTrue("Is everything put in the right place?", java.util.Arrays.equals(ins.getBytes(), bytes));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
@ -31,48 +31,60 @@ package org.jf.dexlib.code.Format;
|
|||||||
import org.jf.dexlib.code.Instruction;
|
import org.jf.dexlib.code.Instruction;
|
||||||
import org.jf.dexlib.code.Opcode;
|
import org.jf.dexlib.code.Opcode;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.NumberUtils;
|
||||||
|
|
||||||
public class Format51l extends Format
|
public class Instruction51l extends Instruction
|
||||||
{
|
{
|
||||||
public static final Format51l Format = new Format51l();
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
private Format51l() {
|
public Instruction51l(DexFile dexFile, Opcode opcode, short regA, long litB) {
|
||||||
}
|
super(dexFile, opcode, (IndexedItem)null);
|
||||||
|
|
||||||
public Instruction make(DexFile dexFile, byte opcode, short regA, long litB) {
|
|
||||||
byte[] bytes = new byte[10];
|
|
||||||
|
|
||||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
|
||||||
|
|
||||||
checkOpcodeFormat(op);
|
|
||||||
|
|
||||||
if (regA >= 1<<8) {
|
if (regA >= 1<<8) {
|
||||||
throw new RuntimeException("The register number must be less than v256");
|
throw new RuntimeException("The register number must be less than v256");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes[0] = opcode;
|
encodedInstruction = new byte[10];
|
||||||
bytes[1] = (byte)regA;
|
encodedInstruction[0] = opcode.value;
|
||||||
|
encodedInstruction[1] = (byte)regA;
|
||||||
bytes[2] = (byte)litB;
|
encodedInstruction[2] = (byte)litB;
|
||||||
bytes[3] = (byte)(litB >> 8);
|
encodedInstruction[3] = (byte)(litB >> 8);
|
||||||
|
encodedInstruction[4] = (byte)(litB >> 16);
|
||||||
bytes[4] = (byte)(litB >> 16);
|
encodedInstruction[5] = (byte)(litB >> 24);
|
||||||
bytes[5] = (byte)(litB >> 24);
|
encodedInstruction[6] = (byte)(litB >> 32);
|
||||||
|
encodedInstruction[7] = (byte)(litB >> 40);
|
||||||
bytes[6] = (byte)(litB >> 32);
|
encodedInstruction[8] = (byte)(litB >> 48);
|
||||||
bytes[7] = (byte)(litB >> 40);
|
encodedInstruction[9] = (byte)(litB >> 56);
|
||||||
|
|
||||||
bytes[8] = (byte)(litB >> 48);
|
|
||||||
bytes[9] = (byte)(litB >> 56);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteCount() {
|
private Instruction51l(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
return 10;
|
super(dexFile, opcode, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormatName() {
|
private Instruction51l() {
|
||||||
return "51l";
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format51l;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new Instruction51l();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
|
return new Instruction51l(dexFile, opcode, rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getRegister() {
|
||||||
|
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLiteral() {
|
||||||
|
return NumberUtils.decodeLong(encodedInstruction, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
|
||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
|
|
||||||
public class PackedSwitchData
|
|
||||||
{
|
|
||||||
public static Instruction make(DexFile dexFile, int firstKey, int[] targets) {
|
|
||||||
byte[] bytes;
|
|
||||||
|
|
||||||
if (targets.length > 0xFFFF) {
|
|
||||||
throw new RuntimeException("The packed-switch data contains too many elements. " +
|
|
||||||
"The maximum number of switch elements is 65535");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = new byte[targets.length * 4 + 8];
|
|
||||||
int position = 8;
|
|
||||||
|
|
||||||
for (int target: targets) {
|
|
||||||
bytes[position++] = (byte)target;
|
|
||||||
bytes[position++] = (byte)(target >> 8);
|
|
||||||
bytes[position++] = (byte)(target >> 16);
|
|
||||||
bytes[position++] = (byte)(target >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
//packed-switch psuedo-opcode
|
|
||||||
bytes[0] = 0x00;
|
|
||||||
bytes[1] = 0x01;
|
|
||||||
|
|
||||||
bytes[2] = (byte)targets.length;
|
|
||||||
bytes[3] = (byte)(targets.length >> 8);
|
|
||||||
|
|
||||||
bytes[4] = (byte)firstKey;
|
|
||||||
bytes[5] = (byte)(firstKey >> 8);
|
|
||||||
bytes[6] = (byte)(firstKey >> 16);
|
|
||||||
bytes[7] = (byte)(firstKey >> 24);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.Input;
|
||||||
|
|
||||||
|
public class PackedSwitchDataPseudoInstruction extends Instruction
|
||||||
|
{
|
||||||
|
public PackedSwitchDataPseudoInstruction(DexFile dexFile, int firstKey, int[] targets) {
|
||||||
|
super(dexFile, Opcode.NOP, (IndexedItem)null);
|
||||||
|
|
||||||
|
if (targets.length > 0xFFFF) {
|
||||||
|
throw new RuntimeException("The packed-switch data contains too many elements. " +
|
||||||
|
"The maximum number of switch elements is 65535");
|
||||||
|
}
|
||||||
|
|
||||||
|
encodedInstruction = new byte[targets.length * 4 + 8];
|
||||||
|
encodedInstruction[0] = 0x00;
|
||||||
|
encodedInstruction[1] = 0x01; //packed-switch pseudo-opcode
|
||||||
|
|
||||||
|
encodedInstruction[2] = (byte)targets.length;
|
||||||
|
encodedInstruction[3] = (byte)(targets.length >> 8);
|
||||||
|
|
||||||
|
encodedInstruction[4] = (byte)firstKey;
|
||||||
|
encodedInstruction[5] = (byte)(firstKey >> 8);
|
||||||
|
encodedInstruction[6] = (byte)(firstKey >> 16);
|
||||||
|
encodedInstruction[7] = (byte)(firstKey >> 24);
|
||||||
|
|
||||||
|
int position= 8;
|
||||||
|
for (int target: targets) {
|
||||||
|
encodedInstruction[position++] = (byte)target;
|
||||||
|
encodedInstruction[position++] = (byte)(target >> 8);
|
||||||
|
encodedInstruction[position++] = (byte)(target >> 16);
|
||||||
|
encodedInstruction[position++] = (byte)(target >> 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkFormat(Format format) {
|
||||||
|
//no need to check the format
|
||||||
|
}
|
||||||
|
|
||||||
|
private PackedSwitchDataPseudoInstruction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new PackedSwitchDataPseudoInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static PackedSwitchDataPseudoInstruction make(DexFile dexFile, Input input) {
|
||||||
|
byte opcodeByte = input.readByte();
|
||||||
|
if (opcodeByte != 0x00) {
|
||||||
|
throw new RuntimeException("Invalid opcode byte for a PackedSwitchData pseudo-instruction");
|
||||||
|
}
|
||||||
|
byte subopcodeByte = input.readByte();
|
||||||
|
if (subopcodeByte != 0x01) {
|
||||||
|
throw new RuntimeException("Invalid sub-opcode byte for a PackedSwitchData pseudo-instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
int targetCount = input.readShort();
|
||||||
|
|
||||||
|
int firstKey = input.readInt();
|
||||||
|
int[] targets = new int[targetCount];
|
||||||
|
|
||||||
|
for (int i=0; i<targetCount; i++) {
|
||||||
|
targets[i] = input.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PackedSwitchDataPseudoInstruction(dexFile, firstKey, targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.SparseSwitchData;
|
||||||
|
}
|
||||||
|
}
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib.code.Format;
|
|
||||||
|
|
||||||
import org.jf.dexlib.code.Instruction;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
|
|
||||||
public class SparseSwitchData
|
|
||||||
{
|
|
||||||
public static Instruction make(DexFile dexFile, int[] keys, int[] targets) {
|
|
||||||
byte[] bytes;
|
|
||||||
|
|
||||||
if (keys.length != targets.length) {
|
|
||||||
throw new RuntimeException("The number of keys and offsets don't match");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targets.length == 0) {
|
|
||||||
throw new RuntimeException("The sparse-switch data must contain at least 1 key/target");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targets.length > 0xFFFF) {
|
|
||||||
throw new RuntimeException("The sparse-switch data contains too many elements. " +
|
|
||||||
"The maximum number of switch elements is 65535");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = new byte[targets.length * 8 + 4];
|
|
||||||
int position = 8;
|
|
||||||
|
|
||||||
if (targets.length > 0) {
|
|
||||||
int key = keys[0];
|
|
||||||
bytes[4] = (byte)key;
|
|
||||||
bytes[5] = (byte)(key >> 8);
|
|
||||||
bytes[6] = (byte)(key >> 16);
|
|
||||||
bytes[7] = (byte)(key >> 24);
|
|
||||||
|
|
||||||
for (int i=1; i<keys.length; i++) {
|
|
||||||
key = keys[i];
|
|
||||||
if (key <= keys[i-1]) {
|
|
||||||
throw new RuntimeException("The targets in a sparse switch block must be sorted in ascending" +
|
|
||||||
"order, by key");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[position++] = (byte)key;
|
|
||||||
bytes[position++] = (byte)(key >> 8);
|
|
||||||
bytes[position++] = (byte)(key >> 16);
|
|
||||||
bytes[position++] = (byte)(key >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int target: targets) {
|
|
||||||
bytes[position++] = (byte)target;
|
|
||||||
bytes[position++] = (byte)(target >> 8);
|
|
||||||
bytes[position++] = (byte)(target >> 16);
|
|
||||||
bytes[position++] = (byte)(target >> 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//sparse-switch psuedo-opcode
|
|
||||||
bytes[0] = 0x00;
|
|
||||||
bytes[1] = 0x02;
|
|
||||||
|
|
||||||
bytes[2] = (byte)targets.length;
|
|
||||||
bytes[3] = (byte)(targets.length >> 8);
|
|
||||||
|
|
||||||
return new Instruction(dexFile, bytes, null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Instruction;
|
||||||
|
import org.jf.dexlib.code.Opcode;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.util.Input;
|
||||||
|
|
||||||
|
public class SparseSwitchDataPseudoInstruction extends Instruction
|
||||||
|
{
|
||||||
|
public SparseSwitchDataPseudoInstruction(DexFile dexFile, int[] keys, int[] targets) {
|
||||||
|
super(dexFile, Opcode.NOP, (IndexedItem)null);
|
||||||
|
|
||||||
|
if (keys.length != targets.length) {
|
||||||
|
throw new RuntimeException("The number of keys and offsets don't match");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targets.length == 0) {
|
||||||
|
throw new RuntimeException("The sparse-switch data must contain at least 1 key/target");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targets.length > 0xFFFF) {
|
||||||
|
throw new RuntimeException("The sparse-switch data contains too many elements. " +
|
||||||
|
"The maximum number of switch elements is 65535");
|
||||||
|
}
|
||||||
|
|
||||||
|
encodedInstruction = new byte[targets.length * 8 + 4];
|
||||||
|
encodedInstruction[0] = 0x00;
|
||||||
|
encodedInstruction[1] = 0x02; //sparse-switch psuedo-opcode
|
||||||
|
|
||||||
|
encodedInstruction[2] = (byte)targets.length;
|
||||||
|
encodedInstruction[3] = (byte)(targets.length >> 8);
|
||||||
|
|
||||||
|
int position = 8;
|
||||||
|
|
||||||
|
if (targets.length > 0) {
|
||||||
|
int key = keys[0];
|
||||||
|
encodedInstruction[4] = (byte)key;
|
||||||
|
encodedInstruction[5] = (byte)(key >> 8);
|
||||||
|
encodedInstruction[6] = (byte)(key >> 16);
|
||||||
|
encodedInstruction[7] = (byte)(key >> 24);
|
||||||
|
|
||||||
|
for (int i=1; i<keys.length; i++) {
|
||||||
|
key = keys[i];
|
||||||
|
if (key <= keys[i-1]) {
|
||||||
|
throw new RuntimeException("The targets in a sparse switch block must be sorted in ascending" +
|
||||||
|
"order, by key");
|
||||||
|
}
|
||||||
|
|
||||||
|
encodedInstruction[position++] = (byte)key;
|
||||||
|
encodedInstruction[position++] = (byte)(key >> 8);
|
||||||
|
encodedInstruction[position++] = (byte)(key >> 16);
|
||||||
|
encodedInstruction[position++] = (byte)(key >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int target: targets) {
|
||||||
|
encodedInstruction[position++] = (byte)target;
|
||||||
|
encodedInstruction[position++] = (byte)(target >> 8);
|
||||||
|
encodedInstruction[position++] = (byte)(target >> 16);
|
||||||
|
encodedInstruction[position++] = (byte)(target >> 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkFormat(Format format) {
|
||||||
|
//no need to check the format
|
||||||
|
}
|
||||||
|
|
||||||
|
private SparseSwitchDataPseudoInstruction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instruction makeClone() {
|
||||||
|
return new SparseSwitchDataPseudoInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SparseSwitchDataPseudoInstruction make(DexFile dexFile, Input input) {
|
||||||
|
byte opcodeByte = input.readByte();
|
||||||
|
if (opcodeByte != 0x00) {
|
||||||
|
throw new RuntimeException("Invalid opcode byte for a SparseSwitchData pseudo-instruction");
|
||||||
|
}
|
||||||
|
byte subopcodeByte = input.readByte();
|
||||||
|
if (subopcodeByte != 0x02) {
|
||||||
|
throw new RuntimeException("Invalid sub-opcode byte for a SparseSwitchData pseudo-instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
int targetCount = input.readShort();
|
||||||
|
|
||||||
|
int[] keys = new int[targetCount];
|
||||||
|
int[] targets = new int[targetCount];
|
||||||
|
|
||||||
|
for (int i=0; i<targetCount; i++) {
|
||||||
|
keys[i] = input.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<targetCount; i++) {
|
||||||
|
targets[i] = input.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SparseSwitchDataPseudoInstruction(dexFile, keys, targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.SparseSwitchData;
|
||||||
|
}
|
||||||
|
}
|
@ -29,179 +29,300 @@
|
|||||||
package org.jf.dexlib.code;
|
package org.jf.dexlib.code;
|
||||||
|
|
||||||
import org.jf.dexlib.*;
|
import org.jf.dexlib.*;
|
||||||
|
import org.jf.dexlib.code.Format.Format;
|
||||||
import org.jf.dexlib.util.Input;
|
import org.jf.dexlib.util.Input;
|
||||||
import org.jf.dexlib.util.AnnotatedOutput;
|
import org.jf.dexlib.util.AnnotatedOutput;
|
||||||
|
|
||||||
public final class Instruction implements Field<Instruction> {
|
import java.util.Collections;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
|
||||||
|
public abstract class Instruction {
|
||||||
private DexFile dexFile;
|
private DexFile dexFile;
|
||||||
private byte[] bytes;
|
|
||||||
private Opcode opcode;
|
private Opcode opcode;
|
||||||
|
private IndexedItem referencedItem;
|
||||||
|
protected byte[] encodedInstruction;
|
||||||
|
|
||||||
private IndexedItem reference;
|
public int getSize() {
|
||||||
|
return encodedInstruction.length;
|
||||||
public byte[] getBytes() {
|
|
||||||
return bytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Opcode getOpcode() {
|
public Opcode getOpcode() {
|
||||||
return opcode;
|
return opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexedItem getReference() {
|
public IndexedItem getReferencedItem() {
|
||||||
return reference;
|
return referencedItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(DexFile dexFile) {
|
protected void setReferencedItem(IndexedItem referencedItem) {
|
||||||
this.dexFile = dexFile;
|
checkReferenceType(referencedItem, this.opcode);
|
||||||
|
this.referencedItem = referencedItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(DexFile dexFile, byte[] bytes, IndexedItem item) {
|
protected Instruction(DexFile dexFile, Opcode opcode, IndexedItem referencedItem) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
this.bytes = bytes;
|
this.opcode = opcode;
|
||||||
this.reference = item;
|
this.referencedItem = referencedItem;
|
||||||
this.opcode = Opcode.getOpcodeByValue(bytes[0]);
|
|
||||||
if (!this.opcode.referenceType.checkItem(item)) {
|
checkFormat(opcode.format);
|
||||||
throw new RuntimeException("item is not the correct type for this opcode (got " + item.getClass().toString() + ", expecting " + opcode.referenceType.toString() + ")");
|
checkReferenceType(referencedItem, this.opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkFormat(Format format) {
|
||||||
|
if (format != getFormat()) {
|
||||||
|
throw new RuntimeException(opcode.name + " does not use " + getFormat().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFrom(Input in) {
|
protected Instruction(DexFile dexFile, Opcode opcode, byte[] rest) {
|
||||||
int startPos = in.getCursor();
|
this.dexFile = dexFile;
|
||||||
|
this.opcode = opcode;
|
||||||
byte opByte = in.readByte();
|
|
||||||
|
|
||||||
if (opByte == 0x00) {
|
if ((rest.length + 1) != opcode.format.size) {
|
||||||
reference = null;
|
throw new RuntimeException("Invalid instruction size. This opcode is " +
|
||||||
byte secondByte = in.readByte();
|
Integer.toString(rest.length + 1) + " bytes, but the opcode should be " +
|
||||||
|
Integer.toString(opcode.format.size) + " bytes.");
|
||||||
int count;
|
|
||||||
|
|
||||||
|
|
||||||
switch (secondByte) {
|
|
||||||
case 0x00:
|
|
||||||
/** nop */
|
|
||||||
bytes = new byte[] { 0x00, 0x00 };
|
|
||||||
return;
|
|
||||||
case 0x01:
|
|
||||||
/** packed switch */
|
|
||||||
count = in.readShort();
|
|
||||||
in.setCursor(startPos);
|
|
||||||
bytes = in.readBytes((count * 4) + 8);
|
|
||||||
return;
|
|
||||||
case 0x02:
|
|
||||||
/** sparse switch */
|
|
||||||
count = in.readShort();
|
|
||||||
in.setCursor(startPos);
|
|
||||||
bytes = in.readBytes((count * 8) + 4);
|
|
||||||
return;
|
|
||||||
case 0x03:
|
|
||||||
/** fill array data */
|
|
||||||
int elementWidth = in.readShort();
|
|
||||||
count = in.readInt();
|
|
||||||
in.setCursor(startPos);
|
|
||||||
bytes = in.readBytes(((elementWidth * count + 1)/2 + 4) * 2);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("Invalid 2nd byte for opcode 0x00");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.opcode = Opcode.getOpcodeByValue(opByte);
|
this.encodedInstruction = new byte[rest.length + 1];
|
||||||
|
encodedInstruction[0] = opcode.value;
|
||||||
|
System.arraycopy(rest, 0, encodedInstruction, 1, rest.length);
|
||||||
|
|
||||||
if (opcode.referenceType != ReferenceType.none) {
|
if (opcode.referenceType != ReferenceType.none) {
|
||||||
in.skipBytes(1);
|
int itemIndex = (encodedInstruction[3] << 8) | encodedInstruction[2];
|
||||||
int referenceIndex = in.readShort();
|
getReferencedItem(dexFile, opcode, itemIndex);
|
||||||
|
|
||||||
//handle const-string/jumbo as a special case
|
|
||||||
if (opByte == 0x1b) {
|
|
||||||
int hiWord = in.readShort();
|
|
||||||
if (hiWord != 0) {
|
|
||||||
referenceIndex += (hiWord<<16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (opcode.referenceType) {
|
|
||||||
case string:
|
|
||||||
reference = dexFile.StringIdsSection.getByIndex(referenceIndex);
|
|
||||||
break;
|
|
||||||
case type:
|
|
||||||
reference = dexFile.TypeIdsSection.getByIndex(referenceIndex);
|
|
||||||
break;
|
|
||||||
case field:
|
|
||||||
reference = dexFile.FieldIdsSection.getByIndex(referenceIndex);
|
|
||||||
break;
|
|
||||||
case method:
|
|
||||||
reference = dexFile.MethodIdsSection.getByIndex(referenceIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reference = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
in.setCursor(startPos);
|
|
||||||
bytes = in.readBytes(opcode.numBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeTo(AnnotatedOutput out) {
|
|
||||||
out.annotate(bytes.length, "instruction");
|
|
||||||
if (needsAlign()) {
|
|
||||||
//the "special instructions" must be 4 byte aligned
|
|
||||||
out.alignTo(4);
|
|
||||||
out.write(bytes);
|
|
||||||
} else if (reference == null) {
|
|
||||||
out.write(bytes);
|
|
||||||
} else {
|
|
||||||
out.write(bytes,0,2);
|
|
||||||
//handle const-string/jumbo as a special case
|
|
||||||
if (bytes[0] == 0x1b) {
|
|
||||||
out.writeInt(reference.getIndex());
|
|
||||||
} else {
|
|
||||||
int index = reference.getIndex();
|
|
||||||
if (index > 0xFFFF) {
|
|
||||||
throw new RuntimeException("String index doesn't fit.");
|
|
||||||
}
|
|
||||||
out.writeShort(reference.getIndex());
|
|
||||||
out.write(bytes, 4, bytes.length - 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyTo(DexFile dexFile, Instruction copy) {
|
protected Instruction() {
|
||||||
copy.bytes = bytes;
|
//this should only be used to make a blank clone within cloneTo()
|
||||||
copy.opcode = opcode;
|
}
|
||||||
|
|
||||||
|
private void checkReferenceType(IndexedItem referencedItem, Opcode opcode) {
|
||||||
|
switch (opcode.referenceType) {
|
||||||
|
case field:
|
||||||
|
if (!(referencedItem instanceof FieldIdItem)) {
|
||||||
|
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
||||||
|
" is the wrong item type for opcode " + opcode.name + ". Expecting FieldIdItem.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case method:
|
||||||
|
if (!(referencedItem instanceof MethodIdItem)) {
|
||||||
|
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
||||||
|
" is the wrong item type for opcode " + opcode.name + ". Expecting MethodIdItem.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case type:
|
||||||
|
if (!(referencedItem instanceof TypeIdItem)) {
|
||||||
|
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
||||||
|
" is the wrong item type for opcode " + opcode.name + ". Expecting TypeIdItem.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case string:
|
||||||
|
if (!(referencedItem instanceof StringIdItem)) {
|
||||||
|
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
||||||
|
" is the wrong item type for opcode " + opcode.name + ". Expecting StringIdItem.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
if (referencedItem != null) {
|
||||||
|
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
||||||
|
" is invalid for opcode " + opcode.name + ". This opcode does not reference an item");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getReferencedItem(DexFile dexFile, Opcode opcode, int itemIndex) {
|
||||||
|
switch (opcode.referenceType) {
|
||||||
|
case field:
|
||||||
|
referencedItem = dexFile.FieldIdsSection.getByIndex(itemIndex);
|
||||||
|
return;
|
||||||
|
case method:
|
||||||
|
referencedItem = dexFile.MethodIdsSection.getByIndex(itemIndex);
|
||||||
|
return;
|
||||||
|
case type:
|
||||||
|
referencedItem = dexFile.TypeIdsSection.getByIndex(itemIndex);
|
||||||
|
return;
|
||||||
|
case string:
|
||||||
|
referencedItem = dexFile.StringIdsSection.getByIndex(itemIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Format getFormat();
|
||||||
|
|
||||||
|
public static interface InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction cloneTo(DexFile dexFile) {
|
||||||
|
Instruction clone = makeClone();
|
||||||
|
clone.encodedInstruction = encodedInstruction.clone();
|
||||||
|
clone.dexFile = dexFile;
|
||||||
|
clone.opcode = opcode;
|
||||||
|
if (referencedItem != null) {
|
||||||
switch (opcode.referenceType) {
|
switch (opcode.referenceType) {
|
||||||
case string:
|
case string:
|
||||||
copy.reference = dexFile.StringIdsSection.intern(dexFile, (StringIdItem)reference);
|
clone.referencedItem = dexFile.StringIdsSection.intern(dexFile, (StringIdItem)referencedItem);
|
||||||
break;
|
break;
|
||||||
case type:
|
case type:
|
||||||
copy.reference = dexFile.TypeIdsSection.intern(dexFile, (TypeIdItem)reference);
|
clone.referencedItem = dexFile.TypeIdsSection.intern(dexFile, (TypeIdItem)referencedItem);
|
||||||
break;
|
break;
|
||||||
case field:
|
case field:
|
||||||
copy.reference = dexFile.FieldIdsSection.intern(dexFile, (FieldIdItem)reference);
|
clone.referencedItem = dexFile.FieldIdsSection.intern(dexFile, (FieldIdItem)referencedItem);
|
||||||
break;
|
break;
|
||||||
case method:
|
case method:
|
||||||
copy.reference = dexFile.MethodIdsSection.intern(dexFile, (MethodIdItem)reference);
|
clone.referencedItem = dexFile.MethodIdsSection.intern(dexFile, (MethodIdItem)referencedItem);
|
||||||
break;
|
break;
|
||||||
case none:
|
case none:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public int place(int offset) {
|
|
||||||
return offset + getSize(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize(int offset) {
|
|
||||||
if (this.needsAlign() && (offset % 4) != 0) {
|
|
||||||
return bytes.length + 2;
|
|
||||||
} else {
|
|
||||||
return bytes.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean needsAlign() {
|
protected abstract Instruction makeClone();
|
||||||
//true if the opcode is one of the "special format" opcodes
|
|
||||||
return bytes[0] == 0 && bytes[1] > 0;
|
// public void readFrom(Input in) {
|
||||||
}
|
// int startPos = in.getCursor();
|
||||||
|
//
|
||||||
|
// byte opByte = in.readByte();
|
||||||
|
//
|
||||||
|
// if (opByte == 0x00) {
|
||||||
|
// reference = null;
|
||||||
|
// byte secondByte = in.readByte();
|
||||||
|
//
|
||||||
|
// int count;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// switch (secondByte) {
|
||||||
|
// case 0x00:
|
||||||
|
// /** nop */
|
||||||
|
// bytes = new byte[] { 0x00, 0x00 };
|
||||||
|
// return;
|
||||||
|
// case 0x01:
|
||||||
|
// /** packed switch */
|
||||||
|
// count = in.readShort();
|
||||||
|
// in.setCursor(startPos);
|
||||||
|
// bytes = in.readBytes((count * 4) + 8);
|
||||||
|
// return;
|
||||||
|
// case 0x02:
|
||||||
|
// /** sparse switch */
|
||||||
|
// count = in.readShort();
|
||||||
|
// in.setCursor(startPos);
|
||||||
|
// bytes = in.readBytes((count * 8) + 4);
|
||||||
|
// return;
|
||||||
|
// case 0x03:
|
||||||
|
// /** fill array data */
|
||||||
|
// int elementWidth = in.readShort();
|
||||||
|
// count = in.readInt();
|
||||||
|
// in.setCursor(startPos);
|
||||||
|
// bytes = in.readBytes(((elementWidth * count + 1)/2 + 4) * 2);
|
||||||
|
// return;
|
||||||
|
// default:
|
||||||
|
// throw new RuntimeException("Invalid 2nd byte for opcode 0x00");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// this.opcode = Opcode.getOpcodeByValue(opByte);
|
||||||
|
//
|
||||||
|
// if (opcode.referenceType != ReferenceType.none) {
|
||||||
|
// in.skipBytes(1);
|
||||||
|
// int referenceIndex = in.readShort();
|
||||||
|
//
|
||||||
|
// //handle const-string/jumbo as a special case
|
||||||
|
// if (opByte == 0x1b) {
|
||||||
|
// int hiWord = in.readShort();
|
||||||
|
// if (hiWord != 0) {
|
||||||
|
// referenceIndex += (hiWord<<16);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// switch (opcode.referenceType) {
|
||||||
|
// case string:
|
||||||
|
// reference = dexFile.StringIdsSection.getByIndex(referenceIndex);
|
||||||
|
// break;
|
||||||
|
// case type:
|
||||||
|
// reference = dexFile.TypeIdsSection.getByIndex(referenceIndex);
|
||||||
|
// break;
|
||||||
|
// case field:
|
||||||
|
// reference = dexFile.FieldIdsSection.getByIndex(referenceIndex);
|
||||||
|
// break;
|
||||||
|
// case method:
|
||||||
|
// reference = dexFile.MethodIdsSection.getByIndex(referenceIndex);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// reference = null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// in.setCursor(startPos);
|
||||||
|
// bytes = in.readBytes(opcode.numBytes);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void writeTo(AnnotatedOutput out) {
|
||||||
|
// out.annotate(bytes.length, "instruction");
|
||||||
|
// if (needsAlign()) {
|
||||||
|
// //the "special instructions" must be 4 byte aligned
|
||||||
|
// out.alignTo(4);
|
||||||
|
// out.write(bytes);
|
||||||
|
// } else if (reference == null) {
|
||||||
|
// out.write(bytes);
|
||||||
|
// } else {
|
||||||
|
// out.write(bytes,0,2);
|
||||||
|
// //handle const-string/jumbo as a special case
|
||||||
|
// if (bytes[0] == 0x1b) {
|
||||||
|
// out.writeInt(reference.getIndex());
|
||||||
|
// } else {
|
||||||
|
// int index = reference.getIndex();
|
||||||
|
// if (index > 0xFFFF) {
|
||||||
|
// throw new RuntimeException("String index doesn't fit.");
|
||||||
|
// }
|
||||||
|
// out.writeShort(reference.getIndex());
|
||||||
|
// out.write(bytes, 4, bytes.length - 4);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void copyTo(DexFile dexFile, Instruction copy) {
|
||||||
|
// copy.bytes = bytes;
|
||||||
|
// copy.opcode = opcode;
|
||||||
|
//
|
||||||
|
// switch (opcode.referenceType) {
|
||||||
|
// case string:
|
||||||
|
// copy.reference = dexFile.StringIdsSection.intern(dexFile, (StringIdItem)reference);
|
||||||
|
// break;
|
||||||
|
// case type:
|
||||||
|
// copy.reference = dexFile.TypeIdsSection.intern(dexFile, (TypeIdItem)reference);
|
||||||
|
// break;
|
||||||
|
// case field:
|
||||||
|
// copy.reference = dexFile.FieldIdsSection.intern(dexFile, (FieldIdItem)reference);
|
||||||
|
// break;
|
||||||
|
// case method:
|
||||||
|
// copy.reference = dexFile.MethodIdsSection.intern(dexFile, (MethodIdItem)reference);
|
||||||
|
// break;
|
||||||
|
// case none:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public int place(int offset) {
|
||||||
|
// return offset + getSize(offset);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public int getSize(int offset) {
|
||||||
|
// if (this.needsAlign() && (offset % 4) != 0) {
|
||||||
|
// return bytes.length + 2;
|
||||||
|
// } else {
|
||||||
|
// return bytes.length;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private boolean needsAlign() {
|
||||||
|
// //true if the opcode is one of the "special format" opcodes
|
||||||
|
// return bytes[0] == 0 && bytes[1] > 0;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
141
src/main/java/org/jf/dexlib/code/InstructionField.java
Normal file
141
src/main/java/org/jf/dexlib/code/InstructionField.java
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.code;
|
||||||
|
|
||||||
|
import org.jf.dexlib.Field;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.IndexedItem;
|
||||||
|
import org.jf.dexlib.code.Format.PackedSwitchDataPseudoInstruction;
|
||||||
|
import org.jf.dexlib.code.Format.SparseSwitchDataPseudoInstruction;
|
||||||
|
import org.jf.dexlib.code.Format.ArrayDataPseudoInstruction;
|
||||||
|
import org.jf.dexlib.util.AnnotatedOutput;
|
||||||
|
import org.jf.dexlib.util.Input;
|
||||||
|
|
||||||
|
public class InstructionField implements Field<InstructionField> {
|
||||||
|
private Instruction instruction;
|
||||||
|
private DexFile dexFile;
|
||||||
|
|
||||||
|
public InstructionField(DexFile dexFile) {
|
||||||
|
this.dexFile = dexFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstructionField(DexFile dexFile, Instruction instruction) {
|
||||||
|
this.dexFile = dexFile;
|
||||||
|
this.instruction = instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTo(AnnotatedOutput out) {
|
||||||
|
byte[] bytes = instruction.encodedInstruction;
|
||||||
|
IndexedItem reference = instruction.getReferencedItem();
|
||||||
|
|
||||||
|
out.annotate(bytes.length, "instruction");
|
||||||
|
if (needsAlign()) {
|
||||||
|
//the "special instructions" must be 4 byte aligned
|
||||||
|
out.alignTo(4);
|
||||||
|
out.write(bytes);
|
||||||
|
} else if (reference == null) {
|
||||||
|
out.write(bytes);
|
||||||
|
} else {
|
||||||
|
out.write(bytes,0,2);
|
||||||
|
//handle const-string/jumbo as a special case
|
||||||
|
if (bytes[0] == 0x1b) {
|
||||||
|
out.writeInt(reference.getIndex());
|
||||||
|
} else {
|
||||||
|
int index = reference.getIndex();
|
||||||
|
if (index > 0xFFFF) {
|
||||||
|
throw new RuntimeException("String index doesn't fit.");
|
||||||
|
}
|
||||||
|
out.writeShort(reference.getIndex());
|
||||||
|
out.write(bytes, 4, bytes.length - 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFrom(Input in) {
|
||||||
|
int startPos = in.getCursor();
|
||||||
|
|
||||||
|
byte opByte = in.readByte();
|
||||||
|
|
||||||
|
if (opByte == 0x00) {
|
||||||
|
byte secondByte = in.readByte();
|
||||||
|
|
||||||
|
switch (secondByte) {
|
||||||
|
case 0x00:
|
||||||
|
//nop
|
||||||
|
instruction = Opcode.NOP.format.Factory.makeInstruction(dexFile, Opcode.NOP, new byte[]{0x00, 0x00});
|
||||||
|
return;
|
||||||
|
case 0x01:
|
||||||
|
//packed switch
|
||||||
|
in.setCursor(startPos);
|
||||||
|
instruction = PackedSwitchDataPseudoInstruction.make(dexFile, in);
|
||||||
|
return;
|
||||||
|
case 0x02:
|
||||||
|
//sparse switch
|
||||||
|
in.setCursor(startPos);
|
||||||
|
instruction = SparseSwitchDataPseudoInstruction.make(dexFile, in);
|
||||||
|
return;
|
||||||
|
case 0x03:
|
||||||
|
//array data
|
||||||
|
in.setCursor(startPos);
|
||||||
|
instruction = ArrayDataPseudoInstruction.make(dexFile, in);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Invalid 2nd byte for opcode 0x00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Opcode opcode = Opcode.getOpcodeByValue(opByte);
|
||||||
|
instruction = opcode.format.Factory.makeInstruction(dexFile, opcode, in.readBytes(opcode.format.size - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int place(int offset) {
|
||||||
|
return offset + getSize(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyTo(DexFile dexFile, InstructionField copy) {
|
||||||
|
copy.instruction = instruction.cloneTo(dexFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize(int offset) {
|
||||||
|
if (this.needsAlign() && (offset % 4) != 0) {
|
||||||
|
return instruction.encodedInstruction.length + 2;
|
||||||
|
} else {
|
||||||
|
return instruction.encodedInstruction.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean needsAlign() {
|
||||||
|
//true if the opcode is one of the "special format" opcodes
|
||||||
|
return instruction.encodedInstruction[0] == 0 && instruction.encodedInstruction[1] > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction getInstruction() {
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
}
|
@ -28,229 +28,231 @@
|
|||||||
|
|
||||||
package org.jf.dexlib.code;
|
package org.jf.dexlib.code;
|
||||||
|
|
||||||
|
import org.jf.dexlib.code.Format.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public enum Opcode
|
public enum Opcode
|
||||||
{
|
{
|
||||||
NOP((byte)0x00, "NOP", (byte)2, ReferenceType.none, "10x"),
|
NOP((byte)0x00, "nop", ReferenceType.none, Format.Format10x),
|
||||||
MOVE((byte)0x01, "MOVE", (byte)2, ReferenceType.none, "12x"),
|
MOVE((byte)0x01, "move", ReferenceType.none, Format.Format12x),
|
||||||
MOVE_FROM16((byte)0x02, "MOVE/FROM16", (byte)4, ReferenceType.none, "22x"),
|
MOVE_FROM16((byte)0x02, "move/from16", ReferenceType.none, Format.Format22x),
|
||||||
MOVE_16((byte)0x03, "MOVE/16", (byte)6, ReferenceType.none, "32x"),
|
MOVE_16((byte)0x03, "move/16", ReferenceType.none, Format.Format32x),
|
||||||
MOVE_WIDE((byte)0x04, "MOVE-WIDE", (byte)2, ReferenceType.none, "12x"),
|
MOVE_WIDE((byte)0x04, "move-wide", ReferenceType.none, Format.Format12x),
|
||||||
MOVE_WIDE_FROM16((byte)0x05, "MOVE-WIDE/FROM16", (byte)4, ReferenceType.none, "22x"),
|
MOVE_WIDE_FROM16((byte)0x05, "move-wide/from16", ReferenceType.none, Format.Format22x),
|
||||||
MOVE_WIDE_16((byte)0x06, "MOVE-WIDE/16", (byte)6, ReferenceType.none, "32x"),
|
MOVE_WIDE_16((byte)0x06, "move-wide/16", ReferenceType.none, Format.Format32x),
|
||||||
MOVE_OBJECT((byte)0x07, "MOVE-OBJECT", (byte)2, ReferenceType.none, "12x"),
|
MOVE_OBJECT((byte)0x07, "move-object", ReferenceType.none, Format.Format12x),
|
||||||
MOVE_OBJECT_FROM16((byte)0x08, "MOVE-OBJECT/FROM16", (byte)4, ReferenceType.none, "22x"),
|
MOVE_OBJECT_FROM16((byte)0x08, "move-object/from16", ReferenceType.none, Format.Format22x),
|
||||||
MOVE_OBJECT_16((byte)0x09, "MOVE-OBJECT/16", (byte)6, ReferenceType.none, "32x"),
|
MOVE_OBJECT_16((byte)0x09, "move-object/16", ReferenceType.none, Format.Format32x),
|
||||||
MOVE_RESULT((byte)0x0a, "MOVE-RESULT", (byte)2, ReferenceType.none, "11x"),
|
MOVE_RESULT((byte)0x0a, "move-result", ReferenceType.none, Format.Format11x),
|
||||||
MOVE_RESULT_WIDE((byte)0x0b, "MOVE-RESULT-WIDE", (byte)2, ReferenceType.none, "11x"),
|
MOVE_RESULT_WIDE((byte)0x0b, "move-result-wide", ReferenceType.none, Format.Format11x),
|
||||||
MOVE_RESULT_OBJECT((byte)0x0c, "MOVE-RESULT-OBJECT", (byte)2, ReferenceType.none, "11x"),
|
MOVE_RESULT_OBJECT((byte)0x0c, "move-result-object", ReferenceType.none, Format.Format11x),
|
||||||
MOVE_EXCEPTION((byte)0x0d, "MOVE-EXCEPTION", (byte)2, ReferenceType.none, "11x"),
|
MOVE_EXCEPTION((byte)0x0d, "move-exception", ReferenceType.none, Format.Format11x),
|
||||||
RETURN_VOID((byte)0x0e, "RETURN-VOID", (byte)2, ReferenceType.none, "10x"),
|
RETURN_VOID((byte)0x0e, "return-void", ReferenceType.none, Format.Format10x),
|
||||||
RETURN((byte)0x0f, "RETURN", (byte)2, ReferenceType.none, "11x"),
|
RETURN((byte)0x0f, "return", ReferenceType.none, Format.Format11x),
|
||||||
RETURN_WIDE((byte)0x10, "RETURN-WIDE", (byte)2, ReferenceType.none, "11x"),
|
RETURN_WIDE((byte)0x10, "return-wide", ReferenceType.none, Format.Format11x),
|
||||||
RETURN_OBJECT((byte)0x11, "RETURN-OBJECT", (byte)2, ReferenceType.none, "11x"),
|
RETURN_OBJECT((byte)0x11, "return-object", ReferenceType.none, Format.Format11x),
|
||||||
CONST_4((byte)0x12, "CONST/4", (byte)2, ReferenceType.none, "11n"),
|
CONST_4((byte)0x12, "const/4", ReferenceType.none, Format.Format11n),
|
||||||
CONST_16((byte)0x13, "CONST/16", (byte)4, ReferenceType.none, "21s"),
|
CONST_16((byte)0x13, "const/16", ReferenceType.none, Format.Format21s),
|
||||||
CONST((byte)0x14, "CONST", (byte)6, ReferenceType.none, "31i"),
|
CONST((byte)0x14, "const", ReferenceType.none, Format.Format31i),
|
||||||
CONST_HIGH16((byte)0x15, "CONST/HIGH16", (byte)4, ReferenceType.none, "21h"),
|
CONST_HIGH16((byte)0x15, "const/high16", ReferenceType.none, Format.Format21h),
|
||||||
CONST_WIDE_16((byte)0x16, "CONST-WIDE/16", (byte)4, ReferenceType.none, "21s"),
|
CONST_WIDE_16((byte)0x16, "const-wide/16", ReferenceType.none, Format.Format21s),
|
||||||
CONST_WIDE_32((byte)0x17, "CONST-WIDE/32", (byte)6, ReferenceType.none, "31i"),
|
CONST_WIDE_32((byte)0x17, "const-wide/32", ReferenceType.none, Format.Format31i),
|
||||||
CONST_WIDE((byte)0x18, "CONST-WIDE", (byte)10, ReferenceType.none, "51l"),
|
CONST_WIDE((byte)0x18, "const-wide", ReferenceType.none, Format.Format51l),
|
||||||
CONST_WIDE_HIGH16((byte)0x19, "CONST-WIDE/HIGH16", (byte)4, ReferenceType.none, "21h"),
|
CONST_WIDE_HIGH16((byte)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h),
|
||||||
CONST_STRING((byte)0x1a, "CONST-STRING", (byte)4, ReferenceType.string, "21c"),
|
CONST_STRING((byte)0x1a, "const-string", ReferenceType.string, Format.Format21c),
|
||||||
CONST_STRING_JUMBO((byte)0x1b, "CONST-STRING/JUMBO", (byte)6, ReferenceType.string, "31c"),
|
CONST_STRING_JUMBO((byte)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c),
|
||||||
CONST_CLASS((byte)0x1c, "CONST-CLASS", (byte)4, ReferenceType.type, "21c"),
|
CONST_CLASS((byte)0x1c, "const-class", ReferenceType.type, Format.Format21c),
|
||||||
MONITOR_ENTER((byte)0x1d, "MONITOR-ENTER", (byte)2, ReferenceType.none, "11x"),
|
MONITOR_ENTER((byte)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x),
|
||||||
MONITOR_EXIT((byte)0x1e, "MONITOR-EXIT", (byte)2, ReferenceType.none, "11x"),
|
MONITOR_EXIT((byte)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x),
|
||||||
CHECK_CAST((byte)0x1f, "CHECK-CAST", (byte)4, ReferenceType.type, "21c"),
|
CHECK_CAST((byte)0x1f, "check-cast", ReferenceType.type, Format.Format21c),
|
||||||
INSTANCE_OF((byte)0x20, "INSTANCE-OF", (byte)4, ReferenceType.type, "22c"),
|
INSTANCE_OF((byte)0x20, "instance-of", ReferenceType.type, Format.Format22c),
|
||||||
ARRAY_LENGTH((byte)0x21, "ARRAY-LENGTH", (byte)2, ReferenceType.none, "12x"),
|
ARRAY_LENGTH((byte)0x21, "array-length", ReferenceType.none, Format.Format12x),
|
||||||
NEW_INSTANCE((byte)0x22, "NEW-INSTANCE", (byte)4, ReferenceType.type, "21c"),
|
NEW_INSTANCE((byte)0x22, "new-instance", ReferenceType.type, Format.Format21c),
|
||||||
NEW_ARRAY((byte)0x23, "NEW-ARRAY", (byte)4, ReferenceType.type, "22c"),
|
NEW_ARRAY((byte)0x23, "new-array", ReferenceType.type, Format.Format22c),
|
||||||
FILLED_NEW_ARRAY((byte)0x24, "FILLED-NEW-ARRAY", (byte)6, ReferenceType.type, "35c"),
|
FILLED_NEW_ARRAY((byte)0x24, "filled-new-array", ReferenceType.type, Format.Format35c),
|
||||||
FILLED_NEW_ARRAY_RANGE((byte)0x25, "FILLED-NEW-ARRAY/RANGE", (byte)6, ReferenceType.type, "3rc"),
|
FILLED_NEW_ARRAY_RANGE((byte)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc),
|
||||||
FILL_ARRAY_DATA((byte)0x26, "FILL-ARRAY-DATA", (byte)6, ReferenceType.none, "31t"),
|
FILL_ARRAY_DATA((byte)0x26, "fill-array-data", ReferenceType.none, Format.Format31t),
|
||||||
THROW((byte)0x27, "THROW", (byte)2, ReferenceType.none, "11x"),
|
THROW((byte)0x27, "throw", ReferenceType.none, Format.Format11x),
|
||||||
GOTO((byte)0x28, "GOTO", (byte)2, ReferenceType.none, "10t"),
|
GOTO((byte)0x28, "goto", ReferenceType.none, Format.Format10t),
|
||||||
GOTO_16((byte)0x29, "GOTO/16", (byte)4, ReferenceType.none, "20t"),
|
GOTO_16((byte)0x29, "goto/16", ReferenceType.none, Format.Format20t),
|
||||||
GOTO_32((byte)0x2a, "GOTO/32", (byte)6, ReferenceType.none, "30t"),
|
GOTO_32((byte)0x2a, "goto/32", ReferenceType.none, Format.Format30t),
|
||||||
PACKED_SWITCH((byte)0x2b, "PACKED-SWITCH", (byte)6, ReferenceType.none, "31t"),
|
PACKED_SWITCH((byte)0x2b, "packed-switch", ReferenceType.none, Format.Format31t),
|
||||||
SPARSE_SWITCH((byte)0x2c, "SPARSE-SWITCH", (byte)6, ReferenceType.none, "31t"),
|
SPARSE_SWITCH((byte)0x2c, "sparse-switch", ReferenceType.none, Format.Format31t),
|
||||||
CMPL_FLOAT((byte)0x2d, "CMPL-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
CMPL_FLOAT((byte)0x2d, "cmpl-float", ReferenceType.none, Format.Format23x),
|
||||||
CMPG_FLOAT((byte)0x2e, "CMPG-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
CMPG_FLOAT((byte)0x2e, "cmpg-float", ReferenceType.none, Format.Format23x),
|
||||||
CMPL_DOUBLE((byte)0x2f, "CMPL-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
CMPL_DOUBLE((byte)0x2f, "cmpl-double", ReferenceType.none, Format.Format23x),
|
||||||
CMPG_DOUBLE((byte)0x30, "CMPG-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
CMPG_DOUBLE((byte)0x30, "cmpg-double", ReferenceType.none, Format.Format23x),
|
||||||
CMP_LONG((byte)0x31, "CMP-LONG", (byte)4, ReferenceType.none, "23x"),
|
CMP_LONG((byte)0x31, "cmp-long", ReferenceType.none, Format.Format23x),
|
||||||
IF_EQ((byte)0x32, "IF-EQ", (byte)4, ReferenceType.none, "22t"),
|
IF_EQ((byte)0x32, "if-eq", ReferenceType.none, Format.Format22t),
|
||||||
IF_NE((byte)0x33, "IF-NE", (byte)4, ReferenceType.none, "22t"),
|
IF_NE((byte)0x33, "if-ne", ReferenceType.none, Format.Format22t),
|
||||||
IF_LT((byte)0x34, "IF-LT", (byte)4, ReferenceType.none, "22t"),
|
IF_LT((byte)0x34, "if-lt", ReferenceType.none, Format.Format22t),
|
||||||
IF_GE((byte)0x35, "IF-GE", (byte)4, ReferenceType.none, "22t"),
|
IF_GE((byte)0x35, "if-ge", ReferenceType.none, Format.Format22t),
|
||||||
IF_GT((byte)0x36, "IF-GT", (byte)4, ReferenceType.none, "22t"),
|
IF_GT((byte)0x36, "if-gt", ReferenceType.none, Format.Format22t),
|
||||||
IF_LE((byte)0x37, "IF-LE", (byte)4, ReferenceType.none, "22t"),
|
IF_LE((byte)0x37, "if-le", ReferenceType.none, Format.Format22t),
|
||||||
IF_EQZ((byte)0x38, "IF-EQZ", (byte)4, ReferenceType.none, "21t"),
|
IF_EQZ((byte)0x38, "if-eqz", ReferenceType.none, Format.Format21t),
|
||||||
IF_NEZ((byte)0x39, "IF-NEZ", (byte)4, ReferenceType.none, "21t"),
|
IF_NEZ((byte)0x39, "if-nez", ReferenceType.none, Format.Format21t),
|
||||||
IF_LTZ((byte)0x3a, "IF-LTZ", (byte)4, ReferenceType.none, "21t"),
|
IF_LTZ((byte)0x3a, "if-ltz", ReferenceType.none, Format.Format21t),
|
||||||
IF_GEZ((byte)0x3b, "IF-GEZ", (byte)4, ReferenceType.none, "21t"),
|
IF_GEZ((byte)0x3b, "if-gez", ReferenceType.none, Format.Format21t),
|
||||||
IF_GTZ((byte)0x3c, "IF-GTZ", (byte)4, ReferenceType.none, "21t"),
|
IF_GTZ((byte)0x3c, "if-gtz", ReferenceType.none, Format.Format21t),
|
||||||
IF_LEZ((byte)0x3d, "IF-LEZ", (byte)4, ReferenceType.none, "21t"),
|
IF_LEZ((byte)0x3d, "if-lez", ReferenceType.none, Format.Format21t),
|
||||||
AGET((byte)0x44, "AGET", (byte)4, ReferenceType.none, "23x"),
|
AGET((byte)0x44, "aget", ReferenceType.none, Format.Format23x),
|
||||||
AGET_WIDE((byte)0x45, "AGET-WIDE", (byte)4, ReferenceType.none, "23x"),
|
AGET_WIDE((byte)0x45, "aget-wide", ReferenceType.none, Format.Format23x),
|
||||||
AGET_OBJECT((byte)0x46, "AGET-OBJECT", (byte)4, ReferenceType.none, "23x"),
|
AGET_OBJECT((byte)0x46, "aget-object", ReferenceType.none, Format.Format23x),
|
||||||
AGET_BOOLEAN((byte)0x47, "AGET-BOOLEAN", (byte)4, ReferenceType.none, "23x"),
|
AGET_BOOLEAN((byte)0x47, "aget-boolean", ReferenceType.none, Format.Format23x),
|
||||||
AGET_BYTE((byte)0x48, "AGET-BYTE", (byte)4, ReferenceType.none, "23x"),
|
AGET_BYTE((byte)0x48, "aget-byte", ReferenceType.none, Format.Format23x),
|
||||||
AGET_CHAR((byte)0x49, "AGET-CHAR", (byte)4, ReferenceType.none, "23x"),
|
AGET_CHAR((byte)0x49, "aget-char", ReferenceType.none, Format.Format23x),
|
||||||
AGET_SHORT((byte)0x4a, "AGET-SHORT", (byte)4, ReferenceType.none, "23x"),
|
AGET_SHORT((byte)0x4a, "aget-short", ReferenceType.none, Format.Format23x),
|
||||||
APUT((byte)0x4b, "APUT", (byte)4, ReferenceType.none, "23x"),
|
APUT((byte)0x4b, "aput", ReferenceType.none, Format.Format23x),
|
||||||
APUT_WIDE((byte)0x4c, "APUT-WIDE", (byte)4, ReferenceType.none, "23x"),
|
APUT_WIDE((byte)0x4c, "aput-wide", ReferenceType.none, Format.Format23x),
|
||||||
APUT_OBJECT((byte)0x4d, "APUT-OBJECT", (byte)4, ReferenceType.none, "23x"),
|
APUT_OBJECT((byte)0x4d, "aput-object", ReferenceType.none, Format.Format23x),
|
||||||
APUT_BOOLEAN((byte)0x4e, "APUT-BOOLEAN", (byte)4, ReferenceType.none, "23x"),
|
APUT_BOOLEAN((byte)0x4e, "aput-boolean", ReferenceType.none, Format.Format23x),
|
||||||
APUT_BYTE((byte)0x4f, "APUT-BYTE", (byte)4, ReferenceType.none, "23x"),
|
APUT_BYTE((byte)0x4f, "aput-byte", ReferenceType.none, Format.Format23x),
|
||||||
APUT_CHAR((byte)0x50, "APUT-CHAR", (byte)4, ReferenceType.none, "23x"),
|
APUT_CHAR((byte)0x50, "aput-char", ReferenceType.none, Format.Format23x),
|
||||||
APUT_SHORT((byte)0x51, "APUT-SHORT", (byte)4, ReferenceType.none, "23x"),
|
APUT_SHORT((byte)0x51, "aput-short", ReferenceType.none, Format.Format23x),
|
||||||
IGET((byte)0x52, "IGET", (byte)4, ReferenceType.field, "22c"),
|
IGET((byte)0x52, "iget", ReferenceType.field, Format.Format22c),
|
||||||
IGET_WIDE((byte)0x53, "IGET-WIDE", (byte)4, ReferenceType.field, "22c"),
|
IGET_WIDE((byte)0x53, "iget-wide", ReferenceType.field, Format.Format22c),
|
||||||
IGET_OBJECT((byte)0x54, "IGET-OBJECT", (byte)4, ReferenceType.field, "22c"),
|
IGET_OBJECT((byte)0x54, "iget-object", ReferenceType.field, Format.Format22c),
|
||||||
IGET_BOOLEAN((byte)0x55, "IGET-BOOLEAN", (byte)4, ReferenceType.field, "22c"),
|
IGET_BOOLEAN((byte)0x55, "iget-boolean", ReferenceType.field, Format.Format22c),
|
||||||
IGET_BYTE((byte)0x56, "IGET-BYTE", (byte)4, ReferenceType.field, "22c"),
|
IGET_BYTE((byte)0x56, "iget-byte", ReferenceType.field, Format.Format22c),
|
||||||
IGET_CHAR((byte)0x57, "IGET-CHAR", (byte)4, ReferenceType.field, "22c"),
|
IGET_CHAR((byte)0x57, "iget-char", ReferenceType.field, Format.Format22c),
|
||||||
IGET_SHORT((byte)0x58, "IGET-SHORT", (byte)4, ReferenceType.field, "22c"),
|
IGET_SHORT((byte)0x58, "iget-short", ReferenceType.field, Format.Format22c),
|
||||||
IPUT((byte)0x59, "IPUT", (byte)4, ReferenceType.field, "22c"),
|
IPUT((byte)0x59, "iput", ReferenceType.field, Format.Format22c),
|
||||||
IPUT_WIDE((byte)0x5a, "IPUT-WIDE", (byte)4, ReferenceType.field, "22c"),
|
IPUT_WIDE((byte)0x5a, "iput-wide", ReferenceType.field, Format.Format22c),
|
||||||
IPUT_OBJECT((byte)0x5b, "IPUT-OBJECT", (byte)4, ReferenceType.field, "22c"),
|
IPUT_OBJECT((byte)0x5b, "iput-object", ReferenceType.field, Format.Format22c),
|
||||||
IPUT_BOOLEAN((byte)0x5c, "IPUT-BOOLEAN", (byte)4, ReferenceType.field, "22c"),
|
IPUT_BOOLEAN((byte)0x5c, "iput-boolean", ReferenceType.field, Format.Format22c),
|
||||||
IPUT_BYTE((byte)0x5d, "IPUT-BYTE", (byte)4, ReferenceType.field, "22c"),
|
IPUT_BYTE((byte)0x5d, "iput-byte", ReferenceType.field, Format.Format22c),
|
||||||
IPUT_CHAR((byte)0x5e, "IPUT-CHAR", (byte)4, ReferenceType.field, "22c"),
|
IPUT_CHAR((byte)0x5e, "iput-char", ReferenceType.field, Format.Format22c),
|
||||||
IPUT_SHORT((byte)0x5f, "IPUT-SHORT", (byte)4, ReferenceType.field, "22c"),
|
IPUT_SHORT((byte)0x5f, "iput-short", ReferenceType.field, Format.Format22c),
|
||||||
SGET((byte)0x60, "SGET", (byte)4, ReferenceType.field, "21c"),
|
SGET((byte)0x60, "sget", ReferenceType.field, Format.Format21c),
|
||||||
SGET_WIDE((byte)0x61, "SGET-WIDE", (byte)4, ReferenceType.field, "21c"),
|
SGET_WIDE((byte)0x61, "sget-wide", ReferenceType.field, Format.Format21c),
|
||||||
SGET_OBJECT((byte)0x62, "SGET-OBJECT", (byte)4, ReferenceType.field, "21c"),
|
SGET_OBJECT((byte)0x62, "sget-object", ReferenceType.field, Format.Format21c),
|
||||||
SGET_BOOLEAN((byte)0x63, "SGET-BOOLEAN", (byte)4, ReferenceType.field, "21c"),
|
SGET_BOOLEAN((byte)0x63, "sget-boolean", ReferenceType.field, Format.Format21c),
|
||||||
SGET_BYTE((byte)0x64, "SGET-BYTE", (byte)4, ReferenceType.field, "21c"),
|
SGET_BYTE((byte)0x64, "sget-byte", ReferenceType.field, Format.Format21c),
|
||||||
SGET_CHAR((byte)0x65, "SGET-CHAR", (byte)4, ReferenceType.field, "21c"),
|
SGET_CHAR((byte)0x65, "sget-char", ReferenceType.field, Format.Format21c),
|
||||||
SGET_SHORT((byte)0x66, "SGET-SHORT", (byte)4, ReferenceType.field, "21c"),
|
SGET_SHORT((byte)0x66, "sget-short", ReferenceType.field, Format.Format21c),
|
||||||
SPUT((byte)0x67, "SPUT", (byte)4, ReferenceType.field, "21c"),
|
SPUT((byte)0x67, "sput", ReferenceType.field, Format.Format21c),
|
||||||
SPUT_WIDE((byte)0x68, "SPUT-WIDE", (byte)4, ReferenceType.field, "21c"),
|
SPUT_WIDE((byte)0x68, "sput-wide", ReferenceType.field, Format.Format21c),
|
||||||
SPUT_OBJECT((byte)0x69, "SPUT-OBJECT", (byte)4, ReferenceType.field, "21c"),
|
SPUT_OBJECT((byte)0x69, "sput-object", ReferenceType.field, Format.Format21c),
|
||||||
SPUT_BOOLEAN((byte)0x6a, "SPUT-BOOLEAN", (byte)4, ReferenceType.field, "21c"),
|
SPUT_BOOLEAN((byte)0x6a, "sput-boolean", ReferenceType.field, Format.Format21c),
|
||||||
SPUT_BYTE((byte)0x6b, "SPUT-BYTE", (byte)4, ReferenceType.field, "21c"),
|
SPUT_BYTE((byte)0x6b, "sput-byte", ReferenceType.field, Format.Format21c),
|
||||||
SPUT_CHAR((byte)0x6c, "SPUT-CHAR", (byte)4, ReferenceType.field, "21c"),
|
SPUT_CHAR((byte)0x6c, "sput-char", ReferenceType.field, Format.Format21c),
|
||||||
SPUT_SHORT((byte)0x6d, "SPUT-SHORT", (byte)4, ReferenceType.field, "21c"),
|
SPUT_SHORT((byte)0x6d, "sput-short", ReferenceType.field, Format.Format21c),
|
||||||
INVOKE_VIRTUAL((byte)0x6e, "INVOKE-VIRTUAL", (byte)6, ReferenceType.method, "35c"),
|
INVOKE_VIRTUAL((byte)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c),
|
||||||
INVOKE_SUPER((byte)0x6f, "INVOKE-SUPER", (byte)6, ReferenceType.method, "35c"),
|
INVOKE_SUPER((byte)0x6f, "invoke-super", ReferenceType.method, Format.Format35c),
|
||||||
INVOKE_DIRECT((byte)0x70, "INVOKE-DIRECT", (byte)6, ReferenceType.method, "35c"),
|
INVOKE_DIRECT((byte)0x70, "invoke-direct", ReferenceType.method, Format.Format35c),
|
||||||
INVOKE_STATIC((byte)0x71, "INVOKE-STATIC", (byte)6, ReferenceType.method, "35c"),
|
INVOKE_STATIC((byte)0x71, "invoke-static", ReferenceType.method, Format.Format35c),
|
||||||
INVOKE_INTERFACE((byte)0x72, "INVOKE-INTERFACE", (byte)6, ReferenceType.method, "35c"),
|
INVOKE_INTERFACE((byte)0x72, "invoke-interface", ReferenceType.method, Format.Format35c),
|
||||||
INVOKE_VIRTUAL_RANGE((byte)0x74, "INVOKE-VIRTUAL/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
INVOKE_VIRTUAL_RANGE((byte)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc),
|
||||||
INVOKE_SUPER_RANGE((byte)0x75, "INVOKE-SUPER/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
INVOKE_SUPER_RANGE((byte)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc),
|
||||||
INVOKE_DIRECT_RANGE((byte)0x76, "INVOKE-DIRECT/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
INVOKE_DIRECT_RANGE((byte)0x76, "invoke-direct/range", ReferenceType.method, Format.Format3rc),
|
||||||
INVOKE_STATIC_RANGE((byte)0x77, "INVOKE-STATIC/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
INVOKE_STATIC_RANGE((byte)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc),
|
||||||
INVOKE_INTERFACE_RANGE((byte)0x78, "INVOKE-INTERFACE/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
INVOKE_INTERFACE_RANGE((byte)0x78, "invoke-interface/range", ReferenceType.method, Format.Format3rc),
|
||||||
NEG_INT((byte)0x7b, "NEG-INT", (byte)2, ReferenceType.none, "12x"),
|
NEG_INT((byte)0x7b, "neg-int", ReferenceType.none, Format.Format12x),
|
||||||
NOT_INT((byte)0x7c, "NOT-INT", (byte)2, ReferenceType.none, "12x"),
|
NOT_INT((byte)0x7c, "not-int", ReferenceType.none, Format.Format12x),
|
||||||
NEG_LONG((byte)0x7d, "NEG-LONG", (byte)2, ReferenceType.none, "12x"),
|
NEG_LONG((byte)0x7d, "neg-long", ReferenceType.none, Format.Format12x),
|
||||||
NOT_LONG((byte)0x7e, "NOT-LONG", (byte)2, ReferenceType.none, "12x"),
|
NOT_LONG((byte)0x7e, "not-long", ReferenceType.none, Format.Format12x),
|
||||||
NEG_FLOAT((byte)0x7f, "NEG-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
NEG_FLOAT((byte)0x7f, "neg-float", ReferenceType.none, Format.Format12x),
|
||||||
NEG_DOUBLE((byte)0x80, "NEG-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
NEG_DOUBLE((byte)0x80, "neg-double", ReferenceType.none, Format.Format12x),
|
||||||
INT_TO_LONG((byte)0x81, "INT-TO-LONG", (byte)2, ReferenceType.none, "12x"),
|
INT_TO_LONG((byte)0x81, "int-to-long", ReferenceType.none, Format.Format12x),
|
||||||
INT_TO_FLOAT((byte)0x82, "INT-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
INT_TO_FLOAT((byte)0x82, "int-to-float", ReferenceType.none, Format.Format12x),
|
||||||
INT_TO_DOUBLE((byte)0x83, "INT-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
INT_TO_DOUBLE((byte)0x83, "int-to-double", ReferenceType.none, Format.Format12x),
|
||||||
LONG_TO_INT((byte)0x84, "LONG-TO-INT", (byte)2, ReferenceType.none, "12x"),
|
LONG_TO_INT((byte)0x84, "long-to-int", ReferenceType.none, Format.Format12x),
|
||||||
LONG_TO_FLOAT((byte)0x85, "LONG-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
LONG_TO_FLOAT((byte)0x85, "long-to-float", ReferenceType.none, Format.Format12x),
|
||||||
LONG_TO_DOUBLE((byte)0x86, "LONG-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
LONG_TO_DOUBLE((byte)0x86, "long-to-double", ReferenceType.none, Format.Format12x),
|
||||||
FLOAT_TO_INT((byte)0x87, "FLOAT-TO-INT", (byte)2, ReferenceType.none, "12x"),
|
FLOAT_TO_INT((byte)0x87, "float-to-int", ReferenceType.none, Format.Format12x),
|
||||||
FLOAT_TO_LONG((byte)0x88, "FLOAT-TO-LONG", (byte)2, ReferenceType.none, "12x"),
|
FLOAT_TO_LONG((byte)0x88, "float-to-long", ReferenceType.none, Format.Format12x),
|
||||||
FLOAT_TO_DOUBLE((byte)0x89, "FLOAT-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
FLOAT_TO_DOUBLE((byte)0x89, "float-to-double", ReferenceType.none, Format.Format12x),
|
||||||
DOUBLE_TO_INT((byte)0x8a, "DOUBLE-TO-INT", (byte)2, ReferenceType.none, "12x"),
|
DOUBLE_TO_INT((byte)0x8a, "double-to-int", ReferenceType.none, Format.Format12x),
|
||||||
DOUBLE_TO_LONG((byte)0x8b, "DOUBLE-TO-LONG", (byte)2, ReferenceType.none, "12x"),
|
DOUBLE_TO_LONG((byte)0x8b, "double-to-long", ReferenceType.none, Format.Format12x),
|
||||||
DOUBLE_TO_FLOAT((byte)0x8c, "DOUBLE-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
DOUBLE_TO_FLOAT((byte)0x8c, "double-to-float", ReferenceType.none, Format.Format12x),
|
||||||
INT_TO_BYTE((byte)0x8d, "INT-TO-BYTE", (byte)2, ReferenceType.none, "12x"),
|
INT_TO_BYTE((byte)0x8d, "int-to-byte", ReferenceType.none, Format.Format12x),
|
||||||
INT_TO_CHAR((byte)0x8e, "INT-TO-CHAR", (byte)2, ReferenceType.none, "12x"),
|
INT_TO_CHAR((byte)0x8e, "int-to-char", ReferenceType.none, Format.Format12x),
|
||||||
INT_TO_SHORT((byte)0x8f, "INT-TO-SHORT", (byte)2, ReferenceType.none, "12x"),
|
INT_TO_SHORT((byte)0x8f, "int-to-short", ReferenceType.none, Format.Format12x),
|
||||||
ADD_INT((byte)0x90, "ADD-INT", (byte)4, ReferenceType.none, "23x"),
|
ADD_INT((byte)0x90, "add-int", ReferenceType.none, Format.Format23x),
|
||||||
SUB_INT((byte)0x91, "SUB-INT", (byte)4, ReferenceType.none, "23x"),
|
SUB_INT((byte)0x91, "sub-int", ReferenceType.none, Format.Format23x),
|
||||||
MUL_INT((byte)0x92, "MUL-INT", (byte)4, ReferenceType.none, "23x"),
|
MUL_INT((byte)0x92, "mul-int", ReferenceType.none, Format.Format23x),
|
||||||
DIV_INT((byte)0x93, "DIV-INT", (byte)4, ReferenceType.none, "23x"),
|
DIV_INT((byte)0x93, "div-int", ReferenceType.none, Format.Format23x),
|
||||||
REM_INT((byte)0x94, "REM-INT", (byte)4, ReferenceType.none, "23x"),
|
REM_INT((byte)0x94, "rem-int", ReferenceType.none, Format.Format23x),
|
||||||
AND_INT((byte)0x95, "AND-INT", (byte)4, ReferenceType.none, "23x"),
|
AND_INT((byte)0x95, "and-int", ReferenceType.none, Format.Format23x),
|
||||||
OR_INT((byte)0x96, "OR-INT", (byte)4, ReferenceType.none, "23x"),
|
OR_INT((byte)0x96, "or-int", ReferenceType.none, Format.Format23x),
|
||||||
XOR_INT((byte)0x97, "XOR-INT", (byte)4, ReferenceType.none, "23x"),
|
XOR_INT((byte)0x97, "xor-int", ReferenceType.none, Format.Format23x),
|
||||||
SHL_INT((byte)0x98, "SHL-INT", (byte)4, ReferenceType.none, "23x"),
|
SHL_INT((byte)0x98, "shl-int", ReferenceType.none, Format.Format23x),
|
||||||
SHR_INT((byte)0x99, "SHR-INT", (byte)4, ReferenceType.none, "23x"),
|
SHR_INT((byte)0x99, "shr-int", ReferenceType.none, Format.Format23x),
|
||||||
USHR_INT((byte)0x9a, "USHR-INT", (byte)4, ReferenceType.none, "23x"),
|
USHR_INT((byte)0x9a, "ushr-int", ReferenceType.none, Format.Format23x),
|
||||||
ADD_LONG((byte)0x9b, "ADD-LONG", (byte)4, ReferenceType.none, "23x"),
|
ADD_LONG((byte)0x9b, "add-long", ReferenceType.none, Format.Format23x),
|
||||||
SUB_LONG((byte)0x9c, "SUB-LONG", (byte)4, ReferenceType.none, "23x"),
|
SUB_LONG((byte)0x9c, "sub-long", ReferenceType.none, Format.Format23x),
|
||||||
MUL_LONG((byte)0x9d, "MUL-LONG", (byte)4, ReferenceType.none, "23x"),
|
MUL_LONG((byte)0x9d, "mul-long", ReferenceType.none, Format.Format23x),
|
||||||
DIV_LONG((byte)0x9e, "DIV-LONG", (byte)4, ReferenceType.none, "23x"),
|
DIV_LONG((byte)0x9e, "div-long", ReferenceType.none, Format.Format23x),
|
||||||
REM_LONG((byte)0x9f, "REM-LONG", (byte)4, ReferenceType.none, "23x"),
|
REM_LONG((byte)0x9f, "rem-long", ReferenceType.none, Format.Format23x),
|
||||||
AND_LONG((byte)0xa0, "AND-LONG", (byte)4, ReferenceType.none, "23x"),
|
AND_LONG((byte)0xa0, "and-long", ReferenceType.none, Format.Format23x),
|
||||||
OR_LONG((byte)0xa1, "OR-LONG", (byte)4, ReferenceType.none, "23x"),
|
OR_LONG((byte)0xa1, "or-long", ReferenceType.none, Format.Format23x),
|
||||||
XOR_LONG((byte)0xa2, "XOR-LONG", (byte)4, ReferenceType.none, "23x"),
|
XOR_LONG((byte)0xa2, "xor-long", ReferenceType.none, Format.Format23x),
|
||||||
SHL_LONG((byte)0xa3, "SHL-LONG", (byte)4, ReferenceType.none, "23x"),
|
SHL_LONG((byte)0xa3, "shl-long", ReferenceType.none, Format.Format23x),
|
||||||
SHR_LONG((byte)0xa4, "SHR-LONG", (byte)4, ReferenceType.none, "23x"),
|
SHR_LONG((byte)0xa4, "shr-long", ReferenceType.none, Format.Format23x),
|
||||||
USHR_LONG((byte)0xa5, "USHR-LONG", (byte)4, ReferenceType.none, "23x"),
|
USHR_LONG((byte)0xa5, "ushr-long", ReferenceType.none, Format.Format23x),
|
||||||
ADD_FLOAT((byte)0xa6, "ADD-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
ADD_FLOAT((byte)0xa6, "add-float", ReferenceType.none, Format.Format23x),
|
||||||
SUB_FLOAT((byte)0xa7, "SUB-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
SUB_FLOAT((byte)0xa7, "sub-float", ReferenceType.none, Format.Format23x),
|
||||||
MUL_FLOAT((byte)0xa8, "MUL-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
MUL_FLOAT((byte)0xa8, "mul-float", ReferenceType.none, Format.Format23x),
|
||||||
DIV_FLOAT((byte)0xa9, "DIV-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
DIV_FLOAT((byte)0xa9, "div-float", ReferenceType.none, Format.Format23x),
|
||||||
REM_FLOAT((byte)0xaa, "REM-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
REM_FLOAT((byte)0xaa, "rem-float", ReferenceType.none, Format.Format23x),
|
||||||
ADD_DOUBLE((byte)0xab, "ADD-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
ADD_DOUBLE((byte)0xab, "add-double", ReferenceType.none, Format.Format23x),
|
||||||
SUB_DOUBLE((byte)0xac, "SUB-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
SUB_DOUBLE((byte)0xac, "sub-double", ReferenceType.none, Format.Format23x),
|
||||||
MUL_DOUBLE((byte)0xad, "MUL-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
MUL_DOUBLE((byte)0xad, "mul-double", ReferenceType.none, Format.Format23x),
|
||||||
DIV_DOUBLE((byte)0xae, "DIV-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
DIV_DOUBLE((byte)0xae, "div-double", ReferenceType.none, Format.Format23x),
|
||||||
REM_DOUBLE((byte)0xaf, "REM-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
REM_DOUBLE((byte)0xaf, "rem-double", ReferenceType.none, Format.Format23x),
|
||||||
ADD_INT_2ADDR((byte)0xb0, "ADD-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
ADD_INT_2ADDR((byte)0xb0, "add-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SUB_INT_2ADDR((byte)0xb1, "SUB-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SUB_INT_2ADDR((byte)0xb1, "sub-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
MUL_INT_2ADDR((byte)0xb2, "MUL-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
MUL_INT_2ADDR((byte)0xb2, "mul-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
DIV_INT_2ADDR((byte)0xb3, "DIV-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
DIV_INT_2ADDR((byte)0xb3, "div-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
REM_INT_2ADDR((byte)0xb4, "REM-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
REM_INT_2ADDR((byte)0xb4, "rem-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
AND_INT_2ADDR((byte)0xb5, "AND-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
AND_INT_2ADDR((byte)0xb5, "and-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
OR_INT_2ADDR((byte)0xb6, "OR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
OR_INT_2ADDR((byte)0xb6, "or-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
XOR_INT_2ADDR((byte)0xb7, "XOR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
XOR_INT_2ADDR((byte)0xb7, "xor-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SHL_INT_2ADDR((byte)0xb8, "SHL-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SHL_INT_2ADDR((byte)0xb8, "shl-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SHR_INT_2ADDR((byte)0xb9, "SHR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SHR_INT_2ADDR((byte)0xb9, "shr-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
USHR_INT_2ADDR((byte)0xba, "USHR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
USHR_INT_2ADDR((byte)0xba, "ushr-int/2addr", ReferenceType.none, Format.Format12x),
|
||||||
ADD_LONG_2ADDR((byte)0xbb, "ADD-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
ADD_LONG_2ADDR((byte)0xbb, "add-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SUB_LONG_2ADDR((byte)0xbc, "SUB-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SUB_LONG_2ADDR((byte)0xbc, "sub-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
MUL_LONG_2ADDR((byte)0xbd, "MUL-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
MUL_LONG_2ADDR((byte)0xbd, "mul-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
DIV_LONG_2ADDR((byte)0xbe, "DIV-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
DIV_LONG_2ADDR((byte)0xbe, "div-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
REM_LONG_2ADDR((byte)0xbf, "REM-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
REM_LONG_2ADDR((byte)0xbf, "rem-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
AND_LONG_2ADDR((byte)0xc0, "AND-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
AND_LONG_2ADDR((byte)0xc0, "and-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
OR_LONG_2ADDR((byte)0xc1, "OR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
OR_LONG_2ADDR((byte)0xc1, "or-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
XOR_LONG_2ADDR((byte)0xc2, "XOR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
XOR_LONG_2ADDR((byte)0xc2, "xor-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SHL_LONG_2ADDR((byte)0xc3, "SHL-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SHL_LONG_2ADDR((byte)0xc3, "shl-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SHR_LONG_2ADDR((byte)0xc4, "SHR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SHR_LONG_2ADDR((byte)0xc4, "shr-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
USHR_LONG_2ADDR((byte)0xc5, "USHR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
USHR_LONG_2ADDR((byte)0xc5, "ushr-long/2addr", ReferenceType.none, Format.Format12x),
|
||||||
ADD_FLOAT_2ADDR((byte)0xc6, "ADD-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
ADD_FLOAT_2ADDR((byte)0xc6, "add-float/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SUB_FLOAT_2ADDR((byte)0xc7, "SUB-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SUB_FLOAT_2ADDR((byte)0xc7, "sub-float/2addr", ReferenceType.none, Format.Format12x),
|
||||||
MUL_FLOAT_2ADDR((byte)0xc8, "MUL-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
MUL_FLOAT_2ADDR((byte)0xc8, "mul-float/2addr", ReferenceType.none, Format.Format12x),
|
||||||
DIV_FLOAT_2ADDR((byte)0xc9, "DIV-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
DIV_FLOAT_2ADDR((byte)0xc9, "div-float/2addr", ReferenceType.none, Format.Format12x),
|
||||||
REM_FLOAT_2ADDR((byte)0xca, "REM-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
REM_FLOAT_2ADDR((byte)0xca, "rem-float/2addr", ReferenceType.none, Format.Format12x),
|
||||||
ADD_DOUBLE_2ADDR((byte)0xcb, "ADD-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
ADD_DOUBLE_2ADDR((byte)0xcb, "add-double/2addr", ReferenceType.none, Format.Format12x),
|
||||||
SUB_DOUBLE_2ADDR((byte)0xcc, "SUB-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
SUB_DOUBLE_2ADDR((byte)0xcc, "sub-double/2addr", ReferenceType.none, Format.Format12x),
|
||||||
MUL_DOUBLE_2ADDR((byte)0xcd, "MUL-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
MUL_DOUBLE_2ADDR((byte)0xcd, "mul-double/2addr", ReferenceType.none, Format.Format12x),
|
||||||
DIV_DOUBLE_2ADDR((byte)0xce, "DIV-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
DIV_DOUBLE_2ADDR((byte)0xce, "div-double/2addr", ReferenceType.none, Format.Format12x),
|
||||||
REM_DOUBLE_2ADDR((byte)0xcf, "REM-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
REM_DOUBLE_2ADDR((byte)0xcf, "rem-double/2addr", ReferenceType.none, Format.Format12x),
|
||||||
ADD_INT_LIT16((byte)0xd0, "ADD-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
ADD_INT_LIT16((byte)0xd0, "add-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
RSUB_INT((byte)0xd1, "RSUB-INT", (byte)4, ReferenceType.none, "22s"),
|
RSUB_INT((byte)0xd1, "rsub-int", ReferenceType.none, Format.Format22s),
|
||||||
MUL_INT_LIT16((byte)0xd2, "MUL-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
MUL_INT_LIT16((byte)0xd2, "mul-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
DIV_INT_LIT16((byte)0xd3, "DIV-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
DIV_INT_LIT16((byte)0xd3, "div-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
REM_INT_LIT16((byte)0xd4, "REM-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
REM_INT_LIT16((byte)0xd4, "rem-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
AND_INT_LIT16((byte)0xd5, "AND-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
AND_INT_LIT16((byte)0xd5, "and-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
OR_INT_LIT16((byte)0xd6, "OR-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
OR_INT_LIT16((byte)0xd6, "or-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
XOR_INT_LIT16((byte)0xd7, "XOR-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
XOR_INT_LIT16((byte)0xd7, "xor-int/lit16", ReferenceType.none, Format.Format22s),
|
||||||
ADD_INT_LIT8((byte)0xd8, "ADD-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
ADD_INT_LIT8((byte)0xd8, "add-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
RSUB_INT_LIT8((byte)0xd9, "RSUB-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
RSUB_INT_LIT8((byte)0xd9, "rsub-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
MUL_INT_LIT8((byte)0xda, "MUL-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
MUL_INT_LIT8((byte)0xda, "mul-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
DIV_INT_LIT8((byte)0xdb, "DIV-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
DIV_INT_LIT8((byte)0xdb, "div-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
REM_INT_LIT8((byte)0xdc, "REM-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
REM_INT_LIT8((byte)0xdc, "rem-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
AND_INT_LIT8((byte)0xdd, "AND-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
AND_INT_LIT8((byte)0xdd, "and-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
OR_INT_LIT8((byte)0xde, "OR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
OR_INT_LIT8((byte)0xde, "or-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
XOR_INT_LIT8((byte)0xdf, "XOR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
XOR_INT_LIT8((byte)0xdf, "xor-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
SHL_INT_LIT8((byte)0xe0, "SHL-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
SHL_INT_LIT8((byte)0xe0, "shl-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
SHR_INT_LIT8((byte)0xe1, "SHR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
SHR_INT_LIT8((byte)0xe1, "shr-int/lit8", ReferenceType.none, Format.Format22b),
|
||||||
USHR_INT_LIT8((byte)0xe2, "USHR-INT/LIT8", (byte)4, ReferenceType.none, "22b");
|
USHR_INT_LIT8((byte)0xe2, "ushr-int/lit8", ReferenceType.none, Format.Format22b);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -269,7 +271,7 @@ public enum Opcode
|
|||||||
|
|
||||||
for (Opcode opcode: Opcode.values()) {
|
for (Opcode opcode: Opcode.values()) {
|
||||||
opcodesByValue.set((opcode.value & 0xFF), opcode);
|
opcodesByValue.set((opcode.value & 0xFF), opcode);
|
||||||
opcodesByName.put(opcode.name.toLowerCase().hashCode(), opcode);
|
opcodesByName.put(opcode.name.hashCode(), opcode);
|
||||||
}
|
}
|
||||||
}catch (Exception ex) {
|
}catch (Exception ex) {
|
||||||
System.out.println(ex.toString());
|
System.out.println(ex.toString());
|
||||||
@ -286,14 +288,12 @@ public enum Opcode
|
|||||||
|
|
||||||
public final byte value;
|
public final byte value;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final byte numBytes;
|
|
||||||
public final ReferenceType referenceType;
|
public final ReferenceType referenceType;
|
||||||
public final String format;
|
public final Format format;
|
||||||
|
|
||||||
Opcode(byte opcodeValue, String opcodeName, byte numBytes, ReferenceType referenceType, String format) {
|
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format) {
|
||||||
this.value = opcodeValue;
|
this.value = opcodeValue;
|
||||||
this.name = opcodeName;
|
this.name = opcodeName;
|
||||||
this.numBytes = numBytes;
|
|
||||||
this.referenceType = referenceType;
|
this.referenceType = referenceType;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
}
|
}
|
||||||
|
78
src/main/java/org/jf/dexlib/util/NumberUtils.java
Normal file
78
src/main/java/org/jf/dexlib/util/NumberUtils.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2009 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib.util;
|
||||||
|
|
||||||
|
public class NumberUtils {
|
||||||
|
|
||||||
|
public static byte decodeHighSignedNibble(byte b) {
|
||||||
|
return (byte)(b >> 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte decodeHighUnsignedNibble(byte b) {
|
||||||
|
return (byte)((b & 0xFF) >>> 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte decodeLowUnsignedNibble(byte b) {
|
||||||
|
return (byte)(b & 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short decodeUnsignedByte(byte b) {
|
||||||
|
return (short)(b & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short decodeShort(byte lsb, byte msb) {
|
||||||
|
return (short)
|
||||||
|
( lsb |
|
||||||
|
(msb << 8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int decodeUnsignedShort(byte lsb, byte msb) {
|
||||||
|
return ((msb & 0xFF) << 8) |
|
||||||
|
(lsb & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int decodeInt(byte lsb, byte mlsb, byte mmsb, byte msb) {
|
||||||
|
return lsb |
|
||||||
|
(mlsb << 8) |
|
||||||
|
(mmsb << 16) |
|
||||||
|
(msb << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long decodeLong(byte[] array, int startIndex) {
|
||||||
|
return array[startIndex++] |
|
||||||
|
(array[startIndex++] >> 8) |
|
||||||
|
(array[startIndex++] >> 16) |
|
||||||
|
(array[startIndex++] >> 24) |
|
||||||
|
((long)array[startIndex++] >> 32) |
|
||||||
|
((long)array[startIndex++] >> 40) |
|
||||||
|
((long)array[startIndex++] >> 48) |
|
||||||
|
((long)array[startIndex++] >> 56);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user