Coverage Report

Created: 2019-01-21 03:01

/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
// 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 "Symbols.h"
10
#include "Config.h"
11
#include "InputChunks.h"
12
#include "InputEvent.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
GlobalSymbol *WasmSym::StackPointer;
31
UndefinedGlobal *WasmSym::TableBase;
32
UndefinedGlobal *WasmSym::MemoryBase;
33
34
234
WasmSymbolType Symbol::getWasmType() const {
35
234
  if (isa<FunctionSymbol>(this))
36
205
    return WASM_SYMBOL_TYPE_FUNCTION;
37
29
  if (isa<DataSymbol>(this))
38
25
    return WASM_SYMBOL_TYPE_DATA;
39
4
  if (isa<GlobalSymbol>(this))
40
4
    return WASM_SYMBOL_TYPE_GLOBAL;
41
0
  if (isa<EventSymbol>(this))
42
0
    return WASM_SYMBOL_TYPE_EVENT;
43
0
  if (isa<SectionSymbol>(this))
44
0
    return WASM_SYMBOL_TYPE_SECTION;
45
0
  llvm_unreachable("invalid symbol kind");
46
0
}
47
48
2.00k
InputChunk *Symbol::getChunk() const {
49
2.00k
  if (auto *F = dyn_cast<DefinedFunction>(this))
50
1.04k
    return F->Function;
51
958
  if (auto *D = dyn_cast<DefinedData>(this))
52
889
    return D->Segment;
53
69
  return nullptr;
54
69
}
55
56
1.15k
bool Symbol::isLive() const {
57
1.15k
  if (auto *G = dyn_cast<DefinedGlobal>(this))
58
17
    return G->Global->Live;
59
1.13k
  if (auto *E = dyn_cast<DefinedEvent>(this))
60
2
    return E->Event->Live;
61
1.13k
  if (InputChunk *C = getChunk())
62
754
    return C->Live;
63
380
  return Referenced;
64
380
}
65
66
436
void Symbol::markLive() {
67
436
  if (auto *G = dyn_cast<DefinedGlobal>(this))
68
1
    G->Global->Live = true;
69
436
  if (auto *E = dyn_cast<DefinedEvent>(this))
70
1
    E->Event->Live = true;
71
436
  if (InputChunk *C = getChunk())
72
277
    C->Live = true;
73
436
  Referenced = true;
74
436
}
75
76
214
uint32_t Symbol::getOutputSymbolIndex() const {
77
214
  assert(OutputSymbolIndex != INVALID_INDEX);
78
214
  return OutputSymbolIndex;
79
214
}
80
81
233
void Symbol::setOutputSymbolIndex(uint32_t Index) {
82
233
  LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index
83
233
                    << "\n");
84
233
  assert(OutputSymbolIndex == INVALID_INDEX);
85
233
  OutputSymbolIndex = Index;
86
233
}
87
88
312
bool Symbol::isWeak() const {
89
312
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
90
312
}
91
92
1.50k
bool Symbol::isLocal() const {
93
1.50k
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
94
1.50k
}
95
96
445
bool Symbol::isHidden() const {
97
445
  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
98
445
}
99
100
80
void Symbol::setHidden(bool IsHidden) {
101
80
  LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
102
80
  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
103
80
  if (IsHidden)
104
0
    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
105
80
  else
106
80
    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
107
80
}
108
109
1.32k
bool Symbol::isExported() const {
110
1.32k
  if (!isDefined() || 
isLocal()1.26k
)
111
59
    return false;
112
1.26k
113
1.26k
  if (ForceExport || 
Config->ExportAll784
)
114
498
    return true;
115
769
116
769
  if (Config->ExportDynamic && 
!isHidden()212
)
117
118
    return true;
118
651
119
651
  return false;
120
651
}
121
122
527
uint32_t FunctionSymbol::getFunctionIndex() const {
123
527
  if (auto *F = dyn_cast<DefinedFunction>(this))
124
483
    return F->Function->getFunctionIndex();
125
44
  assert(FunctionIndex != INVALID_INDEX);
126
44
  return FunctionIndex;
127
44
}
128
129
18
void FunctionSymbol::setFunctionIndex(uint32_t Index) {
130
18
  LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
131
18
  assert(FunctionIndex == INVALID_INDEX);
132
18
  FunctionIndex = Index;
133
18
}
134
135
43
bool FunctionSymbol::hasFunctionIndex() const {
136
43
  if (auto *F = dyn_cast<DefinedFunction>(this))
137
40
    return F->Function->hasFunctionIndex();
138
3
  return FunctionIndex != INVALID_INDEX;
139
3
}
140
141
54
uint32_t FunctionSymbol::getTableIndex() const {
142
54
  if (auto *F = dyn_cast<DefinedFunction>(this))
143
51
    return F->Function->getTableIndex();
144
3
  assert(TableIndex != INVALID_INDEX);
145
3
  return TableIndex;
146
3
}
147
148
85
bool FunctionSymbol::hasTableIndex() const {
149
85
  if (auto *F = dyn_cast<DefinedFunction>(this))
150
81
    return F->Function->hasTableIndex();
151
4
  return TableIndex != INVALID_INDEX;
152
4
}
153
154
43
void FunctionSymbol::setTableIndex(uint32_t Index) {
155
43
  // For imports, we set the table index here on the Symbol; for defined
156
43
  // functions we set the index on the InputFunction so that we don't export
157
43
  // the same thing twice (keeps the table size down).
158
43
  if (auto *F = dyn_cast<DefinedFunction>(this)) {
159
40
    F->Function->setTableIndex(Index);
160
40
    return;
161
40
  }
162
3
  LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
163
3
  assert(TableIndex == INVALID_INDEX);
164
3
  TableIndex = Index;
165
3
}
166
167
DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
168
                                 InputFunction *Function)
169
    : FunctionSymbol(Name, DefinedFunctionKind, Flags, F,
170
                     Function ? &Function->Signature : nullptr),
171
607
      Function(Function) {}
172
173
368
uint32_t DefinedData::getVirtualAddress() const {
174
368
  LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
175
368
  if (Segment)
176
184
    return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset;
177
184
  return Offset;
178
184
}
179
180
265
void DefinedData::setVirtualAddress(uint32_t Value) {
181
265
  LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
182
265
  assert(!Segment);
183
265
  Offset = Value;
184
265
}
185
186
22
uint32_t DefinedData::getOutputSegmentOffset() const {
187
22
  LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
188
22
  return Segment->OutputSegmentOffset + Offset;
189
22
}
190
191
22
uint32_t DefinedData::getOutputSegmentIndex() const {
192
22
  LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
193
22
  return Segment->OutputSeg->Index;
194
22
}
195
196
35
uint32_t GlobalSymbol::getGlobalIndex() const {
197
35
  if (auto *F = dyn_cast<DefinedGlobal>(this))
198
15
    return F->Global->getGlobalIndex();
199
20
  assert(GlobalIndex != INVALID_INDEX);
200
20
  return GlobalIndex;
201
20
}
202
203
10
void GlobalSymbol::setGlobalIndex(uint32_t Index) {
204
10
  LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
205
10
  assert(GlobalIndex == INVALID_INDEX);
206
10
  GlobalIndex = Index;
207
10
}
208
209
0
bool GlobalSymbol::hasGlobalIndex() const {
210
0
  if (auto *F = dyn_cast<DefinedGlobal>(this))
211
0
    return F->Global->hasGlobalIndex();
212
0
  return GlobalIndex != INVALID_INDEX;
213
0
}
214
215
DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
216
                             InputGlobal *Global)
217
    : GlobalSymbol(Name, DefinedGlobalKind, Flags, File,
218
                   Global ? &Global->getType() : nullptr),
219
114
      Global(Global) {}
220
221
2
uint32_t EventSymbol::getEventIndex() const {
222
2
  if (auto *F = dyn_cast<DefinedEvent>(this))
223
2
    return F->Event->getEventIndex();
224
0
  assert(EventIndex != INVALID_INDEX);
225
0
  return EventIndex;
226
0
}
227
228
0
void EventSymbol::setEventIndex(uint32_t Index) {
229
0
  LLVM_DEBUG(dbgs() << "setEventIndex " << Name << " -> " << Index << "\n");
230
0
  assert(EventIndex == INVALID_INDEX);
231
0
  EventIndex = Index;
232
0
}
233
234
0
bool EventSymbol::hasEventIndex() const {
235
0
  if (auto *F = dyn_cast<DefinedEvent>(this))
236
0
    return F->Event->hasEventIndex();
237
0
  return EventIndex != INVALID_INDEX;
238
0
}
239
240
DefinedEvent::DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
241
                           InputEvent *Event)
242
    : EventSymbol(Name, DefinedEventKind, Flags, File,
243
                  Event ? &Event->getType() : nullptr,
244
                  Event ? &Event->Signature : nullptr),
245
1
      Event(Event) {}
246
247
0
uint32_t SectionSymbol::getOutputSectionIndex() const {
248
0
  LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
249
0
  assert(OutputSectionIndex != INVALID_INDEX);
250
0
  return OutputSectionIndex;
251
0
}
252
253
0
void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
254
0
  LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index
255
0
                    << "\n");
256
0
  assert(Index != INVALID_INDEX);
257
0
  OutputSectionIndex = Index;
258
0
}
259
260
12
void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
261
262
32
std::string lld::toString(const wasm::Symbol &Sym) {
263
32
  return lld::maybeDemangleSymbol(Sym.getName());
264
32
}
265
266
504
std::string lld::maybeDemangleSymbol(StringRef Name) {
267
504
  if (Config->Demangle)
268
499
    if (Optional<std::string> S = demangleItanium(Name))
269
3
      return *S;
270
501
  return Name;
271
501
}
272
273
0
std::string lld::toString(wasm::Symbol::Kind Kind) {
274
0
  switch (Kind) {
275
0
  case wasm::Symbol::DefinedFunctionKind:
276
0
    return "DefinedFunction";
277
0
  case wasm::Symbol::DefinedDataKind:
278
0
    return "DefinedData";
279
0
  case wasm::Symbol::DefinedGlobalKind:
280
0
    return "DefinedGlobal";
281
0
  case wasm::Symbol::DefinedEventKind:
282
0
    return "DefinedEvent";
283
0
  case wasm::Symbol::UndefinedFunctionKind:
284
0
    return "UndefinedFunction";
285
0
  case wasm::Symbol::UndefinedDataKind:
286
0
    return "UndefinedData";
287
0
  case wasm::Symbol::UndefinedGlobalKind:
288
0
    return "UndefinedGlobal";
289
0
  case wasm::Symbol::LazyKind:
290
0
    return "LazyKind";
291
0
  case wasm::Symbol::SectionKind:
292
0
    return "SectionKind";
293
0
  }
294
0
  llvm_unreachable("invalid symbol kind");
295
0
}