diff options
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 40 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 2 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 2 |
4 files changed, 29 insertions, 17 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 1bbdb018633..6cfbc5d4585 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -458,7 +458,7 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { }); log(toString(S) + " is being placed in '" + Name + "'"); if (I == End) { - Factory.addInputSec(S, Name); + Factory.addInputSec(S, Name, nullptr); assert(S->getOutputSection()->SectionIndex == INT_MAX); } else { OutputSection *Sec = cast<OutputSection>(*I); diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 4f929cf8cf9..e3d84d2ea60 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -200,14 +200,25 @@ void elf::reportDiscarded(InputSectionBase *IS) { IS->File->getName() + "'"); } -static OutputSection *addSection(InputSectionBase *IS, StringRef OutsecName, - OutputSection *Sec) { - if (Sec && Sec->Live) { +static OutputSection *createSection(InputSectionBase *IS, StringRef OutsecName) { + OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>"); + Sec->Type = IS->Type; + Sec->Flags = IS->Flags; + Sec->addSection(cast<InputSection>(IS)); + + Script->Opt.Commands.push_back(Sec); + + return Sec; +} + +static void addSection(OutputSection *Sec, InputSectionBase *IS, StringRef OutsecName) { + if (Sec->Live) { if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) error("incompatible section flags for " + Sec->Name + "\n>>> " + toString(IS) + ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Sec->Name + ": 0x" + utohexstr(Sec->Flags)); + if (Sec->Type != IS->Type) { if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(IS->Type)) Sec->Type = SHT_PROGBITS; @@ -218,18 +229,12 @@ static OutputSection *addSection(InputSectionBase *IS, StringRef OutsecName, "\n>>> output section " + Sec->Name + ": " + getELFSectionTypeName(Config->EMachine, Sec->Type)); } - Sec->Flags |= IS->Flags; } else { - if (!Sec) { - Sec = Script->createOutputSection(OutsecName, "<internal>"); - Script->Opt.Commands.push_back(Sec); - } Sec->Type = IS->Type; - Sec->Flags = IS->Flags; } + Sec->Flags |= IS->Flags; Sec->addSection(cast<InputSection>(IS)); - return Sec; } void OutputSectionFactory::addInputSec(InputSectionBase *IS, @@ -242,7 +247,7 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS, // If we have destination output section - use it directly. if (OS) { - addSection(IS, OutsecName, OS); + addSection(OS, IS, OutsecName); return; } @@ -254,7 +259,7 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS, // as-is because adding/removing members or merging them with other groups // change their semantics. if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP)) { - addSection(IS, OutsecName, nullptr); + createSection(IS, OutsecName); return; } @@ -268,13 +273,20 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS, (IS->Type == SHT_REL || IS->Type == SHT_RELA)) { auto *Sec = cast<InputSection>(IS); OutputSection *Out = Sec->getRelocatedSection()->getOutputSection(); - Out->RelocationSection = addSection(IS, OutsecName, Out->RelocationSection); + + if (Out->RelocationSection) + addSection(Out->RelocationSection, IS, OutsecName); + else + Out->RelocationSection = createSection(IS, OutsecName); return; } SectionKey Key = createKey(IS, OutsecName); OutputSection *&Sec = Map[Key]; - Sec = addSection(IS, OutsecName, Sec); + if (Sec) + addSection(Sec, IS, OutsecName); + else + Sec = createSection(IS, OutsecName); } OutputSectionFactory::~OutputSectionFactory() {} diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index dbe6c16dbc9..ef6b98aba24 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -165,7 +165,7 @@ public: ~OutputSectionFactory(); void addInputSec(InputSectionBase *IS, StringRef OutsecName, - OutputSection *OS = nullptr); + OutputSection *OS); private: llvm::SmallDenseMap<SectionKey, OutputSection *> Map; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1d8471092fb..34dfeb70952 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -880,7 +880,7 @@ template <class ELFT> void Writer<ELFT>::createSections() { Script->Opt.Commands.clear(); for (InputSectionBase *IS : InputSections) if (IS) - Factory.addInputSec(IS, getOutputSectionName(IS->Name)); + Factory.addInputSec(IS, getOutputSectionName(IS->Name), nullptr); Script->Opt.Commands.insert(Script->Opt.Commands.end(), Old.begin(), Old.end()); |