Skip to content

Differences from ld and lld when handling orphan sections in the presence of MEMORY #127

@jonathonpenix

Description

@jonathonpenix

Description
eld seems to place orphan sections according to the MEMORY region attributes, but it seems that ld and lld have special cases around this where they may ignore the region attributes. See https://reviews.llvm.org/D112925 for some discussion around this in lld. See also https://maskray.me/blog/2024-06-02-understanding-orphan-sections. I'm not sure the original motivation for this behavior in ld.

I'm not sure if eld wants to mirror this behavior or just document it as a divergence from lld/ld, etc.

This came up when testing Zephyr where some tests would fail due to the placement of orphaned .eh_frame sections (the test below isn't exactly matching that situation, but is derived from that). The .eh_frames have since been explicitly /DISCARD/'ed, but not sure if this will come up again.

Example

cat > main.c << '!'
const int data = 1;

int main(int argc, char *argv[]) {
  return 0;
}
!
cat > script.t << '!'
MEMORY {
  REGION1 (rx) : ORIGIN = 0x1000, LENGTH = 0x500
  REGION2 (!rwx) : ORIGIN = 0x2000, LENGTH = 0x500
}

SECTIONS {
  .text : { *(.text) } > REGION2
  /* Uncommenting below, lld places .rodata in REGION1, which makes sense to me.
   * Older versions of GNU ld still places .rodata in REGION2, which seems strange, but
   * it looks like this might have been fixed (newer version seem to place in REGION1)
   */
  /* .rodata : { *(.rodata) } */
}
!

clang --target=riscv32-unknown-elf -c main.c
ld.eld -march riscv32 -T script.t main.o -o eld.a.out
ld.lld -T script.t main.o -o lld.a.out
riscv32-unknown-elf-ld.bfd -T script.t main.o -o ld.a.out

Output

$ llvm-readelf -S eld.a.out
...
  [ 1] .text             PROGBITS        00002000 001000 000020 00  AX  0   0  2
  [ 2] .rodata           PROGBITS        00001000 002000 000004 00   A  0   0  4
...
$ llvm-readelf -S lld.a.out
...
  [ 1] .text             PROGBITS        00002000 001000 000020 00  AX  0   0  2
  [ 2] .rodata           PROGBITS        00002020 001020 000004 00   A  0   0  4
...
$ llvm-readelf -S ld.a.out
...
  [ 1] .text             PROGBITS        00002000 001000 000020 00  AX  0   0  2
  [ 2] .rodata           PROGBITS        00002020 001020 000004 00   A  0   0  4
...

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions