This source file includes following definitions.
- get_vtable
- vl_exit
- vm_open
- vm_close
- vm_sym
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include "lt__private.h"
33 #include "lt_dlloader.h"
34
35
36
37
38
39 #define get_vtable dlopen_LTX_get_vtable
40
41 LT_BEGIN_C_DECLS
42 LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data);
43 LT_END_C_DECLS
44
45
46
47
48 static int vl_exit (lt_user_data loader_data);
49 static lt_module vm_open (lt_user_data loader_data, const char *filename,
50 lt_dladvise advise);
51 static int vm_close (lt_user_data loader_data, lt_module module);
52 static void * vm_sym (lt_user_data loader_data, lt_module module,
53 const char *symbolname);
54
55 static lt_dlvtable *vtable = 0;
56
57
58
59
60 lt_dlvtable *
61 get_vtable (lt_user_data loader_data)
62 {
63 if (!vtable)
64 {
65 vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
66 }
67
68 if (vtable && !vtable->name)
69 {
70 vtable->name = "lt_dlopen";
71 #if defined DLSYM_USCORE
72 vtable->sym_prefix = "_";
73 #endif
74 vtable->module_open = vm_open;
75 vtable->module_close = vm_close;
76 vtable->find_sym = vm_sym;
77 vtable->dlloader_exit = vl_exit;
78 vtable->dlloader_data = loader_data;
79 vtable->priority = LT_DLLOADER_PREPEND;
80 }
81
82 if (vtable && (vtable->dlloader_data != loader_data))
83 {
84 LT__SETERROR (INIT_LOADER);
85 return 0;
86 }
87
88 return vtable;
89 }
90
91
92
93
94
95
96 #if defined HAVE_DLFCN_H
97 # include <dlfcn.h>
98 #endif
99
100 #if defined HAVE_SYS_DL_H
101 # include <sys/dl.h>
102 #endif
103
104
105
106
107 #if !defined LT_LAZY_OR_NOW
108 # if defined RTLD_LAZY
109 # define LT_LAZY_OR_NOW RTLD_LAZY
110 # else
111 # if defined DL_LAZY
112 # define LT_LAZY_OR_NOW DL_LAZY
113 # endif
114 # endif
115 #endif
116 #if !defined LT_LAZY_OR_NOW
117 # if defined RTLD_NOW
118 # define LT_LAZY_OR_NOW RTLD_NOW
119 # else
120 # if defined DL_NOW
121 # define LT_LAZY_OR_NOW DL_NOW
122 # endif
123 # endif
124 #endif
125 #if !defined LT_LAZY_OR_NOW
126 # define LT_LAZY_OR_NOW 0
127 #endif
128
129
130
131 #if !defined RTLD_GLOBAL
132 # if defined DL_GLOBAL
133 # define RTLD_GLOBAL DL_GLOBAL
134 # endif
135 #endif
136 #if !defined RTLD_LOCAL
137 # if defined DL_LOCAL
138 # define RTLD_LOCAL DL_LOCAL
139 # endif
140 #endif
141
142 #if defined HAVE_DLERROR
143 # define DLERROR(arg) dlerror ()
144 #else
145 # define DLERROR(arg) LT__STRERROR (arg)
146 #endif
147
148 #define DL__SETERROR(errorcode) \
149 LT__SETERRORSTR (DLERROR (errorcode))
150
151
152
153
154 static int
155 vl_exit (lt_user_data loader_data LT__UNUSED)
156 {
157 vtable = NULL;
158 return 0;
159 }
160
161
162
163
164
165 static lt_module
166 vm_open (lt_user_data loader_data LT__UNUSED, const char *filename,
167 lt_dladvise advise)
168 {
169 int module_flags = LT_LAZY_OR_NOW;
170 lt_module module;
171 #ifdef RTLD_MEMBER
172 int len = LT_STRLEN (filename);
173 #endif
174
175 if (advise)
176 {
177 #ifdef RTLD_GLOBAL
178
179
180 if (advise->is_symglobal)
181 module_flags |= RTLD_GLOBAL;
182 #else
183
184
185 advise->is_symglobal = 0;
186 #endif
187
188
189 #ifdef RTLD_LOCAL
190 if (advise->is_symlocal)
191 module_flags |= RTLD_LOCAL;
192 #else
193 advise->is_symlocal = 0;
194 #endif
195 }
196
197 #ifdef RTLD_MEMBER
198 if (len >= 4)
199 {
200
201
202 if (filename[len-1] == ')')
203 {
204 const char *opening = strrchr(filename, '(');
205 if (opening && opening < (filename+len-2) && strchr(opening+1, '/') == NULL)
206 module_flags |= RTLD_MEMBER;
207 }
208 }
209 #endif
210
211 module = dlopen (filename, module_flags);
212
213 #if defined RTLD_MEMBER && defined LT_SHARED_LIB_MEMBER
214 if (!module && len && !(module_flags & RTLD_MEMBER) && errno == ENOEXEC)
215 {
216
217
218
219
220 const char *member = LT_SHARED_LIB_MEMBER;
221
222 char *attempt = MALLOC (char, len + strlen (member) + 1);
223 if (!attempt)
224 {
225 LT__SETERROR (NO_MEMORY);
226 return module;
227 }
228
229 sprintf (attempt, "%s%s", filename, member);
230 module = vm_open (loader_data, attempt, advise);
231 FREE (attempt);
232 return module;
233 }
234 #endif
235
236 if (!module)
237 {
238 DL__SETERROR (CANNOT_OPEN);
239 }
240
241 return module;
242 }
243
244
245
246
247 static int
248 vm_close (lt_user_data loader_data LT__UNUSED, lt_module module)
249 {
250 int errors = 0;
251
252 if (dlclose (module) != 0)
253 {
254 DL__SETERROR (CANNOT_CLOSE);
255 ++errors;
256 }
257
258 return errors;
259 }
260
261
262
263
264 static void *
265 vm_sym (lt_user_data loader_data LT__UNUSED, lt_module module, const char *name)
266 {
267 void *address = dlsym (module, name);
268
269 if (!address)
270 {
271 DL__SETERROR (SYMBOL_NOT_FOUND);
272 }
273
274 return address;
275 }