[MIT6.828]ELF文件格式

1、整体
ELF文件结构看起来如下:

Linking View Execution View ============ ============== ELF header ELF header Program header table (optional) Program header table Section 1 Segment 1 ... Segment 2 Section n ... Section header table Section header table (optional)

链接视图(Linking View)是链接器关注的结构,执行视图(Execution View)是程序加载器关注的结构,它们是一个文件的不同表现,之间的关系类似于C语言中的联合。在规定中只有ELF头部(ELF header)是确定位置的,其他可以是不固定(依据ELF头、程序头、区域头的信息而定),但是实际使用中经常用上述布局。

ELF文件中使用部分的数据类型如下:

Name Size Alignment Purpose ==== ==== ========= ======= Elf32_Addr 4 4 Unsigned program address Elf32_Half 2 2 Unsigned medium integer Elf32_Off 4 4 Unsigned file offset Elf32_Sword 4 4 Signed large integer Elf32_Word 4 4 Unsigned large integer unsigned char 1 1 Unsigned small integer

2、ELF头
在ELF文件中,ELF头在文件的最前端,保存了整个文件的信息摘要,是识别文件的入口处,32位ELF文件头其结构如下:

#define EI_NIDENT 16 typedef struct { unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf32_Half e_type; /* Object file type */ Elf32_Half e_machine; /* Architecture */ Elf32_Word e_version; /* Object file version */ Elf32_Addr e_entry; /* Entry point virtual address */ Elf32_Off e_phoff; /* Program header table file offset */ Elf32_Off e_shoff; /* Section header table file offset */ Elf32_Word e_flags; /* Processor-specific flags */ Elf32_Half e_ehsize; /* ELF header size in bytes */ Elf32_Half e_phentsize; /* Program header table entry size */ Elf32_Half e_phnum; /* Program header table entry count */ Elf32_Half e_shentsize; /* Section header table entry size */ Elf32_Half e_shnum; /* Section header table entry count */ Elf32_Half e_shstrndx; /* Section header string table index */ } Elf32_Ehdr;

3、区域和区域头
区域头(Section header)保存在区域头表中,由ELF头中的e_shoff来指定区域头表的位置,e_shentsize指定一条区域头信息的大小,e_shnum指定区域头的数目 ,区域头保存了程序中区域的信息,32位区域头结构如下:
typedef struct { Elf32_Word sh_name; /* Section name (string tbl index) */ Elf32_Word sh_type; /* Section type */ Elf32_Word sh_flags; /* Section flags */ Elf32_Addr sh_addr; /* Section virtual addr at execution */ Elf32_Off sh_offset; /* Section file offset */ Elf32_Word sh_size; /* Section size in bytes */ Elf32_Word sh_link; /* Link to another section */ Elf32_Word sh_info; /* Additional section information */ Elf32_Word sh_addralign; /* Section alignment */ Elf32_Word sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr;
区域的一些特点和规格:
(1)、每个区域都有一个区域头来标识,但是一个区域头可以不标识任何区域。
(2)、区域在文件中连续存放,但要求按照sh_addralign要求的对齐格式对齐。
(3)、区域不能相互重叠,但长度为零的区域是例外。
(4)、文件由ELF头,程序头表,区域头表,区域列表组成。如果还有其他空间,其内容是未指定的,不能依赖于这些空间来存放数据。

4、段和程序头
程序头(Program header),保存了运行视图的信息,在加载程序时需要这些数据结构。以下是程序头的结构:
typedef struct { Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr;
段的一些特点和规格:
(1)、为了在分页系统中提高性能,其文件偏移和虚拟地址对页面大小取模后余数相同,最好的情况是偏移和起始位置都在页开始处。
(2)、程序段中的p_filesz和p_memsz不一定相同,因为某些区域如.bbs没有在文件中保存任何数据,只是保存了一个长度信息。而.bss区域在运行的时候是需要占用内存,一般OS将其初始化为0。
(3)、一个可执行程序或者共享库至少有一个程序头,一个程序头会包括零个以上链接视图下的区段。

5、工具的使用
(1)、readelf,用来查看elf文件的各种段,头,区域,内容详尽。
(2)、objdump,不但可以查看elf文件还可以查看别的格式的二进制文件,还可以进行反汇编,但是对于elf格式的描述没有readelf详细。
(3)、hexdump,十六进制查看器,可以查看任何东西,但是本身不识别文件格式,可以很方便的对文件进行不同偏移,不同大小,不同进制的查看。
(4)、objcopy,用来复制和拼接目标文件,可以指定需要复制的区域,字节。
具体使用方法,man之。

参考资料:
"ELF file structure" http://labmaster.mi.infn.it/Laboratorio2/CompilerCD/clang/l1/ELF.html
《程序员的自我修养:链接、装载与库》http://book.51cto.com/art/200904/120986.htm
Linux Manual (binutils),binutils.info,/usr/include/elf.h

你可能感兴趣的:(struct,header,File,table,Integer,alignment)