aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp b/llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp
new file mode 100644
index 0000000..5789079
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp
@@ -0,0 +1,105 @@
+//===----- LinkGraphLayer.cpp - Add LinkGraphs to an ExecutionSession -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/LinkGraphLayer.h"
+
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h"
+#include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"
+
+#define DEBUG_TYPE "orc"
+
+using namespace llvm;
+using namespace llvm::jitlink;
+using namespace llvm::orc;
+
+namespace {
+
+bool hasInitializerSection(LinkGraph &G) {
+ bool IsMachO = G.getTargetTriple().isOSBinFormatMachO();
+ bool IsElf = G.getTargetTriple().isOSBinFormatELF();
+ if (!IsMachO && !IsElf)
+ return false;
+
+ for (auto &Sec : G.sections()) {
+ if (IsMachO && isMachOInitializerSection(Sec.getName()))
+ return true;
+ if (IsElf && isELFInitializerSection(Sec.getName()))
+ return true;
+ }
+
+ return false;
+}
+
+} // end anonymous namespace
+
+namespace llvm::orc {
+
+LinkGraphLayer::~LinkGraphLayer() = default;
+
+MaterializationUnit::Interface LinkGraphLayer::getInterface(LinkGraph &G) {
+
+ MaterializationUnit::Interface LGI;
+
+ auto AddSymbol = [&](Symbol *Sym) {
+ // Skip local symbols.
+ if (Sym->getScope() == Scope::Local)
+ return;
+ assert(Sym->hasName() && "Anonymous non-local symbol?");
+
+ LGI.SymbolFlags[Sym->getName()] = getJITSymbolFlagsForSymbol(*Sym);
+ };
+
+ for (auto *Sym : G.defined_symbols())
+ AddSymbol(Sym);
+ for (auto *Sym : G.absolute_symbols())
+ AddSymbol(Sym);
+
+ if (hasInitializerSection(G)) {
+ std::string InitSymString;
+ {
+ raw_string_ostream(InitSymString)
+ << "$." << G.getName() << ".__inits" << Counter++;
+ }
+ LGI.InitSymbol = ES.intern(InitSymString);
+ }
+
+ return LGI;
+}
+
+JITSymbolFlags LinkGraphLayer::getJITSymbolFlagsForSymbol(Symbol &Sym) {
+ JITSymbolFlags Flags;
+
+ if (Sym.getLinkage() == Linkage::Weak)
+ Flags |= JITSymbolFlags::Weak;
+
+ if (Sym.getScope() == Scope::Default)
+ Flags |= JITSymbolFlags::Exported;
+ else if (Sym.getScope() == Scope::SideEffectsOnly)
+ Flags |= JITSymbolFlags::MaterializationSideEffectsOnly;
+
+ if (Sym.isCallable())
+ Flags |= JITSymbolFlags::Callable;
+
+ return Flags;
+}
+
+StringRef LinkGraphMaterializationUnit::getName() const { return G->getName(); }
+
+void LinkGraphMaterializationUnit::discard(const JITDylib &JD,
+ const SymbolStringPtr &Name) {
+ for (auto *Sym : G->defined_symbols())
+ if (Sym->getName() == Name) {
+ assert(Sym->getLinkage() == Linkage::Weak &&
+ "Discarding non-weak definition");
+ G->makeExternal(*Sym);
+ break;
+ }
+}
+
+} // namespace llvm::orc