summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp36
-rw-r--r--lld/ELF/OutputSections.cpp19
-rw-r--r--lld/ELF/OutputSections.h2
-rw-r--r--lld/ELF/Writer.cpp5
4 files changed, 30 insertions, 32 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index e82ee3c7879..69a35be858c 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -416,6 +416,7 @@ void LinkerScript::processSectionCommands() {
// Any input section assigned to it is discarded.
if (Sec->Name == "/DISCARD/") {
discard(V);
+ Sec->SectionCommands.clear();
continue;
}
@@ -771,6 +772,25 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
}
}
+static bool isDiscardable(OutputSection &Sec) {
+ // We do not remove empty sections that are explicitly
+ // assigned to any segment.
+ if (!Sec.Phdrs.empty())
+ return false;
+
+ // We do not want to remove sections that have custom address or align
+ // expressions set even if them are empty. We keep them because we
+ // want to be sure that any expressions can be evaluated and report
+ // an error otherwise.
+ if (Sec.AddrExpr || Sec.AlignExpr || Sec.LMAExpr)
+ return false;
+
+ for (BaseCommand *Base : Sec.SectionCommands)
+ if (!isa<InputSectionDescription>(*Base))
+ return false;
+ return getInputSections(&Sec).empty();
+}
+
void LinkerScript::adjustSectionsBeforeSorting() {
// If the output section contains only symbol assignments, create a
// corresponding output section. The issue is what to do with linker script
@@ -798,15 +818,19 @@ void LinkerScript::adjustSectionsBeforeSorting() {
auto *Sec = dyn_cast<OutputSection>(Cmd);
if (!Sec)
continue;
- if (Sec->Live) {
- Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR);
- continue;
- }
- if (!Sec->isAllSectionDescription())
- Sec->Flags = Flags;
+ // A live output section means that some input section was added to it. It
+ // might have been removed (gc, or empty synthetic section), but we at least
+ // know the flags.
+ if (Sec->Live)
+ Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR);
else
+ Sec->Flags = Flags;
+
+ if (isDiscardable(*Sec)) {
+ Sec->Live = false;
Cmd = nullptr;
+ }
}
// It is common practice to use very generic linker scripts. So for any
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 9b8ea2bb461..9d5ebe5fea7 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -78,25 +78,6 @@ OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
Live = false;
}
-bool OutputSection::isAllSectionDescription() const {
- // We do not remove empty sections that are explicitly
- // assigned to any segment.
- if (!Phdrs.empty())
- return false;
-
- // We do not want to remove sections that have custom address or align
- // expressions set even if them are empty. We keep them because we
- // want to be sure that any expressions can be evaluated and report
- // an error otherwise.
- if (AddrExpr || AlignExpr || LMAExpr)
- return false;
-
- for (BaseCommand *Base : SectionCommands)
- if (!isa<InputSectionDescription>(*Base))
- return false;
- return true;
-}
-
// We allow sections of types listed below to merged into a
// single progbits section. This is typically done by linker
// scripts. Merging nobits and progbits will force disk space
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 597fd065a21..35a873488f2 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -42,8 +42,6 @@ class OutputSection final : public BaseCommand, public SectionBase {
public:
OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
- bool isAllSectionDescription() const;
-
static bool classof(const SectionBase *S) {
return S->kind() == SectionBase::Output;
}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a1c534c912c..ade8ebaf3c0 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1382,11 +1382,6 @@ static void removeUnusedSyntheticSections() {
if (auto *ISD = dyn_cast<InputSectionDescription>(B))
llvm::erase_if(ISD->Sections,
[=](InputSection *IS) { return IS == SS; });
-
- // If there are no other alive sections or commands left in the output
- // section description, we remove it from the output.
- if (getInputSections(OS).empty() && OS->isAllSectionDescription())
- OS->Live = false;
}
}
OpenPOWER on IntegriCloud