2

根据输出部分描述的ld手册:

 section [address] [(type)] :
   [AT(lma)]
   [ALIGN(section_align) | ALIGN_WITH_INPUT]
   [SUBALIGN(subsection_align)]
   [constraint]
   {
     output-section-command
     output-section-command
     ...
   } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp] [,]

地址>区域代表VMA,即输出部分的虚拟内存地址。

AT()AT>lma_region代表 LMA,即输出部分的加载内存地址。

我决定仔细查看readelf -e转储 helloworld elf 文件的节头程序头。结果如下:

节标题

程序头

我的问题是:

  • 为什么转储的标头中没有LMA?LMA 在 ELF 文件中如何表示?
  • 红色矩形中的 Addr 列是什么意思?虚拟机?
  • 绿色矩形中的 PhysAddr 是什么意思?

加 1

到目前为止,PhysAddr 似乎是 LMA。

4

1 回答 1

4

为什么转储的标头中没有LMA?LMA 如何在 ELF 文件中表示

首先,elf 文件中没有 LMA 头,它实际上很简单,ELF 文件中的多个部分被映射到段中,如果映射到段中的部分具有 LOAD 标志,例如(PROFBITS)是可加载的部分类型,并且它们映射到的段也是加载类型段(INTERP 和 LOAD),例如也是可加载段,这意味着该 elf 文件中该段中的每个部分都将加载到内存中。在哪里?只是给他们的VMA,所以在elf文件中没有LMA,LMA由VMA表示,因为应该加载指定类型/标志的部分。

红色矩形中的 addr 列是什么意思?

这与您之前的问题直接相关,是的!它确实意味着 VMA,为了正确解释这一点,我们需要了解 ELF 格式是为支持某些内存保护/内存分段的架构设计的。您可能希望为某些部分提供特殊权限,而不是为每个部分提供自己的内存保护,而是将多个部分映射到一个段中,并为唯一的段提供它自己的内存保护。

这导致需要将部分映射到段中,操作系统加载程序如何知道如何将每个部分映射到段中并由此为其提供适当的内存保护?通过它的地址。每个部分还被赋予一个地址,并且通过这些地址/偏移量/大小,它们被映射到一个段中,该段总体上将被分配到内存中,并给出了一些适用于所有部分的内存保护规则。

操作系统可以知道如何映射这些的唯一方法是通过地址,所以是的,如果该部分是可加载类型,它的 ADDR 表示 VMA(至少对于使用虚拟内存且不滥用 elf 文件的现代系统)

PhysAddr 是什么意思?

据我所知,PhysAddr 仅与物理寻址与用户空间程序相关的老式架构相关,这部分应该保存该段所在的实际物理地址,但在大多数现代系统中,这只是被忽略了。 ..

我建议您阅读此http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf

亲自回到学习这个的那天,它对我帮助很大,并给了我很多关于 ELF 文件的知识,希望我对你有所帮助!:)

于 2016-07-29T16:09:11.403 回答