DynamicLibrary.cpp revision 276479
194670Sdes//===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===// 294670Sdes// 394670Sdes// The LLVM Compiler Infrastructure 494670Sdes// 594670Sdes// This file is distributed under the University of Illinois Open Source 699158Sdes// License. See LICENSE.TXT for details. 799158Sdes// 899158Sdes//===----------------------------------------------------------------------===// 994670Sdes// 1094670Sdes// This file implements the operating system DynamicLibrary concept. 1194670Sdes// 1294670Sdes// FIXME: This file leaks ExplicitSymbols and OpenedHandles! 1394670Sdes// 1494670Sdes//===----------------------------------------------------------------------===// 1594670Sdes 1694670Sdes#include "llvm/Support/DynamicLibrary.h" 1794670Sdes#include "llvm-c/Support.h" 1894670Sdes#include "llvm/ADT/DenseSet.h" 1994670Sdes#include "llvm/ADT/StringMap.h" 2094670Sdes#include "llvm/Config/config.h" 2194670Sdes#include "llvm/Support/ManagedStatic.h" 2294670Sdes#include "llvm/Support/Mutex.h" 2394670Sdes#include <cstdio> 2494670Sdes#include <cstring> 2594670Sdes 2694670Sdes// Collection of symbol name/value pairs to be searched prior to any libraries. 2794670Sdesstatic llvm::ManagedStatic<llvm::StringMap<void *> > ExplicitSymbols; 2894670Sdesstatic llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SymbolsMutex; 2994670Sdes 3094670Sdesvoid llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName, 3194670Sdes void *symbolValue) { 3294670Sdes SmartScopedLock<true> lock(*SymbolsMutex); 3394670Sdes (*ExplicitSymbols)[symbolName] = symbolValue; 3499158Sdes} 3594670Sdes 3694670Sdeschar llvm::sys::DynamicLibrary::Invalid = 0; 3794670Sdes 3894670Sdes#ifdef LLVM_ON_WIN32 3994670Sdes 4094670Sdes#include "Windows/DynamicLibrary.inc" 4194670Sdes 4294670Sdes#else 4394670Sdes 4494670Sdes#if HAVE_DLFCN_H 4594670Sdes#include <dlfcn.h> 4694670Sdesusing namespace llvm; 4794670Sdesusing namespace llvm::sys; 4894670Sdes 4994670Sdes//===----------------------------------------------------------------------===// 5094670Sdes//=== WARNING: Implementation here must contain only TRULY operating system 5194670Sdes//=== independent code. 5294670Sdes//===----------------------------------------------------------------------===// 5395908Sdes 5494670Sdesstatic DenseSet<void *> *OpenedHandles = nullptr; 5594670Sdes 5694670SdesDynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, 5794670Sdes std::string *errMsg) { 5894670Sdes SmartScopedLock<true> lock(*SymbolsMutex); 5994670Sdes 6094670Sdes void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL); 6194670Sdes if (!handle) { 6294670Sdes if (errMsg) *errMsg = dlerror(); 6394670Sdes return DynamicLibrary(); 6494670Sdes } 6594670Sdes 6694670Sdes#ifdef __CYGWIN__ 6794670Sdes // Cygwin searches symbols only in the main 6894670Sdes // with the handle of dlopen(NULL, RTLD_GLOBAL). 6994670Sdes if (!filename) 7094670Sdes handle = RTLD_DEFAULT; 7194670Sdes#endif 7294670Sdes 7394670Sdes if (!OpenedHandles) 7494670Sdes OpenedHandles = new DenseSet<void *>(); 7594670Sdes 7694670Sdes // If we've already loaded this library, dlclose() the handle in order to 7794670Sdes // keep the internal refcount at +1. 7894670Sdes if (!OpenedHandles->insert(handle).second) 7994670Sdes dlclose(handle); 8094670Sdes 8194670Sdes return DynamicLibrary(handle); 8294670Sdes} 8394670Sdes 8494670Sdesvoid *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { 8594670Sdes if (!isValid()) 8694670Sdes return nullptr; 8794670Sdes return dlsym(Data, symbolName); 8894670Sdes} 8994670Sdes 9094670Sdes#else 9194670Sdes 9294670Sdesusing namespace llvm; 9394670Sdesusing namespace llvm::sys; 9494670Sdes 9594670SdesDynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, 9694670Sdes std::string *errMsg) { 9794670Sdes if (errMsg) *errMsg = "dlopen() not supported on this platform"; 9894670Sdes return DynamicLibrary(); 9994670Sdes} 10094670Sdes 10194670Sdesvoid *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { 10294670Sdes return NULL; 10394670Sdes} 10494670Sdes 10594670Sdes#endif 10694670Sdes 10794670Sdesnamespace llvm { 10894670Sdesvoid *SearchForAddressOfSpecialSymbol(const char* symbolName); 10994670Sdes} 11094670Sdes 11194670Sdesvoid* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) { 11294670Sdes SmartScopedLock<true> Lock(*SymbolsMutex); 11394670Sdes 11494670Sdes // First check symbols added via AddSymbol(). 11594670Sdes if (ExplicitSymbols.isConstructed()) { 11694670Sdes StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName); 11794670Sdes 11894670Sdes if (i != ExplicitSymbols->end()) 11994670Sdes return i->second; 12094670Sdes } 12194670Sdes 12294670Sdes#if HAVE_DLFCN_H 12394670Sdes // Now search the libraries. 12494670Sdes if (OpenedHandles) { 12594670Sdes for (DenseSet<void *>::iterator I = OpenedHandles->begin(), 12694670Sdes E = OpenedHandles->end(); I != E; ++I) { 12794670Sdes //lt_ptr ptr = lt_dlsym(*I, symbolName); 12894670Sdes void *ptr = dlsym(*I, symbolName); 12994670Sdes if (ptr) { 13094670Sdes return ptr; 13194670Sdes } 13294670Sdes } 13394670Sdes } 13494670Sdes#endif 13594670Sdes 13694670Sdes if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName)) 13794670Sdes return Result; 13894670Sdes 13994670Sdes// This macro returns the address of a well-known, explicit symbol 14094670Sdes#define EXPLICIT_SYMBOL(SYM) \ 14194670Sdes if (!strcmp(symbolName, #SYM)) return &SYM 14294670Sdes 14394670Sdes// On linux we have a weird situation. The stderr/out/in symbols are both 14494670Sdes// macros and global variables because of standards requirements. So, we 14594670Sdes// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. 14694670Sdes#if defined(__linux__) and !defined(__ANDROID__) 14794670Sdes { 14894670Sdes EXPLICIT_SYMBOL(stderr); 14994670Sdes EXPLICIT_SYMBOL(stdout); 15094670Sdes EXPLICIT_SYMBOL(stdin); 15194670Sdes } 15294670Sdes#else 15399158Sdes // For everything else, we want to check to make sure the symbol isn't defined 15499158Sdes // as a macro before using EXPLICIT_SYMBOL. 15594670Sdes { 15694670Sdes#ifndef stdin 15794670Sdes EXPLICIT_SYMBOL(stdin); 15894670Sdes#endif 15994670Sdes#ifndef stdout 16094670Sdes EXPLICIT_SYMBOL(stdout); 16194670Sdes#endif 16294670Sdes#ifndef stderr 16394670Sdes EXPLICIT_SYMBOL(stderr); 16494670Sdes#endif 16594670Sdes } 16694670Sdes#endif 16794670Sdes#undef EXPLICIT_SYMBOL 16894670Sdes 16994670Sdes return nullptr; 17094670Sdes} 17194670Sdes 17294670Sdes#endif // LLVM_ON_WIN32 17394670Sdes 17494670Sdes//===----------------------------------------------------------------------===// 17594670Sdes// C API. 17694670Sdes//===----------------------------------------------------------------------===// 17794670Sdes 17894670SdesLLVMBool LLVMLoadLibraryPermanently(const char* Filename) { 17994670Sdes return llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename); 18094670Sdes} 18194670Sdes