LOAD 段未加载

LOAD 段未加载

在检查/proc/<PID>/mapsAndroid (8) 上运行的 aarch64 进程的文件时,我注意到以下部分:

726048e000-7260564000 r-xp 00000000 103:00 5402    /system/lib64/libc++.so
7260564000-7260565000 ---p 00000000 00:00 0
7260565000-726056d000 r--p 000d6000 103:00 5402    /system/lib64/libc++.so
726056d000-726056e000 rw-p 000de000 103:00 5402    /system/lib64/libc++.so
726056e000-7260571000 rw-p 00000000 00:00 0        [anon:.bss]
72605b3000-72605b5000 r-xp 00000000 103:00 5641    /system/lib64/libpackagelistparser.so

这是程序头表libc++.so

Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
PHDR           0x000040 0x0000000000009040 0x0000000000009040 0x0001c0 0x0001c0 R   0x8
LOAD           0x000000 0x0000000000009000 0x0000000000009000 0x0d58fc 0x0d58fc R E 0x1000
LOAD           0x0d68e0 0x00000000000e08e0 0x00000000000e08e0 0x007770 0x00aea8 RW  0x1000
DYNAMIC        0x0dbb40 0x00000000000e5b40 0x00000000000e5b40 0x000220 0x000220 RW  0x8
NOTE           0x000200 0x0000000000009200 0x0000000000009200 0x000038 0x000038 R   0x4
GNU_EH_FRAME   0x0d3058 0x00000000000dc058 0x00000000000dc058 0x0028a4 0x0028a4 R   0x4
GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0
GNU_RELRO      0x0d68e0 0x00000000000e08e0 0x00000000000e08e0 0x007720 0x007720 RW  0x10

0xe08e0取第二段的地址LOAD并加上 的基数0x726048e000,我得出0x726056e8e0。但是,如上面的映射文件所示,没有映射的段正确的在那个地址。相反,它与该[anon:.bss]段重叠。它甚至没有完全包含在段中,因为大小为 时0xaea8,其结束地址将为0x7260579788

答案1

打印的程序头表的最后一列readelfp_align头的成员,它定义了所定义段的对齐要求。来自 Linux 手册页elf(5)

该成员保存段在内存和文件中对齐的值。可加载进程段的 p_vaddr 和 p_offset 必须具有一致的值(以页面大小为模)。值 0 和 1 表示不需要对齐。否则,p_align 应为 2 的正整数幂,并且 p_vaddr 应等于 p_offset,以 p_align 为模。

由于对齐值的原因0x1000,初始化的只读数据段将包含在具有偏移量0x0d60000x0d68e0向下取整)和大小0x0080000x007770向上取整)的内存映射中,这正是maps文件显示的内容(第四个字段是文件偏移量)映射长度可以通过减去结束地址和起始地址来计算0x726056d000 - 0x7260565000 = 0x8000)。下面的两个映射具有相同的对齐方式,通过它们的保护标志可以猜测它们对应于已初始化数据段(.data)和未初始化数据段(.bss)。

相关内容