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