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