multiboot2 标头在 ELF 文件中“太晚”大偏移,即使它是第一部分

问题描述

在我的最终 multiboot2 中找不到 ELF 标头,因为在二进制文件中它位于偏移量 0x334e0,但 multiboot2 规范只告诉第一个 {{1 }},即 32KiB 字节,被检查。因此,“为时已晚”。

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

我的链接器脚本(用于 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

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

PS:ELF get 是由 cargo/rustc/llvm 组装的,在我的例子中它使用 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 和自定义链接脚本。

解决方法

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

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

您需要将 .rodata... 移动到一个单独的段中(通过调整链接描述文件),您需要为 ELF 标头禁用单独的 RO 段(这将允许 .text 位于第一段)。请参阅 this 答案。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...