Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lld/COFF/MarkLive.cpp
34870 views
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 "llvm/Support/TimeProfiler.h"
15
#include <vector>
16
17
namespace lld::coff {
18
19
// Set live bit on for each reachable chunk. Unmarked (unreachable)
20
// COMDAT chunks will be ignored by Writer, so they will be excluded
21
// from the final output.
22
void markLive(COFFLinkerContext &ctx) {
23
llvm::TimeTraceScope timeScope("Mark live");
24
ScopedTimer t(ctx.gcTimer);
25
26
// We build up a worklist of sections which have been marked as live. We only
27
// push into the worklist when we discover an unmarked section, and we mark
28
// as we push, so sections never appear twice in the list.
29
SmallVector<SectionChunk *, 256> worklist;
30
31
// COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not
32
// traverse DWARF sections. They are live, but they should not keep other
33
// sections alive.
34
for (Chunk *c : ctx.symtab.getChunks())
35
if (auto *sc = dyn_cast<SectionChunk>(c))
36
if (sc->live && !sc->isDWARF())
37
worklist.push_back(sc);
38
39
auto enqueue = [&](SectionChunk *c) {
40
if (c->live)
41
return;
42
c->live = true;
43
worklist.push_back(c);
44
};
45
46
auto addSym = [&](Symbol *b) {
47
if (auto *sym = dyn_cast<DefinedRegular>(b))
48
enqueue(sym->getChunk());
49
else if (auto *sym = dyn_cast<DefinedImportData>(b))
50
sym->file->live = true;
51
else if (auto *sym = dyn_cast<DefinedImportThunk>(b))
52
sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true;
53
};
54
55
// Add GC root chunks.
56
for (Symbol *b : ctx.config.gcroot)
57
addSym(b);
58
59
while (!worklist.empty()) {
60
SectionChunk *sc = worklist.pop_back_val();
61
assert(sc->live && "We mark as live when pushing onto the worklist!");
62
63
// Mark all symbols listed in the relocation table for this section.
64
for (Symbol *b : sc->symbols())
65
if (b)
66
addSym(b);
67
68
// Mark associative sections if any.
69
for (SectionChunk &c : sc->children())
70
enqueue(&c);
71
72
// Mark EC entry thunks.
73
if (Defined *entryThunk = sc->getEntryThunk())
74
addSym(entryThunk);
75
}
76
}
77
}
78
79