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
17using namespace llvm;
18using namespace llvm::jitlink;
19using namespace llvm::orc;
20
21namespace {
22
23bool 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
41namespace llvm::orc {
42
43LinkGraphLayer::~LinkGraphLayer() = default;
44
45MaterializationUnit::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
75JITSymbolFlags 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
92StringRef LinkGraphMaterializationUnit::getName() const { return G->getName(); }
93
94void 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