mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] ld-musl-* and empty .eh_frame
@ 2021-03-05  3:18 Michael Forney
  2021-03-05 15:07 ` Rich Felker
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Forney @ 2021-03-05  3:18 UTC (permalink / raw)
  To: musl

Hi,

Érico noticed that cproc (my C compiler) produced executables that
musl's dynamic linker fails to load when passed as an argument:

  /lib/ld-musl-x86_64.so.1: ./t: Not a valid dynamic program

However, running ./t directly works fine. It turns out that this
is because the executables have an empty .eh_frame section, which
causes musl to attempt an mmap with length 0 which fails with EINVAL.

GNU ld seems to always create a .eh_frame section in the final
executable (unless you pass --no-ld-generated-unwind-info), regardless
of whether any of the objects had one. Since none of the objects I
built have an .eh_frame and none of musl's crt*.o have one, it ends
up empty.

gcc does not have this problem because its crtend.o has a non-empty
.eh_frame (size is 4, so looks to be a CIE terminator according to LSB[0]).

Here's a short shell session demonstrating the problem:

  $ cat t.s
  .text
  .globl main
  main:
          movl $123, %eax
          ret
  $ as -o t.o t.s
  $ ld --dynamic-linker /lib/ld-musl-x86_64.so.1 -o t /lib/crt1.o /lib/crti.o t.o /lib/libc.so /lib/crtn.o
  $ ./t ; echo $?
  123
  $ /lib/ld-musl-x86_64.so.1 ./t
  /lib/ld-musl-x86_64.so.1: ./t: Not a valid dynamic program
  $ strace /lib/ld-musl-x86_64.so.1 ./t
  execve("/lib/ld-musl-x86_64.so.1", ["/lib/ld-musl-x86_64.so.1", "./t"], 0x7ffd8c17e4e8 /* 34 vars */) = 0
  arch_prctl(ARCH_SET_FS, 0x7f3691752aa8) = 0
  set_tid_address(0x7f3691754fd8)         = 31726
  open("./t", O_RDONLY|O_LARGEFILE)       = 3
  read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0 \20@\0\0\0\0\0"..., 960) = 960
  mmap(0x400000, 16384, PROT_READ, MAP_PRIVATE, 3, 0) = 0x400000
  mmap(0x401000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0x1000) = 0x401000
  mmap(0x402000, 0, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0x2000) = -1 EINVAL (Invalid argument)
  munmap(0x400000, 16384)                 = 0
  writev(2, ["/lib/ld-musl-x86_64.so.1: ./t: N"...59, NULL0], 2/lib/ld-musl-x86_64.so.1: ./t: Not a valid dynamic program
  ) = 59
  exit_group(1)                           = ?
  +++ exited with 1 +++
  $

This leaves me with a few questions:

1. Is it invalid for an ELF executable to have an empty .eh_frame
   section? The only documentation I could find about it is [0],
   which says that it must contain one or more CFI records, so 0
   would be invalid.
2. Is it the compiler's responsibility to link with an object
   containing a CIE terminator (like gcc's crtend.o) to prevent an
   empty .eh_frame section?
3. Is it a bug that GNU ld creates an empty .eh_frame by default,
   even when none of the objects it is linking have one? It looks
   like lld does not create an .eh_frame in this case.
4. Should musl's ld.so be able to handle such executables? The
   kernel does not seem to have a problem with it, as well glibc's
   ld.so with an executable I crafted with a 0-length .eh_frame
   section.

Or perhaps some combination of the four? Any insight is appreciated.

Thanks!

[0] https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-05  3:18 [musl] ld-musl-* and empty .eh_frame Michael Forney
@ 2021-03-05 15:07 ` Rich Felker
  2021-03-05 16:12   ` Rich Felker
  0 siblings, 1 reply; 10+ messages in thread
From: Rich Felker @ 2021-03-05 15:07 UTC (permalink / raw)
  To: Michael Forney; +Cc: musl

On Thu, Mar 04, 2021 at 07:18:11PM -0800, Michael Forney wrote:
> Hi,
> 
> Érico noticed that cproc (my C compiler) produced executables that
> musl's dynamic linker fails to load when passed as an argument:
> 
>   /lib/ld-musl-x86_64.so.1: ./t: Not a valid dynamic program
> 
> However, running ./t directly works fine. It turns out that this
> is because the executables have an empty .eh_frame section, which
> causes musl to attempt an mmap with length 0 which fails with EINVAL.

The section itself isn't the problem; rather the linker making a
dedicated PROT_READ segment with no non-zero-length sections in it is.
It really should have collapsed that out. (Also it would not happen
without the separate-text option, which mcm disables because it makes
lots of problems.)

With that said, there's no good reason we should error out on this;
it's syntactically and semantically valid just pointless for the
linker to emit. I think adding if (!n) return p; at the top of
mmap_fixed in dynlink.c fixes it.

> This leaves me with a few questions:
> 
> 1. Is it invalid for an ELF executable to have an empty .eh_frame
>    section? The only documentation I could find about it is [0],
>    which says that it must contain one or more CFI records, so 0
>    would be invalid.
> 2. Is it the compiler's responsibility to link with an object
>    containing a CIE terminator (like gcc's crtend.o) to prevent an
>    empty .eh_frame section?

Sections are irrelevant to an executable file so it doesn't matter
whatsoever. They're involved only in pre-link contracts and debugging.

> 3. Is it a bug that GNU ld creates an empty .eh_frame by default,
>    even when none of the objects it is linking have one? It looks
>    like lld does not create an .eh_frame in this case.

I don't think so. I think the bug is in the segment logic.

> 4. Should musl's ld.so be able to handle such executables? The
>    kernel does not seem to have a problem with it, as well glibc's
>    ld.so with an executable I crafted with a 0-length .eh_frame
>    section.

Yes.

Rich

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-05 15:07 ` Rich Felker
@ 2021-03-05 16:12   ` Rich Felker
  2021-03-05 22:53     ` Michael Forney
  0 siblings, 1 reply; 10+ messages in thread
From: Rich Felker @ 2021-03-05 16:12 UTC (permalink / raw)
  To: Michael Forney; +Cc: musl

On Fri, Mar 05, 2021 at 10:07:32AM -0500, Rich Felker wrote:
> On Thu, Mar 04, 2021 at 07:18:11PM -0800, Michael Forney wrote:
> > Hi,
> > 
> > Érico noticed that cproc (my C compiler) produced executables that
> > musl's dynamic linker fails to load when passed as an argument:
> > 
> >   /lib/ld-musl-x86_64.so.1: ./t: Not a valid dynamic program
> > 
> > However, running ./t directly works fine. It turns out that this
> > is because the executables have an empty .eh_frame section, which
> > causes musl to attempt an mmap with length 0 which fails with EINVAL.
> 
> The section itself isn't the problem; rather the linker making a
> dedicated PROT_READ segment with no non-zero-length sections in it is.
> It really should have collapsed that out. (Also it would not happen
> without the separate-text option, which mcm disables because it makes
> lots of problems.)
> 
> With that said, there's no good reason we should error out on this;
> it's syntactically and semantically valid just pointless for the
> linker to emit. I think adding if (!n) return p; at the top of
> mmap_fixed in dynlink.c fixes it.

In practice this probably does, but there's also something of a
question what to do if the zero-size segment is not page aligned. This
is not actually a mmap error since it will be automatically expanded
out to page boundaries in both directions, but if ld is capable of
emitting such segments they may be semantically wrong (mapping over
top of something else they're not intended to). Can you confirm that
ld isn't doing anything awful here?

Rich

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-05 16:12   ` Rich Felker
@ 2021-03-05 22:53     ` Michael Forney
  2021-03-06  1:14       ` Fangrui Song
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Forney @ 2021-03-05 22:53 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

On 2021-03-05, Rich Felker <dalias@libc.org> wrote:
>> The section itself isn't the problem; rather the linker making a
>> dedicated PROT_READ segment with no non-zero-length sections in it is.
>> It really should have collapsed that out. (Also it would not happen
>> without the separate-text option, which mcm disables because it makes
>> lots of problems.)

Ah, that makes more sense. It explains why my attempt to strip
.eh_frame from the executable did not have an effect; only stripping
it from the objects before linking fixed the issue.

>> With that said, there's no good reason we should error out on this;
>> it's syntactically and semantically valid just pointless for the
>> linker to emit. I think adding if (!n) return p; at the top of
>> mmap_fixed in dynlink.c fixes it.
>
> In practice this probably does, but there's also something of a
> question what to do if the zero-size segment is not page aligned. This
> is not actually a mmap error since it will be automatically expanded
> out to page boundaries in both directions, but if ld is capable of
> emitting such segments they may be semantically wrong (mapping over
> top of something else they're not intended to). Can you confirm that
> ld isn't doing anything awful here?

I'm not too familiar with the binutils codebase, but I can try. As far
as I can tell, the alignment is set to at least the maximum page size:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5601

The offset to make p_vaddr page-aligned is computed here:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5622

and p_vaddr is adjusted here:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5688

So it seems to me that these segments will be page-aligned, but it
could very well be the case that I am not following the code correctly
(or I am just looking at the wrong part of this 13k line file).
Someone more familiar with binutils should probably confirm.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-05 22:53     ` Michael Forney
@ 2021-03-06  1:14       ` Fangrui Song
  2021-03-06  1:28         ` Rich Felker
  2021-03-06  1:30         ` Michael Forney
  0 siblings, 2 replies; 10+ messages in thread
From: Fangrui Song @ 2021-03-06  1:14 UTC (permalink / raw)
  To: musl; +Cc: Rich Felker

On 2021-03-05, Michael Forney wrote:
>On 2021-03-05, Rich Felker <dalias@libc.org> wrote:
>>> The section itself isn't the problem; rather the linker making a
>>> dedicated PROT_READ segment with no non-zero-length sections in it is.
>>> It really should have collapsed that out. (Also it would not happen
>>> without the separate-text option, which mcm disables because it makes
>>> lots of problems.)
>
>Ah, that makes more sense. It explains why my attempt to strip
>.eh_frame from the executable did not have an effect; only stripping
>it from the objects before linking fixed the issue.
>
>>> With that said, there's no good reason we should error out on this;
>>> it's syntactically and semantically valid just pointless for the
>>> linker to emit. I think adding if (!n) return p; at the top of
>>> mmap_fixed in dynlink.c fixes it.
>>
>> In practice this probably does, but there's also something of a
>> question what to do if the zero-size segment is not page aligned. This
>> is not actually a mmap error since it will be automatically expanded
>> out to page boundaries in both directions, but if ld is capable of
>> emitting such segments they may be semantically wrong (mapping over
>> top of something else they're not intended to). Can you confirm that
>> ld isn't doing anything awful here?

Can you clarify how GNU ld creates an empty .eh_frame?
The program header PT_GNU_EH_FRAME is created from .eh_frame_hdr, which
is created by ld --eh-frame-hdr.
If .eh_frame is empty, from my observation GNU ld does not create .eh_frame_hdr

https://maskray.me/blog/2020-11-08-stack-unwinding#eh_frame_hdr-and-pt_eh_frame

>I'm not too familiar with the binutils codebase, but I can try. As far
>as I can tell, the alignment is set to at least the maximum page size:
>https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5601

max-page-size is for layouting PT_LOAD.
It is unrelated to PT_GNU_EH_FRAME.

>The offset to make p_vaddr page-aligned is computed here:
>https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5622
>
>and p_vaddr is adjusted here:
>https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5688
>So it seems to me that these segments will be page-aligned, but it
>could very well be the case that I am not following the code correctly
>(or I am just looking at the wrong part of this 13k line file).
>Someone more familiar with binutils should probably confirm.

The requirement is
http://www.sco.com/developers/gabi/latest/ch5.pheader.html
"p_vaddr should equal p_offset, modulo p_align."

p_vaddr % p_align != 0 is valid.

p_memsz can be zero.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-06  1:14       ` Fangrui Song
@ 2021-03-06  1:28         ` Rich Felker
  2021-03-06  1:30         ` Michael Forney
  1 sibling, 0 replies; 10+ messages in thread
From: Rich Felker @ 2021-03-06  1:28 UTC (permalink / raw)
  To: Fangrui Song; +Cc: musl

On Fri, Mar 05, 2021 at 05:14:05PM -0800, Fangrui Song wrote:
> On 2021-03-05, Michael Forney wrote:
> >On 2021-03-05, Rich Felker <dalias@libc.org> wrote:
> >>>The section itself isn't the problem; rather the linker making a
> >>>dedicated PROT_READ segment with no non-zero-length sections in it is.
> >>>It really should have collapsed that out. (Also it would not happen
> >>>without the separate-text option, which mcm disables because it makes
> >>>lots of problems.)
> >
> >Ah, that makes more sense. It explains why my attempt to strip
> >.eh_frame from the executable did not have an effect; only stripping
> >it from the objects before linking fixed the issue.
> >
> >>>With that said, there's no good reason we should error out on this;
> >>>it's syntactically and semantically valid just pointless for the
> >>>linker to emit. I think adding if (!n) return p; at the top of
> >>>mmap_fixed in dynlink.c fixes it.
> >>
> >>In practice this probably does, but there's also something of a
> >>question what to do if the zero-size segment is not page aligned. This
> >>is not actually a mmap error since it will be automatically expanded
> >>out to page boundaries in both directions, but if ld is capable of
> >>emitting such segments they may be semantically wrong (mapping over
> >>top of something else they're not intended to). Can you confirm that
> >>ld isn't doing anything awful here?
> 
> Can you clarify how GNU ld creates an empty .eh_frame?
> The program header PT_GNU_EH_FRAME is created from .eh_frame_hdr, which
> is created by ld --eh-frame-hdr.
> If .eh_frame is empty, from my observation GNU ld does not create .eh_frame_hdr
> 
> https://maskray.me/blog/2020-11-08-stack-unwinding#eh_frame_hdr-and-pt_eh_frame
> 
> >I'm not too familiar with the binutils codebase, but I can try. As far
> >as I can tell, the alignment is set to at least the maximum page size:
> >https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5601
> 
> max-page-size is for layouting PT_LOAD.
> It is unrelated to PT_GNU_EH_FRAME.

The topic in question is PT_LOAD.

> >The offset to make p_vaddr page-aligned is computed here:
> >https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5622
> >
> >and p_vaddr is adjusted here:
> >https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5688
> >So it seems to me that these segments will be page-aligned, but it
> >could very well be the case that I am not following the code correctly
> >(or I am just looking at the wrong part of this 13k line file).
> >Someone more familiar with binutils should probably confirm.
> 
> The requirement is
> http://www.sco.com/developers/gabi/latest/ch5.pheader.html
> "p_vaddr should equal p_offset, modulo p_align."
> 
> p_vaddr % p_align != 0 is valid.
> 
> p_memsz can be zero.

Are these together valid? In that case, p_memsz==0 but p_vaddr %
p_align != 0 would result in mapping an unused page, no? Or is this
somehow a special case where the mapping size is not supposed to be
expanded out to page-aligned?

Rich

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-06  1:14       ` Fangrui Song
  2021-03-06  1:28         ` Rich Felker
@ 2021-03-06  1:30         ` Michael Forney
  2021-03-06  1:39           ` Fangrui Song
  1 sibling, 1 reply; 10+ messages in thread
From: Michael Forney @ 2021-03-06  1:30 UTC (permalink / raw)
  To: musl; +Cc: Rich Felker

[-- Attachment #1: Type: text/plain, Size: 1514 bytes --]

On 2021-03-05, Fangrui Song <i@maskray.me> wrote:
> Can you clarify how GNU ld creates an empty .eh_frame?

Sure, see the shell snippet in my original post.

> The program header PT_GNU_EH_FRAME is created from .eh_frame_hdr, which
> is created by ld --eh-frame-hdr.
> If .eh_frame is empty, from my observation GNU ld does not create
> .eh_frame_hdr

There is no PT_GNU_EH_FRAME in the executables. Based on Rich's
explanation earlier, my understanding is that the issue is that GNU ld
creates a empty PT_LOAD segment for the empty .eh_frame section.

I attached the output of readelf -l in case that is helpful.

> https://maskray.me/blog/2020-11-08-stack-unwinding#eh_frame_hdr-and-pt_eh_frame
>
>>I'm not too familiar with the binutils codebase, but I can try. As far
>>as I can tell, the alignment is set to at least the maximum page size:
>>https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5601
>
> max-page-size is for layouting PT_LOAD.
> It is unrelated to PT_GNU_EH_FRAME.

The empty PT_LOAD segment is the issue here, not PT_GNU_EH_FRAME.

> The requirement is
> http://www.sco.com/developers/gabi/latest/ch5.pheader.html
> "p_vaddr should equal p_offset, modulo p_align."
>
> p_vaddr % p_align != 0 is valid.
>
> p_memsz can be zero.

Are you saying that GNU ld might create PT_LOAD segments with zero
size, and unaligned p_vaddr? If that's the case, I think Rich might
have a valid concern here.

[-- Attachment #2: t-readelf.txt --]
[-- Type: text/plain, Size: 1891 bytes --]


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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R      0x8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x0000000000000019 0x0000000000000019  R      0x1
      [Requesting program interpreter: /lib/ld-musl-x86_64.so.1]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000000348 0x0000000000000348  R      0x1000
  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000
                 0x0000000000000060 0x0000000000000060  R E    0x1000
  LOAD           0x0000000000002000 0x0000000000402000 0x0000000000402000
                 0x0000000000000000 0x0000000000000000  R      0x1000
  LOAD           0x0000000000002e90 0x0000000000402e90 0x0000000000402e90
                 0x0000000000000190 0x0000000000000190  RW     0x1000
  DYNAMIC        0x0000000000002e90 0x0000000000402e90 0x0000000000402e90
                 0x0000000000000160 0x0000000000000160  RW     0x8
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RWE    0x10
  GNU_RELRO      0x0000000000002e90 0x0000000000402e90 0x0000000000402e90
                 0x0000000000000170 0x0000000000000170  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .gnu.hash .dynsym .dynstr .rela.dyn .rela.plt 
   03     .plt .text 
   04     .eh_frame 
   05     .dynamic .got .got.plt 
   06     .dynamic 
   07     
   08     .dynamic .got 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-06  1:30         ` Michael Forney
@ 2021-03-06  1:39           ` Fangrui Song
  2021-03-06  2:04             ` Michael Forney
  0 siblings, 1 reply; 10+ messages in thread
From: Fangrui Song @ 2021-03-06  1:39 UTC (permalink / raw)
  To: musl; +Cc: Rich Felker

On 2021-03-05, Michael Forney wrote:
>On 2021-03-05, Fangrui Song <i@maskray.me> wrote:
>> Can you clarify how GNU ld creates an empty .eh_frame?
>
>Sure, see the shell snippet in my original post.
>
>> The program header PT_GNU_EH_FRAME is created from .eh_frame_hdr, which
>> is created by ld --eh-frame-hdr.
>> If .eh_frame is empty, from my observation GNU ld does not create
>> .eh_frame_hdr
>
>There is no PT_GNU_EH_FRAME in the executables. Based on Rich's
>explanation earlier, my understanding is that the issue is that GNU ld
>creates a empty PT_LOAD segment for the empty .eh_frame section.
>
>I attached the output of readelf -l in case that is helpful.
>
>> https://maskray.me/blog/2020-11-08-stack-unwinding#eh_frame_hdr-and-pt_eh_frame
>>
>>>I'm not too familiar with the binutils codebase, but I can try. As far
>>>as I can tell, the alignment is set to at least the maximum page size:
>>>https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=84a5d942817a9a54b1170fbbb594787c5839aa54;hb=f35674005e609660f5f45005a9e095541ca4c5fe#l5601
>>
>> max-page-size is for layouting PT_LOAD.
>> It is unrelated to PT_GNU_EH_FRAME.
>
>The empty PT_LOAD segment is the issue here, not PT_GNU_EH_FRAME.
>
>> The requirement is
>> http://www.sco.com/developers/gabi/latest/ch5.pheader.html
>> "p_vaddr should equal p_offset, modulo p_align."
>>
>> p_vaddr % p_align != 0 is valid.
>>
>> p_memsz can be zero.
>
>Are you saying that GNU ld might create PT_LOAD segments with zero
>size, and unaligned p_vaddr? If that's the case, I think Rich might
>have a valid concern here.

p_memsz==0 PT_LOAD is invalid. ld.bfd -z separate-code should not create
such PT_LOAD. But this is more of implementation convention (many libc
implementation error on this case or mmap will fail), not something
regulated by the specification.
(In LLD, we drop such PT_LOAD:
https://github.com/llvm/llvm-project/blob/main/lld/ELF/Writer.cpp#L163)

The empty .eh_frame is suspicious, though. There may be two problems:

1. Why do you have an empty .eh_frame in an object file
2. Why does ld.bfd create empty .eh_frame in that case (I have tried
   simple examples like  `.section .eh_frame,"a"` and I cannot reproduce
   the empty output .eh_frame)

If you don't share the other files, it is difficult to locate the
problem. 2. deserves a http://sourceware.org/ bug.

>
>Elf file type is EXEC (Executable file)
>Entry point 0x401020
>There are 9 program headers, starting at offset 64
>
>Program Headers:
>  Type           Offset             VirtAddr           PhysAddr
>                 FileSiz            MemSiz              Flags  Align
>  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
>                 0x00000000000001f8 0x00000000000001f8  R      0x8
>  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
>                 0x0000000000000019 0x0000000000000019  R      0x1
>      [Requesting program interpreter: /lib/ld-musl-x86_64.so.1]
>  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
>                 0x0000000000000348 0x0000000000000348  R      0x1000
>  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000
>                 0x0000000000000060 0x0000000000000060  R E    0x1000
>  LOAD           0x0000000000002000 0x0000000000402000 0x0000000000402000
>                 0x0000000000000000 0x0000000000000000  R      0x1000
>  LOAD           0x0000000000002e90 0x0000000000402e90 0x0000000000402e90
>                 0x0000000000000190 0x0000000000000190  RW     0x1000
>  DYNAMIC        0x0000000000002e90 0x0000000000402e90 0x0000000000402e90
>                 0x0000000000000160 0x0000000000000160  RW     0x8
>  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
>                 0x0000000000000000 0x0000000000000000  RWE    0x10
>  GNU_RELRO      0x0000000000002e90 0x0000000000402e90 0x0000000000402e90
>                 0x0000000000000170 0x0000000000000170  R      0x1
>
> Section to Segment mapping:
>  Segment Sections...
>   00
>   01     .interp
>   02     .interp .gnu.hash .dynsym .dynstr .rela.dyn .rela.plt
>   03     .plt .text
>   04     .eh_frame
>   05     .dynamic .got .got.plt
>   06     .dynamic
>   07
>   08     .dynamic .got


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-06  1:39           ` Fangrui Song
@ 2021-03-06  2:04             ` Michael Forney
  2021-03-06  2:09               ` Fangrui Song
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Forney @ 2021-03-06  2:04 UTC (permalink / raw)
  To: musl

On 2021-03-05, Fangrui Song <i@maskray.me> wrote:
> The empty .eh_frame is suspicious, though. There may be two problems:
>
> 1. Why do you have an empty .eh_frame in an object file

There is no .eh_frame in any of the object files involved (neither t.o
or crt*.o), just in the final executable. It seems that GNU ld creates
a .eh_frame section unless you pass --no-ld-generated-unwind-info.

> 2. Why does ld.bfd create empty .eh_frame in that case (I have tried
>    simple examples like  `.section .eh_frame,"a"` and I cannot reproduce
>    the empty output .eh_frame)
>
> If you don't share the other files, it is difficult to locate the
> problem.

Which files are you interested in? The recipe I showed earlier should
be sufficient to reproduce the issue. You can use the standard alpine
linux toolchain (using /usr/lib instead of /lib for the paths to the
crt*.o files). With a musl.cc toolchain, you'll need to pass -z
separate-code to get the empty PT_LOAD segment, but the empty
.eh_frame is there either way.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [musl] ld-musl-* and empty .eh_frame
  2021-03-06  2:04             ` Michael Forney
@ 2021-03-06  2:09               ` Fangrui Song
  0 siblings, 0 replies; 10+ messages in thread
From: Fangrui Song @ 2021-03-06  2:09 UTC (permalink / raw)
  To: musl

On 2021-03-05, Michael Forney wrote:
>On 2021-03-05, Fangrui Song <i@maskray.me> wrote:
>> The empty .eh_frame is suspicious, though. There may be two problems:
>>
>> 1. Why do you have an empty .eh_frame in an object file
>
>There is no .eh_frame in any of the object files involved (neither t.o
>or crt*.o), just in the final executable. It seems that GNU ld creates
>a .eh_frame section unless you pass --no-ld-generated-unwind-info.
>
>> 2. Why does ld.bfd create empty .eh_frame in that case (I have tried
>>    simple examples like  `.section .eh_frame,"a"` and I cannot reproduce
>>    the empty output .eh_frame)
>>
>> If you don't share the other files, it is difficult to locate the
>> problem.
>
>Which files are you interested in? The recipe I showed earlier should
>be sufficient to reproduce the issue. You can use the standard alpine
>linux toolchain (using /usr/lib instead of /lib for the paths to the
>crt*.o files). With a musl.cc toolchain, you'll need to pass -z
>separate-code to get the empty PT_LOAD segment, but the empty
>.eh_frame is there either way.

You can build ld from the upstream binutils-gdb repo.
after configure, run `make -j30 all-ld` and use ld/ld-new.

If you can reproduce, p_memsz==0 PT_LOAD in -z separate-code case deserves a bug.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-03-06  2:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-05  3:18 [musl] ld-musl-* and empty .eh_frame Michael Forney
2021-03-05 15:07 ` Rich Felker
2021-03-05 16:12   ` Rich Felker
2021-03-05 22:53     ` Michael Forney
2021-03-06  1:14       ` Fangrui Song
2021-03-06  1:28         ` Rich Felker
2021-03-06  1:30         ` Michael Forney
2021-03-06  1:39           ` Fangrui Song
2021-03-06  2:04             ` Michael Forney
2021-03-06  2:09               ` Fangrui Song

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).