This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF] Add InputSectionDescriptions for Orphan Sections
AbandonedPublic

Authored by peter.smith on Apr 19 2017, 6:46 AM.

Details

Summary

Orphan input sections are sections that do not match any InputSectionDescription, these are either placed in existing OutputSections if their name matches for example

.text : { *(.text) }

will match all orphans with a prefix of .text. However an orphan that does not match the name of an existing OutputSection will have an OutputSection created. The orphan input sections are added to OutputSections, and are handled by the flush() function when doing address assignment. These orphan sections will be invisible to Thunk creation and the ordering of .ARM.exidx sections as they won't appear on any InputSection description.

This change fabricates InputSectionDescriptions to cover the inserted orphan sections. I've checked that this matches the behavior of GNU ld when there is a symbol definition at the end of an existing InputSectionDescription. For example:

.text : { *(.text) SYM = .; }

The orphans are added after SYM is defined.

It will now be possible for createThunks to insert thunks into orphan InputSectionDescriptions and for .ARM.exidx section sorting to work with linker scripts that have orphan Sections. For example the InputSectionDescription:

.ARM.exidx : { *(.ARM.exidx) }

Will only match sections with a name of .ARM.exidx, sections such as .ARM.exidx.text.foo will not match the InputSectionDescription, but will match the OutputSection as an orphan.

Note that the .ARM.exidx ordering code in OutputSections currently works on OutputSections::Sections, so it is likely to be wrong when there is a linker script. I've put a temporary FIXME in that makes the script ordering work. I have a full fix that rewrites the .ARM.exidx ordering code that I'll post in a separate review.

Diff Detail

Event Timeline

peter.smith created this revision.Apr 19 2017, 6:46 AM
emaste added a subscriber: emaste.Apr 19 2017, 9:52 AM
ruiu edited edge metadata.Apr 24 2017, 6:23 PM

What this patch does seems logically correct, but I'm not sure if we still want to keep placeOrphanSections as a separate stage as addOrphanSections. If you update Opt.Commands in addOrphanSections, you don't need them to be separated, no?

The main difficulty in creating and adding the Orphan OutputSectionCommand in addOrphanSections() is that we don't have a good idea of where in the order of OutputSectionCommands to insert them. The placeOrphanSections() is intentionally run immediately after sortSections() has been called so that it can insert the OutputSectionCommands in the right place. There is a comment in Writer.c in sortSections() that says:

// The way we define an order then is:
// *  First put script sections at the start and sort the script and
//    non-script sections independently.
// *  Move each non-script section to its preferred position. We try
//    to put each section in the last position where it it can share
//    a PT_LOAD.

It may be possible to create the Orphan OutputSectionCommands early and have the comparison routine work out the ordering, although there is a comment in the same block as the one above that claims that coming up with a strict weak ordering to get the desired result is not easy.

I did consider creating the InputSectionDescription commands for pre-existing OutputSections in placeOrphanSections but it seemed easier to reuse the existing lookup of OutputSectionCommand in addOrphanSections().

peter.smith abandoned this revision.Jun 22 2017, 8:13 AM

This is no longer required, it was implemented by a series of changes by Rafael starting with I think r303384