diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp | 105 |
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 |