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