bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/25354] New: On RISCV64 LD, with EXACTLY 72 headers/sections, Ph


From: mmints at nvidia dot com
Subject: [Bug ld/25354] New: On RISCV64 LD, with EXACTLY 72 headers/sections, PhysAddr for first Program Header is wrong
Date: Wed, 08 Jan 2020 04:48:26 +0000

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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]