#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <stdarg.h>#include <limits.h>#include <mach-o/dyld.h>#include <mach-o/nlist.h>#include <mach-o/getsect.h>#include "asterisk/dlfcn-compat.h"Include dependency graph for dlfcn.c:

Go to the source code of this file.
Defines | |
| #define | __BSD_VISIBLE 1 |
| #define | DL_IN_LIST 0x01 |
| #define | dl_restrict __restrict |
| #define | ERR_STR_LEN 251 |
| #define | LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) |
| #define | LC_REQ_DYLD 0x80000000 |
| #define | MAGIC_DYLIB_MOD ((NSModule) 'DYMO') |
| #define | MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF') |
| #define | MAX_SEARCH_PATHS 32 |
| #define | NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 |
| #define | NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 |
| #define | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 |
| #define | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 |
| #define | RTLD_SELF ((void *) -3) |
Functions | |
| static struct dlstatus * | allocStatus (void) |
| static void | debug (const char *fmt,...) |
| int | dladdr (const void *dl_restrict p, Dl_info *dl_restrict info) |
| int | dlclose (void *handle) |
| static void | dlcompat_cleanup (void) |
| static void | dlcompat_init_func (void) |
| const char * | dlerror (void) |
| static void | dlerrorfree (void *data) |
| void * | dlopen (const char *path, int mode) |
| void * | dlsym (void *dl_restrict handle, const char *dl_restrict symbol) |
| static void * | dlsymIntern (struct dlstatus *dls, const char *symbol, int canSetError) |
| static void | dolock (void) |
| static void | dounlock (void) |
| static const char * | dyld_error_str (void) |
| static void | error (const char *str,...) |
| static const struct stat * | findFile (const char *file, const char **fullPath) |
| static const char * | get_lib_name (const struct mach_header *mh) |
| static const struct mach_header * | get_mach_header_from_NSModule (NSModule *mod) |
| static const char * | getFullPath (int i, const char *file) |
| static const char * | getSearchPath (int i) |
| static const struct mach_header * | image_for_address (const void *address) |
| static void | insertStatus (struct dlstatus *dls, const struct stat *sbuf) |
| static int | isFlagSet (int mode, int flag) |
| static int | isValidStatus (struct dlstatus *status) |
| static struct dlstatus * | loadModule (const char *path, const struct stat *sbuf, int mode) |
| static struct dlstatus * | lookupStatus (const struct stat *sbuf) |
| static const struct mach_header * | my_find_image (const char *name) |
| static int | promoteLocalToGlobal (struct dlstatus *dls) |
| static void * | reference (struct dlstatus *dls, int mode) |
| static void | resetdlerror (void) |
| static const char * | safegetenv (const char *s) |
| static NSSymbol * | search_linked_libs (const struct mach_header *mh, const char *symbol) |
| static const char * | searchList (void) |
| static void | warning (const char *str) |
Variables | |
| static pthread_mutex_t | dlcompat_mutex |
| static pthread_key_t | dlerror_key |
| static const struct mach_header *(* | dyld_NSAddImage )(const char *, unsigned long)=0 |
| static int(* | dyld_NSIsSymbolNameDefinedInImage )(const struct mach_header *, const char *)=0 |
| static NSSymbol(* | dyld_NSLookupSymbolInImage )(const struct mach_header *, const char *, unsigned long)=0 |
| static struct dlstatus | mainStatus = { 0, MAGIC_DYLIB_MOD, NULL, -1, RTLD_GLOBAL, 0, 0, 0 } |
| static struct dlstatus * | stqueue = &mainStatus |
|
|
|
|
|
Definition at line 102 of file dlfcn.c. Referenced by insertStatus(), and loadModule(). |
|
|
|
|
|
Definition at line 92 of file dlfcn.c. Referenced by error(). |
|
|
Definition at line 58 of file dlfcn.c. Referenced by search_linked_libs(). |
|
|
|
|
|
Definition at line 99 of file dlfcn.c. Referenced by dlclose(), dlsymIntern(), loadModule(), promoteLocalToGlobal(), and reference(). |
|
|
Definition at line 98 of file dlfcn.c. Referenced by loadModule(). |
|
|
Definition at line 95 of file dlfcn.c. Referenced by getSearchPath(). |
|
|
Definition at line 71 of file dlfcn.c. Referenced by loadModule(), and my_find_image(). |
|
|
Definition at line 68 of file dlfcn.c. Referenced by my_find_image(). |
|
|
Definition at line 74 of file dlfcn.c. Referenced by dlsymIntern(), and search_linked_libs(). |
|
|
Definition at line 77 of file dlfcn.c. Referenced by dlsymIntern(), and search_linked_libs(). |
|
|
Referenced by dlsymIntern(). |
|
|
Definition at line 428 of file dlfcn.c. References malloc, dlstatus::module, and dlstatus::next. Referenced by loadModule(). 00429 {
00430 struct dlstatus *dls;
00431 #ifdef REUSE_STATUS
00432 dls = stqueue;
00433 while (dls && dls->module)
00434 dls = dls->next;
00435 if (!dls)
00436 #endif
00437 dls = malloc(sizeof(*dls));
00438 dls->flags = 0;
00439 return dls;
00440 }
|
|
||||||||||||
|
Definition at line 183 of file dlfcn.c. 00184 {
00185 #if DEBUG > 1
00186 va_list arg;
00187 va_start(arg, fmt);
00188 fprintf(stderr, "DLDEBUG: ");
00189 vfprintf(stderr, fmt, arg);
00190 fprintf(stderr, "\n");
00191 fflush(stderr);
00192 va_end(arg);
00193 #endif
00194 }
|
|
||||||||||||
|
Definition at line 1167 of file dlfcn.c. References debug, dolock(), dounlock(), and resetdlerror(). 01168 {
01169 /*
01170 FIXME: USe the routine image_for_address.
01171 */
01172 unsigned long i;
01173 unsigned long j;
01174 unsigned long count = _dyld_image_count();
01175 struct mach_header *mh = 0;
01176 struct load_command *lc = 0;
01177 unsigned long addr = NULL;
01178 unsigned long table_off = (unsigned long)0;
01179 int found = 0;
01180 if (!info)
01181 return 0;
01182 dolock();
01183 resetdlerror();
01184 info->dli_fname = 0;
01185 info->dli_fbase = 0;
01186 info->dli_sname = 0;
01187 info->dli_saddr = 0;
01188 /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com>
01189 * to darwin-development AT lists DOT apple DOT com and slightly modified
01190 */
01191 for (i = 0; i < count; i++)
01192 {
01193 addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
01194 mh = _dyld_get_image_header(i);
01195 if (mh)
01196 {
01197 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01198 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01199 {
01200 if (LC_SEGMENT == lc->cmd &&
01201 addr >= ((struct segment_command *)lc)->vmaddr &&
01202 addr <
01203 ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
01204 {
01205 info->dli_fname = _dyld_get_image_name(i);
01206 info->dli_fbase = (void *)mh;
01207 found = 1;
01208 break;
01209 }
01210 }
01211 if (found)
01212 break;
01213 }
01214 }
01215 if (!found)
01216 {
01217 dounlock();
01218 return 0;
01219 }
01220 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01221 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01222 {
01223 if (LC_SEGMENT == lc->cmd)
01224 {
01225 if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT"))
01226 break;
01227 }
01228 }
01229 table_off =
01230 ((unsigned long)((struct segment_command *)lc)->vmaddr) -
01231 ((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
01232 debug("table off %x", table_off);
01233
01234 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01235 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01236 {
01237 if (LC_SYMTAB == lc->cmd)
01238 {
01239
01240 struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off);
01241 unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
01242 struct nlist *nearest = NULL;
01243 unsigned long diff = 0xffffffff;
01244 unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off);
01245 debug("symtable %x", symtable);
01246 for (i = 0; i < numsyms; i++)
01247 {
01248 /* Ignore the following kinds of Symbols */
01249 if ((!symtable->n_value) /* Undefined */
01250 || (symtable->n_type >= N_PEXT) /* Debug symbol */
01251 || (!(symtable->n_type & N_EXT)) /* Local Symbol */
01252 )
01253 {
01254 symtable++;
01255 continue;
01256 }
01257 if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
01258 {
01259 diff = (unsigned long)symtable->n_value - addr;
01260 nearest = symtable;
01261 }
01262 symtable++;
01263 }
01264 if (nearest)
01265 {
01266 info->dli_saddr = nearest->n_value + ((void *)p - addr);
01267 info->dli_sname = (char *)(strtable + nearest->n_un.n_strx);
01268 }
01269 }
01270 }
01271 dounlock();
01272 return 1;
01273 }
|
|
|
Definition at line 1041 of file dlfcn.c. References debug, dlsymIntern(), dolock(), dounlock(), error(), get_lib_name(), get_mach_header_from_NSModule(), isFlagSet(), isValidStatus(), dlstatus::lib, MAGIC_DYLIB_MOD, dlstatus::mode, dlstatus::module, name, dlstatus::refs, resetdlerror(), RTLD_NODELETE, and warning(). Referenced by __load_resource(), and ast_unload_resource(). 01042 {
01043 struct dlstatus *dls = handle;
01044 dolock();
01045 resetdlerror();
01046 if (!isValidStatus(dls))
01047 {
01048 goto dlcloseerror;
01049 }
01050 if (dls->module == MAGIC_DYLIB_MOD)
01051 {
01052 const char *name;
01053 if (!dls->lib)
01054 {
01055 name = "global context";
01056 }
01057 else
01058 {
01059 name = get_lib_name(dls->lib);
01060 }
01061 warning("trying to close a .dylib!");
01062 error("Not closing \"%s\" - dynamic libraries cannot be closed", name);
01063 goto dlcloseerror;
01064 }
01065 if (!dls->module)
01066 {
01067 error("module already closed");
01068 goto dlcloseerror;
01069 }
01070
01071 if (dls->refs == 1)
01072 {
01073 unsigned long options = 0;
01074 void (*fini) (void);
01075 if ((fini = dlsymIntern(dls, "__fini", 0)))
01076 {
01077 debug("calling _fini()");
01078 fini();
01079 }
01080 #ifdef __ppc__
01081 options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
01082 #endif
01083 #if 1
01084 /* Currently, if a module contains c++ static destructors and it is unloaded, we
01085 * get a segfault in atexit(), due to compiler and dynamic loader differences of
01086 * opinion, this works around that.
01087 * I really need a way to figure out from code if this is still necessary.
01088 */
01089 if ((const struct section *)NULL !=
01090 getsectbynamefromheader(get_mach_header_from_NSModule(dls->module),
01091 "__DATA", "__mod_term_func"))
01092 {
01093 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
01094 }
01095 #endif
01096 #ifdef RTLD_NODELETE
01097 if (isFlagSet(dls->mode, RTLD_NODELETE))
01098 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
01099 #endif
01100 if (!NSUnLinkModule(dls->module, options))
01101 {
01102 error("unable to unlink module");
01103 goto dlcloseerror;
01104 }
01105 dls->refs--;
01106 dls->module = 0;
01107 /* Note: the dlstatus struct dls is neither removed from the list
01108 * nor is the memory it occupies freed. This shouldn't pose a
01109 * problem in mostly all cases, though.
01110 */
01111 }
01112 dounlock();
01113 return 0;
01114 dlcloseerror:
01115 dounlock();
01116 return 1;
01117 }
|
|
|
Definition at line 824 of file dlfcn.c. References dlcompat_mutex, dlerror_key, free, getSearchPath(), dlstatus::next, pthread_mutex_destroy, and searchList(). Referenced by dlcompat_init_func(). 00825 {
00826 struct dlstatus *dls;
00827 struct dlstatus *next;
00828 char *data;
00829 data = (char *)searchList();
00830 if ( data )
00831 free( data );
00832 data = (char *)getSearchPath(-1);
00833 if ( data )
00834 free( data );
00835 pthread_mutex_destroy(&dlcompat_mutex);
00836 pthread_key_delete(dlerror_key);
00837 next = stqueue;
00838 while (next && (next != &mainStatus))
00839 {
00840 dls = next;
00841 next = dls->next;
00842 free(dls);
00843 }
00844 }
|
|
|
Definition at line 801 of file dlfcn.c. References dlcompat_cleanup(), dlcompat_mutex, dlerror_key, dlerrorfree(), dyld_NSAddImage, dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, and pthread_mutex_init. Referenced by dlopen(). 00802 {
00803 static int inited = 0;
00804 if (!inited)
00805 {
00806 inited = 1;
00807 _dyld_func_lookup("__dyld_NSAddImage", (unsigned long *)&dyld_NSAddImage);
00808 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",
00809 (unsigned long *)&dyld_NSIsSymbolNameDefinedInImage);
00810 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (unsigned long *)&dyld_NSLookupSymbolInImage);
00811 if (pthread_mutex_init(&dlcompat_mutex, NULL))
00812 exit(1);
00813 if (pthread_key_create(&dlerror_key, &dlerrorfree))
00814 exit(1);
00815 /* And be neat and tidy and clean up after ourselves */
00816 atexit(dlcompat_cleanup);
00817 }
00818 }
|
|
|
Definition at line 1119 of file dlfcn.c. References dlerror_key, dlthread::errset, and dlthread::errstr. Referenced by __load_resource(). 01120 {
01121 struct dlthread *tss;
01122 char * err_str;
01123 tss = pthread_getspecific(dlerror_key);
01124 err_str = tss->errstr;
01125 tss = pthread_getspecific(dlerror_key);
01126 if (tss->errset == 0)
01127 return 0;
01128 tss->errset = 0;
01129 return (err_str );
01130 }
|
|
|
Definition at line 853 of file dlfcn.c. References free. Referenced by dlcompat_init_func(). 00854 {
00855 free(data);
00856 }
|
|
||||||||||||
|
Definition at line 897 of file dlfcn.c. References dlcompat_init_func(), dolock(), dounlock(), error(), findFile(), isFlagSet(), loadModule(), lookupStatus(), reference(), dlstatus::refs, resetdlerror(), RTLD_LAZY, RTLD_NOLOAD, and RTLD_NOW. Referenced by __load_resource(). 00898 {
00899 const struct stat *sbuf;
00900 struct dlstatus *dls;
00901 const char *fullPath;
00902 dlcompat_init_func(); /* Just in case */
00903 dolock();
00904 resetdlerror();
00905 if (!path)
00906 {
00907 dls = &mainStatus;
00908 goto dlopenok;
00909 }
00910 if (!(sbuf = findFile(path, &fullPath)))
00911 {
00912 error("file \"%s\" not found", path);
00913 goto dlopenerror;
00914 }
00915 /* Now checks that it hasn't been closed already */
00916 if ((dls = lookupStatus(sbuf)) && (dls->refs > 0))
00917 {
00918 /* debug("status found"); */
00919 dls = reference(dls, mode);
00920 goto dlopenok;
00921 }
00922 #ifdef RTLD_NOLOAD
00923 if (isFlagSet(mode, RTLD_NOLOAD))
00924 {
00925 error("no existing handle and RTLD_NOLOAD specified");
00926 goto dlopenerror;
00927 }
00928 #endif
00929 if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW))
00930 {
00931 error("how can I load something both RTLD_LAZY and RTLD_NOW?");
00932 goto dlopenerror;
00933 }
00934 dls = loadModule(fullPath, sbuf, mode);
00935
00936 dlopenok:
00937 dounlock();
00938 return (void *)dls;
00939 dlopenerror:
00940 dounlock();
00941 return NULL;
00942 }
|
|
||||||||||||
|
Definition at line 945 of file dlfcn.c. References dlsymIntern(), dolock(), dounlock(), error(), free, and malloc. Referenced by __load_resource(). 00946 {
00947 int sym_len = strlen(symbol);
00948 void *value = NULL;
00949 char *malloc_sym = NULL;
00950 dolock();
00951 malloc_sym = malloc(sym_len + 2);
00952 if (malloc_sym)
00953 {
00954 sprintf(malloc_sym, "_%s", symbol);
00955 value = dlsymIntern(handle, malloc_sym, 1);
00956 free(malloc_sym);
00957 }
00958 else
00959 {
00960 error("Unable to allocate memory");
00961 goto dlsymerror;
00962 }
00963 dounlock();
00964 return value;
00965 dlsymerror:
00966 dounlock();
00967 return NULL;
00968 }
|
|
||||||||||||||||
|
Definition at line 560 of file dlfcn.c. References debug, dyld_error_str(), dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, error(), free, get_mach_header_from_NSModule(), image_for_address(), isValidStatus(), dlstatus::lib, MAGIC_DYLIB_MOD, malloc, dlstatus::module, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR, resetdlerror(), RTLD_DEFAULT, RTLD_NEXT, RTLD_SELF, and search_linked_libs(). Referenced by dlclose(), dlsym(), and loadModule(). 00561 {
00562 NSSymbol *nssym = 0;
00563 void *caller = __builtin_return_address(1); /* Be *very* careful about inlining */
00564 const struct mach_header *caller_mh = 0;
00565 const char* savedErrorStr = NULL;
00566 resetdlerror();
00567 #ifndef RTLD_SELF
00568 #define RTLD_SELF ((void *) -3)
00569 #endif
00570 if (NULL == dls)
00571 dls = RTLD_SELF;
00572 if ((RTLD_NEXT == dls) || (RTLD_SELF == dls))
00573 {
00574 if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
00575 {
00576 caller_mh = image_for_address(caller);
00577 if (RTLD_SELF == dls)
00578 {
00579 /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE
00580 * But it appears to work anyway, and looking at the code in dyld_libfuncs.c
00581 * this is acceptable.
00582 */
00583 if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol))
00584 {
00585 nssym = dyld_NSLookupSymbolInImage(caller_mh,
00586 symbol,
00587 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
00588 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
00589 }
00590 }
00591 if (!nssym)
00592 {
00593 if (RTLD_SELF == dls)
00594 savedErrorStr = dyld_error_str();
00595 nssym = search_linked_libs(caller_mh, symbol);
00596 }
00597 }
00598 else
00599 {
00600 if (canSetError)
00601 error("RTLD_SELF and RTLD_NEXT are not supported");
00602 return NULL;
00603 }
00604 }
00605 if (!nssym)
00606 {
00607
00608 if (RTLD_DEFAULT == dls)
00609 {
00610 dls = &mainStatus;
00611 }
00612 if (!isValidStatus(dls))
00613 return NULL;
00614
00615 if (dls->module != MAGIC_DYLIB_MOD)
00616 {
00617 nssym = NSLookupSymbolInModule(dls->module, symbol);
00618 if (!nssym && NSIsSymbolNameDefined(symbol))
00619 {
00620 debug("Searching dependencies");
00621 savedErrorStr = dyld_error_str();
00622 nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol);
00623 }
00624 }
00625 else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
00626 {
00627 if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol))
00628 {
00629 nssym = dyld_NSLookupSymbolInImage(dls->lib,
00630 symbol,
00631 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
00632 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
00633 }
00634 else if (NSIsSymbolNameDefined(symbol))
00635 {
00636 debug("Searching dependencies");
00637 savedErrorStr = dyld_error_str();
00638 nssym = search_linked_libs(dls->lib, symbol);
00639 }
00640 }
00641 else if (dls->module == MAGIC_DYLIB_MOD)
00642 {
00643 /* Global context, use NSLookupAndBindSymbol */
00644 if (NSIsSymbolNameDefined(symbol))
00645 {
00646 /* There doesn't seem to be a return on error option for this call???
00647 this is potentially broken, if binding fails, it will improperly
00648 exit the application. */
00649 nssym = NSLookupAndBindSymbol(symbol);
00650 }
00651 else
00652 {
00653 if (savedErrorStr)
00654 free((char*)savedErrorStr);
00655 savedErrorStr = malloc(256);
00656 snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol);
00657 }
00658 }
00659 }
00660 /* Error reporting */
00661 if (!nssym)
00662 {
00663 if (!savedErrorStr || !strlen(savedErrorStr))
00664 {
00665 if (savedErrorStr)
00666 free((char*)savedErrorStr);
00667 savedErrorStr = malloc(256);
00668 snprintf((char*)savedErrorStr, 256,"Symbol \"%s\" not found",symbol);
00669 }
00670 if (canSetError)
00671 {
00672 error(savedErrorStr);
00673 }
00674 else
00675 {
00676 debug(savedErrorStr);
00677 }
00678 if (savedErrorStr)
00679 free((char*)savedErrorStr);
00680 return NULL;
00681 }
00682 return NSAddressOfSymbol(nssym);
00683 }
|
|
|
Definition at line 862 of file dlfcn.c. References dlcompat_mutex, dlerror_key, dlthread::errset, dlthread::lockcnt, malloc, and pthread_mutex_lock. Referenced by dladdr(), dlclose(), dlopen(), and dlsym(). 00863 {
00864 int err = 0;
00865 struct dlthread *tss;
00866 tss = pthread_getspecific(dlerror_key);
00867 if (!tss)
00868 {
00869 tss = malloc(sizeof(struct dlthread));
00870 tss->lockcnt = 0;
00871 tss->errset = 0;
00872 if (pthread_setspecific(dlerror_key, tss))
00873 {
00874 fprintf(stderr,"dlcompat: pthread_setspecific failed\n");
00875 exit(1);
00876 }
00877 }
00878 if (!tss->lockcnt)
00879 err = pthread_mutex_lock(&dlcompat_mutex);
00880 tss->lockcnt = tss->lockcnt +1;
00881 if (err)
00882 exit(err);
00883 }
|
|
|
Definition at line 885 of file dlfcn.c. References dlcompat_mutex, dlerror_key, dlthread::lockcnt, and pthread_mutex_unlock. Referenced by dladdr(), dlclose(), dlopen(), and dlsym(). 00886 {
00887 int err = 0;
00888 struct dlthread *tss;
00889 tss = pthread_getspecific(dlerror_key);
00890 tss->lockcnt = tss->lockcnt -1;
00891 if (!tss->lockcnt)
00892 err = pthread_mutex_unlock(&dlcompat_mutex);
00893 if (err)
00894 exit(err);
00895 }
|
|
|
Definition at line 544 of file dlfcn.c. References malloc. Referenced by dlsymIntern(). 00545 {
00546 NSLinkEditErrors dylder;
00547 int dylderno;
00548 const char *dylderrstr;
00549 const char *dyldfile;
00550 const char* retStr = NULL;
00551 NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr);
00552 if (dylderrstr && strlen(dylderrstr))
00553 {
00554 retStr = malloc(strlen(dylderrstr) +1);
00555 strcpy((char*)retStr,dylderrstr);
00556 }
00557 return retStr;
00558 }
|
|
||||||||||||
|
Definition at line 196 of file dlfcn.c. References debug, dlerror_key, ERR_STR_LEN, dlthread::errset, and dlthread::errstr. Referenced by append_string(), dlclose(), dlopen(), dlsym(), dlsymIntern(), handle_request(), iax2_hangup(), iax2_write(), isValidStatus(), load_module(), loadModule(), reference(), restart_monitor(), and store_config(). 00197 {
00198 va_list arg;
00199 struct dlthread *tss;
00200 char * err_str;
00201 va_start(arg, str);
00202 tss = pthread_getspecific(dlerror_key);
00203 err_str = tss->errstr;
00204 strncpy(err_str, "dlcompat: ", ERR_STR_LEN);
00205 vsnprintf(err_str + 10, ERR_STR_LEN - 10, str, arg);
00206 va_end(arg);
00207 debug("ERROR: %s\n", err_str);
00208 tss->errset = 1;
00209 }
|
|
||||||||||||
|
Definition at line 359 of file dlfcn.c. References debug, and getFullPath(). Referenced by dlopen(). 00360 {
00361 int i = 0;
00362 static struct stat sbuf;
00363 char *fileName;
00364 debug("finding file %s", file);
00365 *fullPath = file;
00366 if (0 == stat(file, &sbuf))
00367 return &sbuf;
00368 if (strchr(file, '/'))
00369 return 0; /* If the path had a / we don't look in env var places */
00370 fileName = NULL;
00371 if (!fileName)
00372 fileName = (char *)file;
00373 while ((*fullPath = getFullPath(i++, fileName)))
00374 {
00375 if (0 == stat(*fullPath, &sbuf))
00376 return &sbuf;
00377 }
00378 ;
00379 return 0;
00380 }
|
|
|
Definition at line 228 of file dlfcn.c. Referenced by dlclose(). 00229 {
00230 unsigned long count = _dyld_image_count();
00231 unsigned long i;
00232 const char *val = NULL;
00233 if (mh)
00234 {
00235 for (i = 0; i < count; i++)
00236 {
00237 if (mh == _dyld_get_image_header(i))
00238 {
00239 val = _dyld_get_image_name(i);
00240 break;
00241 }
00242 }
00243 }
00244 return val;
00245 }
|
|
|
Definition at line 251 of file dlfcn.c. References debug. Referenced by dlclose(), dlsymIntern(), and loadModule(). 00252 {
00253 const char *mod_name = NSNameOfModule(mod);
00254 struct mach_header *mh = NULL;
00255 unsigned long count = _dyld_image_count();
00256 unsigned long i;
00257 debug("Module name: %s", mod_name);
00258 for (i = 0; i < count; i++)
00259 {
00260 if (!strcmp(mod_name, _dyld_get_image_name(i)))
00261 {
00262 mh = _dyld_get_image_header(i);
00263 break;
00264 }
00265 }
00266 return mh;
00267 }
|
|
||||||||||||
|
Definition at line 344 of file dlfcn.c. References getSearchPath(). Referenced by findFile(). 00345 {
00346 static char buf[PATH_MAX];
00347 const char *path = getSearchPath(i);
00348 if (path)
00349 {
00350 snprintf(buf, PATH_MAX, "%s/%s", path, file);
00351 }
00352 return path ? buf : 0;
00353 }
|
|
|
Definition at line 298 of file dlfcn.c. References calloc, debug, free, list, MAX_SEARCH_PATHS, searchList(), and strsep(). Referenced by dlcompat_cleanup(), and getFullPath(). 00299 {
00300 static const char *list = 0;
00301 static char **path = (char **)0;
00302 static int end = 0;
00303 static int numsize = MAX_SEARCH_PATHS;
00304 static char **tmp;
00305 /* So we can call free() in the "destructor" we use i=-1 to return the alloc'd array */
00306 if (i == -1)
00307 {
00308 return (const char*)path;
00309 }
00310 if (!path)
00311 {
00312 path = (char **)calloc(MAX_SEARCH_PATHS, sizeof(char **));
00313 }
00314 if (!list && !end)
00315 list = searchList();
00316 if (i >= (numsize))
00317 {
00318 debug("Increasing size for long PATH");
00319 tmp = (char **)calloc((MAX_SEARCH_PATHS + numsize), sizeof(char **));
00320 if (tmp)
00321 {
00322 memcpy(tmp, path, sizeof(char **) * numsize);
00323 free(path);
00324 path = tmp;
00325 numsize += MAX_SEARCH_PATHS;
00326 }
00327 else
00328 {
00329 return 0;
00330 }
00331 }
00332
00333 while (!path[i] && !end)
00334 {
00335 path[i] = strsep((char **)&list, ":");
00336
00337 if (path[i][0] == 0)
00338 path[i] = 0;
00339 end = (list == 0);
00340 }
00341 return path[i];
00342 }
|
|
|
Definition at line 1135 of file dlfcn.c. Referenced by dlsymIntern(). 01136 {
01137 unsigned long i;
01138 unsigned long j;
01139 unsigned long count = _dyld_image_count();
01140 struct mach_header *mh = 0;
01141 struct load_command *lc = 0;
01142 unsigned long addr = NULL;
01143 for (i = 0; i < count; i++)
01144 {
01145 addr = (unsigned long)address - _dyld_get_image_vmaddr_slide(i);
01146 mh = _dyld_get_image_header(i);
01147 if (mh)
01148 {
01149 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01150 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01151 {
01152 if (LC_SEGMENT == lc->cmd &&
01153 addr >= ((struct segment_command *)lc)->vmaddr &&
01154 addr <
01155 ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
01156 {
01157 goto image_found;
01158 }
01159 }
01160 }
01161 mh = 0;
01162 }
01163 image_found:
01164 return mh;
01165 }
|
|
||||||||||||
|
Definition at line 413 of file dlfcn.c. References debug, dlstatus::device, DL_IN_LIST, dlstatus::flags, dlstatus::inode, dlstatus::mode, dlstatus::next, and dlstatus::refs. Referenced by loadModule(). 00414 {
00415 debug("inserting status");
00416 dls->inode = sbuf->st_ino;
00417 dls->device = sbuf->st_dev;
00418 dls->refs = 0;
00419 dls->mode = 0;
00420 if ((dls->flags & DL_IN_LIST) == 0)
00421 {
00422 dls->next = stqueue;
00423 stqueue = dls;
00424 dls->flags |= DL_IN_LIST;
00425 }
00426 }
|
|
||||||||||||
|
Definition at line 398 of file dlfcn.c. Referenced by dlclose(), dlopen(), loadModule(), and reference(). 00399 {
00400 return (mode & flag) == flag;
00401 }
|
|
|
Definition at line 383 of file dlfcn.c. References error(), FALSE, dlstatus::module, dlstatus::next, dlstatus::refs, and TRUE. Referenced by dlclose(), and dlsymIntern(). 00384 {
00385 /* Walk the list to verify status is contained in it */
00386 struct dlstatus *dls = stqueue;
00387 while (dls && status != dls)
00388 dls = dls->next;
00389 if (dls == 0)
00390 error("invalid handle");
00391 else if ((dls->module == 0) || (dls->refs == 0))
00392 error("handle to closed library");
00393 else
00394 return TRUE;
00395 return FALSE;
00396 }
|
|
||||||||||||||||
|
Definition at line 685 of file dlfcn.c. References allocStatus(), debug, DL_IN_LIST, dlsymIntern(), dyld_NSAddImage, dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, error(), dlstatus::flags, free, get_mach_header_from_NSModule(), insertStatus(), isFlagSet(), dlstatus::lib, lookupStatus(), MAGIC_DYLIB_MOD, MAGIC_DYLIB_OFI, dlstatus::module, NSADDIMAGE_OPTION_RETURN_ON_ERROR, reference(), RTLD_GLOBAL, RTLD_NOW, and warning(). Referenced by dlopen(). 00686 {
00687 NSObjectFileImage ofi = 0;
00688 NSObjectFileImageReturnCode ofirc;
00689 struct dlstatus *dls;
00690 NSLinkEditErrors ler;
00691 int lerno;
00692 const char *errstr;
00693 const char *file;
00694 void (*init) (void);
00695 ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
00696 switch (ofirc)
00697 {
00698 case NSObjectFileImageSuccess:
00699 break;
00700 case NSObjectFileImageInappropriateFile:
00701 if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
00702 {
00703 if (!isFlagSet(mode, RTLD_GLOBAL))
00704 {
00705 warning("trying to open a .dylib with RTLD_LOCAL");
00706 error("unable to open this file with RTLD_LOCAL");
00707 return NULL;
00708 }
00709 }
00710 else
00711 {
00712 error("opening this file is unsupported on this system");
00713 return NULL;
00714 }
00715 break;
00716 case NSObjectFileImageFailure:
00717 error("object file setup failure");
00718 return NULL;
00719 case NSObjectFileImageArch:
00720 error("no object for this architecture");
00721 return NULL;
00722 case NSObjectFileImageFormat:
00723 error("bad object file format");
00724 return NULL;
00725 case NSObjectFileImageAccess:
00726 error("can't read object file");
00727 return NULL;
00728 default:
00729 error("unknown error from NSCreateObjectFileImageFromFile()");
00730 return NULL;
00731 }
00732 dls = lookupStatus(sbuf);
00733 if (!dls)
00734 {
00735 dls = allocStatus();
00736 }
00737 if (!dls)
00738 {
00739 error("unable to allocate memory");
00740 return NULL;
00741 }
00742 dls->lib = 0;
00743 if (ofirc == NSObjectFileImageInappropriateFile)
00744 {
00745 if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR)))
00746 {
00747 debug("Dynamic lib loaded at %ld", dls->lib);
00748 ofi = MAGIC_DYLIB_OFI;
00749 dls->module = MAGIC_DYLIB_MOD;
00750 ofirc = NSObjectFileImageSuccess;
00751 /* Although it is possible with a bit of work to modify this so it works and
00752 functions with RTLD_NOW, I don't deem it necessary at the moment */
00753 }
00754 if (!(dls->module))
00755 {
00756 NSLinkEditError(&ler, &lerno, &file, &errstr);
00757 if (!errstr || (!strlen(errstr)))
00758 error("Can't open this file type");
00759 else
00760 error(errstr);
00761 if ((dls->flags & DL_IN_LIST) == 0)
00762 {
00763 free(dls);
00764 }
00765 return NULL;
00766 }
00767 }
00768 else
00769 {
00770 dls->module = NSLinkModule(ofi, path,
00771 NSLINKMODULE_OPTION_RETURN_ON_ERROR |
00772 NSLINKMODULE_OPTION_PRIVATE |
00773 (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0));
00774 NSDestroyObjectFileImage(ofi);
00775 if (dls->module)
00776 {
00777 dls->lib = get_mach_header_from_NSModule(dls->module);
00778 }
00779 }
00780 if (!dls->module)
00781 {
00782 NSLinkEditError(&ler, &lerno, &file, &errstr);
00783 if ((dls->flags & DL_IN_LIST) == 0)
00784 {
00785 free(dls);
00786 }
00787 error(errstr);
00788 return NULL;
00789 }
00790
00791 insertStatus(dls, sbuf);
00792 dls = reference(dls, mode);
00793 if ((init = dlsymIntern(dls, "__init", 0)))
00794 {
00795 debug("calling _init()");
00796 init();
00797 }
00798 return dls;
00799 }
|
|
|
Definition at line 403 of file dlfcn.c. References debug, dlstatus::device, dlstatus::inode, and dlstatus::next. Referenced by dlopen(), and loadModule(). 00404 {
00405 struct dlstatus *dls = stqueue;
00406 debug("looking for status");
00407 while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0
00408 || sbuf->st_dev != dls->device || sbuf->st_ino != dls->inode))
00409 dls = dls->next;
00410 return dls;
00411 }
|
|
|
Definition at line 476 of file dlfcn.c. References dyld_NSAddImage, NSADDIMAGE_OPTION_RETURN_ON_ERROR, and NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED. Referenced by search_linked_libs(). 00477 {
00478 const struct mach_header *mh = 0;
00479 const char *id = NULL;
00480 int i = _dyld_image_count();
00481 int j;
00482 mh = (struct mach_header *)
00483 dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
00484 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
00485 if (!mh)
00486 {
00487 for (j = 0; j < i; j++)
00488 {
00489 id = _dyld_get_image_name(j);
00490 if (!strcmp(id, name))
00491 {
00492 mh = _dyld_get_image_header(j);
00493 break;
00494 }
00495 }
00496 }
00497 return mh;
00498 }
|
|
|
Definition at line 442 of file dlfcn.c. References debug, MAGIC_DYLIB_MOD, and dlstatus::module. Referenced by reference(). 00443 {
00444 static int (*p) (NSModule module) = 0;
00445 debug("promoting");
00446 if (!p)
00447 _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (unsigned long *)&p);
00448 return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module));
00449 }
|
|
||||||||||||
|
Definition at line 451 of file dlfcn.c. References debug, error(), isFlagSet(), MAGIC_DYLIB_MOD, dlstatus::mode, dlstatus::module, promoteLocalToGlobal(), dlstatus::refs, RTLD_GLOBAL, and warning(). Referenced by dlopen(), and loadModule(). 00452 {
00453 if (dls)
00454 {
00455 if (dls->module == MAGIC_DYLIB_MOD && !isFlagSet(mode, RTLD_GLOBAL))
00456 {
00457 warning("trying to open a .dylib with RTLD_LOCAL");
00458 error("unable to open a .dylib with RTLD_LOCAL");
00459 return NULL;
00460 }
00461 if (isFlagSet(mode, RTLD_GLOBAL) &&
00462 !isFlagSet(dls->mode, RTLD_GLOBAL) && !promoteLocalToGlobal(dls))
00463 {
00464 error("unable to promote local module to global");
00465 return NULL;
00466 }
00467 dls->mode |= mode;
00468 dls->refs++;
00469 }
00470 else
00471 debug("reference called with NULL argument");
00472
00473 return dls;
00474 }
|
|
|
Definition at line 846 of file dlfcn.c. References dlerror_key, and dlthread::errset. Referenced by dladdr(), dlclose(), dlopen(), and dlsymIntern(). 00847 {
00848 struct dlthread *tss;
00849 tss = pthread_getspecific(dlerror_key);
00850 tss->errset = 0;
00851 }
|
|
|
Definition at line 218 of file dlfcn.c. Referenced by searchList(). 00219 {
00220 const char *ss = getenv(s);
00221 return ss ? ss : "";
00222 }
|
|
||||||||||||
|
Definition at line 506 of file dlfcn.c. References debug, dyld_NSAddImage, dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, LC_LOAD_WEAK_DYLIB, my_find_image(), n, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND, and NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR. Referenced by dlsymIntern(). 00507 {
00508 int n;
00509 struct load_command *lc = 0;
00510 struct mach_header *wh;
00511 NSSymbol *nssym = 0;
00512 if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
00513 {
00514 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
00515 for (n = 0; n < mh->ncmds; n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
00516 {
00517 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
00518 {
00519 if ((wh = (struct mach_header *)
00520 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
00521 (char *)lc))))
00522 {
00523 if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol))
00524 {
00525 nssym = dyld_NSLookupSymbolInImage(wh,
00526 symbol,
00527 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
00528 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
00529 break;
00530 }
00531 }
00532 }
00533 }
00534 if ((!nssym) && NSIsSymbolNameDefined(symbol))
00535 {
00536 /* I've never seen this debug message...*/
00537 debug("Symbol \"%s\" is defined but was not found", symbol);
00538 }
00539 }
00540 return nssym;
00541 }
|
|
|
Definition at line 278 of file dlfcn.c. References malloc, and safegetenv(). Referenced by dlcompat_cleanup(), and getSearchPath(). 00279 {
00280 size_t buf_size;
00281 static char *buf=NULL;
00282 const char *ldlp = safegetenv("LD_LIBRARY_PATH");
00283 const char *dyldlp = safegetenv("DYLD_LIBRARY_PATH");
00284 const char *stdpath = getenv("DYLD_FALLBACK_LIBRARY_PATH");
00285 if (!stdpath)
00286 stdpath = "/usr/local/lib:/lib:/usr/lib";
00287 if (!buf)
00288 {
00289 buf_size = strlen(ldlp) + strlen(dyldlp) + strlen(stdpath) + 4;
00290 buf = malloc(buf_size);
00291 snprintf(buf, buf_size, "%s%s%s%s%s%c", dyldlp, (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""),
00292 stdpath, '\0');
00293 }
00294 return buf;
00295 }
|
|
|
Definition at line 211 of file dlfcn.c. Referenced by dlclose(), loadModule(), and reference(). 00212 {
00213 #if DEBUG > 0
00214 fprintf(stderr, "WARNING: dlcompat: %s\n", str);
00215 #endif
00216 }
|
|
|
Definition at line 105 of file dlfcn.c. Referenced by dlcompat_cleanup(), dlcompat_init_func(), dolock(), and dounlock(). |
|
|
Definition at line 108 of file dlfcn.c. Referenced by dlcompat_cleanup(), dlcompat_init_func(), dlerror(), dolock(), dounlock(), error(), and resetdlerror(). |
|
|
Definition at line 80 of file dlfcn.c. Referenced by dlcompat_init_func(), loadModule(), my_find_image(), and search_linked_libs(). |
|
|
Definition at line 81 of file dlfcn.c. Referenced by dlcompat_init_func(), dlsymIntern(), loadModule(), and search_linked_libs(). |
|
|
Definition at line 83 of file dlfcn.c. Referenced by dlcompat_init_func(), dlsymIntern(), loadModule(), and search_linked_libs(). |
|
|
|
|
|
|
1.4.2