https://sourceware.org/bugzilla/show_bug.cgi?id=25354
Bug ID: 25354 Summary: On RISCV64 LD, with EXACTLY 72 headers/sections, PhysAddr for first Program Header is wrong Product: binutils Version: 2.33 Status: UNCONFIRMED Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: mmints at nvidia dot com Target Milestone: --- Created attachment 12174 --> https://sourceware.org/bugzilla/attachment.cgi?id=12174&action=edit Full TEST.ld with the 72 sections. Steps to reproduce: (1) Build binutils 2.33.1 (or a prior version, tested repro on 2.31 as well) with --target=riscv64-elf (2) Using gcc (also built with --target=riscv64-elf), build a simple dummy object file: $ cat dummy.c int main(void) { return 0; } $ gcc -c dummy.c -o dummy.o -nostdlib (3) Create the following .ld file: $ cat TEST.ld MEMORY { virt : ORIGIN = 0x100000, LENGTH = 0x20000 phys : ORIGIN = 0x10000, LENGTH = 0x20000 } __phys_ptr = ORIGIN(phys); SECTIONS { . = ORIGIN(virt); .fakeSection0 . : AT(__phys_ptr) { *(.text); . += 0x100; } __phys_ptr += SIZEOF(.fakeSection0); . += 0x100; .fakeSection1 . : AT(__phys_ptr) { . += 0x100; } __phys_ptr += SIZEOF(.fakeSection1); . += 0x100; // !!!!!!!!!!!!!!!!! (file cropped, please see attachment for full) !!!!!!!! .fakeSection70 . : AT(__phys_ptr) { . += 0x100; } __phys_ptr += SIZEOF(.fakeSection70); . += 0x100; .fakeSection71 . : AT(__phys_ptr) { . += 0x100; } } (4) Build a RISCV .elf: $ ./riscv64-elf/bin/ld dummy.o -o TEST.elf -T TEST.ld $ ./riscv64-elf/bin/readelf --all TEST.elf > TEST.readelf (5) Open TEST.readelf and look for the Program Headers. This is what it looks like for me: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x00000000000ff000 0x000000000000f000 0x0000000000001110 0x0000000000001110 R E 0x1000 LOAD 0x0000000000001210 0x0000000000100210 0x0000000000010110 0x0000000000000000 0x0000000000000100 RW 0x1000 LOAD 0x0000000000001410 0x0000000000100410 0x0000000000010210 0x0000000000000000 0x0000000000000100 RW 0x1000 LOAD 0x0000000000001610 0x0000000000100610 0x0000000000010310 0x0000000000000000 0x0000000000000100 RW 0x1000 ... The first section doesn't make sense, PhysAddr should start at 0x10000 but it's 0xf000. The subsequent sections look fine. Note that there should be EXACTLY 72 LOAD-s in the Program Headers. If you add a section or remove a section, the problem goes away and the headers in TEST.readelf start looking like this: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000001000 0x0000000000100000 0x0000000000010000 0x0000000000000110 0x0000000000000110 R E 0x1000 LOAD 0x0000000000001210 0x0000000000100210 0x0000000000010110 0x0000000000000000 0x0000000000000100 RW 0x1000 LOAD 0x0000000000001410 0x0000000000100410 0x0000000000010210 0x0000000000000000 0x0000000000000100 RW 0x1000 LOAD 0x0000000000001610 0x0000000000100610 0x0000000000010310 0x0000000000000000 0x0000000000000100 RW 0x1000 ... Adding a section assumes adding something like this to the .ld: ... __phys_ptr += SIZEOF(.fakeSection71); . += 0x100; .fakeSection72 . : AT(__phys_ptr) { . += 0x100; } ... Note that Offset, FileSiz and MemSiz also become different, by the same absolute amount of 0x1000 (on a more complex repro the same happened with a different absolute amount instead of 0x1000). *(.text) being in the first section doesn't matter, you can put it anywhere else and the problem persists. But add or remove a section and the problem goes away. The issue only occurs when you have EXACTLY 72 Program Headers (and, in the case of this simple ld script, exactly 72 sections). -- You are receiving this mail because: You are on the CC list for the bug.