static void *dlopen(const char *path, int mode) { void *handle= 0; NSObjectFileImage ofi= 0; if (!dlInitialised) { dlinit(); dlInitialised= 1; } if (!path) return DL_APP_CONTEXT; switch (NSCreateObjectFileImageFromFile(path, &ofi)) { case NSObjectFileImageSuccess: handle= NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(ofi); break; case NSObjectFileImageInappropriateFile: handle= (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); break; default: handle= 0; break; } if (!handle) dlSetError("could not load shared object: %s", path); dprintf((stderr, "dlopen: %s => %d\n", path, (int)handle)); return handle; }
void * caml_dlopen(char * libname, int for_execution) { NSObjectFileImage image; entry_t *bentry = caml_lookup_bundle(libname); NSObjectFileImageReturnCode retCode; void *result = NULL; if (bentry->count > 0) return bentry->handle; retCode = NSCreateObjectFileImageFromFile(libname, &image); switch (retCode) { case NSObjectFileImageSuccess: dlerror_string = NULL; result = (void*)NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); if (result != NULL) { bentry->count++; bentry->handle = result; } else NSDestroyObjectFileImage(image); break; case NSObjectFileImageAccess: dlerror_string = "cannot access this bundle"; break; case NSObjectFileImageArch: dlerror_string = "this bundle has wrong CPU architecture"; break; case NSObjectFileImageFormat: case NSObjectFileImageInappropriateFile: dlerror_string = "this file is not a proper bundle"; break; default: dlerror_string = "could not read object file"; break; } return result; }
static NSModule pr_LoadMachDyldModule(const char *name) { NSObjectFileImage ofi; NSModule h = NULL; if (NSCreateObjectFileImageFromFile(name, &ofi) == NSObjectFileImageSuccess) { h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); if (h == NULL) { NSLinkEditErrors linkEditError; int errorNum; const char *fileName; const char *errorString; NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("LoadMachDyldModule error %d:%d for file %s:\n%s", linkEditError, errorNum, fileName, errorString)); } if (NSDestroyObjectFileImage(ofi) == FALSE) { if (h) { (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE); h = NULL; } } } return h; }
static void dlclose(NS_pair *p) { if (NSUnLinkModule(p->m, NSUNLINKMODULE_OPTION_NONE)) NSDestroyObjectFileImage(p->ofi); free(p); }
SharedLibraryRef dyldSharedLibraryLoader::loadSharedLibrary(const String& filename, const LoggerRef& logger) const { OW_LOG_DEBUG(logger, Format("Load request for %1 received.", filename)); NSObjectFileImage image = 0; NSObjectFileImageReturnCode dsoerr = NSCreateObjectFileImageFromFile(filename.c_str(), &image); const char* err_msg = NULL; NSModule libhandle = NULL; if (dsoerr == NSObjectFileImageSuccess) { libhandle = NSLinkModule(image, filename.c_str(), NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE); if (!libhandle) { NSLinkEditErrors errors; int errorNumber; const char *fileName; NSLinkEditError(&errors, &errorNumber, &fileName, &err_msg); } NSDestroyObjectFileImage(image); } else if ((dsoerr == NSObjectFileImageFormat || dsoerr == NSObjectFileImageInappropriateFile) && NSAddLibrary(filename.c_str()) == TRUE) { OW_LOG_ERROR(logger, Format("NSCreateObject: %1 failed with error \"%2\"", filename, dsoerr)); // libhandle = (NSModule)DYLD_LIBRARY_HANDLE; } else { err_msg = "cannot create object file image or add library"; OW_LOG_ERROR(logger, Format("NSCreateObject: %1 failed with error %2", filename, dsoerr)); } if (libhandle) { try { return SharedLibraryRef( new dyldSharedLibrary(libhandle, filename)); } catch (...) { NSUnLinkModule(libhandle, FALSE); throw; } } else { OW_LOG_ERROR(logger, Format("dyldSharedLibraryLoader::loadSharedLibrary:" " %1", err_msg)); return SharedLibraryRef( 0 ); } }
/* dlopen */ void *darwin_dlopen(const char *path, int mode) { void *module = 0; NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; static int (*make_private_module_public) (NSModule module) = 0; unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE; sys::coreout << "darwin try bind module: " << path << sys::eofl; /* If we got no path, the app wants the global namespace, use -1 as the marker in this case */ if (!path) return (void *)-1; /* Create the object file image, works for things linked with the -bundle arg to ld */ ofirc = NSCreateObjectFileImageFromFile(path, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: /* It was okay, so use NSLinkModule to link in the image */ if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW; module = NSLinkModule(ofi, path,flags); sys::coreout << "darwin bind module: " << path << sys::eofl; /* Don't forget to destroy the object file image, unless you like leaks */ NSDestroyObjectFileImage(ofi); /* If the mode was global, then change the module, this avoids multiply defined symbol errors to first load private then make global. Silly, isn't it. */ if ((mode & RTLD_GLOBAL)) { if (!make_private_module_public) { _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (unsigned long *)&make_private_module_public); } make_private_module_public(module); } break; case NSObjectFileImageInappropriateFile: /* It may have been a dynamic library rather than a bundle, try to load it */ module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); sys::coreout << " wrong filetype use addimage: " << (void*)module << sys::eofl; break; case NSObjectFileImageFailure: error(0,"Object file setup failure : \"%s\"", path); return 0; case NSObjectFileImageArch: error(0,"No object for this architecture : \"%s\"", path); return 0; case NSObjectFileImageFormat: error(0,"Bad object file format : \"%s\"", path); return 0; case NSObjectFileImageAccess: error(0,"Can't read object file : \"%s\"", path); return 0; } if (!module) error(0, "Can not open \"%s\"", path); return module; }
static void *dlclose(void *handle_) { struct pike_dl_handle *handle = handle_; if (handle) { if (handle->module) NSUnLinkModule(handle->module, NSUNLINKMODULE_OPTION_NONE); handle->module = NULL; if (handle->image) NSDestroyObjectFileImage(handle->image); handle->image = NULL; free(handle); } return NULL; }
/* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { lt_module module = 0; NSObjectFileImage ofi = 0; if (!filename) { return (lt_module) -1; } switch (NSCreateObjectFileImageFromFile (filename, &ofi)) { case NSObjectFileImageSuccess: module = NSLinkModule (ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage (ofi); if (module) { lt__module_export (module); } break; case NSObjectFileImageInappropriateFile: if (lt__image_symbol_p && lt__image_symbol) { module = (lt_module) lt__addimage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); } break; case NSObjectFileImageFailure: case NSObjectFileImageArch: case NSObjectFileImageFormat: case NSObjectFileImageAccess: /*NOWORK*/ break; } if (!module) { DYLD__SETERROR (CANNOT_OPEN); } return module; }
CF_PRIVATE void _CFBundleDYLDUnloadBundle(CFBundleRef bundle) { if (bundle->_isLoaded) { #if LOG_BUNDLE_LOAD printf("dyld unload bundle %p, handle %p module %p image %p\n", bundle, bundle->_handleCookie, bundle->_moduleCookie, bundle->_imageCookie); #endif /* LOG_BUNDLE_LOAD */ if (bundle->_moduleCookie && !NSUnLinkModule((NSModule)(bundle->_moduleCookie), NSUNLINKMODULE_OPTION_NONE)) { CFLog(__kCFLogBundle, CFSTR("Internal error unloading bundle %@"), bundle); } else { if (bundle->_moduleCookie && bundle->_imageCookie) (void)NSDestroyObjectFileImage((NSObjectFileImage)(bundle->_imageCookie)); bundle->_connectionCookie = bundle->_handleCookie = NULL; bundle->_imageCookie = bundle->_moduleCookie = NULL; bundle->_isLoaded = false; } } }
static void * dyld_dlopen(const char * file) { NSObjectFileImage o=NULL; NSObjectFileImageReturnCode r; NSModule m=NULL; const unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE; dyld_error_set=0; r = NSCreateObjectFileImageFromFile(file,&o); if (NSObjectFileImageSuccess == r) { m=NSLinkModule(o,file,flags); NSDestroyObjectFileImage(o); if (!m) dyld_error_set=1; } return (void*)m; }
int main() { // NSCreateObjectFileImageFromMemory is only available on Mac OS X - not iPhone OS #if __MAC_OS_X_VERSION_MIN_REQUIRED NSObjectFileImage ofi; if ( NSCreateObjectFileImageFromFile("test.bundle", &ofi) != NSObjectFileImageSuccess ) { FAIL("NSCreateObjectFileImageFromFile failed"); return 1; } NSModule mod = NSLinkModule(ofi, "test.bundle", NSLINKMODULE_OPTION_NONE); if ( mod == NULL ) { FAIL("NSLinkModule failed"); return 1; } NSSymbol sym = NSLookupSymbolInModule(mod, "_checkdata"); if ( sym == NULL ) { FAIL("NSLookupSymbolInModule failed"); return 1; } CheckFunc func = NSAddressOfSymbol(sym); if ( !func() ) { FAIL("NSAddressOfSymbol failed"); return 1; } if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED) ) { FAIL("NSUnLinkModule failed"); return 1; } if ( !NSDestroyObjectFileImage(ofi) ) { FAIL("NSDestroyObjectFileImage failed"); return 1; } // call function again, even though bundle is unloaded func(); #endif PASS("bundle-basic"); return 0; }
static void* ll_load (lua_State *L, const char* path) { NSObjectFileImage img; NSObjectFileImageReturnCode ret; /* this would be a rare case, but prevents crashing if it happens */ if(!_dyld_present()) { lua_pushliteral(L, "dyld not present"); return nullptr; } ret = NSCreateObjectFileImageFromFile(path, &img); if (ret == NSObjectFileImageSuccess) { NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(img); if (mod == nullptr) pusherror(L); return mod; } lua_pushstring(L, errorfromcode(ret)); return nullptr; }
/* ggDarwinDLCose implements a "dlclose() wrapper */ void ggDarwinDLClose(gg_dlhand handle) { struct gg_dlhand_darwin_t *darwin_module; darwin_module = (struct gg_dlhand_darwin_t *)handle; NSUnLinkModule(darwin_module->nsmodule, NSUNLINKMODULE_OPTION_NONE); /* no error checking needed here, because * the error handlers are called, if necessary */ #ifdef HAVE_NSDESTROYOBJECTFILEIMAGE /* Darwin < 6.1 doesn't have this function implemented */ NSDestroyObjectFileImage(darwin_module->objectFileImage); #endif free(darwin_module); return; } /* ggDarwinDLClose */
static NSModule pr_LoadMachDyldModule(const char *name) { NSObjectFileImage ofi; NSModule h = NULL; if (NSCreateObjectFileImageFromFile(name, &ofi) == NSObjectFileImageSuccess) { h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); /* * TODO: If NSLinkModule fails, use NSLinkEditError to retrieve * error information. */ if (NSDestroyObjectFileImage(ofi) == FALSE) { if (h) { (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE); h = NULL; } } } return h; }
/* darwin_dlopen */ static void *darwin_dlopen(const char *path, int mode) { void *module = 0; NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; /* If we got no path, the app wants the global namespace, use -1 as the marker in this case */ if (!path) return (void *)-1; /* Create the object file image, works for things linked with the -bundle arg to ld */ ofirc = NSCreateObjectFileImageFromFile(path, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: /* It was okay, so use NSLinkModule to link in the image */ module = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage(ofi); break; case NSObjectFileImageInappropriateFile: /* It may have been a dynamic library rather than a bundle, try to load it */ module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); break; default: /* God knows what we got */ error(0, "Can not open \"%s\"", path); return 0; } if (!module) error(0, "Can not open \"%s\"", path); return module; }
DWORD OSXPluginInstance::Unload() { if (m_ffInstanceID!=INVALIDINSTANCE) { FFDebugMessage("Failed to call DeInstantiateGL before Unload()"); return FF_FAIL; } DeinitPluginLibrary(); if (m_ffModule != NULL) { if (NSUnLinkModule(m_ffModule, NSUNLINKMODULE_OPTION_NONE)) { m_ffModule = NULL; } else { FFDebugMessage("couldn't free dynamic library"); } } if (m_ffImage != NULL) { if (NSDestroyObjectFileImage(m_ffImage)) { m_ffImage = NULL; } else { FFDebugMessage("couldn't destroy object file image"); } } return FF_SUCCESS; }
static struct dlstatus * loadModule(const char * path, const struct stat * sbuf, int mode) { NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; struct dlstatus * dls; NSLinkEditErrors ler; int lerno; const char* errstr; const char* file; void (*init)(void); ofirc = NSCreateObjectFileImageFromFile(path, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: break; case NSObjectFileImageInappropriateFile: if (isFlagSet(mode, RTLD_LOCAL)) { warning("trying to open a .dylib with RTLD_LOCAL"); error("unable to open this file with RTLD_LOCAL"); return NULL; } break; case NSObjectFileImageFailure: error("object file setup failure"); return NULL; case NSObjectFileImageArch: error("no object for this architecture"); return NULL; case NSObjectFileImageFormat: error("bad object file format"); return NULL; case NSObjectFileImageAccess: error("can't read object file"); return NULL; default: error("unknown error from NSCreateObjectFileImageFromFile()"); return NULL; } dls = lookupStatus(sbuf); if (!dls) { dls = allocStatus(); } if (!dls) { error("unable to allocate memory"); return NULL; } dls->lib=0; if (ofirc == NSObjectFileImageInappropriateFile) { if ((dls->lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { debug("Dynamic lib loaded at %ld",dls->lib); ofi = MAGIC_DYLIB_OFI; dls->module = MAGIC_DYLIB_MOD; ofirc = NSObjectFileImageSuccess; } } else { /* Should change this to take care of RLTD_LAZY etc */ dls->module = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage(ofi); } if (!dls->module) { NSLinkEditError(&ler,&lerno,&file,&errstr); free(dls); error(errstr); return NULL; } insertStatus(dls, sbuf); if ((init = dlsymIntern(dls, "__init",0))) { debug("calling _init()"); init(); } return dls; }
ppl_status_t ppl_dso_load (ppl_dso_handle_t ** dso_handle, const char *path) { #if defined(DSO_USE_SHL) shl_t os_handle = shl_load (path, BIND_IMMEDIATE | BIND_VERBOSE | BIND_NOSTART, 0L); #elif defined(DSO_USE_DYLD) NSObjectFileImage image; NSModule os_handle = NULL; char *err_msg = NULL; if (NSCreateObjectFileImageFromFile (path, &image) != NSObjectFileImageSuccess) { err_msg = "cannot create object file image"; } else { #ifdef NSLINKMODULE_OPTION_PRIVATE os_handle = NSLinkModule (image, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); #else os_handle = NSLinkModule (image, path, TRUE); #endif NSDestroyObjectFileImage (image); } #elif defined(DSO_USE_DLFCN) #if defined(OSF1) || defined(SEQUENT) || defined(SNI) ||\ (defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) void *os_handle = dlopen ((char *) path, RTLD_NOW | RTLD_GLOBAL); #else int flags = RTLD_NOW | RTLD_GLOBAL; void *os_handle; #ifdef _AIX if (strchr (path + 1, '(') && path[strlen (path) - 1] == ')') { /* This special archive.a(dso.so) syntax is required for * the way libtool likes to build shared libraries on AIX. * dlopen() support for such a library requires that the * RTLD_MEMBER flag be enabled. */ flags |= RTLD_MEMBER; } #endif os_handle = dlopen (path, flags); #endif #endif /* DSO_USE_x */ *dso_handle = (ppl_dso_handle_t *) osip_malloc (sizeof (ppl_dso_handle_t)); if (os_handle == NULL) { #if defined(DSO_USE_SHL) (*dso_handle)->errormsg = strerror (errno); return errno; #elif defined(DSO_USE_DYLD) (*dso_handle)->errormsg = (err_msg) ? err_msg : "link failed"; return PPL_EDSOOPEN; #elif defined(DSO_USE_DLFCN) (*dso_handle)->errormsg = dlerror (); return PPL_EDSOOPEN; #endif } (*dso_handle)->handle = (void *) os_handle; (*dso_handle)->errormsg = NULL; return PPL_SUCCESS; }
static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode) { NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; struct dlstatus *dls; NSLinkEditErrors ler; int lerno; const char *errstr; const char *file; void (*init) (void); ofirc = NSCreateObjectFileImageFromFile(path, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: break; case NSObjectFileImageInappropriateFile: if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) { if (isFlagSet(mode, RTLD_LOCAL)) { warning("trying to open a .dylib with RTLD_LOCAL"); error("unable to open this file with RTLD_LOCAL"); return NULL; } } else { error("opening this file is unsupported on this system"); return NULL; } break; case NSObjectFileImageFailure: error("object file setup failure"); return NULL; case NSObjectFileImageArch: error("no object for this architecture"); return NULL; case NSObjectFileImageFormat: error("bad object file format"); return NULL; case NSObjectFileImageAccess: error("can't read object file"); return NULL; default: error("unknown error from NSCreateObjectFileImageFromFile()"); return NULL; } dls = lookupStatus(sbuf); if (!dls) { dls = allocStatus(); } if (!dls) { error("unable to allocate memory"); return NULL; } dls->lib = 0; if (ofirc == NSObjectFileImageInappropriateFile) { if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { debug("Dynamic lib loaded at %ld", dls->lib); ofi = MAGIC_DYLIB_OFI; dls->module = MAGIC_DYLIB_MOD; ofirc = NSObjectFileImageSuccess; /* Although it is possible with a bit of work to modify this so it works and functions with RTLD_NOW, I don't deem it necessary at the moment */ } if (!(dls->module)) { NSLinkEditError(&ler, &lerno, &file, &errstr); if (!errstr || (!strlen(errstr))) error("Can't open this file type"); else error(errstr); if ((dls->flags & DL_IN_LIST) == 0) { free(dls); } return NULL; } } else { dls->module = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0)); NSDestroyObjectFileImage(ofi); if (dls->module) { dls->lib = get_mach_header_from_NSModule(dls->module); } } if (!dls->module) { NSLinkEditError(&ler, &lerno, &file, &errstr); if ((dls->flags & DL_IN_LIST) == 0) { free(dls); } error(errstr); return NULL; } insertStatus(dls, sbuf); dls = reference(dls, mode); if ((init = dlsymIntern(dls, "__init", 0))) { debug("calling _init()"); init(); } return dls; }
int main() { // NSObjectFileImage APIs are only available on Mac OS X - not iPhone OS #if __MAC_OS_X_VERSION_MIN_REQUIRED int fd = open("test.bundle", O_RDONLY, 0); if ( fd == -1 ) { FAIL("open() failed"); return 1; } struct stat stat_buf; if ( fstat(fd, &stat_buf) == -1) { FAIL("fstat() failed"); return 0; } void* loadAddress = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); if ( loadAddress == ((void*)(-1)) ) { FAIL("mmap() failed"); return 0; } close(fd); NSObjectFileImage ofi; if ( NSCreateObjectFileImageFromMemory(loadAddress, stat_buf.st_size, &ofi) != NSObjectFileImageSuccess ) { FAIL("NSCreateObjectFileImageFromMemory failed"); return 0; } NSModule mod = NSLinkModule(ofi, "he_he", NSLINKMODULE_OPTION_NONE); if ( mod == NULL ) { FAIL("NSLinkModule failed"); return 0; } // look for he_he string in list of images loaded struct dyld_all_image_infos* infos = getImageInfosFromKernel(); if ( infos->infoArrayCount < 2 ) { FAIL("bundle-memory-load-all-images: dyld_all_image_infos.infoArrayCount is < 2"); return 0; } bool found = false; for( int i=0; i < infos->infoArrayCount; ++i) { //fprintf(stderr, "infos->infoArray[%d].imageLoadAddress=%p %s\n", i, infos->infoArray[i].imageLoadAddress, infos->infoArray[i].imageFilePath); if ( infos->infoArray[i].imageFilePath == NULL ) { FAIL("bundle-memory-load-all-images: NULL image path found"); exit(0); } if ( strcmp(infos->infoArray[i].imageFilePath, "he_he") == 0 ) found = true; } if ( !found ) { FAIL("bundle-memory-load-all-images: loaded memory bundle 'he_he' nout found"); return 0; } if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) { FAIL("NSUnLinkModule failed"); return 0; } if ( !NSDestroyObjectFileImage(ofi) ) { FAIL("NSDestroyObjectFileImage failed"); return 0; } // Should check that loadAddress is unmmaped now (by call to NSDestroyObjectFileImage) #endif PASS("bundle-memory-load-all-images"); return 0; }
MODULE_SCOPE int TclpLoadMemory( Tcl_Interp *interp, /* Used for error reporting. */ void *buffer, /* Buffer containing the desired code * (allocated with TclpLoadMemoryGetBuffer). */ int size, /* Allocation size of buffer. */ int codeSize, /* Size of code data read into buffer or -1 if * an error occurred and the buffer should * just be freed. */ Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded * file which will be passed back to * (*unloadProcPtr)() to unload the file. */ Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ { Tcl_DyldLoadHandle *dyldLoadHandle; NSObjectFileImage dyldObjFileImage = NULL; Tcl_DyldModuleHandle *modulePtr; NSModule module; const char *objFileImageErrMsg = NULL; /* * Try to create an object file image that we can load from. */ if (codeSize >= 0) { NSObjectFileImageReturnCode err = NSObjectFileImageSuccess; const struct fat_header *fh = buffer; uint32_t ms = 0; #ifndef __LP64__ const struct mach_header *mh = NULL; #define mh_size sizeof(struct mach_header) #define mh_magic MH_MAGIC #define arch_abi 0 #else const struct mach_header_64 *mh = NULL; #define mh_size sizeof(struct mach_header_64) #define mh_magic MH_MAGIC_64 #define arch_abi CPU_ARCH_ABI64 #endif if ((size_t) codeSize >= sizeof(struct fat_header) && fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) { uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); /* * Fat binary, try to find mach_header for our architecture */ TclLoadDbgMsg("Fat binary, %d archs", fh_nfat_arch); if ((size_t) codeSize >= sizeof(struct fat_header) + fh_nfat_arch * sizeof(struct fat_arch)) { void *fatarchs = (char*)buffer + sizeof(struct fat_header); const NXArchInfo *arch = NXGetLocalArchInfo(); struct fat_arch *fa; if (fh->magic != FAT_MAGIC) { swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder); } fa = NXFindBestFatArch(arch->cputype | arch_abi, arch->cpusubtype, fatarchs, fh_nfat_arch); if (fa) { TclLoadDbgMsg("NXFindBestFatArch() successful: " "local cputype %d subtype %d, " "fat cputype %d subtype %d", arch->cputype | arch_abi, arch->cpusubtype, fa->cputype, fa->cpusubtype); mh = (void*)((char*)buffer + fa->offset); ms = fa->size; } else { TclLoadDbgMsg("NXFindBestFatArch() failed"); err = NSObjectFileImageInappropriateFile; } if (fh->magic != FAT_MAGIC) { swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder); } } else { TclLoadDbgMsg("Fat binary header failure"); err = NSObjectFileImageInappropriateFile; } } else { /* * Thin binary */ TclLoadDbgMsg("Thin binary"); mh = buffer; ms = codeSize; } if (ms && !(ms >= mh_size && mh->magic == mh_magic && mh->filetype == MH_BUNDLE)) { TclLoadDbgMsg("Inappropriate file: magic %x filetype %d", mh->magic, mh->filetype); err = NSObjectFileImageInappropriateFile; } if (err == NSObjectFileImageSuccess) { err = NSCreateObjectFileImageFromMemory(buffer, codeSize, &dyldObjFileImage); if (err == NSObjectFileImageSuccess) { TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() " "successful"); } else { objFileImageErrMsg = DyldOFIErrorMsg(err); TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() failed: %s", objFileImageErrMsg); } } else { objFileImageErrMsg = DyldOFIErrorMsg(err); } } /* * If it went wrong (or we were asked to just deallocate), get rid of the * memory block and create an error message. */ if (dyldObjFileImage == NULL) { vm_deallocate(mach_task_self(), (vm_address_t) buffer, size); if (objFileImageErrMsg != NULL) { Tcl_AppendResult(interp, "NSCreateObjectFileImageFromMemory() " "error: ", objFileImageErrMsg, NULL); } return TCL_ERROR; } /* * Extract the module we want from the image of the object file. */ module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { TclLoadDbgMsg("NSLinkModule() successful"); } else { NSLinkEditErrors editError; int errorNumber; const char *errorName, *errMsg; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg); Tcl_AppendResult(interp, errMsg, NULL); return TCL_ERROR; } /* * Stash the module reference within the load handle we create and return. */ modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = NULL; dyldLoadHandle = (Tcl_DyldLoadHandle *) ckalloc(sizeof(Tcl_DyldLoadHandle)); #if TCL_DYLD_USE_DLFCN dyldLoadHandle->dlHandle = NULL; #endif dyldLoadHandle->dyldLibHeader = NULL; dyldLoadHandle->modulePtr = modulePtr; *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; *unloadProcPtr = &TclpUnloadFile; return TCL_OK; }
MODULE_SCOPE int TclpDlopen( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Obj *pathPtr, /* Name of the file containing the desired * code (UTF-8). */ Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded * file which will be passed back to * (*unloadProcPtr)() to unload the file. */ Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ { Tcl_DyldLoadHandle *dyldLoadHandle; #if TCL_DYLD_USE_DLFCN void *dlHandle = NULL; #endif #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) const struct mach_header *dyldLibHeader = NULL; Tcl_DyldModuleHandle *modulePtr = NULL; #endif #if TCL_DYLD_USE_NSMODULE NSLinkEditErrors editError; int errorNumber; const char *errorName, *objFileImageErrMsg = NULL; #endif const char *errMsg = NULL; int result; Tcl_DString ds; char *fileName = NULL; const char *nativePath, *nativeFileName = NULL; /* * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ nativePath = Tcl_FSGetNativePath(pathPtr); #if TCL_DYLD_USE_DLFCN #if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 if (tclMacOSXDarwinRelease >= 8) #endif { dlHandle = dlopen(nativePath, RTLD_NOW | RTLD_LOCAL); if (!dlHandle) { /* * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path. */ fileName = Tcl_GetString(pathPtr); nativeFileName = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); dlHandle = dlopen(nativeFileName, RTLD_NOW | RTLD_LOCAL); } if (dlHandle) { TclLoadDbgMsg("dlopen() successful"); } else { errMsg = dlerror(); TclLoadDbgMsg("dlopen() failed: %s", errMsg); } } if (!dlHandle) #endif /* TCL_DYLD_USE_DLFCN */ { #if TCL_DYLD_USE_NSMODULE dyldLibHeader = NSAddImage(nativePath, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (dyldLibHeader) { TclLoadDbgMsg("NSAddImage() successful"); } else { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); if (editError == NSLinkEditFileAccessError) { /* * The requested file was not found. Let the OS loader examine * the binary search path for whatever string the user gave us * which hopefully refers to a file on the binary path. */ if (!fileName) { fileName = Tcl_GetString(pathPtr); nativeFileName = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); } dyldLibHeader = NSAddImage(nativeFileName, NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (dyldLibHeader) { TclLoadDbgMsg("NSAddImage() successful"); } else { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); TclLoadDbgMsg("NSAddImage() failed: %s", errMsg); } } else if ((editError == NSLinkEditFileFormatError && errorNumber == EBADMACHO) || editError == NSLinkEditOtherError){ NSObjectFileImageReturnCode err; NSObjectFileImage dyldObjFileImage; NSModule module; /* * The requested file was found but was not of type MH_DYLIB, * attempt to load it as a MH_BUNDLE. */ err = NSCreateObjectFileImageFromFile(nativePath, &dyldObjFileImage); if (err == NSObjectFileImageSuccess && dyldObjFileImage) { TclLoadDbgMsg("NSCreateObjectFileImageFromFile() " "successful"); module = NSLinkModule(dyldObjFileImage, nativePath, NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = NULL; TclLoadDbgMsg("NSLinkModule() successful"); } else { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg); } } else { objFileImageErrMsg = DyldOFIErrorMsg(err); TclLoadDbgMsg("NSCreateObjectFileImageFromFile() failed: " "%s", objFileImageErrMsg); } } } #endif /* TCL_DYLD_USE_NSMODULE */ } if (0 #if TCL_DYLD_USE_DLFCN || dlHandle #endif #if TCL_DYLD_USE_NSMODULE || dyldLibHeader || modulePtr #endif ) { dyldLoadHandle = (Tcl_DyldLoadHandle *) ckalloc(sizeof(Tcl_DyldLoadHandle)); #if TCL_DYLD_USE_DLFCN dyldLoadHandle->dlHandle = dlHandle; #endif #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) dyldLoadHandle->dyldLibHeader = dyldLibHeader; dyldLoadHandle->modulePtr = modulePtr; #endif *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; *unloadProcPtr = &TclpUnloadFile; result = TCL_OK; } else { Tcl_AppendResult(interp, errMsg, NULL); #if TCL_DYLD_USE_NSMODULE if (objFileImageErrMsg) { Tcl_AppendResult(interp, "\nNSCreateObjectFileImageFromFile() " "error: ", objFileImageErrMsg, NULL); } #endif result = TCL_ERROR; } if(fileName) { Tcl_DStringFree(&ds); } return result; }
APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle, const char *path, apr_pool_t *pool) { #if defined(DSO_USE_SHL) shl_t os_handle = shl_load(path, BIND_IMMEDIATE, 0L); #elif defined(DSO_USE_DYLD) NSObjectFileImage image; NSModule os_handle = NULL; NSObjectFileImageReturnCode dsoerr; const char* err_msg = NULL; dsoerr = NSCreateObjectFileImageFromFile(path, &image); if (dsoerr == NSObjectFileImageSuccess) { #if defined(NSLINKMODULE_OPTION_RETURN_ON_ERROR) && defined(NSLINKMODULE_OPTION_NONE) os_handle = NSLinkModule(image, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_NONE); /* If something went wrong, get the errors... */ if (!os_handle) { NSLinkEditErrors errors; int errorNumber; const char *fileName; NSLinkEditError(&errors, &errorNumber, &fileName, &err_msg); } #else os_handle = NSLinkModule(image, path, FALSE); #endif NSDestroyObjectFileImage(image); } else if ((dsoerr == NSObjectFileImageFormat || dsoerr == NSObjectFileImageInappropriateFile) && NSAddLibrary(path) == TRUE) { os_handle = (NSModule)DYLD_LIBRARY_HANDLE; } else { err_msg = "cannot create object file image or add library"; } #elif defined(DSO_USE_DLFCN) #if defined(OSF1) || defined(SEQUENT) || defined(SNI) ||\ (defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) void *os_handle = dlopen((char *)path, RTLD_NOW | RTLD_GLOBAL); #else int flags = RTLD_NOW | RTLD_GLOBAL; void *os_handle; #ifdef _AIX if (strchr(path + 1, '(') && path[strlen(path) - 1] == ')') { /* This special archive.a(dso.so) syntax is required for * the way libtool likes to build shared libraries on AIX. * dlopen() support for such a library requires that the * RTLD_MEMBER flag be enabled. */ flags |= RTLD_MEMBER; } #endif os_handle = dlopen(path, flags); #endif #endif /* DSO_USE_x */ *res_handle = apr_pcalloc(pool, sizeof(**res_handle)); if(os_handle == NULL) { #if defined(DSO_USE_SHL) (*res_handle)->errormsg = strerror(errno); return APR_EDSOOPEN; #elif defined(DSO_USE_DYLD) (*res_handle)->errormsg = (err_msg) ? err_msg : "link failed"; return APR_EDSOOPEN; #elif defined(DSO_USE_DLFCN) (*res_handle)->errormsg = dlerror(); return APR_EDSOOPEN; #endif } (*res_handle)->handle = (void*)os_handle; (*res_handle)->pool = pool; (*res_handle)->errormsg = NULL; apr_pool_cleanup_register(pool, *res_handle, dso_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
/** * Load a dynamically linked library using a system dependent method. * * \param p_this vlc object * \param psz_file library file * \param p_handle the module handle returned * \return 0 on success as well as the module handle. */ int module_Load( vlc_object_t *p_this, const char *psz_file, module_handle_t *p_handle ) { module_handle_t handle; #if defined(HAVE_DL_DYLD) NSObjectFileImage image; NSObjectFileImageReturnCode ret; ret = NSCreateObjectFileImageFromFile( psz_file, &image ); if( ret != NSObjectFileImageSuccess ) { msg_Warn( p_this, "cannot create image from `%s'", psz_file ); return -1; } /* Open the dynamic module */ handle = NSLinkModule( image, psz_file, NSLINKMODULE_OPTION_RETURN_ON_ERROR ); if( !handle ) { NSLinkEditErrors errors; const char *psz_file, *psz_err; int i_errnum; NSLinkEditError( &errors, &i_errnum, &psz_file, &psz_err ); msg_Warn( p_this, "cannot link module `%s' (%s)", psz_file, psz_err ); NSDestroyObjectFileImage( image ); return -1; } /* Destroy our image, we won't need it */ NSDestroyObjectFileImage( image ); #elif defined(HAVE_DL_BEOS) handle = load_add_on( psz_file ); if( handle < 0 ) { msg_Warn( p_this, "cannot load module `%s'", psz_file ); return -1; } #elif defined(HAVE_DL_WINDOWS) wchar_t psz_wfile[MAX_PATH]; MultiByteToWideChar( CP_ACP, 0, psz_file, -1, psz_wfile, MAX_PATH ); #ifndef UNDER_CE /* FIXME: this is not thread-safe -- Courmisch */ UINT mode = SetErrorMode (SEM_FAILCRITICALERRORS); SetErrorMode (mode|SEM_FAILCRITICALERRORS); #endif handle = LoadLibraryW( psz_wfile ); #ifndef UNDER_CE SetErrorMode (mode); #endif if( handle == NULL ) { char *psz_err = GetWindowsError(); msg_Warn( p_this, "cannot load module `%s' (%s)", psz_file, psz_err ); free( psz_err ); return -1; } #elif defined(HAVE_DL_DLOPEN) # if defined (RTLD_NOW) const int flags = RTLD_NOW; # elif defined (DL_LAZY) const int flags = DL_LAZY; # else const int flags = 0; # endif handle = dlopen( psz_file, flags ); if( handle == NULL ) { msg_Warn( p_this, "cannot load module `%s' (%s)", psz_file, dlerror() ); return -1; } #elif defined(HAVE_DL_SHL_LOAD) handle = shl_load( psz_file, BIND_IMMEDIATE | BIND_NONFATAL, NULL ); if( handle == NULL ) { msg_Warn( p_this, "cannot load module `%s' (%m)", psz_file ); return -1; } #else # error "Something is wrong in modules.c" #endif *p_handle = handle; return 0; }
CF_PRIVATE Boolean _CFBundleDYLDLoadBundle(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) { CFErrorRef localError = NULL, *subError = (error ? &localError : NULL); NSLinkEditErrors c = NSLinkEditUndefinedError; int errorNumber = 0; const char *fileName = NULL; const char *errorString = NULL; if (!bundle->_isLoaded) { CFURLRef executableURL = CFBundleCopyExecutableURL(bundle); char buff[CFMaxPathSize]; if (executableURL && CFURLGetFileSystemRepresentation(executableURL, true, (uint8_t *)buff, CFMaxPathSize)) { NSObjectFileImage image; NSObjectFileImageReturnCode retCode = NSCreateObjectFileImageFromFile(buff, &image); #if LOG_BUNDLE_LOAD printf("dyld load bundle %p, create image of %s returns image %p retcode %d\n", bundle, buff, image, retCode); #endif /* LOG_BUNDLE_LOAD */ if (retCode == NSObjectFileImageSuccess) { uint32_t options = forceGlobal ? NSLINKMODULE_OPTION_RETURN_ON_ERROR : (NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSModule module = NSLinkModule(image, buff, options); #if LOG_BUNDLE_LOAD printf("dyld load bundle %p, link module of %s options 0x%x returns module %p image %p\n", bundle, buff, options, module, image); #endif /* LOG_BUNDLE_LOAD */ if (module) { bundle->_imageCookie = image; bundle->_moduleCookie = module; bundle->_isLoaded = true; } else { NSLinkEditError(&c, &errorNumber, &fileName, &errorString); if (error) { #if defined(BINARY_SUPPORT_DLFCN) _CFBundleDlfcnPreflight(bundle, subError); #endif /* BINARY_SUPPORT_DLFCN */ if (!localError) { CFStringRef tempString = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, errorString), debugString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("error code %d, error number %d (%@)"), c, errorNumber, tempString); localError = _CFBundleCreateErrorDebug(CFGetAllocator(bundle), bundle, CFBundleExecutableLinkError, debugString); if (tempString) CFRelease(tempString); if (debugString) CFRelease(debugString); } } else { CFStringRef tempString = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, errorString), executableString = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, fileName); CFLog(__kCFLogBundle, CFSTR("Error loading %@: error code %d, error number %d (%@)"), executableString, c, errorNumber, tempString); if (tempString) CFRelease(tempString); if (executableString) CFRelease(executableString); } (void)NSDestroyObjectFileImage(image); } } else { if (error) { if (retCode == NSObjectFileImageArch) { localError = _CFBundleCreateError(CFGetAllocator(bundle), bundle, CFBundleExecutableArchitectureMismatchError); } else if (retCode == NSObjectFileImageInappropriateFile) { Boolean hasRuntimeMismatch = false; uint32_t mainFlags = 0, bundleFlags = 0; if (_CFBundleGrokObjCImageInfoFromMainExecutable(NULL, &mainFlags) && (mainFlags & 0x2) != 0) { if (_CFBundleGetObjCImageInfo(bundle, NULL, &bundleFlags) && (bundleFlags & 0x2) == 0) hasRuntimeMismatch = true; } if (hasRuntimeMismatch) { localError = _CFBundleCreateError(CFGetAllocator(bundle), bundle, CFBundleExecutableRuntimeMismatchError); } else { localError = _CFBundleCreateError(CFGetAllocator(bundle), bundle, CFBundleExecutableNotLoadableError); } } else { #if defined(BINARY_SUPPORT_DLFCN) _CFBundleDlfcnPreflight(bundle, subError); #endif /* BINARY_SUPPORT_DLFCN */ if (!localError) { CFStringRef debugString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("dyld returns %d"), retCode); localError = _CFBundleCreateErrorDebug(CFGetAllocator(bundle), bundle, CFBundleExecutableLinkError, debugString); CFRelease(debugString); } } } else { CFLog(__kCFLogBundle, CFSTR("dyld returns %d when trying to load %@"), retCode, executableURL); } } } else { if (error) { localError = _CFBundleCreateError(CFGetAllocator(bundle), bundle, CFBundleExecutableNotFoundError); } else { CFLog(__kCFLogBundle, CFSTR("Cannot find executable for bundle %@"), bundle); } } if (executableURL) CFRelease(executableURL); } if (!bundle->_isLoaded && error) *error = localError; return bundle->_isLoaded; }
LIBHANDLE flx_load_library(const std::string& filename) { LIBHANDLE library; FLX_SET_NOLIBRARY(library); if (std::getenv("FLX_SHELL_ECHO")!=(char*)0) fprintf(stderr,"[load_library] %s\n", filename.c_str()); //#if FLX_WIN32 || FLX_CYGWIN #if FLX_WIN32 // stop windows showing err dialogues, ignoring error code. (void)SetErrorMode(SEM_NOOPENFILEERRORBOX); library = LoadLibrary(filename.c_str()); if(FLX_CHECK_NOLIBRARY(library)) throw flx_link_failure_t(filename,"LoadLibrary","Cannot find dll"); #else #if FLX_MACOSX_NODLCOMPAT NSObjectFileImage bndl_img; NSObjectFileImageReturnCode res; string s_filename(filename); struct stat st; if (stat(s_filename.c_str(), &st) != 0) { // we can't find the file, so search DYLD_LIBRARY_PATH string paths = getenv("DYLD_LIBRARY_PATH"); size_t i = 0; bool found = false; while ((i = paths.find_first_of(':')) != paths.npos) { string s = paths.substr(0, i) + '/' + filename; paths = paths.substr(i + 1); if (stat(s.c_str(), &st) == 0) { s_filename = s; found = true; break; } } if (!found) { throw flx_link_failure_t(filename, "stat", string("cannot find file: ") + filename); } } res = NSCreateObjectFileImageFromFile(s_filename.c_str(), &bndl_img); if(NSObjectFileImageSuccess != res) throw flx_link_failure_t(filename, "NSCreateObjectFileImageFromFile", "failure to open library"); // don't merge globals with loader's, load programmatically // return on error allows us to continue without being terminated unsigned long link_flags; link_flags = NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR; library = NSLinkModule(bndl_img, filename.c_str(), link_flags); // even if link failed, we do this NSDestroyObjectFileImage(bndl_img); // more info can be gleaned about link errors from NSLinkEditError if(FLX_CHECK_NOLIBRARY(library)) throw flx_link_failure_t(filename, "NSLinkModule", "failed to link"); #else library = dlopen(filename.c_str(),RTLD_NOW); if(FLX_CHECK_NOLIBRARY(library)) throw flx_link_failure_t(filename,"dlopen",dlerror()); #endif #endif return library; }
int main() { // NSCreateObjectFileImageFromMemory is only available on Mac OS X - not iPhone OS #if __MAC_OS_X_VERSION_MIN_REQUIRED NSObjectFileImage ofi; if ( NSCreateObjectFileImageFromFile("test.bundle", &ofi) != NSObjectFileImageSuccess ) { FAIL("NSCreateObjectFileImageFromFile failed"); return 0; } NSModule mod = NSLinkModule(ofi, "test.bundle", NSLINKMODULE_OPTION_NONE); if ( mod == NULL ) { FAIL("NSLinkModule failed"); return 0; } NSSymbol sym = NSLookupSymbolInModule(mod, "_setValue"); if ( sym == NULL ) { FAIL("NSLookupSymbolInModule failed"); return 0; } setter func = NSAddressOfSymbol(sym); (*func)(1); //fprintf(stderr, "address of foo() = %p in bundle first load %p\n", func, mod); NSModule mod2 = NSLinkModule(ofi, "test2.bundle", NSLINKMODULE_OPTION_NONE); if ( mod2 == NULL ) { NSLinkEditErrors c; int errorNumber; const char* fileName; const char* errorString; NSLinkEditError(&c, &errorNumber, &fileName, &errorString); FAIL("2nd NSLinkModule failed: %s", errorString); return 0; } if ( mod == mod2 ) { FAIL("2nd NSLinkModule return same function address as first"); return 0; } NSSymbol sym2getter = NSLookupSymbolInModule(mod2, "_getValue"); if ( sym2getter == NULL ) { FAIL("2nd NSLookupSymbolInModule failed"); return 0; } getter func2getter = NSAddressOfSymbol(sym2getter); if ( (*func2getter)() != 0 ) { FAIL("_getValue() on second link returned non-zero"); return 0; } NSSymbol sym2 = NSLookupSymbolInModule(mod2, "_setValue"); if ( sym2 == NULL ) { FAIL("2nd NSLookupSymbolInModule failed"); return 0; } setter func2 = NSAddressOfSymbol(sym2); (*func2)(2); //fprintf(stderr, "address of foo() = %p in bundle second load %p\n", func2, mod2); if ( func == func2 ) { FAIL("2nd NSAddressOfSymbol return same function address as 1st"); return 0; } NSModule mod3 = NSLinkModule(ofi, "test3.bundle", NSLINKMODULE_OPTION_NONE); if ( mod3 == NULL ) { FAIL("3rd NSLinkModule failed"); return 0; } if ( mod3 == mod ) { FAIL("3rd NSLinkModule return same function address as 1st"); return 0; } if ( mod3 == mod2 ) { FAIL("3rd NSLinkModule return same function address as 2nd"); return 0; } NSSymbol sym3 = NSLookupSymbolInModule(mod3, "_setValue"); if ( sym3 == NULL ) { FAIL("3rd NSLookupSymbolInModule failed"); return 0; } setter func3 = NSAddressOfSymbol(sym3); (*func3)(3); //fprintf(stderr, "address of foo() = %p in bundle third load %p\n", func3, mod3); if ( func3 == func ) { FAIL("3rd NSAddressOfSymbol return same function address as 1st"); return 0; } if ( func3 == func2 ) { FAIL("3rd NSAddressOfSymbol return same function address as 2nd"); return 0; } if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) { FAIL("NSUnLinkModule failed"); return 0; } if ( !NSUnLinkModule(mod3, NSUNLINKMODULE_OPTION_NONE) ) { FAIL("3rd NSUnLinkModule failed"); return 0; } if ( !NSUnLinkModule(mod2, NSUNLINKMODULE_OPTION_NONE) ) { FAIL("2nd NSUnLinkModule failed"); return 0; } // now link again after unlinking everything NSModule mod4 = NSLinkModule(ofi, "test4.bundle", NSLINKMODULE_OPTION_NONE); if ( mod4 == NULL ) { FAIL("4th NSLinkModule failed"); return 0; } // check that this is really a new copy by verifying the getValue() returns zero NSSymbol sym4getter = NSLookupSymbolInModule(mod4, "_getValue"); if ( sym4getter == NULL ) { FAIL("4th NSLookupSymbolInModule failed"); return 0; } getter func4getter = NSAddressOfSymbol(sym4getter); if ( (*func4getter)() != 0 ) { FAIL("_getValue() on fourth link returned non-zero"); return 0; } if ( !NSUnLinkModule(mod4, NSUNLINKMODULE_OPTION_NONE) ) { FAIL("4th NSUnLinkModule failed"); return 0; } if ( !NSDestroyObjectFileImage(ofi) ) { FAIL("NSDestroyObjectFileImage failed"); return 0; } #endif PASS("bundle-multi-link"); return 0; }
static void checkBundle(const char* path, bool unlinkBeforeDestroy) { int fd = open(path, O_RDONLY, 0); if ( fd == -1 ) { printf("[FAIL] open(%s) failed", path); exit(0); } struct stat stat_buf; if ( fstat(fd, &stat_buf) == -1) { printf("[FAIL] fstat() failed\n"); exit(0); } void* loadAddress = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); if ( loadAddress == ((void*)(-1)) ) { printf("[FAIL] mmap() failed\n"); exit(0); } close(fd); NSObjectFileImage ofi; if ( NSCreateObjectFileImageFromMemory(loadAddress, stat_buf.st_size, &ofi) != NSObjectFileImageSuccess ) { printf("[FAIL] NSCreateObjectFileImageFromMemory failed\n"); exit(0); } NSModule mod = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_NONE); if ( mod == NULL ) { printf("[FAIL] NSLinkModule failed\n"); exit(0); } if ( !unlinkBeforeDestroy ) { // API lets you destroy ofi and NSModule lives on if ( !NSDestroyObjectFileImage(ofi) ) { printf("[FAIL] NSDestroyObjectFileImage failed\n"); exit(0); } } NSSymbol sym = NSLookupSymbolInModule(mod, "_fooInBundle"); if ( sym == NULL ) { printf("[FAIL] NSLookupSymbolInModule failed\n"); exit(0); } void* func = NSAddressOfSymbol(sym); if ( func == NULL ) { printf("[FAIL] NSAddressOfSymbol failed\n"); exit(0); } Dl_info info; if ( dladdr(func, &info) == 0 ) { printf("[FAIL] dladdr(&p, xx) failed\n"); exit(0); } //printf("_fooInBundle found in %s\n", info.dli_fname); if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) { printf("[FAIL] NSUnLinkModule failed\n"); exit(0); } if ( dladdr(func, &info) != 0 ) { printf("[FAIL] dladdr(&p, xx) found but should not have\n"); exit(0); } if ( unlinkBeforeDestroy ) { if ( !NSDestroyObjectFileImage(ofi) ) { printf("[FAIL] NSDestroyObjectFileImage failed\n"); exit(0); } } }