This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Store pointer to PT_LOAD instead of pointer to first section (FirstInPtLoad) in OutputSection
ClosedPublic

Authored by grimar on Jul 3 2017, 9:14 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar created this revision.Jul 3 2017, 9:14 AM
ruiu added inline comments.Jul 11 2017, 6:49 PM
ELF/LinkerScript.cpp
794–795 ↗(On Diff #105100)

This change seems fine, but I realized that I do not understand what this function is supposed to do. What is this for?

grimar added inline comments.Jul 12 2017, 5:08 AM
ELF/LinkerScript.cpp
794–795 ↗(On Diff #105100)

Function checks if elf header and program header can be allocated.
If there is no room for them, PT_PHDR should not be emited.

See:
PT_PHDR description:
"Specifies the location and size of the program header table itself, both in the file and in the memory image of the program. This segment type cannot occur more than once in a file. Moreover, it can occur only if the program header table is part of the memory image of the program." (https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html)

Imagine we have script like:
SECTIONS {foo 0 : {*(foo*)} } (took it from no-space.s testcase)

In that case there is no VA space for headers. That means we do not allocate them in PT_LOAD. Output will be:

Program Headers:
Type  Offset   VirtAddr           PhysAddr
LOAD  0x001000 0x0000000000000000 0x0000000000000000
ruiu added inline comments.Jul 12 2017, 3:33 PM
ELF/LinkerScript.cpp
794–795 ↗(On Diff #105100)

There's no rule or something that says a program header must be at beginning of a file, right? If there's no space at beginning of a file for a program header, why don't you put it at end of the file?

grimar added inline comments.Jul 13 2017, 2:41 AM
ELF/LinkerScript.cpp
794–795 ↗(On Diff #105100)

But why would we want to do that ? Neither bfd or gold allocate program headers in this case I think, why should we ?

Spec says about PT_PHDR: "This type, if present, must precede any loadable segment entry." (https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html).
In that case we would need probably to place program headers at the end of last segment and move PT_PHDR before it. Additional complication for no visible reason probably.

Also I think if script is writen in the way when there is no room for headers it may assume them are not allocated.
Script may include asserts of location counter or something that may be broken after this change.

And the last - there is still ELF file header there which must be placed at the begining of the file and we can't move it anyways.

Basing on all above I believe moving of program headers at least does not make sense (or even may be harmfull).

Just in case, this patch does not change any logic, only simplifies the existent code.

grimar updated this revision to Diff 107258.Jul 19 2017, 1:02 AM
  • Rebased.
phosek added a subscriber: phosek.Jul 21 2017, 5:46 PM
phosek added inline comments.
ELF/LinkerScript.cpp
794–795 ↗(On Diff #105100)

We actually ran into this in our kernel: we're using a custom linker script to avoid emitting ELF file or program headers because we don't want them in the kernel image. Since the kernel doesn't start at the beginning of the file, there's always a space so LLD always emits those headers unlike BFD ld or gold.

I have a WIP change that avoids emitting the headers if there's no output section covering them which is the behavior BFD ld and gold use.

grimar updated this revision to Diff 108432.Jul 27 2017, 1:27 AM
  • Rebased.
grimar updated this revision to Diff 112861.Aug 28 2017, 2:15 AM
  • Rebased.
ruiu added inline comments.Aug 28 2017, 10:28 AM
ELF/OutputSections.h
71 ↗(On Diff #112861)

Load is not a good name, no? Phdr is better.

ELF/Writer.cpp
1584–1587 ↗(On Diff #112861)

Is it possible that Cmd->Load exists but Cmd->Load->First is null? If not, simplify this to:

if (!Cmd->Load)
  return alignTo(Off, Cmd->Alignment):
grimar updated this revision to Diff 113039.Aug 29 2017, 1:47 AM
  • Addressed review comments.
ELF/OutputSections.h
71 ↗(On Diff #112861)

Phdr stands for "program header", there are lot of them, isn't it too generic name ?
We want to store pointer to loadable segment section resides in, so may be LoadPhdr or PtLoad
is better ?

ELF/Writer.cpp
1584–1587 ↗(On Diff #112861)

Done.

ruiu added inline comments.Sep 5 2017, 5:55 PM
ELF/LinkerScript.cpp
728 ↗(On Diff #113039)

I'd name this findSection as it finds a given argument from a list. "get" prefix doesn't feel perfectly match to what this function does.

ELF/OutputSections.h
71 ↗(On Diff #112861)

I think I prefer PtLoad over LoadPhdr.

grimar updated this revision to Diff 113974.Sep 6 2017, 2:59 AM
  • Addressed comments.
ELF/LinkerScript.cpp
728 ↗(On Diff #113039)

Did you mean findFirstSection ? (as it finds first section in a given Load)

ELF/OutputSections.h
71 ↗(On Diff #112861)

Renamed to PtLoad.

ruiu accepted this revision.Sep 6 2017, 11:25 AM

LGTM

ELF/LinkerScript.cpp
773 ↗(On Diff #113974)

First is too terse. The member should be renamed FirstSec in a follow-up patch.

This revision is now accepted and ready to land.Sep 6 2017, 11:25 AM
grimar added inline comments.Sep 7 2017, 3:50 AM
ELF/LinkerScript.cpp
773 ↗(On Diff #113974)

Will do, thanks for review !

This revision was automatically updated to reflect the committed changes.