[llvm-dev] Understanding of ldd header allocation

vit9696 via llvm-dev
2017-10-09T17:54:11Z

Hello,

I am currently switching to ldd from ld.bfd on a cross-platform embedded project
and am facing a behaviour difference when using the same linker scripts with
ld.bfd and ldd. Could anybody please give me a more reliable direction I should
go with to get the same behaviour from both of the linkers?

Target binary format is a 32-bit ELF executable, which is expected to consist of
a single RWX segment starting from base 0x80000000. (Since I can reproduce the
difference with at least mips, ppc32, x86, I attached the x86 linker script to
the message as an example.) What is expected from the resulting binary (and what
ld.bfd produces) is that no ELF headers are allocated in the address space, e.g.


Elf file type is EXEC (Executable file)
Entry point 0x80001a0f
There are 1 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x80000000 0x80000000 0x08284 0x08284 RWE 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata .eh_frame .data


However, what ldd does is different. (To create a single segment I use --omagic
argument, it works fine and is unrelated). The first segment is created at a
lower address, with ELF headers in it, and then the actual text section exactly
at 0x80000000:


Elf file type is EXEC (Executable file)
Entry point 0x80002670
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x7ffff034 0x7ffff034 0x00060 0x00060 R   0x4
  LOAD           0x000000 0x7ffff000 0x7ffff000 0x0a098 0x0a098 RWE 0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x0

 Section to Segment mapping:
  Segment Sections...
   00
   01     .text .rodata .data
   02


From what I understand if a linker script is used and the headers fail to
allocate, then they should not be present in the resulting binary. However, it
seems like ldd treats custom headers and automatically generated headers
differently (well, that's at least how I see it at the moment). I think, if
the headers are custom, they may not appear in the address space, otherwise they
(always?) do. I came up with this conclusion because adding the following
command appears to produce a correct binary:

PHDRS
{
  main PT_LOAD;
}


Elf file type is EXEC (Executable file)
Entry point 0x80002670
There are 1 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x80000000 0x80000000 0x09098 0x09098 RWE 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata .data


However, this is not valid for at least ld.bfd, which produces an error in this
case:
ld: no sections assigned to phdrs

At this step I feel a little confused, because even though I have a workaround,
it is unclear whether both behaviours (with and without the mentioned
workaround) are expected in the first place? Or might it actually be a bug in
either of the linkers? Ideally I have some workaround that works in both of the
linkers, but if it is not possible, I could continue going with PHDRS hack.

Best regards,
Vit

-------------- next part --------------
A non-text attachment was scrubbed...
Name: example.lds
Type: application/octet-stream
Size: 293 bytes
Desc: not available
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20171009/ab39f667/attachment.obj>
-------------- next part --------------


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Message signed with OpenPGP
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20171009/ab39f667/attachment.sig>