Это будет длинный, поэтому возьмите кофе/чай/йербу.
Резюме
Как сказать/заставить GNU ld поставить раздел/символ в определенной части выходного файла ELF?
В частности, я не спрашиваю о физическом/нагрузочном адресе символа но о смещении внутри файла.
Фон
Я пытаюсь взять реальное ядро BSD и сделать его совместимым с
Мультизагрузка и загрузка GRUB.
Чтобы сделать изображение ELF совместимым с Multiboot и идентифицируемым
GRUB нужно вставить магическое число (0x1BADB002
) в первый
8KiB файла.
Я имею в виду Multiboot 0.6.96.
Поскольку исходное ядро - довольно большая часть кода,
Я буду использовать примеры, основанные на ядре Bare Bones из вики OSDev.
Поскольку это ядро уже совместимо с Multiboot, я собираюсь использовать
extra_symbol
со значением 0xCAFEBABE
в качестве примера для моего вопроса.
boot.s
содержит:
.set CAFEBABE, 0xCAFEBABE
; ... snip ...
.section .extras
extra_symbol:
.long CAFEBABE
Дополнительный символ в .text
Самый простой вариант - поместить символ с этим значением в .text
раздел перед чем-либо еще:
.text BLOCK(4K) : ALIGN(4K)
{
*(.extras)
*(.multiboot)
*(.text)
}
Это хорошо для примера, но в случае реального ядра BSD .text
запускает путь после 0x2000 (8KiB) в файле. Этот подход не является вариантом.
Дополнительный раздел до .text
?
Другой вариант - поставить весь раздел .extras
до .text
.
В своей наивности я надеялся, что поставить такой раздел до .text
в
компоновщик script также запустит его в предыдущем элементе ELF:
SECTIONS
{
// ... some stuff ...
.extras : { *(.extras) }
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
// ... more stuff ...
}
Это не тот случай:
$ i586-elf-readelf -S myos.bin
There are 10 section headers, starting at offset 0x6078:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .extras PROGBITS 00100000 006010 000004 00 0 0 1
[ 2] .comment PROGBITS 00000000 006014 000011 01 MS 0 0 1
[ 3] .text PROGBITS 00001000 001000 0001e4 00 AX 0 0 4096
[ 4] .rodata.str1.1 PROGBITS 000011e4 0011e4 000016 01 AMS 0 0 1
[ 5] .eh_frame PROGBITS 000011fc 0011fc 000104 00 A 0 0 4
[ 6] .bss PROGBITS 00002000 002000 004010 00 WA 0 0 4096
[ 7] .shstrtab STRTAB 00000000 006025 000050 00 0 0 1
[ 8] .symtab SYMTAB 00000000 006208 000210 10 9 19 4
[ 9] .strtab STRTAB 00000000 006418 000130 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Фактически, раздел входит в первую очередь в таблицу заголовков разделов, но его
смещение в файле (0x6010
) происходит после .text
. На самом деле, он приходит даже
после .bss
.
Вопрос
В спецификации ELF явно указано, что:
Хотя на рисунке показана таблица заголовков программ сразу после Заголовок ELF и таблица заголовка раздела, следующие за разделами, фактические файлы могут отличаться. Кроме того, разделы и сегменты не имеют определенного порядка. Только заголовок ELF имеет фиксированное положение в файле.
Как я могу это использовать и сообщить GNU ld о размещении моего extra_symbol
(возможно, весь раздел .extras
) перед любым другим разделом файла,
предпочтительно сразу после заголовка ELF?