在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。
是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件标准格式,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。
用hexdump查看foobar的十六进制形式:
[root@localhost testc]# hexdump -C foobar
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 a0 80 04 08 34 00 00 00 |............4...|
00000020 68 10 00 00 00 00 00 00 34 00 20 00 03 00 28 00 |h.......4. ...(.|
00000030 07 00 06 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|
00000040 00 80 04 08 68 01 00 00 68 01 00 00 05 00 00 00 |....h...h.......|
00000050 00 10 00 00 01 00 00 00 00 10 00 00 00 a0 04 08 |................|
00000060 00 a0 04 08 08 00 00 00 08 00 00 00 06 00 00 00 |................|
00000070 00 10 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................|
00000090 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 ff 35 04 a0 04 08 ff 35 00 a0 04 08 e8 24 00 00 |.5.....5.....$..|
000000b0 00 83 c4 08 bb 00 00 00 00 b8 01 00 00 00 cd 80 |................|
000000c0 8b 54 24 08 8b 4c 24 04 bb 01 00 00 00 b8 04 00 |.T$..L$.........|
000000d0 00 00 cd 80 c3 55 89 e5 83 ec 18 8b 45 08 3b 45 |.....U......E.;E|
000000e0 0c 7c 16 c7 44 24 04 0d 00 00 00 c7 04 24 14 81 |.|..D$.......$..|
000000f0 04 08 e8 c9 ff ff ff eb 14 c7 44 24 04 0d 00 00 |..........D$....|
00000100 00 c7 04 24 21 81 04 08 e8 b3 ff ff ff b8 00 00 |...$!...........|
00000110 00 00 c9 c3 74 68 65 20 31 73 74 20 6f 6e 65 0a |....the 1st one.|
00000120 00 74 68 65 20 32 6e 64 20 6f 6e 65 0a 00 00 00 |.the 2nd one....|
00000130 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 |.........zR..|..|
00000140 1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00 |................|
00000150 85 ff ff ff 3f 00 00 00 00 41 0e 08 85 02 42 0d |....?....A....B.|
00000160 05 7b c5 0c 04 04 00 00 00 00 00 00 00 00 00 00 |.{..............|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000 03 00 00 00 04 00 00 00 47 43 43 3a 20 28 47 4e |........GCC: (GN|
00001010 55 29 20 34 2e 38 2e 35 20 32 30 31 35 30 36 32 |U) 4.8.5 2015062|
00001020 33 20 28 52 65 64 20 48 61 74 20 34 2e 38 2e 35 |3 (Red Hat 4.8.5|
00001030 2d 32 38 29 00 00 2e 73 68 73 74 72 74 61 62 00 |-28)...shstrtab.|
00001040 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e 65 |.text..rodata..e|
00001050 68 5f 66 72 61 6d 65 00 2e 64 61 74 61 00 2e 63 |h_frame..data..c|
00001060 6f 6d 6d 65 6e 74 00 00 00 00 00 00 00 00 00 00 |omment..........|
00001070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001090 0b 00 00 00 01 00 00 00 06 00 00 00 a0 80 04 08 |................|
000010a0 a0 00 00 00 74 00 00 00 00 00 00 00 00 00 00 00 |....t...........|
000010b0 10 00 00 00 00 00 00 00 11 00 00 00 01 00 00 00 |................|
000010c0 02 00 00 00 14 81 04 08 14 01 00 00 1a 00 00 00 |................|
000010d0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
000010e0 19 00 00 00 01 00 00 00 02 00 00 00 30 81 04 08 |............0...|
000010f0 30 01 00 00 38 00 00 00 00 00 00 00 00 00 00 00 |0...8...........|
00001100 04 00 00 00 00 00 00 00 23 00 00 00 01 00 00 00 |........#.......|
00001110 03 00 00 00 00 a0 04 08 00 10 00 00 08 00 00 00 |................|
00001120 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................|
00001130 29 00 00 00 01 00 00 00 30 00 00 00 00 00 00 00 |).......0.......|
00001140 08 10 00 00 2d 00 00 00 00 00 00 00 00 00 00 00 |....-...........|
00001150 01 00 00 00 01 00 00 00 01 00 00 00 03 00 00 00 |................|
00001160 00 00 00 00 00 00 00 00 35 10 00 00 32 00 00 00 |........5...2...|
00001170 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
00001180
开头是ELFheader:
unsigned char e_ident[16] //7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
char[2] e_type //02 00 //文件类型 可执行文件
char[2] e_machine //03 00 //运行该程序需要的体系结构位Intel80386
char[4] e_version //01 00 00 00 //文件的版本
char[4] e_entry //a0 80 04 08 //程序的入口地址。文件foobar的入口地址位0x080480a0
char[4] e_phoff //34 00 00 00 //Program header table在文件中的偏移量(以字节为单位)。这里是0x34
char[4] e_shoff //68 10 00 00 //Section header table在文件中的偏移量(以字节为单位)。这里是0x1068
char[4] e_flags //00 00 00 00 //对IA32而言,此项为0
char[2] e_ehsize //34 00 //ELFheader大小(以字节为单位)。这里是0x34
char[2] e_phentsize //20 00 //Program header table中每一个条目(一个Programheader)的大小。这里是0x20
char[2] e_phnum //03 00 //Program header table中有多少个条目,这里有3个
char[2] e_shentsize //28 00 //Section header table中每一个条目(一个Sectionheader)的大小。这里值为0x28
char[2] e_shnum //07 00 //Section header table中有多少个条目,这里有7个
char[2] e_shstrndx //06 00 //包含节名称的字符串表是第几个节(从零开始数)。这里值为6,表示第6个节包含节名称
Program header table 在文件中的偏移量(e_phoff)为0x34,而ELF header大小(e_ehsize)也是0x34,可见ELF header后面紧接着就是Program headertable。
Program header:
char[4] p_type // 01 00 00 00 // 段的类型
char[4] p_offset // 00 00 00 00 // 段的第一个字节在文件中的偏移
char[4] p_vaddr // 00 80 04 08 // 段的第一个字节在内存中的偏移,0x08048000
char[4] p_paddr // 00 80 04 08 // 在物理地址定位相关的系统中,此项是为物理地址保留
char[4] p_filesz // 68 01 00 00 // 段在文件中的长度,0x168
char[4] p_memsz // 68 01 00 00 // 段在内存中的长度
char[4] p_flags // 05 00 00 00 // 与段相关的标志
char[4] p_align // 00 10 00 00 // 段在文件以及内存中如何对齐,0x1000
Program header描述的是系统准备程序运行所需要的一个段(Segment)或其他信息。
foobar的Program header共有三项(e_phnum=3),偏移分别为0x34~0x53,0x54~0x73,0x74~0x93。
下面是另外两个段:
char[4] p_type // 01 00 00 00 // 段的类型
char[4] p_offset // 00 10 00 00 // 段的第一个字节在文件中的偏移,0x1000
char[4] p_vaddr // 00 a0 04 08 // 段的第一个字节在内存中的偏移,0x0804a000
char[4] p_paddr // 00 a0 04 08 // 在物理地址定位相关的系统中,此项是为物理地址保留
char[4] p_filesz // 08 00 00 00 // 段在文件中的长度,0x8
char[4] p_memsz // 08 00 00 00 // 段在内存中的长度
char[4] p_flags // 06 00 00 00 // 与段相关的标志
char[4] p_align // 00 10 00 00 // 段在文件以及内存中如何对齐,0x1000
char[4] p_type // 51 e5 74 64 // 段的类型
char[4] p_offset // 00 00 00 00 // 段的第一个字节在文件中的偏移
char[4] p_vaddr // 00 00 00 00 // 段的第一个字节在内存中的偏移
char[4] p_paddr // 00 00 00 00 // 在物理地址定位相关的系统中,此项是为物理地址保留
char[4] p_filesz // 00 00 00 00 // 段在文件中的长度
char[4] p_memsz // 00 00 00 00 // 段在内存中的长度
char[4] p_flags // 07 00 00 00 // 与段相关的标志
char[4] p_align // 10 00 00 00 // 段在文件以及内存中如何对齐
foobar在加载进内存后的情况:
参考:
于渊《Orange’s 一个操作系统的实现》5.3节
百度百科