This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Linkerscript: Fix handling of empty sections
AbandonedPublic

Authored by evgeny777 on Sep 5 2016, 5:24 AM.

Details

Reviewers
ruiu
rafael
Summary

On some occasions output section listed in linker script may not be written to output file. This often happens if same linker script
is used to link many applications, some of them may, for example, contain EH frames or TLS sections and some may not.

In such case two problems arise:

  1. All symbols listed in such sections will be added to symbol table incorrectly. Their section index will be invalid.
  2. If some symbols refer address or size of an empty section then application will fail to link, because this section is not listed in OutputSections vector.

The ld and gold linkers use different approaches to address this problem:

  • ld adds empty section symbols to preceding non-empty output section.
  • gold makes those symbols absolute.

This patch uses gold-like way, converting all section-defined symbols to absolute. The address of an empty section is an address which it should have had in case it wasn't
empty.

Diff Detail

Event Timeline

evgeny777 updated this revision to Diff 70319.Sep 5 2016, 5:24 AM
evgeny777 retitled this revision from to [ELF] Linkerscript: Fix handling of empty sections.
evgeny777 updated this object.
evgeny777 added reviewers: ruiu, rafael.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: grimar, ikudrin, llvm-commits.
evgeny777 updated this revision to Diff 70390.Sep 6 2016, 5:21 AM
evgeny777 removed rL LLVM as the repository for this revision.

Symbols defined in empty sections may be mentioned in relocation section, so it's necessary to copy at least GotIndex, before
converting Synthetic to Regular.

ruiu edited edge metadata.Sep 6 2016, 4:07 PM

I'm wondering why we need to remove empty output sections from output. I cannot think of a reason to not leave them as is except small file/virtual address space wastes for the section table slot for the empty section. Do we need to handle it as a special case?

ELF/LinkerScript.cpp
147

While you are here, can you change the function name so that it sounds like a predicate function? I'd suggest satisifiesConstraint but you may come up with a better name. I think "Check" is not a good name because it is not obvious whether it will return true or false on success.

I'm wondering why we need to remove empty output sections from output. I cannot think of a reason to not leave them as is except small file/virtual address space wastes for the section table slot for the empty section. Do we need to handle it as a special case?

Besides wasting some (small) space in ELF image I see two potential issues

a) What type and attributes will you assign for those empty sections? If you flag them with SHF_ALLOC you may end up having extra LOAD segments in ELF image. If you don't, then you'll have to treat them specially in assignAddresses.

b) All "special" sections listed in linker script (like .got, .eh_frame and so on) will have duplicates in ELF image, because they don't consist of input sections. I don't know if this is a real problem, but looks confusing at the very least (IMHO)

evgeny777 updated this revision to Diff 70680.Sep 8 2016, 4:53 AM
evgeny777 edited edge metadata.

DIff updated. Changes:

  • Rebased
  • checkConstraint -> satisfiesConstraint
  • Fixed bug in handling absolute symbols in empty sections
ruiu added inline comments.Sep 8 2016, 3:56 PM
ELF/LinkerScript.cpp
391
DefinedRegular<ELFT> *Regular = ...;
395–396

Is this uintX_t? Please use real types.

404

What does Sec->getVA() do? I think Sec is always empty here, so I'm not sure what this returns.

695

Please use real type instead of auto.

evgeny777 updated this revision to Diff 70796.Sep 9 2016, 2:50 AM

Addressed review comments.
Linker script processor sets VA for empty sections to allow calculating ALIGNOF, SIZEOF and ADDR for them

ruiu added inline comments.Sep 12 2016, 3:05 PM
ELF/LinkerScript.cpp
157–158

Now you can remove this.

404

Could you answer to this question?

evgeny777 added inline comments.Sep 13 2016, 12:51 AM
ELF/LinkerScript.cpp
404

I thin I've already answered it:

Linker script processor sets VA for empty sections to allow calculating ALIGNOF, SIZEOF and ADDR for them

I want the following script to be processed without errors:

. = 0x10000;
.absolutely_empty_section : {}
sym1 = ADDR(.absolutely_empty_section); // Will return 0x10000
sym2 = SIZEOF(.absolutely_empty_section); // Will return 0
sym3 = ALIGNOF(.absolutely_empty_section); // Will return 1

Please also look at the test case

evgeny777 updated this revision to Diff 71128.Sep 13 2016, 2:40 AM

Rabased + addressed review comments

evgeny777 updated this revision to Diff 71829.Sep 19 2016, 8:30 AM

Diff updated. This one uses a different approach: for all empty sections it virtual output section with type SHT_NULL and SHF_EXCLUDE flag and adds it to OutputSections array. It is slightly more complex than previous ones, but after Rafael added section array "rotation" it looks to be the only way possible.

rafael added inline comments.Sep 19 2016, 9:06 AM
ELF/LinkerScript.cpp
311

Sorry for being late in this review.

If you create these empty sections with

  • the same flags as the one before it.
  • alignment of 1

    you should be able to just leave these sections in the output and not worry about breaking any PT_LOAD, no?

That should make the patch simpler as you would not need to convert the symbols.

evgeny777 added inline comments.Sep 19 2016, 9:12 AM
ELF/LinkerScript.cpp
311

you should be able to just leave these sections in the output and not worry about breaking any PT_LOAD, no?

I don't think so. You have special types of sections, like .got, .got.plt, .eh_frame_hdr, which are created after call to createSections(). Also empty section may be the very first one in linker script.