linker ld elf multiboot

linker - ¿Cómo decir/forzar GNU ld para poner una sección/símbolo en una parte específica del archivo ELF de salida?



multiboot (1)

Para poner la sección antes de .text , ¿ya has tratado de asignarlo ( A ) y ejecutable ( X )?

Si el .interp hack funciona, entonces está bien también, por supuesto.

Va a ser muy largo, así que tome un café / té / yerba.

Resumen

¿Cómo decir / forzar GNU ld para poner una sección / símbolo en una parte específica del archivo ELF de salida?

Específicamente, no estoy preguntando sobre la dirección física / de carga del símbolo sino sobre el desplazamiento dentro del archivo.

Fondo

Estoy tratando de tomar un kernel BSD del mundo real y hacerlo compatible con Multiboot y arrancable por GRUB. Para hacer que una imagen ELF sea compatible con Multiboot e identificable por GRUB, es necesario insertar un número mágico ( 0x1BADB002 ) en los primeros 8KiB del archivo.

Me refiero a Multiboot 0.6.96 .

Como el kernel original es una pieza bastante grande de código, voy a usar ejemplos basados ​​en el kernel Bare Bones de la wiki de OSDev . Como ese kernel ya es compatible con extra_symbol voy a usar un extra_symbol con el valor 0xCAFEBABE como el ejemplo de mi pregunta.

boot.s contiene:

.set CAFEBABE, 0xCAFEBABE ; ... snip ... .section .extras extra_symbol: .long CAFEBABE

Símbolo adicional en .text

La opción más fácil sería poner un símbolo con ese valor en la sección .text justo antes de cualquier otra cosa:

.text BLOCK(4K) : ALIGN(4K) { *(.extras) *(.multiboot) *(.text) }

Eso está bien para el ejemplo, pero en el caso del kernel BSD real, el .text comienza después de 0x2000 (8KiB) en el archivo. Este enfoque no es una opción.

Sección adicional antes de .text ?

Otra opción es poner toda la sección .text antes de .text . En mi ingenuidad, esperaba que poner esa sección antes de .text en el script del enlazador también lo hiciera aparecer antes en el ELF de salida:

SECTIONS { // ... some stuff ... .extras : { *(.extras) } .text BLOCK(4K) : ALIGN(4K) { *(.multiboot) *(.text) } // ... more stuff ... }

Sin embargo, ese no es el caso:

$ 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)

De hecho, la sección aparece primero en la tabla de encabezado de sección, pero su desplazamiento en el archivo ( 0x6010 ) es muy posterior a .text . De hecho, viene incluso después de .bss .

La pregunta

La especificación ELF establece explícitamente que:

Aunque la figura muestra la tabla del encabezado del programa inmediatamente después del encabezado ELF, y la tabla del encabezado de sección que sigue a las secciones, los archivos reales pueden diferir. Además, las secciones y los segmentos no tienen un orden específico. Solo el encabezado ELF tiene una posición fija en el archivo.

¿Cómo hago uso de eso y le digo a GNU ld que coloque mi extra_symbol (probablemente toda la sección .extras ) antes de cualquier otra sección en el archivo, preferiblemente justo después del encabezado ELF?