【发布时间】:2018-02-12 19:14:27
【问题描述】:
来自 ARM 的信息中心,关于 static linking and relocations 部分:
** Section #1 'ER_RO' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
Size : 28 bytes (alignment 4)
Address: 0x00008000
$a
.text
bar
0x00008000: E59f000C .... LDR r0,[pc,#12] ; [0x8014] = 0x801C
0x00008004: E5901000 .... LDR r1,[r0,#0]
0x00008008: E2411001 ..A. SUB r1,r1,#1
0x0000800C: E5801000 .... STR r1,[r0,#0]
0x00008010: E12FFF1E ../. BX lr
$d
0x00008014: 0000801C .... DCD 32796
$a
.text
foo
0x00008018: EAFFFFF8 .... B bar ; 0x8000
来自ELF for the ARM architecture:
表 4-7,映射符号
名称含义
$a - ARM 指令序列的开始
$d - 数据项序列的开始(例如,文字池)
如您所见,ELF 文件包含一个部分,其中有代码 (bar),然后是 data/ro (32796),然后是连续地址中的更多代码 (foo)。
现在,关于任何 SW 文件结构的基本原则是 SW 由不同且独立的部分组成 - text(代码)、data 和 bss。 (以及rodata,如果我们想学究气),我们可以查看MAP 文件。
那么,这个ELF结构与这个基本原理是不相符的,所以我的问题是这里是怎么回事?我误会了这个基本原则吗?如果不是,那么这个ELF 结构会在运行时更改以满足部分分离吗?
为什么ELF部分在某个顺序地址空间中包含混合类型?
注意:我假设示例中使用的分散文件是默认文件,因为包含示例的文档不随示例提供任何分散文件。
【问题讨论】:
-
elf 文件为什么会关心这些部分?这是一个编译器内部概念。 Elf 和其他文件格式是关于加载二进制文件的。显然,如果您对 elf 文件进行 objdump,它会向您显示每个部分,信息就在那里不断挖掘。但是加载更有趣,如果将这些部分组合成一个线性可加载块,我希望文件将它们放在一个块中(PROGBITS)。
-
最初我会更担心通用 elf 而不是 arm 文档,然后如果您发现通用 elf 未涵盖的内容,请联系 arm 文档。
-
同样,您将 arm 工具链上的 arm 文档与可能的 gnu 工具链混淆了?独立的工具链,只要提供正确的结果,就可以以不同的方式遵循他们想要的任何规则(这意味着他们根据您使用的语言将代码实现为功能正确的东西)。