Coverage Report

Created: 2018-10-23 15:26

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/Symbols.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Symbols.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 "Symbols.h"
11
#include "Config.h"
12
#include "InputChunks.h"
13
#include "InputFiles.h"
14
#include "InputGlobal.h"
15
#include "OutputSegment.h"
16
#include "lld/Common/ErrorHandler.h"
17
#include "lld/Common/Strings.h"
18
19
#define DEBUG_TYPE "lld"
20
21
using namespace llvm;
22
using namespace llvm::wasm;
23
using namespace lld;
24
using namespace lld::wasm;
25
26
DefinedFunction *WasmSym::CallCtors;
27
DefinedData *WasmSym::DsoHandle;
28
DefinedData *WasmSym::DataEnd;
29
DefinedData *WasmSym::HeapBase;
30
DefinedGlobal *WasmSym::StackPointer;
31
32
234
WasmSymbolType Symbol::getWasmType() const {
33
234
  if (isa<FunctionSymbol>(this))
34
205
    return WASM_SYMBOL_TYPE_FUNCTION;
35
29
  if (isa<DataSymbol>(this))
36
25
    return WASM_SYMBOL_TYPE_DATA;
37
4
  if (isa<GlobalSymbol>(this))
38
4
    return WASM_SYMBOL_TYPE_GLOBAL;
39
0
  if (isa<SectionSymbol>(this))
40
0
    return WASM_SYMBOL_TYPE_SECTION;
41
0
  llvm_unreachable("invalid symbol kind");
42
0
}
43
44
1.87k
InputChunk *Symbol::getChunk() const {
45
1.87k
  if (auto *F = dyn_cast<DefinedFunction>(this))
46
992
    return F->Function;
47
886
  if (auto *D = dyn_cast<DefinedData>(this))
48
834
    return D->Segment;
49
52
  return nullptr;
50
52
}
51
52
1.08k
bool Symbol::isLive() const {
53
1.08k
  if (auto *G = dyn_cast<DefinedGlobal>(this))
54
17
    return G->Global->Live;
55
1.06k
  if (InputChunk *C = getChunk())
56
719
    return C->Live;
57
349
  return Referenced;
58
349
}
59
60
405
void Symbol::markLive() {
61
405
  if (auto *G = dyn_cast<DefinedGlobal>(this))
62
1
    G->Global->Live = true;
63
405
  if (InputChunk *C = getChunk())
64
261
    C->Live = true;
65
405
  Referenced = true;
66
405
}
67
68
214
uint32_t Symbol::getOutputSymbolIndex() const {
69
214
  assert(OutputSymbolIndex != INVALID_INDEX);
70
214
  return OutputSymbolIndex;
71
214
}
72
73
233
void Symbol::setOutputSymbolIndex(uint32_t Index) {
74
233
  LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index
75
233
                    << "\n");
76
233
  assert(OutputSymbolIndex == INVALID_INDEX);
77
233
  OutputSymbolIndex = Index;
78
233
}
79
80
302
bool Symbol::isWeak() const {
81
302
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
82
302
}
83
84
1.41k
bool Symbol::isLocal() const {
85
1.41k
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
86
1.41k
}
87
88
433
bool Symbol::isHidden() const {
89
433
  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
90
433
}
91
92
75
void Symbol::setHidden(bool IsHidden) {
93
75
  LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
94
75
  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
95
75
  if (IsHidden)
96
0
    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
97
75
  else
98
75
    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
99
75
}
100
101
1.22k
bool Symbol::isExported() const {
102
1.22k
  if (!isDefined() || 
isLocal()1.17k
)
103
50
    return false;
104
1.17k
105
1.17k
  if (ForceExport || 
Config->ExportAll726
)
106
466
    return true;
107
711
108
711
  if (Config->ExportDynamic && 
!isHidden()200
)
109
112
    return true;
110
599
111
599
  return false;
112
599
}
113
114
514
uint32_t FunctionSymbol::getFunctionIndex() const {
115
514
  if (auto *F = dyn_cast<DefinedFunction>(this))
116
474
    return F->Function->getFunctionIndex();
117
40
  assert(FunctionIndex != INVALID_INDEX);
118
40
  return FunctionIndex;
119
40
}
120
121
16
void FunctionSymbol::setFunctionIndex(uint32_t Index) {
122
16
  LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
123
16
  assert(FunctionIndex == INVALID_INDEX);
124
16
  FunctionIndex = Index;
125
16
}
126
127
41
bool FunctionSymbol::hasFunctionIndex() const {
128
41
  if (auto *F = dyn_cast<DefinedFunction>(this))
129
39
    return F->Function->hasFunctionIndex();
130
2
  return FunctionIndex != INVALID_INDEX;
131
2
}
132
133
52
uint32_t FunctionSymbol::getTableIndex() const {
134
52
  if (auto *F = dyn_cast<DefinedFunction>(this))
135
50
    return F->Function->getTableIndex();
136
2
  assert(TableIndex != INVALID_INDEX);
137
2
  return TableIndex;
138
2
}
139
140
81
bool FunctionSymbol::hasTableIndex() const {
141
81
  if (auto *F = dyn_cast<DefinedFunction>(this))
142
79
    return F->Function->hasTableIndex();
143
2
  return TableIndex != INVALID_INDEX;
144
2
}
145
146
41
void FunctionSymbol::setTableIndex(uint32_t Index) {
147
41
  // For imports, we set the table index here on the Symbol; for defined
148
41
  // functions we set the index on the InputFunction so that we don't export
149
41
  // the same thing twice (keeps the table size down).
150
41
  if (auto *F = dyn_cast<DefinedFunction>(this)) {
151
39
    F->Function->setTableIndex(Index);
152
39
    return;
153
39
  }
154
2
  LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
155
2
  assert(TableIndex == INVALID_INDEX);
156
2
  TableIndex = Index;
157
2
}
158
159
DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
160
                                 InputFunction *Function)
161
    : FunctionSymbol(Name, DefinedFunctionKind, Flags, F,
162
                     Function ? &Function->Signature : nullptr),
163
591
      Function(Function) {}
164
165
350
uint32_t DefinedData::getVirtualAddress() const {
166
350
  LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
167
350
  if (Segment)
168
178
    return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset;
169
172
  return Offset;
170
172
}
171
172
246
void DefinedData::setVirtualAddress(uint32_t Value) {
173
246
  LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
174
246
  assert(!Segment);
175
246
  Offset = Value;
176
246
}
177
178
22
uint32_t DefinedData::getOutputSegmentOffset() const {
179
22
  LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
180
22
  return Segment->OutputSegmentOffset + Offset;
181
22
}
182
183
22
uint32_t DefinedData::getOutputSegmentIndex() const {
184
22
  LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
185
22
  return Segment->OutputSeg->Index;
186
22
}
187
188
30
uint32_t GlobalSymbol::getGlobalIndex() const {
189
30
  if (auto *F = dyn_cast<DefinedGlobal>(this))
190
15
    return F->Global->getGlobalIndex();
191
15
  assert(GlobalIndex != INVALID_INDEX);
192
15
  return GlobalIndex;
193
15
}
194
195
7
void GlobalSymbol::setGlobalIndex(uint32_t Index) {
196
7
  LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
197
7
  assert(GlobalIndex == INVALID_INDEX);
198
7
  GlobalIndex = Index;
199
7
}
200
201
0
bool GlobalSymbol::hasGlobalIndex() const {
202
0
  if (auto *F = dyn_cast<DefinedGlobal>(this))
203
0
    return F->Global->hasGlobalIndex();
204
0
  return GlobalIndex != INVALID_INDEX;
205
0
}
206
207
DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
208
                             InputGlobal *Global)
209
    : GlobalSymbol(Name, DefinedGlobalKind, Flags, File,
210
                   Global ? &Global->getType() : nullptr),
211
108
      Global(Global) {}
212
213
0
uint32_t SectionSymbol::getOutputSectionIndex() const {
214
0
  LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
215
0
  assert(OutputSectionIndex != INVALID_INDEX);
216
0
  return OutputSectionIndex;
217
0
}
218
219
0
void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
220
0
  LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index
221
0
                    << "\n");
222
0
  assert(Index != INVALID_INDEX);
223
0
  OutputSectionIndex = Index;
224
0
}
225
226
12
void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
227
228
7
std::string lld::toString(const wasm::Symbol &Sym) {
229
7
  if (Config->Demangle)
230
6
    if (Optional<std::string> S = demangleItanium(Sym.getName()))
231
1
      return *S;
232
6
  return Sym.getName();
233
6
}
234
235
0
std::string lld::toString(wasm::Symbol::Kind Kind) {
236
0
  switch (Kind) {
237
0
  case wasm::Symbol::DefinedFunctionKind:
238
0
    return "DefinedFunction";
239
0
  case wasm::Symbol::DefinedDataKind:
240
0
    return "DefinedData";
241
0
  case wasm::Symbol::DefinedGlobalKind:
242
0
    return "DefinedGlobal";
243
0
  case wasm::Symbol::UndefinedFunctionKind:
244
0
    return "UndefinedFunction";
245
0
  case wasm::Symbol::UndefinedDataKind:
246
0
    return "UndefinedData";
247
0
  case wasm::Symbol::UndefinedGlobalKind:
248
0
    return "UndefinedGlobal";
249
0
  case wasm::Symbol::LazyKind:
250
0
    return "LazyKind";
251
0
  case wasm::Symbol::SectionKind:
252
0
    return "SectionKind";
253
0
  }
254
0
  llvm_unreachable("invalid symbol kind");
255
0
}