summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/InputSection.cpp3
-rw-r--r--lld/ELF/InputSection.h5
-rw-r--r--lld/ELF/MarkLive.cpp11
3 files changed, 12 insertions, 7 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 76795a24ac6..ff91463a8fe 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -53,7 +53,8 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
const Elf_Shdr *Hdr, StringRef Name,
Kind SectionKind)
: InputSectionData(SectionKind, Name, getSectionContents(File, Hdr),
- isCompressed<ELFT>(Hdr, Name), !Config->GcSections),
+ isCompressed<ELFT>(Hdr, Name),
+ !Config->GcSections || !(Hdr->sh_flags & SHF_ALLOC)),
Header(Hdr), File(File), Repl(this) {
// The ELF spec states that a value of 0 means the section has
// no alignment constraits.
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 3fd89bd8ec8..fcac34c1b0a 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -167,7 +167,10 @@ public:
void splitIntoPieces();
// Mark the piece at a given offset live. Used by GC.
- void markLiveAt(uintX_t Offset) { LiveOffsets.insert(Offset); }
+ void markLiveAt(uintX_t Offset) {
+ assert(this->getSectionHdr()->sh_flags & llvm::ELF::SHF_ALLOC);
+ LiveOffsets.insert(Offset);
+ }
// Translate an offset in the input section to an offset
// in the output section.
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 847575711d2..452fc29ab91 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -201,6 +201,10 @@ template <class ELFT> void elf::markLive() {
if (!R.Sec || R.Sec == &InputSection<ELFT>::Discarded)
return;
+ // We don't gc non alloc sections.
+ if (!(R.Sec->getSectionHdr()->sh_flags & SHF_ALLOC))
+ return;
+
// Usually, a whole section is marked as live or dead, but in mergeable
// (splittable) sections, each piece of data has independent liveness bit.
// So we explicitly tell it which offset is in use.
@@ -210,12 +214,9 @@ template <class ELFT> void elf::markLive() {
if (R.Sec->Live)
return;
R.Sec->Live = true;
- // Add input section to the queue. We don't want to consider relocations
- // from non-allocatable input sections, because we can bring those
- // allocatable sections to living which otherwise would be dead.
+ // Add input section to the queue.
if (InputSection<ELFT> *S = dyn_cast<InputSection<ELFT>>(R.Sec))
- if (S->getSectionHdr()->sh_flags & SHF_ALLOC)
- Q.push_back(S);
+ Q.push_back(S);
};
auto MarkSymbol = [&](const SymbolBody *Sym) {
OpenPOWER on IntegriCloud