This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Support PHDRS command
AbandonedPublic

Authored by denis-protivensky on Dec 3 2015, 7:35 AM.

Details

Reviewers
ruiu
rafael
Summary
  • match sections to one or more headers
  • use NONE header to discard layouting of specific section
  • support all available header types (except custom numeric values)
  • TLS section layout doesn't work yet
  • test cases are provided

Diff Detail

Event Timeline

denis-protivensky retitled this revision from to [ELF] Support PHDRS command.
denis-protivensky updated this object.
denis-protivensky added reviewers: ruiu, rafael.
denis-protivensky added a project: lld.
denis-protivensky added a subscriber: llvm-commits.
grimar added a subscriber: grimar.Dec 3 2015, 9:48 AM
ruiu edited edge metadata.Dec 3 2015, 10:45 AM

First round of review.

ELF/LinkerScript.cpp
295–298
StringRef Name = next();
uint32_t Type = readPhdrType();
Config->Phdrs.emplace_back({Name, Type});
328

It's better to be a bit more specific, say, read zero or more tokens in the form of :phdr.

329

for (;;) for consistency.

ELF/Writer.cpp
1157

This function is already too long and need to be refactored. Please at least factor this new code out from this function.

emaste added a subscriber: emaste.Dec 3 2015, 2:34 PM
denis-protivensky edited edge metadata.
denis-protivensky marked 4 inline comments as done.

Updated:

  • style fixes in linker script's PHDRS parsing
  • move custom header processing out to a separate method
ruiu added inline comments.Dec 4 2015, 12:30 PM
ELF/Writer.cpp
1038

This function needs a function comment to describe what it is intended to do.

1042

This for loop is probably too long. Isn't there any way to split?

denis-protivensky marked 2 inline comments as done.

Updated:

  • Add method comment
  • Simplify custom header layout loop
  • Check if no sections assigned to custom headers
  • Improve NONE header handling
  • Style fixes in the header layout loop
ELF/Writer.cpp
1042

Done, thanks. This also allowed me to add one more check with test case when no sections assigned to PHDRS.

ruiu added inline comments.Dec 7 2015, 11:18 AM
ELF/Writer.cpp
1061

I wanted to split this into multiple functions -- this function is 90 lines long which feels too long to me.

denis-protivensky marked an inline comment as done.

Updated:

  • move out some functionality to couple of methods
  • improve NONE header handling (it now can be specified with other headers and just ignored)
ruiu added a comment.Dec 15 2015, 2:11 PM

I'm sorry that this code review was slipped from my inbox.

ELF/Writer.cpp
44

Please use std::vector if there's no strong reason to use SmallVector.

105–106

These fields need a brief comment that they are for the linker script's phdr command.

1038–1055

Please add a function comment.

1042

Instead of const std::vector<X> &, you want to use ArrayRef<X>.

1060–1076

This also needs a function comment.

1078–1091

This needs a comment too. They are all non-trivial, so they need some descriptions to help reader understand what they are supposed to do.

denis-protivensky marked 6 inline comments as done.

Updated:

  • Use std::vector instead of SmallVector
  • Add comments to methods
  • Rename fillPhdrs -> fillUnusedPhdrs
ELF/Writer.cpp
1042

I can't do that because lookup returns temporary object, and I bind it to const reference to prolong its lifetime to the end of the scope. ArrayRef constructs without copying the vector, so it'll be destroyed before used.

ruiu added inline comments.Dec 16 2015, 12:45 PM
ELF/Writer.cpp
58

Since IndicesVector is now just a std::vector, I'd write std::vector<size_t> instead of IndicesVector.

107

Ditto

1068

Please do not use auto here as the actual type is not obvious in this local context.

1072–1073

PhdrInds.insert(PhdrIns.end(), std::begin(It->second), std::end(It->second)) is more common?

1093–1104

Can you please write more details about how you process PHDR command for those who happens to come to this file and read this code (not for me who is reading only the delta), so that they can get the whole picture what you are doing with this function (and the helper functions you added above) without reading all the code?

denis-protivensky marked 4 inline comments as done.

Updated:

  • Remove IndicesVector typedef
  • Replace std::copy with insert into vector
  • Add more comments to functions
ELF/Writer.cpp
1068

I thought we agreed to use auto for cases when returning iterators from methods like find and similar, no?

Rebased on top of actual sources.

grimar added inline comments.Jan 18 2016, 7:07 AM
ELF/Writer.cpp
1176

Wouldn`t it be better to write something like:

if (hasCustomPhdrs()) {
   layoutCustomPhdrs(VA, FileOff);
   return;
}

And just copy a piece of left logic from below to layoutCustomPhdrs() or even to separate it to another method ?

Also in currect variant bracket is missed:

if (hasCustomPhdrs()) {
1217

Change is not relative to this patch (fix of formatting).

1469

There should be brackets I think:

for (const std::pair<StringRef, OutputSectionDescription> &OutSec :
       Config->OutputSections) {
...
ELF/Writer.cpp
1176

No, it's not better, because there already were cases when the common logic below was extended. This would have caused logical issue in the case you propose.

Concerning the braces - I don't remember us putting them for one-line operator blocks.

1217

It's related, because you don't see that the whole code moved by one tab left (by default, ignore space mode is on). So this is the result of clang-formatting the whole shifted piece.

1469

No, I was told to remove these earlier. We don't use braces for blocks that constitute of one operator.

grimar added inline comments.Jan 18 2016, 7:32 AM
ELF/Writer.cpp
1176

(About braces):

I found multiple usings for one-line blocks:
std::string elf2::searchLibrary()
void LinkerScript::run()
void LinkerScript::addFile(StringRef S)
And no using in the way you do. I think we dont use them only if there is no else branch. And always do if it is exist.

1217

Yep, I know its moved, I just supposed correct way would be to not format that part here (to format it in separate patch).

1469

Hmm that wierd for me then :) Because quick search shows that sometimes we do:

Writer<ELFT>::copyLocalSymbols();
void Writer<ELFT>::createSections();

Concerning formatting - let's wait for another reviewer's opinion then.

ruiu added a comment.Jan 19 2016, 10:32 AM

I'm sorry for the delay. I was thinking if this is a right design. Will send code review comments soon.

ruiu added a comment.Jan 19 2016, 8:33 PM

I don't like the current code to create a program header because it's not easy to read, and this is yet another piece of code that also creates a program header. This also feels a bit too complicated. I think one reason why phdr creation is hard to read is because the functions doing that are members of Writer, and they mutate Writer's fields.

They also do too much stuff once. They are creating program header while assigning addresses to sections.

Abstractly, in order to support PHDRS command, we want to have a class or a function that create a list of program header fields, and associate OutputSections to zero or more program header field. Can you model that way?

denis-protivensky abandoned this revision.Jan 22 2016, 1:42 AM

I'll think how to rework this.