This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF] Fix Thunks with placement restrictions and linker scripts

Authored by peter.smith on Apr 4 2017, 3:48 AM.



Apologies, now with Summary.

This change is a generalization of D30641 Fix Ordering of Mips LA25 Thunks when Linker Script used so that it works for range extension thunks as well.

This is the messiest change needed to support range extension thunks.

The first part makes it possible to assign addresses multiple times when using a linker script. All this requires us to do is to reset any state accumulated by the last call. The second part deals with the synchronization of OutputSection and LinkerScript data structures.

When a linker script SECTIONS command describes an OutputSection the code that writes out the InputSections contained in the OutputSection use OutputSection.Sections. However the address assignment for linker scripts uses the alternative representation of one or more InputSectionDescription commands to assign the addresses. This is necessary as linker scripts can do things like .text { *(.text.*) . = . +0x100 ; *(.text) } which can't be represented using OutputSection.Sections.

When we come to insert Thunks, the InputSectionDescription(s) and OutputSection.Sections have been synchronized so that the order of sections in InputSectionDescription(s) matches the OutputSection.Sections. If we add any Thunks we must add to both InputSectionDescription(s) and to OutputSections.Sections.

On the assumption that we still have the two representations we have a choice:
1.) Insert thunks into OutputSection.Sections and derive changes for InputSectionDescriptions(s) from it.
2.) Insert thunks into InputSectionDescription(s) and derive changes for OutputSection.Sections from it.

I've chosen the first option as it keeps the code to synchronize the OutputSections in LinkerScripts and doesn't need to use any knowledge of Thunks, the downside is that the synchronization is more complicated. The second option requires us to extract the InputSectionDescriptions from the LinkerScript, make a special case for OutputSections without a Linker Script, makes the efficient allocation of range thunks more complicated, but makes the synchronization simple.

The approach to the synchronization relies on the InputSectionDescription and OutputSection being synchronized prior to Thunks being created. As inserting Thunks never alters the order of non-Thunk sections we can recover the original mapping. The only difficult decision we have to make is if there is a ThunkSection between two InputSectionDescriptions, we must be careful to assign it to the InputSectionDescription that can support our desired OutSecOff.

I don't particularly like that we have to synchronize the representations, but I'm not sure if there is a much better way either. If the linker was driven entirely by InputSectionDescriptions, even without a linker script then no synchronization would be needed, this would be quite a substantial change though.

Diff Detail

Event Timeline

peter.smith created this revision.Apr 4 2017, 3:48 AM
peter.smith updated this revision to Diff 94190.Apr 5 2017, 4:17 AM

Rebasing patch on top of recent linkerscript refactoring.

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

I'm abandoning the range thunks implementation that inserts into OutputSections in favour of an implementation that inserts into InputSectionDescription.