This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF] Make createThunks() use InputSectionDescriptions

Authored by peter.smith on May 3 2017, 5:59 AM.



Some Thunks such as Mips LA25 Thunks need to be added at a specific address, when the OutputSection is covered by a SECTIONS command the script assigns the addresses using the InputSectionDescription. This will take precedence over the OutputSections::Sections. By inserting into InputSectionDescription the Script->assignAddresses() will correctly take into account of the placement of inserted thunks.

This change is a step towards range extension Thunks. We will need to iteratively add Thunks, recalculate addresses, add more Thunks until no more Thunks are added. All the address calculation is now driven by Script->assignAddresses() which works from InputSectionDescriptions::Sections so at the end of each iteration we'll need to have the Thunks inserted into InputSectionDescriptions::Sections.

The translation from using OutputSection::Sections() to InputSectionDescriptions() is fairly mechanical, instead of tracking the Thunks inserted per OutputSection we track the Thunks inserted per InputSectionDescription::Sections.

There is some extra complication in mergeThunks() as it is not sufficient to just add the ThunkSections to the end of OutputSection::Sections. The call to Script->synchronize() before the final address allocation will prefer the order of OutputSection::Sections over InputSectionDescriptions::Sections. To solve this we copy the InputSectionDescriptions with Thunks inserted back into OutputSections. This will only need to be done once after createThunks() has finished.

There are some design alternatives that could avoid the synchronization to OutputSections::Sections
1.) Don't convert createThunks() to use InputSectionDescriptions, instead we will call Script->synchronize() after we have added the Thunks. This was how the original range thunk submission D31656 worked. If the intention is to move away from OutputSection::Sections then this is not the right option.
2.) Only call Script->synchronize() on the OutputSections that need synchronizing, this shouldn't involve any OutputSections that contain Thunks. This could work although it could be fragile.
3.) Move the call to createThunks() after the call to Sec->finalize<ELFT>(), and move Script->synchronize() before createThunks(). I'm not keen on doing this as it implies that Sec->finalize<ELFT>() is not final.
4.) Instead of calling Script->finalize(), reorder the SHF_LINK_ORDER sections using InputSectionDescription so that Script->finalize() is not necessary. See D32233

Diff Detail

Event Timeline

peter.smith created this revision.May 3 2017, 5:59 AM

Updating diff to account for the detemplating of ThunkCreator and the proposed change in D33239 to move SHF_LINK_ORDER processing earlier in the link.
The key differences are:

  • When taken together with the proposed change in D33239 synchronize() is no longer needed
  • I've separated allocateHeaders() which only needs to, and I think can only, run once from assignAddresses() which needs to run many times for Thunks
peter.smith abandoned this revision.Jun 22 2017, 8:04 AM

This is no longer required it was implemented in D33835