Mercurial > hg > xemacs-beta
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; |