Add support for the upcoming execute-inline/range odexed instruction

git-svn-id: https://smali.googlecode.com/svn/trunk@544 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2010-01-01 22:35:54 +00:00
parent c043c35800
commit be2472d6d7
3 changed files with 42 additions and 1 deletions

View File

@ -53,6 +53,7 @@ public class UnresolvedNullReferenceMethodItem extends InstructionFormatMethodIt
template.setAttribute("Register", formatRegister(instruction.ObjectRegisterNum));
switch (instruction.OriginalInstruction.opcode)
{
case EXECUTE_INLINE_RANGE:
case INVOKE_VIRTUAL_QUICK_RANGE:
case INVOKE_SUPER_QUICK_RANGE:
template.setAttribute("UseInvokeRange", 1);

View File

@ -255,6 +255,7 @@ public enum Opcode
INVOKE_EXECUTE_INLINE((byte)0xee, "execute-inline", ReferenceType.none, Format.Format35ms, true),
EXECUTE_INLINE_RANGE((byte)0xef, "execute-inline/range", ReferenceType.none, Format.Format3rms, true),
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, true),
IGET_QUICK((byte)0xf2, "iget-quick", ReferenceType.none, Format.Format22cs, true),
IGET_WIDE_QUICK((byte)0xf3, "iget-wide-quick", ReferenceType.none, Format.Format22cs, true),

View File

@ -119,7 +119,8 @@ public class DeodexUtil {
instructionThrowTable.set(Opcode.DIV_INT_LIT8.value & 0xFF);
instructionThrowTable.set(Opcode.REM_INT_LIT8.value & 0xFF);
instructionThrowTable.set(Opcode.THROW.value & 0xFF);
instructionThrowTable.set(Opcode.INVOKE_EXECUTE_INLINE.value & 0xFF);
instructionThrowTable.set(Opcode.INVOKE_EXECUTE_INLINE.value & 0xFF);
instructionThrowTable.set(Opcode.EXECUTE_INLINE_RANGE.value & 0xFF);
instructionThrowTable.set(Opcode.IGET_QUICK.value & 0xFF);
instructionThrowTable.set(Opcode.IGET_WIDE_QUICK.value & 0xFF);
instructionThrowTable.set(Opcode.IGET_OBJECT_QUICK.value & 0xFF);
@ -275,6 +276,42 @@ public class DeodexUtil {
return true;
}
case EXECUTE_INLINE_RANGE:
{
int inlineMethodIndex = ((Instruction3rms)i.instruction).getMethodIndex();
Deodexerant.InlineMethod inlineMethod =
deodexerant.lookupInlineMethod(inlineMethodIndex);
if (inlineMethod == null) {
throw new RuntimeException("Could not find the inline method with index " + inlineMethodIndex);
}
assert inlineMethod != null;
assert inlineMethod.getMethodIdItem() != null;
Opcode opcode = null;
switch (inlineMethod.getMethodType()) {
case Direct:
opcode = Opcode.INVOKE_DIRECT_RANGE;
break;
case Static:
opcode = Opcode.INVOKE_STATIC_RANGE;
break;
case Virtual:
opcode = Opcode.INVOKE_VIRTUAL_RANGE;
break;
}
i.fixedInstruction = new Instruction3rmsf(opcode, (Instruction3rms)i.instruction,
inlineMethod.getMethodIdItem());
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize(i.offset*2)/2);
assert nextInstruction != null;
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
nextInstruction.registerReferenceType =
inlineMethod.getMethodIdItem().getPrototype().getReturnType().getTypeDescriptor();
}
return true;
}
case INVOKE_DIRECT_EMPTY:
{
i.fixedInstruction = new Instruction35sf((Instruction35s)i.instruction);
@ -897,6 +934,8 @@ public class DeodexUtil {
this.insnsMap = insnsMap;
if (instruction.opcode.odexOnly) {
//we don't need INVOKE_EXECUTE_INLINE or EXECUTE_INLINE_RANGE here, because we don't need to know
//the type of the object register in order to resolve which method is being called
switch (instruction.opcode) {
case IGET_QUICK:
case IGET_WIDE_QUICK: