2011年(15)
分类: 嵌入式
2011-12-19 11:43:20
GAS是典型的单遍PASS的汇编器,只对程序源文件进行一遍扫描(可以通过设置变量need_pass_2来达到两边扫描的目的),在处理可识别解析符号的同时,将不可解析符号进行记录,而在输出对应目标文件的同时,对不可解析符号进行解析,并生成对应的目标代码重定位信息和错误警告信息,从而完成整个汇编过程。
由于GAS以BFD库作为操作底层源文件和二进制文件,所以GAS对于目标文件信息的生成和填写均是通过BFD结构变量(名为stdoutput的全局变量),并且以此结构作为组织GAS输出的基础结构。GAS具体数据逻辑结构如下图所示:
在BFD结构中,目标文件的段信息保存在BFD的section链表中,而在GAS分析源文件的过程中,会用subsegment作为临时逻辑结构存放各子段信息,而具体的源代码则以frag作为逻辑结构进行保存同源代码相关的各种信息(包括relax信息,重定位信息,最终的二进制输出信息)。
从这个逻辑结构当中,可以比较明了的看到,GAS的主要工作,就是通过单遍扫描(或者两遍)输入源文件,将目标文件需要的信息,填充到BFD各个结构当中,然后交由BFD库的底层实现将文件信息按照目标格式输出。换句话说,GAS的主要工作,就是根据BFD的结构进行填空。
目标文件输出流程如下图所示:
在输出阶段,BFD结构中的各项信息均已完整填充,唯一遗漏的信息包括第一遍扫描中没有得到解析的地址信息和在扫描过程中的fix链表信息。这个过程主要是由write_object_file进行的,除了相应的初始化过程,分为三个主要步骤,首先第一步为relax,主要功能是处理跳转指令的伪指令操作,并对对应的跳转指令进行调整,第二步为fix,即对第一遍处理时没有解析的地址信息进行解析,而没有解析的地址符号则会输出到对应的重定位信息中。然后就是利用BFD库中相关函数,对文件进行输出。