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