Path: blob/main/contrib/llvm-project/lld/COFF/MarkLive.cpp
34870 views
//===- MarkLive.cpp -------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "COFFLinkerContext.h"9#include "Chunks.h"10#include "Symbols.h"11#include "lld/Common/Timer.h"12#include "llvm/ADT/STLExtras.h"13#include "llvm/Support/TimeProfiler.h"14#include <vector>1516namespace lld::coff {1718// Set live bit on for each reachable chunk. Unmarked (unreachable)19// COMDAT chunks will be ignored by Writer, so they will be excluded20// from the final output.21void markLive(COFFLinkerContext &ctx) {22llvm::TimeTraceScope timeScope("Mark live");23ScopedTimer t(ctx.gcTimer);2425// We build up a worklist of sections which have been marked as live. We only26// push into the worklist when we discover an unmarked section, and we mark27// as we push, so sections never appear twice in the list.28SmallVector<SectionChunk *, 256> worklist;2930// COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not31// traverse DWARF sections. They are live, but they should not keep other32// sections alive.33for (Chunk *c : ctx.symtab.getChunks())34if (auto *sc = dyn_cast<SectionChunk>(c))35if (sc->live && !sc->isDWARF())36worklist.push_back(sc);3738auto enqueue = [&](SectionChunk *c) {39if (c->live)40return;41c->live = true;42worklist.push_back(c);43};4445auto addSym = [&](Symbol *b) {46if (auto *sym = dyn_cast<DefinedRegular>(b))47enqueue(sym->getChunk());48else if (auto *sym = dyn_cast<DefinedImportData>(b))49sym->file->live = true;50else if (auto *sym = dyn_cast<DefinedImportThunk>(b))51sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true;52};5354// Add GC root chunks.55for (Symbol *b : ctx.config.gcroot)56addSym(b);5758while (!worklist.empty()) {59SectionChunk *sc = worklist.pop_back_val();60assert(sc->live && "We mark as live when pushing onto the worklist!");6162// Mark all symbols listed in the relocation table for this section.63for (Symbol *b : sc->symbols())64if (b)65addSym(b);6667// Mark associative sections if any.68for (SectionChunk &c : sc->children())69enqueue(&c);7071// Mark EC entry thunks.72if (Defined *entryThunk = sc->getEntryThunk())73addSym(entryThunk);74}75}76}777879