也是之前的代码,快速回忆一下。
如果不了解可重定位文件以及基础的编译原理的话这部分可能会很难理解,推荐去看《深入理解计算机系统》《程序员的自我修养》《编译原理》
下面是可重定位文件.o文件的基本结构
包括三部分,ELF header是用来描述文件属性的部分,Section是保存不同段或节的内容的部分,Section header table是描述不同段或节的属性的部分,下面分别介绍
ELF header大致内容是这样的
其他部分不难理解,就是英语阅读,比较难的是Magic部分,Magic是魔数的意思,大体每一字节的意义如下
前面四个字节是给操作系统识别文件类型的,不认识的文件类型操作系统是不会加载的。后面几位字面意思,第七个字节是说明的elf版本号,一般都是01,后面的9个字节没用。
然后介绍Section header table的内容
这里描述了12个段或节的属性,包括地址类型,不同的段或节是什么或保存什么内容下面介绍。Section的内容如下
.text用来存放代码段内容,.data存放初始化了的全局变量和静态变量,.rodata存放只读内容,如const修饰的常量,需要注意的是在.data和.rodata之间还有一个.bss段,用来存放未初始化的全局变量和静态变量以及初始化为零的全局变量和静态变量,但它在文件中不占空间只是占位,会在加载执行时内存自动为它分配空间。一般.bss段都需要在汇编start启动程序中清零,后面链接脚本就为这个操作给汇编留了后门。
其他段和节的大体介绍
这里的符号表很重要,但就不展开了。接下来还是回到链接脚本的内容,首先需要了解链接脚本的一些语法。具体参考这篇文章【裸机开发】链接脚本(.lds文件)的基本语法
这里需要留意的地方有两个,一个是.text段需要把start.o程序入口放在最前面,当然也可以通过ENTRY指定程序入口,这里就图方便了。然后是用__bss_start和__bss_end标记bss段起止地址,留后门方便汇编清零bss段。