Почему в GNU ld есть раздел, который не отображается в скрипте компоновщика? - PullRequest
0 голосов

Я пытаюсь создать минимальный пример C для загрузочного сектора в образовательных целях.

Однако я заметил, что мой пример не был распознан как загрузочный сектор, потому что его волшебные 0x55aa байты былине представлены как 511-й и 512-й байты.

Затем я провел дальнейшее исследование, и кажется, что это связано с тем, что раздел .eh_frame включается в изображение, хотя он никогда не упоминался в сценарии компоновщика.

Почему это так?

Точная настройка присутствует здесь и воспроизведена ниже

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.

...