This source file includes following definitions.
- get_vtable
- vl_exit
- vl_init
- vm_open
- vm_close
- vm_sym
- dylderror
- lt__nsmodule_get_header
- lt__header_get_instnam
- lt__match_loadedlib
- lt__linkedlib_symbol
   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      dyld_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_init  (lt_user_data loader_data);
  49 static int       vl_exit  (lt_user_data loader_data);
  50 static lt_module vm_open  (lt_user_data loader_data, const char *filename,
  51                            lt_dladvise advise);
  52 static int       vm_close (lt_user_data loader_data, lt_module module);
  53 static void *    vm_sym   (lt_user_data loader_data, lt_module module,
  54                           const char *symbolname);
  55 
  56 static lt_dlvtable *vtable = 0;
  57 
  58 
  59 
  60 
  61 lt_dlvtable *
  62 get_vtable (lt_user_data loader_data)
     
  63 {
  64   if (!vtable)
  65     {
  66       vtable = lt__zalloc (sizeof *vtable);
  67     }
  68 
  69   if (vtable && !vtable->name)
  70     {
  71       vtable->name              = "lt_dyld";
  72       vtable->sym_prefix        = "_";
  73       vtable->dlloader_init     = vl_init;
  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_APPEND;
  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_MACH_O_DYLD_H
  97 #  if !defined __APPLE_CC__ && !defined __MWERKS__ && !defined __private_extern__
  98   
  99 #    define __private_extern__ extern
 100 #  endif
 101 #  include <mach-o/dyld.h>
 102 #endif
 103 
 104 #include <mach-o/getsect.h>
 105 
 106 
 107 #if !defined ENUM_DYLD_BOOL
 108 # define ENUM_DYLD_BOOL
 109 # undef FALSE
 110 # undef TRUE
 111  enum DYLD_BOOL {
 112     FALSE,
 113     TRUE
 114  };
 115 #endif
 116 #if !defined LC_REQ_DYLD
 117 # define LC_REQ_DYLD 0x80000000
 118 #endif
 119 #if !defined LC_LOAD_WEAK_DYLIB
 120 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
 121 #endif
 122 
 123 #if !defined NSADDIMAGE_OPTION_NONE
 124 #  define NSADDIMAGE_OPTION_NONE                          0x0
 125 #endif
 126 #if !defined NSADDIMAGE_OPTION_RETURN_ON_ERROR
 127 #  define NSADDIMAGE_OPTION_RETURN_ON_ERROR               0x1
 128 #endif
 129 #if !defined NSADDIMAGE_OPTION_WITH_SEARCHING
 130 #  define NSADDIMAGE_OPTION_WITH_SEARCHING                0x2
 131 #endif
 132 #if !defined NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
 133 #  define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED         0x4
 134 #endif
 135 #if !defined NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
 136 #  define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
 137 #endif
 138 
 139 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
 140 #  define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND               0x0
 141 #endif
 142 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
 143 #  define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW           0x1
 144 #endif
 145 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
 146 #  define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY         0x2
 147 #endif
 148 #if !defined NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
 149 #  define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR    0x4
 150 #endif
 151 
 152 #define LT__SYMLOOKUP_OPTS      (NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW \
 153                                 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR)
 154 
 155 #if defined __BIG_ENDIAN__
 156 #  define LT__MAGIC     MH_MAGIC
 157 #else
 158 #  define LT__MAGIC     MH_CIGAM
 159 #endif
 160 
 161 #define DYLD__SETMYERROR(errmsg)    LT__SETERRORSTR (dylderror (errmsg))
 162 #define DYLD__SETERROR(errcode)     DYLD__SETMYERROR (LT__STRERROR (errcode))
 163 
 164 typedef struct mach_header mach_header;
 165 typedef struct dylib_command dylib_command;
 166 
 167 static const char *dylderror (const char *errmsg);
 168 static const mach_header *lt__nsmodule_get_header (NSModule module);
 169 static const char *lt__header_get_instnam (const mach_header *mh);
 170 static const mach_header *lt__match_loadedlib (const char *name);
 171 static NSSymbol lt__linkedlib_symbol (const char *symname, const mach_header *mh);
 172 
 173 static const mach_header *(*lt__addimage)       (const char *image_name,
 174                                                  unsigned long options) = 0;
 175 static NSSymbol (*lt__image_symbol)             (const mach_header *image,
 176                                                  const char *symbolName,
 177                                                  unsigned long options) = 0;
 178 static enum DYLD_BOOL (*lt__image_symbol_p)     (const mach_header *image,
 179                                                  const char *symbolName) = 0;
 180 static enum DYLD_BOOL (*lt__module_export)      (NSModule module) = 0;
 181 
 182 static int dyld_cannot_close                              = 0;
 183 
 184 
 185 
 186 
 187 static int
 188 vl_exit (lt_user_data loader_data LT__UNUSED)
     
 189 {
 190   vtable = NULL;
 191   return 0;
 192 }
 193 
 194 
 195 static int
 196 vl_init (lt_user_data loader_data)
     
 197 {
 198   int errors = 0;
 199 
 200   if (! dyld_cannot_close)
 201     {
 202       if (!_dyld_present ())
 203         {
 204           ++errors;
 205         }
 206       else
 207         {
 208           (void) _dyld_func_lookup ("__dyld_NSAddImage",
 209                                     (unsigned long*) <__addimage);
 210           (void) _dyld_func_lookup ("__dyld_NSLookupSymbolInImage",
 211                                     (unsigned long*)<__image_symbol);
 212           (void) _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage",
 213                                     (unsigned long*) <__image_symbol_p);
 214           (void) _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic",
 215                                     (unsigned long*) <__module_export);
 216           dyld_cannot_close = lt_dladderror ("can't close a dylib");
 217         }
 218     }
 219 
 220   return errors;
 221 }
 222 
 223 
 224 
 225 
 226 
 227 static lt_module
 228 vm_open (lt_user_data loader_data, const char *filename,
     
 229          lt_dladvise advise LT__UNUSED)
 230 {
 231   lt_module module = 0;
 232   NSObjectFileImage ofi = 0;
 233 
 234   if (!filename)
 235     {
 236       return (lt_module) -1;
 237     }
 238 
 239   switch (NSCreateObjectFileImageFromFile (filename, &ofi))
 240     {
 241     case NSObjectFileImageSuccess:
 242       module = NSLinkModule (ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR
 243                                             | NSLINKMODULE_OPTION_PRIVATE
 244                                             | NSLINKMODULE_OPTION_BINDNOW);
 245       NSDestroyObjectFileImage (ofi);
 246 
 247       if (module)
 248         {
 249           lt__module_export (module);
 250         }
 251       break;
 252 
 253     case NSObjectFileImageInappropriateFile:
 254       if (lt__image_symbol_p && lt__image_symbol)
 255         {
 256           module = (lt_module) lt__addimage(filename,
 257                                             NSADDIMAGE_OPTION_RETURN_ON_ERROR);
 258         }
 259       break;
 260 
 261     case NSObjectFileImageFailure:
 262     case NSObjectFileImageArch:
 263     case NSObjectFileImageFormat:
 264     case NSObjectFileImageAccess:
 265       
 266       break;
 267     }
 268 
 269   if (!module)
 270     {
 271       DYLD__SETERROR (CANNOT_OPEN);
 272     }
 273 
 274   return module;
 275 }
 276 
 277 
 278 
 279 
 280 static int
 281 vm_close (lt_user_data loader_data, lt_module module)
     
 282 {
 283   int errors = 0;
 284 
 285   if (module != (lt_module) -1)
 286     {
 287       const mach_header *mh = (const mach_header *) module;
 288       int flags = 0;
 289       if (mh->magic == LT__MAGIC)
 290         {
 291           lt_dlseterror (dyld_cannot_close);
 292           ++errors;
 293         }
 294       else
 295         {
 296           
 297 
 298 
 299           if ((const struct section *) NULL !=
 300               getsectbynamefromheader (lt__nsmodule_get_header (module),
 301                                        "__DATA", "__mod_term_func"))
 302             {
 303               flags |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
 304             }
 305 #if defined __ppc__
 306           flags |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
 307 #endif
 308           if (!NSUnLinkModule (module, flags))
 309             {
 310               DYLD__SETERROR (CANNOT_CLOSE);
 311               ++errors;
 312             }
 313         }
 314     }
 315 
 316   return errors;
 317 }
 318 
 319 
 320 
 321 static void *
 322 vm_sym (lt_user_data loader_data, lt_module module, const char *name)
     
 323 {
 324   NSSymbol *nssym = 0;
 325   const mach_header *mh = (const mach_header *) module;
 326   char saveError[256] = "Symbol not found";
 327 
 328   if (module == (lt_module) -1)
 329     {
 330       void *address, *unused;
 331       _dyld_lookup_and_bind (name, (unsigned long*) &address, &unused);
 332       return address;
 333     }
 334 
 335   if (mh->magic == LT__MAGIC)
 336     {
 337       if (lt__image_symbol_p && lt__image_symbol)
 338         {
 339           if (lt__image_symbol_p (mh, name))
 340             {
 341               nssym = lt__image_symbol (mh, name, LT__SYMLOOKUP_OPTS);
 342             }
 343         }
 344 
 345     }
 346   else
 347     {
 348       nssym = NSLookupSymbolInModule (module, name);
 349     }
 350 
 351   if (!nssym)
 352     {
 353       strlcpy (saveError, dylderror (LT__STRERROR (SYMBOL_NOT_FOUND)), 255);
 354       saveError[255] = 0;
 355       if (!mh)
 356         {
 357           mh = (mach_header *)lt__nsmodule_get_header (module);
 358         }
 359       nssym = lt__linkedlib_symbol (name, mh);
 360     }
 361 
 362   if (!nssym)
 363     {
 364       LT__SETERRORSTR (saveError);
 365     }
 366 
 367   return nssym ? NSAddressOfSymbol (nssym) : 0;
 368 }
 369 
 370 
 371 
 372 
 373 
 374 
 375 
 376 
 377 static const char *
 378 dylderror (const char *errmsg)
     
 379 {
 380   NSLinkEditErrors ler;
 381   int lerno;
 382   const char *file;
 383   const char *errstr;
 384 
 385   NSLinkEditError (&ler, &lerno, &file, &errstr);
 386 
 387   if (! (errstr && *errstr))
 388     {
 389       errstr = errmsg;
 390     }
 391 
 392   return errstr;
 393 }
 394 
 395 
 396 static const mach_header *
 397 lt__nsmodule_get_header (NSModule module)
     
 398 {
 399   int i = _dyld_image_count();
 400   const char *modname = NSNameOfModule (module);
 401   const mach_header *mh = 0;
 402 
 403   if (!modname)
 404     return NULL;
 405 
 406   while (i > 0)
 407     {
 408       --i;
 409       if (strneq (_dyld_get_image_name (i), modname))
 410         {
 411           mh = _dyld_get_image_header (i);
 412           break;
 413         }
 414     }
 415 
 416   return mh;
 417 }
 418 
 419 
 420 
 421 
 422 
 423 static const char *
 424 lt__header_get_instnam (const mach_header *mh)
     
 425 {
 426   unsigned long offset = sizeof(mach_header);
 427   const char* result   = 0;
 428   int j;
 429 
 430   for (j = 0; j < mh->ncmds; j++)
 431     {
 432       struct load_command *lc;
 433 
 434       lc = (struct load_command*) (((unsigned long) mh) + offset);
 435       if (LC_ID_DYLIB == lc->cmd)
 436         {
 437           result=(char*)(((dylib_command*) lc)->dylib.name.offset +
 438                          (unsigned long) lc);
 439         }
 440       offset += lc->cmdsize;
 441     }
 442 
 443   return result;
 444 }
 445 
 446 static const mach_header *
 447 lt__match_loadedlib (const char *name)
     
 448 {
 449   const mach_header *mh = 0;
 450   int i = _dyld_image_count();
 451 
 452   while (i > 0)
 453     {
 454       const char *id;
 455 
 456       --i;
 457       id = lt__header_get_instnam (_dyld_get_image_header (i));
 458       if (id && strneq (id, name))
 459         {
 460           mh = _dyld_get_image_header (i);
 461           break;
 462         }
 463     }
 464 
 465   return mh;
 466 }
 467 
 468 
 469 static NSSymbol
 470 lt__linkedlib_symbol (const char *symname, const mach_header *mh)
     
 471 {
 472   NSSymbol symbol = 0;
 473 
 474   if (lt__image_symbol && NSIsSymbolNameDefined (symname))
 475     {
 476       unsigned long offset = sizeof(mach_header);
 477       struct load_command *lc;
 478       int j;
 479 
 480       for (j = 0; j < mh->ncmds; j++)
 481         {
 482           lc = (struct load_command*) (((unsigned long) mh) + offset);
 483           if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
 484             {
 485               unsigned long base = ((dylib_command *) lc)->dylib.name.offset;
 486               char *name = (char *) (base + (unsigned long) lc);
 487               const mach_header *mh1 = lt__match_loadedlib (name);
 488 
 489               if (!mh1)
 490                 {
 491                   
 492                   mh1 = lt__addimage (name,
 493                                       NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
 494                                       | NSADDIMAGE_OPTION_WITH_SEARCHING
 495                                       | NSADDIMAGE_OPTION_RETURN_ON_ERROR);
 496                 }
 497 
 498               if (mh1)
 499                 {
 500                   symbol = lt__image_symbol (mh1, symname, LT__SYMLOOKUP_OPTS);
 501                   if (symbol)
 502                     break;
 503                 }
 504             }
 505 
 506           offset += lc->cmdsize;
 507         }
 508     }
 509 
 510   return symbol;
 511 }