linux目标文件ELF的格式
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">现在PC上流行的可执行文件格式主要是windows下的PE和linux下的ELF文件,他们都是COFF格式文件变种。目标文件时源代码编译后但未进行链接的那些中间文件,它跟可执行文件的格式几乎没有什么区别,因此目标文件(.o文件)也和可执行文件使用一样的储存格式。</span>
在linux中除了可执行文件还有几种文件也是使用ELF格式储存的,其中包括动态库文件(.so),可重定位文件(.o),核心转储文件(进程终止时系统将一些进程信息储存到该类型的文件)。我们可以使用file命令查看文件类型 eg:
xiang@xiang:~/workspace/linux$ file prim prim: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xd54ce2ecedb22482c79f597093ff8c0b8f7c7113, not stripped xiang@xiang:~/workspace/linux$关于ELF文件的格式,其中包含了文件头(file header),代码段(.text),数据段(.data)未初始化数据段(.bss)等,通过objdump 命令可以查看各个段的信息。
xiang@xiang:~/workspace/algorithm$ g++ -c prim.cpp -o prim.o xiang@xiang:~/workspace/algorithm$ objdump -h prim.o prim.o: file format elf32-i386 Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000031f 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 00000000 00000000 00000354 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 003d3c21 00000000 00000000 00000360 2**5 ALLOC 3 .rodata 00000008 00000000 00000000 00000360 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .ctors 00000004 00000000 00000000 00000368 2**2 CONTENTS, ALLOC, LOAD, RELOC, DATA 5 .comment 0000002c 00000000 00000000 0000036c 2**0 CONTENTS, READONLY 6 .note.GNU-stack 00000000 00000000 00000000 00000398 2**0 CONTENTS, READONLY 7 .eh_frame 000000dc 00000000 00000000 00000398 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA xiang@xiang:~/workspace/algorithm$ objdump -h prim1,文件头(file header)在文件头中包含了文件的魔数,机器字长,版本,运行平台,文件类型,入口地址,短信息等内容,其中魔数用于告诉系统文件的类型,如ELF文件的魔数就是DEL符+ELF,
2,代码,数据段这些段非常熟悉,需要说明的一点就是.data段包含的是已经初始化的全局变量和静态变量,而。bss段包含的时未初始化的全局变脸和静态变量。其中有些文件中还存在。rodata段,存放只读数据段。另外在.bss段中的变量的默认值为0,因此.bss在elf文件中实际上并不占用空间,只是在装载的时候需要分配虚拟内存空间。
3. 段表,段表是elf文件除了文件头之外最重要的一个数据结构,其中包含了elf的各个段的信息,如每个段的段名,段的长度,在文件中的偏移,读写权限等,elf文件中的段结构就是由段表决定的,编译器,链接器装载器都是通过段表进行访问各个段的,段表的位置文件头中e_shoff决定,是在文件中的相对偏移。
4,重定位表,链接器的作用是链接多个目标文件,在一个文件中变量引用或函数引用可能定义在其他的目标文件中,而这些符号引用需要使用绝对地址。对于这些符号引用需要放在一个特定的段中,这个段就是重定位表。代码段的重定位信息放在.rel.text中,数据段的重定位信息放在.rel.data中。
5,字符串表,在ELF文件中有好多字符串,如段名,变量名,因为字符串的长度往往是不确定的,使用固定的结构来表示比较困难,一种常用的方法就是将所有的字符串放在一个单独的表中,而使用该字符串的地方只需要有个对该字符串的引用就可以了。
6,符号表,为了能将不同的目标文件链接起来,需要解决不同目标文件之间的相互引用问题。为了解决这个问题,在每个文件中存在很多符号表,其中包括全局符号表,外部符号表,局部符号等。其中全局符号包含定义在本目标文件中的全局符号,这些符号可以被其他的目标文件引用,外部符号包含了在本目标文件中引用,却未在本目标文件中定义的符号。
局部符号,指只有在编译单元内部可见的符号,在链接的过程中没有实际作用,链接器一般会忽略他们。
关于符号还涉及函数签名,强符号,弱符号等问题。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。