This source file includes following definitions.
- get_vtable
- vl_init
- vl_exit
- vm_open
- vm_close
- vm_sym
- free_symlists
- add_symlist
- lt_dlpreload_default
- lt_dlpreload
- lt_dlpreload_open
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 preopen_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_init (lt_user_data loader_data);
49 static int vl_exit (lt_user_data loader_data);
50 static lt_module vm_open (lt_user_data loader_data, const char *filename,
51 lt_dladvise advise);
52 static int vm_close (lt_user_data loader_data, lt_module module);
53 static void * vm_sym (lt_user_data loader_data, lt_module module,
54 const char *symbolname);
55
56 static lt_dlvtable *vtable = 0;
57
58
59
60
61 lt_dlvtable *
62 get_vtable (lt_user_data loader_data)
63 {
64 if (!vtable)
65 {
66 vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
67 }
68
69 if (vtable && !vtable->name)
70 {
71 vtable->name = "lt_preopen";
72 vtable->sym_prefix = 0;
73 vtable->module_open = vm_open;
74 vtable->module_close = vm_close;
75 vtable->find_sym = vm_sym;
76 vtable->dlloader_init = vl_init;
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
97 typedef struct symlist_chain
98 {
99 struct symlist_chain *next;
100 const lt_dlsymlist *symlist;
101 } symlist_chain;
102
103
104 static int add_symlist (const lt_dlsymlist *symlist);
105 static int free_symlists (void);
106
107
108 static symlist_chain *preloaded_symlists = 0;
109
110
111 static const lt_dlsymlist *default_preloaded_symbols = 0;
112
113
114
115 static int
116 vl_init (lt_user_data LT__UNUSED loader_data)
117 {
118 int errors = 0;
119
120 preloaded_symlists = 0;
121 if (default_preloaded_symbols)
122 {
123 errors = lt_dlpreload (default_preloaded_symbols);
124 }
125
126 return errors;
127 }
128
129
130
131
132 static int
133 vl_exit (lt_user_data LT__UNUSED loader_data)
134 {
135 vtable = NULL;
136 free_symlists ();
137 return 0;
138 }
139
140
141
142
143
144 static lt_module
145 vm_open (lt_user_data LT__UNUSED loader_data, const char *filename,
146 lt_dladvise LT__UNUSED advise)
147 {
148 symlist_chain *lists;
149 lt_module module = 0;
150
151 if (!preloaded_symlists)
152 {
153 LT__SETERROR (NO_SYMBOLS);
154 goto done;
155 }
156
157
158
159
160
161 if (!filename)
162 {
163 filename = "@PROGRAM@";
164 }
165
166 for (lists = preloaded_symlists; lists; lists = lists->next)
167 {
168 const lt_dlsymlist *symbol;
169 for (symbol= lists->symlist; symbol->name; ++symbol)
170 {
171 if (!symbol->address && streq (symbol->name, filename))
172 {
173
174
175
176
177
178 const lt_dlsymlist *next_symbol = symbol +1;
179 if (next_symbol->address && next_symbol->name)
180 {
181 module = (lt_module) lists->symlist;
182 goto done;
183 }
184 }
185 }
186 }
187
188 LT__SETERROR (FILE_NOT_FOUND);
189
190 done:
191 return module;
192 }
193
194
195
196
197 static int
198 vm_close (lt_user_data LT__UNUSED loader_data, lt_module LT__UNUSED module)
199 {
200
201 module = 0;
202 return 0;
203 }
204
205
206
207
208 static void *
209 vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name)
210 {
211 lt_dlsymlist *symbol = (lt_dlsymlist*) module;
212
213 symbol +=2;
214
215 while (symbol->name)
216 {
217 if (streq (symbol->name, name))
218 {
219 return symbol->address;
220 }
221
222 ++symbol;
223 }
224
225 LT__SETERROR (SYMBOL_NOT_FOUND);
226
227 return 0;
228 }
229
230
231
232
233
234
235
236
237 static int
238 free_symlists (void)
239 {
240 symlist_chain *lists;
241
242 lists = preloaded_symlists;
243 while (lists)
244 {
245 symlist_chain *next = lists->next;
246 FREE (lists);
247 lists = next;
248 }
249 preloaded_symlists = 0;
250
251 return 0;
252 }
253
254
255 static int
256 add_symlist (const lt_dlsymlist *symlist)
257 {
258 symlist_chain *lists;
259 int errors = 0;
260
261
262 for (lists = preloaded_symlists;
263 lists && lists->symlist != symlist; lists = lists->next)
264 ;
265
266
267 if (!lists)
268 {
269 symlist_chain *tmp = (symlist_chain *) lt__zalloc (sizeof *tmp);
270
271 if (tmp)
272 {
273 tmp->symlist = symlist;
274 tmp->next = preloaded_symlists;
275 preloaded_symlists = tmp;
276 }
277 else
278 {
279 ++errors;
280 }
281 }
282
283 return errors;
284 }
285
286
287
288
289
290
291
292 int
293 lt_dlpreload_default (const lt_dlsymlist *preloaded)
294 {
295 default_preloaded_symbols = preloaded;
296 return 0;
297 }
298
299
300
301
302 int
303 lt_dlpreload (const lt_dlsymlist *preloaded)
304 {
305 int errors = 0;
306
307 if (preloaded)
308 {
309 errors = add_symlist (preloaded);
310 }
311 else
312 {
313 free_symlists();
314
315 if (default_preloaded_symbols)
316 {
317 errors = lt_dlpreload (default_preloaded_symbols);
318 }
319 }
320
321 return errors;
322 }
323
324
325
326
327
328 int
329 lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
330 {
331 symlist_chain *list;
332 int errors = 0;
333 int found = 0;
334
335
336 for (list = preloaded_symlists; list; list = list->next)
337 {
338
339 if ((originator && streq (list->symlist->name, originator))
340 || (!originator && streq (list->symlist->name, "@PROGRAM@")))
341 {
342 const lt_dlsymlist *symbol;
343 unsigned int idx = 0;
344
345 ++found;
346
347
348
349 while ((symbol = &list->symlist[++idx])->name != 0)
350 {
351 if ((symbol->address == 0)
352 && (strneq (symbol->name, "@PROGRAM@")))
353 {
354 lt_dlhandle handle = lt_dlopen (symbol->name);
355 if (handle == 0)
356 {
357 ++errors;
358 }
359 else
360 {
361 errors += (*func) (handle);
362 }
363 }
364 }
365 }
366 }
367
368 if (!found)
369 {
370 LT__SETERROR(CANNOT_OPEN);
371 ++errors;
372 }
373
374 return errors;
375 }