comparison src/sysdll.c @ 1851:7fdde2d3ae5f

[xemacs-hg @ 2004-01-03 23:06:49 by james] Malcolm Purvis' patch to add MacOS X dynamic lib support.
author james
date Sat, 03 Jan 2004 23:06:51 +0000
parents 3fe1a35b705d
children 91d4c8c65a0f
comparison
equal deleted inserted replaced
1850:38f35d20ac8c 1851:7fdde2d3ae5f
275 dll_close (dll_handle h) 275 dll_close (dll_handle h)
276 { 276 {
277 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE); 277 return NSUnLinkModule((NSModule)h, NSUNLINKMODULE_OPTION_NONE);
278 } 278 }
279 279
280 /* Given an address, return the mach_header for the image containing it
281 * or zero if the given address is not contained in any loaded images.
282 *
283 * Note: image_for_address(), my_find_image() and search_linked_libs() are
284 * based on code from the dlcompat library
285 * (http://www.opendarwin.org/projects/dlcompat).
286 */
287
288 static struct mach_header*
289 image_for_address(void *address)
290 {
291 unsigned long i;
292 unsigned long count = _dyld_image_count();
293 struct mach_header *mh = 0;
294
295 for (i = 0; i < count; i++)
296 {
297 unsigned long addr = (unsigned long)address -
298 _dyld_get_image_vmaddr_slide(i);
299 mh = _dyld_get_image_header(i);
300
301 if (mh)
302 {
303 struct load_command *lc =
304 (struct load_command *)((char *)mh + sizeof(struct mach_header));
305 unsigned long j;
306
307 for (j = 0; j < mh->ncmds;
308 j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
309 {
310 if (LC_SEGMENT == lc->cmd &&
311 addr >= ((struct segment_command *)lc)->vmaddr &&
312 addr <
313 ((struct segment_command *)lc)->vmaddr +
314 ((struct segment_command *)lc)->vmsize)
315 {
316 goto image_found;
317 }
318 }
319 }
320
321 mh = 0;
322 }
323
324 image_found:
325 return mh;
326 }
327
328 static const struct mach_header*
329 my_find_image(const char *name)
330 {
331 const struct mach_header *mh = (struct mach_header *)
332 NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
333 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
334
335 if (!mh)
336 {
337 int count = _dyld_image_count();
338 int j;
339
340 for (j = 0; j < count; j++)
341 {
342 const char *id = _dyld_get_image_name(j);
343
344 if (!strcmp(id, name))
345 {
346 mh = _dyld_get_image_header(j);
347 break;
348 }
349 }
350 }
351
352 return mh;
353 }
354
355 /*
356 * dyld adds libraries by first adding the directly dependant libraries in
357 * link order, and then adding the dependencies for those libraries, so we
358 * should do the same... but we don't bother adding the extra dependencies, if
359 * the symbols are neither in the loaded image nor any of it's direct
360 * dependencies, then it probably isn't there.
361 */
362 static NSSymbol
363 search_linked_libs(const struct mach_header * mh, const char *symbol)
364 {
365 int n;
366 NSSymbol nssym = 0;
367
368 struct load_command *lc =
369 (struct load_command *)((char *)mh + sizeof(struct mach_header));
370
371 for (n = 0; n < mh->ncmds;
372 n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
373 {
374 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
375 {
376 struct mach_header *wh;
377
378 if ((wh = (struct mach_header *)
379 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
380 (char *)lc))))
381 {
382 if (NSIsSymbolNameDefinedInImage(wh, symbol))
383 {
384 nssym =
385 NSLookupSymbolInImage(wh,
386 symbol,
387 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
388 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
389 break;
390 }
391 }
392 }
393 }
394
395 return nssym;
396 }
397
280 dll_func 398 dll_func
281 dll_function (dll_handle h, const CIbyte *n) 399 dll_function (dll_handle h, const CIbyte *n)
282 { 400 {
283 NSSymbol sym; 401 NSSymbol sym = 0;
284 MAYBE_PREPEND_UNDERSCORE (n); 402 MAYBE_PREPEND_UNDERSCORE (n);
285 sym = NSLookupSymbolInModule((NSModule)h, n); 403
286 if (sym == 0) return 0; 404 /* NULL means the program image and shared libraries, not bundles. */
287 return (dll_func)NSAddressOfSymbol(sym); 405
288 } 406 if (h == NULL)
407 {
408 /* NOTE: This assumes that this function is included in the main program
409 and not in a shared library. */
410 const struct mach_header* my_mh = image_for_address(&dll_function);
411
412 if (NSIsSymbolNameDefinedInImage(my_mh, n))
413 {
414 sym =
415 NSLookupSymbolInImage(my_mh,
416 n,
417 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
418 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
419 }
420
421 if (!sym)
422 {
423 sym = search_linked_libs(my_mh, n);
424 }
425 }
426 else
427 {
428 sym = NSLookupSymbolInModule((NSModule)h, n);
429 }
430
431 if (sym == 0) return 0;
432 return (dll_func)NSAddressOfSymbol(sym);
433 }
289 434
290 dll_var 435 dll_var
291 dll_variable (dll_handle h, const CIbyte *n) 436 dll_variable (dll_handle h, const CIbyte *n)
292 { 437 {
293 NSSymbol sym; 438 NSSymbol sym;