xref: /llvm-project/llvm/lib/ExecutionEngine/Orc/LinkGraphLayer.cpp (revision b3d2548d5b04ed3b7aaedfd22e62da40875c0f31)
1*b3d2548dSLang Hames //===----- LinkGraphLayer.cpp - Add LinkGraphs to an ExecutionSession -----===//
2*b3d2548dSLang Hames //
3*b3d2548dSLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*b3d2548dSLang Hames // See https://llvm.org/LICENSE.txt for license information.
5*b3d2548dSLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*b3d2548dSLang Hames //
7*b3d2548dSLang Hames //===----------------------------------------------------------------------===//
8*b3d2548dSLang Hames 
9*b3d2548dSLang Hames #include "llvm/ExecutionEngine/Orc/LinkGraphLayer.h"
10*b3d2548dSLang Hames 
11*b3d2548dSLang Hames #include "llvm/ExecutionEngine/JITLink/JITLink.h"
12*b3d2548dSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h"
13*b3d2548dSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"
14*b3d2548dSLang Hames 
15*b3d2548dSLang Hames #define DEBUG_TYPE "orc"
16*b3d2548dSLang Hames 
17*b3d2548dSLang Hames using namespace llvm;
18*b3d2548dSLang Hames using namespace llvm::jitlink;
19*b3d2548dSLang Hames using namespace llvm::orc;
20*b3d2548dSLang Hames 
21*b3d2548dSLang Hames namespace {
22*b3d2548dSLang Hames 
23*b3d2548dSLang Hames bool hasInitializerSection(LinkGraph &G) {
24*b3d2548dSLang Hames   bool IsMachO = G.getTargetTriple().isOSBinFormatMachO();
25*b3d2548dSLang Hames   bool IsElf = G.getTargetTriple().isOSBinFormatELF();
26*b3d2548dSLang Hames   if (!IsMachO && !IsElf)
27*b3d2548dSLang Hames     return false;
28*b3d2548dSLang Hames 
29*b3d2548dSLang Hames   for (auto &Sec : G.sections()) {
30*b3d2548dSLang Hames     if (IsMachO && isMachOInitializerSection(Sec.getName()))
31*b3d2548dSLang Hames       return true;
32*b3d2548dSLang Hames     if (IsElf && isELFInitializerSection(Sec.getName()))
33*b3d2548dSLang Hames       return true;
34*b3d2548dSLang Hames   }
35*b3d2548dSLang Hames 
36*b3d2548dSLang Hames   return false;
37*b3d2548dSLang Hames }
38*b3d2548dSLang Hames 
39*b3d2548dSLang Hames } // end anonymous namespace
40*b3d2548dSLang Hames 
41*b3d2548dSLang Hames namespace llvm::orc {
42*b3d2548dSLang Hames 
43*b3d2548dSLang Hames LinkGraphLayer::~LinkGraphLayer() = default;
44*b3d2548dSLang Hames 
45*b3d2548dSLang Hames MaterializationUnit::Interface LinkGraphLayer::getInterface(LinkGraph &G) {
46*b3d2548dSLang Hames 
47*b3d2548dSLang Hames   MaterializationUnit::Interface LGI;
48*b3d2548dSLang Hames 
49*b3d2548dSLang Hames   auto AddSymbol = [&](Symbol *Sym) {
50*b3d2548dSLang Hames     // Skip local symbols.
51*b3d2548dSLang Hames     if (Sym->getScope() == Scope::Local)
52*b3d2548dSLang Hames       return;
53*b3d2548dSLang Hames     assert(Sym->hasName() && "Anonymous non-local symbol?");
54*b3d2548dSLang Hames 
55*b3d2548dSLang Hames     LGI.SymbolFlags[Sym->getName()] = getJITSymbolFlagsForSymbol(*Sym);
56*b3d2548dSLang Hames   };
57*b3d2548dSLang Hames 
58*b3d2548dSLang Hames   for (auto *Sym : G.defined_symbols())
59*b3d2548dSLang Hames     AddSymbol(Sym);
60*b3d2548dSLang Hames   for (auto *Sym : G.absolute_symbols())
61*b3d2548dSLang Hames     AddSymbol(Sym);
62*b3d2548dSLang Hames 
63*b3d2548dSLang Hames   if (hasInitializerSection(G)) {
64*b3d2548dSLang Hames     std::string InitSymString;
65*b3d2548dSLang Hames     {
66*b3d2548dSLang Hames       raw_string_ostream(InitSymString)
67*b3d2548dSLang Hames           << "$." << G.getName() << ".__inits" << Counter++;
68*b3d2548dSLang Hames     }
69*b3d2548dSLang Hames     LGI.InitSymbol = ES.intern(InitSymString);
70*b3d2548dSLang Hames   }
71*b3d2548dSLang Hames 
72*b3d2548dSLang Hames   return LGI;
73*b3d2548dSLang Hames }
74*b3d2548dSLang Hames 
75*b3d2548dSLang Hames JITSymbolFlags LinkGraphLayer::getJITSymbolFlagsForSymbol(Symbol &Sym) {
76*b3d2548dSLang Hames   JITSymbolFlags Flags;
77*b3d2548dSLang Hames 
78*b3d2548dSLang Hames   if (Sym.getLinkage() == Linkage::Weak)
79*b3d2548dSLang Hames     Flags |= JITSymbolFlags::Weak;
80*b3d2548dSLang Hames 
81*b3d2548dSLang Hames   if (Sym.getScope() == Scope::Default)
82*b3d2548dSLang Hames     Flags |= JITSymbolFlags::Exported;
83*b3d2548dSLang Hames   else if (Sym.getScope() == Scope::SideEffectsOnly)
84*b3d2548dSLang Hames     Flags |= JITSymbolFlags::MaterializationSideEffectsOnly;
85*b3d2548dSLang Hames 
86*b3d2548dSLang Hames   if (Sym.isCallable())
87*b3d2548dSLang Hames     Flags |= JITSymbolFlags::Callable;
88*b3d2548dSLang Hames 
89*b3d2548dSLang Hames   return Flags;
90*b3d2548dSLang Hames }
91*b3d2548dSLang Hames 
92*b3d2548dSLang Hames StringRef LinkGraphMaterializationUnit::getName() const { return G->getName(); }
93*b3d2548dSLang Hames 
94*b3d2548dSLang Hames void LinkGraphMaterializationUnit::discard(const JITDylib &JD,
95*b3d2548dSLang Hames                                            const SymbolStringPtr &Name) {
96*b3d2548dSLang Hames   for (auto *Sym : G->defined_symbols())
97*b3d2548dSLang Hames     if (Sym->getName() == Name) {
98*b3d2548dSLang Hames       assert(Sym->getLinkage() == Linkage::Weak &&
99*b3d2548dSLang Hames              "Discarding non-weak definition");
100*b3d2548dSLang Hames       G->makeExternal(*Sym);
101*b3d2548dSLang Hames       break;
102*b3d2548dSLang Hames     }
103*b3d2548dSLang Hames }
104*b3d2548dSLang Hames 
105*b3d2548dSLang Hames } // namespace llvm::orc
106