This source file includes following definitions.
- get_vtable
- vl_exit
- vl_init
- vm_open
- vm_close
- vm_sym
- dylderror
- lt__nsmodule_get_header
- lt__header_get_instnam
- lt__match_loadedlib
- lt__linkedlib_symbol
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 dyld_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__zalloc (sizeof *vtable);
67 }
68
69 if (vtable && !vtable->name)
70 {
71 vtable->name = "lt_dyld";
72 vtable->sym_prefix = "_";
73 vtable->dlloader_init = vl_init;
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_APPEND;
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_MACH_O_DYLD_H
97 # if !defined __APPLE_CC__ && !defined __MWERKS__ && !defined __private_extern__
98
99 # define __private_extern__ extern
100 # endif
101 # include <mach-o/dyld.h>
102 #endif
103
104 #include <mach-o/getsect.h>
105
106
107 #if !defined ENUM_DYLD_BOOL
108 # define ENUM_DYLD_BOOL
109 # undef FALSE
110 # undef TRUE
111 enum DYLD_BOOL {
112 FALSE,
113 TRUE
114 };
115 #endif
116 #if !defined LC_REQ_DYLD
117 # define LC_REQ_DYLD 0x80000000
118 #endif
119 #if !defined LC_LOAD_WEAK_DYLIB
120 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
121 #endif
122
123 #if !defined NSADDIMAGE_OPTION_NONE
124 # define NSADDIMAGE_OPTION_NONE 0x0
125 #endif
126 #if !defined NSADDIMAGE_OPTION_RETURN_ON_ERROR
127 # define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
128 #endif
129 #if !defined NSADDIMAGE_OPTION_WITH_SEARCHING
130 # define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
131 #endif
132 #if !defined NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
133 # define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
134 #endif
135 #if !defined NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
136 # define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
137 #endif
138
139 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
140 # define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
141 #endif
142 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
143 # define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
144 #endif
145 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
146 # define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
147 #endif
148 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
149 # define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
150 #endif
151
152 #define LT__SYMLOOKUP_OPTS (NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW \
153 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR)
154
155 #if defined __BIG_ENDIAN__
156 # define LT__MAGIC MH_MAGIC
157 #else
158 # define LT__MAGIC MH_CIGAM
159 #endif
160
161 #define DYLD__SETMYERROR(errmsg) LT__SETERRORSTR (dylderror (errmsg))
162 #define DYLD__SETERROR(errcode) DYLD__SETMYERROR (LT__STRERROR (errcode))
163
164 typedef struct mach_header mach_header;
165 typedef struct dylib_command dylib_command;
166
167 static const char *dylderror (const char *errmsg);
168 static const mach_header *lt__nsmodule_get_header (NSModule module);
169 static const char *lt__header_get_instnam (const mach_header *mh);
170 static const mach_header *lt__match_loadedlib (const char *name);
171 static NSSymbol lt__linkedlib_symbol (const char *symname, const mach_header *mh);
172
173 static const mach_header *(*lt__addimage) (const char *image_name,
174 unsigned long options) = 0;
175 static NSSymbol (*lt__image_symbol) (const mach_header *image,
176 const char *symbolName,
177 unsigned long options) = 0;
178 static enum DYLD_BOOL (*lt__image_symbol_p) (const mach_header *image,
179 const char *symbolName) = 0;
180 static enum DYLD_BOOL (*lt__module_export) (NSModule module) = 0;
181
182 static int dyld_cannot_close = 0;
183
184
185
186
187 static int
188 vl_exit (lt_user_data loader_data LT__UNUSED)
189 {
190 vtable = NULL;
191 return 0;
192 }
193
194
195 static int
196 vl_init (lt_user_data loader_data)
197 {
198 int errors = 0;
199
200 if (! dyld_cannot_close)
201 {
202 if (!_dyld_present ())
203 {
204 ++errors;
205 }
206 else
207 {
208 (void) _dyld_func_lookup ("__dyld_NSAddImage",
209 (unsigned long*) <__addimage);
210 (void) _dyld_func_lookup ("__dyld_NSLookupSymbolInImage",
211 (unsigned long*)<__image_symbol);
212 (void) _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage",
213 (unsigned long*) <__image_symbol_p);
214 (void) _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic",
215 (unsigned long*) <__module_export);
216 dyld_cannot_close = lt_dladderror ("can't close a dylib");
217 }
218 }
219
220 return errors;
221 }
222
223
224
225
226
227 static lt_module
228 vm_open (lt_user_data loader_data, const char *filename,
229 lt_dladvise advise LT__UNUSED)
230 {
231 lt_module module = 0;
232 NSObjectFileImage ofi = 0;
233
234 if (!filename)
235 {
236 return (lt_module) -1;
237 }
238
239 switch (NSCreateObjectFileImageFromFile (filename, &ofi))
240 {
241 case NSObjectFileImageSuccess:
242 module = NSLinkModule (ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR
243 | NSLINKMODULE_OPTION_PRIVATE
244 | NSLINKMODULE_OPTION_BINDNOW);
245 NSDestroyObjectFileImage (ofi);
246
247 if (module)
248 {
249 lt__module_export (module);
250 }
251 break;
252
253 case NSObjectFileImageInappropriateFile:
254 if (lt__image_symbol_p && lt__image_symbol)
255 {
256 module = (lt_module) lt__addimage(filename,
257 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
258 }
259 break;
260
261 case NSObjectFileImageFailure:
262 case NSObjectFileImageArch:
263 case NSObjectFileImageFormat:
264 case NSObjectFileImageAccess:
265
266 break;
267 }
268
269 if (!module)
270 {
271 DYLD__SETERROR (CANNOT_OPEN);
272 }
273
274 return module;
275 }
276
277
278
279
280 static int
281 vm_close (lt_user_data loader_data, lt_module module)
282 {
283 int errors = 0;
284
285 if (module != (lt_module) -1)
286 {
287 const mach_header *mh = (const mach_header *) module;
288 int flags = 0;
289 if (mh->magic == LT__MAGIC)
290 {
291 lt_dlseterror (dyld_cannot_close);
292 ++errors;
293 }
294 else
295 {
296
297
298
299 if ((const struct section *) NULL !=
300 getsectbynamefromheader (lt__nsmodule_get_header (module),
301 "__DATA", "__mod_term_func"))
302 {
303 flags |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
304 }
305 #if defined __ppc__
306 flags |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
307 #endif
308 if (!NSUnLinkModule (module, flags))
309 {
310 DYLD__SETERROR (CANNOT_CLOSE);
311 ++errors;
312 }
313 }
314 }
315
316 return errors;
317 }
318
319
320
321 static void *
322 vm_sym (lt_user_data loader_data, lt_module module, const char *name)
323 {
324 NSSymbol *nssym = 0;
325 const mach_header *mh = (const mach_header *) module;
326 char saveError[256] = "Symbol not found";
327
328 if (module == (lt_module) -1)
329 {
330 void *address, *unused;
331 _dyld_lookup_and_bind (name, (unsigned long*) &address, &unused);
332 return address;
333 }
334
335 if (mh->magic == LT__MAGIC)
336 {
337 if (lt__image_symbol_p && lt__image_symbol)
338 {
339 if (lt__image_symbol_p (mh, name))
340 {
341 nssym = lt__image_symbol (mh, name, LT__SYMLOOKUP_OPTS);
342 }
343 }
344
345 }
346 else
347 {
348 nssym = NSLookupSymbolInModule (module, name);
349 }
350
351 if (!nssym)
352 {
353 strlcpy (saveError, dylderror (LT__STRERROR (SYMBOL_NOT_FOUND)), 255);
354 saveError[255] = 0;
355 if (!mh)
356 {
357 mh = (mach_header *)lt__nsmodule_get_header (module);
358 }
359 nssym = lt__linkedlib_symbol (name, mh);
360 }
361
362 if (!nssym)
363 {
364 LT__SETERRORSTR (saveError);
365 }
366
367 return nssym ? NSAddressOfSymbol (nssym) : 0;
368 }
369
370
371
372
373
374
375
376
377 static const char *
378 dylderror (const char *errmsg)
379 {
380 NSLinkEditErrors ler;
381 int lerno;
382 const char *file;
383 const char *errstr;
384
385 NSLinkEditError (&ler, &lerno, &file, &errstr);
386
387 if (! (errstr && *errstr))
388 {
389 errstr = errmsg;
390 }
391
392 return errstr;
393 }
394
395
396 static const mach_header *
397 lt__nsmodule_get_header (NSModule module)
398 {
399 int i = _dyld_image_count();
400 const char *modname = NSNameOfModule (module);
401 const mach_header *mh = 0;
402
403 if (!modname)
404 return NULL;
405
406 while (i > 0)
407 {
408 --i;
409 if (strneq (_dyld_get_image_name (i), modname))
410 {
411 mh = _dyld_get_image_header (i);
412 break;
413 }
414 }
415
416 return mh;
417 }
418
419
420
421
422
423 static const char *
424 lt__header_get_instnam (const mach_header *mh)
425 {
426 unsigned long offset = sizeof(mach_header);
427 const char* result = 0;
428 int j;
429
430 for (j = 0; j < mh->ncmds; j++)
431 {
432 struct load_command *lc;
433
434 lc = (struct load_command*) (((unsigned long) mh) + offset);
435 if (LC_ID_DYLIB == lc->cmd)
436 {
437 result=(char*)(((dylib_command*) lc)->dylib.name.offset +
438 (unsigned long) lc);
439 }
440 offset += lc->cmdsize;
441 }
442
443 return result;
444 }
445
446 static const mach_header *
447 lt__match_loadedlib (const char *name)
448 {
449 const mach_header *mh = 0;
450 int i = _dyld_image_count();
451
452 while (i > 0)
453 {
454 const char *id;
455
456 --i;
457 id = lt__header_get_instnam (_dyld_get_image_header (i));
458 if (id && strneq (id, name))
459 {
460 mh = _dyld_get_image_header (i);
461 break;
462 }
463 }
464
465 return mh;
466 }
467
468
469 static NSSymbol
470 lt__linkedlib_symbol (const char *symname, const mach_header *mh)
471 {
472 NSSymbol symbol = 0;
473
474 if (lt__image_symbol && NSIsSymbolNameDefined (symname))
475 {
476 unsigned long offset = sizeof(mach_header);
477 struct load_command *lc;
478 int j;
479
480 for (j = 0; j < mh->ncmds; j++)
481 {
482 lc = (struct load_command*) (((unsigned long) mh) + offset);
483 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
484 {
485 unsigned long base = ((dylib_command *) lc)->dylib.name.offset;
486 char *name = (char *) (base + (unsigned long) lc);
487 const mach_header *mh1 = lt__match_loadedlib (name);
488
489 if (!mh1)
490 {
491
492 mh1 = lt__addimage (name,
493 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
494 | NSADDIMAGE_OPTION_WITH_SEARCHING
495 | NSADDIMAGE_OPTION_RETURN_ON_ERROR);
496 }
497
498 if (mh1)
499 {
500 symbol = lt__image_symbol (mh1, symname, LT__SYMLOOKUP_OPTS);
501 if (symbol)
502 break;
503 }
504 }
505
506 offset += lc->cmdsize;
507 }
508 }
509
510 return symbol;
511 }