#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.
Data Structures | |
struct | dlstatus |
struct | dlthread |
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, dlstatus::next, and stqueue. 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 dolock(), 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(), mainStatus, dlstatus::next, pthread_mutex_destroy, searchList(), and stqueue. 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(), mainStatus, 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, mainStatus, 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 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(), and restart_monitor(). 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, dlstatus::refs, and stqueue. 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().
|
|
Definition at line 383 of file dlfcn.c. References error(), FALSE, dlstatus::module, dlstatus::next, dlstatus::refs, stqueue, 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, dlstatus::next, and stqueue. 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(), dtmf_detect(), loadModule(), mf_detect(), 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(). |
|
Definition at line 133 of file dlfcn.c. Referenced by dlcompat_cleanup(), dlopen(), and dlsymIntern(). |
|
Definition at line 134 of file dlfcn.c. Referenced by allocStatus(), dlcompat_cleanup(), insertStatus(), isValidStatus(), and lookupStatus(). |