ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
elf文件头是对elf文件段的描述,是程序必须装载的。描述磁盘上可执行程序的内存布局以及如何映射到内存上,使用readelf -h命令查看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: DYN (Shared object file)共享目标文件
Machine: AArch64
Version: 0x1
Entry point address: 0xffffffc010080000
Start of program headers: 64 (bytes into file)
Start of section headers: 519047696 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 22
Size of section headers: 64 (bytes)
Number of section headers: 51
Section header string table index: 49
typedef struct elf64_hdr {
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry; /* Entry point virtual address */ /*程序的入口地址,由于.o并不是可执行文件因此这里为0*/
Elf64_Off e_phoff; /* Program header table file offset */ /*.o文件没有程序投这里也为0*/
Elf64_Off e_shoff; /* Section header table file offset */ /* 表示节头表存储的偏移地址*/
Elf64_Word e_flags;
Elf64_Half e_ehsize;//elf文件头大小,占用的字节
Elf64_Half e_phentsize;//表示程序头表中每个元素的大小(占用的存储字节数)
Elf64_Half e_phnum;//程序头表中的元素个数
Elf64_Half e_shentsize;//节头表每个元素的大小
Elf64_Half e_shnum;//节头表元素个数
Elf64_Half e_shstrndx;//因为elf文件由很多节组成,每个节需要有个名称,这里表示
} Elf64_Ehdr;
使用readelf -S 命令读取节头表。
There are 51 section headers, starting at offset 0x1ef00a10:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .head.text PROGBITS ffffffc010080000 00010000
0000000000001000 0000000000000000 AX 0 0 4096
[ 2] .text PROGBITS ffffffc010081000 00011000
00000000013ee578 0000000000000000 WAX 0 0 4096
[ 3] .rodata PROGBITS ffffffc011500000 01400000
0000000001107e20 0000000000000000 WAMS 0 0 1048576
[ 4] ".mmuoff.data.wri PROGBITS ffffffc012607e20 02507e20
0000000000000008 0000000000000000 WA 0 0 8
[ 5] .rodata1 PROGBITS ffffffc012607e28 02507e28
0000000000000000 0000000000000000 WA 0 0 1
[ 6] .pci_fixup PROGBITS ffffffc012607e28 02507e28
00000000000033a8 0000000000000000 A 0 0 8
[ 7] .builtin_fw PROGBITS ffffffc01260b1d0 0250b1d0
0000000000000000 0000000000000000 A 0 0 1
[ 8] __ksymtab PROGBITS ffffffc01260b1d0 0250b1d0
0000000000029fe8 0000000000000000 A 0 0 8
[ 9] __ksymtab_gpl PROGBITS ffffffc0126351b8 025351b8
0000000000023b08 0000000000000000 A 0 0 8
[10] __ksymtab_unused PROGBITS ffffffc012658cc0 02558cc0
0000000000000000 0000000000000000 A 0 0 1
[11] __ksymtab_unused_ PROGBITS ffffffc012658cc0 02558cc0
0000000000000000 0000000000000000 A 0 0 1
[12] __ksymtab_gpl_fut PROGBITS ffffffc012658cc0 02558cc0
0000000000000000 0000000000000000 A 0 0 1
[13] __kcrctab PROGBITS ffffffc012658cc0 02558cc0
0000000000006ffc 0000000000000000 A 0 0 4
[14] __kcrctab_gpl PROGBITS ffffffc01265fcbc 0255fcbc
0000000000005f2c 0000000000000000 A 0 0 1
[15] __kcrctab_unused PROGBITS ffffffc012665be8 02565be8
0000000000000000 0000000000000000 A 0 0 1
[16] __kcrctab_unused_ PROGBITS ffffffc012665be8 02565be8
0000000000000000 0000000000000000 A 0 0 1
[17] __kcrctab_gpl_fut PROGBITS ffffffc012665be8 02565be8
0000000000000000 0000000000000000 A 0 0 1
[18] __ksymtab_strings PROGBITS ffffffc012665be8 02565be8
000000000004322e 0000000000000000 A 0 0 1
[19] __init_rodata PROGBITS ffffffc0126a8e16 025a8e16
0000000000000000 0000000000000000 A 0 0 1
[20] __param PROGBITS ffffffc0126a8e18 025a8e18
0000000000004100 0000000000000000 A 0 0 8
[21] __modver PROGBITS ffffffc0126acf18 025acf18
00000000000000c0 0000000000000000 A 0 0 8
[22] __ex_table PROGBITS ffffffc0126ad000 025ad000
0000000000004040 0000000000000000 A 0 0 8
[23] .modinfo PROGBITS ffffffc0126b1040 025b1040
00000000000225d7 0000000000000000 A 0 0 1
[24] .notes NOTE ffffffc0126d3618 025d3618
0000000000000030 0000000000000000 A 0 0 4
[25] .init.text PROGBITS ffffffc0126e0000 025e0000
000000000009066c 0000000000000000 AX 0 0 4
[26] .exit.text PROGBITS ffffffc01277066c 0267066c
0000000000009fa0 0000000000000000 AX 0 0 4
[27] .altinstructions PROGBITS ffffffc01277a60c 0267a60c
0000000000076fa4 0000000000000000 A 0 0 1
[28] .altinstr_replace PROGBITS ffffffc0127f15b0 026f15b0
0000000000031134 0000000000000000 AX 0 0 4
[29] .init.data PROGBITS ffffffc012823000 02723000
0000000000017988 0000000000000000 WAMS 0 0 256
[30] .data..percpu PROGBITS ffffffc01283b000 0273b000
0000000000016958 0000000000000000 WA 0 0 64
readelf: Warning: [31]: Link field (0) should index a symtab section.
[31] .rela.dyn RELA ffffffc012851958 02751958
00000000002d0840 0000000000000018 A 0 0 8
[32] .data PROGBITS ffffffc012b30000 02a30000
0000000000276050 0000000000000000 WA 0 0 4096
[33] __bug_table PROGBITS ffffffc012da6050 02ca6050
0000000000024b70 0000000000000000 WA 0 0 4
[34] .mmuoff.data.writ PROGBITS ffffffc012dcb000 02ccb000
0000000000000010 0000000000000000 WA 0 0 2048
[35] .mmuoff.data.read PROGBITS ffffffc012dcb800 02ccb800
0000000000000008 0000000000000000 WA 0 0 8
[36] .pecoff_edata_pad PROGBITS ffffffc012dcb808 02ccb808
00000000000001f8 0000000000000000 WA 0 0 1
[37] .sbss PROGBITS ffffffc012dcba00 02ccba00
0000000000000000 0000000000000000 WA 0 0 1
[38] .bss NOBITS ffffffc012dcc000 02ccc000
0000000000395cd8 0000000000000000 WA 0 0 4096
[39] .comment PROGBITS 0000000000000000 02ccc000
0000000000000114 0000000000000001 MS 0 0 1
[40] .debug_line PROGBITS 0000000000000000 02ccc114
0000000002884c2f 0000000000000000 0 0 1
[41] .debug_info PROGBITS 0000000000000000 05550d43
0000000011027cf1 0000000000000000 0 0 1
[42] .debug_abbrev PROGBITS 0000000000000000 16578a34
000000000033cdbe 0000000000000000 0 0 1
[43] .debug_aranges PROGBITS 0000000000000000 168b5800
0000000000000780 0000000000000000 0 0 16
[44] .debug_ranges PROGBITS 0000000000000000 168b5f80
0000000000a9e3e0 0000000000000000 0 0 16
[45] .debug_loc PROGBITS 0000000000000000 17354360
00000000061d777c 0000000000000000 0 0 1
[46] .debug_str PROGBITS 0000000000000000 1d52badc
000000000051cba5 0000000000000001 MS 0 0 1
[47] .debug_frame PROGBITS 0000000000000000 1da48688
000000000021ea78 0000000000000000 0 0 8
[48] .symtab SYMTAB 0000000000000000 1dc67100
0000000000c439f8 0000000000000018 50 493372 8
[49] .shstrtab STRTAB 0000000000000000 1e8aaaf8
0000000000000282 0000000000000000 0 0 1
[50] .strtab STRTAB 0000000000000000 1e8aad7a
0000000000655c8f 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
SYMTAB
.symtab是符号表。Ndx列是每个符号所在的Section编号,例如data_items在第3个Section里(也就是.data),各Section的编号见Section Header Table。
Value列是每个符号所代表的地址,在目标文件中,符号地址都是相对于该符号所在Section的相对地址。从Bind这一列可以看出_start这个符号是GLOBAL的,
而其它符号是LOCAL的,GLOBAL符号是在汇编程序中用.globl指示声明过的符