I've added the folks implementing ldscripts to the review list as SHF_LINK_ORDER does have some impact, particularly for ld -r. I also ran into a couple of problems whilst testing against ldscripts. In particular ld -r with a linker script isn't working at all right now. Apologies for abusing this review to communicate, I thought the surrounding context might be useful. I'm happy to restate in llvm-dev or PRs if you'd prefer.
Sections with the SHF_LINK_ORDER flag set have an ordering dependency on the Section identified by the sh_link field. The wording in the ELF specification is not especially clear but the intent behind the only known use case is. SHF_LINK_ORDER is used to build a table of exception table sections in order of ascending address such that it can be binary searched by the exceptions runtime based on the address the exception was thrown.
Note:
The known uses of the SHF_LINK_ORDER flag is limited to ARM and Itanium exception table index sections .ARM.exidx and .IA_64.unwind. As far as I can tell it is not possible with clang and gcc to create arbitrary sections with the SHF_LINK_ORDER flag set, the exception table sections are created by the assembler in response to directives such as .cantunwind.
References:
ELF Specification: http://www.sco.com/developers/gabi/latest/ch4.sheader.html
ARM EHABI: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
Itanium ABI: http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-IA64/LSB-Core-IA64/sections.html
I have used the limited scope of sections that lld will encounter to simplify the implementation. A similar approach is taken by Gold, which doesn't seem to handle SHF_LINK_ORDER generally, instead it makes a special case of .ARM.exidx sections. I've put the limitations in Review questions.
Review questions:
Should SHF_LINK_ORDER support be restricted to Target ARM?
SHF_LINK_ORDER is in the generic ELF specification, but the only known ABIs that use it are ARM and Itanium, both for exception index tables. As the implementation has a performance penalty I've restricted it to the ARM target.
Is it acceptable to reorder the SHF_LINK_ORDER sections post address assignment?
The sorting of the InputSections is currently done after addresses are assigned to OutputSections. This isn't ideal as in the general case reordering InputSections could invalidate the dynamic relocations created by ScanRelocations. It also prevents an permitted size optimization to .ARM.exidx sections that compresses identical adjacent table entries. In practice this can't happen in any ABI conforming image due to the properties of .ARM.exidx (All .ARM.exidx sections must be contiguous, all have 4-byte alignment and a size that is a multiple of 8, so interchanging their order won't affect anything else).
In an ideal world the reordering of SHF_LINK_ORDER sections would be done as soon as the order of Output and Input Sections is known but prior to any function that depends on precise addresses. However there isn't a simple way of getting the section order information out of ldscripts early without side-effecting the image. See ldscript issues.
Is the support for ld -r robust enough?
For relocatable links each OutputSection with a SHF_LINK_ORDER flag can only link to a single OutputSection. The current implementation takes advantage of the naming convention of the ABI for .ARM.exidx sections. Supporting arbitrary names for SHF_LINK_ORDER sections will need a more complex solution based on following shf_link.
Linker Script issues:
ld -r with a linker script isn't working at all right now. The default createSections() calls assignOffsets(), if a script is used with -r then neither assignOffsets or assignAddresses() is called so all the output section headers have size 0. I think a possible fix is to use assignAddresses() with orphan OutputSections given a base address of 0.
Sorting OutputSections and calling LinkerScript::assignAddresses() has side-effects. If assignAddresses() is called before addPredefineSections() and in its normal place after addPredefineSections() then any user-defined section with a name like .shstrtab (in test linkersctipt-sections.s) has an OutputSection created for it and hence gains an index. This sorts it before all the predefined sections when the second sort is performed after addPredefineSections(). More seriously assignOffsets() is called twice on some section types which will alter their size as sh_size will be non-zero from the first call to assignAddresses(). I considered writing some code to unpick the side-effects but instead went for the late resolution of SHF_LINK_ORDER. I think it would be very useful to have a way of incrementally updating the output and input section addresses when using ldscripts. For example consider long branch thunks, to calculate that a thunk is needed we need the address of source and destination, adding a thunk affects the addresses.