From 4dbff20c91aa5cf5bed789b229222aa9d2eecf6b Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 16 Sep 2015 21:40:47 +0000 Subject: COFF: Fix bug that not all symbols were written to symtab if /opt:noref. Only live symbols are written to the symbol table. Because isLive() returned false if dead-stripping was disabled entirely, only non-COMDAT sections were written to the symbol table. This patch fixes the issue. llvm-svn: 247856 --- lld/COFF/Writer.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'lld/COFF/Writer.cpp') diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 8cc48b57adf..b133d1c5701 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -251,6 +251,13 @@ void Writer::markLive() { // as we push, so sections never appear twice in the list. SmallVector Worklist; + // COMDAT section chunks are dead by default. Add non-COMDAT chunks. + for (Chunk *C : Symtab->getChunks()) + if (auto *SC = dyn_cast(C)) + if (SC->isLive()) + Worklist.push_back(SC); + + // Add GC root chunks. for (Undefined *U : Config->GCRoot) { auto *D = dyn_cast(U->repl()); if (!D || D->isLive()) @@ -258,13 +265,7 @@ void Writer::markLive() { D->markLive(); Worklist.push_back(D->getChunk()); } - for (Chunk *C : Symtab->getChunks()) { - auto *SC = dyn_cast(C); - if (!SC || SC->isCOMDAT() || SC->isLive()) - continue; - SC->markLive(); - Worklist.push_back(SC); - } + while (!Worklist.empty()) { SectionChunk *SC = Worklist.pop_back_val(); assert(SC->isLive() && "We mark as live when pushing onto the worklist!"); @@ -305,13 +306,11 @@ void Writer::createSections() { // First, bin chunks by name. std::map> Map; for (Chunk *C : Symtab->getChunks()) { - if (Config->DoGC) { - auto *SC = dyn_cast(C); - if (SC && !SC->isLive()) { - if (Config->Verbose) - SC->printDiscardedMessage(); - continue; - } + auto *SC = dyn_cast(C); + if (SC && !SC->isLive()) { + if (Config->Verbose) + SC->printDiscardedMessage(); + continue; } Map[C->getSectionName()].push_back(C); } -- cgit v1.2.3