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 loader_data LT__UNUSED)
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 loader_data LT__UNUSED)
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 loader_data LT__UNUSED, const char *filename,
146 lt_dladvise advise LT__UNUSED)
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 loader_data LT__UNUSED, lt_module module LT__UNUSED)
199 {
200
201 module = 0;
202 return 0;
203 }
204
205
206
207
208 static void *
209 vm_sym (lt_user_data loader_data LT__UNUSED, lt_module module, const char *name)
210 {
211 lt_dlsymlist *symbol = (lt_dlsymlist*) module;
212
213 if (symbol[1].name && STREQ (symbol[1].name, "@INIT@"))
214 {
215 symbol++;
216 }
217
218 symbol +=2;
219
220 while (symbol->name)
221 {
222 if (STREQ (symbol->name, name))
223 {
224 return symbol->address;
225 }
226
227 ++symbol;
228 }
229
230 LT__SETERROR (SYMBOL_NOT_FOUND);
231
232 return 0;
233 }
234
235
236
237
238
239
240
241
242 static int
243 free_symlists (void)
244 {
245 symlist_chain *lists;
246
247 lists = preloaded_symlists;
248 while (lists)
249 {
250 symlist_chain *next = lists->next;
251 FREE (lists);
252 lists = next;
253 }
254 preloaded_symlists = 0;
255
256 return 0;
257 }
258
259
260 static int
261 add_symlist (const lt_dlsymlist *symlist)
262 {
263 symlist_chain *lists;
264 int errors = 0;
265
266
267 for (lists = preloaded_symlists;
268 lists && lists->symlist != symlist; lists = lists->next)
269 ;
270
271
272 if (!lists)
273 {
274 symlist_chain *tmp = (symlist_chain *) lt__zalloc (sizeof *tmp);
275
276 if (tmp)
277 {
278 tmp->symlist = symlist;
279 tmp->next = preloaded_symlists;
280 preloaded_symlists = tmp;
281
282 if (symlist[1].name && STREQ (symlist[1].name, "@INIT@"))
283 {
284 void (*init_symlist)(void);
285 *(void **)(&init_symlist) = symlist[1].address;
286 (*init_symlist)();
287 }
288 }
289 else
290 {
291 ++errors;
292 }
293 }
294
295 return errors;
296 }
297
298
299
300
301
302
303
304 int
305 lt_dlpreload_default (const lt_dlsymlist *preloaded)
306 {
307 default_preloaded_symbols = preloaded;
308 return 0;
309 }
310
311
312
313
314 int
315 lt_dlpreload (const lt_dlsymlist *preloaded)
316 {
317 int errors = 0;
318
319 if (preloaded)
320 {
321 errors = add_symlist (preloaded);
322 }
323 else
324 {
325 free_symlists();
326
327 if (default_preloaded_symbols)
328 {
329 errors = lt_dlpreload (default_preloaded_symbols);
330 }
331 }
332
333 return errors;
334 }
335
336
337
338
339
340 int
341 lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
342 {
343 symlist_chain *list;
344 int errors = 0;
345 int found = 0;
346
347
348 for (list = preloaded_symlists; list; list = list->next)
349 {
350
351 if ((originator && STREQ (list->symlist->name, originator))
352 || (!originator && STREQ (list->symlist->name, "@PROGRAM@")))
353 {
354 const lt_dlsymlist *symbol;
355 unsigned int idx = 0;
356
357 ++found;
358
359
360
361 while ((symbol = &list->symlist[++idx])->name != 0)
362 {
363 if ((symbol->address == 0)
364 && (STRNEQ (symbol->name, "@PROGRAM@")))
365 {
366 lt_dlhandle handle = lt_dlopen (symbol->name);
367 if (handle == 0)
368 {
369 ++errors;
370 }
371 else
372 {
373 errors += (*func) (handle);
374 }
375 }
376 }
377 }
378 }
379
380 if (!found)
381 {
382 LT__SETERROR(CANNOT_OPEN);
383 ++errors;
384 }
385
386 return errors;
387 }