1

在我的multiboot2final 中找不到标头ELF,因为在二进制文件中它位于 offset 处0x334e0,但 multiboot2 规范只检查第一个32KiB,即0x8000字节。因此,它“为时已晚”。

我不知道我该如何解决这个问题。ELF 标头是否过于臃肿?multiboot2 标头本身是正确的,即检查 multiboot2 标头的几个工具告诉它是正确的。当我将标题与其他代码链接在一起时,它只是不起作用。如果我调整工具以验证 multiboot2 标头,即bootimage[ 1 ] 比第一个更查看32KiB,它也可以工作。

我的链接器脚本(用于GNU ld):

/** The "start"-symbol from start.asm. */
ENTRY(start)

SECTIONS {

    /* Multiboot2-Header must be 64-bit (8 byte) aligned according to spec. */
    . = ALIGN(8);
    .multiboot2_header :
    {
        /* ensure that the multiboot header is at the beginning */
        *(.multiboot2_header)
    }

    .text :
    {
        *(.text)
    }
}

readelf -WSl <my-elf>告诉,该.multiboot2_header部分确实是第一个:

There are 1526 section headers, starting at offset 0x3ca8d8:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .multiboot2_header PROGBITS        0000000000000000 0334e8 000048 00      0   0  8
  [ 2] .debug_abbrev     PROGBITS        0000000000000000 033530 00ecea 00      0   0  1
  [ 3] .debug_info       PROGBITS        0000000000000000 04221a 0f0391 00      0   0  1
  [ 4] .debug_aranges    PROGBITS        0000000000000000 1325ab 019f40 00      0   0  1
  [ 5] .debug_ranges     PROGBITS        0000000000000000 14c4eb 0301d0 00      0   0  1
  [ 6] .debug_str        PROGBITS        0000000000000000 17c6bb 0c5de1 01  MS  0   0  1
  [ 7] .debug_pubnames   PROGBITS        0000000000000000 24249c 035215 00      0   0  1
  [ 8] .debug_pubtypes   PROGBITS        0000000000000000 2776b1 058c44 00      0   0  1
  [ 9] .debug_frame      PROGBITS        0000000000000000 2d02f8 033b60 00      0   0  8
  [10] .debug_line       PROGBITS        0000000000000000 303e58 08390a 00      0   0  1
  [11] .debug_loc        PROGBITS        0000000000000000 387762 0038d8 00      0   0  1
  [12] .comment          PROGBITS        0000000000000000 38b03a 000013 01  MS  0   0  1
  [13] .symtab           SYMTAB          0000000000000000 38b050 0089d0 18     15 803  8
  [14] .shstrtab         STRTAB          0000000000000000 393a20 01cec9 00      0   0  1
  [15] .strtab           STRTAB          0000000000000000 3b08e9 019fee 00      0   0  1
  [16] .rodata._ZN137_$LT$rust_multiboot2_64_bit_kernel..logger..BootStageAwareLogger$u20$as$u20$rust_multiboot2_64_bit_kernel..boot_stage..BootStageAware$GT$15next_boot_stage17h5918ecf04a4f1232E PROGBITS        0000000000000000 000160 000010 00   A  0   0  4
  ...
  [179] .rodata..L__unnamed_94 PROGBITS        00000000000045a8 004708 00007f 00   A  0   0  1
  [180] .eh_frame_hdr     PROGBITS        0000000000004628 004788 00000c 00   A  0   0  4
  [181] .eh_frame         PROGBITS        0000000000004638 004798 00001c 00   A  0   0  8
  [182] .text             PROGBITS        0000000000004654 0047b4 00001b 00  AX  0   0  4
  [183] .text._ZN29rust_multiboot2_64_bit_kernel6logger20BootStageAwareLogger13apply_to_each17h77f9f12abd1f054eE PROGBITS        0000000000004670 0047d0 000130 00  AX  0   0 16
  ...
  [1388] .text._ZN54_$LT$u32$u20$as$u20$core..ops..bit..Shl$LT$i32$GT$$GT$3shl17h0ba8101e5b58ae12E PROGBITS        0000000000030390 0304f0 000049 00  AX  0   0 16
  [1389] .text._ZN58_$LT$$RF$u32$u20$as$u20$core..ops..bit..Shl$LT$i32$GT$$GT$3shl17h518033907a793365E PROGBITS        00000000000303e0 030540 000021 00  AX  0   0 16
  [1390] .text.memcpy      PROGBITS        0000000000030410 030570 00004e 00  AX  0   0 16
  [1391] .text.memset      PROGBITS        0000000000030460 0305c0 0000a4 00  AX  0   0 16
  [1392] .text.memcmp      PROGBITS        0000000000030510 030670 000179 00  AX  0   0 16
  [1393] .data.rel.ro..L__unnamed_1 PROGBITS        0000000000030690 0307f0 0002c0 00  WA  0   0  8
  [1394] .data.rel.ro..L__unnamed_2 PROGBITS        0000000000030950 030ab0 000300 00  WA  0   0  8
  ...
  [1515] .data.rel.ro..L__unnamed_169 PROGBITS        00000000000332e0 033440 000018 00  WA  0   0  8
  [1516] .got              PROGBITS        00000000000332f8 033458 000090 00  WA  0   0  8
  [1517] .bss._ZN29rust_multiboot2_64_bit_kernel6logger6LOGGER17h0a7e2a9a53f2b5ddE NOBITS          0000000000033388 0334e8 000018 00  WA  0   0  8
  [1518] .bss              NOBITS          00000000000333a0 0334e8 020000 00  WA  0   0  8
  [1519] .bss._ZN29rust_multiboot2_64_bit_kernel3mb225MULTIBOOT2_INFO_STRUCTURE17h67db2667e3bd19ceE NOBITS          00000000000533a0 0334e8 000018 00  WA  0   0  8
  [1520] .bss._ZN29rust_multiboot2_64_bit_kernel5panic13PANIC_HANDLER17h02bbbbc17c579b55E NOBITS          00000000000533b8 0334e8 00000c 00  WA  0   0  4
  [1521] .bss._ZN29rust_multiboot2_64_bit_kernel5xuefi10UEFI_ST_BS17ha7c24b049d2b76abE NOBITS          00000000000533c8 0334e8 000008 00  WA  0   0  8
  [1522] .bss._ZN29rust_multiboot2_64_bit_kernel10boot_stage10BOOT_STAGE17he05c77811885a1c6E NOBITS          00000000000533d0 0334e8 000001 00  WA  0   0  1
  [1523] .bss._ZN29rust_multiboot2_64_bit_kernel11kernelalloc9ALLOCATOR17h93bce260f0439187E NOBITS          00000000000533d1 0334e8 000001 00  WA  0   0  1
  [1524] .bss._ZN3log5STATE17hdfa5c64bc29aed3eE NOBITS          00000000000533d8 0334e8 000008 00  WA  0   0  8
  [1525] .bss._ZN3log20MAX_LOG_LEVEL_FILTER17h84bf10c3ec44ab54E NOBITS          00000000000533e0 0334e8 000008 00  WA  0   0  8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Elf file type is EXEC (Executable file)
Entry point 0x4654
There are 5 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000160 0x0000000000000000 0x0000000000000000 0x004654 0x004654 R   0x10
  LOAD           0x0047b4 0x0000000000004654 0x0000000000004654 0x02c035 0x02c035 R E 0x10
  LOAD           0x0307f0 0x0000000000030690 0x0000000000030690 0x002cf8 0x022d58 RW  0x8
  GNU_EH_FRAME   0x004788 0x0000000000004628 0x0000000000004628 0x00000c 0x00000c R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     .rodata._ZN137_$LT$rust_multib...
   01     .text .text._ZN29rust_multiboot2_64_bit_kernel6logger2...
   02     .data.rel.ro..L__unnamed_1 .data.rel.ro..L__unnamed_2 ...
   03     .eh_frame_hdr 
   04     

在那里,您可以看到文件中的标题“为时已晚”。我该如何解决这个问题?如何将它移动到 ELF 文件中的较小偏移量,即更靠近文件开头?

PS:ELF get 是由 cargo/rustc/llvm 组装的,GNU ld在我的例子中它与自定义链接脚本一起使用。

4

1 回答 1

0
 Section to Segment mapping:
  Segment Sections...
   00     .rodata._ZN137_$LT$rust_multib...
   01     .text .text._ZN29rust_multiboot2_64_bit_kernel6logger2...
...

很明显,这些.rodata._ZN....部分在文件中的偏移量较低,.text实际上并不是第一个。

您需要移动.rodata...到一个单独的段(通过调整链接描述文件),或者您需要禁用ROELF 标头的单独段(这将允许.text在第一个段中)。看到这个答案。

于 2021-07-22T01:20:30.750 回答