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(QualifiedName: Sec.getName())) |
31 | return true; |
32 | if (IsElf && isELFInitializerSection(SecName: 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&: *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(SymName: 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&: *Sym); |
101 | break; |
102 | } |
103 | } |
104 | |
105 | } // namespace llvm::orc |
106 |