summaryrefslogtreecommitdiff
path: root/wasm/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'wasm/Symbols.cpp')
-rw-r--r--wasm/Symbols.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/wasm/Symbols.cpp b/wasm/Symbols.cpp
new file mode 100644
index 000000000000..6bf5459c2663
--- /dev/null
+++ b/wasm/Symbols.cpp
@@ -0,0 +1,114 @@
+//===- Symbols.cpp --------------------------------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Symbols.h"
+
+#include "Config.h"
+#include "InputFiles.h"
+#include "InputSegment.h"
+#include "lld/Common/ErrorHandler.h"
+#include "lld/Common/Strings.h"
+
+#define DEBUG_TYPE "lld"
+
+using namespace llvm;
+using namespace lld;
+using namespace lld::wasm;
+
+uint32_t Symbol::getGlobalIndex() const {
+ assert(!Sym->isFunction());
+ return Sym->ElementIndex;
+}
+
+uint32_t Symbol::getFunctionIndex() const {
+ assert(Sym->isFunction());
+ return Sym->ElementIndex;
+}
+
+const WasmSignature &Symbol::getFunctionType() const {
+ assert(FunctionType != nullptr);
+ return *FunctionType;
+}
+
+uint32_t Symbol::getVirtualAddress() const {
+ assert(isGlobal());
+ DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
+ if (isUndefined())
+ return UINT32_MAX;
+ if (VirtualAddress.hasValue())
+ return VirtualAddress.getValue();
+
+ 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);
+}
+
+uint32_t Symbol::getOutputIndex() const {
+ if (isUndefined() && isWeak())
+ return 0;
+ return OutputIndex.getValue();
+}
+
+void Symbol::setVirtualAddress(uint32_t Value) {
+ DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
+ assert(!VirtualAddress.hasValue());
+ VirtualAddress = Value;
+}
+
+void Symbol::setOutputIndex(uint32_t Index) {
+ DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n");
+ assert(!OutputIndex.hasValue());
+ OutputIndex = Index;
+}
+
+void Symbol::setTableIndex(uint32_t Index) {
+ DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
+ assert(!TableIndex.hasValue());
+ 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;
+}
+
+bool Symbol::isWeak() const { return Sym && Sym->isWeak(); }
+
+bool Symbol::isHidden() const { return Sym && Sym->isHidden(); }
+
+std::string lld::toString(const wasm::Symbol &Sym) {
+ if (Config->Demangle)
+ if (Optional<std::string> S = demangleItanium(Sym.getName()))
+ return "`" + *S + "'";
+ return Sym.getName();
+}
+
+std::string lld::toString(wasm::Symbol::Kind Kind) {
+ switch (Kind) {
+ case wasm::Symbol::DefinedFunctionKind:
+ return "DefinedFunction";
+ case wasm::Symbol::DefinedGlobalKind:
+ return "DefinedGlobal";
+ case wasm::Symbol::UndefinedFunctionKind:
+ return "UndefinedFunction";
+ case wasm::Symbol::UndefinedGlobalKind:
+ return "UndefinedGlobal";
+ case wasm::Symbol::LazyKind:
+ return "LazyKind";
+ }
+ llvm_unreachable("Invalid symbol kind!");
+}