如何告诉/强制GNU ld将一个节/符号放在输出ELF文件的特定部分?

时间:2013-11-11 18:04:51

标签: linker ld elf multiboot

这将是一个很长的,所以抓一些咖啡/茶/ yerba。

摘要

如何告诉/强制GNU ld放置一个部分/符号 在输出ELF文件的特定部分?

具体来说,我不是在询问符号的物理/加载地址 但关于文件中的偏移量。

背景

我正在尝试使用真实世界的BSD内核并使其兼容 多引导并可由GRUB引导。 为了使ELF图像与Multiboot兼容并且可识别 通过GRUB,需要在第一个中嵌入一个幻数(0x1BADB002) 8KiB的文件。

我指的是Multiboot 0.6.96

由于原始内核是相当大的代码, 我将使用基于Bare Bones kernel from OSDev wiki的示例。 由于该内核已经符合Multiboot标准,我将使用 值extra_symbol的{​​{1}}作为我问题的示例。

0xCAFEBABE包含:

boot.s

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

中的额外符号

最简单的选择是将带有该值的符号放入.text 之前的部分:

.text

这对于示例来说很好,但是对于真正的BSD内核.text BLOCK(4K) : ALIGN(4K) { *(.extras) *(.multiboot) *(.text) } 在文件中的0x2000(8KiB)之后开始。这种方法不是一种选择。

.text之前的额外部分?

另一种选择是将整个.text部分放在.extras之前。 在我天真的时候,我希望在.text之前放一个这样的部分 链接器脚本也会使它出现在输出ELF的前面:

.text

但事实并非如此:

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之后。

问题

ELF规范明确指出:

  

虽然图中显示了紧随其后的程序头表   ELF标题,以及各节之后的节标题表,实际   文件可能不同。此外,部分和细分没有指定的顺序。   只有ELF标题在文件中有固定的位置。

如何使用它并告诉GNU ld放置.bss (可能是整个extra_symbol部分)在文件中的任何其他部分之前, 最好是在ELF标题之后?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题——多重引导签名是在 .text 部分之后加载的——并且使用 Florian 的指针,这就是我如何强制我的示例部分在 ELF 文件的开头加载。

.section .multiboot, "ax", @progbits
.align 4
.long MAGIC
.long FLAGS
...

即通过在节声明处标记为可分配和可执行

答案 1 :(得分:0)

为了将该部分放在.text之前,您是否已尝试将其分配(A)和可执行文件(X)?

如果.interp hack有效,那么当然也没关系。