可重定位对象文件

Posted by Persuez's Blog on July 10, 2018

对象文件分为三种

  1. 可重定位对象文件(relocatable object file):以某种形式包含二进制代码和数据,并且可以和其他的可重定位对象文件在编译时一起组合编译成另外一种对象文件-可执行对象文件。
  2. 可执行对象文件(executable object file):以某种形式包含二进制代码和数据,特点是可以直接被复制到内存中并执行。
  3. 共享对象文件(shared object file):这是一种特殊形式的可重定位对象文件,可以在加载时(load time)或运行时(run time)被动态加载进内存并链接。

编译器(ccl)和汇编器(as)生成可重定位对象文件(包括共享对象文件),链接器(ld)生成可执行对象文件。

ELF文件(Executable and Linkable Format)

ELF是一种现代 x86-64 Linux 和 Unix 系统使用的对象文件格式。在此先说ELF的可重定位对象文件的格式。 elf链接

  • ELF header :开始16字节描述了系统的 the word size 和字节顺序,剩余部分包含了一些让链接器去解析该文件的信息,包括:

       1. ELF header 的大小
       2. 该对象文件的类型(可重定位,可执行还是共享)
       3. 机器类型(如 x86-64)
       4. 对 section header table的偏移量
    
  • .text:程序编译后的机器码
  • .rodata:read-only数据,如printf的格式化字符串参数和switch语句的 case 跳转表。
  • .data:初始化的全局变量和静态(static) C 变量(初始化为0的两种类型变量在.bss断)。局部变量并不在这里,因为局部变量是在运行时维护在栈区的。
  • .bss:未被初始化的全局变量和静态(static) C 变量,并且那些被初始化为0的全局变量和静态(static) C 变量。值得注意的是,这一段并不占用磁盘空间,仅仅是占位符。这么设计对象文件是考虑空间效率。在运行时,这些变量在内存中被分配空间并被初始化为0。
  • .symtab:符号表(symbol table)中包含自己定义和引用其他程序的函数和全局变量的一些重要信息。符号表被放在.symtab段。注意要和编译器的符号表区分开,.symtab 的符号表不包含局部变量。
  • .rel.text:这部分与其他对象文件combine时, .text 段中需要被重定位的指令的地址信息。一般调用了外部函数和引用的全局变量的指令需要重定位。需要注意的是,可执行对象文件并不需要这一段,所以如果没有特别指定的话,链接器通常会忽略这一段。
  • .rel.data:引用或定义的全局变量的重定位信息。
  • .debug:一个 debugging symbol table 包含了自己定义的局部变量,typedefs,自己定义的和引用的全局变量和C源代码程序。只有编译模块指定了 -g 选项才会出现。
  • .line:C 源代码和 .text 中机器码对应的行数映射。只有编译模块指定了 -g 选项才会出现。
  • .strtab:A string table for the symbol tables in the .symtal and .debug sections and for the section names in the section headers. A string table is a sequence of null-terminated character strings.