diff options
Diffstat (limited to 'main/dlfcn.c')
-rw-r--r-- | main/dlfcn.c | 306 |
1 files changed, 111 insertions, 195 deletions
diff --git a/main/dlfcn.c b/main/dlfcn.c index 802e7942f..4c3a1a99b 100644 --- a/main/dlfcn.c +++ b/main/dlfcn.c @@ -1,7 +1,7 @@ /* Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> & Peter O'Gorman <ogorman@users.sourceforge.net> - + Portions may be copyright others, see the AUTHORS file included with this distribution. @@ -544,10 +544,9 @@ static inline const char *dyld_error_str() const char *dyldfile; const char* retStr = NULL; NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr); - if (dylderrstr && strlen(dylderrstr)) - { - retStr = ast_malloc(strlen(dylderrstr) +1); - strcpy((char*)retStr,dylderrstr); + if (dylderrstr && strlen(dylderrstr)) { + retStr = ast_malloc(strlen(dylderrstr) + 1); + strcpy((char*)retStr, dylderrstr); } return retStr; } @@ -564,51 +563,41 @@ static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetErr #endif if (NULL == dls) dls = RTLD_SELF; - if ((RTLD_NEXT == dls) || (RTLD_SELF == dls)) - { - if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) - { + if ((RTLD_NEXT == dls) || (RTLD_SELF == dls)) { + if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) { caller_mh = image_for_address(caller); - if (RTLD_SELF == dls) - { + if (RTLD_SELF == dls) { /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE * But it appears to work anyway, and looking at the code in dyld_libfuncs.c * this is acceptable. */ - if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol)) - { + if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol)) { nssym = dyld_NSLookupSymbolInImage(caller_mh, symbol, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); } } - if (!nssym) - { + if (!nssym) { if (RTLD_SELF == dls) savedErrorStr = dyld_error_str(); nssym = search_linked_libs(caller_mh, symbol); } - } - else - { + } else { if (canSetError) error("RTLD_SELF and RTLD_NEXT are not supported"); return NULL; } } - if (!nssym) - { + if (!nssym) { - if (RTLD_DEFAULT == dls) - { + if (RTLD_DEFAULT == dls) { dls = &mainStatus; } if (!isValidStatus(dls)) return NULL; - if (dls->module != MAGIC_DYLIB_MOD) - { + if (dls->module != MAGIC_DYLIB_MOD) { nssym = NSLookupSymbolInModule(dls->module, symbol); if (!nssym && NSIsSymbolNameDefined(symbol)) { @@ -616,58 +605,43 @@ static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetErr savedErrorStr = dyld_error_str(); nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol); } - } - else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) - { - if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol)) - { + } else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) { + if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol)) { nssym = dyld_NSLookupSymbolInImage(dls->lib, symbol, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); - } - else if (NSIsSymbolNameDefined(symbol)) - { + } else if (NSIsSymbolNameDefined(symbol)) { debug("Searching dependencies"); savedErrorStr = dyld_error_str(); nssym = search_linked_libs(dls->lib, symbol); } - } - else if (dls->module == MAGIC_DYLIB_MOD) - { + } else if (dls->module == MAGIC_DYLIB_MOD) { /* Global context, use NSLookupAndBindSymbol */ - if (NSIsSymbolNameDefined(symbol)) - { + if (NSIsSymbolNameDefined(symbol)) { /* There doesn't seem to be a return on error option for this call??? this is potentially broken, if binding fails, it will improperly exit the application. */ nssym = NSLookupAndBindSymbol(symbol); - } - else - { + } else { if (savedErrorStr) ast_free(savedErrorStr); savedErrorStr = ast_malloc(256); - snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol); + snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not in global context", symbol); } } } /* Error reporting */ - if (!nssym) - { - if (!savedErrorStr || !strlen(savedErrorStr)) - { + if (!nssym) { + if (!savedErrorStr || !strlen(savedErrorStr)) { if (savedErrorStr) ast_free(savedErrorStr); savedErrorStr = ast_malloc(256); - snprintf((char*)savedErrorStr, 256,"Symbol \"%s\" not found",symbol); + snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not found", symbol); } - if (canSetError) - { + if (canSetError) { error(savedErrorStr); - } - else - { + } else { debug(savedErrorStr); } if (savedErrorStr) @@ -688,57 +662,48 @@ static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, in const char *file; void (*init) (void); ofirc = NSCreateObjectFileImageFromFile(path, &ofi); - switch (ofirc) - { - case NSObjectFileImageSuccess: - break; - case NSObjectFileImageInappropriateFile: - if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) - { - if (!isFlagSet(mode, RTLD_GLOBAL)) - { - warning("trying to open a .dylib with RTLD_LOCAL"); - error("unable to open this file with RTLD_LOCAL"); - return NULL; - } - } - else - { - error("opening this file is unsupported on this system"); + switch (ofirc) { + case NSObjectFileImageSuccess: + break; + case NSObjectFileImageInappropriateFile: + if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) { + if (!isFlagSet(mode, RTLD_GLOBAL)) { + warning("trying to open a .dylib with RTLD_LOCAL"); + error("unable to open this file with RTLD_LOCAL"); return NULL; } - break; - case NSObjectFileImageFailure: - error("object file setup failure"); - return NULL; - case NSObjectFileImageArch: - error("no object for this architecture"); - return NULL; - case NSObjectFileImageFormat: - error("bad object file format"); - return NULL; - case NSObjectFileImageAccess: - error("can't read object file"); - return NULL; - default: - error("unknown error from NSCreateObjectFileImageFromFile()"); + } else { + error("opening this file is unsupported on this system"); return NULL; + } + break; + case NSObjectFileImageFailure: + error("object file setup failure"); + return NULL; + case NSObjectFileImageArch: + error("no object for this architecture"); + return NULL; + case NSObjectFileImageFormat: + error("bad object file format"); + return NULL; + case NSObjectFileImageAccess: + error("can't read object file"); + return NULL; + default: + error("unknown error from NSCreateObjectFileImageFromFile()"); + return NULL; } dls = lookupStatus(sbuf); - if (!dls) - { + if (!dls) { dls = allocStatus(); } - if (!dls) - { + if (!dls) { error("unable to allocate memory"); return NULL; } dls->lib = 0; - if (ofirc == NSObjectFileImageInappropriateFile) - { - if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) - { + if (ofirc == NSObjectFileImageInappropriateFile) { + if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { debug("Dynamic lib loaded at %ld", dls->lib); ofi = MAGIC_DYLIB_OFI; dls->module = MAGIC_DYLIB_MOD; @@ -746,8 +711,7 @@ static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, in /* Although it is possible with a bit of work to modify this so it works and functions with RTLD_NOW, I don't deem it necessary at the moment */ } - if (!(dls->module)) - { + if (!(dls->module)) { NSLinkEditError(&ler, &lerno, &file, &errstr); if (!errstr || (!strlen(errstr))) error("Can't open this file type"); @@ -759,24 +723,19 @@ static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, in } return NULL; } - } - else - { + } else { dls->module = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0)); NSDestroyObjectFileImage(ofi); - if (dls->module) - { + if (dls->module) { dls->lib = get_mach_header_from_NSModule(dls->module); } } - if (!dls->module) - { + if (!dls->module) { NSLinkEditError(&ler, &lerno, &file, &errstr); - if ((dls->flags & DL_IN_LIST) == 0) - { + if ((dls->flags & DL_IN_LIST) == 0) { ast_free(dls); } error(errstr); @@ -785,8 +744,7 @@ static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, in insertStatus(dls, sbuf); dls = reference(dls, mode); - if ((init = dlsymIntern(dls, "__init", 0))) - { + if ((init = dlsymIntern(dls, "__init", 0))) { debug("calling _init()"); init(); } @@ -796,8 +754,7 @@ static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, in static void dlcompat_init_func(void) { static int inited = 0; - if (!inited) - { + if (!inited) { inited = 1; _dyld_func_lookup("__dyld_NSAddImage", (unsigned long *)&dyld_NSAddImage); _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", @@ -830,8 +787,7 @@ static void dlcompat_cleanup(void) pthread_mutex_destroy(&dlcompat_mutex); pthread_key_delete(dlerror_key); next = stqueue; - while (next && (next != &mainStatus)) - { + while (next && (next != &mainStatus)) { dls = next; next = dls->next; ast_free(dls); @@ -859,20 +815,18 @@ static inline void dolock(void) int err = 0; struct dlthread *tss; tss = pthread_getspecific(dlerror_key); - if (!tss) - { + if (!tss) { tss = ast_malloc(sizeof(*tss)); tss->lockcnt = 0; tss->errset = 0; - if (pthread_setspecific(dlerror_key, tss)) - { - fprintf(stderr,"dlcompat: pthread_setspecific failed\n"); + if (pthread_setspecific(dlerror_key, tss)) { + fprintf(stderr, "dlcompat: pthread_setspecific failed\n"); exit(1); } } if (!tss->lockcnt) err = pthread_mutex_lock(&dlcompat_mutex); - tss->lockcnt = tss->lockcnt +1; + tss->lockcnt = tss->lockcnt + 1; if (err) exit(err); } @@ -897,41 +851,36 @@ void *dlopen(const char *path, int mode) dlcompat_init_func(); /* Just in case */ dolock(); resetdlerror(); - if (!path) - { + if (!path) { dls = &mainStatus; goto dlopenok; } - if (!(sbuf = findFile(path, &fullPath))) - { + if (!(sbuf = findFile(path, &fullPath))) { error("file \"%s\" not found", path); goto dlopenerror; } /* Now checks that it hasn't been closed already */ - if ((dls = lookupStatus(sbuf)) && (dls->refs > 0)) - { + if ((dls = lookupStatus(sbuf)) && (dls->refs > 0)) { /* debug("status found"); */ dls = reference(dls, mode); goto dlopenok; } #ifdef RTLD_NOLOAD - if (isFlagSet(mode, RTLD_NOLOAD)) - { + if (isFlagSet(mode, RTLD_NOLOAD)) { error("no existing handle and RTLD_NOLOAD specified"); goto dlopenerror; } #endif - if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW)) - { + if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW)) { error("how can I load something both RTLD_LAZY and RTLD_NOW?"); goto dlopenerror; } dls = loadModule(fullPath, sbuf, mode); - dlopenok: +dlopenok: dounlock(); return (void *)dls; - dlopenerror: +dlopenerror: dounlock(); return NULL; } @@ -944,20 +893,17 @@ void *dlsym(void * dl_restrict handle, const char * dl_restrict symbol) char *malloc_sym = NULL; dolock(); malloc_sym = ast_malloc(sym_len + 2); - if (malloc_sym) - { + if (malloc_sym) { sprintf(malloc_sym, "_%s", symbol); value = dlsymIntern(handle, malloc_sym, 1); ast_free(malloc_sym); - } - else - { + } else { error("Unable to allocate memory"); goto dlsymerror; } dounlock(); return value; - dlsymerror: +dlsymerror: dounlock(); return NULL; } @@ -989,14 +935,11 @@ static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol) void *value = NULL; char *malloc_sym = NULL; malloc_sym = ast_malloc(sym_len + 2); - if (malloc_sym) - { + if (malloc_sym) { sprintf(malloc_sym, "_%s", symbol); value = dlsymIntern(handle, malloc_sym, 1); ast_free(malloc_sym); - } - else - { + } else { error("Unable to allocate memory"); } return value; @@ -1038,37 +981,29 @@ int dlclose(void *handle) struct dlstatus *dls = handle; dolock(); resetdlerror(); - if (!isValidStatus(dls)) - { + if (!isValidStatus(dls)) { goto dlcloseerror; } - if (dls->module == MAGIC_DYLIB_MOD) - { + if (dls->module == MAGIC_DYLIB_MOD) { const char *name; - if (!dls->lib) - { + if (!dls->lib) { name = "global context"; - } - else - { + } else { name = get_lib_name(dls->lib); } warning("trying to close a .dylib!"); error("Not closing \"%s\" - dynamic libraries cannot be closed", name); goto dlcloseerror; } - if (!dls->module) - { + if (!dls->module) { error("module already closed"); goto dlcloseerror; } - if (dls->refs == 1) - { + if (dls->refs == 1) { unsigned long options = 0; void (*fini) (void); - if ((fini = dlsymIntern(dls, "__fini", 0))) - { + if ((fini = dlsymIntern(dls, "__fini", 0))) { debug("calling _fini()"); fini(); } @@ -1083,8 +1018,7 @@ int dlclose(void *handle) */ if ((const struct section *)NULL != getsectbynamefromheader(get_mach_header_from_NSModule(dls->module), - "__DATA", "__mod_term_func")) - { + "__DATA", "__mod_term_func")) { options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; } #endif @@ -1092,8 +1026,7 @@ int dlclose(void *handle) if (isFlagSet(dls->mode, RTLD_NODELETE)) options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; #endif - if (!NSUnLinkModule(dls->module, options)) - { + if (!NSUnLinkModule(dls->module, options)) { error("unable to unlink module"); goto dlcloseerror; } @@ -1106,7 +1039,7 @@ int dlclose(void *handle) } dounlock(); return 0; - dlcloseerror: +dlcloseerror: dounlock(); return 1; } @@ -1135,27 +1068,23 @@ const struct mach_header *image_for_address(const void *address) struct mach_header *mh = 0; struct load_command *lc = 0; unsigned long addr = NULL; - for (i = 0; i < count; i++) - { + for (i = 0; i < count; i++) { addr = (unsigned long)address - _dyld_get_image_vmaddr_slide(i); mh = _dyld_get_image_header(i); - if (mh) - { + if (mh) { lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); - for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) - { + for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) { if (LC_SEGMENT == lc->cmd && addr >= ((struct segment_command *)lc)->vmaddr && addr < - ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) - { + ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) { goto image_found; } } } mh = 0; } - image_found: +image_found: return mh; } @@ -1183,20 +1112,16 @@ int dladdr(const void * dl_restrict p, Dl_info * dl_restrict info) /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com> * to darwin-development AT lists DOT apple DOT com and slightly modified */ - for (i = 0; i < count; i++) - { + for (i = 0; i < count; i++) { addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i); mh = _dyld_get_image_header(i); - if (mh) - { + if (mh) { lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); - for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) - { + for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) { if (LC_SEGMENT == lc->cmd && addr >= ((struct segment_command *)lc)->vmaddr && addr < - ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) - { + ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) { info->dli_fname = _dyld_get_image_name(i); info->dli_fbase = (void *)mh; found = 1; @@ -1207,16 +1132,13 @@ int dladdr(const void * dl_restrict p, Dl_info * dl_restrict info) break; } } - if (!found) - { + if (!found) { dounlock(); return 0; } lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); - for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) - { - if (LC_SEGMENT == lc->cmd) - { + for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) { + if (LC_SEGMENT == lc->cmd) { if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT")) break; } @@ -1227,10 +1149,8 @@ int dladdr(const void * dl_restrict p, Dl_info * dl_restrict info) debug("table off %x", table_off); lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); - for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) - { - if (LC_SYMTAB == lc->cmd) - { + for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) { + if (LC_SYMTAB == lc->cmd) { struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off); unsigned long numsyms = ((struct symtab_command *)lc)->nsyms; @@ -1238,26 +1158,22 @@ int dladdr(const void * dl_restrict p, Dl_info * dl_restrict info) unsigned long diff = 0xffffffff; unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off); debug("symtable %x", symtable); - for (i = 0; i < numsyms; i++) - { + for (i = 0; i < numsyms; i++) { /* Ignore the following kinds of Symbols */ - if ((!symtable->n_value) /* Undefined */ - || (symtable->n_type >= N_PEXT) /* Debug symbol */ - || (!(symtable->n_type & N_EXT)) /* Local Symbol */ - ) - { + if ((!symtable->n_value) /* Undefined */ + || (symtable->n_type >= N_PEXT) /* Debug symbol */ + || (!(symtable->n_type & N_EXT)) /* Local Symbol */ + ) { symtable++; continue; } - if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr))) - { + if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr))) { diff = (unsigned long)symtable->n_value - addr; nearest = symtable; } symtable++; } - if (nearest) - { + if (nearest) { info->dli_saddr = nearest->n_value + ((void *)p - addr); info->dli_sname = (char *)(strtable + nearest->n_un.n_strx); } |