程序员的自我修养——链接、装载和库

2 编译和链接

2.1 被隐藏的过程

2.2 编译器做了什么

2.3 连接器年龄比编译器长

2.4 模块拼装——静态链接

2.5 小结

1 Elf文件

1.1 文件头

Magic:魔术数字
魔术数字16个字节。最开始的4个字节是所有的ELF文件都必须相同的标识码。分别为:0x7F(ASCII中的DEL控制字符)、0x45(‘E’)、0x4c(‘L’)和0x46(‘F’)。这四个字节又被称为ELF文件的魔数。
第5个字节: 0x01表示32位。 0x02表示64位。
第6个字节: 字节序。标识ELF文件是大端的还是小端。
第7个字节: 主版本号,一般是1. 因为ELF标准自1.2版本以后就再无更新。
最后的9个字节:没有标准定义, 一般填写0。有的平台会将其作为扩展标志。

Class:Elf32 / Elf64
Data:大小端

Type: REL(Relocatable file),可执行文件,动态链接文件。

常量含义
ET_REL1可重定位文件,一般为.o文件
ET_EXEC2可执行文件
ET_DYN3共享目标文件,一般为.so文件

机器类型:
ELF文件做不到像java字节码文件那样跨平台。 也就是说不同操作系统下的elf文件内容是有区别的。
e_machine就表示平台属性,3就表示在intel x86机器下使用。

常量含义
EM_M321AT&T WE 32100
EM_SPARC2SPARC
EM_3863Intel X86
EM_68K4Motorola 68000

文件机器字节长度
数据存储方式
版本
运行平台
ABI版本
硬件平台,
硬件平台版本
入口地址,
程序头入口和长度
段表的位置和长度
段的数量

ELF文件头的结构和相关常数被定义在“/usr/include/elf.h”里面。ELF文件有32和64位的版本,相应地,文件头结构有两种,分别是:Elf32_Ehdr和Elf64_Ehdr. 32位和64位的文件头的内容是一样的,有些成员大小不一样。

1.2 段表

段表是保存段基本属性的结构。段表是ELF文件中除文件头外最重要的结构。 它描述了各个段的信息,例如段名、段长度、在文件中的偏移读写权限等。编译器、连接器和装载器都是依靠段表来定位和访问各个段的属性的。段表在ELF文件中的位置由文件头中e_shoff成员决定。

段表是以Elf32_Shdr结构体为元素的数组。数组元素的个数就是段的个数,每个结构体对应一个段。Elf32_Shdr又被称为段描述符。

段名称

段类型:
段名字只在链接和编译过程中有意义,并不能真正表示段类型。我们可以将一个数据段命名为“.text”

常量含义
SHT_NULL0无效段
SHT_PROGBITS1程序段。代码段、数据段都是这种类型的。
SHT_SYMTAB2表示该段的内容为符号表。

段的标志位:
表示该段在进程虚拟地址空间中的属性,例如是否可写,是否可执行等。

常量含义
SHF_WRITE1表示该段在进程空间中可写
SHF_ALLOC2表示该段在进程空间中须要分配空间。有些包含指示或控制信息的段不需要在进程空间中被分配空间,它们一般不会有这个标志。像代码段、数据段和.bss段都会有这个标志
SHF_EXECINSTR4表示该段在进程空间中可被执行,一般指代码段

段的链接信息(sh_link,sh_info):
与链接没有关系的段,这两个成员是没有意义的。

1.2.1 重定位表

.rel.text段,其类型(sh_type)为“SHT_REL”,即是一个重定位表。

一个重定位表同时也是ELF的一个段。 它的sh_link表示符号表得下标,sh_info表示其作用于哪个段。

1.2.2 字符串表

ELF文件中有很多字符串,如段名,变量名等。因为字符串长度往往不固定,所以很难用固定的结构来表示。 常见的做法就是把字符串集中起来放到一个表,然后使用字符串在表中的偏移来引用字符串。

一般字符串表在ELF文件中以段的形式保存。常见的段名为.strtab或.shstrtab。这两个字符串表分别为字符串表(String Table)和段表字符串表(Section Header String Table)。顾名思义,字符串表用来保存普通的字符串,比如符号的名字;段表字符串用来保存段表中用到的字符串,最常见的就是段名(sh_name)。

e_shstrndx是文件头结构体的最后一个成员,它是“Section header string table index”。段表字符串表本身也是ELF文件中的一个普通的段,e_shstrndx就表示段表字符串表在段表中的下表。

参考资料

[1] 程序员的自我修养——链接、装载与库
[2] https://www.bilibili.com/video/BV1mK411B7Ux/?spm_id_from=333.337.search-card.all.click&vd_source=f4dcb991bbc4da0932ef216329aefb60

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序员自我修养:链接,装载》是一本由林锐、郭晓东、郑蕾等人合著的计算机技术书籍,在该书中,作者从程序员的视角出发,对链接装载等概念进行了深入的阐述和解析。 在计算机编程中,链接是指将各个源文件中的代码模块组合成一个可执行的程序的过程。链接可以分为静态链接和动态链接两种方式。静态链接是在编译时将所有代码模块合并成一个独立的可执行文件,而动态链接是在运行时根据需要加载相应的代码模块。 装载是指将一个程序从磁盘上加载到内存中准备执行的过程。在装载过程中,操作系统会为程序分配内存空间,并将程序中的各个模块加载到相应的内存地址上。装载过程中还包括解析模块之间的引用关系,以及进行地址重定位等操作。 是指一组可重用的代码模块,通过链接装载的方式被程序调用。可以分为静态和动态。静态是在编译时将的代码链接到程序中,使程序与的代码合并为一个可执行文件。动态则是在运行时通过动态链接的方式加载并调用。 《程序员自我修养:链接,装载》对于理解链接装载的原理和机制具有极大的帮助。通过学习这些概念,程序员可以更好地优化代码结构和组织,提高程序的性能和可维护性。同时,了解链接装载的工作原理也对于进行调试和故障排除具有重要意义。 总之,链接装载是计算机编程中的重要概念,对于程序员来说掌握这些知识是非常必要的。《程序员自我修养:链接,装载》这本书提供了深入浅出的解释和实例,对于想要学习和掌握这些知识的程序员来说是一本非常有价值的参考书籍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值