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