1 //===- MarkLive.cpp -------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "COFFLinkerContext.h" 10 #include "Chunks.h" 11 #include "Symbols.h" 12 #include "lld/Common/Timer.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include <vector> 15 16 namespace lld::coff { 17 18 // Set live bit on for each reachable chunk. Unmarked (unreachable) 19 // COMDAT chunks will be ignored by Writer, so they will be excluded 20 // from the final output. 21 void markLive(COFFLinkerContext &ctx) { 22 ScopedTimer t(ctx.gcTimer); 23 24 // We build up a worklist of sections which have been marked as live. We only 25 // push into the worklist when we discover an unmarked section, and we mark 26 // as we push, so sections never appear twice in the list. 27 SmallVector<SectionChunk *, 256> worklist; 28 29 // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not 30 // traverse DWARF sections. They are live, but they should not keep other 31 // sections alive. 32 for (Chunk *c : ctx.symtab.getChunks()) 33 if (auto *sc = dyn_cast<SectionChunk>(c)) 34 if (sc->live && !sc->isDWARF()) 35 worklist.push_back(sc); 36 37 auto enqueue = [&](SectionChunk *c) { 38 if (c->live) 39 return; 40 c->live = true; 41 worklist.push_back(c); 42 }; 43 44 auto addSym = [&](Symbol *b) { 45 if (auto *sym = dyn_cast<DefinedRegular>(b)) 46 enqueue(sym->getChunk()); 47 else if (auto *sym = dyn_cast<DefinedImportData>(b)) 48 sym->file->live = true; 49 else if (auto *sym = dyn_cast<DefinedImportThunk>(b)) 50 sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true; 51 }; 52 53 // Add GC root chunks. 54 for (Symbol *b : ctx.config.gcroot) 55 addSym(b); 56 57 while (!worklist.empty()) { 58 SectionChunk *sc = worklist.pop_back_val(); 59 assert(sc->live && "We mark as live when pushing onto the worklist!"); 60 61 // Mark all symbols listed in the relocation table for this section. 62 for (Symbol *b : sc->symbols()) 63 if (b) 64 addSym(b); 65 66 // Mark associative sections if any. 67 for (SectionChunk &c : sc->children()) 68 enqueue(&c); 69 } 70 } 71 } 72