DynamicLibrary.inc revision 319799
1317683Sdim//===- Unix/DynamicLibrary.cpp - Unix DL Implementation ---------*- C++ -*-===// 2317683Sdim// 3317683Sdim// The LLVM Compiler Infrastructure 4317683Sdim// 5317683Sdim// This file is distributed under the University of Illinois Open Source 6317683Sdim// License. See LICENSE.TXT for details. 7317683Sdim// 8317683Sdim//===----------------------------------------------------------------------===// 9317683Sdim// 10317683Sdim// This file provides the UNIX specific implementation of DynamicLibrary. 11317683Sdim// 12317683Sdim//===----------------------------------------------------------------------===// 13317683Sdim 14317683Sdim#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN) 15317683Sdim#include <dlfcn.h> 16317683Sdim 17317683SdimDynamicLibrary::HandleSet::~HandleSet() { 18319799Sdim // Close the libraries in reverse order. 19319799Sdim for (void *Handle : llvm::reverse(Handles)) 20317683Sdim ::dlclose(Handle); 21317683Sdim if (Process) 22317683Sdim ::dlclose(Process); 23317683Sdim} 24317683Sdim 25317683Sdimvoid *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { 26317683Sdim void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL); 27317683Sdim if (!Handle) { 28317683Sdim if (Err) *Err = ::dlerror(); 29317683Sdim return &DynamicLibrary::Invalid; 30317683Sdim } 31317683Sdim 32317683Sdim#ifdef __CYGWIN__ 33317683Sdim // Cygwin searches symbols only in the main 34317683Sdim // with the handle of dlopen(NULL, RTLD_GLOBAL). 35317969Sdim if (!File) 36317683Sdim Handle = RTLD_DEFAULT; 37317683Sdim#endif 38317683Sdim 39317683Sdim return Handle; 40317683Sdim} 41317683Sdim 42317683Sdimvoid DynamicLibrary::HandleSet::DLClose(void *Handle) { 43317683Sdim ::dlclose(Handle); 44317683Sdim} 45317683Sdim 46317683Sdimvoid *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { 47317683Sdim return ::dlsym(Handle, Symbol); 48317683Sdim} 49317683Sdim 50317683Sdim#else // !HAVE_DLOPEN 51317683Sdim 52317683SdimDynamicLibrary::HandleSet::~HandleSet() {} 53317683Sdim 54317683Sdimvoid *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { 55317683Sdim if (Err) *Err = "dlopen() not supported on this platform"; 56317683Sdim return &Invalid; 57317683Sdim} 58317683Sdim 59317683Sdimvoid DynamicLibrary::HandleSet::DLClose(void *Handle) { 60317683Sdim} 61317683Sdim 62317683Sdimvoid *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { 63317683Sdim return nullptr; 64317683Sdim} 65317683Sdim 66317683Sdim#endif 67317683Sdim 68317683Sdim// Must declare the symbols in the global namespace. 69317683Sdimstatic void *DoSearch(const char* SymbolName) { 70317683Sdim#define EXPLICIT_SYMBOL(SYM) \ 71317683Sdim extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM 72317683Sdim 73317683Sdim // If this is darwin, it has some funky issues, try to solve them here. Some 74317683Sdim // important symbols are marked 'private external' which doesn't allow 75317683Sdim // SearchForAddressOfSymbol to find them. As such, we special case them here, 76317683Sdim // there is only a small handful of them. 77317683Sdim 78317683Sdim#ifdef __APPLE__ 79317683Sdim { 80317683Sdim // __eprintf is sometimes used for assert() handling on x86. 81317683Sdim // 82317683Sdim // FIXME: Currently disabled when using Clang, as we don't always have our 83317683Sdim // runtime support libraries available. 84317683Sdim#ifndef __clang__ 85317683Sdim#ifdef __i386__ 86317683Sdim EXPLICIT_SYMBOL(__eprintf); 87317683Sdim#endif 88317683Sdim#endif 89317683Sdim } 90317683Sdim#endif 91317683Sdim 92317683Sdim#ifdef __CYGWIN__ 93317683Sdim { 94317683Sdim EXPLICIT_SYMBOL(_alloca); 95317683Sdim EXPLICIT_SYMBOL(__main); 96317683Sdim } 97317683Sdim#endif 98317683Sdim 99317683Sdim#undef EXPLICIT_SYMBOL 100317683Sdim 101317683Sdim// This macro returns the address of a well-known, explicit symbol 102317683Sdim#define EXPLICIT_SYMBOL(SYM) \ 103317683Sdim if (!strcmp(SymbolName, #SYM)) return &SYM 104317683Sdim 105319799Sdim// Under glibc we have a weird situation. The stderr/out/in symbols are both 106317683Sdim// macros and global variables because of standards requirements. So, we 107317683Sdim// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. 108319799Sdim#if defined(__GLIBC__) 109317683Sdim { 110317683Sdim EXPLICIT_SYMBOL(stderr); 111317683Sdim EXPLICIT_SYMBOL(stdout); 112317683Sdim EXPLICIT_SYMBOL(stdin); 113317683Sdim } 114317683Sdim#else 115317683Sdim // For everything else, we want to check to make sure the symbol isn't defined 116317683Sdim // as a macro before using EXPLICIT_SYMBOL. 117317683Sdim { 118317683Sdim#ifndef stdin 119317683Sdim EXPLICIT_SYMBOL(stdin); 120317683Sdim#endif 121317683Sdim#ifndef stdout 122317683Sdim EXPLICIT_SYMBOL(stdout); 123317683Sdim#endif 124317683Sdim#ifndef stderr 125317683Sdim EXPLICIT_SYMBOL(stderr); 126317683Sdim#endif 127317683Sdim } 128317683Sdim#endif 129317683Sdim#undef EXPLICIT_SYMBOL 130317683Sdim 131317683Sdim return nullptr; 132317683Sdim} 133