运行环境: Linux系统 gcc编译器
参考书籍: 《Computer Systems:A Programmer’s Perspective》(《深入理解计算机系统》)
主要内容: ELF可重定位目标文件(.o文件),主要讲解ELF头部信息,节头部表,及符号表
运行实例: swap.c、main.c(main.c引用swap.c)
ELF头部信息,节头部表,及符号表在代码区后面有相应注释,注意查看
几个表是相互关联的,最好结合起来查看!
swap.c
extern int buf[];
int *bufp0=&buf[0];
static int *bufp1;
void swap()
{
int temp;
bufp1=&buf[1];
temp=*bufp0;
*bufp0=*bufp1;
*bufp1=temp;
}
main.c
int buf[2]={
1,2};
void swap();
int main()
{
swap();
return 0;
}
在Unix系统上从源文件到目标文件的转化是由编译器驱动程序完成的
在这里我们主要讲解 .o文件 相关信息
典型的ELF可重定位目标文件的格式:
一、查看ELF头(ELF header):
-$ readelf -h main.o
ELF文件头结构定义在“/usr/include/elf.h”头文件下,ELF文件有32位版本和64位版本,故其头文件结构也有32位结构和64位结构,分别定义为Elf32_Ehdr和Elf64_Ehdr。两种版本文件内容一样,只是有些成员的大小不一样。以下是32位版本的文件头结构Elf32_Ehdr。
ELF header/格式代码如下:
#define EI_NIDENT 16
typedef struct{
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type; //它标识的是该文件的类型。
Elf32_Half e_machine; //表明运行该程序需要的体系结构。
Elf32_Word e_version; // 表示文件的版本。
Elf32_Addr e_entry; //程序的入口地址。
Elf32_Off e_phoff; //表示Program header table 在文件中的偏移量
Elf32_Off e_shoff; //表示Section header table 在文件中的偏移量
Elf32_Word e_flags; // 对IA32而言,此项为0。
Elf32_Half e_ehsize; //表示ELF header大小
Elf32_Half e_phentsize; //表示Program header table中每一个条目的大小。
Elf32_Half e_phnum; //表示Program header table中有多少个条目。
Elf32_Half e_shentsize; // 表示Section header table中的每一个条目的大小
Elf32_Half e_shnum; //表示Section header table中有多少个条目。
Elf32_Half e_shstrndx; //包含节名称的字符串是第几个节(从零开始计数
}Elf32_Ehdr;
ELF 头:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 // Magic 魔数,用来指名该文件是一个 ELF 目标文件。第一个字节 7F 是个固定的数;后面的 3 个字节正是 E, L, F 三个字母的 ASCII 形式
类别: ELF64 //64位的ELF文件格式
数据: 2 补码,小端序 (little endian) //数据按二进制补码形式给出并由小端模式存放
版本: 1 (current) // ELF文件头版本号为1
OS/ABI: UNIX - System V //指出操作系统类型,此条详情见https://www.cnblogs.com/DragonStart/p/7524995.html
ABI 版本: