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:
JesusFreke@JesusFreke.com 2009-06-11 06:11:11 +00:00
parent 0e91ee0cc2
commit 67a4c3cbb2
41 changed files with 2263 additions and 1428 deletions

View File

@ -323,91 +323,91 @@ instruction returns [int size]
@init {boolean needsNop = false; int targetCount = 0;}
: //e.g. goto endloop:
//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?)
| //e.g. return
INSTRUCTION_FORMAT10x {$size = Format10x.Format.getByteCount();}
INSTRUCTION_FORMAT10x {$size = Format.Format10x.size;}
-> ^(I_STATEMENT_FORMAT10x[$start, "I_STATEMENT_FORMAT10x"] INSTRUCTION_FORMAT10x)
| //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)
| //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)
| //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)
| //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?)
| //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)
| //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)
| //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)
| //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)
| //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)
| //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?)
| //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)
| //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)
| //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)
| //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)
| //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?)
| //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)
| //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)
| //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?)
| //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)
| //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)
| //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?)
| //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)
| //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)
| //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)
| //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)
| //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)
| //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)
|
ARRAY_DATA_DIRECTIVE

View File

@ -401,7 +401,7 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod,
annotations
)
{
ArrayList<Instruction> instructions = $statements.instructions;
ArrayList<InstructionField> instructions = $statements.instructions;
Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> temp = $method::tryList.encodeTries(dexFile);
List<CodeItem.TryItem> tries = temp.first;
@ -640,16 +640,16 @@ source
$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
{
$instructions = new ArrayList<Instruction>();
$instructions = new ArrayList<InstructionField>();
}
: ^(I_STATEMENTS (instruction[$totalMethodRegisters, $methodParameterRegisters]
{
if ($instruction.instruction != null) {
$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;}
| 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:
^(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].");
}
$instruction = Format10t.Format.make(dexFile, opcode.value, (byte)addressOffset);
$instruction = new InstructionField(dexFile, new Instruction10t(dexFile, opcode, (byte)addressOffset));
}
| //e.g. return
^(I_STATEMENT_FORMAT10x INSTRUCTION_FORMAT10x)
{
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
^(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;
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
^(I_STATEMENT_FORMAT11x INSTRUCTION_FORMAT11x REGISTER)
@ -727,7 +727,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT11x.text);
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
^(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 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:
^(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].");
}
$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;
^(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;
$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!"
^(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);
$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
^(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;
$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
^(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;
$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
^(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;
$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:
^(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].");
}
$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
^(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;
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;
^(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;
$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;
^(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;
$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
^(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;
$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:
^(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].");
}
$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
^(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);
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
^(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 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:
^(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;
$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!"
^(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);
$instruction = Format31c.Format.make(dexFile, opcode.value, regA, stringIdItem);
$instruction = new InstructionField(dexFile, new Instruction31c(dexFile, opcode, regA, stringIdItem));
}
| //e.g. const v0, 123456
^(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;
$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:
^(I_STATEMENT_FORMAT31t INSTRUCTION_FORMAT31t REGISTER offset_or_label)
@ -935,7 +935,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
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
^(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 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
^(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;
$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
^(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;
$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;
^(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;
//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
^(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;
//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
^(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;
$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
^(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;
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[] 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])
@ -1045,7 +1045,7 @@ instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Ins
int[] keys = $sparse_switch_keys.keys;
int[] targets = $sparse_switch_targets.targets;
$instruction = SparseSwitchData.make(dexFile, keys, targets);
$instruction = new InstructionField(dexFile, new SparseSwitchDataPseudoInstruction(dexFile, keys, targets));
};
catch [Exception ex] {
reportError(new SemanticException(input, ex));

View File

@ -30,6 +30,7 @@ package org.jf.dexlib;
import org.jf.dexlib.code.Instruction;
import org.jf.dexlib.code.Opcode;
import org.jf.dexlib.code.InstructionField;
import org.jf.dexlib.ItemType;
import org.jf.dexlib.util.Input;
import org.jf.dexlib.util.AnnotatedOutput;
@ -39,7 +40,7 @@ import java.util.List;
import java.util.HashMap;
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<EncodedCatchHandler> catchHandlerList = new ArrayList<EncodedCatchHandler>();
@ -57,7 +58,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
public CodeItem(final DexFile dexFile, int offset) {
super(offset);
instructionList = new ArrayList<Instruction>();
instructionList = new ArrayList<InstructionField>();
fields = new Field[] {
registersCountField = new ShortIntegerField("registers_size"),
@ -82,7 +83,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
public CodeItem(final DexFile dexFile,
int registersCount,
int inArguments,
List<Instruction> instructions,
List<InstructionField> instructions,
DebugInfoItem debugInfo,
List<TryItem> tries,
List<EncodedCatchHandler> handlers) {
@ -447,7 +448,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
public void writeTo(AnnotatedOutput out) {
int startPosition = out.getCursor();
for (Instruction instruction: instructionList) {
for (InstructionField instruction: instructionList) {
instruction.writeTo(out);
}
if ((out.getCursor() - startPosition) != (instructionsSizeField.getCachedValue() * 2)) {
@ -460,7 +461,7 @@ public class CodeItem extends OffsettedItem<CodeItem> {
int startPosition = in.getCursor();
do {
Instruction instruction = new Instruction(dexFile);
InstructionField instruction = new InstructionField(dexFile);
instruction.readFrom(in);
instructionList.add(instruction);
} while (in.getCursor() - startPosition < numBytes);
@ -475,23 +476,23 @@ public class CodeItem extends OffsettedItem<CodeItem> {
}
public void copyTo(DexFile dexFile, InstructionListField copy) {
ArrayList<Instruction> copyInstructionList = copy.getInstructionList();
ArrayList<InstructionField> copyInstructionList = copy.getInstructionList();
copyInstructionList.clear();
for (Instruction instruction: instructionList) {
Instruction instructionCopy = new Instruction(dexFile);
for (InstructionField instruction: instructionList) {
InstructionField instructionCopy = new InstructionField(dexFile);
instruction.copyTo(dexFile, instructionCopy);
copyInstructionList.add(instructionCopy);
}
}
private ArrayList<Instruction> getInstructionList() {
private ArrayList<InstructionField> getInstructionList() {
return instructionList;
}
//return the word size of the instruction list
public int getInstructionWordCount() {
int bytes = 0;
for (Instruction instruction: instructionList) {
for (InstructionField instruction: instructionList) {
bytes += instruction.getSize(bytes);
}
return bytes/2;
@ -500,11 +501,11 @@ public class CodeItem extends OffsettedItem<CodeItem> {
//return the highest parameter word count of any method invokation
public int getOutArguments() {
int maxParamWordCount = 0;
for (Instruction instruction: instructionList) {
IndexedItem item = instruction.getReference();
for (InstructionField instruction: instructionList) {
IndexedItem item = instruction.getInstruction().getReferencedItem();
if (item instanceof MethodIdItem) {
MethodIdItem methodIdItem = (MethodIdItem)item;
Opcode opcode = instruction.getOpcode();
Opcode opcode = instruction.getInstruction().getOpcode();
boolean isStatic = false;
if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -28,16 +28,43 @@
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();
public abstract String getFormatName();
Format10t(Instruction10t.Factory, 2),
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) {
if (!opcode.format.equals(getFormatName())) {
throw new RuntimeException("Opcode " + opcode.name + " does not use format " + getFormatName());
}
public final Instruction.InstructionFactory Factory;
public final int size;
private Format(Instruction.InstructionFactory factory, int size) {
this.Factory = factory;
this.size = size;
}
}

View File

@ -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";
}
}

View File

@ -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";
}
}

View File

@ -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";
}
}

View File

@ -31,33 +31,51 @@ 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;
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 Instruction make(DexFile dexFile, byte opcode, byte offA) {
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction10t(DexFile dexFile, Opcode opcode, byte offA) {
super(dexFile, opcode, (IndexedItem)null);
if (offA == 0) {
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()
{
return 2;
private Instruction10t(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
}
public String getFormatName()
{
return "10t";
private Instruction10t() {
}
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];
}
}

View File

@ -32,41 +32,40 @@ 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;
public class Format21c extends Format
public class Instruction10x extends Instruction
{
public static final Format21c Format = new Format21c();
public static final InstructionFactory Factory = new Factory();
private Format21c() {
public Instruction10x(DexFile dexFile, Opcode opcode) {
super(dexFile, opcode, (IndexedItem)null);
encodedInstruction = new byte[2];
encodedInstruction[0] = opcode.value;
}
public Instruction make(DexFile dexFile, byte opcode, short regA, IndexedItem item) {
byte[] bytes = new byte[4];
public Instruction10x(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
if (regA >= 1<<8) {
throw new RuntimeException("The register number must be less than v256");
if (rest[0] != 0x00) {
throw new RuntimeException("The second byte of the instruction must be 0");
}
}
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");
private Instruction10x() {
}
public Format getFormat() {
return Format.Format10x;
}
protected Instruction makeClone() {
return new Instruction10x();
}
private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] rest) {
return new Instruction10x(dexFile, opcode, rest);
}
bytes[0] = opcode;
bytes[1] = (byte)regA;
return new Instruction(dexFile, bytes, item);
}
public int getByteCount() {
return 4;
}
public String getFormatName() {
return "21c";
}
}

View File

@ -31,21 +31,15 @@ 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 Format11n extends Format
public class Instruction11n extends Instruction
{
public static final Format11n Format = new Format11n();
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 static final InstructionFactory Factory = new Factory();
public Instruction11n(DexFile dexFile, Opcode opcode, byte regA, byte litB) {
super(dexFile, opcode, (IndexedItem)null);
if (regA >= 1<<4) {
throw new RuntimeException("The register number must be less than v16");
@ -56,20 +50,38 @@ public class Format11n extends Format
throw new RuntimeException("The literal value must be between -8 and 7 inclusive");
}
bytes[0] = opcode;
bytes[1] = (byte)((litB << 4) | regA);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[2];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)((litB << 4) | regA);
}
public int getByteCount()
{
return 2;
private Instruction11n(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName()
{
return "11n";
private Instruction11n() {
}
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]);
}
}

View File

@ -32,36 +32,47 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, IndexedItem item) {
byte[] bytes = new byte[6];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction11x(DexFile dexFile, Opcode opcode, short regA) {
super(dexFile, opcode, (IndexedItem)null);
if (regA >= 1<<8) {
throw new RuntimeException("The register number must be less than v256");
}
bytes[0] = opcode;
bytes[1] = (byte)regA;
return new Instruction(dexFile, bytes, item);
encodedInstruction = new byte[2];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
}
public int getByteCount() {
return 6;
private Instruction11x(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName() {
return "31c";
private Instruction11x() {
}
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]);
}
}

View File

@ -32,38 +32,52 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB, IndexedItem item) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction12x(DexFile dexFile, Opcode opcode, byte regA, byte regB) {
super(dexFile, opcode, (IndexedItem)null);
if (regA >= 1<<4 ||
regB >= 1<<4) {
throw new RuntimeException("The register number must be less than v16");
}
bytes[0] = opcode;
bytes[1] = (byte)((regB << 4) | regA);
return new Instruction(dexFile, bytes, item);
encodedInstruction = new byte[2];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)((regB << 4) | regA);
}
public int getByteCount() {
return 4;
private Instruction12x(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName() {
return "22c";
private Instruction12x() {
}
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]);
}
}

View File

@ -31,39 +31,53 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short offA) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction20t(DexFile dexFile, Opcode opcode, short offA) {
super(dexFile, opcode, (IndexedItem)null);
if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
bytes[0] = opcode;
bytes[2] = (byte)offA;
bytes[3] = (byte)(offA >> 8);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[2] = (byte)offA;
encodedInstruction[3] = (byte)(offA>>8);
}
public int getByteCount()
{
return 4;
private Instruction20t(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
}
public String getFormatName()
{
return "20t";
private Instruction20t() {
}
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]);
}
}

View 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]);
}
}

View File

@ -31,40 +31,54 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, short litB) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction21h(DexFile dexFile, Opcode opcode, short regA, short litB) {
super(dexFile, opcode, (IndexedItem)null);
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)litB;
bytes[3] = (byte)(litB >> 8);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)litB;
encodedInstruction[3] = (byte)(litB >> 8);
}
public int getByteCount()
{
return 4;
private Instruction21h(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName()
{
return "21h";
private Instruction21h() {
}
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]);
}
}

View File

@ -31,40 +31,54 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, short litB) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction21s(DexFile dexFile, Opcode opcode, short regA, short litB) {
super(dexFile, opcode, (IndexedItem)null);
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)litB;
bytes[3] = (byte)(litB >> 8);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)litB;
encodedInstruction[3] = (byte)(litB >> 8);
}
public int getByteCount()
{
return 4;
private Instruction21s(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName()
{
return "21s";
private Instruction21s() {
}
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]);
}
}

View File

@ -31,44 +31,62 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, short offB) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction21t(DexFile dexFile, Opcode opcode, short regA, short offB) {
super(dexFile, opcode, (IndexedItem)null);
if (regA >= 1<<8) {
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.");
}
bytes[0] = opcode;
bytes[1] = (byte)regA;
bytes[2] = (byte)offB;
bytes[3] = (byte)(offB >> 8);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)offB;
encodedInstruction[3] = (byte)(offB >> 8);
}
public int getByteCount()
{
return 4;
private Instruction21t(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
}
public String getFormatName()
{
return "21t";
private Instruction21t() {
}
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]);
}
}

View 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];
}
}

View File

@ -31,39 +31,54 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB) {
byte[] bytes = new byte[2];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction22c(DexFile dexFile, Opcode opcode, byte regA, byte regB, IndexedItem item) {
super(dexFile, opcode, item);
if (regA >= 1<<4 ||
regB >= 1<<4) {
throw new RuntimeException("The register number must be less than v16");
}
bytes[0] = opcode;
bytes[1] = (byte)((regB << 4) | regA);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)((regB << 4) | regA);
//the item index will be set later, during placement/writing
}
public int getByteCount()
{
return 2;
private Instruction22c(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName()
{
return "12x";
private Instruction22c() {
}
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]);
}
}

View File

@ -31,44 +31,59 @@ 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 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) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
if (regA >= 1<<4) {
if (regA >= 1<<4 ||
regB >= 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");
encodedInstruction = new byte[4];
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()
{
return 4;
public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(encodedInstruction[1]);
}
public String getFormatName()
{
return "22s";
public byte getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(encodedInstruction[1]);
}
public short getLiteral() {
return NumberUtils.decodeShort(encodedInstruction[2], encodedInstruction[3]);
}
}

View File

@ -31,26 +31,18 @@ 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 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) {
byte[] bytes = new byte[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) {
if (regA >= 1<<4 ||
regB >= 1<<4) {
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.");
}
bytes[0] = opcode;
bytes[1] = (byte)((regB << 4) | regA);
bytes[2] = (byte)offC;
bytes[3] = (byte)(offC >> 8);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)((regB << 4) | regA);
encodedInstruction[2] = (byte)offC;
encodedInstruction[3] = (byte)(offC >> 8);
}
public int getByteCount() {
return 4;
private Instruction22t(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
}
public String getFormatName() {
return "22t";
private Instruction22t() {
}
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]);
}
}

View File

@ -31,42 +31,58 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, int regB) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction22x(DexFile dexFile, Opcode opcode, short regA, int regB) {
super(dexFile, opcode, (IndexedItem)null);
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) {
throw new RuntimeException("The register number must be less than v65536");
}
bytes[0] = opcode;
bytes[1] = (byte)regA;
bytes[2] = (byte)regB;
bytes[3] = (byte)(regB >> 8);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)regB;
encodedInstruction[3] = (byte)(regB >> 8);
}
public int getByteCount() {
return 4;
private Instruction22x(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName() {
return "22x";
private Instruction22x() {
}
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]);
}
}

View File

@ -31,46 +31,60 @@ 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 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) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
if (regA >= 1<<8) {
if (regA >= 1<<8 ||
regB >= 1<<8 ||
regC >= 1<<8) {
throw new RuntimeException("The register number must be less than v256");
}
if (regB >= 1<<8) {
throw new RuntimeException("The register number must be less than v256");
}
if (regC >= 1<<8) {
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);
encodedInstruction = new byte[4];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)regB;
encodedInstruction[3] = (byte)regC;
}
public int getByteCount() {
return 4;
private Instruction23x(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName() {
return "23x";
private Instruction23x() {
}
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]);
}
}

View 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]);
}
}

View File

@ -31,42 +31,49 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, short regB, byte litC) {
byte[] bytes = new byte[4];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction31c(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 (regB >= 1<<8) {
throw new RuntimeException("The register number must be less than v256");
encodedInstruction = new byte[6];
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() {
return "22b";
public short getRegister() {
return NumberUtils.decodeUnsignedByte(encodedInstruction[1]);
}
}

View File

@ -31,42 +31,57 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, int litB) {
byte[] bytes = new byte[6];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction31i(DexFile dexFile, Opcode opcode, short regA, int litB) {
super(dexFile, opcode, (IndexedItem)null);
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)litB;
bytes[3] = (byte)(litB >> 8);
bytes[4] = (byte)(litB >> 16);
bytes[5] = (byte)(litB >> 24);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[6];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)litB;
encodedInstruction[3] = (byte)(litB >> 8);
encodedInstruction[4] = (byte)(litB >> 16);
encodedInstruction[5] = (byte)(litB >> 24);
}
public int getByteCount() {
return 6;
private Instruction31i(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName() {
return "31i";
private Instruction31i() {
}
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]);
}
}

View File

@ -31,33 +31,57 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA) {
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction31t(DexFile dexFile, Opcode opcode, short regA, int offB) {
super(dexFile, opcode, (IndexedItem)null);
if (regA >= 1<<8) {
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()
{
return 2;
private Instruction31t(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName()
{
return "11x";
private Instruction31t() {
}
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]);
}
}

View File

@ -31,45 +31,56 @@ 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 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) {
byte[] bytes = new byte[6];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
if (regA >= 1<<16) {
if (regA >= 1<<16 ||
regB >= 1<<16) {
throw new RuntimeException("The register number must be less than v65536");
}
if (regB >= 1<<16) {
throw new RuntimeException("The register number must be less than v65536");
encodedInstruction = new byte[6];
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() {
return "32x";
public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(encodedInstruction[4], encodedInstruction[5]);
}
}

View File

@ -29,27 +29,23 @@
package org.jf.dexlib.code.Format;
import org.jf.dexlib.*;
import org.jf.dexlib.util.NumberUtils;
import org.jf.dexlib.code.Instruction;
import 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 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);
public Instruction35c(DexFile dexFile, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG,
byte regA, IndexedItem item) {
super(dexFile, opcode, item);
if (regCount > 5) {
throw new RuntimeException("regCount cannot be greater than 5");
}
if (regD >= 1<<4 ||
regE >= 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");
}
bytes[0] = opcode;
bytes[1] = (byte)((regCount << 4) | regA);
bytes[4] = (byte)((regE << 4) | regD);
bytes[5] = (byte)((regG << 4) | regF);
encodedInstruction = new byte[6];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)((regCount << 4) | regA);
//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,
//the construction will throw an exception
Instruction instruction = new Instruction(dexFile, bytes, item);
checkItem();
}
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
String type = ((TypeIdItem)item).getTypeDescriptor();
if (type.charAt(0) != '[') {
@ -76,39 +129,13 @@ public class Format35c extends Format
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
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
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");
}
} 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}));
}*/
}

View File

@ -29,23 +29,17 @@
package org.jf.dexlib.code.Format;
import org.jf.dexlib.*;
import org.jf.dexlib.util.NumberUtils;
import org.jf.dexlib.code.Instruction;
import 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 Instruction make(DexFile dexFile, byte opcode, short regCount, int startReg, IndexedItem item) {
byte[] bytes = new byte[6];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction3rc(DexFile dexFile, Opcode opcode, short regCount, int startReg, IndexedItem item) {
super(dexFile, opcode, item);
if (regCount >= 1<<8) {
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");
}
bytes[0] = opcode;
bytes[1] = (byte)regCount;
bytes[4] = (byte)startReg;
bytes[5] = (byte)(startReg >> 8);
encodedInstruction = new byte[6];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regCount;
//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,
//the construction will throw an exception
Instruction instruction = new Instruction(dexFile, bytes, item);
checkItem();
}
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
String type = ((TypeIdItem)item).getTypeDescriptor();
if (type.charAt(0) != '[') {
@ -79,40 +110,12 @@ public class Format3rc extends Format
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
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
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");
}
} 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));
}*/
}

View File

@ -31,48 +31,60 @@ 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 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 Instruction make(DexFile dexFile, byte opcode, short regA, long litB) {
byte[] bytes = new byte[10];
Opcode op = Opcode.getOpcodeByValue(opcode);
checkOpcodeFormat(op);
public Instruction51l(DexFile dexFile, Opcode opcode, short regA, long litB) {
super(dexFile, opcode, (IndexedItem)null);
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)litB;
bytes[3] = (byte)(litB >> 8);
bytes[4] = (byte)(litB >> 16);
bytes[5] = (byte)(litB >> 24);
bytes[6] = (byte)(litB >> 32);
bytes[7] = (byte)(litB >> 40);
bytes[8] = (byte)(litB >> 48);
bytes[9] = (byte)(litB >> 56);
return new Instruction(dexFile, bytes, null);
encodedInstruction = new byte[10];
encodedInstruction[0] = opcode.value;
encodedInstruction[1] = (byte)regA;
encodedInstruction[2] = (byte)litB;
encodedInstruction[3] = (byte)(litB >> 8);
encodedInstruction[4] = (byte)(litB >> 16);
encodedInstruction[5] = (byte)(litB >> 24);
encodedInstruction[6] = (byte)(litB >> 32);
encodedInstruction[7] = (byte)(litB >> 40);
encodedInstruction[8] = (byte)(litB >> 48);
encodedInstruction[9] = (byte)(litB >> 56);
}
public int getByteCount() {
return 10;
private Instruction51l(DexFile dexFile, Opcode opcode, byte[] rest) {
super(dexFile, opcode, rest);
}
public String getFormatName() {
return "51l";
private Instruction51l() {
}
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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -29,179 +29,300 @@
package org.jf.dexlib.code;
import org.jf.dexlib.*;
import org.jf.dexlib.code.Format.Format;
import org.jf.dexlib.util.Input;
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 byte[] bytes;
private Opcode opcode;
private IndexedItem referencedItem;
protected byte[] encodedInstruction;
private IndexedItem reference;
public byte[] getBytes() {
return bytes;
public int getSize() {
return encodedInstruction.length;
}
public Opcode getOpcode() {
return opcode;
}
public IndexedItem getReference() {
return reference;
public IndexedItem getReferencedItem() {
return referencedItem;
}
public Instruction(DexFile dexFile) {
this.dexFile = dexFile;
protected void setReferencedItem(IndexedItem referencedItem) {
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.bytes = bytes;
this.reference = item;
this.opcode = Opcode.getOpcodeByValue(bytes[0]);
if (!this.opcode.referenceType.checkItem(item)) {
throw new RuntimeException("item is not the correct type for this opcode (got " + item.getClass().toString() + ", expecting " + opcode.referenceType.toString() + ")");
this.opcode = opcode;
this.referencedItem = referencedItem;
checkFormat(opcode.format);
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) {
int startPos = in.getCursor();
protected Instruction(DexFile dexFile, Opcode opcode, byte[] rest) {
this.dexFile = dexFile;
this.opcode = opcode;
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");
}
if ((rest.length + 1) != opcode.format.size) {
throw new RuntimeException("Invalid instruction size. This opcode is " +
Integer.toString(rest.length + 1) + " bytes, but the opcode should be " +
Integer.toString(opcode.format.size) + " bytes.");
}
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) {
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);
}
int itemIndex = (encodedInstruction[3] << 8) | encodedInstruction[2];
getReferencedItem(dexFile, opcode, itemIndex);
}
}
public void copyTo(DexFile dexFile, Instruction copy) {
copy.bytes = bytes;
copy.opcode = opcode;
protected Instruction() {
//this should only be used to make a blank clone within cloneTo()
}
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) {
case string:
copy.reference = dexFile.StringIdsSection.intern(dexFile, (StringIdItem)reference);
clone.referencedItem = dexFile.StringIdsSection.intern(dexFile, (StringIdItem)referencedItem);
break;
case type:
copy.reference = dexFile.TypeIdsSection.intern(dexFile, (TypeIdItem)reference);
clone.referencedItem = dexFile.TypeIdsSection.intern(dexFile, (TypeIdItem)referencedItem);
break;
case field:
copy.reference = dexFile.FieldIdsSection.intern(dexFile, (FieldIdItem)reference);
clone.referencedItem = dexFile.FieldIdsSection.intern(dexFile, (FieldIdItem)referencedItem);
break;
case method:
copy.reference = dexFile.MethodIdsSection.intern(dexFile, (MethodIdItem)reference);
clone.referencedItem = dexFile.MethodIdsSection.intern(dexFile, (MethodIdItem)referencedItem);
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;
}
return clone;
}
private boolean needsAlign() {
//true if the opcode is one of the "special format" opcodes
return bytes[0] == 0 && bytes[1] > 0;
}
protected abstract Instruction makeClone();
// 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;
// }
}

View 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;
}
}

View File

@ -28,229 +28,231 @@
package org.jf.dexlib.code;
import org.jf.dexlib.code.Format.*;
import java.util.ArrayList;
import java.util.HashMap;
public enum Opcode
{
NOP((byte)0x00, "NOP", (byte)2, ReferenceType.none, "10x"),
MOVE((byte)0x01, "MOVE", (byte)2, ReferenceType.none, "12x"),
MOVE_FROM16((byte)0x02, "MOVE/FROM16", (byte)4, ReferenceType.none, "22x"),
MOVE_16((byte)0x03, "MOVE/16", (byte)6, ReferenceType.none, "32x"),
MOVE_WIDE((byte)0x04, "MOVE-WIDE", (byte)2, ReferenceType.none, "12x"),
MOVE_WIDE_FROM16((byte)0x05, "MOVE-WIDE/FROM16", (byte)4, ReferenceType.none, "22x"),
MOVE_WIDE_16((byte)0x06, "MOVE-WIDE/16", (byte)6, ReferenceType.none, "32x"),
MOVE_OBJECT((byte)0x07, "MOVE-OBJECT", (byte)2, ReferenceType.none, "12x"),
MOVE_OBJECT_FROM16((byte)0x08, "MOVE-OBJECT/FROM16", (byte)4, ReferenceType.none, "22x"),
MOVE_OBJECT_16((byte)0x09, "MOVE-OBJECT/16", (byte)6, ReferenceType.none, "32x"),
MOVE_RESULT((byte)0x0a, "MOVE-RESULT", (byte)2, ReferenceType.none, "11x"),
MOVE_RESULT_WIDE((byte)0x0b, "MOVE-RESULT-WIDE", (byte)2, ReferenceType.none, "11x"),
MOVE_RESULT_OBJECT((byte)0x0c, "MOVE-RESULT-OBJECT", (byte)2, ReferenceType.none, "11x"),
MOVE_EXCEPTION((byte)0x0d, "MOVE-EXCEPTION", (byte)2, ReferenceType.none, "11x"),
RETURN_VOID((byte)0x0e, "RETURN-VOID", (byte)2, ReferenceType.none, "10x"),
RETURN((byte)0x0f, "RETURN", (byte)2, ReferenceType.none, "11x"),
RETURN_WIDE((byte)0x10, "RETURN-WIDE", (byte)2, ReferenceType.none, "11x"),
RETURN_OBJECT((byte)0x11, "RETURN-OBJECT", (byte)2, ReferenceType.none, "11x"),
CONST_4((byte)0x12, "CONST/4", (byte)2, ReferenceType.none, "11n"),
CONST_16((byte)0x13, "CONST/16", (byte)4, ReferenceType.none, "21s"),
CONST((byte)0x14, "CONST", (byte)6, ReferenceType.none, "31i"),
CONST_HIGH16((byte)0x15, "CONST/HIGH16", (byte)4, ReferenceType.none, "21h"),
CONST_WIDE_16((byte)0x16, "CONST-WIDE/16", (byte)4, ReferenceType.none, "21s"),
CONST_WIDE_32((byte)0x17, "CONST-WIDE/32", (byte)6, ReferenceType.none, "31i"),
CONST_WIDE((byte)0x18, "CONST-WIDE", (byte)10, ReferenceType.none, "51l"),
CONST_WIDE_HIGH16((byte)0x19, "CONST-WIDE/HIGH16", (byte)4, ReferenceType.none, "21h"),
CONST_STRING((byte)0x1a, "CONST-STRING", (byte)4, ReferenceType.string, "21c"),
CONST_STRING_JUMBO((byte)0x1b, "CONST-STRING/JUMBO", (byte)6, ReferenceType.string, "31c"),
CONST_CLASS((byte)0x1c, "CONST-CLASS", (byte)4, ReferenceType.type, "21c"),
MONITOR_ENTER((byte)0x1d, "MONITOR-ENTER", (byte)2, ReferenceType.none, "11x"),
MONITOR_EXIT((byte)0x1e, "MONITOR-EXIT", (byte)2, ReferenceType.none, "11x"),
CHECK_CAST((byte)0x1f, "CHECK-CAST", (byte)4, ReferenceType.type, "21c"),
INSTANCE_OF((byte)0x20, "INSTANCE-OF", (byte)4, ReferenceType.type, "22c"),
ARRAY_LENGTH((byte)0x21, "ARRAY-LENGTH", (byte)2, ReferenceType.none, "12x"),
NEW_INSTANCE((byte)0x22, "NEW-INSTANCE", (byte)4, ReferenceType.type, "21c"),
NEW_ARRAY((byte)0x23, "NEW-ARRAY", (byte)4, ReferenceType.type, "22c"),
FILLED_NEW_ARRAY((byte)0x24, "FILLED-NEW-ARRAY", (byte)6, ReferenceType.type, "35c"),
FILLED_NEW_ARRAY_RANGE((byte)0x25, "FILLED-NEW-ARRAY/RANGE", (byte)6, ReferenceType.type, "3rc"),
FILL_ARRAY_DATA((byte)0x26, "FILL-ARRAY-DATA", (byte)6, ReferenceType.none, "31t"),
THROW((byte)0x27, "THROW", (byte)2, ReferenceType.none, "11x"),
GOTO((byte)0x28, "GOTO", (byte)2, ReferenceType.none, "10t"),
GOTO_16((byte)0x29, "GOTO/16", (byte)4, ReferenceType.none, "20t"),
GOTO_32((byte)0x2a, "GOTO/32", (byte)6, ReferenceType.none, "30t"),
PACKED_SWITCH((byte)0x2b, "PACKED-SWITCH", (byte)6, ReferenceType.none, "31t"),
SPARSE_SWITCH((byte)0x2c, "SPARSE-SWITCH", (byte)6, ReferenceType.none, "31t"),
CMPL_FLOAT((byte)0x2d, "CMPL-FLOAT", (byte)4, ReferenceType.none, "23x"),
CMPG_FLOAT((byte)0x2e, "CMPG-FLOAT", (byte)4, ReferenceType.none, "23x"),
CMPL_DOUBLE((byte)0x2f, "CMPL-DOUBLE", (byte)4, ReferenceType.none, "23x"),
CMPG_DOUBLE((byte)0x30, "CMPG-DOUBLE", (byte)4, ReferenceType.none, "23x"),
CMP_LONG((byte)0x31, "CMP-LONG", (byte)4, ReferenceType.none, "23x"),
IF_EQ((byte)0x32, "IF-EQ", (byte)4, ReferenceType.none, "22t"),
IF_NE((byte)0x33, "IF-NE", (byte)4, ReferenceType.none, "22t"),
IF_LT((byte)0x34, "IF-LT", (byte)4, ReferenceType.none, "22t"),
IF_GE((byte)0x35, "IF-GE", (byte)4, ReferenceType.none, "22t"),
IF_GT((byte)0x36, "IF-GT", (byte)4, ReferenceType.none, "22t"),
IF_LE((byte)0x37, "IF-LE", (byte)4, ReferenceType.none, "22t"),
IF_EQZ((byte)0x38, "IF-EQZ", (byte)4, ReferenceType.none, "21t"),
IF_NEZ((byte)0x39, "IF-NEZ", (byte)4, ReferenceType.none, "21t"),
IF_LTZ((byte)0x3a, "IF-LTZ", (byte)4, ReferenceType.none, "21t"),
IF_GEZ((byte)0x3b, "IF-GEZ", (byte)4, ReferenceType.none, "21t"),
IF_GTZ((byte)0x3c, "IF-GTZ", (byte)4, ReferenceType.none, "21t"),
IF_LEZ((byte)0x3d, "IF-LEZ", (byte)4, ReferenceType.none, "21t"),
AGET((byte)0x44, "AGET", (byte)4, ReferenceType.none, "23x"),
AGET_WIDE((byte)0x45, "AGET-WIDE", (byte)4, ReferenceType.none, "23x"),
AGET_OBJECT((byte)0x46, "AGET-OBJECT", (byte)4, ReferenceType.none, "23x"),
AGET_BOOLEAN((byte)0x47, "AGET-BOOLEAN", (byte)4, ReferenceType.none, "23x"),
AGET_BYTE((byte)0x48, "AGET-BYTE", (byte)4, ReferenceType.none, "23x"),
AGET_CHAR((byte)0x49, "AGET-CHAR", (byte)4, ReferenceType.none, "23x"),
AGET_SHORT((byte)0x4a, "AGET-SHORT", (byte)4, ReferenceType.none, "23x"),
APUT((byte)0x4b, "APUT", (byte)4, ReferenceType.none, "23x"),
APUT_WIDE((byte)0x4c, "APUT-WIDE", (byte)4, ReferenceType.none, "23x"),
APUT_OBJECT((byte)0x4d, "APUT-OBJECT", (byte)4, ReferenceType.none, "23x"),
APUT_BOOLEAN((byte)0x4e, "APUT-BOOLEAN", (byte)4, ReferenceType.none, "23x"),
APUT_BYTE((byte)0x4f, "APUT-BYTE", (byte)4, ReferenceType.none, "23x"),
APUT_CHAR((byte)0x50, "APUT-CHAR", (byte)4, ReferenceType.none, "23x"),
APUT_SHORT((byte)0x51, "APUT-SHORT", (byte)4, ReferenceType.none, "23x"),
IGET((byte)0x52, "IGET", (byte)4, ReferenceType.field, "22c"),
IGET_WIDE((byte)0x53, "IGET-WIDE", (byte)4, ReferenceType.field, "22c"),
IGET_OBJECT((byte)0x54, "IGET-OBJECT", (byte)4, ReferenceType.field, "22c"),
IGET_BOOLEAN((byte)0x55, "IGET-BOOLEAN", (byte)4, ReferenceType.field, "22c"),
IGET_BYTE((byte)0x56, "IGET-BYTE", (byte)4, ReferenceType.field, "22c"),
IGET_CHAR((byte)0x57, "IGET-CHAR", (byte)4, ReferenceType.field, "22c"),
IGET_SHORT((byte)0x58, "IGET-SHORT", (byte)4, ReferenceType.field, "22c"),
IPUT((byte)0x59, "IPUT", (byte)4, ReferenceType.field, "22c"),
IPUT_WIDE((byte)0x5a, "IPUT-WIDE", (byte)4, ReferenceType.field, "22c"),
IPUT_OBJECT((byte)0x5b, "IPUT-OBJECT", (byte)4, ReferenceType.field, "22c"),
IPUT_BOOLEAN((byte)0x5c, "IPUT-BOOLEAN", (byte)4, ReferenceType.field, "22c"),
IPUT_BYTE((byte)0x5d, "IPUT-BYTE", (byte)4, ReferenceType.field, "22c"),
IPUT_CHAR((byte)0x5e, "IPUT-CHAR", (byte)4, ReferenceType.field, "22c"),
IPUT_SHORT((byte)0x5f, "IPUT-SHORT", (byte)4, ReferenceType.field, "22c"),
SGET((byte)0x60, "SGET", (byte)4, ReferenceType.field, "21c"),
SGET_WIDE((byte)0x61, "SGET-WIDE", (byte)4, ReferenceType.field, "21c"),
SGET_OBJECT((byte)0x62, "SGET-OBJECT", (byte)4, ReferenceType.field, "21c"),
SGET_BOOLEAN((byte)0x63, "SGET-BOOLEAN", (byte)4, ReferenceType.field, "21c"),
SGET_BYTE((byte)0x64, "SGET-BYTE", (byte)4, ReferenceType.field, "21c"),
SGET_CHAR((byte)0x65, "SGET-CHAR", (byte)4, ReferenceType.field, "21c"),
SGET_SHORT((byte)0x66, "SGET-SHORT", (byte)4, ReferenceType.field, "21c"),
SPUT((byte)0x67, "SPUT", (byte)4, ReferenceType.field, "21c"),
SPUT_WIDE((byte)0x68, "SPUT-WIDE", (byte)4, ReferenceType.field, "21c"),
SPUT_OBJECT((byte)0x69, "SPUT-OBJECT", (byte)4, ReferenceType.field, "21c"),
SPUT_BOOLEAN((byte)0x6a, "SPUT-BOOLEAN", (byte)4, ReferenceType.field, "21c"),
SPUT_BYTE((byte)0x6b, "SPUT-BYTE", (byte)4, ReferenceType.field, "21c"),
SPUT_CHAR((byte)0x6c, "SPUT-CHAR", (byte)4, ReferenceType.field, "21c"),
SPUT_SHORT((byte)0x6d, "SPUT-SHORT", (byte)4, ReferenceType.field, "21c"),
INVOKE_VIRTUAL((byte)0x6e, "INVOKE-VIRTUAL", (byte)6, ReferenceType.method, "35c"),
INVOKE_SUPER((byte)0x6f, "INVOKE-SUPER", (byte)6, ReferenceType.method, "35c"),
INVOKE_DIRECT((byte)0x70, "INVOKE-DIRECT", (byte)6, ReferenceType.method, "35c"),
INVOKE_STATIC((byte)0x71, "INVOKE-STATIC", (byte)6, ReferenceType.method, "35c"),
INVOKE_INTERFACE((byte)0x72, "INVOKE-INTERFACE", (byte)6, ReferenceType.method, "35c"),
INVOKE_VIRTUAL_RANGE((byte)0x74, "INVOKE-VIRTUAL/RANGE", (byte)6, ReferenceType.method, "3rc"),
INVOKE_SUPER_RANGE((byte)0x75, "INVOKE-SUPER/RANGE", (byte)6, ReferenceType.method, "3rc"),
INVOKE_DIRECT_RANGE((byte)0x76, "INVOKE-DIRECT/RANGE", (byte)6, ReferenceType.method, "3rc"),
INVOKE_STATIC_RANGE((byte)0x77, "INVOKE-STATIC/RANGE", (byte)6, ReferenceType.method, "3rc"),
INVOKE_INTERFACE_RANGE((byte)0x78, "INVOKE-INTERFACE/RANGE", (byte)6, ReferenceType.method, "3rc"),
NEG_INT((byte)0x7b, "NEG-INT", (byte)2, ReferenceType.none, "12x"),
NOT_INT((byte)0x7c, "NOT-INT", (byte)2, ReferenceType.none, "12x"),
NEG_LONG((byte)0x7d, "NEG-LONG", (byte)2, ReferenceType.none, "12x"),
NOT_LONG((byte)0x7e, "NOT-LONG", (byte)2, ReferenceType.none, "12x"),
NEG_FLOAT((byte)0x7f, "NEG-FLOAT", (byte)2, ReferenceType.none, "12x"),
NEG_DOUBLE((byte)0x80, "NEG-DOUBLE", (byte)2, ReferenceType.none, "12x"),
INT_TO_LONG((byte)0x81, "INT-TO-LONG", (byte)2, ReferenceType.none, "12x"),
INT_TO_FLOAT((byte)0x82, "INT-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
INT_TO_DOUBLE((byte)0x83, "INT-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
LONG_TO_INT((byte)0x84, "LONG-TO-INT", (byte)2, ReferenceType.none, "12x"),
LONG_TO_FLOAT((byte)0x85, "LONG-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
LONG_TO_DOUBLE((byte)0x86, "LONG-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
FLOAT_TO_INT((byte)0x87, "FLOAT-TO-INT", (byte)2, ReferenceType.none, "12x"),
FLOAT_TO_LONG((byte)0x88, "FLOAT-TO-LONG", (byte)2, ReferenceType.none, "12x"),
FLOAT_TO_DOUBLE((byte)0x89, "FLOAT-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
DOUBLE_TO_INT((byte)0x8a, "DOUBLE-TO-INT", (byte)2, ReferenceType.none, "12x"),
DOUBLE_TO_LONG((byte)0x8b, "DOUBLE-TO-LONG", (byte)2, ReferenceType.none, "12x"),
DOUBLE_TO_FLOAT((byte)0x8c, "DOUBLE-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
INT_TO_BYTE((byte)0x8d, "INT-TO-BYTE", (byte)2, ReferenceType.none, "12x"),
INT_TO_CHAR((byte)0x8e, "INT-TO-CHAR", (byte)2, ReferenceType.none, "12x"),
INT_TO_SHORT((byte)0x8f, "INT-TO-SHORT", (byte)2, ReferenceType.none, "12x"),
ADD_INT((byte)0x90, "ADD-INT", (byte)4, ReferenceType.none, "23x"),
SUB_INT((byte)0x91, "SUB-INT", (byte)4, ReferenceType.none, "23x"),
MUL_INT((byte)0x92, "MUL-INT", (byte)4, ReferenceType.none, "23x"),
DIV_INT((byte)0x93, "DIV-INT", (byte)4, ReferenceType.none, "23x"),
REM_INT((byte)0x94, "REM-INT", (byte)4, ReferenceType.none, "23x"),
AND_INT((byte)0x95, "AND-INT", (byte)4, ReferenceType.none, "23x"),
OR_INT((byte)0x96, "OR-INT", (byte)4, ReferenceType.none, "23x"),
XOR_INT((byte)0x97, "XOR-INT", (byte)4, ReferenceType.none, "23x"),
SHL_INT((byte)0x98, "SHL-INT", (byte)4, ReferenceType.none, "23x"),
SHR_INT((byte)0x99, "SHR-INT", (byte)4, ReferenceType.none, "23x"),
USHR_INT((byte)0x9a, "USHR-INT", (byte)4, ReferenceType.none, "23x"),
ADD_LONG((byte)0x9b, "ADD-LONG", (byte)4, ReferenceType.none, "23x"),
SUB_LONG((byte)0x9c, "SUB-LONG", (byte)4, ReferenceType.none, "23x"),
MUL_LONG((byte)0x9d, "MUL-LONG", (byte)4, ReferenceType.none, "23x"),
DIV_LONG((byte)0x9e, "DIV-LONG", (byte)4, ReferenceType.none, "23x"),
REM_LONG((byte)0x9f, "REM-LONG", (byte)4, ReferenceType.none, "23x"),
AND_LONG((byte)0xa0, "AND-LONG", (byte)4, ReferenceType.none, "23x"),
OR_LONG((byte)0xa1, "OR-LONG", (byte)4, ReferenceType.none, "23x"),
XOR_LONG((byte)0xa2, "XOR-LONG", (byte)4, ReferenceType.none, "23x"),
SHL_LONG((byte)0xa3, "SHL-LONG", (byte)4, ReferenceType.none, "23x"),
SHR_LONG((byte)0xa4, "SHR-LONG", (byte)4, ReferenceType.none, "23x"),
USHR_LONG((byte)0xa5, "USHR-LONG", (byte)4, ReferenceType.none, "23x"),
ADD_FLOAT((byte)0xa6, "ADD-FLOAT", (byte)4, ReferenceType.none, "23x"),
SUB_FLOAT((byte)0xa7, "SUB-FLOAT", (byte)4, ReferenceType.none, "23x"),
MUL_FLOAT((byte)0xa8, "MUL-FLOAT", (byte)4, ReferenceType.none, "23x"),
DIV_FLOAT((byte)0xa9, "DIV-FLOAT", (byte)4, ReferenceType.none, "23x"),
REM_FLOAT((byte)0xaa, "REM-FLOAT", (byte)4, ReferenceType.none, "23x"),
ADD_DOUBLE((byte)0xab, "ADD-DOUBLE", (byte)4, ReferenceType.none, "23x"),
SUB_DOUBLE((byte)0xac, "SUB-DOUBLE", (byte)4, ReferenceType.none, "23x"),
MUL_DOUBLE((byte)0xad, "MUL-DOUBLE", (byte)4, ReferenceType.none, "23x"),
DIV_DOUBLE((byte)0xae, "DIV-DOUBLE", (byte)4, ReferenceType.none, "23x"),
REM_DOUBLE((byte)0xaf, "REM-DOUBLE", (byte)4, ReferenceType.none, "23x"),
ADD_INT_2ADDR((byte)0xb0, "ADD-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
SUB_INT_2ADDR((byte)0xb1, "SUB-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
MUL_INT_2ADDR((byte)0xb2, "MUL-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
DIV_INT_2ADDR((byte)0xb3, "DIV-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
REM_INT_2ADDR((byte)0xb4, "REM-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
AND_INT_2ADDR((byte)0xb5, "AND-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
OR_INT_2ADDR((byte)0xb6, "OR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
XOR_INT_2ADDR((byte)0xb7, "XOR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
SHL_INT_2ADDR((byte)0xb8, "SHL-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
SHR_INT_2ADDR((byte)0xb9, "SHR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
USHR_INT_2ADDR((byte)0xba, "USHR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
ADD_LONG_2ADDR((byte)0xbb, "ADD-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
SUB_LONG_2ADDR((byte)0xbc, "SUB-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
MUL_LONG_2ADDR((byte)0xbd, "MUL-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
DIV_LONG_2ADDR((byte)0xbe, "DIV-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
REM_LONG_2ADDR((byte)0xbf, "REM-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
AND_LONG_2ADDR((byte)0xc0, "AND-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
OR_LONG_2ADDR((byte)0xc1, "OR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
XOR_LONG_2ADDR((byte)0xc2, "XOR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
SHL_LONG_2ADDR((byte)0xc3, "SHL-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
SHR_LONG_2ADDR((byte)0xc4, "SHR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
USHR_LONG_2ADDR((byte)0xc5, "USHR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
ADD_FLOAT_2ADDR((byte)0xc6, "ADD-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
SUB_FLOAT_2ADDR((byte)0xc7, "SUB-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
MUL_FLOAT_2ADDR((byte)0xc8, "MUL-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
DIV_FLOAT_2ADDR((byte)0xc9, "DIV-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
REM_FLOAT_2ADDR((byte)0xca, "REM-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
ADD_DOUBLE_2ADDR((byte)0xcb, "ADD-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
SUB_DOUBLE_2ADDR((byte)0xcc, "SUB-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
MUL_DOUBLE_2ADDR((byte)0xcd, "MUL-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
DIV_DOUBLE_2ADDR((byte)0xce, "DIV-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
REM_DOUBLE_2ADDR((byte)0xcf, "REM-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
ADD_INT_LIT16((byte)0xd0, "ADD-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
RSUB_INT((byte)0xd1, "RSUB-INT", (byte)4, ReferenceType.none, "22s"),
MUL_INT_LIT16((byte)0xd2, "MUL-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
DIV_INT_LIT16((byte)0xd3, "DIV-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
REM_INT_LIT16((byte)0xd4, "REM-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
AND_INT_LIT16((byte)0xd5, "AND-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
OR_INT_LIT16((byte)0xd6, "OR-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
XOR_INT_LIT16((byte)0xd7, "XOR-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
ADD_INT_LIT8((byte)0xd8, "ADD-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
RSUB_INT_LIT8((byte)0xd9, "RSUB-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
MUL_INT_LIT8((byte)0xda, "MUL-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
DIV_INT_LIT8((byte)0xdb, "DIV-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
REM_INT_LIT8((byte)0xdc, "REM-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
AND_INT_LIT8((byte)0xdd, "AND-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
OR_INT_LIT8((byte)0xde, "OR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
XOR_INT_LIT8((byte)0xdf, "XOR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
SHL_INT_LIT8((byte)0xe0, "SHL-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
SHR_INT_LIT8((byte)0xe1, "SHR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
USHR_INT_LIT8((byte)0xe2, "USHR-INT/LIT8", (byte)4, ReferenceType.none, "22b");
NOP((byte)0x00, "nop", ReferenceType.none, Format.Format10x),
MOVE((byte)0x01, "move", ReferenceType.none, Format.Format12x),
MOVE_FROM16((byte)0x02, "move/from16", ReferenceType.none, Format.Format22x),
MOVE_16((byte)0x03, "move/16", ReferenceType.none, Format.Format32x),
MOVE_WIDE((byte)0x04, "move-wide", ReferenceType.none, Format.Format12x),
MOVE_WIDE_FROM16((byte)0x05, "move-wide/from16", ReferenceType.none, Format.Format22x),
MOVE_WIDE_16((byte)0x06, "move-wide/16", ReferenceType.none, Format.Format32x),
MOVE_OBJECT((byte)0x07, "move-object", ReferenceType.none, Format.Format12x),
MOVE_OBJECT_FROM16((byte)0x08, "move-object/from16", ReferenceType.none, Format.Format22x),
MOVE_OBJECT_16((byte)0x09, "move-object/16", ReferenceType.none, Format.Format32x),
MOVE_RESULT((byte)0x0a, "move-result", ReferenceType.none, Format.Format11x),
MOVE_RESULT_WIDE((byte)0x0b, "move-result-wide", ReferenceType.none, Format.Format11x),
MOVE_RESULT_OBJECT((byte)0x0c, "move-result-object", ReferenceType.none, Format.Format11x),
MOVE_EXCEPTION((byte)0x0d, "move-exception", ReferenceType.none, Format.Format11x),
RETURN_VOID((byte)0x0e, "return-void", ReferenceType.none, Format.Format10x),
RETURN((byte)0x0f, "return", ReferenceType.none, Format.Format11x),
RETURN_WIDE((byte)0x10, "return-wide", ReferenceType.none, Format.Format11x),
RETURN_OBJECT((byte)0x11, "return-object", ReferenceType.none, Format.Format11x),
CONST_4((byte)0x12, "const/4", ReferenceType.none, Format.Format11n),
CONST_16((byte)0x13, "const/16", ReferenceType.none, Format.Format21s),
CONST((byte)0x14, "const", ReferenceType.none, Format.Format31i),
CONST_HIGH16((byte)0x15, "const/high16", ReferenceType.none, Format.Format21h),
CONST_WIDE_16((byte)0x16, "const-wide/16", ReferenceType.none, Format.Format21s),
CONST_WIDE_32((byte)0x17, "const-wide/32", ReferenceType.none, Format.Format31i),
CONST_WIDE((byte)0x18, "const-wide", ReferenceType.none, Format.Format51l),
CONST_WIDE_HIGH16((byte)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h),
CONST_STRING((byte)0x1a, "const-string", ReferenceType.string, Format.Format21c),
CONST_STRING_JUMBO((byte)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c),
CONST_CLASS((byte)0x1c, "const-class", ReferenceType.type, Format.Format21c),
MONITOR_ENTER((byte)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x),
MONITOR_EXIT((byte)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x),
CHECK_CAST((byte)0x1f, "check-cast", ReferenceType.type, Format.Format21c),
INSTANCE_OF((byte)0x20, "instance-of", ReferenceType.type, Format.Format22c),
ARRAY_LENGTH((byte)0x21, "array-length", ReferenceType.none, Format.Format12x),
NEW_INSTANCE((byte)0x22, "new-instance", ReferenceType.type, Format.Format21c),
NEW_ARRAY((byte)0x23, "new-array", ReferenceType.type, Format.Format22c),
FILLED_NEW_ARRAY((byte)0x24, "filled-new-array", ReferenceType.type, Format.Format35c),
FILLED_NEW_ARRAY_RANGE((byte)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc),
FILL_ARRAY_DATA((byte)0x26, "fill-array-data", ReferenceType.none, Format.Format31t),
THROW((byte)0x27, "throw", ReferenceType.none, Format.Format11x),
GOTO((byte)0x28, "goto", ReferenceType.none, Format.Format10t),
GOTO_16((byte)0x29, "goto/16", ReferenceType.none, Format.Format20t),
GOTO_32((byte)0x2a, "goto/32", ReferenceType.none, Format.Format30t),
PACKED_SWITCH((byte)0x2b, "packed-switch", ReferenceType.none, Format.Format31t),
SPARSE_SWITCH((byte)0x2c, "sparse-switch", ReferenceType.none, Format.Format31t),
CMPL_FLOAT((byte)0x2d, "cmpl-float", ReferenceType.none, Format.Format23x),
CMPG_FLOAT((byte)0x2e, "cmpg-float", ReferenceType.none, Format.Format23x),
CMPL_DOUBLE((byte)0x2f, "cmpl-double", ReferenceType.none, Format.Format23x),
CMPG_DOUBLE((byte)0x30, "cmpg-double", ReferenceType.none, Format.Format23x),
CMP_LONG((byte)0x31, "cmp-long", ReferenceType.none, Format.Format23x),
IF_EQ((byte)0x32, "if-eq", ReferenceType.none, Format.Format22t),
IF_NE((byte)0x33, "if-ne", ReferenceType.none, Format.Format22t),
IF_LT((byte)0x34, "if-lt", ReferenceType.none, Format.Format22t),
IF_GE((byte)0x35, "if-ge", ReferenceType.none, Format.Format22t),
IF_GT((byte)0x36, "if-gt", ReferenceType.none, Format.Format22t),
IF_LE((byte)0x37, "if-le", ReferenceType.none, Format.Format22t),
IF_EQZ((byte)0x38, "if-eqz", ReferenceType.none, Format.Format21t),
IF_NEZ((byte)0x39, "if-nez", ReferenceType.none, Format.Format21t),
IF_LTZ((byte)0x3a, "if-ltz", ReferenceType.none, Format.Format21t),
IF_GEZ((byte)0x3b, "if-gez", ReferenceType.none, Format.Format21t),
IF_GTZ((byte)0x3c, "if-gtz", ReferenceType.none, Format.Format21t),
IF_LEZ((byte)0x3d, "if-lez", ReferenceType.none, Format.Format21t),
AGET((byte)0x44, "aget", ReferenceType.none, Format.Format23x),
AGET_WIDE((byte)0x45, "aget-wide", ReferenceType.none, Format.Format23x),
AGET_OBJECT((byte)0x46, "aget-object", ReferenceType.none, Format.Format23x),
AGET_BOOLEAN((byte)0x47, "aget-boolean", ReferenceType.none, Format.Format23x),
AGET_BYTE((byte)0x48, "aget-byte", ReferenceType.none, Format.Format23x),
AGET_CHAR((byte)0x49, "aget-char", ReferenceType.none, Format.Format23x),
AGET_SHORT((byte)0x4a, "aget-short", ReferenceType.none, Format.Format23x),
APUT((byte)0x4b, "aput", ReferenceType.none, Format.Format23x),
APUT_WIDE((byte)0x4c, "aput-wide", ReferenceType.none, Format.Format23x),
APUT_OBJECT((byte)0x4d, "aput-object", ReferenceType.none, Format.Format23x),
APUT_BOOLEAN((byte)0x4e, "aput-boolean", ReferenceType.none, Format.Format23x),
APUT_BYTE((byte)0x4f, "aput-byte", ReferenceType.none, Format.Format23x),
APUT_CHAR((byte)0x50, "aput-char", ReferenceType.none, Format.Format23x),
APUT_SHORT((byte)0x51, "aput-short", ReferenceType.none, Format.Format23x),
IGET((byte)0x52, "iget", ReferenceType.field, Format.Format22c),
IGET_WIDE((byte)0x53, "iget-wide", ReferenceType.field, Format.Format22c),
IGET_OBJECT((byte)0x54, "iget-object", ReferenceType.field, Format.Format22c),
IGET_BOOLEAN((byte)0x55, "iget-boolean", ReferenceType.field, Format.Format22c),
IGET_BYTE((byte)0x56, "iget-byte", ReferenceType.field, Format.Format22c),
IGET_CHAR((byte)0x57, "iget-char", ReferenceType.field, Format.Format22c),
IGET_SHORT((byte)0x58, "iget-short", ReferenceType.field, Format.Format22c),
IPUT((byte)0x59, "iput", ReferenceType.field, Format.Format22c),
IPUT_WIDE((byte)0x5a, "iput-wide", ReferenceType.field, Format.Format22c),
IPUT_OBJECT((byte)0x5b, "iput-object", ReferenceType.field, Format.Format22c),
IPUT_BOOLEAN((byte)0x5c, "iput-boolean", ReferenceType.field, Format.Format22c),
IPUT_BYTE((byte)0x5d, "iput-byte", ReferenceType.field, Format.Format22c),
IPUT_CHAR((byte)0x5e, "iput-char", ReferenceType.field, Format.Format22c),
IPUT_SHORT((byte)0x5f, "iput-short", ReferenceType.field, Format.Format22c),
SGET((byte)0x60, "sget", ReferenceType.field, Format.Format21c),
SGET_WIDE((byte)0x61, "sget-wide", ReferenceType.field, Format.Format21c),
SGET_OBJECT((byte)0x62, "sget-object", ReferenceType.field, Format.Format21c),
SGET_BOOLEAN((byte)0x63, "sget-boolean", ReferenceType.field, Format.Format21c),
SGET_BYTE((byte)0x64, "sget-byte", ReferenceType.field, Format.Format21c),
SGET_CHAR((byte)0x65, "sget-char", ReferenceType.field, Format.Format21c),
SGET_SHORT((byte)0x66, "sget-short", ReferenceType.field, Format.Format21c),
SPUT((byte)0x67, "sput", ReferenceType.field, Format.Format21c),
SPUT_WIDE((byte)0x68, "sput-wide", ReferenceType.field, Format.Format21c),
SPUT_OBJECT((byte)0x69, "sput-object", ReferenceType.field, Format.Format21c),
SPUT_BOOLEAN((byte)0x6a, "sput-boolean", ReferenceType.field, Format.Format21c),
SPUT_BYTE((byte)0x6b, "sput-byte", ReferenceType.field, Format.Format21c),
SPUT_CHAR((byte)0x6c, "sput-char", ReferenceType.field, Format.Format21c),
SPUT_SHORT((byte)0x6d, "sput-short", ReferenceType.field, Format.Format21c),
INVOKE_VIRTUAL((byte)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c),
INVOKE_SUPER((byte)0x6f, "invoke-super", ReferenceType.method, Format.Format35c),
INVOKE_DIRECT((byte)0x70, "invoke-direct", ReferenceType.method, Format.Format35c),
INVOKE_STATIC((byte)0x71, "invoke-static", ReferenceType.method, Format.Format35c),
INVOKE_INTERFACE((byte)0x72, "invoke-interface", ReferenceType.method, Format.Format35c),
INVOKE_VIRTUAL_RANGE((byte)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc),
INVOKE_SUPER_RANGE((byte)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc),
INVOKE_DIRECT_RANGE((byte)0x76, "invoke-direct/range", ReferenceType.method, Format.Format3rc),
INVOKE_STATIC_RANGE((byte)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc),
INVOKE_INTERFACE_RANGE((byte)0x78, "invoke-interface/range", ReferenceType.method, Format.Format3rc),
NEG_INT((byte)0x7b, "neg-int", ReferenceType.none, Format.Format12x),
NOT_INT((byte)0x7c, "not-int", ReferenceType.none, Format.Format12x),
NEG_LONG((byte)0x7d, "neg-long", ReferenceType.none, Format.Format12x),
NOT_LONG((byte)0x7e, "not-long", ReferenceType.none, Format.Format12x),
NEG_FLOAT((byte)0x7f, "neg-float", ReferenceType.none, Format.Format12x),
NEG_DOUBLE((byte)0x80, "neg-double", ReferenceType.none, Format.Format12x),
INT_TO_LONG((byte)0x81, "int-to-long", ReferenceType.none, Format.Format12x),
INT_TO_FLOAT((byte)0x82, "int-to-float", ReferenceType.none, Format.Format12x),
INT_TO_DOUBLE((byte)0x83, "int-to-double", ReferenceType.none, Format.Format12x),
LONG_TO_INT((byte)0x84, "long-to-int", ReferenceType.none, Format.Format12x),
LONG_TO_FLOAT((byte)0x85, "long-to-float", ReferenceType.none, Format.Format12x),
LONG_TO_DOUBLE((byte)0x86, "long-to-double", ReferenceType.none, Format.Format12x),
FLOAT_TO_INT((byte)0x87, "float-to-int", ReferenceType.none, Format.Format12x),
FLOAT_TO_LONG((byte)0x88, "float-to-long", ReferenceType.none, Format.Format12x),
FLOAT_TO_DOUBLE((byte)0x89, "float-to-double", ReferenceType.none, Format.Format12x),
DOUBLE_TO_INT((byte)0x8a, "double-to-int", ReferenceType.none, Format.Format12x),
DOUBLE_TO_LONG((byte)0x8b, "double-to-long", ReferenceType.none, Format.Format12x),
DOUBLE_TO_FLOAT((byte)0x8c, "double-to-float", ReferenceType.none, Format.Format12x),
INT_TO_BYTE((byte)0x8d, "int-to-byte", ReferenceType.none, Format.Format12x),
INT_TO_CHAR((byte)0x8e, "int-to-char", ReferenceType.none, Format.Format12x),
INT_TO_SHORT((byte)0x8f, "int-to-short", ReferenceType.none, Format.Format12x),
ADD_INT((byte)0x90, "add-int", ReferenceType.none, Format.Format23x),
SUB_INT((byte)0x91, "sub-int", ReferenceType.none, Format.Format23x),
MUL_INT((byte)0x92, "mul-int", ReferenceType.none, Format.Format23x),
DIV_INT((byte)0x93, "div-int", ReferenceType.none, Format.Format23x),
REM_INT((byte)0x94, "rem-int", ReferenceType.none, Format.Format23x),
AND_INT((byte)0x95, "and-int", ReferenceType.none, Format.Format23x),
OR_INT((byte)0x96, "or-int", ReferenceType.none, Format.Format23x),
XOR_INT((byte)0x97, "xor-int", ReferenceType.none, Format.Format23x),
SHL_INT((byte)0x98, "shl-int", ReferenceType.none, Format.Format23x),
SHR_INT((byte)0x99, "shr-int", ReferenceType.none, Format.Format23x),
USHR_INT((byte)0x9a, "ushr-int", ReferenceType.none, Format.Format23x),
ADD_LONG((byte)0x9b, "add-long", ReferenceType.none, Format.Format23x),
SUB_LONG((byte)0x9c, "sub-long", ReferenceType.none, Format.Format23x),
MUL_LONG((byte)0x9d, "mul-long", ReferenceType.none, Format.Format23x),
DIV_LONG((byte)0x9e, "div-long", ReferenceType.none, Format.Format23x),
REM_LONG((byte)0x9f, "rem-long", ReferenceType.none, Format.Format23x),
AND_LONG((byte)0xa0, "and-long", ReferenceType.none, Format.Format23x),
OR_LONG((byte)0xa1, "or-long", ReferenceType.none, Format.Format23x),
XOR_LONG((byte)0xa2, "xor-long", ReferenceType.none, Format.Format23x),
SHL_LONG((byte)0xa3, "shl-long", ReferenceType.none, Format.Format23x),
SHR_LONG((byte)0xa4, "shr-long", ReferenceType.none, Format.Format23x),
USHR_LONG((byte)0xa5, "ushr-long", ReferenceType.none, Format.Format23x),
ADD_FLOAT((byte)0xa6, "add-float", ReferenceType.none, Format.Format23x),
SUB_FLOAT((byte)0xa7, "sub-float", ReferenceType.none, Format.Format23x),
MUL_FLOAT((byte)0xa8, "mul-float", ReferenceType.none, Format.Format23x),
DIV_FLOAT((byte)0xa9, "div-float", ReferenceType.none, Format.Format23x),
REM_FLOAT((byte)0xaa, "rem-float", ReferenceType.none, Format.Format23x),
ADD_DOUBLE((byte)0xab, "add-double", ReferenceType.none, Format.Format23x),
SUB_DOUBLE((byte)0xac, "sub-double", ReferenceType.none, Format.Format23x),
MUL_DOUBLE((byte)0xad, "mul-double", ReferenceType.none, Format.Format23x),
DIV_DOUBLE((byte)0xae, "div-double", ReferenceType.none, Format.Format23x),
REM_DOUBLE((byte)0xaf, "rem-double", ReferenceType.none, Format.Format23x),
ADD_INT_2ADDR((byte)0xb0, "add-int/2addr", ReferenceType.none, Format.Format12x),
SUB_INT_2ADDR((byte)0xb1, "sub-int/2addr", ReferenceType.none, Format.Format12x),
MUL_INT_2ADDR((byte)0xb2, "mul-int/2addr", ReferenceType.none, Format.Format12x),
DIV_INT_2ADDR((byte)0xb3, "div-int/2addr", ReferenceType.none, Format.Format12x),
REM_INT_2ADDR((byte)0xb4, "rem-int/2addr", ReferenceType.none, Format.Format12x),
AND_INT_2ADDR((byte)0xb5, "and-int/2addr", ReferenceType.none, Format.Format12x),
OR_INT_2ADDR((byte)0xb6, "or-int/2addr", ReferenceType.none, Format.Format12x),
XOR_INT_2ADDR((byte)0xb7, "xor-int/2addr", ReferenceType.none, Format.Format12x),
SHL_INT_2ADDR((byte)0xb8, "shl-int/2addr", ReferenceType.none, Format.Format12x),
SHR_INT_2ADDR((byte)0xb9, "shr-int/2addr", ReferenceType.none, Format.Format12x),
USHR_INT_2ADDR((byte)0xba, "ushr-int/2addr", ReferenceType.none, Format.Format12x),
ADD_LONG_2ADDR((byte)0xbb, "add-long/2addr", ReferenceType.none, Format.Format12x),
SUB_LONG_2ADDR((byte)0xbc, "sub-long/2addr", ReferenceType.none, Format.Format12x),
MUL_LONG_2ADDR((byte)0xbd, "mul-long/2addr", ReferenceType.none, Format.Format12x),
DIV_LONG_2ADDR((byte)0xbe, "div-long/2addr", ReferenceType.none, Format.Format12x),
REM_LONG_2ADDR((byte)0xbf, "rem-long/2addr", ReferenceType.none, Format.Format12x),
AND_LONG_2ADDR((byte)0xc0, "and-long/2addr", ReferenceType.none, Format.Format12x),
OR_LONG_2ADDR((byte)0xc1, "or-long/2addr", ReferenceType.none, Format.Format12x),
XOR_LONG_2ADDR((byte)0xc2, "xor-long/2addr", ReferenceType.none, Format.Format12x),
SHL_LONG_2ADDR((byte)0xc3, "shl-long/2addr", ReferenceType.none, Format.Format12x),
SHR_LONG_2ADDR((byte)0xc4, "shr-long/2addr", ReferenceType.none, Format.Format12x),
USHR_LONG_2ADDR((byte)0xc5, "ushr-long/2addr", ReferenceType.none, Format.Format12x),
ADD_FLOAT_2ADDR((byte)0xc6, "add-float/2addr", ReferenceType.none, Format.Format12x),
SUB_FLOAT_2ADDR((byte)0xc7, "sub-float/2addr", ReferenceType.none, Format.Format12x),
MUL_FLOAT_2ADDR((byte)0xc8, "mul-float/2addr", ReferenceType.none, Format.Format12x),
DIV_FLOAT_2ADDR((byte)0xc9, "div-float/2addr", ReferenceType.none, Format.Format12x),
REM_FLOAT_2ADDR((byte)0xca, "rem-float/2addr", ReferenceType.none, Format.Format12x),
ADD_DOUBLE_2ADDR((byte)0xcb, "add-double/2addr", ReferenceType.none, Format.Format12x),
SUB_DOUBLE_2ADDR((byte)0xcc, "sub-double/2addr", ReferenceType.none, Format.Format12x),
MUL_DOUBLE_2ADDR((byte)0xcd, "mul-double/2addr", ReferenceType.none, Format.Format12x),
DIV_DOUBLE_2ADDR((byte)0xce, "div-double/2addr", ReferenceType.none, Format.Format12x),
REM_DOUBLE_2ADDR((byte)0xcf, "rem-double/2addr", ReferenceType.none, Format.Format12x),
ADD_INT_LIT16((byte)0xd0, "add-int/lit16", ReferenceType.none, Format.Format22s),
RSUB_INT((byte)0xd1, "rsub-int", ReferenceType.none, Format.Format22s),
MUL_INT_LIT16((byte)0xd2, "mul-int/lit16", ReferenceType.none, Format.Format22s),
DIV_INT_LIT16((byte)0xd3, "div-int/lit16", ReferenceType.none, Format.Format22s),
REM_INT_LIT16((byte)0xd4, "rem-int/lit16", ReferenceType.none, Format.Format22s),
AND_INT_LIT16((byte)0xd5, "and-int/lit16", ReferenceType.none, Format.Format22s),
OR_INT_LIT16((byte)0xd6, "or-int/lit16", ReferenceType.none, Format.Format22s),
XOR_INT_LIT16((byte)0xd7, "xor-int/lit16", ReferenceType.none, Format.Format22s),
ADD_INT_LIT8((byte)0xd8, "add-int/lit8", ReferenceType.none, Format.Format22b),
RSUB_INT_LIT8((byte)0xd9, "rsub-int/lit8", ReferenceType.none, Format.Format22b),
MUL_INT_LIT8((byte)0xda, "mul-int/lit8", ReferenceType.none, Format.Format22b),
DIV_INT_LIT8((byte)0xdb, "div-int/lit8", ReferenceType.none, Format.Format22b),
REM_INT_LIT8((byte)0xdc, "rem-int/lit8", ReferenceType.none, Format.Format22b),
AND_INT_LIT8((byte)0xdd, "and-int/lit8", ReferenceType.none, Format.Format22b),
OR_INT_LIT8((byte)0xde, "or-int/lit8", ReferenceType.none, Format.Format22b),
XOR_INT_LIT8((byte)0xdf, "xor-int/lit8", ReferenceType.none, Format.Format22b),
SHL_INT_LIT8((byte)0xe0, "shl-int/lit8", ReferenceType.none, Format.Format22b),
SHR_INT_LIT8((byte)0xe1, "shr-int/lit8", ReferenceType.none, Format.Format22b),
USHR_INT_LIT8((byte)0xe2, "ushr-int/lit8", ReferenceType.none, Format.Format22b);
@ -269,7 +271,7 @@ public enum Opcode
for (Opcode opcode: Opcode.values()) {
opcodesByValue.set((opcode.value & 0xFF), opcode);
opcodesByName.put(opcode.name.toLowerCase().hashCode(), opcode);
opcodesByName.put(opcode.name.hashCode(), opcode);
}
}catch (Exception ex) {
System.out.println(ex.toString());
@ -286,14 +288,12 @@ public enum Opcode
public final byte value;
public final String name;
public final byte numBytes;
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.name = opcodeName;
this.numBytes = numBytes;
this.referenceType = referenceType;
this.format = format;
}

View 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);
}
}