summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp2
-rw-r--r--lld/ELF/OutputSections.cpp40
-rw-r--r--lld/ELF/OutputSections.h2
-rw-r--r--lld/ELF/Writer.cpp2
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());
OpenPOWER on IntegriCloud