【问题标题】:Understanding certain ELF file structure了解某些 ELF 文件结构
【发布时间】: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(代码)、databss。 (以及rodata,如果我们想学究气),我们可以查看MAP 文件。

那么,这个ELF结构与这个基本原理是不相符的,所以我的问题是这里是怎么回事?我误会了这个基本原则吗?如果不是,那么这个ELF 结构会在运行时更改以满足部分分离吗? 为什么ELF部分在某个顺序地址空间中包含混合类型?

注意:我假设示例中使用的分散文件是默认文件,因为包含示例的文档不随示例提供任何分散文件。

【问题讨论】:

  • elf 文件为什么会关心这些部分?这是一个编译器内部概念。 Elf 和其他文件格式是关于加载二进制文件的。显然,如果您对 elf 文件进行 objdump,它会向您显示每个部分,信息就在那里不断挖掘。但是加载更有趣,如果将这些部分组合成一个线性可加载块,我希望文件将它们放在一个块中(PROGBITS)。
  • 最初我会更担心通用 elf 而不是 arm 文档,然后如果您发现通用 elf 未涵盖的内容,请联系 arm 文档。
  • 同样,您将 arm 工具链上的 arm 文档与可能的 gnu 工具链混淆了?独立的工具链,只要提供正确的结果,就可以以不同的方式遵循他们想要的任何规则(这意味着他们根据您使用的语言将代码实现为功能正确的东西)。

标签: c gcc linker arm elf


【解决方案1】:

在运行时,段无关紧要,只有程序头中的 PT_LOAD 段。那里的 ELF 规范也非常灵活,但是一些加载器对它们可以处理的 PT_LOAD 段有限制。

以这种方式拆分代码和数据的原因可能是该架构仅支持有限范围的 PC 相对寻址,并且需要一个常量池来加载大多数常量(因为通过立即数构造它们太昂贵了)。尽可能少的大型常量池很有吸引力,因为它可以提高数据和指令缓存的利用率(而不是缓存类型不正确且永远无法使用的内存),但如果代码大小超出了可以直接解决的范围。

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多