3.5.2 Linux 0.12中的目标文件格式
在Linux 0.12系统中,可以使用objdump命令来查看模块文件或执行文件中文件头结构的具体值。例如,下面列出了hello.o目标文件及其执行文件中文件头的具体值。
[/usr/root]# gcc -c -o hello.o hello.c [/usr/root]# gcc -o hello hello.o [/usr/root]# [/usr/root]# hexdump -x hello.o 0000000 0107 0000 0028 0000 0000 0000 0000 0000 0000010 0024 0000 0000 0000 0010 0000 0000 0000 0000020 6548 6c6c 2c6f 7720 726f 646c 0a21 0000 0000030 8955 68e5 0000 0000 e3e8 ffff 31ff ebc0 0000040 0003 0000 c3c9 0000 0019 0000 0002 0d00 0000050 0014 0000 0004 0400 0004 0000 0004 0000 0000060 0000 0000 0012 0000 0005 0000 0010 0000 0000070 0018 0000 0001 0000 0000 0000 0020 0000 0000080 6367 5f63 6f63 706d 6c69 6465 002e 6d5f 0000090 6961 006e 705f 6972 746e 0066 000009c [/usr/root]# objdump -h hello.o hello.o: magic: 0x107 (407)machine type: 0 flags: 0x0 text 0x28 data 0x0 bss 0x0 nsyms 3 entry 0x0 trsize 0x10 drsize 0x0 [/usr/root]# [/usr/root]# hexdump -x hello | more 0000000 010b 0000 3000 0000 1000 0000 0000 0000 0000010 069c 0000 0000 0000 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 0000 0000 * 0000400 448b 0824 00a3 0030 e800 001a 0000 006a 0000410 dbe8 000d eb00 00f9 6548 6c6c 2c6f 7720 0000420 726f 646c 0a21 0000 8955 68e5 0018 0000 ...... --More--q [/usr/root]# [/usr/root]# objdump -h hello hello: magic: 0x10b (413)machine type: 0 flags: 0x0 text 0x3000 data 0x1000 bss 0x0 nsyms 141 entry 0x0 trsize 0x0 drsize 0x0 [/usr/root]# |
可以看出,hello.o模块文件的魔数是0407(OMAGIC),代码段紧跟在头结构之后。除了文件头结构以外,还包括一个长度为0x28字节的代码段和一个具有3个符号项的符号表以及长度为0x10字节的代码段重定位信息。其余各段的长度均为0。对应的执行文件hello的魔数是0413(ZMAGIC),代码段从文件偏移位置1024字节开始存放。代码段和数据段的长度分别为0x3000和0x1000字节,并带有包含141个项的符号表。可以使用命令strip删除执行文件中的符号表信息。例如下面我们删除了hello执行文件中的符号信息。可以看出hello执行文件的符号表长度变成了0,并且hello文件的长度也从原来的20591字节减小到17412字节。
[/usr/root]# ll hello -rwx--x--x1 root 4096 20591 Nov 14 18:30 hello [/usr/root]# objdump -h hello hello: magic: 0x10b (413)machine type: 0flags: 0x0text 0x3000 data 0x1000 bss 0x0 nsyms 141 entry 0x0 trsize 0x0 drsize 0x0 [/usr/root]# strip hello [/usr/root]# ll hello -rwx--x--x1 root 4096 17412 Nov 14 18:33 hello [/usr/root]# objdump -h hello hello: magic: 0x10b (413)machine type: 0flags: 0x0text 0x3000 data 0x1000 bss 0x0 nsyms 0 entry 0x0 trsize 0x0 drsize 0x0 [/usr/root]# |
磁盘上a.out执行文件的各区在进程逻辑地址空间中的对应关系如图3-8所示。Linux 0.12系统中进程的逻辑空间大小是64MB。对于ZMAGIC类型的a.out执行文件,它的代码区的长度是内存页面的整数倍。由于Linux 0.12内核使用需求页技术,即在一页代码实际要使用的时候才被加载到物理内存页面中,而在进行加载操作的fs/execve()函数中仅仅为其设置了分页机制的页目录项和页表项,因此需求页技术可以加快程序的加载速度。
|
| 图3-8 a.out执行文件映射到进程逻辑地址空间 |
图中bss是进程的未初始化数据区,用于存放静态的未初始化数据。在开始执行程序时bss的第1页内存会被设置为全0。图中heap是堆空间区,用于分配进程在执行过程中动态申请的内存空间。