This source file includes following definitions.
- get_vtable
 
- vl_exit
 
- vm_open
 
- vm_close
 
- vm_sym
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 #include "lt__private.h"
  33 #include "lt_dlloader.h"
  34 
  35 
  36 
  37 
  38 
  39 #define get_vtable      dlopen_LTX_get_vtable
  40 
  41 LT_BEGIN_C_DECLS
  42 LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data);
  43 LT_END_C_DECLS
  44 
  45 
  46 
  47 
  48 static int       vl_exit  (lt_user_data loader_data);
  49 static lt_module vm_open  (lt_user_data loader_data, const char *filename,
  50                            lt_dladvise advise);
  51 static int       vm_close (lt_user_data loader_data, lt_module module);
  52 static void *    vm_sym   (lt_user_data loader_data, lt_module module,
  53                           const char *symbolname);
  54 
  55 static lt_dlvtable *vtable = 0;
  56 
  57 
  58 
  59 
  60 lt_dlvtable *
  61 get_vtable (lt_user_data loader_data)
     
  62 {
  63   if (!vtable)
  64     {
  65       vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
  66     }
  67 
  68   if (vtable && !vtable->name)
  69     {
  70       vtable->name              = "lt_dlopen";
  71 #if defined DLSYM_USCORE
  72       vtable->sym_prefix        = "_";
  73 #endif
  74       vtable->module_open       = vm_open;
  75       vtable->module_close      = vm_close;
  76       vtable->find_sym          = vm_sym;
  77       vtable->dlloader_exit     = vl_exit;
  78       vtable->dlloader_data     = loader_data;
  79       vtable->priority          = LT_DLLOADER_PREPEND;
  80     }
  81 
  82   if (vtable && (vtable->dlloader_data != loader_data))
  83     {
  84       LT__SETERROR (INIT_LOADER);
  85       return 0;
  86     }
  87 
  88   return vtable;
  89 }
  90 
  91 
  92 
  93 
  94 
  95 
  96 #if defined HAVE_DLFCN_H
  97 #  include <dlfcn.h>
  98 #endif
  99 
 100 #if defined HAVE_SYS_DL_H
 101 #  include <sys/dl.h>
 102 #endif
 103 
 104 
 105 
 106 
 107 #if !defined LT_LAZY_OR_NOW
 108 #  if defined RTLD_LAZY
 109 #    define LT_LAZY_OR_NOW      RTLD_LAZY
 110 #  else
 111 #    if defined DL_LAZY
 112 #      define LT_LAZY_OR_NOW    DL_LAZY
 113 #    endif
 114 #  endif 
 115 #endif
 116 #if !defined LT_LAZY_OR_NOW
 117 #  if defined RTLD_NOW
 118 #    define LT_LAZY_OR_NOW      RTLD_NOW
 119 #  else
 120 #    if defined DL_NOW
 121 #      define LT_LAZY_OR_NOW    DL_NOW
 122 #    endif
 123 #  endif 
 124 #endif
 125 #if !defined LT_LAZY_OR_NOW
 126 #  define LT_LAZY_OR_NOW        0
 127 #endif 
 128 
 129 
 130 
 131 #if !defined RTLD_GLOBAL
 132 #  if defined DL_GLOBAL
 133 #    define RTLD_GLOBAL         DL_GLOBAL
 134 #  endif
 135 #endif 
 136 #if !defined RTLD_LOCAL
 137 #  if defined DL_LOCAL
 138 #    define RTLD_LOCAL          DL_LOCAL
 139 #  endif
 140 #endif 
 141 
 142 #if defined HAVE_DLERROR
 143 #  define DLERROR(arg)  dlerror ()
 144 #else
 145 #  define DLERROR(arg)  LT__STRERROR (arg)
 146 #endif
 147 
 148 #define DL__SETERROR(errorcode) \
 149         LT__SETERRORSTR (DLERROR (errorcode))
 150 
 151 
 152 
 153 
 154 static int
 155 vl_exit (lt_user_data loader_data LT__UNUSED)
     
 156 {
 157   vtable = NULL;
 158   return 0;
 159 }
 160 
 161 
 162 
 163 
 164 
 165 static lt_module
 166 vm_open (lt_user_data loader_data LT__UNUSED, const char *filename,
     
 167          lt_dladvise advise)
 168 {
 169   int           module_flags = LT_LAZY_OR_NOW;
 170   lt_module     module;
 171 #ifdef RTLD_MEMBER
 172   int           len = LT_STRLEN (filename);
 173 #endif
 174 
 175   if (advise)
 176     {
 177 #ifdef RTLD_GLOBAL
 178       
 179 
 180       if (advise->is_symglobal)
 181         module_flags |= RTLD_GLOBAL;
 182 #else
 183       
 184 
 185       advise->is_symglobal = 0;
 186 #endif
 187 
 188 
 189 #ifdef RTLD_LOCAL
 190       if (advise->is_symlocal)
 191         module_flags |= RTLD_LOCAL;
 192 #else
 193       advise->is_symlocal = 0;
 194 #endif
 195     }
 196 
 197 #ifdef RTLD_MEMBER 
 198   if (len >= 4) 
 199     {
 200       
 201 
 202       if (filename[len-1] == ')')
 203         {
 204           const char *opening = strrchr(filename, '(');
 205           if (opening && opening < (filename+len-2) && strchr(opening+1, '/') == NULL)
 206             module_flags |= RTLD_MEMBER;
 207         }
 208     }
 209 #endif
 210 
 211   module = dlopen (filename, module_flags);
 212 
 213 #if defined RTLD_MEMBER && defined LT_SHARED_LIB_MEMBER
 214   if (!module && len && !(module_flags & RTLD_MEMBER) && errno == ENOEXEC)
 215     {
 216       
 217 
 218 
 219 
 220       const char *member = LT_SHARED_LIB_MEMBER;
 221 
 222       char *attempt = MALLOC (char, len + strlen (member) + 1);
 223       if (!attempt)
 224         {
 225           LT__SETERROR (NO_MEMORY);
 226           return module;
 227         }
 228 
 229       sprintf (attempt, "%s%s", filename, member);
 230       module = vm_open (loader_data, attempt, advise);
 231       FREE (attempt);
 232       return module;
 233     }
 234 #endif
 235 
 236   if (!module)
 237     {
 238       DL__SETERROR (CANNOT_OPEN);
 239     }
 240 
 241   return module;
 242 }
 243 
 244 
 245 
 246 
 247 static int
 248 vm_close (lt_user_data loader_data LT__UNUSED, lt_module module)
     
 249 {
 250   int errors = 0;
 251 
 252   if (dlclose (module) != 0)
 253     {
 254       DL__SETERROR (CANNOT_CLOSE);
 255       ++errors;
 256     }
 257 
 258   return errors;
 259 }
 260 
 261 
 262 
 263 
 264 static void *
 265 vm_sym (lt_user_data loader_data LT__UNUSED, lt_module module, const char *name)
     
 266 {
 267   void *address = dlsym (module, name);
 268 
 269   if (!address)
 270     {
 271       DL__SETERROR (SYMBOL_NOT_FOUND);
 272     }
 273 
 274   return address;
 275 }