DynamicLibrary.inc revision 320970
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); 23320970Sdim 24320970Sdim // llvm_shutdown called, Return to default 25320970Sdim DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker; 26317683Sdim} 27317683Sdim 28317683Sdimvoid *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { 29317683Sdim void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL); 30317683Sdim if (!Handle) { 31317683Sdim if (Err) *Err = ::dlerror(); 32317683Sdim return &DynamicLibrary::Invalid; 33317683Sdim } 34317683Sdim 35317683Sdim#ifdef __CYGWIN__ 36317683Sdim // Cygwin searches symbols only in the main 37317683Sdim // with the handle of dlopen(NULL, RTLD_GLOBAL). 38317969Sdim if (!File) 39317683Sdim Handle = RTLD_DEFAULT; 40317683Sdim#endif 41317683Sdim 42317683Sdim return Handle; 43317683Sdim} 44317683Sdim 45317683Sdimvoid DynamicLibrary::HandleSet::DLClose(void *Handle) { 46317683Sdim ::dlclose(Handle); 47317683Sdim} 48317683Sdim 49317683Sdimvoid *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { 50317683Sdim return ::dlsym(Handle, Symbol); 51317683Sdim} 52317683Sdim 53317683Sdim#else // !HAVE_DLOPEN 54317683Sdim 55317683SdimDynamicLibrary::HandleSet::~HandleSet() {} 56317683Sdim 57317683Sdimvoid *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { 58317683Sdim if (Err) *Err = "dlopen() not supported on this platform"; 59317683Sdim return &Invalid; 60317683Sdim} 61317683Sdim 62317683Sdimvoid DynamicLibrary::HandleSet::DLClose(void *Handle) { 63317683Sdim} 64317683Sdim 65317683Sdimvoid *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { 66317683Sdim return nullptr; 67317683Sdim} 68317683Sdim 69317683Sdim#endif 70317683Sdim 71317683Sdim// Must declare the symbols in the global namespace. 72317683Sdimstatic void *DoSearch(const char* SymbolName) { 73317683Sdim#define EXPLICIT_SYMBOL(SYM) \ 74317683Sdim extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM 75317683Sdim 76317683Sdim // If this is darwin, it has some funky issues, try to solve them here. Some 77317683Sdim // important symbols are marked 'private external' which doesn't allow 78317683Sdim // SearchForAddressOfSymbol to find them. As such, we special case them here, 79317683Sdim // there is only a small handful of them. 80317683Sdim 81317683Sdim#ifdef __APPLE__ 82317683Sdim { 83317683Sdim // __eprintf is sometimes used for assert() handling on x86. 84317683Sdim // 85317683Sdim // FIXME: Currently disabled when using Clang, as we don't always have our 86317683Sdim // runtime support libraries available. 87317683Sdim#ifndef __clang__ 88317683Sdim#ifdef __i386__ 89317683Sdim EXPLICIT_SYMBOL(__eprintf); 90317683Sdim#endif 91317683Sdim#endif 92317683Sdim } 93317683Sdim#endif 94317683Sdim 95317683Sdim#ifdef __CYGWIN__ 96317683Sdim { 97317683Sdim EXPLICIT_SYMBOL(_alloca); 98317683Sdim EXPLICIT_SYMBOL(__main); 99317683Sdim } 100317683Sdim#endif 101317683Sdim 102317683Sdim#undef EXPLICIT_SYMBOL 103317683Sdim 104317683Sdim// This macro returns the address of a well-known, explicit symbol 105317683Sdim#define EXPLICIT_SYMBOL(SYM) \ 106317683Sdim if (!strcmp(SymbolName, #SYM)) return &SYM 107317683Sdim 108319799Sdim// Under glibc we have a weird situation. The stderr/out/in symbols are both 109317683Sdim// macros and global variables because of standards requirements. So, we 110317683Sdim// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. 111319799Sdim#if defined(__GLIBC__) 112317683Sdim { 113317683Sdim EXPLICIT_SYMBOL(stderr); 114317683Sdim EXPLICIT_SYMBOL(stdout); 115317683Sdim EXPLICIT_SYMBOL(stdin); 116317683Sdim } 117317683Sdim#else 118317683Sdim // For everything else, we want to check to make sure the symbol isn't defined 119317683Sdim // as a macro before using EXPLICIT_SYMBOL. 120317683Sdim { 121317683Sdim#ifndef stdin 122317683Sdim EXPLICIT_SYMBOL(stdin); 123317683Sdim#endif 124317683Sdim#ifndef stdout 125317683Sdim EXPLICIT_SYMBOL(stdout); 126317683Sdim#endif 127317683Sdim#ifndef stderr 128317683Sdim EXPLICIT_SYMBOL(stderr); 129317683Sdim#endif 130317683Sdim } 131317683Sdim#endif 132317683Sdim#undef EXPLICIT_SYMBOL 133317683Sdim 134317683Sdim return nullptr; 135317683Sdim} 136