LLVM  8.0.1
DynamicLibrary.inc
Go to the documentation of this file.
1 //===- Unix/DynamicLibrary.cpp - Unix DL Implementation ---------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides the UNIX specific implementation of DynamicLibrary.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
15 #include <dlfcn.h>
16 
18  // Close the libraries in reverse order.
19  for (void *Handle : llvm::reverse(Handles))
20  ::dlclose(Handle);
21  if (Process)
22  ::dlclose(Process);
23 
24  // llvm_shutdown called, Return to default
25  DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
26 }
27 
28 void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
29  void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
30  if (!Handle) {
31  if (Err) *Err = ::dlerror();
33  }
34 
35 #ifdef __CYGWIN__
36  // Cygwin searches symbols only in the main
37  // with the handle of dlopen(NULL, RTLD_GLOBAL).
38  if (!File)
39  Handle = RTLD_DEFAULT;
40 #endif
41 
42  return Handle;
43 }
44 
45 void DynamicLibrary::HandleSet::DLClose(void *Handle) {
46  ::dlclose(Handle);
47 }
48 
49 void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
50  return ::dlsym(Handle, Symbol);
51 }
52 
53 #else // !HAVE_DLOPEN
54 
56 
57 void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
58  if (Err) *Err = "dlopen() not supported on this platform";
59  return &Invalid;
60 }
61 
62 void DynamicLibrary::HandleSet::DLClose(void *Handle) {
63 }
64 
65 void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
66  return nullptr;
67 }
68 
69 #endif
70 
71 // Must declare the symbols in the global namespace.
72 static void *DoSearch(const char* SymbolName) {
73 #define EXPLICIT_SYMBOL(SYM) \
74  extern void *SYM; if (!strcmp(SymbolName, #SYM)) return (void*)&SYM
75 
76  // If this is darwin, it has some funky issues, try to solve them here. Some
77  // important symbols are marked 'private external' which doesn't allow
78  // SearchForAddressOfSymbol to find them. As such, we special case them here,
79  // there is only a small handful of them.
80 
81 #ifdef __APPLE__
82  {
83  // __eprintf is sometimes used for assert() handling on x86.
84  //
85  // FIXME: Currently disabled when using Clang, as we don't always have our
86  // runtime support libraries available.
87 #ifndef __clang__
88 #ifdef __i386__
89  EXPLICIT_SYMBOL(__eprintf);
90 #endif
91 #endif
92  }
93 #endif
94 
95 #ifdef __CYGWIN__
96  {
97  EXPLICIT_SYMBOL(_alloca);
98  EXPLICIT_SYMBOL(__main);
99  }
100 #endif
101 
102 #undef EXPLICIT_SYMBOL
103 
104 // This macro returns the address of a well-known, explicit symbol
105 #define EXPLICIT_SYMBOL(SYM) \
106  if (!strcmp(SymbolName, #SYM)) return &SYM
107 
108 // Under glibc we have a weird situation. The stderr/out/in symbols are both
109 // macros and global variables because of standards requirements. So, we
110 // boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
111 #if defined(__GLIBC__)
112  {
113  EXPLICIT_SYMBOL(stderr);
114  EXPLICIT_SYMBOL(stdout);
115  EXPLICIT_SYMBOL(stdin);
116  }
117 #else
118  // For everything else, we want to check to make sure the symbol isn't defined
119  // as a macro before using EXPLICIT_SYMBOL.
120  {
121 #ifndef stdin
122  EXPLICIT_SYMBOL(stdin);
123 #endif
124 #ifndef stdout
125  EXPLICIT_SYMBOL(stdout);
126 #endif
127 #ifndef stderr
128  EXPLICIT_SYMBOL(stderr);
129 #endif
130  }
131 #endif
132 #undef EXPLICIT_SYMBOL
133 
134  return nullptr;
135 }
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
static void * DLSym(void *Handle, const char *Symbol)
static void * DLOpen(const char *Filename, std::string *Err)
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Definition: STLExtras.h:267
static void DLClose(void *Handle)