好问题,感谢@R.. 的提示。只是为了提供一个扩展的答案:
最近,对于 Android,有人在我们的一台设备上报告了针对我们的 vdso 的失败测试用例。奇怪的是,本地内核构建无法重现该问题(其中 vdso.so 是内核构建过程的输出),因此我需要从实时设备中提取它的副本。
为了将 vdso 拉出正在运行的设备,您需要知道它的映射位置以及它的大小。此信息由/proc/<pid>/maps
长时间运行的进程(例如 pid 1、init)提供。前任:
$ adb root
$ adb shell cat /proc/1/maps | grep vdso
7fa6403000-7fa6405000 r-xp 00000000 00:00 0 [vdso]
所以这告诉我们 vdso 是 8192 字节(0x7fa6405000 - 0x7fa6403000 == 0x2000 == 8192),从0x7fa6403000开始。0x2000 不是 0x7fa6403000 的倍数(0x0.8的余数 == 0.5),所以我们使用4096(0x1000)(大小的一半)作为块大小,将计数加倍,并跳过块大小的133850115倍数(133850115 * 4096 == 548250071040 == 0x7FA6403000)。
$ adb shell dd if=/proc/1/mem of=/data/local/tmp/vdso.so bs=4096 count=2 skip=133850115
2+0 records in
2+0 records out
8192 bytes (8.0 K) copied, 0.000442 s, 18 M/s
$ adb shell ls -l /data/local/tmp
-rw-rw-rw- 1 root root 8192 2019-02-20 23:51 vdso.so
$ adb pull /data/local/tmp/vdso.so
/data/local/tmp/vdso.so: 1 file pulled. 3.2 MB/s (8192 bytes in 0.002s)
$ file vdso.so
vdso.so: ELF 64-bit LSB shared object ARM aarch64, version 1 (SYSV), dynamically linked, stripped
$ readelf -s vdso.so
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000000002e8 0 SECTION LOCAL DEFAULT 6
2: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.39
3: 00000000000007dc 108 FUNC GLOBAL DEFAULT 7
__kernel_clock_getres@@LINUX_2.6.39
4: 00000000000008c0 8 FUNC GLOBAL DEFAULT 7
__kernel_rt_sigreturn@@LINUX_2.6.39
5: 00000000000006e4 248 FUNC GLOBAL DEFAULT 7
__kernel_gettimeofday@@LINUX_2.6.39
6: 0000000000000848 96 FUNC GLOBAL DEFAULT 7
__kernel_time@@LINUX_2.6.39
7: 0000000000000300 996 FUNC GLOBAL DEFAULT 7
__kernel_clock_gettime@@LINUX_2.6.39