isOdexFile was no longer being used, and hasOdexOpcodes had a slightly
misleading name, since it could potentially return true for an odex or
oat embedded dex file that didn't actually have any odex opcodes.
The current implementation only supported 6 of the possible kind values for a MethodHandle object.
However, as the link below shows there are in fact 9. All 9 can be seen in the MethodHandleType
class which is used by dexdump to translate the kind value of a MethodHandle object to a string
representation.
https://android.googlesource.com/platform/art/+/android-8.1.0_r41/runtime/dex_file.h
Moreover, this in fact lines up with the 9 different kinds for a MethodHandle object in standard
java bytecode (though the values are swapped around for some reason).
https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandleInfo.html
These changes add in the additional 3 kind values and make sure all nesscary hooks using the
kind values of MethodHandle reference them.
For testing purposes, I found the easiest way to get correctly formatted invoke-custom and
invoke-polymorphic instructions was to use the already generated dex files used to test
dexdump. They can be found at the link below (invoke-custom.dex and invoke-polymorphic.dex).
https://android.googlesource.com/platform/art/+/android-8.1.0_r41/test/dexdump/
Previously the offset of the method prototype was 3 bytes from the
instruction start for both instructions. This would put it somewhere in
the middle of the register values and method reference. Changed it to
the correct offset which is 6 bytes in both cases.
45cc Instruction Format
op(8 bits)
number_of_regs(4 bits)
reg_g(4 bits)
method_reference(16 bits)
reg_d(4 bits)
reg_c(4 bits)
reg_f(4 bits)
ref_e(4 bits)
method_prototype(16 bits)
Example of invoke-polymorphic using 45cc
Instruction: fa302f0021030800
DexDump: invoke-polymorphic {v1, v2, v3}, Ljava/lang/invoke/MethodHandle;
.invoke:([Ljava/lang/Object;)Ljava/lang/Object;,
(II)Ljava/lang/Object; // method@002f, proto@0008
4rcc Instruction Format
op(8 bits)
number_of_regs(8 bits)
method_reference(16 bits)
start_register(16 bits)
method_prototype(16 bits)
Example of invoke-polymorphic using 4rcc
Instruction: fb092f0000000800
DexDump: invoke-polymorphic/range {v0, v1, v2, v3, v4, v5, v6, v7, v8},
Ljava/lang/invoke/MethodHandle;.invoke:([Ljava/lang/Object;)
Ljava/lang/Object;, (IIIIIIILjava/lang/String;)Ljava/lang/Object;
// method@002f, proto@0008
Note that this commit silently changes the behavior of dexlib2 public API.
But mapDexVersionToApi was made available only a day ago in dexlib2 2.2.4,
and if the next version is published quickly, then this change should have
no real impact on clients.
Now, util only contains the utilities that are needed by smali/baksmali,
but not dexlib2. E.g. the common command line parsing utilities, some path
utilities, etc.
This also reverses the dependency between the util module and dexlib2.
- The OAT Header has a new field containing the offset to the
entries for the DEX files.
- The change was made in OAT 127.
- All offsets in the header had to be adjusted to account
for this new field.
- The offset to the entries for the DEX files also had to
be adjusted to use this field as they are no longer
right after the key value store.
- The format of the DEX entries also changed in OAT 127 and
again in OAT 131.
- The field containing the offset to the method bss
mapping was added in OAT 127.
- The field containing the offset to the dex sections
layout was added in OAT 131 right before the method
bss mapping offset.