Cary Coutant ccoutant@gmail.com
Tue Oct 2 21:06:00 GMT 2018

> 1. Linker kernel passes AT_PHDR to main and assumes that AT_PHDR
> is in a PT_LOAD segment.


One could argue that this is the real (and only) problem. If it's
going to pass a pointer to the program headers, the kernel should make
sure that the headers are mapped, whether or not they're part of a
PT_LOAD segment.

Even with no-separate-code, or with a read-only segment before the
text, the inclusion of the program headers in the first PT_LOAD
segment is merely a happy accident -- it's a side effect of way the
linker rounds segment boundaries down and up to page boundaries, and
depends entirely on the property that the first PT_LOAD segment falls
within the first page of the executable file. If, for some reason, the
linker were to place additional non-loadable stuff between the headers
and the text (e.g., symbol tables, section tables), this could fail.
In fact, if the program headers themselves happen to be so large as to
spill over onto the second page of the file, the first PT_LOAD segment
would not necessarily include the first page of the file.

Now, I understand that fixing the Linux kernel to map the headers even
if they're not part of a PT_LOAD segment isn't a practical
alternative. That leads to...

> 2. gABI doesn't require phdrs in a PT_LOAD segment.

It doesn't belong in the gABI, as the mechanics of making the program
header information available to the dynamic loader and the running
program are processor- and OS-specific.

Since this is a Linux-specific issue, not an architecture-specific
one, we really should put this in an osABI document rather than a
psABI document. I suppose the LSB serves as such. Or maybe the gnu ABI

> 3. Ld won't create a PT_LOAD segment just to hold phdrs.

You seem to be breezing right past the idea of doing exactly this.
Why? The scripting language already allows you to declare which
segment should include FILEHDR and PHDRS. For -z separate-code, why
not use a default linker script with something like the following?

       headers PT_PHDR PHDRS ;
       interp PT_INTERP ;
       header_seg PT_LOAD FILEHDR PHDRS ;
       text PT_LOAD ;
       data PT_LOAD ;
       dynamic PT_DYNAMIC ;

> 4. With -z separate-code, linker won't put any non-code in a PF_X PT_LOAD
> segment.
> When there are only PF_X PT_LOAD segments, phdrs isn't in any PT_LOAD
> segment.
> You are looking for a solution to create a PT_LOAD segment just to hold phdrs.
> I have investigated it.  It is very intrusive.  My solution, which you
> called a hack,
> is to add a read-only SHF_ALLOC section so that a PT_LOAD segment will
> be created by ld to hold phdrs when there is only PF_X PT_LOAD segments
> otherwise.

How is it intrusive? If the above linker script doesn't do the job,
isn't that a bug anyway?

And, really, there's no denying that adding an otherwise-unnecessary
note section -- just to get us back into the realm of "it works by
happy accident" -- is a pure hack.


More information about the Binutils mailing list