/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/COFF/MarkLive.cpp
Line | Count | Source |
1 | | //===- MarkLive.cpp -------------------------------------------------------===// |
2 | | // |
3 | | // The LLVM Linker |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | |
10 | | #include "Chunks.h" |
11 | | #include "Symbols.h" |
12 | | #include "llvm/ADT/STLExtras.h" |
13 | | #include <vector> |
14 | | |
15 | | namespace lld { |
16 | | namespace 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 | 250 | void markLive(const std::vector<Chunk *> &Chunks) { |
22 | 250 | // We build up a worklist of sections which have been marked as live. We only |
23 | 250 | // push into the worklist when we discover an unmarked section, and we mark |
24 | 250 | // as we push, so sections never appear twice in the list. |
25 | 250 | SmallVector<SectionChunk *, 256> Worklist; |
26 | 250 | |
27 | 250 | // COMDAT section chunks are dead by default. Add non-COMDAT chunks. |
28 | 250 | for (Chunk *C : Chunks) |
29 | 724 | if (auto *724 SC724 = dyn_cast<SectionChunk>(C)) |
30 | 714 | if (714 SC->isLive()714 ) |
31 | 650 | Worklist.push_back(SC); |
32 | 250 | |
33 | 672 | auto Enqueue = [&](SectionChunk *C) { |
34 | 672 | if (C->isLive()) |
35 | 623 | return; |
36 | 49 | C->markLive(); |
37 | 49 | Worklist.push_back(C); |
38 | 49 | }; |
39 | 250 | |
40 | 771 | auto AddSym = [&](SymbolBody *B) { |
41 | 771 | if (auto *Sym = dyn_cast<DefinedRegular>(B)) |
42 | 663 | Enqueue(Sym->getChunk()); |
43 | 108 | else if (auto *108 Sym108 = dyn_cast<DefinedImportData>(B)) |
44 | 3 | Sym->File->Live = true; |
45 | 105 | else if (auto *105 Sym105 = dyn_cast<DefinedImportThunk>(B)) |
46 | 63 | Sym->WrappedSym->File->Live = true; |
47 | 771 | }; |
48 | 250 | |
49 | 250 | // Add GC root chunks. |
50 | 250 | for (SymbolBody *B : Config->GCRoot) |
51 | 346 | AddSym(B); |
52 | 250 | |
53 | 949 | while (!Worklist.empty()949 ) { |
54 | 699 | SectionChunk *SC = Worklist.pop_back_val(); |
55 | 699 | |
56 | 699 | // If this section was discarded, there are relocations referring to |
57 | 699 | // discarded sections. Ignore these sections to avoid crashing. They will be |
58 | 699 | // diagnosed during relocation processing. |
59 | 699 | if (SC->isDiscarded()) |
60 | 1 | continue; |
61 | 698 | |
62 | 699 | assert(SC->isLive() && "We mark as live when pushing onto the worklist!"); |
63 | 698 | |
64 | 698 | // Mark all symbols listed in the relocation table for this section. |
65 | 698 | for (SymbolBody *B : SC->symbols()) |
66 | 425 | AddSym(B); |
67 | 698 | |
68 | 698 | // Mark associative sections if any. |
69 | 698 | for (SectionChunk *C : SC->children()) |
70 | 9 | Enqueue(C); |
71 | 699 | } |
72 | 250 | } |
73 | | |
74 | | } |
75 | | } |