实验程序:
$ cat SimpleSection.c
int printf(const char* format,...);
int globa_init_var = 84;
int global_uninit_val;
void func1(int i){
printf("%d\n",i);
}
int main(){
static int static_var = 85;
static int static_var2;
int a = 1;
int b;
func1(static_var+static_var2+a+b);
return 0;
}
-----------------------------------------------------------------------------------------------------------
elf头数据结构
/usr/include/elf.h
85 typedef struct
86 {
87 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
88 Elf64_Half e_type; /* Object file type */ //可重定位 可执行 共享
89 Elf64_Half e_machine; /* Architecture */
90 Elf64_Word e_version; /* Object file version */
91 Elf64_Addr e_entry; /* Entry point virtual address */
92 Elf64_Off e_phoff; /* Program header table file offset */
93 Elf64_Off e_shoff; /* Section header table file offset */
94 Elf64_Word e_flags; /* Processor-specific flags */
95 Elf64_Half e_ehsize; /* ELF header size in bytes */
96 Elf64_Half e_phentsize; /* Program header table entry size */
97 Elf64_Half e_phnum; /* Program header table entry count */
98 Elf64_Half e_shentsize; /* Section header table entry size */
99 Elf64_Half e_shnum; /* Section header table entry count */
100 Elf64_Half e_shstrndx; /* Section header string table index */
101 } Elf64_Ehdr;
$ gcc -c -o SimpleSection.o SimpleSection.c
$ readelf -h SimpleSection.o
ELF 头:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (可重定位文件)
Machine: Advanced Micro Devices X86-64
Version: 0x1
入口点地址: 0x0
程序头起点: 0 (bytes into file)
Start of section headers: 400 (bytes into file)
标志: 0x0
本头的大小: 64 (字节)
程序头大小: 0 (字节)
Number of program headers: 0
节头大小: 64 (字节)
节头数量: 13
字符串表索引节头: 10
--------------------------------------------------------------------------------------
上面内容比较清晰,不过多介绍。注意其中的入口点地址目前为0,因为目前是可重定位文件,等最终链接完成就会得到最终地址,另外看一下最后一项:字符串表索引节头 指的是字符串表在section table中的索引
section table如下:
$ readelf -S SimpleSection.o
共有 13 个节头,从偏移量 0x190 开始:
节头:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000056 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 000006b8
0000000000000078 0000000000000018 11 1 8
[ 3] .data PROGBITS 0000000000000000 00000098
0000000000000008 0000000000000000 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 000000a0
0000000000000004 0000000000000000 WA 0 0 4
[ 5] .rodata PROGBITS 0000000000000000 000000a0
0000000000000004 0000000000000000 A 0 0 1
[ 6] .comment PROGBITS 0000000000000000 000000a4
0000000000000025 0000000000000001 MS 0 0 1
[ 7] .note.GNU-stack PROGBITS 0000000000000000 000000c9
0000000000000000 0000000000000000 0 0 1
[ 8] .eh_frame PROGBITS 0000000000000000 000000d0
0000000000000058 0000000000000000 A 0 0 8
[ 9] .rela.eh_frame RELA 0000000000000000 00000730
0000000000000030 0000000000000018 11 8 8
[10] .shstrtab STRTAB 0000000000000000 00000128 //保存段表中用到的字符串,最常见的就是段名
0000000000000061 0000000000000000 0 0 1
[11] .symtab SYMTAB 0000000000000000 000004d0
0000000000000180 0000000000000018 12 11 8
[12] .strtab STRTAB 0000000000000000 00000650 //保存普通字符串,如符号的名字
0000000000000065 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
上面其实就是一个Section table的数组,继续看一下Section header对应的数据结构:
270 /* Section header. */
286 typedef struct
287 {
288 Elf64_Word sh_name; /* Section name (string tbl index) */ //索引的是.shstrtab
289 Elf64_Word sh_type; /* Section type */
290 Elf64_Xword sh_flags; /* Section flags */
291 Elf64_Addr sh_addr; /* Section virtual addr at execution */
292 Elf64_Off sh_offset; /* Section file offset */
293 Elf64_Xword sh_size; /* Section size in bytes */
294 Elf64_Word sh_link; /* Link to another section */ //该段使用的字符串在段表中的下标
295 Elf64_Word sh_info; /* Additional section information */ //重定位表所作用的段在段表中的下标
296 Elf64_Xword sh_addralign; /* Section alignment */
297 Elf64_Xword sh_entsize; /* Entry size if section holds table */
298 } Elf64_Shdr;
以.rela.text为例,它的sh_link为11,指向的是.symtab,说明它的字符串在.symtab中,它的sh_info为1,指向的是.text,说明它是对.text段进行重定位。
我们来查看一下.symtab的内容:
$ readelf -s SimpleSection.o
Symbol table '.symtab' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FIL