📄 ltdl.c
字号:
lt_user_data loader_data; const char *filename;{ static shl_t self = (shl_t) 0; lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); /* Since searching for a symbol against a NULL module handle will also look in everything else that was already loaded and exported with the -E compiler flag, we always cache a handle saved before any modules are loaded. */ if (!self) { lt_ptr address; shl_findsym (&self, "main", TYPE_UNDEFINED, &address); } if (!filename) { module = self; } else { module = shl_load (filename, LT_BIND_FLAGS, 0L); if (!module) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); } } return module;}static intsys_shl_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (module && (shl_unload ((shl_t) (module)) != 0)) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } return errors;}static lt_ptrsys_shl_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = 0; /* sys_shl_open should never return a NULL module handle */ if (module == (lt_module) 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); } else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) { if (!address) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } } return address;}static struct lt_user_dlloader sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0};#endif /* HAVE_SHL_LOAD *//* --- LOADLIBRARY() INTERFACE LOADER --- */#ifdef __WINDOWS__/* dynamic linking for Win32 */#include <windows.h>/* Forward declaration; required to implement handle search below. */static lt_dlhandle handles;static lt_modulesys_wll_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ lt_dlhandle cur; lt_module module = 0; const char *errormsg = 0; char *searchname = 0; char *ext; char self_name_buf[MAX_PATH]; if (!filename) { /* Get the name of main module */ *self_name_buf = 0; GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); filename = ext = self_name_buf; } else { ext = strrchr (filename, '.'); } if (ext) { /* FILENAME already has an extension. */ searchname = lt_estrdup (filename); } else { /* Append a `.' to stop Windows from adding an implicit `.dll' extension. */ searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); if (searchname) sprintf (searchname, "%s.", filename); } if (!searchname) return 0;#if __CYGWIN__ { char wpath[MAX_PATH]; cygwin_conv_to_full_win32_path(searchname, wpath); module = LoadLibrary(wpath); }#else module = LoadLibrary (searchname);#endif LT_DLFREE (searchname); /* libltdl expects this function to fail if it is unable to physically load the library. Sadly, LoadLibrary will search the loaded libraries for a match and return one of them if the path search load fails. We check whether LoadLibrary is returning a handle to an already loaded module, and simulate failure if we find one. */ LT_DLMUTEX_LOCK (); cur = handles; while (cur) { if (!cur->module) { cur = 0; break; } if (cur->module == module) { break; } cur = cur->next; } LT_DLMUTEX_UNLOCK (); if (cur || !module) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); module = 0; } return module;}static intsys_wll_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (FreeLibrary(module) == 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } return errors;}static lt_ptrsys_wll_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = GetProcAddress (module, symbol); if (!address) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } return address;}static struct lt_user_dlloader sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0};#endif /* __WINDOWS__ *//* --- LOAD_ADD_ON() INTERFACE LOADER --- */#ifdef __BEOS__/* dynamic linking for BeOS */#include <kernel/image.h>static lt_modulesys_bedl_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ image_id image = 0; if (filename) { image = load_add_on (filename); } else { image_info info; int32 cookie = 0; if (get_next_image_info (0, &cookie, &info) == B_OK) image = load_add_on (info.name); } if (image <= 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); image = 0; } return (lt_module) image;}static intsys_bedl_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (unload_add_on ((image_id) module) != B_OK) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } return errors;}static lt_ptrsys_bedl_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = 0; image_id image = (image_id) module; if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); address = 0; } return address;}static struct lt_user_dlloader sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0};#endif /* __BEOS__ *//* --- DLD_LINK() INTERFACE LOADER --- */#if HAVE_DLD/* dynamic linking with dld */#if HAVE_DLD_H#include <dld.h>#endifstatic lt_modulesys_dld_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ lt_module module = strdup (filename); if (dld_link (filename) != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); LT_DLFREE (module); module = 0; } return module;}static intsys_dld_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (dld_unlink_by_file ((char*)(module), 1) != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } else { LT_DLFREE (module); } return errors;}static lt_ptrsys_dld_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = dld_get_func (symbol); if (!address) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } return address;}static struct lt_user_dlloader sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0};#endif /* HAVE_DLD *//* --- 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -