[llvm] r301240 - Revert "Refactor DynamicLibrary so searching for a symbol will have a defined order"
Bill Seurer via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 25 14:00:52 PDT 2017
The run with a clean build worked.
On 04/25/2017 03:43 PM, Frederich Munch wrote:
> Ok.
>
> I'm ready to re-land the original commit, but thinking its better to
> hold off until this is verified as the problem.
>
> Otherwise let me know and I'll commit it now.
>
> ------------------------------------------------------------------------
> *From:* Bill Seurer <seurer at linux.vnet.ibm.com>
> *Sent:* Tuesday, April 25, 2017 8:36 PM
> *To:* Frederich Munch; llvm-commits at lists.llvm.org
> *Subject:* Re: [llvm] r301240 - Revert "Refactor DynamicLibrary so
> searching for a symbol will have a defined order"
>
> I am forcing the bot to do a clean build which sounds like it should
> clean that up.
>
> On 04/25/2017 03:33 PM, Frederich Munch wrote:
>> If I'm reading this correctly, the bot is running an invalid test/binary.
>>
>> The DynamicLibrary test was added in the original commit and is passing
>> on the bot as of *r30**1238*
>>
>> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/2052/steps/ninja%20check%201/logs/stdio
>>
>>
>> After the reversion the binary sticks around, but the changes that allow
>> the test to pass are gone.
>>
>>
>> ------------------------------------------------------------------------
>> *From:* Bill Seurer <seurer at linux.vnet.ibm.com>
>> *Sent:* Tuesday, April 25, 2017 8:00 PM
>> *To:* Frederich Munch; llvm-commits at lists.llvm.org
>> *Subject:* Re: [llvm] r301240 - Revert "Refactor DynamicLibrary so
>> searching for a symbol will have a defined order"
>>
>> It looks like this revision may be causing a test case failure on
>> ppc64le:
>> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/2053
>>
>> ******************** TEST 'LLVM-Unit ::
>> Support/DynamicLibrary/DynamicLibraryTests/DynamicLibrary.Shutdown'
>> FAILED ********************
>> Note: Google Test filter = DynamicLibrary.Shutdown
>> [==========] Running 1 test from 1 test case.
>> [----------] Global test environment set-up.
>> [----------] 1 test from DynamicLibrary
>> [ RUN ] DynamicLibrary.Shutdown
>> /home/buildbots/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp:117:
>>
>> Failure
>> Expected: A
>> Which is: ""
>> To be equal to: "Global::~Global"
>> /home/buildbots/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp:118:
>>
>> Failure
>> Expected: B
>> Which is: "Local::Local"
>> To be equal to: "Local::~Local"
>> [ FAILED ] DynamicLibrary.Shutdown (11 ms)
>> [----------] 1 test from DynamicLibrary (11 ms total)
>>
>> [----------] Global test environment tear-down
>> [==========] 1 test from 1 test case ran. (11 ms total)
>> [ PASSED ] 0 tests.
>> [ FAILED ] 1 test, listed below:
>> [ FAILED ] DynamicLibrary.Shutdown
>>
>> 1 FAILED TEST
>>
>>
>> I haven't been able to reproduce this on another machine, though.
>>
>> On 04/24/2017 03:16 PM, Frederich Munch via llvm-commits wrote:
>>> Author: marsupial
>>> Date: Mon Apr 24 15:16:01 2017
>>> New Revision: 301240
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=301240&view=rev
>>> Log:
>>> Revert "Refactor DynamicLibrary so searching for a symbol will have a defined order"
>>> The i686-mingw32-RA-on-linux bot is still having errors.
>>>
>>> This reverts commit r301236.
>>>
>>> Added:
>>> llvm/trunk/lib/Support/SearchForAddressOfSpecialSymbol.cpp
>>> Removed:
>>> llvm/trunk/lib/Support/Unix/DynamicLibrary.inc
>>> llvm/trunk/unittests/Support/DynamicLibrary/CMakeLists.txt
>>> llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
>>> llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.cxx
>>> llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.h
>>> Modified:
>>> llvm/trunk/include/llvm/Support/DynamicLibrary.h
>>> llvm/trunk/lib/Support/CMakeLists.txt
>>> llvm/trunk/lib/Support/DynamicLibrary.cpp
>>> llvm/trunk/lib/Support/Windows/DynamicLibrary.inc
>>> llvm/trunk/unittests/Support/CMakeLists.txt
>>>
>>> Modified: llvm/trunk/include/llvm/Support/DynamicLibrary.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DynamicLibrary.h?rev=301240&r1=301239&r2=301240&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/DynamicLibrary.h (original)
>>> +++ llvm/trunk/include/llvm/Support/DynamicLibrary.h Mon Apr 24 15:16:01 2017
>>> @@ -58,7 +58,7 @@ namespace sys {
>>> void *getAddressOfSymbol(const char *symbolName);
>>>
>>> /// This function permanently loads the dynamic library at the given path.
>>> - /// The library will only be unloaded when llvm_shutdown() is called.
>>> + /// The library will only be unloaded when the program terminates.
>>> /// This returns a valid DynamicLibrary instance on success and an invalid
>>> /// instance on failure (see isValid()). \p *errMsg will only be modified
>>> /// if the library fails to load.
>>> @@ -71,8 +71,7 @@ namespace sys {
>>> /// Registers an externally loaded library. The library will be unloaded
>>> /// when the program terminates.
>>> ///
>>> - /// It is safe to call this function multiple times for the same library,
>>> - /// though ownership is only taken if there was no error.
>>> + /// It is safe to call this function multiple times for the same library.
>>> ///
>>> /// \returns An empty \p DynamicLibrary if the library was already loaded.
>>> static DynamicLibrary addPermanentLibrary(void *handle,
>>> @@ -107,8 +106,6 @@ namespace sys {
>>> /// libraries.
>>> /// @brief Add searchable symbol/value pair.
>>> static void AddSymbol(StringRef symbolName, void *symbolValue);
>>> -
>>> - class HandleSet;
>>> };
>>>
>>> } // End sys namespace
>>>
>>> Modified: llvm/trunk/lib/Support/CMakeLists.txt
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=301240&r1=301239&r2=301240&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Support/CMakeLists.txt (original)
>>> +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Apr 24 15:16:01 2017
>>> @@ -130,6 +130,7 @@ add_llvm_library(LLVMSupport
>>> Process.cpp
>>> Program.cpp
>>> RWMutex.cpp
>>> + SearchForAddressOfSpecialSymbol.cpp
>>> Signals.cpp
>>> TargetRegistry.cpp
>>> ThreadLocal.cpp
>>>
>>> Modified: llvm/trunk/lib/Support/DynamicLibrary.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DynamicLibrary.cpp?rev=301240&r1=301239&r2=301240&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Support/DynamicLibrary.cpp (original)
>>> +++ llvm/trunk/lib/Support/DynamicLibrary.cpp Mon Apr 24 15:16:01 2017
>>> @@ -20,164 +20,169 @@
>>> #include "llvm/Support/Mutex.h"
>>> #include <cstdio>
>>> #include <cstring>
>>> -#include <vector>
>>>
>>> -using namespace llvm;
>>> -using namespace llvm::sys;
>>> +// Collection of symbol name/value pairs to be searched prior to any libraries.
>>> +static llvm::ManagedStatic<llvm::StringMap<void *> > ExplicitSymbols;
>>> +static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SymbolsMutex;
>>>
>>> -// All methods for HandleSet should be used holding SymbolsMutex.
>>> -class DynamicLibrary::HandleSet {
>>> - typedef std::vector<void *> HandleList;
>>> - HandleList Handles;
>>> - void *Process;
>>> +void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
>>> + void *symbolValue) {
>>> + SmartScopedLock<true> lock(*SymbolsMutex);
>>> + (*ExplicitSymbols)[symbolName] = symbolValue;
>>> +}
>>>
>>> -public:
>>> - static void *DLOpen(const char *Filename, std::string *Err);
>>> - static void DLClose(void *Handle);
>>> - static void *DLSym(void *Handle, const char *Symbol);
>>> +char llvm::sys::DynamicLibrary::Invalid = 0;
>>>
>>> - HandleSet() : Process(nullptr) {}
>>> - ~HandleSet();
>>> +#ifdef LLVM_ON_WIN32
>>>
>>> - HandleList::iterator Find(void *Handle) {
>>> - return std::find(Handles.begin(), Handles.end(), Handle);
>>> - }
>>> +#include "Windows/DynamicLibrary.inc"
>>> +
>>> +#else
>>>
>>> - bool Contains(void *Handle) {
>>> - return Handle == Process || Find(Handle) != Handles.end();
>>> +#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
>>> +#include <dlfcn.h>
>>> +using namespace llvm;
>>> +using namespace llvm::sys;
>>> +
>>> +//===----------------------------------------------------------------------===//
>>> +//=== WARNING: Implementation here must contain only TRULY operating system
>>> +//=== independent code.
>>> +//===----------------------------------------------------------------------===//
>>> +
>>> +static llvm::ManagedStatic<DenseSet<void *> > OpenedHandles;
>>> +
>>> +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
>>> + std::string *errMsg) {
>>> + SmartScopedLock<true> lock(*SymbolsMutex);
>>> +
>>> + void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
>>> + if (!handle) {
>>> + if (errMsg) *errMsg = dlerror();
>>> + return DynamicLibrary();
>>> }
>>>
>>> - bool AddLibrary(void *Handle, bool IsProcess = false, bool CanClose = true) {
>>> -#ifdef LLVM_ON_WIN32
>>> - assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle.");
>>> +#ifdef __CYGWIN__
>>> + // Cygwin searches symbols only in the main
>>> + // with the handle of dlopen(NULL, RTLD_GLOBAL).
>>> + if (!filename)
>>> + handle = RTLD_DEFAULT;
>>> #endif
>>>
>>> - if (LLVM_LIKELY(!IsProcess)) {
>>> - if (Find(Handle) != Handles.end()) {
>>> - if (CanClose)
>>> - DLClose(Handle);
>>> - return false;
>>> - }
>>> - Handles.push_back(Handle);
>>> - } else {
>>> -#ifndef LLVM_ON_WIN32
>>> - if (Process) {
>>> - if (CanClose)
>>> - DLClose(Process);
>>> - if (Process == Handle)
>>> - return false;
>>> - }
>>> -#endif
>>> - Process = Handle;
>>> - }
>>> - return true;
>>> - }
>>> + // If we've already loaded this library, dlclose() the handle in order to
>>> + // keep the internal refcount at +1.
>>> + if (!OpenedHandles->insert(handle).second)
>>> + dlclose(handle);
>>>
>>> - void *Lookup(const char *Symbol) {
>>> - // Process handle gets first try.
>>> - if (Process) {
>>> - if (void *Ptr = DLSym(Process, Symbol))
>>> - return Ptr;
>>> -#ifndef NDEBUG
>>> - for (void *Handle : Handles)
>>> - assert(!DLSym(Handle, Symbol) && "Symbol exists in non process handle");
>>> -#endif
>>> - } else {
>>> - // Iterate in reverse, so newer libraries/symbols override older.
>>> - for (auto &&I = Handles.rbegin(), E = Handles.rend(); I != E; ++I) {
>>> - if (void *Ptr = DLSym(*I, Symbol))
>>> - return Ptr;
>>> - }
>>> - }
>>> - return nullptr;
>>> + return DynamicLibrary(handle);
>>> +}
>>> +
>>> +DynamicLibrary DynamicLibrary::addPermanentLibrary(void *handle,
>>> + std::string *errMsg) {
>>> + SmartScopedLock<true> lock(*SymbolsMutex);
>>> + // If we've already loaded this library, tell the caller.
>>> + if (!OpenedHandles->insert(handle).second) {
>>> + if (errMsg) *errMsg = "Library already loaded";
>>> + return DynamicLibrary();
>>> }
>>> -};
>>>
>>> -namespace {
>>> -// Collection of symbol name/value pairs to be searched prior to any libraries.
>>> -static llvm::ManagedStatic<llvm::StringMap<void *>> ExplicitSymbols;
>>> -// Collection of known library handles.
>>> -static llvm::ManagedStatic<DynamicLibrary::HandleSet> OpenedHandles;
>>> -// Lock for ExplicitSymbols and OpenedHandles.
>>> -static llvm::ManagedStatic<llvm::sys::SmartMutex<true>> SymbolsMutex;
>>> + return DynamicLibrary(handle);
>>> }
>>>
>>> -#ifdef LLVM_ON_WIN32
>>> -
>>> -#include "Windows/DynamicLibrary.inc"
>>> +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
>>> + if (!isValid())
>>> + return nullptr;
>>> + return dlsym(Data, symbolName);
>>> +}
>>>
>>> #else
>>>
>>> -#include "Unix/DynamicLibrary.inc"
>>> -
>>> -#endif
>>> -
>>> -char DynamicLibrary::Invalid;
>>> +using namespace llvm;
>>> +using namespace llvm::sys;
>>>
>>> -namespace llvm {
>>> -void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
>>> - return DoSearch(SymbolName); // DynamicLibrary.inc
>>> -}
>>> +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
>>> + std::string *errMsg) {
>>> + if (errMsg) *errMsg = "dlopen() not supported on this platform";
>>> + return DynamicLibrary();
>>> }
>>>
>>> -void DynamicLibrary::AddSymbol(StringRef SymbolName, void *SymbolValue) {
>>> - SmartScopedLock<true> Lock(*SymbolsMutex);
>>> - (*ExplicitSymbols)[SymbolName] = SymbolValue;
>>> +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
>>> + return NULL;
>>> }
>>>
>>> -DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName,
>>> - std::string *Err) {
>>> - SmartScopedLock<true> Lock(*SymbolsMutex);
>>> - void *Handle = HandleSet::DLOpen(FileName, Err);
>>> - if (Handle != &Invalid)
>>> - OpenedHandles->AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
>>> +#endif
>>>
>>> - return DynamicLibrary(Handle);
>>> +namespace llvm {
>>> +void *SearchForAddressOfSpecialSymbol(const char* symbolName);
>>> }
>>>
>>> -DynamicLibrary DynamicLibrary::addPermanentLibrary(void *Handle,
>>> - std::string *Err) {
>>> +void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
>>> SmartScopedLock<true> Lock(*SymbolsMutex);
>>> - // If we've already loaded this library, tell the caller.
>>> - if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false))
>>> - *Err = "Library already loaded";
>>> -
>>> - return DynamicLibrary(Handle);
>>> -}
>>> -
>>> -void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
>>> - if (!isValid())
>>> - return nullptr;
>>> - return HandleSet::DLSym(Data, SymbolName);
>>> -}
>>>
>>> -void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
>>> - {
>>> - SmartScopedLock<true> Lock(*SymbolsMutex);
>>> + // First check symbols added via AddSymbol().
>>> + if (ExplicitSymbols.isConstructed()) {
>>> + StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
>>>
>>> - // First check symbols added via AddSymbol().
>>> - if (ExplicitSymbols.isConstructed()) {
>>> - StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
>>> + if (i != ExplicitSymbols->end())
>>> + return i->second;
>>> + }
>>>
>>> - if (i != ExplicitSymbols->end())
>>> - return i->second;
>>> +#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
>>> + // Now search the libraries.
>>> + if (OpenedHandles.isConstructed()) {
>>> + for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
>>> + E = OpenedHandles->end(); I != E; ++I) {
>>> + //lt_ptr ptr = lt_dlsym(*I, symbolName);
>>> + void *ptr = dlsym(*I, symbolName);
>>> + if (ptr) {
>>> + return ptr;
>>> + }
>>> }
>>> + }
>>> +#endif
>>>
>>> - // Now search the libraries.
>>> - if (OpenedHandles.isConstructed()) {
>>> - if (void *Ptr = OpenedHandles->Lookup(SymbolName))
>>> - return Ptr;
>>> - }
>>> + if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
>>> + return Result;
>>> +
>>> +// This macro returns the address of a well-known, explicit symbol
>>> +#define EXPLICIT_SYMBOL(SYM) \
>>> + if (!strcmp(symbolName, #SYM)) return &SYM
>>> +
>>> +// On linux we have a weird situation. The stderr/out/in symbols are both
>>> +// macros and global variables because of standards requirements. So, we
>>> +// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
>>> +#if defined(__linux__) and !defined(__ANDROID__)
>>> + {
>>> + EXPLICIT_SYMBOL(stderr);
>>> + EXPLICIT_SYMBOL(stdout);
>>> + EXPLICIT_SYMBOL(stdin);
>>> }
>>> +#else
>>> + // For everything else, we want to check to make sure the symbol isn't defined
>>> + // as a macro before using EXPLICIT_SYMBOL.
>>> + {
>>> +#ifndef stdin
>>> + EXPLICIT_SYMBOL(stdin);
>>> +#endif
>>> +#ifndef stdout
>>> + EXPLICIT_SYMBOL(stdout);
>>> +#endif
>>> +#ifndef stderr
>>> + EXPLICIT_SYMBOL(stderr);
>>> +#endif
>>> + }
>>> +#endif
>>> +#undef EXPLICIT_SYMBOL
>>>
>>> - return llvm::SearchForAddressOfSpecialSymbol(SymbolName);
>>> + return nullptr;
>>> }
>>>
>>> +#endif // LLVM_ON_WIN32
>>> +
>>> //===----------------------------------------------------------------------===//
>>> // C API.
>>> //===----------------------------------------------------------------------===//
>>>
>>> -LLVMBool LLVMLoadLibraryPermanently(const char *Filename) {
>>> +LLVMBool LLVMLoadLibraryPermanently(const char* Filename) {
>>> return llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename);
>>> }
>>>
>>>
>>> Added: llvm/trunk/lib/Support/SearchForAddressOfSpecialSymbol.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/SearchForAddressOfSpecialSymbol.cpp?rev=301240&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/lib/Support/SearchForAddressOfSpecialSymbol.cpp (added)
>>> +++ llvm/trunk/lib/Support/SearchForAddressOfSpecialSymbol.cpp Mon Apr 24 15:16:01 2017
>>> @@ -0,0 +1,58 @@
>>> +//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
>>> +//
>>> +// The LLVM Compiler Infrastructure
>>> +//
>>> +// This file is distributed under the University of Illinois Open Source
>>> +// License. See LICENSE.TXT for details.
>>> +//
>>> +//===----------------------------------------------------------------------===//
>>> +//
>>> +// This file pulls the addresses of certain symbols out of the linker. It must
>>> +// include as few header files as possible because it declares the symbols as
>>> +// void*, which would conflict with the actual symbol type if any header
>>> +// declared it.
>>> +//
>>> +//===----------------------------------------------------------------------===//
>>> +
>>> +#include <string.h>
>>> +
>>> +// Must declare the symbols in the global namespace.
>>> +static void *DoSearch(const char* symbolName) {
>>> +#define EXPLICIT_SYMBOL(SYM) \
>>> + extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
>>> +
>>> + // If this is darwin, it has some funky issues, try to solve them here. Some
>>> + // important symbols are marked 'private external' which doesn't allow
>>> + // SearchForAddressOfSymbol to find them. As such, we special case them here,
>>> + // there is only a small handful of them.
>>> +
>>> +#ifdef __APPLE__
>>> + {
>>> + // __eprintf is sometimes used for assert() handling on x86.
>>> + //
>>> + // FIXME: Currently disabled when using Clang, as we don't always have our
>>> + // runtime support libraries available.
>>> +#ifndef __clang__
>>> +#ifdef __i386__
>>> + EXPLICIT_SYMBOL(__eprintf);
>>> +#endif
>>> +#endif
>>> + }
>>> +#endif
>>> +
>>> +#ifdef __CYGWIN__
>>> + {
>>> + EXPLICIT_SYMBOL(_alloca);
>>> + EXPLICIT_SYMBOL(__main);
>>> + }
>>> +#endif
>>> +
>>> +#undef EXPLICIT_SYMBOL
>>> + return nullptr;
>>> +}
>>> +
>>> +namespace llvm {
>>> +void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
>>> + return DoSearch(symbolName);
>>> +}
>>> +} // namespace llvm
>>>
>>> Removed: llvm/trunk/lib/Support/Unix/DynamicLibrary.inc
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/DynamicLibrary.inc?rev=301239&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/lib/Support/Unix/DynamicLibrary.inc (original)
>>> +++ llvm/trunk/lib/Support/Unix/DynamicLibrary.inc (removed)
>>> @@ -1,131 +0,0 @@
>>> -//===- Unix/DynamicLibrary.cpp - Unix DL Implementation ---------*- C++ -*-===//
>>> -//
>>> -// The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -//
>>> -// This file provides the UNIX specific implementation of DynamicLibrary.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
>>> -#include <dlfcn.h>
>>> -
>>> -DynamicLibrary::HandleSet::~HandleSet() {
>>> - for (void *Handle : Handles)
>>> - ::dlclose(Handle);
>>> - if (Process)
>>> - ::dlclose(Process);
>>> -}
>>> -
>>> -void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
>>> - void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
>>> - if (!Handle) {
>>> - if (Err) *Err = ::dlerror();
>>> - return &DynamicLibrary::Invalid;
>>> - }
>>> -
>>> -#ifdef __CYGWIN__
>>> - // Cygwin searches symbols only in the main
>>> - // with the handle of dlopen(NULL, RTLD_GLOBAL).
>>> - if (!Filename)
>>> - Handle = RTLD_DEFAULT;
>>> -#endif
>>> -
>>> - return Handle;
>>> -}
>>> -
>>> -void DynamicLibrary::HandleSet::DLClose(void *Handle) {
>>> - ::dlclose(Handle);
>>> -}
>>> -
>>> -void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
>>> - return ::dlsym(Handle, Symbol);
>>> -}
>>> -
>>> -#else // !HAVE_DLOPEN
>>> -
>>> -DynamicLibrary::HandleSet::~HandleSet() {}
>>> -
>>> -void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
>>> - if (Err) *Err = "dlopen() not supported on this platform";
>>> - return &Invalid;
>>> -}
>>> -
>>> -void DynamicLibrary::HandleSet::DLClose(void *Handle) {
>>> -}
>>> -
>>> -void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
>>> - return nullptr;
>>> -}
>>> -
>>> -#endif
>>> -
>>> -// Must declare the symbols in the global namespace.
>>> -static void *DoSearch(const char* SymbolName) {
>>> -#define EXPLICIT_SYMBOL(SYM) \
>>> - extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM
>>> -
>>> - // If this is darwin, it has some funky issues, try to solve them here. Some
>>> - // important symbols are marked 'private external' which doesn't allow
>>> - // SearchForAddressOfSymbol to find them. As such, we special case them here,
>>> - // there is only a small handful of them.
>>> -
>>> -#ifdef __APPLE__
>>> - {
>>> - // __eprintf is sometimes used for assert() handling on x86.
>>> - //
>>> - // FIXME: Currently disabled when using Clang, as we don't always have our
>>> - // runtime support libraries available.
>>> -#ifndef __clang__
>>> -#ifdef __i386__
>>> - EXPLICIT_SYMBOL(__eprintf);
>>> -#endif
>>> -#endif
>>> - }
>>> -#endif
>>> -
>>> -#ifdef __CYGWIN__
>>> - {
>>> - EXPLICIT_SYMBOL(_alloca);
>>> - EXPLICIT_SYMBOL(__main);
>>> - }
>>> -#endif
>>> -
>>> -#undef EXPLICIT_SYMBOL
>>> -
>>> -// This macro returns the address of a well-known, explicit symbol
>>> -#define EXPLICIT_SYMBOL(SYM) \
>>> - if (!strcmp(SymbolName, #SYM)) return &SYM
>>> -
>>> -// On linux we have a weird situation. The stderr/out/in symbols are both
>>> -// macros and global variables because of standards requirements. So, we
>>> -// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
>>> -#if defined(__linux__) and !defined(__ANDROID__)
>>> - {
>>> - EXPLICIT_SYMBOL(stderr);
>>> - EXPLICIT_SYMBOL(stdout);
>>> - EXPLICIT_SYMBOL(stdin);
>>> - }
>>> -#else
>>> - // For everything else, we want to check to make sure the symbol isn't defined
>>> - // as a macro before using EXPLICIT_SYMBOL.
>>> - {
>>> -#ifndef stdin
>>> - EXPLICIT_SYMBOL(stdin);
>>> -#endif
>>> -#ifndef stdout
>>> - EXPLICIT_SYMBOL(stdout);
>>> -#endif
>>> -#ifndef stderr
>>> - EXPLICIT_SYMBOL(stderr);
>>> -#endif
>>> - }
>>> -#endif
>>> -#undef EXPLICIT_SYMBOL
>>> -
>>> - return nullptr;
>>> -}
>>>
>>> Modified: llvm/trunk/lib/Support/Windows/DynamicLibrary.inc
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/DynamicLibrary.inc?rev=301240&r1=301239&r2=301240&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Support/Windows/DynamicLibrary.inc (original)
>>> +++ llvm/trunk/lib/Support/Windows/DynamicLibrary.inc Mon Apr 24 15:16:01 2017
>>> @@ -12,139 +12,97 @@
>>> //===----------------------------------------------------------------------===//
>>>
>>> #include "WindowsSupport.h"
>>> -#include "llvm/Support/raw_ostream.h"
>>>
>>> -#include <Psapi.h>
>>> +#ifdef __MINGW32__
>>> + #include <imagehlp.h>
>>> +#else
>>> + #include <dbghelp.h>
>>> +#endif
>>> +
>>> +#ifdef _MSC_VER
>>> + #include <ntverp.h>
>>> +#endif
>>> +
>>> +namespace llvm {
>>>
>>> //===----------------------------------------------------------------------===//
>>> //=== WARNING: Implementation here must contain only Win32 specific code
>>> //=== and must not be UNIX code.
>>> //===----------------------------------------------------------------------===//
>>>
>>> +typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
>>> +static fpEnumerateLoadedModules fEnumerateLoadedModules;
>>> +static llvm::ManagedStatic<DenseSet<HMODULE> > OpenedHandles;
>>> +
>>> +static bool loadDebugHelp(void) {
>>> + HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
>>> + if (hLib) {
>>> + fEnumerateLoadedModules = (fpEnumerateLoadedModules)
>>> + ::GetProcAddress(hLib, "EnumerateLoadedModules64");
>>> + }
>>> + return fEnumerateLoadedModules != 0;
>>> +}
>>>
>>> -DynamicLibrary::HandleSet::~HandleSet() {
>>> - for (void *Handle : Handles)
>>> - FreeLibrary(HMODULE(Handle));
>>> -
>>> - // 'Process' should not be released on Windows.
>>> - assert((!Process || Process==this) && "Bad Handle");
>>> -}
>>> -
>>> -void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
>>> - // Create the instance and return it to be the *Process* handle
>>> - // simillar to dlopen(NULL, RTLD_LAZY|RTLD_GLOBAL)
>>> - if (!File)
>>> - return &(*OpenedHandles);
>>> +static BOOL CALLBACK
>>> +ELM_Callback(PCSTR ModuleName, DWORD64 ModuleBase,
>>> + ULONG ModuleSize, PVOID UserContext) {
>>> + OpenedHandles->insert((HMODULE)ModuleBase);
>>> + return TRUE;
>>> +}
>>> +
>>> +sys::DynamicLibrary
>>> +sys::DynamicLibrary::getPermanentLibrary(const char *filename,
>>> + std::string *errMsg) {
>>> + SmartScopedLock<true> lock(*SymbolsMutex);
>>> +
>>> + if (!filename) {
>>> + // When no file is specified, enumerate all DLLs and EXEs in the process.
>>> + if (!fEnumerateLoadedModules) {
>>> + if (!loadDebugHelp()) {
>>> + assert(false && "These APIs should always be available");
>>> + return DynamicLibrary();
>>> + }
>>> + }
>>>
>>> - SmallVector<wchar_t, MAX_PATH> FileUnicode;
>>> - if (std::error_code ec = windows::UTF8ToUTF16(File, FileUnicode)) {
>>> - SetLastError(ec.value());
>>> - MakeErrMsg(Err, std::string(File) + ": Can't convert to UTF-16");
>>> - return &DynamicLibrary::Invalid;
>>> + fEnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
>>> + // Dummy library that represents "search all handles".
>>> + // This is mostly to ensure that the return value still shows up as "valid".
>>> + return DynamicLibrary(&OpenedHandles);
>>> }
>>>
>>> - HMODULE Handle = LoadLibraryW(FileUnicode.data());
>>> - if (Handle == NULL) {
>>> - MakeErrMsg(Err, std::string(File) + ": Can't open");
>>> - return &DynamicLibrary::Invalid;
>>> + SmallVector<wchar_t, MAX_PATH> filenameUnicode;
>>> + if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
>>> + SetLastError(ec.value());
>>> + MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16");
>>> + return DynamicLibrary();
>>> }
>>>
>>> - return reinterpret_cast<void*>(Handle);
>>> -}
>>> + HMODULE a_handle = LoadLibraryW(filenameUnicode.data());
>>>
>>> -static DynamicLibrary::HandleSet *IsOpenedHandlesInstance(void *Handle) {
>>> - if (!OpenedHandles.isConstructed())
>>> - return nullptr;
>>> - DynamicLibrary::HandleSet &Inst = *OpenedHandles;
>>> - return Handle == &Inst ? &Inst : nullptr;
>>> -}
>>> + if (a_handle == 0) {
>>> + MakeErrMsg(errMsg, std::string(filename) + ": Can't open");
>>> + return DynamicLibrary();
>>> + }
>>>
>>> -void DynamicLibrary::HandleSet::DLClose(void *Handle) {
>>> - if (HandleSet* HS = IsOpenedHandlesInstance(Handle))
>>> - HS->Process = nullptr; // Just drop the *Process* handle.
>>> - else
>>> - FreeLibrary((HMODULE)Handle);
>>> + // If we've already loaded this library, FreeLibrary() the handle in order to
>>> + // keep the internal refcount at +1.
>>> + if (!OpenedHandles->insert(a_handle).second)
>>> + FreeLibrary(a_handle);
>>> +
>>> + return DynamicLibrary(a_handle);
>>> }
>>>
>>> -static bool GetProcessModules(HANDLE H, DWORD &Bytes, HMODULE *Data = nullptr) {
>>> - // EnumProcessModules will fail on Windows 64 while MingW-32 doesn't have
>>> - // EnumProcessModulesEx.
>>> - if (
>>> -#ifdef _WIN64
>>> - !EnumProcessModulesEx(H, Data, Bytes, &Bytes, LIST_MODULES_64BIT)
>>> -#else
>>> - !EnumProcessModules(H, Data, Bytes, &Bytes)
>>> -#endif
>>> - ) {
>>> - std::string Err;
>>> - if (MakeErrMsg(&Err, "EnumProcessModules failure"))
>>> - llvm::errs() << Err << "\n";
>>> - return false;
>>> - }
>>> - return true;
>>> -}
>>> -
>>> -void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
>>> - HandleSet* HS = IsOpenedHandlesInstance(Handle);
>>> - if (!HS)
>>> - return (void *)uintptr_t(GetProcAddress((HMODULE)Handle, Symbol));
>>> -
>>> - // Could have done a dlclose on the *Process* handle
>>> - if (!HS->Process)
>>> - return nullptr;
>>> -
>>> - // Trials indicate EnumProcessModulesEx is consistantly faster than using
>>> - // EnumerateLoadedModules64 or CreateToolhelp32Snapshot.
>>> - //
>>> - // | Handles | DbgHelp.dll | CreateSnapshot | EnumProcessModulesEx
>>> - // |=========|=============|========================================
>>> - // | 37 | 0.0000585 * | 0.0003031 | 0.0000152
>>> - // | 1020 | 0.0026310 * | 0.0121598 | 0.0002683
>>> - // | 2084 | 0.0149418 * | 0.0369936 | 0.0005610
>>> - //
>>> - // * Not including the load time of Dbghelp.dll (~.005 sec)
>>> - //
>>> - // There's still a case to somehow cache the result of EnumProcessModulesEx
>>> - // across invocations, but the complication of doing that properly...
>>> - // Possibly using LdrRegisterDllNotification to invalidate the cache?
>>> -
>>> - DWORD Bytes = 0;
>>> - HMODULE Self = HMODULE(GetCurrentProcess());
>>> - if (!GetProcessModules(Self, Bytes))
>>> - return nullptr;
>>> -
>>> - // Get the most recent list in case any modules added/removed between calls
>>> - // to EnumProcessModulesEx that gets the amount of, then copies the HMODULES.
>>> - // MSDN is pretty clear that if the module list changes during the call to
>>> - // EnumProcessModulesEx the results should not be used.
>>> - std::vector<HMODULE> Handles;
>>> - do {
>>> - assert(Bytes && ((Bytes % sizeof(HMODULE)) == 0) &&
>>> - "Should have at least one module and be aligned");
>>> - Handles.resize(Bytes / sizeof(HMODULE));
>>> - if (!GetProcessModules(Self, Bytes, Handles.data()))
>>> - return nullptr;
>>> - } while (Bytes != (Handles.size() * sizeof(HMODULE)));
>>> -
>>> - // Try EXE first, mirroring what dlsym(dlopen(NULL)) does.
>>> - if (FARPROC Ptr = GetProcAddress(HMODULE(Handles.front()), Symbol))
>>> - return (void *) uintptr_t(Ptr);
>>> -
>>> - if (Handles.size() > 1) {
>>> - // This is different behaviour than what Posix dlsym(dlopen(NULL)) does.
>>> - // Doing that here is causing real problems for the JIT where msvc.dll
>>> - // and ucrt.dll can define the same symbols. The runtime linker will choose
>>> - // symbols from ucrt.dll first, but iterating NOT in reverse here would
>>> - // mean that the msvc.dll versions would be returned.
>>> -
>>> - for (auto I = Handles.rbegin(), E = Handles.rend()-1; I != E; ++I) {
>>> - if (FARPROC Ptr = GetProcAddress(HMODULE(*I), Symbol))
>>> - return (void *) uintptr_t(Ptr);
>>> - }
>>> +sys::DynamicLibrary
>>> +sys::DynamicLibrary::addPermanentLibrary(void *handle, std::string *errMsg) {
>>> + SmartScopedLock<true> lock(*SymbolsMutex);
>>> + // If we've already loaded this library, tell the caller.
>>> + if (!OpenedHandles->insert((HMODULE)handle).second) {
>>> + MakeErrMsg(errMsg, "Library already loaded");
>>> + return DynamicLibrary();
>>> }
>>> - return nullptr;
>>> -}
>>>
>>> + return DynamicLibrary(handle);
>>> +}
>>>
>>> // Stack probing routines are in the support library (e.g. libgcc), but we don't
>>> // have dynamic linking on windows. Provide a hook.
>>> @@ -171,18 +129,38 @@ void *DynamicLibrary::HandleSet::DLSym(v
>>> #undef INLINE_DEF_SYMBOL1
>>> #undef INLINE_DEF_SYMBOL2
>>>
>>> -static void *DoSearch(const char *SymbolName) {
>>> +void *sys::DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
>>> + SmartScopedLock<true> Lock(*SymbolsMutex);
>>> +
>>> + // First check symbols added via AddSymbol().
>>> + if (ExplicitSymbols.isConstructed()) {
>>> + StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
>>> +
>>> + if (i != ExplicitSymbols->end())
>>> + return i->second;
>>> + }
>>> +
>>> + // Now search the libraries.
>>> + if (OpenedHandles.isConstructed()) {
>>> + for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(),
>>> + E = OpenedHandles->end(); I != E; ++I) {
>>> + FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
>>> + if (ptr) {
>>> + return (void *)(intptr_t)ptr;
>>> + }
>>> + }
>>> + }
>>>
>>> #define EXPLICIT_SYMBOL(SYM) \
>>> - if (!strcmp(SymbolName, #SYM)) \
>>> + if (!strcmp(symbolName, #SYM)) \
>>> return (void *)&SYM;
>>> #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
>>> - if (!strcmp(SymbolName, #SYMFROM)) \
>>> + if (!strcmp(symbolName, #SYMFROM)) \
>>> return (void *)&SYMTO;
>>>
>>> #ifdef _M_IX86
>>> #define INLINE_DEF_SYMBOL1(TYP, SYM) \
>>> - if (!strcmp(SymbolName, #SYM)) \
>>> + if (!strcmp(symbolName, #SYM)) \
>>> return (void *)&inline_##SYM;
>>> #define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM)
>>> #endif
>>> @@ -196,5 +174,15 @@ static void *DoSearch(const char *Symbol
>>> #undef INLINE_DEF_SYMBOL1
>>> #undef INLINE_DEF_SYMBOL2
>>>
>>> - return nullptr;
>>> + return 0;
>>> +}
>>> +
>>> +void *sys::DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
>>> + if (!isValid())
>>> + return NULL;
>>> + if (Data == &OpenedHandles)
>>> + return SearchForAddressOfSymbol(symbolName);
>>> + return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
>>> +}
>>> +
>>> }
>>>
>>> Modified: llvm/trunk/unittests/Support/CMakeLists.txt
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=301240&r1=301239&r2=301240&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/CMakeLists.txt (original)
>>> +++ llvm/trunk/unittests/Support/CMakeLists.txt Mon Apr 24 15:16:01 2017
>>> @@ -67,5 +67,3 @@ add_llvm_unittest(SupportTests
>>>
>>> # ManagedStatic.cpp uses <pthread>.
>>> target_link_libraries(SupportTests ${LLVM_PTHREAD_LIB})
>>> -
>>> -add_subdirectory(DynamicLibrary)
>>>
>>> Removed: llvm/trunk/unittests/Support/DynamicLibrary/CMakeLists.txt
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/DynamicLibrary/CMakeLists.txt?rev=301239&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/DynamicLibrary/CMakeLists.txt (original)
>>> +++ llvm/trunk/unittests/Support/DynamicLibrary/CMakeLists.txt (removed)
>>> @@ -1,19 +0,0 @@
>>> -set(LLVM_LINK_COMPONENTS Support)
>>> -
>>> -add_llvm_unittest(DynamicLibraryTests DynamicLibraryTest.cpp)
>>> -
>>> -export_executable_symbols(DynamicLibraryTests)
>>> -
>>> -add_library(PipSqueak SHARED PipSqueak.cxx)
>>> -
>>> -set_output_directory(PipSqueak
>>> - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
>>> - LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
>>> - )
>>> -
>>> -set_target_properties(PipSqueak
>>> - PROPERTIES PREFIX ""
>>> - SUFFIX ".so"
>>> - )
>>> -
>>> -add_dependencies(DynamicLibraryTests PipSqueak)
>>>
>>> Removed: llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp?rev=301239&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp (original)
>>> +++ llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp (removed)
>>> @@ -1,133 +0,0 @@
>>> -//===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryTest.cpp --------===//
>>> -//
>>> -// The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#include "llvm/Config/config.h"
>>> -#include "llvm/Support/DynamicLibrary.h"
>>> -#include "llvm/Support/FileSystem.h"
>>> -#include "llvm/Support/ManagedStatic.h"
>>> -#include "llvm/Support/Path.h"
>>> -#include "gtest/gtest.h"
>>> -
>>> -#include "PipSqueak.h"
>>> -#include <string>
>>> -
>>> -using namespace llvm;
>>> -using namespace llvm::sys;
>>> -
>>> -extern "C" PIPSQUEAK_EXPORT const char *TestA() { return "ProcessCall"; }
>>> -
>>> -std::string LibPath() {
>>> - std::string Path =
>>> - fs::getMainExecutable("DynamicLibraryTests", (void *)&TestA);
>>> - llvm::SmallString<256> Buf(path::parent_path(Path));
>>> - path::append(Buf, "PipSqueak.so");
>>> - return Buf.str();
>>> -}
>>> -
>>> -#if defined(_WIN32) || (defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN))
>>> -
>>> -typedef void (*SetStrings)(std::string &GStr, std::string &LStr);
>>> -typedef const char *(*GetString)();
>>> -
>>> -template <class T> static T FuncPtr(void *Ptr) {
>>> - union {
>>> - T F;
>>> - void *P;
>>> - } Tmp;
>>> - Tmp.P = Ptr;
>>> - return Tmp.F;
>>> -}
>>> -template <class T> static void* PtrFunc(T *Func) {
>>> - union {
>>> - T *F;
>>> - void *P;
>>> - } Tmp;
>>> - Tmp.F = Func;
>>> - return Tmp.P;
>>> -}
>>> -
>>> -static const char *OverloadTestA() { return "OverloadCall"; }
>>> -
>>> -std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; }
>>> -
>>> -TEST(DynamicLibrary, Overload) {
>>> - {
>>> - std::string Err;
>>> - llvm_shutdown_obj Shutdown;
>>> - DynamicLibrary DL =
>>> - DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
>>> - EXPECT_TRUE(DL.isValid());
>>> - EXPECT_TRUE(Err.empty());
>>> -
>>> - GetString GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
>>> - EXPECT_TRUE(GS != nullptr && GS != &TestA);
>>> - EXPECT_EQ(StdString(GS()), "LibCall");
>>> -
>>> - GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
>>> - EXPECT_TRUE(GS != nullptr && GS != &TestA);
>>> - EXPECT_EQ(StdString(GS()), "LibCall");
>>> -
>>> - DL = DynamicLibrary::getPermanentLibrary(nullptr, &Err);
>>> - EXPECT_TRUE(DL.isValid());
>>> - EXPECT_TRUE(Err.empty());
>>> -
>>> - GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
>>> - EXPECT_TRUE(GS != nullptr && GS == &TestA);
>>> - EXPECT_EQ(StdString(GS()), "ProcessCall");
>>> -
>>> - GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
>>> - EXPECT_TRUE(GS != nullptr && GS == &TestA);
>>> - EXPECT_EQ(StdString(GS()), "ProcessCall");
>>> -
>>> - DynamicLibrary::AddSymbol("TestA", PtrFunc(&OverloadTestA));
>>> - GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
>>> - EXPECT_TRUE(GS != nullptr && GS != &OverloadTestA);
>>> -
>>> - GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
>>> - EXPECT_TRUE(GS != nullptr && GS == &OverloadTestA);
>>> - EXPECT_EQ(StdString(GS()), "OverloadCall");
>>> - }
>>> - EXPECT_TRUE(FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol(
>>> - "TestA")) == nullptr);
>>> -}
>>> -
>>> -TEST(DynamicLibrary, Shutdown) {
>>> - std::string A, B;
>>> - {
>>> - std::string Err;
>>> - llvm_shutdown_obj Shutdown;
>>> - DynamicLibrary DL =
>>> - DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
>>> - EXPECT_TRUE(DL.isValid());
>>> - EXPECT_TRUE(Err.empty());
>>> -
>>> - SetStrings SS = FuncPtr<SetStrings>(
>>> - DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
>>> - EXPECT_TRUE(SS != nullptr);
>>> -
>>> - SS(A, B);
>>> - EXPECT_EQ(B, "Local::Local");
>>> - }
>>> - EXPECT_EQ(A, "Global::~Global");
>>> - EXPECT_EQ(B, "Local::~Local");
>>> - EXPECT_TRUE(FuncPtr<SetStrings>(DynamicLibrary::SearchForAddressOfSymbol(
>>> - "SetStrings")) == nullptr);
>>> -}
>>> -
>>> -#else
>>> -
>>> -TEST(DynamicLibrary, Unsupported) {
>>> - std::string Err;
>>> - DynamicLibrary DL =
>>> - DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
>>> - EXPECT_FALSE(DL.isValid());
>>> - EXPECT_EQ(Err, "dlopen() not supported on this platform");
>>> -}
>>> -
>>> -#endif
>>>
>>> Removed: llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.cxx
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.cxx?rev=301239&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.cxx (original)
>>> +++ llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.cxx (removed)
>>> @@ -1,36 +0,0 @@
>>> -//===- llvm/unittest/Support/DynamicLibrary/PipSqueak.cxx -----------------===//
>>> -//
>>> -// The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#include "PipSqueak.h"
>>> -#include <string>
>>> -
>>> -struct Global {
>>> - std::string *Str;
>>> - Global() : Str(nullptr) {}
>>> - ~Global() {
>>> - if (Str)
>>> - *Str = "Global::~Global";
>>> - }
>>> -};
>>> -
>>> -struct Local {
>>> - std::string &Str;
>>> - Local(std::string &S) : Str(S) { Str = "Local::Local"; }
>>> - ~Local() { Str = "Local::~Local"; }
>>> -};
>>> -
>>> -static Global Glb;
>>> -
>>> -extern "C" PIPSQUEAK_EXPORT void SetStrings(std::string &GStr,
>>> - std::string &LStr) {
>>> - static Local Lcl(LStr);
>>> - Glb.Str = &GStr;
>>> -}
>>> -
>>> -extern "C" PIPSQUEAK_EXPORT const char *TestA() { return "LibCall"; }
>>>
>>> Removed: llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.h?rev=301239&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.h (original)
>>> +++ llvm/trunk/unittests/Support/DynamicLibrary/PipSqueak.h (removed)
>>> @@ -1,19 +0,0 @@
>>> -//===- llvm/unittest/Support/DynamicLibrary/PipSqueak.h -------------------===//
>>> -//
>>> -// The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#ifndef LLVM_PIPSQUEAK_H
>>> -#define LLVM_PIPSQUEAK_H
>>> -
>>> -#ifdef _WIN32
>>> -#define PIPSQUEAK_EXPORT __declspec(dllexport)
>>> -#else
>>> -#define PIPSQUEAK_EXPORT
>>> -#endif
>>> -
>>> -#endif
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>> llvm-commits Info Page
>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
>> lists.llvm.org
>> To see the collection of prior postings to the list, visit the
>> llvm-commits Archives. Using llvm-commits: To post a message to all the
>> list members ...
>>
>>
>>
>>>
>>
>>
>> --
>>
>> -Bill Seurer
>>
>
>
> --
>
> -Bill Seurer
>
--
-Bill Seurer
More information about the llvm-commits
mailing list