1 可执行目标文件的ELF格式
1.1 相比.o的ELF格式,有哪些变化?
(1).rel.text和.rel.data消失了
为什么这两个节会消失?
链接器将各.o中同名的.text和.data节整合到一起时,会对整合后的.text和.data进行重定位。
其实重定位时主要针对就是.text和.data节,不过这.text和.data节重定位时需要依赖.rel.text和.rel.data中的信息,一旦重定位结束后,这两个节的使命就完成了,自然也就会消失。
(2)多出了两个节
1)init节
(a)作用
这个节会提供_init等函数,专门用于实现程序的一些初始化。
程序入口为_start,从_start开始执行后,在正式调用main函数之前,会先调用_init等函数进行程序的初始化(比如建立函数栈等等)。
(b)init节怎么来的
回顾gcc链接的过程
collect2 //链接程序 -dynamic-linker /lib64/ld-linux-x86-64.so.2 //动态链接器 crt1.o crti.o crtbegin.o //启动代码 ccyIcm4A.o //自己程序的.o -lc //libc,常用c函数库——c标准库的子库 crtend.o crtn.o //扫尾代码
init节就是由gcc提供的crt1.o、crti.o、crtbegin.o等.o构建而来的。
2)“段头部表”节
重定位时,链接器根据“链接脚本文件”所给的运行地址,给.text/.data中指令和变量重定位运行地址时,这些“运行地址”只是链接时理论上安排的。
当加载程序到内存中运行时,就需要将硬盘上所存放的程序,搬到“运行地址”所指定的内存位置,段头部表中的内容,就是用来辅助加载程序的。
1.2 再说说“可执行目标文件”的ELF格式
“可执行目标文件”的各个节,可以进行进一步的归类。
总结:
1)程序最终运行时,需要搬到内存上的节有:ELF/.init/.text/.rodata/.data/.bss。
搬到内存上什么位置呢?
搬到重定位的“运行地址”所指定的位置。
2)ELF/.init/.text/.rodata:只读的存储段(代码段)
3).data/.bss:可读可写存储段(静态数据段)
之所以称为静态数据段,是因为.data/.bss的空间规划,是在编译时就进行了理论安排,并不是程序运行起来才安排的,所以被称为静态数据段。