【问题标题】:Some beginner questions about elf files, sections headers and how they work in general when we run an application一些关于 elf 文件、节标题以及在我们运行应用程序时它们通常如何工作的初学者问题
【发布时间】:2020-02-17 19:00:16
【问题描述】:

我正在学习 elf 文件。我读了一些关于它的东西,我开始对它了解得很少,但是有些东西让我感到困惑。我想继续学习并掌握它,但首先我想确保我把最简单的事情做对了。我将在下面说明我所知道的,请纠正我的错误。

当你编写一个 C 应用程序并编译它(比如使用 gcc)时,它会被翻译成代表代码和数据的机器指令。 调用编译器的输出是一个elf文件。 elf 文件包含(除其他外)一个节头,它基本上是一系列 Elf64_Shdr,每个节对应于您编译的应用程序包含的每个节。 所以基本上一个部分只是一些机器指令,它们代表代码或数据以及一些关于它的信息,比如它在哪里(第一条指令的地址),它有多长(大小),它是可写的还是可读的(一些flags) 等。 我对节和节标题的理解是否正确?

当我们运行 make 命令并将 elf 文件传递​​给它时,链接器开始发挥作用,并查看编译器创建的所有部分,查看它们的名称和属性,并按照 ld 脚本文件的规则将它们分组为“段”并创建我们可以运行的可执行文件所以基本上段只不过是相同属性的部分,它们组合在具有特定名称的公共部分中。这是正确的吗?

然后,当我们实际运行创建的可执行文件时,加载器开始发挥作用,并查看链接器创建的这些段,并通过读取它们包含的这些信息,将机器指令映射到不同的内存位置,以便进程可以运行.这就是所谓的(在我的理解中)记忆图像。这是正确的吗?

感谢您阅读并帮助我消除疑虑,谢谢。

【问题讨论】:

    标签: elf


    【解决方案1】:

    您的描述有多个不准确之处,不清楚您是否对所涉及的处理理解不准确,或者在描述它们时不准确。

    当你编写一个 C 应用程序并编译它(比如使用 gcc)时,它会被翻译成代表代码和数据的机器指令。

    这并不完全准确:“机器指令”和“机器代码”之间存在区别。

    当您编译@​​987654322@ 文件时,一些编译器会将其翻译成机器指令(汇编),然后将其传递给汇编器以生成机器代码(GCC 会这样做)。其他编译器集成了汇编器,并且有效地跳过了汇编生成步骤(Clang 会这样做)。

    调用编译器的输出是一个elf文件。

    一些而非所有系统上,编译的结果是一个可重定位的ELF文件。其他系统生成不同格式的目标文件,例如 XCOFF 或 Mach-O。

    elf 文件包含(除其他外)一个节头,它基本上是一系列 Elf64_Shdr,每个节对应于您编译的应用程序包含的每个节。

    应用程序尚未构建,因此这是不准确的。此外,Elf64_Shdr 仅适用于 64 位 ELF 平台;在 32 位机器上是 Elf32_Ehdr

    当我们运行 make 命令时

    make 命令与没有任何关系。它只是根据需要调用编译器和链接器(或其他工具)。您可以将其替换为 shell 脚本,或者直接手动输入命令。

    并将elf文件传递给它

    链接步骤涉及一个或更多(通常更多)可重定位ELF目标文件、存档库和动态库。

    链接器开始发挥作用,查看编译器创建的所有部分,查看它们的名称和属性,并按照 ld 脚本文件的规则将它们分组为“段”

    要了解链接器的作用,您可以阅读此series of blog posts

    您的描述使链接器的功能变得微不足道。链接器要复杂得多,它会执行您未提及的重定位解析以及许多其他任务。

    并创建我们可以运行的可执行文件。

    通常是真的。

    您可以要求链接器将多个可重定位目标文件组合成一个组合目标文件(使用ld -r foo.o bar.o -o combined.o),在这种情况下,结果将不是可执行文件文件。

    您也可以要求链接器链接共享库而不是链接可执行文件。

    因此,基本上,段只不过是具有相同属性的部分,它们组合在具有特定名称的公共部分中。

    错误。链接比将部分组合在一起很多

    然后当我们实际运行创建的可执行文件时,加载器开始发挥作用

    加载器只对动态链接的可执行文件起作用。完全静态的可执行文件没有加载器,直接由内核自己启动。

    并查看链接器创建的这些段,并通过读取其中包含的信息将机器指令映射到不同的内存位置,以便进程可以运行。这就是所谓的(在我的理解中)记忆图像。

    大部分是正确的。内存映像的某些部分根本不来自磁盘(例如线程本地存储和组合 .bss 部分的内容)

    【讨论】:

      猜你喜欢
      • 2014-10-17
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多