【发布时间】:2020-11-28 18:39:38
【问题描述】:
我了解 ELF 及其程序标头。当我使用readelf 读取文件类型为DYN 的ELF 时。我看到 Program Headers 中的虚拟地址值实际上来自内核虚拟地址空间。
Elf file type is DYN (Shared object file)
Entry point 0x1060
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000600 0x0000000000000600 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001f5 0x00000000000001f5 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000168 0x0000000000000168 R 0x1000
LOAD 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8
0x0000000000000258 0x0000000000000260 RW 0x1000
DYNAMIC 0x0000000000002dc8 0x0000000000003dc8 0x0000000000003dc8
0x00000000000001f0 0x00000000000001f0 RW 0x8
NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358
0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x0000000000002018 0x0000000000002018 0x0000000000002018
0x0000000000000044 0x0000000000000044 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8
0x0000000000000248 0x0000000000000248 R 0x1
我能够推断出在加载二进制文件时实际的 VirtAddr 应该是 = 基地址 + VirtAddr。但是我不知道加载器是如何计算基地址值的?
另外,我知道 .text 和 .data 是用于加载二进制文件的两个 PT_LOAD 段。但我在示例中看到了 4 个 PT_LOAD 程序头。两个 PT_LOAD 程序头是干什么用的?
【问题讨论】:
-
我实际上只从这个页面得到了基地址的想法。它说“可执行和共享目标文件有一个基地址,它是与程序目标文件的内存映像相关联的最低虚拟地址。基地址的一种用途是在动态链接期间重新定位程序的内存映像。”但我仍然不知道如何找到最低的虚拟地址?
标签: c executable elf dynamic-linking readelf