/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/Unix/DynamicLibrary.inc
Line | Count | Source (jump to first uncovered line) |
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 | | |
17 | 289 | DynamicLibrary::HandleSet::~HandleSet() { |
18 | 289 | // Close the libraries in reverse order. |
19 | 289 | for (void *Handle : llvm::reverse(Handles)) |
20 | 99 | ::dlclose(Handle); |
21 | 289 | if (Process) |
22 | 192 | ::dlclose(Process); |
23 | 289 | |
24 | 289 | // llvm_shutdown called, Return to default |
25 | 289 | DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker; |
26 | 289 | } |
27 | | |
28 | 474 | void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { |
29 | 474 | void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL); |
30 | 474 | if (!Handle474 ) { |
31 | 0 | if (Err0 ) *Err = ::dlerror()0 ; |
32 | 0 | return &DynamicLibrary::Invalid; |
33 | 0 | } |
34 | 474 | |
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 | 474 | return Handle; |
43 | 474 | } |
44 | | |
45 | 124 | void DynamicLibrary::HandleSet::DLClose(void *Handle) { |
46 | 124 | ::dlclose(Handle); |
47 | 124 | } |
48 | | |
49 | 255 | void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { |
50 | 255 | return ::dlsym(Handle, Symbol); |
51 | 255 | } |
52 | | |
53 | | #else // !HAVE_DLOPEN |
54 | | |
55 | | DynamicLibrary::HandleSet::~HandleSet() {} |
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 | 22 | static void *DoSearch(const char* SymbolName) { |
73 | 22 | #define EXPLICIT_SYMBOL(SYM) \ |
74 | 22 | extern void *SYM; if (!strcmp(SymbolName, #SYM)) return &SYM |
75 | 22 | |
76 | 22 | // If this is darwin, it has some funky issues, try to solve them here. Some |
77 | 22 | // important symbols are marked 'private external' which doesn't allow |
78 | 22 | // SearchForAddressOfSymbol to find them. As such, we special case them here, |
79 | 22 | // there is only a small handful of them. |
80 | 22 | |
81 | 22 | #ifdef __APPLE__ |
82 | 22 | { |
83 | 22 | // __eprintf is sometimes used for assert() handling on x86. |
84 | 22 | // |
85 | 22 | // FIXME: Currently disabled when using Clang, as we don't always have our |
86 | 22 | // runtime support libraries available. |
87 | | #ifndef __clang__ |
88 | | #ifdef __i386__ |
89 | | EXPLICIT_SYMBOL(__eprintf); |
90 | | #endif |
91 | | #endif |
92 | | } |
93 | 22 | #endif |
94 | 22 | |
95 | | #ifdef __CYGWIN__ |
96 | | { |
97 | | EXPLICIT_SYMBOL(_alloca); |
98 | | EXPLICIT_SYMBOL(__main); |
99 | | } |
100 | | #endif |
101 | | |
102 | 22 | #undef EXPLICIT_SYMBOL |
103 | 22 | |
104 | 22 | // This macro returns the address of a well-known, explicit symbol |
105 | 22 | #define EXPLICIT_SYMBOL(SYM) \ |
106 | 22 | if (!strcmp(SymbolName, #SYM)) return &SYM |
107 | 22 | |
108 | 22 | // Under glibc we have a weird situation. The stderr/out/in symbols are both |
109 | 22 | // macros and global variables because of standards requirements. So, we |
110 | 22 | // 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 | 22 | // as a macro before using EXPLICIT_SYMBOL. |
120 | 22 | { |
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 | 22 | #endif |
132 | 22 | #undef EXPLICIT_SYMBOL |
133 | 22 | |
134 | 22 | return nullptr; |
135 | 22 | } |