| //===----- 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 |