123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- #include "lt__private.h"
- #include "lt_dlloader.h"
- #define get_vtable dlopen_LTX_get_vtable
- LT_BEGIN_C_DECLS
- LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data);
- LT_END_C_DECLS
- static int vl_exit (lt_user_data loader_data);
- static lt_module vm_open (lt_user_data loader_data, const char *filename,
- lt_dladvise advise);
- static int vm_close (lt_user_data loader_data, lt_module module);
- static void * vm_sym (lt_user_data loader_data, lt_module module,
- const char *symbolname);
- static lt_dlvtable *vtable = 0;
- lt_dlvtable *
- get_vtable (lt_user_data loader_data)
- {
- if (!vtable)
- {
- vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
- }
- if (vtable && !vtable->name)
- {
- vtable->name = "lt_dlopen";
- #if defined DLSYM_USCORE
- vtable->sym_prefix = "_";
- #endif
- vtable->module_open = vm_open;
- vtable->module_close = vm_close;
- vtable->find_sym = vm_sym;
- vtable->dlloader_exit = vl_exit;
- vtable->dlloader_data = loader_data;
- vtable->priority = LT_DLLOADER_PREPEND;
- }
- if (vtable && (vtable->dlloader_data != loader_data))
- {
- LT__SETERROR (INIT_LOADER);
- return 0;
- }
- return vtable;
- }
- #if defined HAVE_DLFCN_H
- # include <dlfcn.h>
- #endif
- #if defined HAVE_SYS_DL_H
- # include <sys/dl.h>
- #endif
- #if !defined LT_LAZY_OR_NOW
- # if defined RTLD_LAZY
- # define LT_LAZY_OR_NOW RTLD_LAZY
- # else
- # if defined DL_LAZY
- # define LT_LAZY_OR_NOW DL_LAZY
- # endif
- # endif
- #endif
- #if !defined LT_LAZY_OR_NOW
- # if defined RTLD_NOW
- # define LT_LAZY_OR_NOW RTLD_NOW
- # else
- # if defined DL_NOW
- # define LT_LAZY_OR_NOW DL_NOW
- # endif
- # endif
- #endif
- #if !defined LT_LAZY_OR_NOW
- # define LT_LAZY_OR_NOW 0
- #endif
- #if !defined RTLD_GLOBAL
- # if defined DL_GLOBAL
- # define RTLD_GLOBAL DL_GLOBAL
- # endif
- #endif
- #if !defined RTLD_LOCAL
- # if defined DL_LOCAL
- # define RTLD_LOCAL DL_LOCAL
- # endif
- #endif
- #if defined HAVE_DLERROR
- # define DLERROR(arg) dlerror ()
- #else
- # define DLERROR(arg) LT__STRERROR (arg)
- #endif
- #define DL__SETERROR(errorcode) \
- LT__SETERRORSTR (DLERROR (errorcode))
- static int
- vl_exit (lt_user_data loader_data LT__UNUSED)
- {
- vtable = NULL;
- return 0;
- }
- static lt_module
- vm_open (lt_user_data loader_data LT__UNUSED, const char *filename,
- lt_dladvise advise)
- {
- int module_flags = LT_LAZY_OR_NOW;
- lt_module module;
- #ifdef RTLD_MEMBER
- int len = LT_STRLEN (filename);
- #endif
- if (advise)
- {
- #ifdef RTLD_GLOBAL
-
- if (advise->is_symglobal)
- module_flags |= RTLD_GLOBAL;
- #else
-
- advise->is_symglobal = 0;
- #endif
- #ifdef RTLD_LOCAL
- if (advise->is_symlocal)
- module_flags |= RTLD_LOCAL;
- #else
- advise->is_symlocal = 0;
- #endif
- }
- #ifdef RTLD_MEMBER
- if (len >= 4)
- {
-
- if (filename[len-1] == ')')
- {
- const char *opening = strrchr(filename, '(');
- if (opening && opening < (filename+len-2) && strchr(opening+1, '/') == NULL)
- module_flags |= RTLD_MEMBER;
- }
- }
- #endif
- module = dlopen (filename, module_flags);
- #if defined RTLD_MEMBER && defined LT_SHARED_LIB_MEMBER
- if (!module && len && !(module_flags & RTLD_MEMBER) && errno == ENOEXEC)
- {
-
- const char *member = LT_SHARED_LIB_MEMBER;
- char *attempt = MALLOC (char, len + strlen (member) + 1);
- if (!attempt)
- {
- LT__SETERROR (NO_MEMORY);
- return module;
- }
- sprintf (attempt, "%s%s", filename, member);
- module = vm_open (loader_data, attempt, advise);
- FREE (attempt);
- return module;
- }
- #endif
- if (!module)
- {
- DL__SETERROR (CANNOT_OPEN);
- }
- return module;
- }
- static int
- vm_close (lt_user_data loader_data LT__UNUSED, lt_module module)
- {
- int errors = 0;
- if (dlclose (module) != 0)
- {
- DL__SETERROR (CANNOT_CLOSE);
- ++errors;
- }
- return errors;
- }
- static void *
- vm_sym (lt_user_data loader_data LT__UNUSED, lt_module module, const char *name)
- {
- void *address = dlsym (module, name);
- if (!address)
- {
- DL__SETERROR (SYMBOL_NOT_FOUND);
- }
- return address;
- }
|