Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -258,6 +258,8 @@ std::vector *OutputSections; void fabricateDefaultCommands(); + std::vector *> + inputSectionRanges(StringRef S); void addOrphanSections(OutputSectionFactory &Factory); void removeEmptyCommands(); void adjustSectionsBeforeSorting(); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -510,6 +510,28 @@ } } +// For an OutputSection S, return the InputSectionDescriptions that are +// associated with S. The intention is that callers can iterate over +// InputSectionDescription::Sections and insert sections such as Thunks. +std::vector *> +LinkerScript::inputSectionRanges(StringRef S) { + std::vector *> Ranges; + auto OutCmdPos = std::find_if( + Opt.Commands.begin(), Opt.Commands.end(), [=](BaseCommand *Cmd) { + if (auto *OSCmd = dyn_cast(Cmd)) + return (OSCmd->Name == S); + return false; + }); + if (OutCmdPos == Opt.Commands.end()) + return Ranges; + auto *OutCmd = cast(*OutCmdPos); + for (auto *BaseCmd : OutCmd->Commands) { + if (auto *ISD = dyn_cast(BaseCmd)) + Ranges.push_back(&ISD->Sections); + } + return Ranges; +} + uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) { bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS; uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1195,8 +1195,6 @@ if (ErrorCount) return; - // So far we have added sections from input object files. - // This function adds linker-created Out::* sections. addPredefinedSections(); removeUnusedSyntheticSections(OutputSections); @@ -1264,8 +1262,17 @@ // ARM ABI requires .ARM.exidx to be terminated by some piece of data. // We have the terminater synthetic section class. Add that at the end. auto *OS = dyn_cast_or_null(findSection(".ARM.exidx")); - if (OS && !OS->Sections.empty() && !Config->Relocatable) - OS->addSection(make()); + if (!OS || OS->Sections.empty() || Config->Relocatable) + return; + + auto *Sentinel = make(); + OS->addSection(Sentinel); + // If there are linker script commands existing at this point then add the + // sentinel to these too. + std::vector *> Ranges = + Script->inputSectionRanges(OS->Name); + if (!Ranges.empty()) + Ranges.back()->push_back(Sentinel); } // The linker is expected to define SECNAME_start and SECNAME_end