如何解决为什么gcc汇编器会生成两个程序段的ELF文件?
我正在尝试围绕 ELF 文件格式的工作原理以及对象链接和执行的方式。
为了了解更多信息,我尝试分析以下汇编代码的输出:
#----------------------------------------------------------------------------------------
# Exits immediately using code 3. Runs on 64-bit Linux
# gcc -c basic.s && ld basic.o && ./a.out
#----------------------------------------------------------------------------------------
.global _start
.text
_start:
# _exit(3)
mov $60,%rax # system call 60 is exit
mov $3,%rdi # we want return code 3
syscall # invoke operating system to exit
我正在使用 readelf
和 hd
来分析输出 a.out
。
以下是相关输出:
readelf -l a.out
:
Elf file type is EXEC (Executable file)
Entry point 0x401000
There are 2 program headers,starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000b0 0x00000000000000b0 R 0x1000
LOAD 0x0000000000001000 0x0000000000401000 0x0000000000401000
0x0000000000000010 0x0000000000000010 R E 0x1000
Section to Segment mapping:
Segment Sections...
00
01 .text
hd a.out
的摘录:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 3e 00 01 00 00 00 00 10 40 00 00 00 00 00 |..>.......@.....|
00000020 40 00 00 00 00 00 00 00 e0 10 00 00 00 00 00 00 |@...............|
00000030 00 00 00 00 40 00 38 00 02 00 40 00 05 00 04 00 |....@.8...@.....|
00000040 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 |..@.......@.....|
00000060 b0 00 00 00 00 00 00 00 b0 00 00 00 00 00 00 00 |................|
00000070 00 10 00 00 00 00 00 00 01 00 00 00 05 00 00 00 |................|
00000080 00 10 00 00 00 00 00 00 00 10 40 00 00 00 00 00 |..........@.....|
00000090 00 10 40 00 00 00 00 00 10 00 00 00 00 00 00 00 |..@.............|
000000a0 10 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
[...]
和
[...]
00001000 48 c7 c0 3c 00 00 00 48 c7 c7 03 00 00 00 0f 05 |H..<...H........|
[...]
从这个分析中可以看出,有一个名为“.text”的程序段,它有 10 个字节长,在文件偏移量 0x1000 处包含指令“MOV、MOV、SYSCALL”——一切都符合预期。但是,还有另外一个程序段,这个没有名字的,定义在偏移量0x0000和0x00b0之间,正好是ELF头+程序头0+程序头1所占用的空间。我试过一个最小的C程序,和gcc在那里也创建了一个类似的程序部分。
问题:为什么?什么目的?为什么要定义这个程序段,这个段和这个程序的执行有什么关系?
额外问题:为什么实际的机器代码放在偏移量 0x1000 处;将它放在 0x00b0 上,紧跟在另一个之后不是更有效吗?
我在 Intel x86_64 cpu 上使用 Ubuntu 20.04 和 gcc 9.3.0(Ubuntu 9.3.0-17ubuntu1~20.04)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。