所用程序elf.cc(平台为32位Intel x86的linux):
#include
using namespace std;
int global_ini_var = 84;
int global_uninit_var;
void func1( int i )
{
cout << i << endl;
}
int main( void )
{
static int static_var = 85;
static int static_var2;
int a = 1;
int b;
func1( static_var + static_var2 + a + b );
return a;
}
// 用g++来生成目标文件(参数-c表示只编译不链接)
g++ -c elf.cc
生成2040字节的elf.o文件,使用的binutils的工具objdump来查看elf.o。
// 输入-h得到ELF文件的各个段的基本信息(-x会得到更多信息)
objdump -h elf.o
结果:
elf.o: 文件格式 elf32-i386
节:
Idx Name Size VMA LMA File off Algn
0 .text 000000be 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000008 00000000 00000000 000000f4 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 0000000c 00000000 00000000 000000fc 2**2
ALLOC
3 .init_array 00000004 00000000 00000000 000000fc 2**2
CONTENTS, ALLOC, LOAD, RELOC, DATA
4 .comment 0000002c 00000000 00000000 00000100 2**0
CONTENTS, READONLY
5 .note.GNU-stack 00000000 00000000 00000000 0000012c 2**0
CONTENTS, READONLY
6 .eh_frame 00000098 00000000 00000000 0000012c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
共有6个段,段的属性中Size表示段的长度,File Offset表示段的起始位置,VMA(Virtual Memory Address)表示虚拟内存地址
,LMA(Load Memory Address)表示内存装载地址。Algn表示对齐标识。
各段第二行表示各段属性,CONTENTS表示该段在文件中存在,其中.bss没有CONTENTS,表示它实际在ELF文件中不存在,
.note.GUN-stack有CONTENTS,但长度为0,我们认为它也不在ELF文件中存在。ALLOC表示其在进程中需要分配空间。
READONLY表示只读段。
下面是elf.o在ELF中的结构图:
下面挖掘各段的内容。objdump的“-s”参数可以将所有段的内容以十六进制的方式打印出来,“-d”参数可以将所有包含指令的段反汇编。
mimiasd@mimiasd-All-Series:~$ objdump -s -d elf.o
elf.o: 文件格式 elf32-i386
Contents of section .text:
0000 5589e583 ec188b45 08894424 04c70424 U......E..D$...$
0010 00000000 e8fcffff ffc74424 04000000 ..........D$....
0020 00890424 e8fcffff ffc9c355 89e583e4 ...$.......U....
0030 f083ec20 c7442418 01000000 8b150400 ... .D$.........
0040 0000a108 00000001 c28b4424 1801c28b ..........D$....
0050 44241c01 d0890424 e8fcffff ff8b4424 D$.....$......D$
0060 18c9c355 89e583ec 18837d08 01753181 ...U......}..u1.
0070 7d0cffff 00007528 c7042404 000000e8 }.....u(..$.....
0080 fcffffff c7442408 00000000 c7442404 .....D$......D$.
0090 04000000 c7042400 000000e8 fcffffff ......$.........
00a0 c9c35589 e583ec18 c7442404 ffff0000 ..U......D$.....
00b0 c7042401 000000e8 a7ffffff c9c3 ..$...........
Contents of section .data:
0000 54000000 55000000 T...U...
Contents of section .init_array:
0000 a2000000 ....
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520342e .GCC: (Ubuntu 4.
0010 382e342d 32756275 6e747531 7e31342e 8.4-2ubuntu1~14.
0020 30342e33 2920342e 382e3400 04.3) 4.8.4.
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 017c0801 .........zR..|..
0010 1b0c0404 88010000 1c000000 1c000000 ................
0020 00000000 2b000000 00410e08 8502420d ....+....A....B.
0030 0567c50c 04040000 1c000000 3c000000 .g..........<...>
0040 2b000000 38000000 00410e08 8502420d +...8....A....B.
0050 0574c50c 04040000 1c000000 5c000000 .t..........\...
0060 63000000 3f000000 00410e08 8502420d c...?....A....B.
0070 057bc50c 04040000 1c000000 7c000000 .{..........|...
0080 a2000000 1c000000 00410e08 8502420d .........A....B.
0090 0558c50c 04040000 .X......
Disassembly of section .text:
00000000 <_z5func1i>:
0:55 push %ebp
1:89 e5 mov %esp,%ebp
3:83 ec 18 sub $0x18,%esp
6:8b 45 08 mov 0x8(%ebp),%eax
9:89 44 24 04 mov %eax,0x4(%esp)
d:c7 04 24 00 00 00 00 movl $0x0,(%esp)
14:e8 fc ff ff ff call 15 <_z5func1i>
19:c7 44 24 04 00 00 00 movl $0x0,0x4(%esp)
20:00
21:89 04 24 mov %eax,(%esp)
24:e8 fc ff ff ff call 25 <_z5func1i>
29:c9 leave
2a:c3 ret
0000002b :
2b:55 push %ebp
2c:89 e5 mov %esp,%ebp
2e:83 e4 f0 and $0xfffffff0,%esp
31:83 ec 20 sub $0x20,%esp
34:c7 44 24 18 01 00 00 movl $0x1,0x18(%esp)
3b:00
3c:8b 15 04 00 00 00 mov 0x4,%edx
42:a1 08 00 00 00 mov 0x8,%eax
47:01 c2 add %eax,%edx
49:8b 44 24 18 mov 0x18(%esp),%eax
4d:01 c2 add %eax,%edx
4f:8b 44 24 1c mov 0x1c(%esp),%eax
53:01 d0 add %edx,%eax
55:89 04 24 mov %eax,(%esp)
58:e8 fc ff ff ff call 59
5d:8b 44 24 18 mov 0x18(%esp),%eax
61:c9 leave
62:c3 ret
00000063 <_z41__static_initialization_and_destruction_0ii>:
63:55 push %ebp
64:89 e5 mov %esp,%ebp
66:83 ec 18 sub $0x18,%esp
69:83 7d 08 01 cmpl $0x1,0x8(%ebp)
6d:75 31 jne a0 <_z41__static_initialization_and_destruction_0ii>
6f:81 7d 0c ff ff 00 00 cmpl $0xffff,0xc(%ebp)
76:75 28 jne a0 <_z41__static_initialization_and_destruction_0ii>
78:c7 04 24 04 00 00 00 movl $0x4,(%esp)
7f:e8 fc ff ff ff call 80 <_z41__static_initialization_and_destruction_0ii>
84:c7 44 24 08 00 00 00 movl $0x0,0x8(%esp)
8b:00
8c:c7 44 24 04 04 00 00 movl $0x4,0x4(%esp)
93:00
94:c7 04 24 00 00 00 00 movl $0x0,(%esp)
9b:e8 fc ff ff ff call 9c <_z41__static_initialization_and_destruction_0ii>
a0:c9 leave
a1:c3 ret
000000a2 <_global__sub_i_global_ini_var>:
a2:55 push %ebp
a3:89 e5 mov %esp,%ebp
a5:83 ec 18 sub $0x18,%esp
a8:c7 44 24 04 ff ff 00 movl $0xffff,0x4(%esp)
af:00
b0:c7 04 24 01 00 00 00 movl $0x1,(%esp)
b7:e8 a7 ff ff ff call 63 <_z41__static_initialization_and_destruction_0ii>
bc:c9 leave
bd:c3 ret
自定义段:
__attribute__( ( section( "FOO" ) ) ) int global = 42;
__attribute__( ( section( "BAR" ) ) ) void foo()
{
}