为什么GNU ld会包含一个未出现在链接描述文件中的部分?

时间:2018-12-02 21:11:46

标签: ld linker-scripts

出于教育目的,我正在尝试在引导扇区上创建一个最小的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上进行了测试。

0 个答案:

没有答案