From 4f013bb3b2ea6a6b2df422bc3387662b26935525 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 26 Apr 2017 22:30:15 +0000 Subject: [PATCH] Create an OutputSection for each non-empty OutputSectionCommand. We were already pretty close, the one exception was when a name was reused in another SECTIONS directive: SECTIONS { .text : { *(.text) } .data : { *(.data) } } SECTIONS { .data : { *(other) } } In this case we would create a single .data and magically output "other" while looking at the first OutputSectionCommand. We now create two .data sections. This matches what gold does. If we really want to create a single one, we should change the parser so that the above is parsed as if the user had written SECTIONS { .text : { *(.text) } .data : { *(.data) *(other)} } That is, there should be only one OutputSectionCommand for .data and it would have two InputSectionDescriptions. By itself this patch makes the code a bit more complicated, but is an important step in allowing assignAddresses to operate just on the linker script. llvm-svn: 301484 --- lld/ELF/LinkerScript.cpp | 34 +++++++++++++++++++--------------- lld/ELF/OutputSections.cpp | 12 +++++++++--- lld/ELF/OutputSections.h | 2 ++ lld/test/ELF/linkerscript/sections.s | 3 ++- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 63eb904..74b5aa0 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -407,7 +407,7 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { // Add input sections to an output section. for (InputSectionBase *S : V) - Factory.addInputSec(S, Cmd->Name); + Factory.addInputSec(S, Cmd->Name, Cmd->Sec); } } CurOutSec = nullptr; @@ -465,9 +465,21 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) { // Add sections that didn't match any sections command. void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { - for (InputSectionBase *S : InputSections) - if (S->Live && !S->OutSec) - Factory.addInputSec(S, getOutputSectionName(S->Name)); + for (InputSectionBase *S : InputSections) { + if (!S->Live || S->OutSec) + continue; + StringRef Name = getOutputSectionName(S->Name); + auto I = std::find_if( + Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) { + if (auto *Cmd = dyn_cast(Base)) + return Cmd->Name == Name; + return false; + }); + if (I == Opt.Commands.end()) + Factory.addInputSec(S, Name); + else + Factory.addInputSec(S, Name, cast(*I)->Sec); + } } static bool isTbss(OutputSection *Sec) { @@ -576,14 +588,6 @@ void LinkerScript::process(BaseCommand &Base) { } } -static OutputSection * -findSection(StringRef Name, const std::vector &Sections) { - for (OutputSection *Sec : Sections) - if (Sec->Name == Name) - return Sec; - return nullptr; -} - // This function searches for a memory region to place the given output // section in. If found, a pointer to the appropriate memory region is // returned. Otherwise, a nullptr is returned. @@ -663,7 +667,8 @@ void LinkerScript::removeEmptyCommands() { auto Pos = std::remove_if( Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) { if (auto *Cmd = dyn_cast(Base)) - return !Cmd->Sec; + return std::find(OutputSections->begin(), OutputSections->end(), + Cmd->Sec) == OutputSections->end(); return false; }); Opt.Commands.erase(Pos, Opt.Commands.end()); @@ -687,8 +692,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { auto *Cmd = dyn_cast(Base); if (!Cmd) continue; - if (OutputSection *Sec = findSection(Cmd->Name, *OutputSections)) { - Cmd->Sec = Sec; + if (OutputSection *Sec = Cmd->Sec) { Flags = Sec->Flags; Type = Sec->Type; continue; diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 71fc00a..839f68f 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -395,14 +395,20 @@ static void reportDiscarded(InputSectionBase *IS) { void OutputSectionFactory::addInputSec(InputSectionBase *IS, StringRef OutsecName) { + SectionKey Key = createKey(IS, OutsecName); + OutputSection *&Sec = Map[Key]; + return addInputSec(IS, OutsecName, Sec); +} + +void OutputSectionFactory::addInputSec(InputSectionBase *IS, + StringRef OutsecName, + OutputSection *&Sec) { if (!IS->Live) { reportDiscarded(IS); return; } - SectionKey Key = createKey(IS, OutsecName); uint64_t Flags = getOutFlags(IS); - OutputSection *&Sec = Map[Key]; if (Sec) { if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) error("incompatible section flags for " + Sec->Name + @@ -418,7 +424,7 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS, } Sec->Flags |= Flags; } else { - Sec = make(Key.Name, IS->Type, Flags); + Sec = make(OutsecName, IS->Type, Flags); OutputSections.push_back(Sec); } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index bcda77d..6405fb3 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -141,6 +141,8 @@ public: ~OutputSectionFactory(); void addInputSec(InputSectionBase *IS, StringRef OutsecName); + void addInputSec(InputSectionBase *IS, StringRef OutsecName, + OutputSection *&Sec); private: llvm::SmallDenseMap Map; diff --git a/lld/test/ELF/linkerscript/sections.s b/lld/test/ELF/linkerscript/sections.s index b7d396f..69c6f19 100644 --- a/lld/test/ELF/linkerscript/sections.s +++ b/lld/test/ELF/linkerscript/sections.s @@ -86,7 +86,8 @@ # Idx Name Size # SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA -# SEC-MULTI-NEXT: .data 00000023 {{[0-9a-f]*}} DATA +# SEC-MULTI-NEXT: .data 00000020 {{[0-9a-f]*}} DATA +# SEC-MULTI-NEXT: .data 00000003 {{[0-9a-f]*}} DATA # SEC-MULTI-NEXT: .bss 00000002 {{[0-9a-f]*}} BSS # SEC-MULTI-NEXT: .comment 00000008 {{[0-9a-f]*}} # SEC-MULTI-NEXT: .symtab 00000030 {{[0-9a-f]*}} -- 2.7.4