1185222Ssam//===---- llvm-jitlink.h - Session and format-specific decls ----*- C++ -*-===//
2185222Ssam//
3185222Ssam// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4185222Ssam// See https://llvm.org/LICENSE.txt for license information.
5185222Ssam// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6185222Ssam//
7185222Ssam//===----------------------------------------------------------------------===//
8185222Ssam//
9185222Ssam// llvm-jitlink Session class and tool utilities.
10185222Ssam//
11185222Ssam//===----------------------------------------------------------------------===//
12185222Ssam
13185222Ssam#ifndef LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
14185222Ssam#define LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
15185222Ssam
16185222Ssam#include "llvm/ADT/Optional.h"
17185222Ssam#include "llvm/ADT/StringSet.h"
18185222Ssam#include "llvm/ADT/Triple.h"
19185222Ssam#include "llvm/ExecutionEngine/Orc/Core.h"
20185222Ssam#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
21185222Ssam#include "llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h"
22185222Ssam#include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
23185222Ssam#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
24185222Ssam#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
25185222Ssam#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
26185222Ssam#include "llvm/Support/Error.h"
27185222Ssam#include "llvm/Support/Regex.h"
28185222Ssam#include "llvm/Support/raw_ostream.h"
29185222Ssam
30185222Ssam#include <vector>
31185222Ssam
32185222Ssamnamespace llvm {
33185222Ssam
34185222Ssamstruct Session;
35185222Ssam
36186334Ssam/// ObjectLinkingLayer with additional support for symbol promotion.
37186334Ssamclass LLVMJITLinkObjectLinkingLayer : public orc::ObjectLinkingLayer {
38185222Ssampublic:
39185222Ssam  using orc::ObjectLinkingLayer::add;
40185222Ssam
41185222Ssam  LLVMJITLinkObjectLinkingLayer(Session &S,
42185222Ssam                                jitlink::JITLinkMemoryManager &MemMgr);
43185222Ssam
44185222Ssam  Error add(orc::ResourceTrackerSP RT,
45185222Ssam            std::unique_ptr<MemoryBuffer> O) override;
46185222Ssam
47185222Ssamprivate:
48185222Ssam  Session &S;
49185222Ssam};
50185222Ssam
51185222Ssamusing LLVMJITLinkChannel = orc::shared::FDRawByteChannel;
52185222Ssamusing LLVMJITLinkRPCEndpoint =
53185222Ssam    orc::shared::MultiThreadedRPCEndpoint<LLVMJITLinkChannel>;
54185222Ssamusing LLVMJITLinkRemoteMemoryAccess =
55185222Ssam    orc::OrcRPCTPCMemoryAccess<LLVMJITLinkRPCEndpoint>;
56185222Ssam
57185222Ssamclass LLVMJITLinkRemoteTargetProcessControl
58185222Ssam    : public orc::OrcRPCTargetProcessControlBase<LLVMJITLinkRPCEndpoint> {
59185222Ssampublic:
60185222Ssam  using BaseT = orc::OrcRPCTargetProcessControlBase<LLVMJITLinkRPCEndpoint>;
61185222Ssam  static Expected<std::unique_ptr<TargetProcessControl>> LaunchExecutor();
62185222Ssam
63185222Ssam  static Expected<std::unique_ptr<TargetProcessControl>> ConnectToExecutor();
64185222Ssam
65185222Ssam  Error disconnect() override;
66185222Ssam
67185222Ssamprivate:
68  using LLVMJITLinkRemoteMemoryAccess =
69      orc::OrcRPCTPCMemoryAccess<LLVMJITLinkRemoteTargetProcessControl>;
70
71  using LLVMJITLinkRemoteMemoryManager =
72      orc::OrcRPCTPCJITLinkMemoryManager<LLVMJITLinkRemoteTargetProcessControl>;
73
74  LLVMJITLinkRemoteTargetProcessControl(
75      std::shared_ptr<orc::SymbolStringPool> SSP,
76      std::unique_ptr<LLVMJITLinkChannel> Channel,
77      std::unique_ptr<LLVMJITLinkRPCEndpoint> Endpoint,
78      ErrorReporter ReportError, Error &Err)
79      : BaseT(std::move(SSP), *Endpoint, std::move(ReportError)),
80        Channel(std::move(Channel)), Endpoint(std::move(Endpoint)) {
81    ErrorAsOutParameter _(&Err);
82
83    ListenerThread = std::thread([&]() {
84      while (!Finished) {
85        if (auto Err = this->Endpoint->handleOne()) {
86          reportError(std::move(Err));
87          return;
88        }
89      }
90    });
91
92    if (auto Err2 = initializeORCRPCTPCBase()) {
93      Err = joinErrors(std::move(Err2), disconnect());
94      return;
95    }
96
97    OwnedMemAccess = std::make_unique<LLVMJITLinkRemoteMemoryAccess>(*this);
98    MemAccess = OwnedMemAccess.get();
99    OwnedMemMgr = std::make_unique<LLVMJITLinkRemoteMemoryManager>(*this);
100    MemMgr = OwnedMemMgr.get();
101  }
102
103  std::unique_ptr<LLVMJITLinkChannel> Channel;
104  std::unique_ptr<LLVMJITLinkRPCEndpoint> Endpoint;
105  std::unique_ptr<TargetProcessControl::MemoryAccess> OwnedMemAccess;
106  std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
107  std::atomic<bool> Finished{false};
108  std::thread ListenerThread;
109};
110
111struct Session {
112  std::unique_ptr<orc::TargetProcessControl> TPC;
113  orc::ExecutionSession ES;
114  orc::JITDylib *MainJD;
115  LLVMJITLinkObjectLinkingLayer ObjLayer;
116  std::vector<orc::JITDylib *> JDSearchOrder;
117
118  ~Session();
119
120  static Expected<std::unique_ptr<Session>> Create(Triple TT);
121  void dumpSessionInfo(raw_ostream &OS);
122  void modifyPassConfig(const Triple &FTT,
123                        jitlink::PassConfiguration &PassConfig);
124
125  using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo;
126
127  struct FileInfo {
128    StringMap<MemoryRegionInfo> SectionInfos;
129    StringMap<MemoryRegionInfo> StubInfos;
130    StringMap<MemoryRegionInfo> GOTEntryInfos;
131  };
132
133  using SymbolInfoMap = StringMap<MemoryRegionInfo>;
134  using FileInfoMap = StringMap<FileInfo>;
135
136  Expected<FileInfo &> findFileInfo(StringRef FileName);
137  Expected<MemoryRegionInfo &> findSectionInfo(StringRef FileName,
138                                               StringRef SectionName);
139  Expected<MemoryRegionInfo &> findStubInfo(StringRef FileName,
140                                            StringRef TargetName);
141  Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
142                                                StringRef TargetName);
143
144  bool isSymbolRegistered(StringRef Name);
145  Expected<MemoryRegionInfo &> findSymbolInfo(StringRef SymbolName,
146                                              Twine ErrorMsgStem);
147
148  SymbolInfoMap SymbolInfos;
149  FileInfoMap FileInfos;
150  uint64_t SizeBeforePruning = 0;
151  uint64_t SizeAfterFixups = 0;
152
153  StringSet<> HarnessFiles;
154  StringSet<> HarnessExternals;
155  StringSet<> HarnessDefinitions;
156  DenseMap<StringRef, StringRef> CanonicalWeakDefs;
157
158private:
159  Session(std::unique_ptr<orc::TargetProcessControl> TPC, Error &Err);
160};
161
162/// Record symbols, GOT entries, stubs, and sections for ELF file.
163Error registerELFGraphInfo(Session &S, jitlink::LinkGraph &G);
164
165/// Record symbols, GOT entries, stubs, and sections for MachO file.
166Error registerMachOGraphInfo(Session &S, jitlink::LinkGraph &G);
167
168} // end namespace llvm
169
170#endif // LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
171