]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/MarkLive.cpp
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / MarkLive.cpp
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 "Chunks.h"
10 #include "Symbols.h"
11 #include "lld/Common/Timer.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include <vector>
14
15 namespace lld {
16 namespace coff {
17
18 static Timer gctimer("GC", Timer::root());
19
20 // Set live bit on for each reachable chunk. Unmarked (unreachable)
21 // COMDAT chunks will be ignored by Writer, so they will be excluded
22 // from the final output.
23 void markLive(ArrayRef<Chunk *> chunks) {
24   ScopedTimer t(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.
32   for (Chunk *c : chunks)
33     if (auto *sc = dyn_cast<SectionChunk>(c))
34       if (sc->live)
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 : 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 }
73 }