Android 中 vector 反汇编示例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013989732/article/details/82777625

前言

最近遇到一个 native crash 问题,如下所示:(Android 8.1)

Revision: '0'
ABI: 'arm64'
pid: 1863, tid: 3348, name: Binder:1863_F  >>> system_server <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8
Cause: null pointer dereference
    x0   c200007682ae00c0  x1   0000000070556938  x2   0000000000000001  x3   000000761afa89d8
    x4   00000000137c0248  x5   0000000000000010  x6   0000000000000001  x7   0000000000000008
    x8   0000000000000000  x9   238e9a517469cba9  x10  000000761afa89d4  x11  000000764e6e47b8
    x12  0000000000000006  x13  0000000000000019  x14  0000000000000229  x15  0000000000000007
    x16  000000761afa89d8  x17  0000000000000020  x18  0000000000000008  x19  0000000070556938
    x20  0000000000000001  x21  000000761afa9588  x22  000000764eaa9300  x23  000000764eaa93f8
    x24  000000764e623e73  x25  000000764e623e7b  x26  0000000000000043  x27  000000761afa9588
    x28  0000000000000059  x29  000000761afa88a0  x30  000000764e2dde4c
    sp   000000761afa8860  pc   000000764e2cae80  pstate 0000000080000000
    v0   0000000000000000ffffffffffffffff  v1   000000761afa90a0000000761afa9110
    v2   000000000000000075636553636e7953  v3   00000000000000000000000000000000
    v4   00000000000000000000000000000000  v5   00000000000000004000000000000000
    v6   00000000000000000000000000000000  v7   00000000000000008020080280200802
    v8   00000000000000000000000000000000  v9   00000000000000000000000000000000
    v10  00000000000000000000000000000000  v11  00000000000000000000000000000000
    v12  00000000000000000000000000000000  v13  00000000000000000000000000000000
    v14  00000000000000000000000000000000  v15  00000000000000000000000000000000
    v16  40100401401004014010040140100401  v17  80080000000000008800000000404000
    v18  80000800000000000000000000000000  v19  0000000000000000d362ff28f3dabbdf
    v20  000000000000000000000000ebad8084  v21  000000000000000000000000ebad8085
    v22  000000000000000000000000ebad8086  v23  000000000000000000000000ebad8087
    v24  000000000000000000000000ebad8088  v25  000000000000000000000000ebad8089
    v26  000000000000000000000000ebad808a  v27  000000000000000000000000ebad808b
    v28  000000000000000000000000ebad808c  v29  000000000000000000000000ebad808d
    v30  000000000000000000000000ebad808e  v31  000000000000000000000000133c7810
    fpsr 00000013  fpcr 00000000

backtrace:
    #00 pc 0000000000215e80  /system/lib64/libart.so (art::gc::Heap::FindContinuousSpaceFromObject(art::ObjPtr<art::mirror::Object>, bool) const+68)
    #01 pc 0000000000228e48  /system/lib64/libart.so (art::gc::Heap::IsMovableObject(art::ObjPtr<art::mirror::Object>) const+12)
    #02 pc 0000000000382f04  /system/lib64/libart.so (art::JNI::GetStringCritical(_JNIEnv*, _jstring*, unsigned char*)+596)
    #03 pc 000000000011342c  /system/lib64/libandroid_runtime.so (android::android_os_Parcel_enforceInterface(_JNIEnv*, _jclass*, long, _jstring*)+76)
    #04 pc 0000000000cc9254  /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.app.admin.SecurityLog.readEventsOnWrapping [DEDUPED]+180)
    #05 pc 000000000177afc8  /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.os.Parcel.enforceInterface+56)
    #06 pc 00000000014f05ec  /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.net.IConnectivityManager$Stub.onTransact+17724)
    #07 pc 00000000009c017c  /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.os.Binder.execTransact+524)
    #08 pc 0000000000549588  /system/lib64/libart.so (art_quick_invoke_stub+584)
    #09 pc 00000000000dd178  /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
    #10 pc 000000000046d290  /system/lib64/libart.so (art::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::ArgArray*, art::JValue*, char const*)+100)
    #11 pc 000000000046e718  /system/lib64/libart.so (art::InvokeVirtualOrInterfaceWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+440)
    #12 pc 0000000000347ed8  /system/lib64/libart.so (art::JNI::CallBooleanMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+624)
    #13 pc 00000000000bba88  /system/lib64/libandroid_runtime.so (_JNIEnv::CallBooleanMethod(_jobject*, _jmethodID*, ...)+120)
    #14 pc 000000000011f2cc  /system/lib64/libandroid_runtime.so (JavaBBinder::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+156)
    #15 pc 000000000004ae38  /system/lib64/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+136)
    #16 pc 0000000000054e04  /system/lib64/libbinder.so (android::IPCThreadState::executeCommand(int)+532)
    #17 pc 0000000000054b40  /system/lib64/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+156)
    #18 pc 0000000000055178  /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+60)
    #19 pc 00000000000761f8  /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24)
    #20 pc 0000000000011460  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+280)
    #21 pc 00000000000ab6a0  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140)
    #22 pc 0000000000067e3c  /system/lib64/libc.so (__pthread_start(void*)+36)
    #23 pc 000000000001f280  /system/lib64/libc.so (__start_thread+68)

在反汇编 FindContinuousSpaceFromObject 方法的时候,始终理解的不太清楚,因此,使用 gdb 来辅助理解一下。因为 gdb 调试过程当中,使用了一些 gdb 分析的常用技巧,并且新了解到了一些汇编知识,因此,将自己的一些收获总结下来。(注:因为手头的机器恰好是 Android 7.0 的,所以 gdb 调试分析过程基于 Android 7.0,与上面的 log 略有不同)

一、FindContinuousSpaceFromObject

首先看一下 FindContinuousSpaceFromObject 方法的实现,基于 Android 7.0:
art/runtime/gc/heap.cc

space::ContinuousSpace* Heap::FindContinuousSpaceFromObject(const mirror::Object* obj,
                                                            bool fail_ok) const {
  for (const auto& space : continuous_spaces_) {
    if (space->Contains(obj)) {
      return space;
    }
  }
  if (!fail_ok) {
    LOG(FATAL) << "object " << reinterpret_cast<const void*>(obj) << " not inside any spaces!";
  }
  return nullptr;
}

二、gdb 分析过程

首先,我们需要将断点设置在 FindContinuousSpaceFromObject 方法处,通过:

nm libart.so | grep -i FindContinuousSpaceFromObject

我们可以知道 FindContinuousSpaceFromObject 对应的 symbol 为:

_ZNK3art2gc4Heap29FindContinuousSpaceFromObjectEPKNS_6mirror6ObjectEb

通过 b 来设置断点,continue 使程序继续运行:
在这里插入图片描述
通过 disass 查看其对应的汇编代码:

Dump of assembler code for function art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const:
   0x0000007fa15dd42c <+0>:	stp	x24, x23, [sp,#-64]!
   0x0000007fa15dd430 <+4>:	stp	x22, x21, [sp,#16]
   0x0000007fa15dd434 <+8>:	stp	x20, x19, [sp,#32]
   0x0000007fa15dd438 <+12>:	stp	x29, x30, [sp,#48]
   0x0000007fa15dd43c <+16>:	add	x29, sp, #0x30
   0x0000007fa15dd440 <+20>:	sub	sp, sp, #0x10
   0x0000007fa15dd444 <+24>:	adrp	x22, 0x7fa19f8000 <_ZTVN3art5arm6412Arm64ContextE+32>
   0x0000007fa15dd448 <+28>:	ldr	x22, [x22,#1368]
   0x0000007fa15dd44c <+32>:	mov	w20, w2
   0x0000007fa15dd450 <+36>:	mov	x19, x1
   0x0000007fa15dd454 <+40>:	ldr	x22, [x22]
   0x0000007fa15dd458 <+44>:	str	x22, [sp,#8]
=> 0x0000007fa15dd45c <+48>:	ldp	x23, x21, [x0]
   0x0000007fa15dd460 <+52>:	cmp	x23, x21
   0x0000007fa15dd464 <+56>:	b.eq	0x7fa15dd494 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+104>
   0x0000007fa15dd468 <+60>:	mov	x24, x23
   0x0000007fa15dd46c <+64>:	ldr	x0, [x24],#8
   0x0000007fa15dd470 <+68>:	mov	x1, x19
   0x0000007fa15dd474 <+72>:	ldr	x8, [x0]
   0x0000007fa15dd478 <+76>:	ldr	x8, [x8,#8]
   0x0000007fa15dd47c <+80>:	blr	x8
   0x0000007fa15dd480 <+84>:	and	w8, w0, #0x1
   0x0000007fa15dd484 <+88>:	tbnz	w8, #0, 0x7fa15dd530 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+260>
   0x0000007fa15dd488 <+92>:	cmp	x21, x24
   0x0000007fa15dd48c <+96>:	mov	x23, x24
   0x0000007fa15dd490 <+100>:	b.ne	0x7fa15dd468 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+60>
   0x0000007fa15dd494 <+104>:	and	w8, w20, #0x1
   0x0000007fa15dd498 <+108>:	tbz	w8, #0, 0x7fa15dd4a4 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+120>
   0x0000007fa15dd49c <+112>:	mov	x0, xzr
   0x0000007fa15dd4a0 <+116>:	b	0x7fa15dd534 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+264>
   0x0000007fa15dd4a4 <+120>:	adrp	x1, 0x7fa195e000
   0x0000007fa15dd4a8 <+124>:	add	x1, x1, #0xb83
   0x0000007fa15dd4ac <+128>:	mov	x0, sp
   0x0000007fa15dd4b0 <+132>:	mov	w2, #0x515                 	// #1301
   0x0000007fa15dd4b4 <+136>:	orr	w3, wzr, #0x6
   0x0000007fa15dd4b8 <+140>:	mov	w4, #0xffffffff            	// #-1
   0x0000007fa15dd4bc <+144>:	bl	0x7fa14be818 <art::LogMessage::LogMessage(char const*, unsigned int, art::LogSeverity, int)>
   0x0000007fa15dd4c0 <+148>:	mov	x0, sp
   0x0000007fa15dd4c4 <+152>:	bl	0x7fa14be810 <art::LogMessage::stream()>
   0x0000007fa15dd4c8 <+156>:	adrp	x21, 0x7fa195f000
   0x0000007fa15dd4cc <+160>:	add	x21, x21, #0x806
   0x0000007fa15dd4d0 <+164>:	mov	x20, x0
   0x0000007fa15dd4d4 <+168>:	orr	w1, wzr, #0x8
   0x0000007fa15dd4d8 <+172>:	mov	x0, x21
   0x0000007fa15dd4dc <+176>:	bl	0x7fa1497b00 <__strlen_chk@plt>
   0x0000007fa15dd4e0 <+180>:	mov	x2, x0
   0x0000007fa15dd4e4 <+184>:	mov	x0, x20
   0x0000007fa15dd4e8 <+188>:	mov	x1, x21
   0x0000007fa15dd4ec <+192>:	bl	0x7fa14b5c74 <std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long)>
   0x0000007fa15dd4f0 <+196>:	mov	x1, x19
   0x0000007fa15dd4f4 <+200>:	bl	0x7fa14b5abc <std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(void const*)>
   0x0000007fa15dd4f8 <+204>:	adrp	x20, 0x7fa195f000
   0x0000007fa15dd4fc <+208>:	add	x20, x20, #0x80e
   0x0000007fa15dd500 <+212>:	mov	x19, x0
   0x0000007fa15dd504 <+216>:	orr	w1, wzr, #0x18
   0x0000007fa15dd508 <+220>:	mov	x0, x20
   0x0000007fa15dd50c <+224>:	bl	0x7fa1497b00 <__strlen_chk@plt>
   0x0000007fa15dd510 <+228>:	mov	x2, x0
   0x0000007fa15dd514 <+232>:	mov	x0, x19
   0x0000007fa15dd518 <+236>:	mov	x1, x20
   0x0000007fa15dd51c <+240>:	bl	0x7fa14b5c74 <std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long)>
   0x0000007fa15dd520 <+244>:	mov	x0, sp
   0x0000007fa15dd524 <+248>:	bl	0x7fa14be964 <art::LogMessage::~LogMessage()>
   0x0000007fa15dd528 <+252>:	mov	x0, xzr
   0x0000007fa15dd52c <+256>:	b	0x7fa15dd534 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+264>
   0x0000007fa15dd530 <+260>:	ldr	x0, [x23]
   0x0000007fa15dd534 <+264>:	ldr	x8, [sp,#8]
   0x0000007fa15dd538 <+268>:	sub	x8, x22, x8
   0x0000007fa15dd53c <+272>:	cbnz	x8, 0x7fa15dd558 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+300>
   0x0000007fa15dd540 <+276>:	sub	sp, x29, #0x30
   0x0000007fa15dd544 <+280>:	ldp	x29, x30, [sp,#48]
   0x0000007fa15dd548 <+284>:	ldp	x20, x19, [sp,#32]
   0x0000007fa15dd54c <+288>:	ldp	x22, x21, [sp,#16]
   0x0000007fa15dd550 <+292>:	ldp	x24, x23, [sp],#64
   0x0000007fa15dd554 <+296>:	ret
   0x0000007fa15dd558 <+300>:	bl	0x7fa1497af0 <__stack_chk_fail@plt>
End of assembler dump.

我们主要关注一下:

Dump of assembler code for function art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const:
   0x0000007fa15dd42c <+0>:	stp	x24, x23, [sp,#-64]!
   0x0000007fa15dd430 <+4>:	stp	x22, x21, [sp,#16]
   0x0000007fa15dd434 <+8>:	stp	x20, x19, [sp,#32]
   0x0000007fa15dd438 <+12>:	stp	x29, x30, [sp,#48]
   0x0000007fa15dd43c <+16>:	add	x29, sp, #0x30
   0x0000007fa15dd440 <+20>:	sub	sp, sp, #0x10
   0x0000007fa15dd444 <+24>:	adrp	x22, 0x7fa19f8000 <_ZTVN3art5arm6412Arm64ContextE+32>
   0x0000007fa15dd448 <+28>:	ldr	x22, [x22,#1368]
   // 此处开始主要部分
   0x0000007fa15dd44c <+32>:	mov	w20, w2    // 参数2,bool fail_ok
   0x0000007fa15dd450 <+36>:	mov	x19, x1    // 参数1,const mirror::Object* obj
   0x0000007fa15dd454 <+40>:	ldr	x22, [x22]
   0x0000007fa15dd458 <+44>:	str	x22, [sp,#8]
=> 0x0000007fa15dd45c <+48>:	ldp	x23, x21, [x0]    // x0 中是 this 指针,即指向 Heap 对象的指针
   0x0000007fa15dd460 <+52>:	cmp	x23, x21
   0x0000007fa15dd464 <+56>:	b.eq	0x7fa15dd494 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+104>
   // b.ne	0x7fa15dd468 会跳转到此处
   0x0000007fa15dd468 <+60>:	mov	x24, x23
   0x0000007fa15dd46c <+64>:	ldr	x0, [x24],#8
   0x0000007fa15dd470 <+68>:	mov	x1, x19
   0x0000007fa15dd474 <+72>:	ldr	x8, [x0]
   0x0000007fa15dd478 <+76>:	ldr	x8, [x8,#8]
   0x0000007fa15dd47c <+80>:	blr	x8
   0x0000007fa15dd480 <+84>:	and	w8, w0, #0x1
   0x0000007fa15dd484 <+88>:	tbnz	w8, #0, 0x7fa15dd530 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+260>
   0x0000007fa15dd488 <+92>:	cmp	x21, x24
   0x0000007fa15dd48c <+96>:	mov	x23, x24
   0x0000007fa15dd490 <+100>:	b.ne	0x7fa15dd468 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+60>

这一段是循环的主要内容,如下所示:

  for (const auto& space : continuous_spaces_) {
    if (space->Contains(obj)) {
      return space;
    }
  }

从上面的注释来看,我们可以知道,x0 中是 this 指针,即指向 Heap 对象的指针,那么

0x0000007fa15dd45c <+48>:	ldp	x23, x21, [x0] 

是在干什么呢?我们可以通过

b *0x0000007fa15dd460

把断点打在

扫描二维码关注公众号,回复: 3796080 查看本文章
0x0000007fa15dd460 <+52>:	cmp	x23, x21

处,然后看一下各个寄存器的值来加以分析。

// x0 即为 0x7fa1a4c700
(gdb) p /x $x0
$1 = 0x7fa1a4c700
// 因为 x0 中是指向 ‘art::gc::Heap’ 类型的指针,所以 print 一下其对应的对象
(gdb) p ('art::gc::Heap')*0x7fa1a4c700
$2 = {
  static kDefaultStartingSize = 4096, 
  static kDefaultInitialSize = 2097152, 
  ...
  continuous_spaces_ = {
    <std::__1::__vector_base<art::gc::space::ContinuousSpace*, std::__1::allocator<art::gc::space::ContinuousSpace*> >> = {
      <std::__1::__vector_base_common<true>> = {<No data fields>}, 
      members of std::__1::__vector_base<art::gc::space::ContinuousSpace*, std::__1::allocator<art::gc::space::ContinuousSpace*> >: 
      __begin_ = 0x7fa1a80200, 
      __end_ = 0x7fa1a802c0, 
      __end_cap_ = {
  ...
}
// 所以可知 Heap 对象的第一个成员即为 continuous_spaces_,
// 其类型为 'std::__1::__vector_base<art::gc::space::ContinuousSpace*, std::__1::allocator<art::gc::space::ContinuousSpace*> >' 
// 所以 ldp	x23, x21, [x0] 对应的就是分别把 __begin_ 和 __end_ 放在了 x23、x21 中
// 可以验证一下
(gdb) p /x $x23
$5 = 0x7fa1a80200
(gdb) p /x $x21
$6 = 0x7fa1a802c0
// 所以 cmp	x23, x21 就是比较  __begin_(或当前指针)和 __end_ 两个指针
// 从而我们可以确定 continuous_spaces_ 中是否还有元素

接下来调整断点到

0x0000007fa15dd47c <+80>:	blr	x8
   // x24 = x23,即 x24 现在为 __begin_
   0x0000007fa15dd468 <+60>:	mov	x24, x23
   0x0000007fa15dd46c <+64>:	ldr	x0, [x24],#8
   // x23 即 __begin_
(gdb) p /x $x23
$7 = 0x7fa1a80200
   // x24 比 __begin_ 多 8,可知 ldr	x0, [x24],#8 会使 x24 = x24 + 8
   // 即指针增加一个元素单位长度
(gdb) p /x $x24
$8 = 0x7fa1a80208
   // 因为 x0 中的值等于地址 0x7fa1a80200 中的值,此时 x24 还没加 8
   // 所以 ldr	x0, [x24],#8 可以看作
   // 先 ldr	x0, [x24]
   // 再 x24 = x24 + 8
(gdb) p /x $x0
$9 = 0x7fa1aa3380
(gdb) x/1xg 0x7fa1a80200
0x7fa1a80200:	0x0000007fa1aa3380
(gdb) x/1xg 0x7fa1a80208
0x7fa1a80208:	0x0000007fa1a26300
   // x1 为参数1,即 const mirror::Object* obj
   0x0000007fa15dd470 <+68>:	mov	x1, x19
   // x0 中是一个 art::gc::space::ContinuousSpace* 指针
   // 所以 x8 中赋值的是一个 art::gc::space::ContinuousSpace 对象的数据
   0x0000007fa15dd474 <+72>:	ldr	x8, [x0]
   // 即应该为 0x7fa19ef428
(gdb) p ('art::gc::space::ContinuousSpace')*0x7fa1aa3380
$12 = {
  <art::gc::space::Space> = {
    _vptr$Space = 0x7fa19ef428 <vtable for art::gc::space::RosAllocSpace+16>, 
    name_ = {
    ...  
}
   // 所以 load 之后 x8 中应该为地址 0x7fa19ef428+8 上的值
   0x0000007fa15dd478 <+76>:	ldr	x8, [x8,#8]
   // 验证一下:
(gdb) p /x $x8
$13 = 0x7fa15f4f78
(gdb) p /x 0x7fa19ef428 + 8
$14 = 0x7fa19ef430
(gdb) x/1xg 0x7fa19ef430
0x7fa19ef430 <_ZTVN3art2gc5space13RosAllocSpaceE+24>:	0x0000007fa15f4f78
   // 验证没问题   
=> 0x0000007fa15dd47c <+80>:	blr	x8
   0x0000007fa15dd480 <+84>:	and	w8, w0, #0x1
   0x0000007fa15dd484 <+88>:	tbnz	w8, #0, 0x7fa15dd530 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+260>
   0x0000007fa15dd488 <+92>:	cmp	x21, x24
   0x0000007fa15dd48c <+96>:	mov	x23, x24
   0x0000007fa15dd490 <+100>:	b.ne	0x7fa15dd468 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+60>

上面解释了各个汇编指令大体的意思,并结合 gdb 做了一些测试;那么

_vptr$Space = 0x7fa19ef428 <vtable for art::gc::space::RosAllocSpace+16> 

是什么呢?为什么 blr x8 就相当于调用 Contains() 方法了呢?
原因是 art::gc::space::ContinuousSpace 的父类为 class art::gc::space::Space,查看其结构:

(gdb) ptype 'art::gc::space::Space'
type = class art::gc::space::Space {
  protected:
    std::__1::string name_;
    art::gc::space::GcRetentionPolicy gc_retention_policy_;

  public:
    virtual void Dump(std::__1::ostream &) const;
    const char * GetName(void) const;
    art::gc::space::GcRetentionPolicy GetGcRetentionPolicy(void) const;
    virtual bool Contains(const art::mirror::Object *) const;
    virtual art::gc::space::SpaceType GetType(void) const;
    bool IsImageSpace(void) const;
    art::gc::space::ImageSpace * AsImageSpace(void);
    bool IsMallocSpace(void) const;
    art::gc::space::MallocSpace * AsMallocSpace(void);
    virtual bool IsDlMallocSpace(void) const;
    virtual art::gc::space::DlMallocSpace * AsDlMallocSpace(void);
    virtual bool IsRosAllocSpace(void) const;
    virtual art::gc::space::RosAllocSpace * AsRosAllocSpace(void);
    bool IsZygoteSpace(void) const;
    virtual art::gc::space::ZygoteSpace * AsZygoteSpace(void);
    bool IsBumpPointerSpace(void) const;
    virtual art::gc::space::BumpPointerSpace * AsBumpPointerSpace(void);
    bool IsRegionSpace(void) const;
    virtual art::gc::space::RegionSpace * AsRegionSpace(void);
    bool IsLargeObjectSpace(void) const;
    art::gc::space::LargeObjectSpace * AsLargeObjectSpace(void);
    virtual bool IsContinuousSpace(void) const;
    art::gc::space::ContinuousSpace * AsContinuousSpace(void);
    virtual bool IsDiscontinuousSpace(void) const;
    art::gc::space::DiscontinuousSpace * AsDiscontinuousSpace(void);
    virtual bool IsAllocSpace(void) const;
    virtual art::gc::space::AllocSpace * AsAllocSpace(void);
    virtual bool IsContinuousMemMapAllocSpace(void) const;
    virtual art::gc::space::ContinuousMemMapAllocSpace * AsContinuousMemMapAllocSpace(void);
    virtual bool CanMoveObjects(void) const;
    virtual ~Space(void);
  protected:
    Space(const std::__1::string &, art::gc::space::GcRetentionPolicy);
  private:
    Space(void);
    Space(const art::gc::space::Space &);
  protected:
    void SetGcRetentionPolicy(art::gc::space::GcRetentionPolicy);
  private:
    void operator=(const art::gc::space::Space &);
}

其中存在虚函数,0x7fa19ef428 即为 art::gc::space::ContinuousSpace 实例的自动生成的 vtable 的地址,用于查找对应的虚函数的调用地址,因为 Contains() 方法为第二个虚函数,所以 0x7fa19ef428+8 中的值才为 Contains() 方法的跳转地址。

三、总结

需要注意的点:

  • ldr x8, [x0]:假设 x0 中为 num_ptr,这里就为取地址 num_ptr 中的值放到 x8 中
  • ldr x8, [x8,#8]:假设 x8 中为 num_ptr,这里就为取地址(num_ptr+8)中的值放到 x8 中
  • ldr x0, [x24],#8:假设 x24 中为 num_ptr,这里就为取地址 num_ptr 中的值放到 x0 中,并且将 (num_ptr+8)放到 x24 中
  • 注意 vtable
  • for (const auto& space : continuous_spaces_) 依据 std::__1::__vector_base 的 _begin、_end 指针以及指向当前元素的指针来判断是否结束循环

猜你喜欢

转载自blog.csdn.net/u013989732/article/details/82777625
今日推荐