diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:08:33 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:08:33 +0000 |
| commit | 20d35e67e67f106f617c939725101223211659f0 (patch) | |
| tree | 64eb963cbf5ba58765e0a6b64a440965d66a7a4d /wasm/Symbols.cpp | |
| parent | ae1a339de31cf4065777531959a11e55a2e5fa00 (diff) | |
Notes
Diffstat (limited to 'wasm/Symbols.cpp')
| -rw-r--r-- | wasm/Symbols.cpp | 240 |
1 files changed, 189 insertions, 51 deletions
diff --git a/wasm/Symbols.cpp b/wasm/Symbols.cpp index 6bf5459c26633..a11081cbcf779 100644 --- a/wasm/Symbols.cpp +++ b/wasm/Symbols.cpp @@ -8,92 +8,224 @@ //===----------------------------------------------------------------------===// #include "Symbols.h" - #include "Config.h" +#include "InputChunks.h" #include "InputFiles.h" -#include "InputSegment.h" +#include "InputGlobal.h" +#include "OutputSegment.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Strings.h" #define DEBUG_TYPE "lld" using namespace llvm; +using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -uint32_t Symbol::getGlobalIndex() const { - assert(!Sym->isFunction()); - return Sym->ElementIndex; +DefinedFunction *WasmSym::CallCtors; +DefinedData *WasmSym::DsoHandle; +DefinedData *WasmSym::DataEnd; +DefinedData *WasmSym::HeapBase; +DefinedGlobal *WasmSym::StackPointer; + +WasmSymbolType Symbol::getWasmType() const { + if (isa<FunctionSymbol>(this)) + return WASM_SYMBOL_TYPE_FUNCTION; + if (isa<DataSymbol>(this)) + return WASM_SYMBOL_TYPE_DATA; + if (isa<GlobalSymbol>(this)) + return WASM_SYMBOL_TYPE_GLOBAL; + if (isa<SectionSymbol>(this)) + return WASM_SYMBOL_TYPE_SECTION; + llvm_unreachable("invalid symbol kind"); +} + +InputChunk *Symbol::getChunk() const { + if (auto *F = dyn_cast<DefinedFunction>(this)) + return F->Function; + if (auto *D = dyn_cast<DefinedData>(this)) + return D->Segment; + return nullptr; +} + +bool Symbol::isLive() const { + if (auto *G = dyn_cast<DefinedGlobal>(this)) + return G->Global->Live; + if (InputChunk *C = getChunk()) + return C->Live; + return Referenced; } -uint32_t Symbol::getFunctionIndex() const { - assert(Sym->isFunction()); - return Sym->ElementIndex; +void Symbol::markLive() { + if (auto *G = dyn_cast<DefinedGlobal>(this)) + G->Global->Live = true; + if (InputChunk *C = getChunk()) + C->Live = true; + Referenced = true; } -const WasmSignature &Symbol::getFunctionType() const { - assert(FunctionType != nullptr); - return *FunctionType; +uint32_t Symbol::getOutputSymbolIndex() const { + assert(OutputSymbolIndex != INVALID_INDEX); + return OutputSymbolIndex; } -uint32_t Symbol::getVirtualAddress() const { - assert(isGlobal()); - DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); - if (isUndefined()) - return UINT32_MAX; - if (VirtualAddress.hasValue()) - return VirtualAddress.getValue(); +void Symbol::setOutputSymbolIndex(uint32_t Index) { + LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index + << "\n"); + assert(OutputSymbolIndex == INVALID_INDEX); + OutputSymbolIndex = Index; +} + +bool Symbol::isWeak() const { + return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK; +} - assert(Sym != nullptr); - ObjFile *Obj = cast<ObjFile>(File); - const WasmGlobal &Global = - Obj->getWasmObj()->globals()[getGlobalIndex() - Obj->NumGlobalImports()]; - assert(Global.Type == llvm::wasm::WASM_TYPE_I32); - assert(Segment); - return Segment->translateVA(Global.InitExpr.Value.Int32); +bool Symbol::isLocal() const { + return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL; } -uint32_t Symbol::getOutputIndex() const { - if (isUndefined() && isWeak()) - return 0; - return OutputIndex.getValue(); +bool Symbol::isHidden() const { + return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN; } -void Symbol::setVirtualAddress(uint32_t Value) { - DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); - assert(!VirtualAddress.hasValue()); - VirtualAddress = Value; +void Symbol::setHidden(bool IsHidden) { + LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n"); + Flags &= ~WASM_SYMBOL_VISIBILITY_MASK; + if (IsHidden) + Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; + else + Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; } -void Symbol::setOutputIndex(uint32_t Index) { - DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); - assert(!OutputIndex.hasValue()); - OutputIndex = Index; +bool Symbol::isExported() const { + if (!isDefined() || isLocal()) + return false; + + if (ForceExport || Config->ExportAll) + return true; + + return !isHidden(); } -void Symbol::setTableIndex(uint32_t Index) { - DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); - assert(!TableIndex.hasValue()); +uint32_t FunctionSymbol::getFunctionIndex() const { + if (auto *F = dyn_cast<DefinedFunction>(this)) + return F->Function->getFunctionIndex(); + assert(FunctionIndex != INVALID_INDEX); + return FunctionIndex; +} + +void FunctionSymbol::setFunctionIndex(uint32_t Index) { + LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n"); + assert(FunctionIndex == INVALID_INDEX); + FunctionIndex = Index; +} + +bool FunctionSymbol::hasFunctionIndex() const { + if (auto *F = dyn_cast<DefinedFunction>(this)) + return F->Function->hasFunctionIndex(); + return FunctionIndex != INVALID_INDEX; +} + +uint32_t FunctionSymbol::getTableIndex() const { + if (auto *F = dyn_cast<DefinedFunction>(this)) + return F->Function->getTableIndex(); + assert(TableIndex != INVALID_INDEX); + return TableIndex; +} + +bool FunctionSymbol::hasTableIndex() const { + if (auto *F = dyn_cast<DefinedFunction>(this)) + return F->Function->hasTableIndex(); + return TableIndex != INVALID_INDEX; +} + +void FunctionSymbol::setTableIndex(uint32_t Index) { + // For imports, we set the table index here on the Symbol; for defined + // functions we set the index on the InputFunction so that we don't export + // the same thing twice (keeps the table size down). + if (auto *F = dyn_cast<DefinedFunction>(this)) { + F->Function->setTableIndex(Index); + return; + } + LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); + assert(TableIndex == INVALID_INDEX); TableIndex = Index; } -void Symbol::update(Kind K, InputFile *F, const WasmSymbol *WasmSym, - const InputSegment *Seg, const WasmSignature *Sig) { - SymbolKind = K; - File = F; - Sym = WasmSym; - Segment = Seg; - FunctionType = Sig; +DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, + InputFunction *Function) + : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, + Function ? &Function->Signature : nullptr), + Function(Function) {} + +uint32_t DefinedData::getVirtualAddress() const { + LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); + if (Segment) + return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset; + return Offset; +} + +void DefinedData::setVirtualAddress(uint32_t Value) { + LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); + assert(!Segment); + Offset = Value; +} + +uint32_t DefinedData::getOutputSegmentOffset() const { + LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); + return Segment->OutputSegmentOffset + Offset; +} + +uint32_t DefinedData::getOutputSegmentIndex() const { + LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n"); + return Segment->OutputSeg->Index; +} + +uint32_t GlobalSymbol::getGlobalIndex() const { + if (auto *F = dyn_cast<DefinedGlobal>(this)) + return F->Global->getGlobalIndex(); + assert(GlobalIndex != INVALID_INDEX); + return GlobalIndex; +} + +void GlobalSymbol::setGlobalIndex(uint32_t Index) { + LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n"); + assert(GlobalIndex == INVALID_INDEX); + GlobalIndex = Index; +} + +bool GlobalSymbol::hasGlobalIndex() const { + if (auto *F = dyn_cast<DefinedGlobal>(this)) + return F->Global->hasGlobalIndex(); + return GlobalIndex != INVALID_INDEX; } -bool Symbol::isWeak() const { return Sym && Sym->isWeak(); } +DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, + InputGlobal *Global) + : GlobalSymbol(Name, DefinedGlobalKind, Flags, File, + Global ? &Global->getType() : nullptr), + Global(Global) {} + +uint32_t SectionSymbol::getOutputSectionIndex() const { + LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n"); + assert(OutputSectionIndex != INVALID_INDEX); + return OutputSectionIndex; +} + +void SectionSymbol::setOutputSectionIndex(uint32_t Index) { + LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index + << "\n"); + assert(Index != INVALID_INDEX); + OutputSectionIndex = Index; +} -bool Symbol::isHidden() const { return Sym && Sym->isHidden(); } +void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); } std::string lld::toString(const wasm::Symbol &Sym) { if (Config->Demangle) if (Optional<std::string> S = demangleItanium(Sym.getName())) - return "`" + *S + "'"; + return *S; return Sym.getName(); } @@ -101,14 +233,20 @@ std::string lld::toString(wasm::Symbol::Kind Kind) { switch (Kind) { case wasm::Symbol::DefinedFunctionKind: return "DefinedFunction"; + case wasm::Symbol::DefinedDataKind: + return "DefinedData"; case wasm::Symbol::DefinedGlobalKind: return "DefinedGlobal"; case wasm::Symbol::UndefinedFunctionKind: return "UndefinedFunction"; + case wasm::Symbol::UndefinedDataKind: + return "UndefinedData"; case wasm::Symbol::UndefinedGlobalKind: return "UndefinedGlobal"; case wasm::Symbol::LazyKind: return "LazyKind"; + case wasm::Symbol::SectionKind: + return "SectionKind"; } - llvm_unreachable("Invalid symbol kind!"); + llvm_unreachable("invalid symbol kind"); } |
