📄 ltdl.c
字号:
| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR ); if (retSym) break; } } offset += lc->cmdsize; } } return retSym;}static intsys_dyld_init(){ int retCode = 0; int err = 0; if (!_dyld_present()) { retCode=1; } else { err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage); err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage); err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage); err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic); } return retCode;}static lt_modulesys_dyld_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ lt_module module = 0; NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; if (!filename) return (lt_module)-1; ofirc = NSCreateObjectFileImageFromFile(filename, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: module = NSLinkModule(ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage(ofi); if (module) ltdl_NSMakePrivateModulePublic(module); break; case NSObjectFileImageInappropriateFile: if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) { module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); break; } default: LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); return 0; } if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); return module;}static intsys_dyld_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int retCode = 0; int flags = 0; if (module == (lt_module)-1) return 0;#ifdef __BIG_ENDIAN__ if (((struct mach_header *)module)->magic == MH_MAGIC)#else if (((struct mach_header *)module)->magic == MH_CIGAM)#endif { LT_DLMUTEX_SETERROR("Can not close a dylib"); retCode = 1; } else {#if 1/* Currently, if a module contains c++ static destructors and it is unloaded, we get a segfault in atexit(), due to compiler and dynamic loader differences of opinion, this works around that.*/ if ((const struct section *)NULL != getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module), "__DATA","__mod_term_func")) { flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; }#endif#ifdef __ppc__ flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;#endif if (!NSUnLinkModule(module,flags)) { retCode=1; LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE))); } } return retCode;}static lt_ptrsys_dyld_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = 0; NSSymbol *nssym = 0; void *unused; const struct mach_header *mh=NULL; char saveError[256] = "Symbol not found"; if (module == (lt_module)-1) { _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused); return address; }#ifdef __BIG_ENDIAN__ if (((struct mach_header *)module)->magic == MH_MAGIC)#else if (((struct mach_header *)module)->magic == MH_CIGAM)#endif { if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) { mh=module; if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol)) { nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module, symbol, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR ); } } } else { nssym = NSLookupSymbolInModule(module, symbol); } if (!nssym) { strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255); saveError[255] = 0; if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module); nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh); } if (!nssym) { LT_DLMUTEX_SETERROR (saveError); return NULL; } return NSAddressOfSymbol(nssym);}static struct lt_user_dlloader sys_dyld = { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };#endif /* HAVE_DYLD *//* --- DLPREOPEN() INTERFACE LOADER --- *//* emulate dynamic linking using preloaded_symbols */typedef struct lt_dlsymlists_t{ struct lt_dlsymlists_t *next; const lt_dlsymlist *syms;} lt_dlsymlists_t;static const lt_dlsymlist *default_preloaded_symbols = 0;static lt_dlsymlists_t *preloaded_symbols = 0;static intpresym_init (loader_data) lt_user_data loader_data;{ int errors = 0; LT_DLMUTEX_LOCK (); preloaded_symbols = 0; if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } LT_DLMUTEX_UNLOCK (); return errors;}static intpresym_free_symlists (){ lt_dlsymlists_t *lists; LT_DLMUTEX_LOCK (); lists = preloaded_symbols; while (lists) { lt_dlsymlists_t *tmp = lists; lists = lists->next; LT_DLFREE (tmp); } preloaded_symbols = 0; LT_DLMUTEX_UNLOCK (); return 0;}static intpresym_exit (loader_data) lt_user_data loader_data;{ presym_free_symlists (); return 0;}static intpresym_add_symlist (preloaded) const lt_dlsymlist *preloaded;{ lt_dlsymlists_t *tmp; lt_dlsymlists_t *lists; int errors = 0; LT_DLMUTEX_LOCK (); lists = preloaded_symbols; while (lists) { if (lists->syms == preloaded) { goto done; } lists = lists->next; } tmp = LT_EMALLOC (lt_dlsymlists_t, 1); if (tmp) { memset (tmp, 0, sizeof(lt_dlsymlists_t)); tmp->syms = preloaded; tmp->next = preloaded_symbols; preloaded_symbols = tmp; } else { ++errors; } done: LT_DLMUTEX_UNLOCK (); return errors;}static lt_modulepresym_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ lt_dlsymlists_t *lists; lt_module module = (lt_module) 0; LT_DLMUTEX_LOCK (); lists = preloaded_symbols; if (!lists) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); goto done; } /* Can't use NULL as the reflective symbol header, as NULL is used to mark the end of the entire symbol list. Self-dlpreopened symbols follow this magic number, chosen to be an unlikely clash with a real module name. */ if (!filename) { filename = "@PROGRAM@"; } while (lists) { const lt_dlsymlist *syms = lists->syms; while (syms->name) { if (!syms->address && strcmp(syms->name, filename) == 0) { module = (lt_module) syms; goto done; } ++syms; } lists = lists->next; } LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); done: LT_DLMUTEX_UNLOCK (); return module;}static intpresym_close (loader_data, module) lt_user_data loader_data; lt_module module;{ /* Just to silence gcc -Wall */ module = 0; return 0;}static lt_ptrpresym_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_dlsymlist *syms = (lt_dlsymlist*) module; ++syms; while (syms->address) { if (strcmp(syms->name, symbol) == 0) { return syms->address; } ++syms; } LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); return 0;}static struct lt_user_dlloader presym = { 0, presym_open, presym_close, presym_sym, presym_exit, 0};/* --- DYNAMIC MODULE LOADING --- *//* The type of a function used at each iteration of foreach_dirinpath(). */typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, lt_ptr data2));static int foreach_dirinpath LT_PARAMS((const char *search_path, const char *base_name, foreach_callback_func *func, lt_ptr data1, lt_ptr data2));static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, lt_ptr ignored));static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, lt_ptr ignored));static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, lt_ptr data2));static int canonicalize_path LT_PARAMS((const char *path, char **pcanonical));static int argzize_path LT_PARAMS((const char *path, char **pargz, size_t *pargz_len));static FILE *find_file LT_PARAMS((const char *search_path, const char *base_name, char **pdir));static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, const char *base_name, lt_dlhandle *handle));static int find_module LT_PARAMS((lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, const char *old_name, int installed));static int free_vars LT_PARAMS((char *dlname, char *oldname, char *libdir, char *deplibs));static int load_deplibs LT_PARAMS((lt_dlhandle handle, char *deplibs));static int trim LT_PARAMS((char **dest, const char *str));static int try_dlopen LT_PARAMS((lt_dlhandle *handle, const char *filename));static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, const char *filename));static int unload_deplibs LT_PARAMS((lt_dlhandle handle));static int lt_argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, char *before, const char *entry));static int lt_argz_insertinorder LT_PARAMS((char **pargz, size_t *pargz_len, const char *entry));static int lt_argz_insertdir LT_PARAMS((char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp));static int lt_dlpath_insertdir LT_PARAMS((char **ppath, char *before, const char *dir));static int list_files_by_dir LT_PARAMS((const char *dirnam, char **pargz, size_t *pargz_len));static int file_not_found LT_PARAMS((void));static char *user_search_path= 0;static lt_dlloader *loaders = 0;static lt_dlhandle handles = 0;static int initialized = 0;/* Initialize libltdl. */intlt_dlinit (){ int errors = 0; LT_DLMUTEX_LOCK (); /* Initialize only at first call. */ if (++initialized == 1) { handles = 0; user_search_path = 0; /* empty search path */#if HAVE_LIBDL errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");#endif#if HAVE_SHL_LOAD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");#endif#ifdef __WINDOWS__ errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");#endif#ifdef __BEOS__ errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");#endif#if HAVE_DLD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");#endif#if HAVE_DYLD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld"); errors += sys_dyld_init();#endif errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); if (presym_init (presym.dlloader_data)) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); ++errors; } else if (errors != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); ++errors; } } LT_DLMUTEX_UNLOCK (); return errors;}intlt_dlpreload (preloaded) const lt_dlsymlist *preloaded;{ int errors = 0; if (preloaded) { errors = presym_add_symlist (preloaded); } else { presym_free_symlists(); LT_DLMUTEX_LOCK (); if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } LT_DLMUTEX_UNLOCK (); } return errors;}intlt_dlpreload_default (preloaded) const lt_dlsymlist *preloaded;{ LT_DLMUTEX_LOCK (); default_preloaded_symbols = preloaded; LT_DLMUTEX_UNLOCK (); return 0;}intlt_dlexit (){ /* shut down libltdl */ lt_dlloader *loader; int errors = 0; LT_DLMUTEX_LOCK (); loader = loaders; if (!initialized) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); ++errors; goto done; } /* shut down only at last call. */ if (--initialized == 0) { int level; while (handles && LT_DLIS_RESIDENT (handles)) { handles = handles->next; } /* close all modules */ for (level = 1; handles; ++level) { lt_dlhandle cur = handles; int saw_nonresident = 0; while (cur) { lt_dlhandle tmp = cur; cur = cur->next; if (!LT_DLIS_RESIDENT (tmp)) saw_nonresident = 1; if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) { if (lt_dlclose (tmp)) { ++errors; } } } /* done if only resident modules are left */ if (!saw_nonresident) break; } /* close all loaders */ while (loader) { lt_dlloader *next = loader->next; lt_user_data data = loader->dlloader_data; if (loader->dlloader_exit && loader->dlloader_exit (data)) { ++errors; } LT_DLMEM_REASSIGN (loader, next);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -