【问题标题】:ELF files - What is a section and why do we need it?ELF 文件 - 什么是节,我们为什么需要它?
【发布时间】:2023-03-04 09:44:01
【问题描述】:

我一直在阅读 ELF 标准 here。据我了解,每个 ELF 都包含 ELF 标头、程序标头(为什么不止一个?)和节标头。谁能解释一下:

  1. ELF 文件是如何生成的?是编译器的责任吗?
  2. 什么是部分,我们为什么需要它们?
  3. 什么是程序头,我们为什么需要它们?
  4. 在程序头中,字段 p_vaddr 和 p_paddr 的含义是什么?
  5. 每个部分都有自己的部分标题吗?

或者,有没有人有一个更友好的 ELF 文档的链接?

【问题讨论】:

    标签: elf


    【解决方案1】:

    这是我找到的最好的文档:http://www.skyfree.org/linux/references/ELF_Format.pdf

    1. 每个节只有一个节头,但可以有节头没有节

    【讨论】:

      【解决方案2】:

      2 - 有许多不同的部分,例如:重定位部分为重定位符号提供了许多信息。我使用信息加载一个精灵对象并运行/重新定位该对象。 另一个例子:调试部分记录调试信息,gdb 使用数据显示调试信息。 符号部分记录符号信息。

      3 - loader使用的编程头,loader通过查找编程头来加载elf执行文件。

      【讨论】:

        【解决方案3】:

        This link 包含更好的解释。

        1. ELF 文件是如何生成的?是编译器的责任吗?*

          它取决于架构。

        2. 什么是部分,我们为什么需要它们?

          不同的段有不同的信息,例如代码、初始化数据、未初始化数据等。这些信息将被编译器和链接器使用。

        3. 什么是程序头,我们为什么需要它们?

          操作系统在加载可执行文件时会使用程序头。这些标头包含有关段的信息(具有某些权限的连续内存块),例如需要加载哪些部分、解释器信息等。

        4. 在程序头中,字段 p_vaddr 和 p_paddr 的含义是什么?

          一般来说虚拟地址和物理地址是一样的。但可能因系统而异。

        5. 每个部分都有自己的部分标题吗?

          是的。每个节在节头表中都有一个节头条目。

        【讨论】:

          【解决方案4】:
          1. ELF 文件是如何生成的?是编译器的责任吗?

            它们可以由编译器、汇编器或任何其他可以生成它们的工具生成。即使是您自己编写的用于生成 ELF 文件的程序;)毕竟它们只是字节流,因此只需将字节以二进制模式写入文件即可生成它们。你也可以这样做。

          2. 什么是部分,我们为什么需要它们?

            ELF 文件被细分为多个部分。节是文件中最小的连续区域。您可以将它们视为管理器中的页面,每个页面都有自己的名称和类型,用于描述其中包含的内容。链接器使用此信息将来自不同模块的程序的不同部分合并到一个可执行文件或库中,方法是合并相同类型的部分(如果您愿意,可以将页面粘合在一起)。

            在可执行文件中,节是可选的,但它们通常用于描述文件中的内容、文件的开始位置以及占用的字节数。

          3. 什么是程序头,我们为什么需要它们?

            它们主要用于制作可执行文件。为了运行一个程序,节是不够的,因为你不仅要指定文件中有什么,还要指定在运行过程中应该将它加载到内存中的什么位置。程序标头仅用于此目的:它们描述 segments,它们是正在运行的进程中的内存区域,具有不同的访问权限和内容。

            每个程序头描述一个。它告诉加载器应该将文件中的某个区域加载到内存中的哪个位置以及应该为该区域设置什么权限(例如,是否应该允许它从中执行代码?它应该是可写的还是仅用于读取?)

            细分可以进一步细分为多个部分。例如,如果您必须指定您的代码段进一步细分为程序显示的消息的代码和静态只读字符串。或者你的数据段细分为时髦数据和硬核数据:J 由你决定。

            在可执行文件中,节是可选的,但拥有它们很好,因为它们描述了文件中的内容并允许转储文件的选定部分(例如,使用 objdump 工具)。不过,有时需要它们来存储动态链接信息符号表调试信息,诸如此类。

          4. 在程序头中,p_vaddrp_paddr 字段的含义是什么?

            这些是加载文件中数据的地址。它们将文件的内容映射到相应的内存位置。第一个是虚拟地址,第二个是物理地址

            物理地址是“原始”内存地址。在现代操作系统上,这些不再在用户空间中使用。相反,用户态程序使用虚拟地址。操作系统欺骗用户空间程序,认为它在内存中是单独的,并且整个地址空间都可供它使用。在底层,操作系统将这些虚拟地址映射到实际内存中的物理地址,并且对程序透明地执行此操作。

            当然,并非虚拟地址空间中的每个地址都可以同时使用。实际可用的物理内存存在限制。所以操作系统只是为程序实际使用的段映射内存(这里是 ELF 文件的程序头中的“段”部分发挥作用的地方)。如果进程试图访问一些未映射的内存,操作系统会介入并说:“对不起,伙计,这块内存不属于你”。 (程序可以寻址它,但不能访问它。)

          5. 每个部分都有自己的部分标题吗?

            是的。如果它在 Section Headers Table 中没有条目,则它不是一个部分:q 因为他们唯一的方法来判断文件的某些部分是否是一个部分,是查看 Section Headers Table 它告诉你哪些部分在文件中定义,您可以在哪里找到它们。

            您可以将章节标题表视为一本书中的目录。没有目录,毕竟没有任何章节,因为它们没有在任何地方列出。这本书可能有标题,但内容没有细分为可以通过目录找到的逻辑章节。 ELF 文件中的部分也是如此:可以有一些数据区域,但如果没有 SHT 的“目录”,您将无法分辨。

          【讨论】:

            猜你喜欢
            • 2017-08-24
            • 1970-01-01
            • 2011-01-15
            • 2017-02-24
            • 2011-08-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多