From 1f6efa3996dd1929fbc129203ce5009b620e6969 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Mon, 29 Nov 2010 18:16:10 +0000 Subject: Merge System into Support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120298 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/DynamicLibrary.cpp | 177 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 lib/Support/DynamicLibrary.cpp (limited to 'lib/Support/DynamicLibrary.cpp') diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp new file mode 100644 index 0000000..cd9927a --- /dev/null +++ b/lib/Support/DynamicLibrary.cpp @@ -0,0 +1,177 @@ +//===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header file implements the operating system DynamicLibrary concept. +// +// FIXME: This file leaks the ExplicitSymbols and OpenedHandles vector, and is +// not thread safe! +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Config/config.h" +#include +#include +#include +#include + +// Collection of symbol name/value pairs to be searched prior to any libraries. +static std::map *ExplicitSymbols = 0; + +namespace { + +struct ExplicitSymbolsDeleter { + ~ExplicitSymbolsDeleter() { + if (ExplicitSymbols) + delete ExplicitSymbols; + } +}; + +} + +static ExplicitSymbolsDeleter Dummy; + +void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName, + void *symbolValue) { + if (ExplicitSymbols == 0) + ExplicitSymbols = new std::map(); + (*ExplicitSymbols)[symbolName] = symbolValue; +} + +#ifdef LLVM_ON_WIN32 + +#include "Windows/DynamicLibrary.inc" + +#else + +#if HAVE_DLFCN_H +#include +using namespace llvm; +using namespace llvm::sys; + +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only TRULY operating system +//=== independent code. +//===----------------------------------------------------------------------===// + +static SmartMutex* HandlesMutex; +static std::vector *OpenedHandles = 0; + +static bool InitializeMutex() { + HandlesMutex = new SmartMutex; + return HandlesMutex != 0; +} + +static bool EnsureMutexInitialized() { + static bool result = InitializeMutex(); + return result; +} + + +bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, + std::string *ErrMsg) { + void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL); + if (H == 0) { + if (ErrMsg) *ErrMsg = dlerror(); + return true; + } +#ifdef __CYGWIN__ + // Cygwin searches symbols only in the main + // with the handle of dlopen(NULL, RTLD_GLOBAL). + if (Filename == NULL) + H = RTLD_DEFAULT; +#endif + EnsureMutexInitialized(); + SmartScopedLock Lock(*HandlesMutex); + if (OpenedHandles == 0) + OpenedHandles = new std::vector(); + OpenedHandles->push_back(H); + return false; +} +#else + +using namespace llvm; +using namespace llvm::sys; + +bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, + std::string *ErrMsg) { + if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform"; + return true; +} +#endif + +namespace llvm { +void *SearchForAddressOfSpecialSymbol(const char* symbolName); +} + +void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { + // First check symbols added via AddSymbol(). + if (ExplicitSymbols) { + std::map::iterator I = + ExplicitSymbols->find(symbolName); + std::map::iterator E = ExplicitSymbols->end(); + + if (I != E) + return I->second; + } + +#if HAVE_DLFCN_H + // Now search the libraries. + EnsureMutexInitialized(); + SmartScopedLock Lock(*HandlesMutex); + if (OpenedHandles) { + for (std::vector::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 + + 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__) + { + 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 0; +} + +#endif // LLVM_ON_WIN32 -- cgit v1.1 From 0ea112f104215ccba8d89c839cdeded6e3d49e59 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Tue, 7 Dec 2010 07:56:20 +0000 Subject: Don't leak the mutex when loading dynamic libraries. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121119 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/DynamicLibrary.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'lib/Support/DynamicLibrary.cpp') diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp index cd9927a..455c380 100644 --- a/lib/Support/DynamicLibrary.cpp +++ b/lib/Support/DynamicLibrary.cpp @@ -61,17 +61,12 @@ using namespace llvm::sys; //=== independent code. //===----------------------------------------------------------------------===// -static SmartMutex* HandlesMutex; static std::vector *OpenedHandles = 0; -static bool InitializeMutex() { - HandlesMutex = new SmartMutex; - return HandlesMutex != 0; -} -static bool EnsureMutexInitialized() { - static bool result = InitializeMutex(); - return result; +static SmartMutex& getMutex() { + static SmartMutex HandlesMutex; + return HandlesMutex; } @@ -88,8 +83,7 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, if (Filename == NULL) H = RTLD_DEFAULT; #endif - EnsureMutexInitialized(); - SmartScopedLock Lock(*HandlesMutex); + SmartScopedLock Lock(getMutex()); if (OpenedHandles == 0) OpenedHandles = new std::vector(); OpenedHandles->push_back(H); @@ -124,8 +118,7 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { #if HAVE_DLFCN_H // Now search the libraries. - EnsureMutexInitialized(); - SmartScopedLock Lock(*HandlesMutex); + SmartScopedLock Lock(getMutex()); if (OpenedHandles) { for (std::vector::iterator I = OpenedHandles->begin(), E = OpenedHandles->end(); I != E; ++I) { -- cgit v1.1