ART深入浅出(7) - OAT文件的格式

本文基于Android 7.1,不过因为从BSP拿到的版本略有区别,所以本文提到的源码未必与读者找到的源码完全一致。本文在提供源码片断时,将按照 : 的方式,如果行号对不上,请参考类名和函数名来找到对应的源码。从本章开始,我将介绍OAT文件的格式以ELF文件格式作为外壳从手机上下载一个oat文件。一般我都是研究boot.oat。比如,用命令 adb pull /data/da
摘要由CSDN通过智能技术生成

本文基于Android 7.1,不过因为从BSP拿到的版本略有区别,所以本文提到的源码未必与读者找到的源码完全一致。本文在提供源码片断时,将按照 <源码相对android工程的路径>:<行号> <类名> <函数名> 的方式,如果行号对不上,请参考类名和函数名来找到对应的源码。

了解ART的基本运作原理,就需要了解ART编译出的代码是怎么运行的。我们将使用oatdump得到的代码,进行仔细分析。

从简单示例出发

以一个非常简单的函数为例:
frameworks/base/core/java/android/app/Activity.java:988

988    public void onCreate(@Nullable Bundle savedInstanceState,
989            @Nullable PersistableBundle persistentState) {
990        onCreate(savedInstanceState);
991    }

这个函数,仅仅是调用了同名的onCreate函数的实现。
编译成oat文件后(存放在boot.oat内),用oatdump出来,我找到对应的dex代码

  129: void android.app.Activity.onCreate(android.os.Bundle, android.os.PersistableBundle) (dex_method_idx=2085)
    DEX CODE:
      0x0000: 6e20 2408 1000            | invoke-virtual {v0, v1}, void android.app.Activity.onCreate(android.os.Bundle) // method@2084
      0x0003: 0e00                      | return-void

这个dex代码看起来也非常简单。
接下来,我们看看编译出的机器码,反汇编后是什么:

    QuickMethodFrameInfo
      frame_size_in_bytes: 48
      core_spill_mask: 0x000040e0 (r5, r6, r7, r14)
      fp_spill_mask: 0x00000000 
      vr_stack_locations:
        ins: v0[sp + #52] v1[sp + #56] v2[sp + #60]
        method*: v3[sp + #0]
        outs: v0[sp + #4] v1[sp + #8]
    CODE: (code_offset=0x0337a6d5 size_offset=0x0337a6d0 size=66)...
      0x0337a6d4: f5ad5c00  sub     r12, sp, #8192
      0x0337a6d8: f8dcc000  ldr.w   r12, [r12, #0]
        StackMap [native_pc=0x337a6dd] (dex_pc=0x0, native_pc_offset=0x8, dex_register_map_offset=0xffffffff, inline_info_offset=0xffffffff, register_mask=0x0, stack_mask=0b000000)
      0x0337a6dc: b5e0      push    {
  r5, r6, r7, lr}
      0x0337a6de: b088      sub     sp, sp, #32
      0x0337a6e0: 9000      str     r0, [sp, #0]
      0x0337a6e2: f8b9c000  ldrh.w  r12, [r9, #0]  ; state_and_flags
      0x0337a6e6: f1bc0f00  cmp.w   r12, #0
      0x0337a6ea: d10a      bne     +20 (0x0337a702)
      0x0337a6ec: 461d      mov     r5, r3
      0x0337a6ee: 460e      mov     r6, r1
      0x0337a6f0: 4617      mov     r7, r2
      0x0337a6f2: 6808      ldr     r0, [r1, #0]
      0x0337a6f4: f8d004c8  ldr.w   r0, [r0, #1224]
      0x0337a6f8: f8d0e020  ldr.w   lr, [r0, #32]
      0x0337a6fc: 47f0      blx     lr
        StackMap [native_pc=0x337a6ff] (dex_pc=0x0, native_pc_offset=0x2a, dex_register_map_offset=0x0, inline_info_offset=0xffffffff, register_mask=0xe0, stack_mask=0b000000)
          v0: in register (6)   [entry 0]
          v1: in register (7)   [entry 1]
          v2: in register (5)   [entry 2]
      0x0337a6fe: b008      add     sp, sp, #32
      0x0337a700: bde0      pop     {
  r5, r6, r7, pc}
      0x0337a702: 9103      str     r1, [sp, 
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值