[编译链接装载系列]之聊聊目标文件与ELF格式

本文详细探讨了目标文件的格式,特别是Linux下的ELF(Executable and Linkable Format)格式。从目标文件的节(Section)和段(Segment)的区别,到ELF文件结构的各个部分,包括文件头、节头结构和辅助信息如重定位表、字符串表。文章通过实例分析了目标文件中的.text、.data、.bss、.rodata等节,并介绍了链接器如何处理符号和重定位信息。最后,讨论了符号表结构及其在链接过程中的作用。
摘要由CSDN通过智能技术生成

编译器编译源代码后生成的文件叫做目标文件,从结构上讲它是已经编译后的可执行文件格式,只是还没有经过链接,其中可能有些符号或有些地址还没有调整。它本身就是按照可执行文件格式存储的,跟真正的可执行文件在结构上稍有不同。

目标文件的格式:

现在 PC 平台流行的可执行文件格式主要是 Windows 下的 PE( Portable Executable,可移植可执行 ) 和 Linux 的 ELF( Executable and Linkable Format,可执行链接格式 ),它们都是 COFF (Common Object Fifle Format,一般目标文件格式 )格式的变种。从广义上看,目标文件和可执行文件的格式其实几乎是一样的,在 Linux 下,我们可以将他们统称为 ELF 文件;在 Windows 下可以统称为 PE-COFF 文件格式。

这里写图片描述

在 Linux 下使用 file 命令查看相应的文件格式:

这里写图片描述

目标文件是什么样的

目标文件是什么样的呢? 下面我们通过一个具体的例子来看一下。如不加说明,以下分析都是基于 32 位 x86 平台,如何在 64 位系统下编译 32 位可执行程序,需要安装 32 位版本的 glibc库,然后在编译时加上选项 “-m32”,如下所示:

这里写图片描述
这里写图片描述

源代码如下:

这里写图片描述

下面我们用 GCC 编译这个文件(只编译不链接),然后用 objdump 查看 ELF 文件的基本信息,如下:

这里写图片描述

我们可以看到目标文件是由很多的“节”(Section)组成的,有 .text节、.data节、.bss节、.rodata节、.comment—注释信息节和 .note.GNU-stack—堆栈提示节等。目标文件将所有信息按不同的属性以“节”(Section)的形式存储,有时候也叫“段”(Segment),很难在中文的翻译上加以区分,其实它们两个还是有区别的。

Section 和 Segment 的区别

在汇编源码中,通常用语法关键字 section 或 segment 来表示一段区域,在程序中“逻辑地”划分一段区域,这个区域就是节。此时所说的 section 和 segment 都是汇编语法中的关键字,它们在语法中都表示“节”,不是段,只是不同编译器的关键字不同而已。经过汇编生成目标文件之后,由这些 section 和 segment 修饰的程序区域便成为了“节”(section)。

但是操作系统加载程序时,不关心节的数量和大小,只关心节的属性,因为程序是要加载到内存中才能运行,而内存的访问会涉及到全局描述符表中段描述符的访问权限等属性,操作系统通过设置 GDT 全局描述符表来构建段描述符,在段描述符中指定段的位置、大小和属性。操作系统加载程序时不需要对逐个节进行加载,只要给出相同权限的节的集合就行了,比如把所有只读可执行的节归并到一块,所有可读可写的节归并到一块,这样操作系统就能为它们分配不同的段选择子,从而指向不同段描述符,实现不同的访问权限。

汇编器只生成了目标文件,尚未链接,因此将“节”合并的工作是由链接器来完成的,链接器将目标文件中属性相同的节合并成一个大的 section 集合,这个集合称为 segment,也就是段,就是平时说的可执行程序内存空间中的代码段和数据段。

总结下就是“节”出现于目标文件中,段诞生于可执行文件中,某个节(section)属于某个段

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值