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