• 编译一个.java在Android上运行并通过oatdump反汇编查看oat文件


    编译一个.java在Android上运行并通过oatdump反汇编查看oat文件

    我们有一个Java程序helloworld:

    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中的dxJDK使用的是1.6。(1.8版本会出现错误)

    之后将我们的HelloWorld.dex通过adb push到手机中,接下来通过dalvikvm就可以运行该dex文件。
    dalvikvm -cp HelloWorld.dex HelloWorld(这里的-cp是指class path)

    如果我们想dump一下oat文件,就要借助oatdump。
    执行: oatdump --oat-file=HelloWorld.odex > dump.txt
    就可以把dump结果保存到dump.txt中。
    接下来我们打开该文件可以看到:(部分)

    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的方法添加在这个后边。)

  • 相关阅读:
    WinForm 清空界面控件值的小技巧
    MVC 图片上传总是request.files.count() 等于0
    LinqToSQL 左连接右连接内链接
    C# utc datetime 互相转化
    mvc javascript form.submit()
    Java API中文版下载
    jQuery的链式操作
    【转】Eclipse/MyEclipse中使用复制粘贴功能卡的解决办法
    servlet什么时候被实例化?
    Jquery总结 $("h3 a", patch);
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/11843699.html
Copyright © 2020-2023  润新知