编译一个.java在Android上运行并经过oatdump反汇编查看oat文件
咱们有一个Java程序helloworld:java
public class HelloWorld { int add_call(int a,int b){ return a + b; } public static void main(String[] args) { HelloWorld m = new HelloWorld(); int c = m.add_call(1, 2); System.out.println("Hello xianlong"); } }
经过javac将程序编译成class文件,helloworld.class
javac Helloworld.java
接下来将.class经过dx工具转换成dex文件
./dx --dex --output=HelloWorld.dex HelloWorld.class
工具
这里要注意的是,个人dx文件使用的是以前系统源码中的prebuilts/sdk/tool
中的dx
。JDK
使用的是1.6。(1.8版本会出现错误)ui
以后将咱们的HelloWorld.dex
经过adb push到手机中,接下来经过dalvikvm就能够运行该dex文件。 dalvikvm -cp HelloWorld.dex HelloWorld
(这里的-cp是指class path)spa
若是咱们想dump一下oat文件,就要借助oatdump。 执行: oatdump --oat-file=HelloWorld.odex > dump.txt
就能够把dump结果保存到dump.txt中。 接下来咱们打开该文件能够看到:(部分)code
0: LHelloWorld; (offset=0x0000064c) (type_idx=1) (StatusInitialized) (OatClassSomeCompiled) 0: void HelloWorld.<init>() (dex_method_idx=0) DEX CODE: 0x0000: 7010 0400 0000 | invoke-direct {v0}, void java.lang.Object.<init>() // method@4 0x0003: 7300 | return-void-no-barrier OatMethodOffsets (offset=0x00000000) code_offset: 0x00000000 OatQuickMethodHeader (offset=0x00000000) vmap_table: (offset=0x00000000) QuickMethodFrameInfo frame_size_in_bytes: 0 core_spill_mask: 0x00000000 fp_spill_mask: 0x00000000 vr_stack_locations: ins: v0[sp + #8] method*: v1[sp + #0] outs: v0[sp + #8] CODE: (code_offset=0x00000000 size_offset=0x00000000 size=0) NO CODE! 1: void HelloWorld.main(java.lang.String[]) (dex_method_idx=2) DEX CODE: 0x0000: 2200 0100 | new-instance v0, HelloWorld // type@TypeIndex[1] 0x0002: 7010 0000 0000 | invoke-direct {v0}, void HelloWorld.<init>() // method@0 0x0005: 1211 | const/4 v1, #+1 0x0006: 1222 | const/4 v2, #+2 0x0007: e930 0b00 1002 | invoke-virtual-quick {v0, v1, v2}, // vtable@11 0x000a: 6200 0000 | sget-object v0, Ljava/io/PrintStream; java.lang.System.out // field@0 0x000c: 1a01 0100 | const-string v1, "Hello xianlong" // string@1 0x000e: e920 2c00 1000 | invoke-virtual-quick {v0, v1}, // vtable@44 0x0011: 7300 | return-void-no-barrier OatMethodOffsets (offset=0x00000658) code_offset: 0x00000000 OatQuickMethodHeader (offset=0x00001008) vmap_table: (offset=0x000003a4) quickened data QuickMethodFrameInfo frame_size_in_bytes: 0 core_spill_mask: 0x00000000 fp_spill_mask: 0x00000000 vr_stack_locations: locals: v0[sp + #4294967280] v1[sp + #4294967284] v2[sp + #4294967288] ins: v3[sp + #8] method*: v4[sp + #0] outs: v0[sp + #8] v1[sp + #12] v2[sp + #16] CODE: (code_offset=0x00000000 size_offset=0x0000101c size=0) NO CODE! 2: int HelloWorld.add_call(int, int) (dex_method_idx=1) DEX CODE: 0x0000: 9000 0203 | add-int v0, v2, v3 0x0002: 0f00 | return v0
发现都是dex code没有code,看来咱们须要手动编译才能AOT的生成机器码。(以后搞明白了会将手动AOT的方法添加在这个后边。)get