lld extra program headers

Hello all,

The lld linker appears to generate extra ELF program headers and thus
causes file sizes to be significantly larger than what would get with
ld.gold or ld.bfd.

# readelf -l test.bfd

Elf file type is EXEC (Executable file)
Entry point 0x4000b0
There are 2 program headers, starting at offset 64

Program Headers:
  Type Offset VirtAddr PhysAddr
                 FileSiz MemSiz Flags Align
  LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000000c0 0x00000000000000c0 R E 0x200000
  GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000 RW 0x10

Section to Segment mapping:
  Segment Sections...
   00 .text
   01
# readelf -l test.gold

Elf file type is EXEC (Executable file)
Entry point 0x4000b0
There are 2 program headers, starting at offset 64

Program Headers:
  Type Offset VirtAddr PhysAddr
                 FileSiz MemSiz Flags Align
  LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000000c0 0x00000000000000c0 R E 0x1000
  GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000 RW 0x10

Section to Segment mapping:
  Segment Sections...
   00 .text
   01
# readelf -l test.lld

Elf file type is EXEC (Executable file)
Entry point 0x201000
There are 4 program headers, starting at offset 64

Program Headers:
  Type Offset VirtAddr PhysAddr
                 FileSiz MemSiz Flags Align
  PHDR 0x0000000000000040 0x0000000000200040 0x0000000000200040
                 0x00000000000000e0 0x00000000000000e0 R 0x8
  LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000
                 0x0000000000000120 0x0000000000000120 R 0x1000
  LOAD 0x0000000000001000 0x0000000000201000 0x0000000000201000
                 0x0000000000000010 0x0000000000000010 R E 0x1000
  GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000 RW 0x0

Section to Segment mapping:
  Segment Sections...
   00
   01
   02 .text
   03

Now obviously disk space is relatively cheap these days but if it could
be avoided, can we avoid generating these unused memory mappings unless
a PT_INTERP section is going to be generated? I could also be
misunderstanding things, and it might be normal to map the program's
program headers into memory (and thus the entire ELF header).

Thanks.

Hi Will,

ld.gold and ld.bfd seem handle PHDR and INTERP as executable segments. That’s why they use only one page for PHDR, INTERP and the first executable page.

lld on the other hand handles them as non-executable segments, as they are not really executable code. I think what lld does is more desirable.

Note too that that is just a different default. You can pass
--no-rosegment to lld if you want.

Cheers,
Rafael

Rui Ueyama via llvm-dev <llvm-dev@lists.llvm.org> writes: