2
2
3
3
#include " clang/Interpreter/CppInterOp.h"
4
4
5
+
6
+ #include " llvm/ExecutionEngine/Orc/Core.h"
7
+ #include " llvm/ExecutionEngine/Orc/DebugUtils.h"
5
8
#include " llvm/Support/FileSystem.h"
6
9
#include " llvm/Support/Path.h"
7
-
10
+ # include " llvm/Support/raw_ostream.h "
8
11
9
12
// Helper functions
10
13
13
16
// GetMainExecutable (since some platforms don't support taking the
14
17
// address of main, and some platforms can't implement GetMainExecutable
15
18
// without being given the address of a function in the main executable).
16
- std::string GetExecutablePath (const char * Argv0) {
19
+ std::string GetExecutablePath (const char * Argv0, void * mainAddr = nullptr ) {
17
20
// This just needs to be some symbol in the binary; C++ doesn't
18
21
// allow taking the address of ::main however.
19
- void * MainAddr = (void *)intptr_t (GetExecutablePath);
22
+ void * MainAddr = mainAddr ? mainAddr : (void *)intptr_t (GetExecutablePath);
20
23
return llvm::sys::fs::getMainExecutable (Argv0, MainAddr);
21
24
}
22
25
26
+ // Mangle symbol name
23
27
static inline std::string MangleNameForDlsym (const std::string& name) {
24
28
std::string nameForDlsym = name;
25
29
#if defined(R__MACOSX) || defined(R__WIN32)
@@ -29,30 +33,33 @@ static inline std::string MangleNameForDlsym(const std::string& name) {
29
33
return nameForDlsym;
30
34
}
31
35
36
+ #include " ../../lib/Interpreter/CppInterOp.cpp"
37
+
38
+
32
39
// Tests
33
40
34
41
TEST (DynamicLibraryManagerTest, Sanity) {
35
42
EXPECT_TRUE (Cpp::CreateInterpreter ());
36
43
EXPECT_FALSE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_zero" ).c_str ()));
37
44
38
- std::string BinaryPath = GetExecutablePath (/* Argv0= */ nullptr );
45
+ std::string BinaryPath = GetExecutablePath (nullptr , nullptr );
39
46
llvm::StringRef Dir = llvm::sys::path::parent_path (BinaryPath);
40
47
Cpp::AddSearchPath (Dir.str ().c_str ());
41
48
49
+ // Find and load library with "ret_zero" symbol defined and exported
50
+ //
42
51
// FIXME: dlsym on mach-o takes the C-level name, however, the macho-o format
43
52
// adds an additional underscore (_) prefix to the lowered names. Figure out
44
53
// how to harmonize that API.
45
-
46
54
std::string PathToTestSharedLib =
47
55
Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_zero" ).c_str (), /* system_search=*/ false );
48
-
49
56
EXPECT_STRNE (" " , PathToTestSharedLib.c_str ())
50
- << " Cannot find: '" << PathToTestSharedLib << " ' in '" << Dir.str ()
51
- << " '" ;
52
-
57
+ << " Cannot find: '" << PathToTestSharedLib << " ' in '" << Dir.str () << " '" ;
53
58
EXPECT_TRUE (Cpp::LoadLibrary (PathToTestSharedLib.c_str ()));
59
+
54
60
// Force ExecutionEngine to be created.
55
61
Cpp::Process (" " );
62
+
56
63
// FIXME: Conda returns false to run this code on osx.
57
64
EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_zero" ).c_str ()));
58
65
@@ -70,19 +77,18 @@ TEST(DynamicLibraryManagerTest, LibrariesAutoload) {
70
77
EXPECT_FALSE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_one" ).c_str ()));
71
78
72
79
// Libraries Search path by default is set to main executable directory.
73
- std::string BinaryPath = GetExecutablePath (/* Argv0= */ nullptr );
80
+ std::string BinaryPath = GetExecutablePath (nullptr , nullptr );
74
81
llvm::StringRef Dir = llvm::sys::path::parent_path (BinaryPath);
75
82
Cpp::AddSearchPath (Dir.str ().c_str ());
76
83
77
- // Find library with "rec_one " symbol defined and exported
84
+ // Find library with "ret_one " symbol defined and exported
78
85
//
79
86
// FIXME: dlsym on mach-o takes the C-level name, however, the macho-o format
80
87
// adds an additional underscore (_) prefix to the lowered names. Figure out
81
88
// how to harmonize that API. For now we use out minimal implementation of
82
89
// helper function.
83
90
std::string PathToTestSharedLib1 =
84
91
Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_one" ).c_str (), /* system_search=*/ false );
85
-
86
92
// If result is "" then we cannot find this library.
87
93
EXPECT_STRNE (" " , PathToTestSharedLib1.c_str ())
88
94
<< " Cannot find: '" << PathToTestSharedLib1 << " ' in '" << Dir.str () << " '" ;
@@ -117,13 +123,95 @@ TEST(DynamicLibraryManagerTest, LibrariesAutoload) {
117
123
Cpp::SetLibrariesAutoload (false );
118
124
// Check autorum status (must be turned OFF)
119
125
EXPECT_FALSE (Cpp::GetLibrariesAutoload ());
120
- // EXPECT_FALSE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str())); // if unload works
121
- // EXPECT_TRUE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str()));
126
+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_one" ).c_str ())); // false if unload works
122
127
123
128
// Autoload turn ON again
124
129
Cpp::SetLibrariesAutoload (true );
125
130
// Check autorum status (must be turned ON)
126
131
EXPECT_TRUE (Cpp::GetLibrariesAutoload ());
127
- // EXPECT_FALSE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str())); // if unload works
128
- // EXPECT_TRUE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str()));
132
+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_one" ).c_str ()));
133
+
134
+ // Find library with "ret_1" symbol defined and exported
135
+ std::string PathToTestSharedLib2 =
136
+ Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_1" ).c_str (), /* system_search=*/ false );
137
+ // If result is "" then we cannot find this library.
138
+ EXPECT_STRNE (" " , PathToTestSharedLib2.c_str ())
139
+ << " Cannot find: '" << PathToTestSharedLib2 << " ' in '" << Dir.str () << " '" ;
140
+ // Find symbol must success (when auotload=on)
141
+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_1" ).c_str ()));
142
+ // Find symbol must success (when auotload=on)
143
+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_2" ).c_str ()));
144
+ }
145
+
146
+ TEST (DynamicLibraryManagerTest, LibrariesAutoloadExtraCoverage) {
147
+ EXPECT_TRUE (Cpp::CreateInterpreter ());
148
+
149
+ // Libraries Search path by default is set to main executable directory.
150
+ std::string BinaryPath = GetExecutablePath (nullptr , nullptr );
151
+ llvm::StringRef Dir = llvm::sys::path::parent_path (BinaryPath);
152
+ Cpp::AddSearchPath (Dir.str ().c_str ());
153
+
154
+ // Force ExecutionEngine to be created.
155
+ Cpp::Process (" " );
156
+
157
+ // Autoload turn ON
158
+ Cpp::SetLibrariesAutoload (true );
159
+ // Check autorum status (must be turned ON)
160
+ EXPECT_TRUE (Cpp::GetLibrariesAutoload ());
161
+
162
+ // Cover: MU getName()
163
+ std::string res;
164
+ llvm::raw_string_ostream rss (res);
165
+ const llvm::orc::SymbolNameVector syms;
166
+ Cpp::AutoLoadLibrarySearchGenerator::AutoloadLibraryMU MU (" test" , syms);
167
+ rss << MU;
168
+ EXPECT_STRNE (" " , rss.str ().c_str ()) << " MU problem!" ;
169
+
170
+ // Cover: LoadLibrary error
171
+ // if (DLM->loadLibrary(lib, false) != DynamicLibraryManager::LoadLibResult::kLoadLibSuccess) {
172
+ // LLVM_DEBUG(dbgs() << "MU: Failed to load library " << lib);
173
+ // string err = "MU: Failed to load library! " + lib;
174
+ // perror(err.c_str());
175
+ // } else {
176
+ // Find library with "ret_value" symbol defined and exported
177
+ std::string PathToTestSharedLib3 =
178
+ Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_val" ).c_str (), /* system_search=*/ false );
179
+ // If result is "" then we cannot find this library.
180
+ EXPECT_STRNE (" " , PathToTestSharedLib3.c_str ())
181
+ << " Cannot find: '" << PathToTestSharedLib3 << " ' in '" << Dir.str () << " '" ;
182
+ // Remove library for simulate load error
183
+ llvm::sys::fs::remove (PathToTestSharedLib3, true );
184
+ EXPECT_TRUE (Cpp::GetLibrariesAutoload ());
185
+ // FIXME: Conda returns false to run this code on osx.
186
+ EXPECT_FALSE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_val" ).c_str ()));
187
+
188
+ // Cover
189
+ // } else {
190
+ // // Collect all failing symbols, delegate their responsibility and then
191
+ // // fail their materialization. R->defineNonExistent() sounds like it
192
+ // // should do that, but it's not implemented?!
193
+ // failedSymbols.insert(symbol);
194
+ // TODO: implement test this case
195
+
196
+ // Cover
197
+ // if (!failedSymbols.empty()) {
198
+ // auto failingMR = R->delegate(failedSymbols);
199
+ // if (failingMR) {
200
+ // (*failingMR)->failMaterialization();
201
+ // TODO: implement test this case
202
+
203
+ // Cover
204
+ // void discard(const llvm::orc::JITDylib &JD, const llvm::orc::SymbolStringPtr &Name) override {}
205
+ // TODO: implement test this case
206
+
207
+ // Cover
208
+ // if (Path.empty()) {
209
+ // LLVM_DEBUG(dbgs() << "DynamicLibraryManager::lookupLibMaybeAddExt(): "
210
+ // TODO: implement test this case
211
+
212
+ // Cover
213
+ // platform::DLClose(dyLibHandle, &errMsg);
214
+ // if (!errMsg.empty()) {
215
+ // LLVM_DEBUG(dbgs() << "DynamicLibraryManager::unloadLibrary(): "
216
+ // TODO: implement test this case
129
217
}
0 commit comments