This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF] User linkerscript InputSectionDescription for .ARM.exidx dependency order

Authored by peter.smith on Apr 19 2017, 9:43 AM.



InputSections with a SHF_LINK_ORDER dependency must be ordered in the same order as the InputSections that they have a dependency on. This ordering is done late in the link when the OutputSection containing a SHF_LINK_ORDER dependency is finalized. The reordering needs to handle these cases:

  • No linker script SECTIONS command describing OutputSection
  • Linker script that fully describes OutputSection with no orphans
  • Linker script that partially describes OutputSection with orphans

At present we sort the OutputSection::Sections vector which will be fully or partially ignored if a linker script fully or partially describes the .ARM.exidx OutputSection. This is analogous to the insertion of thunks directly into OutputSection::Sections.

Building upon D32223:

This change:

  • introduces a function inputSectionRanges() to obtain just the InputSectionDescriptions from an OutputSection.
  • Inserts the .ARM.exidx sentinel into an InputSectionDescription
  • Moves the fabricateInputSectionDescriptions before the call to OutputSection::finalize(), we need to do at least one call to Script->assignAddresses() to assign each InputSection its OutSecOff.
  • Added a function to clear the state that accumulates with each call to assignAddresses() so that we can call it more than once.
  • Consolidates the InputSectionDescriptions for .ARM.exidx into one as we need to sort the entire table. We can get multiple InputSectionDescriptions when something like
.ARM.exidx { *(.ARM.exidx) }

which will get orphans of the form .ARM.exidx.suffix.

  • Sort the InputSectionDescription using the same criteria as before.
  • Adds a test case that would previously fail as the later call to Script->assignAddresses() would ignore the sorting done to OutputSection::Sections().

Diff Detail

Event Timeline

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

I'm not totally sure if this is towards a right direction. We used to be sorting .ARM.exidx in a direct way -- we had code to directly look at .ARM.exidx input sections and sort them, but now we are creating intermediate data that is to be interpreted by the linker script processor. This seems more intricate way to do a fairly straightforward thing, which is just to sort input sections. Do you think there's a more direct way of doing it?

I can think of some options, although each has their own trade-off. Apologies for the length of the answer.

To restate what I think the requirements are:

  1. All of the .ARM.exidx* sections need to be placed contiguously in one "table".
  2. The order of the .ARM.exidx* sections needs to match the order of the code sections that the .ARM.exidx sections have a link order dependency to.

For non-linker script links, or linker script links where .ARM.exidx sections are all orphans we use the naming rules to ensure that there is a single .ARM.exidx OutputSection containing all the .ARM.exidx* InputSections, that takes care of requirement 1.
For linker script links where .ARM.exidx sections are not orphans we are somewhat reliant on the user to get the pattern right to satisfy 1.) The best pattern is .ARM.exidx : { *(.ARM.exidx*) }, but .ARM.exidx : { *(.ARM.exidx) } without the trailing * will work as the sections will be orphans.

At the moment if all .ARM.exidx sections are orphans or there is no linker script we can sort the OutputSections::Sections directly to satisfy 2.)
If any of the .ARM.exidx sections are covered by a linker script, our current Output::Sections sort will be ignored by the Script->assignAddresses() and we are likely to not satisfy 2.)

With this in mind, I think the options are:
1.) Do not include .ARM.exidx sections in any InputSectionDescription::Section, they will always be added as orphans, this will either mean some special case code in LinkerScripts to not add the sections, or some code to go in and remove them from the InputSectionDescriptions prior to final address assignment. This would allow the existing direct sorting approach to work as the script's handling of orphans would just work.
2.) Do what I originally proposed for RangeThunks and synchronize/rewrite the output of sorting OutputSection::Sections with the InputSectionDescriptions. I think that this is just a different way of implementing option 1.) but putting the special case code after, rather than before.
3.) The option above, which is to work entirely in InputSectionDescription::Section. This doesn't require quite so much special case code in LinkerScripts for .ARM.exidx, but it does mean that the sorting code has to cope with linker scripts that have multiple InputSectionDescriptions due to orphans or just users writing something like .ARM.exidx : { *(.ARM.exidx) *(*) }.

I think that option 1 could end up being simpler overall. I'm going to be at a conference for the rest of the week, but if I can't get something finished today I'll do so early next week.

I've created D32485 for an alternative implementation that just makes the link order sections orphans. I think that this ends up being a bit simpler overall.

peter.smith abandoned this revision.May 16 2017, 7:30 AM

Abandoning this revision in favour of D33239.