15

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

概括

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

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

背景

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

我指的是Multiboot 0.6.96

由于原始内核是相当大的一段代码,我将使用基于来自 OSDev wiki 的 Bare Bones 内核的示例。由于该内核已经与 Multiboot 兼容,因此我将使用 extra_symbolwith value0xCAFEBABE作为我的问题的示例。

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在链接描述文件之前放置这样一个部分也会使其更早地出现在输出 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 标头之后?

4

2 回答 2

2

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

如果.interphack 有效,那么当然也可以。

于 2017-07-17T20:10:27.923 回答
1

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

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

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

于 2021-01-05T06:03:32.030 回答