理解计算机系统_链接_ELF可重定位目标文件(二)
前言理解计算机系统二周目,参考书深入理解计算机系统(以下称本书).读这本书可能不会让编程能力有直接提高,但可以让你明白计算机底层的运行机制,对程序员有间接帮助引入连接上一篇https://blog.csdn.net/jllws1/article/details/159314239?spm1011.2124.3001.6209符号和符号表符号相当于每个节的数据对象.至于这些数据对象是否有对应的数据类型,在上一节有过分析,有的节有数据类型,有的节没有.编译完一个.c文件后,将得到的数据块中有全局变量,全局函数,他们的标识符就是符号.符号的内容本书P468的7.5节大标题下提到了符号的内容1本模块全局变量和函数2其他模块全局变量和函数3本模块静态变量和静态函数(由static修饰)下面提到了static(C语言)和private(C)的含义,有两种语言基础的应该明白,这叫做数据私有.如果非本模块(或者类)要访问私有的数据,需要提供公共接口.符号和符号表的定义符号表符号数组本书P469有符号定义,如下:编译完毕后,生成一些数据块,包括全局变量和函数,同时可能有其他模块的全局变量和函数,这些数据有标识符.符号是对数据的完整描述.从软件的角度来看,数据的描述有几个部分:数据类型,数值,数据对象,地址.站在硬件的角度,数据描述是地址(相对或绝对地址)和所占空间大小.符号(数据对象名称)是增加的一部分,也是和软件描述数据共通的一部分.1name:字符串表偏移本书P468第三段讲了.strtab是一个字符串表---string table的缩写.包括了.symtab和.debug节,以及节头部的节名字.所以.strtab内容的形式如下://C语言表示 char *strtab[]{data1_name,section1_name,......}他是一个字符串数组.属性name记录字节偏移,如果生成的数据对象名字叫做data1_name,那么偏移为0;如果第二项是节名,如.text,那么偏移为10---data1_name占9个字符,加1个空字符\0.第三项数据的偏移等于106(.text为6)16,依此类推.记录偏移的目的,是查找符号名称.操作如下:指针指向.strtab,加上偏移量name,从指针到\0之间得到的字符串即当前对象的符号名称.2type和binding:类型和范围注释写得很清楚,type表示函数或者数据,binding代表局部或全局.函数一般都是全局的,除非在各自编译单元中明确用static修饰.用static修饰的是静态局部变量,只能在本单元或者函数中使用.值得注意的是:type和binding各用1个位即可表达,总共两位,这里用了1个字节,说明并不是越小越好.3reserved(Unused)字面意思:保留的(未使用). 一个字节的占位符一个符号对象所占空间为24字节,是为了满足对齐的需要---64位机每次寻址按8字节的倍数对写软件的人来说,符号数据类型的借鉴意义也是对齐,32位机按照4字节的倍数,64位机按8字节的倍数4section:节(字段)的索引这里的索引按字面意思理解,有11个就够了,因此用4位(最大16)就行.因为下面也看不见示例,所以笔者观点只作参考.用2个字节表达,理解成占位需要.5value:距离目标节的起始位置的偏移符号代表的数据块,在节里面的位置由value决定.6size:数据大小对比name,用指针和\0来访问数据.节中的数据块,由value确定开始位置,大小由size确定.综合来看,数据从几个方面被描述:名称(name),类型范围(typebinding),位置和大小(section,value,size)节头部表内容上一帖分析了节头部表的内容,这里需要更新.节头部表只需要表达每个节的大小和起始地址(相对)即可,因为其他内容在符号中已有说明序号/section head index节起始地址长度1ELF头0x00162text0x10/3rodata//……………………11strtab……节头部表示意当查找符号内容时,在节头部表中由section head index(序号)查找到起始地址(相对),计算出节相对于数据空间的偏移,然后根据符号数据对象内的信息,查找相关数据.ELF头内容也应该做更新.除了必须的信息内容,偏移用8个字节(64位最大表示的数字),其他可以空置.总共仍为16字节.