Coverage Report

Created: 2018-06-25 02:00

/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
0
WasmSymbolType Symbol::getWasmType() const {
33
0
  if (isa<FunctionSymbol>(this))
34
0
    return WASM_SYMBOL_TYPE_FUNCTION;
35
0
  if (isa<DataSymbol>(this))
36
0
    return WASM_SYMBOL_TYPE_DATA;
37
0
  if (isa<GlobalSymbol>(this))
38
0
    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
0
InputChunk *Symbol::getChunk() const {
45
0
  if (auto *F = dyn_cast<DefinedFunction>(this))
46
0
    return F->Function;
47
0
  if (auto *D = dyn_cast<DefinedData>(this))
48
0
    return D->Segment;
49
0
  return nullptr;
50
0
}
51
52
0
bool Symbol::isLive() const {
53
0
  if (auto *G = dyn_cast<DefinedGlobal>(this))
54
0
    return G->Global->Live;
55
0
  if (InputChunk *C = getChunk())
56
0
    return C->Live;
57
0
  return Referenced;
58
0
}
59
60
0
void Symbol::markLive() {
61
0
  if (auto *G = dyn_cast<DefinedGlobal>(this))
62
0
    G->Global->Live = true;
63
0
  if (InputChunk *C = getChunk())
64
0
    C->Live = true;
65
0
  Referenced = true;
66
0
}
67
68
0
uint32_t Symbol::getOutputSymbolIndex() const {
69
0
  assert(OutputSymbolIndex != INVALID_INDEX);
70
0
  return OutputSymbolIndex;
71
0
}
72
73
0
void Symbol::setOutputSymbolIndex(uint32_t Index) {
74
0
  LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index
75
0
                    << "\n");
76
0
  assert(OutputSymbolIndex == INVALID_INDEX);
77
0
  OutputSymbolIndex = Index;
78
0
}
79
80
0
bool Symbol::isWeak() const {
81
0
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
82
0
}
83
84
0
bool Symbol::isLocal() const {
85
0
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
86
0
}
87
88
0
bool Symbol::isHidden() const {
89
0
  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
90
0
}
91
92
0
void Symbol::setHidden(bool IsHidden) {
93
0
  LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
94
0
  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
95
0
  if (IsHidden)
96
0
    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
97
0
  else
98
0
    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
99
0
}
100
101
0
uint32_t FunctionSymbol::getFunctionIndex() const {
102
0
  if (auto *F = dyn_cast<DefinedFunction>(this))
103
0
    return F->Function->getFunctionIndex();
104
0
  assert(FunctionIndex != INVALID_INDEX);
105
0
  return FunctionIndex;
106
0
}
107
108
0
void FunctionSymbol::setFunctionIndex(uint32_t Index) {
109
0
  LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
110
0
  assert(FunctionIndex == INVALID_INDEX);
111
0
  FunctionIndex = Index;
112
0
}
113
114
0
bool FunctionSymbol::hasFunctionIndex() const {
115
0
  if (auto *F = dyn_cast<DefinedFunction>(this))
116
0
    return F->Function->hasFunctionIndex();
117
0
  return FunctionIndex != INVALID_INDEX;
118
0
}
119
120
0
uint32_t FunctionSymbol::getTableIndex() const {
121
0
  if (auto *F = dyn_cast<DefinedFunction>(this))
122
0
    return F->Function->getTableIndex();
123
0
  assert(TableIndex != INVALID_INDEX);
124
0
  return TableIndex;
125
0
}
126
127
0
bool FunctionSymbol::hasTableIndex() const {
128
0
  if (auto *F = dyn_cast<DefinedFunction>(this))
129
0
    return F->Function->hasTableIndex();
130
0
  return TableIndex != INVALID_INDEX;
131
0
}
132
133
0
void FunctionSymbol::setTableIndex(uint32_t Index) {
134
0
  // For imports, we set the table index here on the Symbol; for defined
135
0
  // functions we set the index on the InputFunction so that we don't export
136
0
  // the same thing twice (keeps the table size down).
137
0
  if (auto *F = dyn_cast<DefinedFunction>(this)) {
138
0
    F->Function->setTableIndex(Index);
139
0
    return;
140
0
  }
141
0
  LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
142
0
  assert(TableIndex == INVALID_INDEX);
143
0
  TableIndex = Index;
144
0
}
145
146
DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
147
                                 InputFunction *Function)
148
    : FunctionSymbol(Name, DefinedFunctionKind, Flags, F,
149
                     Function ? &Function->Signature : nullptr),
150
0
      Function(Function) {}
151
152
0
uint32_t DefinedData::getVirtualAddress() const {
153
0
  LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
154
0
  if (Segment)
155
0
    return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset;
156
0
  return Offset;
157
0
}
158
159
0
void DefinedData::setVirtualAddress(uint32_t Value) {
160
0
  LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
161
0
  assert(!Segment);
162
0
  Offset = Value;
163
0
}
164
165
0
uint32_t DefinedData::getOutputSegmentOffset() const {
166
0
  LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
167
0
  return Segment->OutputSegmentOffset + Offset;
168
0
}
169
170
0
uint32_t DefinedData::getOutputSegmentIndex() const {
171
0
  LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
172
0
  return Segment->OutputSeg->Index;
173
0
}
174
175
0
uint32_t GlobalSymbol::getGlobalIndex() const {
176
0
  if (auto *F = dyn_cast<DefinedGlobal>(this))
177
0
    return F->Global->getGlobalIndex();
178
0
  assert(GlobalIndex != INVALID_INDEX);
179
0
  return GlobalIndex;
180
0
}
181
182
0
void GlobalSymbol::setGlobalIndex(uint32_t Index) {
183
0
  LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
184
0
  assert(GlobalIndex == INVALID_INDEX);
185
0
  GlobalIndex = Index;
186
0
}
187
188
0
bool GlobalSymbol::hasGlobalIndex() const {
189
0
  if (auto *F = dyn_cast<DefinedGlobal>(this))
190
0
    return F->Global->hasGlobalIndex();
191
0
  return GlobalIndex != INVALID_INDEX;
192
0
}
193
194
DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
195
                             InputGlobal *Global)
196
    : GlobalSymbol(Name, DefinedGlobalKind, Flags, File,
197
                   Global ? &Global->getType() : nullptr),
198
0
      Global(Global) {}
199
200
0
uint32_t SectionSymbol::getOutputSectionIndex() const {
201
0
  LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
202
0
  assert(OutputSectionIndex != INVALID_INDEX);
203
0
  return OutputSectionIndex;
204
0
}
205
206
0
void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
207
0
  LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index
208
0
                    << "\n");
209
0
  assert(Index != INVALID_INDEX);
210
0
  OutputSectionIndex = Index;
211
0
}
212
213
0
void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
214
215
0
std::string lld::toString(const wasm::Symbol &Sym) {
216
0
  if (Config->Demangle)
217
0
    if (Optional<std::string> S = demangleItanium(Sym.getName()))
218
0
      return *S;
219
0
  return Sym.getName();
220
0
}
221
222
0
std::string lld::toString(wasm::Symbol::Kind Kind) {
223
0
  switch (Kind) {
224
0
  case wasm::Symbol::DefinedFunctionKind:
225
0
    return "DefinedFunction";
226
0
  case wasm::Symbol::DefinedDataKind:
227
0
    return "DefinedData";
228
0
  case wasm::Symbol::DefinedGlobalKind:
229
0
    return "DefinedGlobal";
230
0
  case wasm::Symbol::UndefinedFunctionKind:
231
0
    return "UndefinedFunction";
232
0
  case wasm::Symbol::UndefinedDataKind:
233
0
    return "UndefinedData";
234
0
  case wasm::Symbol::UndefinedGlobalKind:
235
0
    return "UndefinedGlobal";
236
0
  case wasm::Symbol::LazyKind:
237
0
    return "LazyKind";
238
0
  case wasm::Symbol::SectionKind:
239
0
    return "SectionKind";
240
0
  }
241
0
  llvm_unreachable("invalid symbol kind");
242
0
}