agra-uni-bremen / riscv-vp

RISC-V Virtual Prototype
MIT License
139 stars 49 forks source link

ELF loader does not recognize NOBIT sections #10

Open U2654 opened 3 years ago

U2654 commented 3 years ago

The following elf program header fails within elf_loader.h in line 54. The used linker script is a standard one of the freedom-e-sdk. The problem is the fourth section which corresponds to the .bss section and surprises the GenericElfLoader...

    LOAD off    0x00001000 vaddr 0x20010000 paddr 0x20010000 align 2**12
         filesz 0x000011a8 memsz 0x000011a8 flags rwx
    LOAD off    0x00003000 vaddr 0x80000000 paddr 0x20018e80 align 2**12
         filesz 0x00000b0c memsz 0x00000b0c flags rw-
     TLS off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags ---
    LOAD off    0x00003b10 vaddr 0x80000b10 paddr 0x80000b10 align 2**12
         filesz 0x00000000 memsz 0x00000cb0 flags rw-
    LOAD off    0x00003b0c vaddr 0x00000000 paddr 0x00000000 align 2**12
         filesz 0x00000000 memsz 0x00000000 flags ---
    LOAD off    0x00004200 vaddr 0x20011200 paddr 0x20011200 align 2**12
         filesz 0x00007c7a memsz 0x00007c7a flags r-x
    LOAD off    0x0000be7a vaddr 0x00000000 paddr 0x00000000 align 2**12
         filesz 0x00000000 memsz 0x00000000 flags ---
Cirromulus commented 3 years ago

Could you please add:

  1. Steps to reproduce the error
  2. Related error messages
  3. Maybe even a short gdb-session narrowing the problem down
U2654 commented 3 years ago
  1. Compile example with freedom-studio for hifive1-revb. I know revb is currently not supported but this does not matter as you can generate an elf file with this sections.
  2. run

    ./hifive-vp firmware.elf 
    
        SystemC 2.3.3-Accellera --- Feb 22 2021 22:06:21
        Copyright (c) 1996-2018 by all Contributors,
        ALL RIGHTS RESERVED
    Assertion failed: ((addr >= offset) && (addr + p->p_memsz <= offset + size)), function load_executable_image, file /Users/matthias/embedded/riscv-vp/vp/src/./core/common/elf_loader.h, line 54.
    Abort trap: 6

    The assert does not expect the vaddr 0x80000b10.

Cirromulus commented 3 years ago

As we don't use the freedom-studio, could you post your ELF? Do you know why the assertion fails, what are the other parameters? Usually, a .bss is no problem.

U2654 commented 3 years ago

Yes, it is not a .bss problem. Actually, it is a sifive ld-script issue. However, the elf works on physical hw. Thus, it might be useful to consider. Attached is the "hello world" example built of the freedom-e-sdk for the hifive1 platform. Same issue... hello.elf.gz

Cirromulus commented 3 years ago

Solution introduced breaks certain other setups. As far as I understand it, your ELFs do not contain zero-bit sections but mention it, other ELFs actually carry the zeroes.

U2654 commented 3 years ago

As far as I remember, paddr was not accepted (assert) as paddr > offset + size.

Cirromulus commented 3 years ago

The Specification states:

ELF allows for any segment to contain NOBITS sections. The link-editor places such sections at the end of the segment they are assigned to. This is implemented using the program header entry p_filesz and p_memsz fields, which must follow the following rule.

        p_memsz >= p_filesz
If p_memsz is greater than p_filesz, the extra bytes are NOBITS. The first p_filesz bytes come from the object file, and any remaining bytes up to p_memsz are zeroed by the system prior to use.

The default assignment rules assign read-only NOBITS sections to the text segment, and writable NOBITS sections to the data segment. The link-editor defines the bss segment as an alternative segment that can accept writable NOBITS sections. This segment is disabled by default, and must be explicitly enabled to be used.

Since writable NOBITS sections are easily handled as part of the data segment, the benefit of having a separate bss segment may not be immediately obvious. By convention, the process dynamic memory heap starts at the end of the final segment, which must be writable. This is usually the data segment, but if bss is enabled, bss becomes the final segment. When building a dynamic executable, enabling the bss segment with an appropriate alignment can be used to enable large page assignment of the heap. For example, the following enables the bss segment and sets an alignment of 4MB.

        LOAD_SEGMENT bss {
                ALIGN=0x400000;
        };

Our Problem was, that if NOBITS was detected, all data was discarded. The correct way would be copying for p_filesz bytes and then filling the rest with zeroes. I'm on that.