出于教育目的,我正在尝试在引导扇区上创建一个最小的C示例。
但是,我注意到我的示例没有被识别为引导扇区,因为他的魔幻0x55aa
字节没有出现在第511和512字节之间。
然后,我进一步进行了调查,这似乎是因为.eh_frame
部分已包含在图像中,即使链接器脚本中从未提及它。
那是为什么?
确切的设置is present here,并复制如下
build.sh:
as -ggdb3 -o entry.o entry.S
gcc -c -ggdb3 -nostartfiles -nostdlib -o main.o main.c
ld -o main.elf -T linker.ld entry.o main.o
ld --oformat binary -o main.img -T linker.ld entry.o main.o
qemu-system-x86_64 -hda main.img
linker.ld
ENTRY(mystart)
SECTIONS
{
.text : {
entry.o(.text)
*(.text)
*(.rodata)
*(.data)
/**(.eh_frame)*/
. = 0x1FE;
SHORT(0xAA55)
}
/* Reserve 16 MiB of stack. */
__stack_bottom = .;
. = . + 0x1000000;
__stack_top = .;
}
entry.S:
.text
.global mystart
mystart:
mov %rsp, __stack_top
call main
jmp .
main.c:
void main(void) {
while (1);
}
如果我取消注释上面的.eh_frame
框架,那么它将被包含在指定的位置,并且一切正常,尽管这并不理想,我宁愿完全忽略该部分。
但是,如果我从不提及它,为什么还要尝试在最终图像中包含.eh_frame
?
我通过以下操作发现了有关.eh_frame
的信息:
hd main.img
给出:
00000000 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 |.........zR..x..|
00000010 1b 0c 07 08 90 01 00 00 1c 00 00 00 1c 00 00 00 |................|
00000020 27 00 00 00 06 00 00 00 00 41 0e 10 86 02 43 0d |'........A....C.|
00000030 06 00 00 00 00 00 00 00 48 89 24 25 38 02 00 01 |........H.$%8...|
00000040 e8 02 00 00 00 eb fe 55 48 89 e5 eb fe 66 2e 0f |.......UH....f..|
00000050 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 |.......f........|
00000060 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 |.f.........f....|
00000070 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 |.....f.........f|
00000080 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 |.........f......|
00000090 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f |...f.........f..|
000000a0 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 |.......f........|
000000b0 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 |.f.........f....|
000000c0 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 |.....f.........f|
000000d0 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 |.........f......|
000000e0 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f |...f.........f..|
000000f0 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 |.......f........|
00000100 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 |.f.........f....|
00000110 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 |.....f.........f|
00000120 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 |.........f......|
00000130 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f |...f.........f..|
00000140 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 |.......f........|
00000150 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 |.f.........f....|
00000160 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 |.....f.........f|
00000170 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 |.........f......|
00000180 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f |...f.........f..|
00000190 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 |.......f........|
000001a0 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 |.f.........f....|
000001b0 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 |.....f.........f|
000001c0 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 |.........f......|
000001d0 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f |...f.........f..|
000001e0 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 |.......f........|
000001f0 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 |.f.........f....|
00000200 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 |.....f.........f|
00000210 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 |.........f......|
00000220 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 0f 1f |...f.........f..|
00000230 84 00 00 00 00 00 55 aa |......U.|
00000238
然后:
objdump -D main.o
其中包含:
Disassembly of section .eh_frame:
0000000000000000 <.eh_frame>:
0: 14 00 adc $0x0,%al
2: 00 00 add %al,(%rax)
4: 00 00 add %al,(%rax)
6: 00 00 add %al,(%rax)
8: 01 7a 52 add %edi,0x52(%rdx)
b: 00 01 add %al,(%rcx)
d: 78 10 js 1f <.eh_frame+0x1f>
f: 01 1b add %ebx,(%rbx)
11: 0c 07 or $0x7,%al
13: 08 90 01 00 00 1c or %dl,0x1c000001(%rax)
19: 00 00 add %al,(%rax)
1b: 00 1c 00 add %bl,(%rax,%rax,1)
1e: 00 00 add %al,(%rax)
20: 00 00 add %al,(%rax)
22: 00 00 add %al,(%rax)
24: 06 (bad)
25: 00 00 add %al,(%rax)
27: 00 00 add %al,(%rax)
29: 41 0e rex.B (bad)
2b: 10 86 02 43 0d 06 adc %al,0x60d4302(%rsi)
31: 00 00 add %al,(%rax)
33: 00 00 add %al,(%rax)
35: 00 00 add %al,(%rax)
...
因此我们可以看到,在hd main.img
中,第一个字节与.eh_frame
中的字节完全相同,并且图像大小为512 + sizeof(.eh_frame
)而不是预期为512。
在Ubuntu 18.04,GCC 7.3.0,binutils 2.30上进行了测试。