《程序员自我修养》阅读笔记-目标文件里有什么

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《程序员自我修养》阅读笔记-目标文件里有什么相关的知识,希望对你有一定的参考价值。

linux下的目标文件(.o文件)采用ELF格式。目标文件里采用段section的格式存储,比如代码段啊(存代码),数据段啊(初始化了的全局变量和局部静态变量),BSS段啊(未初始化的全局和局部静态变量),只读数据段啊(程序中用到的字符串)等。在所有的段外,有一个重要的结构叫做文件头。所以这里从文件头开始说。

1 文件头主要包含以下内容(没什么用的就不写了):

 (1)e_ident:这里面一个重要的内容就是魔数和机器的位数。魔数用来标识文件的类型,比如elf啊,a.out啊,MZ啊等。机器位数就是32或者64.

 (2)e_type:有三种,可重定位文件(就是目标文件),可执行文件,共享目标文件(就是动态链接库文件)

 (3)e_shoff: 段表在文件中的偏移(接下来会说段表相关内容)

 (4)e_ehsize :文件头本身的大小

 (5)e_shentsize: 段表描述符的大小。就是段表有很多项,这个是说每一项的大小是多少(接下来会说段表相关内容)

 (6)e_shnum: 段表描述符数量(接下来会说段表相关内容)

 (7)e_shstrndx: 段表字符串表在段表中的下标。段表字符串表就是存储所有所有段的名字的一个表。一般段表字符串表的名字可能是.shstrtab(接下来会说段表相关内容)

   从这里可以知道段表的位置(e_shoff),段表中有多少项(e_shnum),这样就能从段表中解析出所有的段。下面是段表的相关内容。

2 段表。段表有很多项。每一项主要包含以下内容:

 (1)sh_name:这个值记录的是段的名字在段表字符串表的下标

 (2)sh_type:段的类型。主要的类型有程序段,符号表段,字符串表,重定位表,哈希表,动态链接信息等

 (3)sh_flag:段的标志位,有三种:可写,需要分配空间,可执行

 (4)sh_addr:段虚拟地址,被加载后在进程空间的地址;

 (5)sh_offset:段的偏移

 (6)sh_size:段的长度

 (7)sh_link,sh_info:段的链接信息。如果段的内容与链接有关,这两个值才有意义。比如动态链接符号表啊,重定位表啊,sh_link表示这些表使用的字符串表或符号表在段表中的下标,sh_info表示重定位表作用的段在段表中的下标。

 (8)sh_addralign: 对齐信息

 (9)sh_entsize:项的长度。有些段,比如符号表,每个项的大小是相同的,所以需要每个项的大小。

3 重定位表:代码段如果需要重定位,那么就会有针对代码段的重定位段,比如.rel.text;数据段如果需要重定位,那么也需要专门的重定位表,比如.rel.data。每个重定位段是专门的一个段。它的sh_link表示符号表的下标,sh_info表示它作用于哪个段。关于重定位表的详细结构在下一篇阅读笔记中说明。

4 字符串表:字符串表是将用到的字符串都放到一起,然后每个用到字符串的地方只需要给出字符串表的下标即可。一般字符串表存放程序中用到的字符串,而段表字符串表用来存储段表中用到的字符串,比如段名。

5 符号表。符号是进行链接的接口。符号表由很多项组成的。每一项包含的内容如下:

 (1)st_name:符号名在字符串表的下标

 (2)st_value:简单的说,这个表示符号(函数啊,变量啊)的地址,实际上大多数时候这个值表示的是符号相对于所在段的偏移。在可执行文件中,这个表示符号的虚拟地址(这个对动态链接有用)。

 (3)st_size:符号大小,比如double的大小为8个字节

 (4)st_info:它的第四位表示符号的绑定信息(局部符号,全局符号,弱引用),高28位表示符号类型(数据啊,函数啊等)

 (5)sh_shndx:如果符号定义在本目标文件,这个表示符号所在段的下标。

 

以上是关于《程序员自我修养》阅读笔记-目标文件里有什么的主要内容,如果未能解决你的问题,请参考以下文章

读书笔记第三周《程序员的自我修养》

《程序员的自我修养》读书笔记 -- 第三章

《程序员自我修养》阅读笔记-静态链接

程序员自我修养阅读笔记——动态链接

程序员自我修养阅读笔记——动态链接

读书笔记|《程序员的自我修养》- 02 目标文件