+217
-4
lines changedFilter options
+217
-4
lines changed Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
25
25
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
26
26
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
27
27
#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
28
+
#include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h"
28
29
#include "llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h"
29
30
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
30
31
#include "llvm/Support/InitLLVM.h"
@@ -51,17 +52,23 @@ ExitOnError ExitOnErr;
51
52
52
53
const llvm::StringRef FooMod =
53
54
R"(
55
+
declare i32 @return1()
56
+
54
57
define i32 @foo_body() {
55
58
entry:
56
-
ret i32 1
59
+
%0 = call i32 @return1()
60
+
ret i32 %0
57
61
}
58
62
)";
59
63
60
64
const llvm::StringRef BarMod =
61
65
R"(
66
+
declare i32 @return2()
67
+
62
68
define i32 @bar_body() {
63
69
entry:
64
-
ret i32 2
70
+
%0 = call i32 @return2()
71
+
ret i32 %0
65
72
}
66
73
)";
67
74
@@ -91,6 +98,9 @@ const llvm::StringRef MainMod =
91
98
declare i32 @bar()
92
99
)";
93
100
101
+
extern "C" int32_t return1() { return 1; }
102
+
extern "C" int32_t return2() { return 2; }
103
+
94
104
static void *reenter(void *Ctx, void *TrampolineAddr) {
95
105
std::promise<void *> LandingAddressP;
96
106
auto LandingAddressF = LandingAddressP.get_future();
@@ -105,6 +115,11 @@ static void *reenter(void *Ctx, void *TrampolineAddr) {
105
115
return LandingAddressF.get();
106
116
}
107
117
118
+
static void reportErrorAndExit() {
119
+
errs() << "Unable to lazily compile function. Exiting.\n";
120
+
exit(1);
121
+
}
122
+
108
123
cl::list<std::string> InputArgv(cl::Positional,
109
124
cl::desc("<program arguments>..."));
110
125
@@ -135,8 +150,11 @@ int main(int argc, char *argv[]) {
135
150
auto TPCIU = ExitOnErr(TPCIndirectionUtils::Create(*TPC));
136
151
ExitOnErr(TPCIU->writeResolverBlock(pointerToJITTargetAddress(&reenter),
137
152
pointerToJITTargetAddress(TPCIU.get())));
138
-
TPCIU->createLazyCallThroughManager(J->getExecutionSession(), 0);
153
+
TPCIU->createLazyCallThroughManager(
154
+
J->getExecutionSession(), pointerToJITTargetAddress(&reportErrorAndExit));
139
155
auto ISM = TPCIU->createIndirectStubsManager();
156
+
J->getMainJITDylib().addGenerator(
157
+
ExitOnErr(TPCDynamicLibrarySearchGenerator::GetForTargetProcess(*TPC)));
140
158
141
159
// (4) Add modules.
142
160
ExitOnErr(J->addIRModule(ExitOnErr(parseExampleModule(FooMod, "foo-mod"))));
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
1
+
//===------------ TPCDynamicLibrarySearchGenerator.h ------------*- C++ -*-===//
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
+
// Support loading and searching of dynamic libraries in a target process via
10
+
// the TargetProcessControl class.
11
+
//
12
+
//===----------------------------------------------------------------------===//
13
+
14
+
#ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
15
+
#define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
16
+
17
+
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
18
+
19
+
namespace llvm {
20
+
namespace orc {
21
+
22
+
class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator {
23
+
public:
24
+
/// Create a DynamicLibrarySearchGenerator that searches for symbols in the
25
+
/// library with the given handle.
26
+
///
27
+
/// If the Allow predicate is given then only symbols matching the predicate
28
+
/// will be searched for. If the predicate is not given then all symbols will
29
+
/// be searched for.
30
+
TPCDynamicLibrarySearchGenerator(
31
+
TargetProcessControl &TPC,
32
+
TargetProcessControl::DynamicLibraryHandle DylibHandle)
33
+
: TPC(TPC), DylibHandle(DylibHandle) {}
34
+
35
+
/// Permanently loads the library at the given path and, on success, returns
36
+
/// a DynamicLibrarySearchGenerator that will search it for symbol definitions
37
+
/// in the library. On failure returns the reason the library failed to load.
38
+
static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
39
+
Load(TargetProcessControl &TPC, const char *LibraryPath);
40
+
41
+
/// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in
42
+
/// the target process.
43
+
static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
44
+
GetForTargetProcess(TargetProcessControl &TPC) {
45
+
return Load(TPC, nullptr);
46
+
}
47
+
48
+
Error tryToGenerate(LookupKind K, JITDylib &JD,
49
+
JITDylibLookupFlags JDLookupFlags,
50
+
const SymbolLookupSet &Symbols) override;
51
+
52
+
private:
53
+
TargetProcessControl &TPC;
54
+
TargetProcessControl::DynamicLibraryHandle DylibHandle;
55
+
};
56
+
57
+
} // end namespace orc
58
+
} // end namespace llvm
59
+
60
+
#endif // LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
Original file line number Diff line number Diff line change
@@ -13,11 +13,16 @@
13
13
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
14
14
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
15
15
16
+
#include "llvm/ADT/Optional.h"
17
+
#include "llvm/ADT/StringRef.h"
16
18
#include "llvm/ADT/Triple.h"
17
19
#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
20
+
#include "llvm/ExecutionEngine/Orc/Core.h"
21
+
#include "llvm/Support/DynamicLibrary.h"
18
22
#include "llvm/Support/MSVCErrorWorkarounds.h"
19
23
20
24
#include <future>
25
+
#include <vector>
21
26
22
27
namespace llvm {
23
28
namespace orc {
@@ -105,6 +110,22 @@ class TargetProcessControl {
105
110
}
106
111
};
107
112
113
+
using DynamicLibraryHandle = JITTargetAddress;
114
+
115
+
/// Request lookup within a single library.
116
+
/// If Library is None then the whole target process should be searched.
117
+
struct LookupRequestElement {
118
+
LookupRequestElement(DynamicLibraryHandle Handle,
119
+
const SymbolLookupSet &Symbols)
120
+
: Handle(Handle), Symbols(Symbols) {}
121
+
DynamicLibraryHandle Handle;
122
+
const SymbolLookupSet &Symbols;
123
+
};
124
+
125
+
using LookupRequest = ArrayRef<LookupRequestElement>;
126
+
127
+
using LookupResult = std::vector<std::vector<JITTargetAddress>>;
128
+
108
129
virtual ~TargetProcessControl();
109
130
110
131
/// Return the Triple for the target process.
@@ -119,7 +140,16 @@ class TargetProcessControl {
119
140
/// Return a MemoryAccess object for the target process.
120
141
MemoryAccess &getMemoryAccess() const { return *MemAccess; }
121
142
122
-
/// Load the library at the given path.
143
+
/// Load the library at the given path. Returns a handle to the loaded
144
+
/// library. If LibraryPath is null this function will return the global
145
+
/// handle for the target process.
146
+
virtual Expected<DynamicLibraryHandle>
147
+
loadLibrary(const char *LibraryPath) = 0;
148
+
149
+
/// Search for symbols in the target process.
150
+
/// The result of the lookup is a 2-dimentional array of target addresses
151
+
/// that correspond to the lookup order.
152
+
virtual Expected<LookupResult> lookupSymbols(LookupRequest Request) = 0;
123
153
124
154
protected:
125
155
TargetProcessControl(Triple TT, unsigned PageSize);
@@ -138,6 +168,10 @@ class SelfTargetProcessControl : public TargetProcessControl,
138
168
139
169
static Expected<std::unique_ptr<SelfTargetProcessControl>> Create();
140
170
171
+
Expected<DynamicLibraryHandle> loadLibrary(const char *LibraryPath) override;
172
+
173
+
Expected<LookupResult> lookupSymbols(LookupRequest Request) override;
174
+
141
175
private:
142
176
void writeUInt8s(ArrayRef<UInt8Write> Ws,
143
177
WriteResultFn OnWriteComplete) override;
@@ -156,6 +190,9 @@ class SelfTargetProcessControl : public TargetProcessControl,
156
190
157
191
std::unique_ptr<jitlink::InProcessMemoryManager> IPMM =
158
192
std::make_unique<jitlink::InProcessMemoryManager>();
193
+
194
+
char GlobalManglingPrefix = 0;
195
+
std::vector<std::unique_ptr<sys::DynamicLibrary>> DynamicLibraries;
159
196
};
160
197
161
198
} // end namespace orc
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ add_llvm_component_library(LLVMOrcJIT
26
26
SpeculateAnalyses.cpp
27
27
TargetProcessControl.cpp
28
28
ThreadSafeModule.cpp
29
+
TPCDynamicLibrarySearchGenerator.cpp
29
30
TPCIndirectionUtils.cpp
30
31
ADDITIONAL_HEADER_DIRS
31
32
${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/Orc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
1
+
//===---------------- TPCDynamicLibrarySearchGenerator.cpp ----------------===//
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/TPCDynamicLibrarySearchGenerator.h"
10
+
11
+
namespace llvm {
12
+
namespace orc {
13
+
14
+
Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
15
+
TPCDynamicLibrarySearchGenerator::Load(TargetProcessControl &TPC,
16
+
const char *LibraryPath) {
17
+
auto Handle = TPC.loadLibrary(LibraryPath);
18
+
if (!Handle)
19
+
return Handle.takeError();
20
+
21
+
return std::make_unique<TPCDynamicLibrarySearchGenerator>(TPC, *Handle);
22
+
}
23
+
24
+
Error TPCDynamicLibrarySearchGenerator::tryToGenerate(
25
+
LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
26
+
const SymbolLookupSet &Symbols) {
27
+
28
+
if (Symbols.empty())
29
+
return Error::success();
30
+
31
+
SymbolMap NewSymbols;
32
+
33
+
TargetProcessControl::LookupRequestElement Request(DylibHandle, Symbols);
34
+
auto Result = TPC.lookupSymbols(Request);
35
+
if (!Result)
36
+
return Result.takeError();
37
+
38
+
assert(Result->size() == 1 && "Results for more than one library returned");
39
+
assert(Result->front().size() == Symbols.size() &&
40
+
"Result has incorrect number of elements");
41
+
42
+
auto ResultI = Result->front().begin();
43
+
for (auto &KV : Symbols)
44
+
NewSymbols[KV.first] =
45
+
JITEvaluatedSymbol(*ResultI++, JITSymbolFlags::Exported);
46
+
47
+
return JD.define(absoluteSymbols(std::move(NewSymbols)));
48
+
}
49
+
50
+
} // end namespace orc
51
+
} // end namespace llvm
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@
7
7
//===----------------------------------------------------------------------===//
8
8
9
9
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
10
+
11
+
#include "llvm/ExecutionEngine/Orc/Core.h"
10
12
#include "llvm/Support/Host.h"
11
13
#include "llvm/Support/Process.h"
12
14
@@ -26,6 +28,8 @@ SelfTargetProcessControl::SelfTargetProcessControl(Triple TT, unsigned PageSize)
26
28
: TargetProcessControl(std::move(TT), PageSize) {
27
29
this->MemMgr = IPMM.get();
28
30
this->MemAccess = this;
31
+
if (this->TT.isOSBinFormatMachO())
32
+
GlobalManglingPrefix = '_';
29
33
}
30
34
31
35
Expected<std::unique_ptr<SelfTargetProcessControl>>
@@ -39,6 +43,48 @@ SelfTargetProcessControl::Create() {
39
43
return std::make_unique<SelfTargetProcessControl>(std::move(TT), *PageSize);
40
44
}
41
45
46
+
Expected<TargetProcessControl::DynamicLibraryHandle>
47
+
SelfTargetProcessControl::loadLibrary(const char *LibraryPath) {
48
+
std::string ErrMsg;
49
+
auto Dylib = std::make_unique<sys::DynamicLibrary>(
50
+
sys::DynamicLibrary::getPermanentLibrary(LibraryPath, &ErrMsg));
51
+
if (!Dylib->isValid())
52
+
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
53
+
DynamicLibraries.push_back(std::move(Dylib));
54
+
return pointerToJITTargetAddress(DynamicLibraries.back().get());
55
+
}
56
+
57
+
Expected<TargetProcessControl::LookupResult>
58
+
SelfTargetProcessControl::lookupSymbols(LookupRequest Request) {
59
+
LookupResult R;
60
+
61
+
for (auto &Elem : Request) {
62
+
auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
63
+
assert(llvm::find_if(DynamicLibraries,
64
+
[=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
65
+
return DL.get() == Dylib;
66
+
}) != DynamicLibraries.end() &&
67
+
"Invalid handle");
68
+
69
+
R.push_back(std::vector<JITTargetAddress>());
70
+
for (auto &KV : Elem.Symbols) {
71
+
auto &Sym = KV.first;
72
+
std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
73
+
(*Sym).size() - !!GlobalManglingPrefix);
74
+
if (void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str()))
75
+
R.back().push_back(pointerToJITTargetAddress(Addr));
76
+
else if (KV.second == SymbolLookupFlags::RequiredSymbol) {
77
+
// FIXME: Collect all failing symbols before erroring out.
78
+
SymbolNameVector MissingSymbols;
79
+
MissingSymbols.push_back(Sym);
80
+
return make_error<SymbolsNotFound>(std::move(MissingSymbols));
81
+
}
82
+
}
83
+
}
84
+
85
+
return R;
86
+
}
87
+
42
88
void SelfTargetProcessControl::writeUInt8s(ArrayRef<UInt8Write> Ws,
43
89
WriteResultFn OnWriteComplete) {
44
90
for (auto &W : Ws)
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4