1*c1db8cf9SFrederich Munch //===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryTest.cpp --------===// 2*c1db8cf9SFrederich Munch // 3*c1db8cf9SFrederich Munch // The LLVM Compiler Infrastructure 4*c1db8cf9SFrederich Munch // 5*c1db8cf9SFrederich Munch // This file is distributed under the University of Illinois Open Source 6*c1db8cf9SFrederich Munch // License. See LICENSE.TXT for details. 7*c1db8cf9SFrederich Munch // 8*c1db8cf9SFrederich Munch //===----------------------------------------------------------------------===// 9*c1db8cf9SFrederich Munch 10*c1db8cf9SFrederich Munch #include "llvm/Config/config.h" 11*c1db8cf9SFrederich Munch #include "llvm/Support/DynamicLibrary.h" 12*c1db8cf9SFrederich Munch #include "llvm/Support/FileSystem.h" 13*c1db8cf9SFrederich Munch #include "llvm/Support/ManagedStatic.h" 14*c1db8cf9SFrederich Munch #include "llvm/Support/Path.h" 15*c1db8cf9SFrederich Munch #include "gtest/gtest.h" 16*c1db8cf9SFrederich Munch 17*c1db8cf9SFrederich Munch #include "PipSqueak.h" 18*c1db8cf9SFrederich Munch #include <string> 19*c1db8cf9SFrederich Munch 20*c1db8cf9SFrederich Munch using namespace llvm; 21*c1db8cf9SFrederich Munch using namespace llvm::sys; 22*c1db8cf9SFrederich Munch 23*c1db8cf9SFrederich Munch extern "C" PIPSQUEAK_EXPORT const char *TestA() { return "ProcessCall"; } 24*c1db8cf9SFrederich Munch 25*c1db8cf9SFrederich Munch std::string LibPath() { 26*c1db8cf9SFrederich Munch std::string Path = 27*c1db8cf9SFrederich Munch fs::getMainExecutable("DynamicLibraryTests", (void *)&TestA); 28*c1db8cf9SFrederich Munch llvm::SmallString<256> Buf(path::parent_path(Path)); 29*c1db8cf9SFrederich Munch path::append(Buf, "PipSqueak.so"); 30*c1db8cf9SFrederich Munch return Buf.str(); 31*c1db8cf9SFrederich Munch } 32*c1db8cf9SFrederich Munch 33*c1db8cf9SFrederich Munch #if defined(_WIN32) || (defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)) 34*c1db8cf9SFrederich Munch 35*c1db8cf9SFrederich Munch typedef void (*SetStrings)(std::string &GStr, std::string &LStr); 36*c1db8cf9SFrederich Munch typedef const char *(*GetString)(); 37*c1db8cf9SFrederich Munch 38*c1db8cf9SFrederich Munch template <class T> static T FuncPtr(void *Ptr) { 39*c1db8cf9SFrederich Munch union { 40*c1db8cf9SFrederich Munch T F; 41*c1db8cf9SFrederich Munch void *P; 42*c1db8cf9SFrederich Munch } Tmp; 43*c1db8cf9SFrederich Munch Tmp.P = Ptr; 44*c1db8cf9SFrederich Munch return Tmp.F; 45*c1db8cf9SFrederich Munch } 46*c1db8cf9SFrederich Munch template <class T> static void* PtrFunc(T *Func) { 47*c1db8cf9SFrederich Munch union { 48*c1db8cf9SFrederich Munch T *F; 49*c1db8cf9SFrederich Munch void *P; 50*c1db8cf9SFrederich Munch } Tmp; 51*c1db8cf9SFrederich Munch Tmp.F = Func; 52*c1db8cf9SFrederich Munch return Tmp.P; 53*c1db8cf9SFrederich Munch } 54*c1db8cf9SFrederich Munch 55*c1db8cf9SFrederich Munch static const char *OverloadTestA() { return "OverloadCall"; } 56*c1db8cf9SFrederich Munch 57*c1db8cf9SFrederich Munch std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; } 58*c1db8cf9SFrederich Munch 59*c1db8cf9SFrederich Munch TEST(DynamicLibrary, Overload) { 60*c1db8cf9SFrederich Munch { 61*c1db8cf9SFrederich Munch std::string Err; 62*c1db8cf9SFrederich Munch llvm_shutdown_obj Shutdown; 63*c1db8cf9SFrederich Munch DynamicLibrary DL = 64*c1db8cf9SFrederich Munch DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err); 65*c1db8cf9SFrederich Munch EXPECT_TRUE(DL.isValid()); 66*c1db8cf9SFrederich Munch EXPECT_TRUE(Err.empty()); 67*c1db8cf9SFrederich Munch 68*c1db8cf9SFrederich Munch GetString GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA")); 69*c1db8cf9SFrederich Munch EXPECT_TRUE(GS != nullptr && GS != &TestA); 70*c1db8cf9SFrederich Munch EXPECT_EQ(StdString(GS()), "LibCall"); 71*c1db8cf9SFrederich Munch 72*c1db8cf9SFrederich Munch GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA")); 73*c1db8cf9SFrederich Munch EXPECT_TRUE(GS != nullptr && GS != &TestA); 74*c1db8cf9SFrederich Munch EXPECT_EQ(StdString(GS()), "LibCall"); 75*c1db8cf9SFrederich Munch 76*c1db8cf9SFrederich Munch DL = DynamicLibrary::getPermanentLibrary(nullptr, &Err); 77*c1db8cf9SFrederich Munch EXPECT_TRUE(DL.isValid()); 78*c1db8cf9SFrederich Munch EXPECT_TRUE(Err.empty()); 79*c1db8cf9SFrederich Munch 80*c1db8cf9SFrederich Munch GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA")); 81*c1db8cf9SFrederich Munch EXPECT_TRUE(GS != nullptr && GS == &TestA); 82*c1db8cf9SFrederich Munch EXPECT_EQ(StdString(GS()), "ProcessCall"); 83*c1db8cf9SFrederich Munch 84*c1db8cf9SFrederich Munch GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA")); 85*c1db8cf9SFrederich Munch EXPECT_TRUE(GS != nullptr && GS == &TestA); 86*c1db8cf9SFrederich Munch EXPECT_EQ(StdString(GS()), "ProcessCall"); 87*c1db8cf9SFrederich Munch 88*c1db8cf9SFrederich Munch DynamicLibrary::AddSymbol("TestA", PtrFunc(&OverloadTestA)); 89*c1db8cf9SFrederich Munch GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA")); 90*c1db8cf9SFrederich Munch EXPECT_TRUE(GS != nullptr && GS != &OverloadTestA); 91*c1db8cf9SFrederich Munch 92*c1db8cf9SFrederich Munch GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA")); 93*c1db8cf9SFrederich Munch EXPECT_TRUE(GS != nullptr && GS == &OverloadTestA); 94*c1db8cf9SFrederich Munch EXPECT_EQ(StdString(GS()), "OverloadCall"); 95*c1db8cf9SFrederich Munch } 96*c1db8cf9SFrederich Munch EXPECT_TRUE(FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol( 97*c1db8cf9SFrederich Munch "TestA")) == nullptr); 98*c1db8cf9SFrederich Munch } 99*c1db8cf9SFrederich Munch 100*c1db8cf9SFrederich Munch TEST(DynamicLibrary, Shutdown) { 101*c1db8cf9SFrederich Munch std::string A, B; 102*c1db8cf9SFrederich Munch { 103*c1db8cf9SFrederich Munch std::string Err; 104*c1db8cf9SFrederich Munch llvm_shutdown_obj Shutdown; 105*c1db8cf9SFrederich Munch DynamicLibrary DL = 106*c1db8cf9SFrederich Munch DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err); 107*c1db8cf9SFrederich Munch EXPECT_TRUE(DL.isValid()); 108*c1db8cf9SFrederich Munch EXPECT_TRUE(Err.empty()); 109*c1db8cf9SFrederich Munch 110*c1db8cf9SFrederich Munch SetStrings SS = FuncPtr<SetStrings>( 111*c1db8cf9SFrederich Munch DynamicLibrary::SearchForAddressOfSymbol("SetStrings")); 112*c1db8cf9SFrederich Munch EXPECT_TRUE(SS != nullptr); 113*c1db8cf9SFrederich Munch 114*c1db8cf9SFrederich Munch SS(A, B); 115*c1db8cf9SFrederich Munch EXPECT_EQ(B, "Local::Local"); 116*c1db8cf9SFrederich Munch } 117*c1db8cf9SFrederich Munch EXPECT_EQ(A, "Global::~Global"); 118*c1db8cf9SFrederich Munch EXPECT_EQ(B, "Local::~Local"); 119*c1db8cf9SFrederich Munch EXPECT_TRUE(FuncPtr<SetStrings>(DynamicLibrary::SearchForAddressOfSymbol( 120*c1db8cf9SFrederich Munch "SetStrings")) == nullptr); 121*c1db8cf9SFrederich Munch } 122*c1db8cf9SFrederich Munch 123*c1db8cf9SFrederich Munch #else 124*c1db8cf9SFrederich Munch 125*c1db8cf9SFrederich Munch TEST(DynamicLibrary, Unsupported) { 126*c1db8cf9SFrederich Munch std::string Err; 127*c1db8cf9SFrederich Munch DynamicLibrary DL = 128*c1db8cf9SFrederich Munch DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err); 129*c1db8cf9SFrederich Munch EXPECT_FALSE(DL.isValid()); 130*c1db8cf9SFrederich Munch EXPECT_EQ(Err, "dlopen() not supported on this platform"); 131*c1db8cf9SFrederich Munch } 132*c1db8cf9SFrederich Munch 133*c1db8cf9SFrederich Munch #endif 134