This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Create output sections in LinkerScript class
ClosedPublic

Authored by evgeny777 on Jul 18 2016, 2:55 AM.

Details

Summary

Creating this patch according to George suggestion here
https://reviews.llvm.org/D19976

This patch moves output section creation from Writer<ELFT> to LinkerScript<ELFT>.
Input section order in linker script is respected and can be different from section order in input files.
All lld unit tests pass successfully without modification

The main goal of this patch is to give a go to https://reviews.llvm.org/D22215
and many other unsupported features (like symbol assignment, PROVIDE, PROVIDE_HIDDEN, e.t.c)

Diff Detail

Event Timeline

evgeny777 updated this revision to Diff 64289.Jul 18 2016, 2:55 AM
evgeny777 retitled this revision from to [ELF] Create output sections in LinkerScript class.
evgeny777 updated this object.
evgeny777 added reviewers: grimar, ruiu.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: ikudrin, llvm-commits.
grimar edited edge metadata.Jul 18 2016, 4:56 AM

Though that patch is different from what I posted, I have no arguments for not to land it for now, until
possible redesign is under discussions. I have just cosmetic сomments about.

ELF/LinkerScript.cpp
199

This method seems to be a almost copy of elf::isDiscarded(). Do you really need it then ?

227

I would move Result below typedef, we usually declare typedefs at first lines of method.
Also it's naming is probably incorrect, I believe we do not use 2 uppercases character in a row for naming things. And I think do not leave a type in name (Up == Unique Ptr right ?)

232

We place dots at the end of comments.

237

I would write as

if (!isDiscarded(S))
  if (globMatch(R.SectionPattern, S->getSectionName())))
241

Ditto about dot.

243

Lets be consistent with code above:

InputSectionBase<ELFT> *S
ELF/LinkerScript.h
27

I think it is not in common in lld code to declare new type in globals.

37

Not relative change.

ELF/Writer.cpp
75

Looks you can leave Factory to be local object, it does not really needs to be member.
You can just give it to createSections/finalizeSections. I have no real preference here though.

evgeny777 added inline comments.Jul 18 2016, 5:24 AM
ELF/LinkerScript.cpp
199

elf::isDiscarded no longer calls LinkerScript::isDiscarded and does not check S->OutSec.

ELF/Writer.cpp
75

It holds name-value section map. See OutputSectionFactory::create()

grimar added inline comments.Jul 18 2016, 5:30 AM
ELF/LinkerScript.cpp
199

I know, but you probably can check that separatelly and keep the common logic.

ruiu added inline comments.Jul 19 2016, 1:49 PM
ELF/LinkerScript.cpp
198

Having two functions with the same name (elf::isDicarded and LinkerScript::isDiscarded) is confusing because from LinkerScript class, the latter hides the former.

Can you move elf::isDiscarded to Writer.cpp and make it a static non-member function? Then the other isDiscarded is not visible from this file, so it is less confusing.

211

This is a helper function for createSections and heavily relies on it. I usually write such function as a lambda for readability -- such as Add in OutputSections.cpp.

228

For consistency, please remove this typedef.

245

Does this work? It adds the same section again if it is mentioned in a linker script.

ELF/LinkerScript.h
27

Yup. We don't usually do this, so it is better to avoid it for consistency.

ELF/Writer.cpp
640–645

Can you make this function return a vector of sections rather than mutating OwningSections? Then, I think you can remove OwningSections member from this class by making it a local variable in run.

evgeny777 added inline comments.Jul 19 2016, 1:55 PM
ELF/LinkerScript.cpp
245

Yes. When input section is added to output section, the OutSec member variable of InputSectionBase<ELFT> class points to output section class instance. It is being checked inside LinkerScript<ELFT>::isDiscarded method:

return !S || !S->Live || S->OutSec || getOutputSection(S) == "/DISCARD/";

So input section can't be added twice

evgeny777 updated this revision to Diff 64683.Jul 20 2016, 7:05 AM

Review updated

ruiu accepted this revision.Jul 20 2016, 7:21 AM
ruiu edited edge metadata.

LGTM with the following changes.

ELF/LinkerScript.cpp
229

Do you need elf:: specifier? If not, please remove.

238

elf::

242

Add a space after if.

244–245

} else { (or, in general, please run clang-format-diff.)

ELF/Writer.cpp
222

OwningSections was named such because Writer owned sections using this variable. It is no longer the case. So please rename something different, say just Sections.

226–229

Why don't you use a regular for-each loop?

for (std::unique_ptr<OutputSectionBase<ELFT>> &S : OwningSections)
  OutputSections.push_back(S.get());
This revision is now accepted and ready to land.Jul 20 2016, 7:21 AM
evgeny777 closed this revision.Jul 21 2016, 1:32 AM