Mercurial > hg > CbC > CbC_llvm
comparison lib/Support/DynamicLibrary.cpp @ 3:9ad51c7bc036
1st commit. remove git dir and add all files.
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 15 May 2013 06:43:32 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 3:9ad51c7bc036 |
---|---|
1 //===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- 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 header file implements the operating system DynamicLibrary concept. | |
11 // | |
12 // FIXME: This file leaks ExplicitSymbols and OpenedHandles! | |
13 // | |
14 //===----------------------------------------------------------------------===// | |
15 | |
16 #include "llvm/Support/DynamicLibrary.h" | |
17 #include "llvm/ADT/DenseSet.h" | |
18 #include "llvm/ADT/StringMap.h" | |
19 #include "llvm/Config/config.h" | |
20 #include "llvm/Support/Mutex.h" | |
21 #include <cstdio> | |
22 #include <cstring> | |
23 | |
24 // Collection of symbol name/value pairs to be searched prior to any libraries. | |
25 static llvm::StringMap<void *> *ExplicitSymbols = 0; | |
26 | |
27 namespace { | |
28 | |
29 struct ExplicitSymbolsDeleter { | |
30 ~ExplicitSymbolsDeleter() { | |
31 delete ExplicitSymbols; | |
32 } | |
33 }; | |
34 | |
35 } | |
36 | |
37 static ExplicitSymbolsDeleter Dummy; | |
38 | |
39 | |
40 static llvm::sys::SmartMutex<true>& getMutex() { | |
41 static llvm::sys::SmartMutex<true> HandlesMutex; | |
42 return HandlesMutex; | |
43 } | |
44 | |
45 void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName, | |
46 void *symbolValue) { | |
47 SmartScopedLock<true> lock(getMutex()); | |
48 if (ExplicitSymbols == 0) | |
49 ExplicitSymbols = new StringMap<void*>(); | |
50 (*ExplicitSymbols)[symbolName] = symbolValue; | |
51 } | |
52 | |
53 char llvm::sys::DynamicLibrary::Invalid = 0; | |
54 | |
55 #ifdef LLVM_ON_WIN32 | |
56 | |
57 #include "Windows/DynamicLibrary.inc" | |
58 | |
59 #else | |
60 | |
61 #if HAVE_DLFCN_H | |
62 #include <dlfcn.h> | |
63 using namespace llvm; | |
64 using namespace llvm::sys; | |
65 | |
66 //===----------------------------------------------------------------------===// | |
67 //=== WARNING: Implementation here must contain only TRULY operating system | |
68 //=== independent code. | |
69 //===----------------------------------------------------------------------===// | |
70 | |
71 static DenseSet<void *> *OpenedHandles = 0; | |
72 | |
73 DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, | |
74 std::string *errMsg) { | |
75 SmartScopedLock<true> lock(getMutex()); | |
76 | |
77 void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL); | |
78 if (handle == 0) { | |
79 if (errMsg) *errMsg = dlerror(); | |
80 return DynamicLibrary(); | |
81 } | |
82 | |
83 #ifdef __CYGWIN__ | |
84 // Cygwin searches symbols only in the main | |
85 // with the handle of dlopen(NULL, RTLD_GLOBAL). | |
86 if (filename == NULL) | |
87 handle = RTLD_DEFAULT; | |
88 #endif | |
89 | |
90 if (OpenedHandles == 0) | |
91 OpenedHandles = new DenseSet<void *>(); | |
92 | |
93 // If we've already loaded this library, dlclose() the handle in order to | |
94 // keep the internal refcount at +1. | |
95 if (!OpenedHandles->insert(handle).second) | |
96 dlclose(handle); | |
97 | |
98 return DynamicLibrary(handle); | |
99 } | |
100 | |
101 void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { | |
102 if (!isValid()) | |
103 return NULL; | |
104 return dlsym(Data, symbolName); | |
105 } | |
106 | |
107 #else | |
108 | |
109 using namespace llvm; | |
110 using namespace llvm::sys; | |
111 | |
112 DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, | |
113 std::string *errMsg) { | |
114 if (errMsg) *errMsg = "dlopen() not supported on this platform"; | |
115 return DynamicLibrary(); | |
116 } | |
117 | |
118 void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { | |
119 return NULL; | |
120 } | |
121 | |
122 #endif | |
123 | |
124 namespace llvm { | |
125 void *SearchForAddressOfSpecialSymbol(const char* symbolName); | |
126 } | |
127 | |
128 void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) { | |
129 SmartScopedLock<true> Lock(getMutex()); | |
130 | |
131 // First check symbols added via AddSymbol(). | |
132 if (ExplicitSymbols) { | |
133 StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName); | |
134 | |
135 if (i != ExplicitSymbols->end()) | |
136 return i->second; | |
137 } | |
138 | |
139 #if HAVE_DLFCN_H | |
140 // Now search the libraries. | |
141 if (OpenedHandles) { | |
142 for (DenseSet<void *>::iterator I = OpenedHandles->begin(), | |
143 E = OpenedHandles->end(); I != E; ++I) { | |
144 //lt_ptr ptr = lt_dlsym(*I, symbolName); | |
145 void *ptr = dlsym(*I, symbolName); | |
146 if (ptr) { | |
147 return ptr; | |
148 } | |
149 } | |
150 } | |
151 #endif | |
152 | |
153 if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName)) | |
154 return Result; | |
155 | |
156 // This macro returns the address of a well-known, explicit symbol | |
157 #define EXPLICIT_SYMBOL(SYM) \ | |
158 if (!strcmp(symbolName, #SYM)) return &SYM | |
159 | |
160 // On linux we have a weird situation. The stderr/out/in symbols are both | |
161 // macros and global variables because of standards requirements. So, we | |
162 // boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. | |
163 #if defined(__linux__) and !defined(__ANDROID__) | |
164 { | |
165 EXPLICIT_SYMBOL(stderr); | |
166 EXPLICIT_SYMBOL(stdout); | |
167 EXPLICIT_SYMBOL(stdin); | |
168 } | |
169 #else | |
170 // For everything else, we want to check to make sure the symbol isn't defined | |
171 // as a macro before using EXPLICIT_SYMBOL. | |
172 { | |
173 #ifndef stdin | |
174 EXPLICIT_SYMBOL(stdin); | |
175 #endif | |
176 #ifndef stdout | |
177 EXPLICIT_SYMBOL(stdout); | |
178 #endif | |
179 #ifndef stderr | |
180 EXPLICIT_SYMBOL(stderr); | |
181 #endif | |
182 } | |
183 #endif | |
184 #undef EXPLICIT_SYMBOL | |
185 | |
186 return 0; | |
187 } | |
188 | |
189 #endif // LLVM_ON_WIN32 |