xref: /openbsd/gnu/llvm/lld/wasm/Symbols.cpp (revision dfe94b16)
1ece8a530Spatrick //===- Symbols.cpp --------------------------------------------------------===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick 
9ece8a530Spatrick #include "Symbols.h"
10ece8a530Spatrick #include "Config.h"
11ece8a530Spatrick #include "InputChunks.h"
121cf9926bSpatrick #include "InputElement.h"
13ece8a530Spatrick #include "InputFiles.h"
14ece8a530Spatrick #include "OutputSections.h"
15ece8a530Spatrick #include "OutputSegment.h"
16ece8a530Spatrick #include "lld/Common/ErrorHandler.h"
171cf9926bSpatrick #include "lld/Common/Memory.h"
18*dfe94b16Srobert #include "llvm/Demangle/Demangle.h"
19ece8a530Spatrick 
20ece8a530Spatrick #define DEBUG_TYPE "lld"
21ece8a530Spatrick 
22ece8a530Spatrick using namespace llvm;
23ece8a530Spatrick using namespace llvm::object;
24ece8a530Spatrick using namespace llvm::wasm;
25*dfe94b16Srobert using namespace lld::wasm;
26ece8a530Spatrick 
27ece8a530Spatrick namespace lld {
toString(const wasm::Symbol & sym)28ece8a530Spatrick std::string toString(const wasm::Symbol &sym) {
29ece8a530Spatrick   return maybeDemangleSymbol(sym.getName());
30ece8a530Spatrick }
31ece8a530Spatrick 
maybeDemangleSymbol(StringRef name)32ece8a530Spatrick std::string maybeDemangleSymbol(StringRef name) {
33bb684c34Spatrick   // WebAssembly requires caller and callee signatures to match, so we mangle
34bb684c34Spatrick   // `main` in the case where we need to pass it arguments.
35bb684c34Spatrick   if (name == "__main_argc_argv")
36bb684c34Spatrick     return "main";
37ece8a530Spatrick   if (wasm::config->demangle)
38*dfe94b16Srobert     return demangle(name.str());
39*dfe94b16Srobert   return name.str();
40ece8a530Spatrick }
41ece8a530Spatrick 
toString(wasm::Symbol::Kind kind)42ece8a530Spatrick std::string toString(wasm::Symbol::Kind kind) {
43ece8a530Spatrick   switch (kind) {
44ece8a530Spatrick   case wasm::Symbol::DefinedFunctionKind:
45ece8a530Spatrick     return "DefinedFunction";
46ece8a530Spatrick   case wasm::Symbol::DefinedDataKind:
47ece8a530Spatrick     return "DefinedData";
48ece8a530Spatrick   case wasm::Symbol::DefinedGlobalKind:
49ece8a530Spatrick     return "DefinedGlobal";
501cf9926bSpatrick   case wasm::Symbol::DefinedTableKind:
511cf9926bSpatrick     return "DefinedTable";
521cf9926bSpatrick   case wasm::Symbol::DefinedTagKind:
531cf9926bSpatrick     return "DefinedTag";
54ece8a530Spatrick   case wasm::Symbol::UndefinedFunctionKind:
55ece8a530Spatrick     return "UndefinedFunction";
56ece8a530Spatrick   case wasm::Symbol::UndefinedDataKind:
57ece8a530Spatrick     return "UndefinedData";
58ece8a530Spatrick   case wasm::Symbol::UndefinedGlobalKind:
59ece8a530Spatrick     return "UndefinedGlobal";
601cf9926bSpatrick   case wasm::Symbol::UndefinedTableKind:
611cf9926bSpatrick     return "UndefinedTable";
62*dfe94b16Srobert   case wasm::Symbol::UndefinedTagKind:
63*dfe94b16Srobert     return "UndefinedTag";
64ece8a530Spatrick   case wasm::Symbol::LazyKind:
65ece8a530Spatrick     return "LazyKind";
66ece8a530Spatrick   case wasm::Symbol::SectionKind:
67ece8a530Spatrick     return "SectionKind";
68ece8a530Spatrick   case wasm::Symbol::OutputSectionKind:
69ece8a530Spatrick     return "OutputSectionKind";
70ece8a530Spatrick   }
71ece8a530Spatrick   llvm_unreachable("invalid symbol kind");
72ece8a530Spatrick }
73ece8a530Spatrick 
74ece8a530Spatrick namespace wasm {
75ece8a530Spatrick DefinedFunction *WasmSym::callCtors;
761cf9926bSpatrick DefinedFunction *WasmSym::callDtors;
77ece8a530Spatrick DefinedFunction *WasmSym::initMemory;
781cf9926bSpatrick DefinedFunction *WasmSym::applyDataRelocs;
791cf9926bSpatrick DefinedFunction *WasmSym::applyGlobalRelocs;
80*dfe94b16Srobert DefinedFunction *WasmSym::applyGlobalTLSRelocs;
81ece8a530Spatrick DefinedFunction *WasmSym::initTLS;
821cf9926bSpatrick DefinedFunction *WasmSym::startFunction;
83ece8a530Spatrick DefinedData *WasmSym::dsoHandle;
84ece8a530Spatrick DefinedData *WasmSym::dataEnd;
85ece8a530Spatrick DefinedData *WasmSym::globalBase;
86ece8a530Spatrick DefinedData *WasmSym::heapBase;
87*dfe94b16Srobert DefinedData *WasmSym::heapEnd;
88ece8a530Spatrick DefinedData *WasmSym::initMemoryFlag;
89ece8a530Spatrick GlobalSymbol *WasmSym::stackPointer;
90*dfe94b16Srobert DefinedData *WasmSym::stackLow;
91*dfe94b16Srobert DefinedData *WasmSym::stackHigh;
92ece8a530Spatrick GlobalSymbol *WasmSym::tlsBase;
93ece8a530Spatrick GlobalSymbol *WasmSym::tlsSize;
94ece8a530Spatrick GlobalSymbol *WasmSym::tlsAlign;
95ece8a530Spatrick UndefinedGlobal *WasmSym::tableBase;
96ece8a530Spatrick DefinedData *WasmSym::definedTableBase;
971cf9926bSpatrick UndefinedGlobal *WasmSym::tableBase32;
981cf9926bSpatrick DefinedData *WasmSym::definedTableBase32;
99ece8a530Spatrick UndefinedGlobal *WasmSym::memoryBase;
100ece8a530Spatrick DefinedData *WasmSym::definedMemoryBase;
1011cf9926bSpatrick TableSymbol *WasmSym::indirectFunctionTable;
102ece8a530Spatrick 
getWasmType() const103ece8a530Spatrick WasmSymbolType Symbol::getWasmType() const {
104ece8a530Spatrick   if (isa<FunctionSymbol>(this))
105ece8a530Spatrick     return WASM_SYMBOL_TYPE_FUNCTION;
106ece8a530Spatrick   if (isa<DataSymbol>(this))
107ece8a530Spatrick     return WASM_SYMBOL_TYPE_DATA;
108ece8a530Spatrick   if (isa<GlobalSymbol>(this))
109ece8a530Spatrick     return WASM_SYMBOL_TYPE_GLOBAL;
1101cf9926bSpatrick   if (isa<TagSymbol>(this))
1111cf9926bSpatrick     return WASM_SYMBOL_TYPE_TAG;
1121cf9926bSpatrick   if (isa<TableSymbol>(this))
1131cf9926bSpatrick     return WASM_SYMBOL_TYPE_TABLE;
114ece8a530Spatrick   if (isa<SectionSymbol>(this) || isa<OutputSectionSymbol>(this))
115ece8a530Spatrick     return WASM_SYMBOL_TYPE_SECTION;
116ece8a530Spatrick   llvm_unreachable("invalid symbol kind");
117ece8a530Spatrick }
118ece8a530Spatrick 
getSignature() const119ece8a530Spatrick const WasmSignature *Symbol::getSignature() const {
120ece8a530Spatrick   if (auto* f = dyn_cast<FunctionSymbol>(this))
121ece8a530Spatrick     return f->signature;
122*dfe94b16Srobert   if (auto *t = dyn_cast<TagSymbol>(this))
123*dfe94b16Srobert     return t->signature;
124ece8a530Spatrick   if (auto *l = dyn_cast<LazySymbol>(this))
125ece8a530Spatrick     return l->signature;
126ece8a530Spatrick   return nullptr;
127ece8a530Spatrick }
128ece8a530Spatrick 
getChunk() const129ece8a530Spatrick InputChunk *Symbol::getChunk() const {
130ece8a530Spatrick   if (auto *f = dyn_cast<DefinedFunction>(this))
131ece8a530Spatrick     return f->function;
1321cf9926bSpatrick   if (auto *f = dyn_cast<UndefinedFunction>(this))
1331cf9926bSpatrick     if (f->stubFunction)
1341cf9926bSpatrick       return f->stubFunction->function;
135ece8a530Spatrick   if (auto *d = dyn_cast<DefinedData>(this))
136ece8a530Spatrick     return d->segment;
137ece8a530Spatrick   return nullptr;
138ece8a530Spatrick }
139ece8a530Spatrick 
isDiscarded() const140ece8a530Spatrick bool Symbol::isDiscarded() const {
141ece8a530Spatrick   if (InputChunk *c = getChunk())
142ece8a530Spatrick     return c->discarded;
143ece8a530Spatrick   return false;
144ece8a530Spatrick }
145ece8a530Spatrick 
isLive() const146ece8a530Spatrick bool Symbol::isLive() const {
147ece8a530Spatrick   if (auto *g = dyn_cast<DefinedGlobal>(this))
148ece8a530Spatrick     return g->global->live;
1491cf9926bSpatrick   if (auto *t = dyn_cast<DefinedTag>(this))
1501cf9926bSpatrick     return t->tag->live;
1511cf9926bSpatrick   if (auto *t = dyn_cast<DefinedTable>(this))
1521cf9926bSpatrick     return t->table->live;
153ece8a530Spatrick   if (InputChunk *c = getChunk())
154ece8a530Spatrick     return c->live;
155ece8a530Spatrick   return referenced;
156ece8a530Spatrick }
157ece8a530Spatrick 
markLive()158ece8a530Spatrick void Symbol::markLive() {
159ece8a530Spatrick   assert(!isDiscarded());
1601cf9926bSpatrick   referenced = true;
161*dfe94b16Srobert   if (file != nullptr && isDefined())
1621cf9926bSpatrick     file->markLive();
163ece8a530Spatrick   if (auto *g = dyn_cast<DefinedGlobal>(this))
164ece8a530Spatrick     g->global->live = true;
1651cf9926bSpatrick   if (auto *t = dyn_cast<DefinedTag>(this))
1661cf9926bSpatrick     t->tag->live = true;
1671cf9926bSpatrick   if (auto *t = dyn_cast<DefinedTable>(this))
1681cf9926bSpatrick     t->table->live = true;
1691cf9926bSpatrick   if (InputChunk *c = getChunk()) {
1701cf9926bSpatrick     // Usually, a whole chunk is marked as live or dead, but in mergeable
1711cf9926bSpatrick     // (splittable) sections, each piece of data has independent liveness bit.
1721cf9926bSpatrick     // So we explicitly tell it which offset is in use.
1731cf9926bSpatrick     if (auto *d = dyn_cast<DefinedData>(this)) {
1741cf9926bSpatrick       if (auto *ms = dyn_cast<MergeInputChunk>(c)) {
1751cf9926bSpatrick         ms->getSectionPiece(d->value)->live = true;
1761cf9926bSpatrick       }
1771cf9926bSpatrick     }
178ece8a530Spatrick     c->live = true;
1791cf9926bSpatrick   }
180ece8a530Spatrick }
181ece8a530Spatrick 
getOutputSymbolIndex() const182ece8a530Spatrick uint32_t Symbol::getOutputSymbolIndex() const {
183ece8a530Spatrick   assert(outputSymbolIndex != INVALID_INDEX);
184ece8a530Spatrick   return outputSymbolIndex;
185ece8a530Spatrick }
186ece8a530Spatrick 
setOutputSymbolIndex(uint32_t index)187ece8a530Spatrick void Symbol::setOutputSymbolIndex(uint32_t index) {
188ece8a530Spatrick   LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << name << " -> " << index
189ece8a530Spatrick                     << "\n");
190ece8a530Spatrick   assert(outputSymbolIndex == INVALID_INDEX);
191ece8a530Spatrick   outputSymbolIndex = index;
192ece8a530Spatrick }
193ece8a530Spatrick 
setGOTIndex(uint32_t index)194ece8a530Spatrick void Symbol::setGOTIndex(uint32_t index) {
195ece8a530Spatrick   LLVM_DEBUG(dbgs() << "setGOTIndex " << name << " -> " << index << "\n");
196ece8a530Spatrick   assert(gotIndex == INVALID_INDEX);
197ece8a530Spatrick   gotIndex = index;
198ece8a530Spatrick }
199ece8a530Spatrick 
isWeak() const200ece8a530Spatrick bool Symbol::isWeak() const {
201ece8a530Spatrick   return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
202ece8a530Spatrick }
203ece8a530Spatrick 
isLocal() const204ece8a530Spatrick bool Symbol::isLocal() const {
205ece8a530Spatrick   return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
206ece8a530Spatrick }
207ece8a530Spatrick 
isHidden() const208ece8a530Spatrick bool Symbol::isHidden() const {
209ece8a530Spatrick   return (flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
210ece8a530Spatrick }
211ece8a530Spatrick 
isTLS() const212*dfe94b16Srobert bool Symbol::isTLS() const { return flags & WASM_SYMBOL_TLS; }
213*dfe94b16Srobert 
setHidden(bool isHidden)214ece8a530Spatrick void Symbol::setHidden(bool isHidden) {
215ece8a530Spatrick   LLVM_DEBUG(dbgs() << "setHidden: " << name << " -> " << isHidden << "\n");
216ece8a530Spatrick   flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
217ece8a530Spatrick   if (isHidden)
218ece8a530Spatrick     flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
219ece8a530Spatrick   else
220ece8a530Spatrick     flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
221ece8a530Spatrick }
222ece8a530Spatrick 
isImported() const223*dfe94b16Srobert bool Symbol::isImported() const {
224*dfe94b16Srobert   return isUndefined() && (importName.has_value() || forceImport);
225*dfe94b16Srobert }
226*dfe94b16Srobert 
isExported() const227ece8a530Spatrick bool Symbol::isExported() const {
228ece8a530Spatrick   if (!isDefined() || isLocal())
229ece8a530Spatrick     return false;
230ece8a530Spatrick 
231*dfe94b16Srobert   // Shared libraries must export all weakly defined symbols
232*dfe94b16Srobert   // in case they contain the version that will be chosen by
233*dfe94b16Srobert   // the dynamic linker.
234*dfe94b16Srobert   if (config->shared && isLive() && isWeak() && !isHidden())
235*dfe94b16Srobert     return true;
236*dfe94b16Srobert 
2371cf9926bSpatrick   if (config->exportAll || (config->exportDynamic && !isHidden()))
238ece8a530Spatrick     return true;
239ece8a530Spatrick 
2401cf9926bSpatrick   return isExportedExplicit();
2411cf9926bSpatrick }
242ece8a530Spatrick 
isExportedExplicit() const2431cf9926bSpatrick bool Symbol::isExportedExplicit() const {
2441cf9926bSpatrick   return forceExport || flags & WASM_SYMBOL_EXPORTED;
245ece8a530Spatrick }
246ece8a530Spatrick 
isNoStrip() const247ece8a530Spatrick bool Symbol::isNoStrip() const {
248ece8a530Spatrick   return flags & WASM_SYMBOL_NO_STRIP;
249ece8a530Spatrick }
250ece8a530Spatrick 
getFunctionIndex() const251ece8a530Spatrick uint32_t FunctionSymbol::getFunctionIndex() const {
252*dfe94b16Srobert   if (const auto *u = dyn_cast<UndefinedFunction>(this))
253*dfe94b16Srobert     if (u->stubFunction)
2541cf9926bSpatrick       return u->stubFunction->getFunctionIndex();
255*dfe94b16Srobert   if (functionIndex != INVALID_INDEX)
256ece8a530Spatrick     return functionIndex;
257*dfe94b16Srobert   auto *f = cast<DefinedFunction>(this);
258*dfe94b16Srobert   return f->function->getFunctionIndex();
259ece8a530Spatrick }
260ece8a530Spatrick 
setFunctionIndex(uint32_t index)261ece8a530Spatrick void FunctionSymbol::setFunctionIndex(uint32_t index) {
262ece8a530Spatrick   LLVM_DEBUG(dbgs() << "setFunctionIndex " << name << " -> " << index << "\n");
263ece8a530Spatrick   assert(functionIndex == INVALID_INDEX);
264ece8a530Spatrick   functionIndex = index;
265ece8a530Spatrick }
266ece8a530Spatrick 
hasFunctionIndex() const267ece8a530Spatrick bool FunctionSymbol::hasFunctionIndex() const {
268ece8a530Spatrick   if (auto *f = dyn_cast<DefinedFunction>(this))
269ece8a530Spatrick     return f->function->hasFunctionIndex();
270ece8a530Spatrick   return functionIndex != INVALID_INDEX;
271ece8a530Spatrick }
272ece8a530Spatrick 
getTableIndex() const273ece8a530Spatrick uint32_t FunctionSymbol::getTableIndex() const {
274ece8a530Spatrick   if (auto *f = dyn_cast<DefinedFunction>(this))
275ece8a530Spatrick     return f->function->getTableIndex();
276ece8a530Spatrick   assert(tableIndex != INVALID_INDEX);
277ece8a530Spatrick   return tableIndex;
278ece8a530Spatrick }
279ece8a530Spatrick 
hasTableIndex() const280ece8a530Spatrick bool FunctionSymbol::hasTableIndex() const {
281ece8a530Spatrick   if (auto *f = dyn_cast<DefinedFunction>(this))
282ece8a530Spatrick     return f->function->hasTableIndex();
283ece8a530Spatrick   return tableIndex != INVALID_INDEX;
284ece8a530Spatrick }
285ece8a530Spatrick 
setTableIndex(uint32_t index)286ece8a530Spatrick void FunctionSymbol::setTableIndex(uint32_t index) {
287ece8a530Spatrick   // For imports, we set the table index here on the Symbol; for defined
288ece8a530Spatrick   // functions we set the index on the InputFunction so that we don't export
289ece8a530Spatrick   // the same thing twice (keeps the table size down).
290ece8a530Spatrick   if (auto *f = dyn_cast<DefinedFunction>(this)) {
291ece8a530Spatrick     f->function->setTableIndex(index);
292ece8a530Spatrick     return;
293ece8a530Spatrick   }
294ece8a530Spatrick   LLVM_DEBUG(dbgs() << "setTableIndex " << name << " -> " << index << "\n");
295ece8a530Spatrick   assert(tableIndex == INVALID_INDEX);
296ece8a530Spatrick   tableIndex = index;
297ece8a530Spatrick }
298ece8a530Spatrick 
DefinedFunction(StringRef name,uint32_t flags,InputFile * f,InputFunction * function)299ece8a530Spatrick DefinedFunction::DefinedFunction(StringRef name, uint32_t flags, InputFile *f,
300ece8a530Spatrick                                  InputFunction *function)
301ece8a530Spatrick     : FunctionSymbol(name, DefinedFunctionKind, flags, f,
302ece8a530Spatrick                      function ? &function->signature : nullptr),
303ece8a530Spatrick       function(function) {}
304ece8a530Spatrick 
getExportedFunctionIndex() const305*dfe94b16Srobert uint32_t DefinedFunction::getExportedFunctionIndex() const {
306*dfe94b16Srobert   return function->getFunctionIndex();
307*dfe94b16Srobert }
308*dfe94b16Srobert 
getVA() const3091cf9926bSpatrick uint64_t DefinedData::getVA() const {
3101cf9926bSpatrick   LLVM_DEBUG(dbgs() << "getVA: " << getName() << "\n");
311*dfe94b16Srobert   // In the shared memory case, TLS symbols are relative to the start of the TLS
312*dfe94b16Srobert   // output segment (__tls_base).  When building without shared memory, TLS
313*dfe94b16Srobert   // symbols absolute, just like non-TLS.
314*dfe94b16Srobert   if (isTLS() && config->sharedMemory)
315*dfe94b16Srobert     return getOutputSegmentOffset() + value;
3161cf9926bSpatrick   if (segment)
3171cf9926bSpatrick     return segment->getVA(value);
3181cf9926bSpatrick   return value;
319ece8a530Spatrick }
320ece8a530Spatrick 
setVA(uint64_t value_)3211cf9926bSpatrick void DefinedData::setVA(uint64_t value_) {
3221cf9926bSpatrick   LLVM_DEBUG(dbgs() << "setVA " << name << " -> " << value_ << "\n");
323ece8a530Spatrick   assert(!segment);
3241cf9926bSpatrick   value = value_;
325ece8a530Spatrick }
326ece8a530Spatrick 
getOutputSegmentOffset() const327bb684c34Spatrick uint64_t DefinedData::getOutputSegmentOffset() const {
328ece8a530Spatrick   LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
3291cf9926bSpatrick   return segment->getChunkOffset(value);
330ece8a530Spatrick }
331ece8a530Spatrick 
getOutputSegmentIndex() const332bb684c34Spatrick uint64_t DefinedData::getOutputSegmentIndex() const {
333ece8a530Spatrick   LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
334ece8a530Spatrick   return segment->outputSeg->index;
335ece8a530Spatrick }
336ece8a530Spatrick 
getGlobalIndex() const337ece8a530Spatrick uint32_t GlobalSymbol::getGlobalIndex() const {
338ece8a530Spatrick   if (auto *f = dyn_cast<DefinedGlobal>(this))
3391cf9926bSpatrick     return f->global->getAssignedIndex();
340ece8a530Spatrick   assert(globalIndex != INVALID_INDEX);
341ece8a530Spatrick   return globalIndex;
342ece8a530Spatrick }
343ece8a530Spatrick 
setGlobalIndex(uint32_t index)344ece8a530Spatrick void GlobalSymbol::setGlobalIndex(uint32_t index) {
345ece8a530Spatrick   LLVM_DEBUG(dbgs() << "setGlobalIndex " << name << " -> " << index << "\n");
346ece8a530Spatrick   assert(globalIndex == INVALID_INDEX);
347ece8a530Spatrick   globalIndex = index;
348ece8a530Spatrick }
349ece8a530Spatrick 
hasGlobalIndex() const350ece8a530Spatrick bool GlobalSymbol::hasGlobalIndex() const {
351ece8a530Spatrick   if (auto *f = dyn_cast<DefinedGlobal>(this))
3521cf9926bSpatrick     return f->global->hasAssignedIndex();
353ece8a530Spatrick   return globalIndex != INVALID_INDEX;
354ece8a530Spatrick }
355ece8a530Spatrick 
DefinedGlobal(StringRef name,uint32_t flags,InputFile * file,InputGlobal * global)356ece8a530Spatrick DefinedGlobal::DefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
357ece8a530Spatrick                              InputGlobal *global)
358ece8a530Spatrick     : GlobalSymbol(name, DefinedGlobalKind, flags, file,
359ece8a530Spatrick                    global ? &global->getType() : nullptr),
360ece8a530Spatrick       global(global) {}
361ece8a530Spatrick 
getTagIndex() const3621cf9926bSpatrick uint32_t TagSymbol::getTagIndex() const {
3631cf9926bSpatrick   if (auto *f = dyn_cast<DefinedTag>(this))
3641cf9926bSpatrick     return f->tag->getAssignedIndex();
3651cf9926bSpatrick   assert(tagIndex != INVALID_INDEX);
3661cf9926bSpatrick   return tagIndex;
367ece8a530Spatrick }
368ece8a530Spatrick 
setTagIndex(uint32_t index)3691cf9926bSpatrick void TagSymbol::setTagIndex(uint32_t index) {
3701cf9926bSpatrick   LLVM_DEBUG(dbgs() << "setTagIndex " << name << " -> " << index << "\n");
3711cf9926bSpatrick   assert(tagIndex == INVALID_INDEX);
3721cf9926bSpatrick   tagIndex = index;
373ece8a530Spatrick }
374ece8a530Spatrick 
hasTagIndex() const3751cf9926bSpatrick bool TagSymbol::hasTagIndex() const {
3761cf9926bSpatrick   if (auto *f = dyn_cast<DefinedTag>(this))
3771cf9926bSpatrick     return f->tag->hasAssignedIndex();
3781cf9926bSpatrick   return tagIndex != INVALID_INDEX;
379ece8a530Spatrick }
380ece8a530Spatrick 
DefinedTag(StringRef name,uint32_t flags,InputFile * file,InputTag * tag)3811cf9926bSpatrick DefinedTag::DefinedTag(StringRef name, uint32_t flags, InputFile *file,
3821cf9926bSpatrick                        InputTag *tag)
3831cf9926bSpatrick     : TagSymbol(name, DefinedTagKind, flags, file,
3841cf9926bSpatrick                 tag ? &tag->signature : nullptr),
3851cf9926bSpatrick       tag(tag) {}
3861cf9926bSpatrick 
setLimits(const WasmLimits & limits)3871cf9926bSpatrick void TableSymbol::setLimits(const WasmLimits &limits) {
3881cf9926bSpatrick   if (auto *t = dyn_cast<DefinedTable>(this))
3891cf9926bSpatrick     t->table->setLimits(limits);
3901cf9926bSpatrick   auto *newType = make<WasmTableType>(*tableType);
3911cf9926bSpatrick   newType->Limits = limits;
3921cf9926bSpatrick   tableType = newType;
3931cf9926bSpatrick }
3941cf9926bSpatrick 
getTableNumber() const3951cf9926bSpatrick uint32_t TableSymbol::getTableNumber() const {
3961cf9926bSpatrick   if (const auto *t = dyn_cast<DefinedTable>(this))
3971cf9926bSpatrick     return t->table->getAssignedIndex();
3981cf9926bSpatrick   assert(tableNumber != INVALID_INDEX);
3991cf9926bSpatrick   return tableNumber;
4001cf9926bSpatrick }
4011cf9926bSpatrick 
setTableNumber(uint32_t number)4021cf9926bSpatrick void TableSymbol::setTableNumber(uint32_t number) {
4031cf9926bSpatrick   if (const auto *t = dyn_cast<DefinedTable>(this))
4041cf9926bSpatrick     return t->table->assignIndex(number);
4051cf9926bSpatrick   LLVM_DEBUG(dbgs() << "setTableNumber " << name << " -> " << number << "\n");
4061cf9926bSpatrick   assert(tableNumber == INVALID_INDEX);
4071cf9926bSpatrick   tableNumber = number;
4081cf9926bSpatrick }
4091cf9926bSpatrick 
hasTableNumber() const4101cf9926bSpatrick bool TableSymbol::hasTableNumber() const {
4111cf9926bSpatrick   if (const auto *t = dyn_cast<DefinedTable>(this))
4121cf9926bSpatrick     return t->table->hasAssignedIndex();
4131cf9926bSpatrick   return tableNumber != INVALID_INDEX;
4141cf9926bSpatrick }
4151cf9926bSpatrick 
DefinedTable(StringRef name,uint32_t flags,InputFile * file,InputTable * table)4161cf9926bSpatrick DefinedTable::DefinedTable(StringRef name, uint32_t flags, InputFile *file,
4171cf9926bSpatrick                            InputTable *table)
4181cf9926bSpatrick     : TableSymbol(name, DefinedTableKind, flags, file,
4191cf9926bSpatrick                   table ? &table->getType() : nullptr),
4201cf9926bSpatrick       table(table) {}
421ece8a530Spatrick 
getOutputSectionSymbol() const422ece8a530Spatrick const OutputSectionSymbol *SectionSymbol::getOutputSectionSymbol() const {
423ece8a530Spatrick   assert(section->outputSec && section->outputSec->sectionSym);
424ece8a530Spatrick   return section->outputSec->sectionSym;
425ece8a530Spatrick }
426ece8a530Spatrick 
fetch()427ece8a530Spatrick void LazySymbol::fetch() { cast<ArchiveFile>(file)->addMember(&archiveSymbol); }
428ece8a530Spatrick 
setWeak()4291cf9926bSpatrick void LazySymbol::setWeak() {
4301cf9926bSpatrick   flags |= (flags & ~WASM_SYMBOL_BINDING_MASK) | WASM_SYMBOL_BINDING_WEAK;
4311cf9926bSpatrick }
4321cf9926bSpatrick 
getMemberBuffer()433ece8a530Spatrick MemoryBufferRef LazySymbol::getMemberBuffer() {
434ece8a530Spatrick   Archive::Child c =
435ece8a530Spatrick       CHECK(archiveSymbol.getMember(),
436ece8a530Spatrick             "could not get the member for symbol " + toString(*this));
437ece8a530Spatrick 
438ece8a530Spatrick   return CHECK(c.getMemoryBufferRef(),
439ece8a530Spatrick                "could not get the buffer for the member defining symbol " +
440ece8a530Spatrick                    toString(*this));
441ece8a530Spatrick }
442ece8a530Spatrick 
printTraceSymbolUndefined(StringRef name,const InputFile * file)443ece8a530Spatrick void printTraceSymbolUndefined(StringRef name, const InputFile* file) {
444ece8a530Spatrick   message(toString(file) + ": reference to " + name);
445ece8a530Spatrick }
446ece8a530Spatrick 
447ece8a530Spatrick // Print out a log message for --trace-symbol.
printTraceSymbol(Symbol * sym)448ece8a530Spatrick void printTraceSymbol(Symbol *sym) {
449ece8a530Spatrick   // Undefined symbols are traced via printTraceSymbolUndefined
450ece8a530Spatrick   if (sym->isUndefined())
451ece8a530Spatrick     return;
452ece8a530Spatrick 
453ece8a530Spatrick   std::string s;
454ece8a530Spatrick   if (sym->isLazy())
455ece8a530Spatrick     s = ": lazy definition of ";
456ece8a530Spatrick   else
457ece8a530Spatrick     s = ": definition of ";
458ece8a530Spatrick 
459ece8a530Spatrick   message(toString(sym->getFile()) + s + sym->getName());
460ece8a530Spatrick }
461ece8a530Spatrick 
462ece8a530Spatrick const char *defaultModule = "env";
463ece8a530Spatrick const char *functionTableName = "__indirect_function_table";
464*dfe94b16Srobert const char *memoryName = "memory";
465ece8a530Spatrick 
466ece8a530Spatrick } // namespace wasm
467ece8a530Spatrick } // namespace lld
468