void* NSGLGetProcAddress (const GLubyte *name) { static const struct mach_header* image = NULL; NSSymbol symbol; char* symbolName; if (NULL == image) { #ifdef GLEW_REGAL image = NSAddImage("libRegal.dylib", NSADDIMAGE_OPTION_RETURN_ON_ERROR); #else image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); #endif } /* prepend a '_' for the Unix C symbol mangling convention */ symbolName = malloc(strlen((const char*)name) + 2); strcpy(symbolName+1, (const char*)name); symbolName[0] = '_'; symbol = NULL; /* if (NSIsSymbolNameDefined(symbolName)) symbol = NSLookupAndBindSymbol(symbolName); */ symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL; free(symbolName); if( symbol ) return NSAddressOfSymbol(symbol); #ifdef GLEW_APPLE_GLX return dlGetProcAddress( name ); // try next for glx symbols #else return NULL; #endif }
IFXRESULT CIFXOpenGLOS::LoadOpenGL() { IFXRESULT rc = IFX_OK; if(m_bOpenGLLoaded) { return rc; } if(0 == s_phOpenGL) { ClearOpenGLFuncs(); s_phOpenGL = NSAddImage(OPENGL_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE); if (!s_phOpenGL) { IFXTRACE_GENERIC(L"%s:%i NSAddImage() error %s\n", OPENGL_LIBRARY_PATH); rc = IFX_E_UNSUPPORTED; } } if(0 == s_phAGL) { ClearOpenGLFuncs(); s_phAGL = NSAddImage(AGL_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE); if (!s_phAGL) { IFXTRACE_GENERIC(L"%s:%i NSAddImage() error %s\n", AGL_LIBRARY_PATH); rc = IFX_E_UNSUPPORTED; } } if(s_phOpenGL && s_phAGL && (0 == glEnable)) { GetOpenGLFuncs(); if(0 == glEnable) { UnloadOpenGL(); rc = IFX_E_UNSUPPORTED; } } if(IFXSUCCESS(rc)) { m_bOpenGLLoaded = TRUE; } return rc; }
const void *gwwv_NSAddImage(char *name,uint32_t options) { const void *lib = NSAddImage(name,options); char *temp; if (( lib!=NULL && lib!=(void *) -1) || name==NULL || *name=='/' ) return( lib ); temp = galloc( strlen("/sw/lib/") + strlen(name) +1 ); strcpy(temp,"/sw/lib/"); strcat(temp,name); lib = NSAddImage(temp,options); free(temp); return( lib ); }
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* CASharedLibrary::GetRoutineAddressIfLibraryLoaded(const char* inRoutineName, const char* /*inLibraryName*/, const char* inLibraryPath) { void* theRoutine = 0; #if CASharedLibrary_Use_DYLD const struct mach_header* theImage = NSAddImage(inLibraryPath, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED); if(theImage != 0) { NSSymbol theSymbol = NSLookupSymbolInImage(theImage, inRoutineName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND); if(theSymbol != 0) { theRoutine = NSAddressOfSymbol(theSymbol); } } #else void* theImage = dlopen(inLibraryPath, RTLD_LAZY | RTLD_NOLOAD); if(theImage != NULL) { // we assume that all routine names passed here have a leading underscore which gets shaved // off when passed to dlsym theRoutine = dlsym(theImage, &(inRoutineName[1])); } #endif return theRoutine; }
/* 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 ReadDependentCB(const char *aDependentLib, bool do_preload) { if (do_preload) preload(aDependentLib); (void) NSAddImage(aDependentLib, NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME); }
nsresult XPCOMGlueLoad(const char *xpcomFile, GetFrozenFunctionsFunc *func) { const mach_header* lib = nsnull; if (xpcomFile[0] != '.' || xpcomFile[1] != '\0') { char xpcomDir[PATH_MAX]; if (realpath(xpcomFile, xpcomDir)) { char *lastSlash = strrchr(xpcomDir, '/'); if (lastSlash) { *lastSlash = '\0'; XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB); snprintf(lastSlash, PATH_MAX - strlen(xpcomDir), "/" XUL_DLL); sXULLibImage = NSAddImage(xpcomDir, NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME); } } lib = NSAddImage(xpcomFile, NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME); if (!lib) { NSLinkEditErrors linkEditError; int errorNum; const char *errorString; const char *fileName; NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); fprintf(stderr, "XPCOMGlueLoad error %d:%d for file %s:\n%s\n", linkEditError, errorNum, fileName, errorString); } } *func = (GetFrozenFunctionsFunc) LookupSymbol(lib, "_NS_GetFrozenFunctions"); return *func ? NS_OK : NS_ERROR_NOT_AVAILABLE; }
int main() { // NSAddImage is only available on Mac OS X - not iPhone OS #if __MAC_OS_X_VERSION_MIN_REQUIRED // test that NSAddImage() does not crash if image is not loaded const struct mach_header * mh = NSAddImage("/System/Library/Frameworks/Cocoa.framework/Cocoa", NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED); if ( mh != NULL ) FAIL("NSAddImage-RETURN_ONLY_IF_LOADED"); else #endif PASS("NSAddImage-RETURN_ONLY_IF_LOADED"); return EXIT_SUCCESS; }
CF_PRIVATE Boolean _CFBundleDYLDLoadFramework(CFBundleRef bundle, CFErrorRef *error) { // !!! Framework loading should be better. Can't unload frameworks. 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)) { void *image = (void *)NSAddImage(buff, NSADDIMAGE_OPTION_RETURN_ON_ERROR); #if LOG_BUNDLE_LOAD printf("dyld load framework %p, add image of %s returns image %p\n", bundle, buff, image); #endif /* LOG_BUNDLE_LOAD */ if (image) { bundle->_imageCookie = image; 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); } } } 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; }
void *ILDynLibraryOpen(const char *name) { NSObjectFileImage file; NSObjectFileImageReturnCode result; NSModule module; void *image; const char *msg; /* Attempt to open the dylib file */ result = NSCreateObjectFileImageFromFile(name, &file); if(result == NSObjectFileImageInappropriateFile) { /* May be an image, and not a bundle */ image = (void *)NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if(image) { return image; } } if(result != NSObjectFileImageSuccess) { switch(result) { case NSObjectFileImageFailure: msg = " (NSObjectFileImageFailure)"; break; case NSObjectFileImageInappropriateFile: msg = " (NSObjectFileImageInappropriateFile)"; break; case NSObjectFileImageArch: msg = " (NSObjectFileImageArch)"; break; case NSObjectFileImageFormat: msg = " (NSObjectFileImageFormat)"; break; case NSObjectFileImageAccess: msg = " (NSObjectFileImageAccess)"; break; default: msg = ""; break; } #ifdef IL_DYNLIB_DEBUG fprintf(stderr, "%s: could not load dynamic library%s\n", name, msg); #endif return 0; } /* Link the module dependencies */ module = NSLinkModule(file, name, NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); return (void *)module; }
int main(int argc, const char* argv[]) { #if __MAC_OS_X_VERSION_MIN_REQUIRED const struct mach_header *image; image = NSAddImage("AppKit.framework/AppKit", NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING); if ( image == NULL ) FAIL("Could not load AppKit"); else #endif PASS("AppKit loaded"); return 0; }
void* CASharedLibrary::GetRoutineAddressIfLibraryLoaded(const char* inRoutineName, const char* /*inLibraryName*/, const char* inLibraryPath) { void* theRoutine = 0; const struct mach_header* theImage = NSAddImage(inLibraryPath, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED); if(theImage != 0) { NSSymbol theSymbol = NSLookupSymbolInImage(theImage, inRoutineName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND); if(theSymbol != 0) { theRoutine = NSAddressOfSymbol(theSymbol); } } return theRoutine; }
void* NSGLGetProcAddress (const GLubyte *name) { static const struct mach_header* image = NULL; NSSymbol symbol; char* symbolName; if (NULL == image) { image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); } /* prepend a '_' for the Unix C symbol mangling convention */ symbolName = malloc(strlen((const char*)name) + 2); strcpy(symbolName+1, (const char*)name); symbolName[0] = '_'; symbol = NULL; /* if (NSIsSymbolNameDefined(symbolName)) symbol = NSLookupAndBindSymbol(symbolName); */ symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL; free(symbolName); return symbol ? NSAddressOfSymbol(symbol) : NULL; }
/* 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; }
const struct mach_header *loadFramework(const char *execPath) { return NSAddImage(execPath, NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME); }
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; }
cc_libhandle cc_dl_open(const char * filename) { cc_libhandle h = new struct cc_libhandle_struct; h->nativehnd = NULL; h->libname = NULL_STR; #ifdef HAVE_DL_LIB #ifdef HAVE_DYLD_RUNTIME_BINDING /* Mac OS X: Search for library shipped with bundled Inventor framework or directly in application bundle. */ if (h->nativehnd == NULL) { cc_string * path = cc_find_file(filename); if (cc_string_length(path) > 0) { if (cc_dl_debugging()) { cc_debugerror_postinfo("cc_dl_open", "opening: %s", cc_string_get_text(path)); } h->nativehnd = dlopen(cc_string_get_text(path), RTLD_LAZY); } cc_string_destruct(path); } #endif /* HAVE_DYLD_RUNTIME_BINDING */ if (h->nativehnd == NULL) { /* try loading path-less */ h->nativehnd = dlopen(filename, RTLD_LAZY); } /* If dlopen() fails for any reason than not being able to find the dynamic link-library given by "filename" on disk, we should really detect it and report an error, whether we're running in debug mode or release mode. The libdl interface doesn't provide any means to do that, though, so we'll just /assume/ that a NULL return means the library couldn't be found. But if a special debugging environment variable is found, we'll spit out the error message, which could prove useful for remote debugging: */ if (cc_dl_debugging() && (h->nativehnd == NULL)) { const char * e = dlerror(); if (e) { cc_debugerror_post("cc_dl_open", "dlopen(\"%s\") failed with: '%s'", filename, e); } } #elif defined (HAVE_DYLD_RUNTIME_BINDING) if (filename == NULL) { /* Simulate the behaviour of dlopen(NULL) by returning a handle to the first image loaded by the dynamic linker, which is the current process. See dyld(3). Note that this handle is not necessary for the dyld cc_dl_sym() implementation, but it makes it possible to use cc_dl_open() in the "classic" dlopen() style (where a NULL return value would indicate failure). */ h->nativehnd = _dyld_get_image_header(0); } else { /* Note that we must use NSAddImage, since we want to load a shared library, instead of NSCreateObjectFileImageFromFile() and NSLinkModule(), which work only with loadable modules/bundles. See NSModule(3), NSObjectFileImage(3) and http://fink.sourceforge.net/doc/porting/shared.php for details. */ cc_string * path = cc_find_file(filename); if (cc_string_length(path) > 0) { if (cc_dl_debugging()) { cc_debugerror_postinfo("cc_dlopen", "opening: %s", cc_string_get_text(path)); } h->nativehnd = (void *) NSAddImage(cc_string_get_text(path), NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (cc_dl_debugging() && !h->nativehnd) { NSLinkEditErrors c; int e; const char * file; const char * errstr; NSLinkEditError(&c, &e, &file, &errstr); cc_debugerror_post("cc_dlopen", "%s", errstr); } cc_string_destruct(path); } } #elif defined (HAVE_WINDLL_RUNTIME_BINDING) /* We don't want to call LoadLibrary(NULL) because this causes a crash on some Windows platforms (Crashes on Windows2000 has been reported). 20021101 thammer. */ if (filename != NULL) { /* Don't use GetModuleHandle(): LoadLibrary() will *not* load a new image if the module is already loaded, it will only inc the reference count. Also, GetModuleHandle() doesn't inc the reference count, so it is dangerous in the sense that the module could be free'd from somewhere else between us opening it, and until it is used for resolving symbols. */ h->nativehnd = LoadLibrary(filename); if (cc_dl_debugging() && (h->nativehnd == NULL)) { cc_string funcstr; cc_string_construct(&funcstr); cc_string_sprintf(&funcstr, "LoadLibrary(\"%s\")", filename ? filename : "(null)"); cc_win32_print_error("cc_dl_open", cc_string_get_text(&funcstr), GetLastError()); cc_string_clean(&funcstr); } } else { h->nativehnd = GetModuleHandle(NULL); if (cc_dl_debugging() && (h->nativehnd == NULL)) { cc_win32_print_error("cc_dl_open", "GetModuleHandle(NULL)", GetLastError()); } } #elif defined (HAVE_DLD_LIB) /* FIXME: there is a good reason to try to use shn_load() *first*, then dlopen() on HP-UX: according to a discussion on the libtool mailinglist, dlopen() for HP-UX was buggy in an official release, needing a patch to function properly. This would take some changes to the configure checks (we cut off further checking if libdl is found), and any code that depends on _either_ HAVE_DL_LIB _or_ HAVE_DLD_LIB being defined, but not both at the same time. 20010626 mortene. */ /* This define not available on older versions. */ #ifndef DYNAMIC_PATH #define DYNAMIC_PATH 0 #endif /* DYNAMIC_PATH */ /* Handle attempt to look at running executable image and already loaded dynamic libraries. */ if (filename == NULL) { shl_t exehnd = (shl_t)0; void * dummy; int ret = shl_findsym(&exehnd, "main", TYPE_UNDEFINED, &dummy); if (ret != -1) { h->nativehnd = exehnd; } else { const char * e = strerror(errno); cc_debugerror_post("cc_dl_open", "shl_findsym(&NULL, \"main\", ...) failed with: '%s'", e); } } else { h->nativehnd = shl_load(filename, BIND_IMMEDIATE|BIND_NONFATAL|DYNAMIC_PATH, 0L); /* If a special debugging environment variable is found, we'll spit out the error message, which could prove useful for remote debugging. Note that if shl_load() fails for any reason than not being able to find the dynamic link-library given by "filename" on disk, we detect it and report an error, whether we're running in debug mode or release mode. ENOENT means "the specified library does not exist" -- all other errors should be warned about no matter what. */ if ((h->nativehnd == NULL) && (cc_dl_debugging() || (errno != ENOENT))) { const char * e = strerror(errno); cc_debugerror_post("cc_dl_open", "shl_load(\"%s\") failed with: '%s'", filename ? filename : "(null)", e); } } #endif if (h->nativehnd == NULL) { delete h; h = NULL; } else { h->libname = filename ? filename : NULL_STR; if (cc_dl_debugging()) { #ifdef HAVE_WINDLL_RUNTIME_BINDING char libpath[512]; DWORD retval = GetModuleFileName((HINSTANCE) h->nativehnd, libpath, sizeof(libpath)); assert(retval > 0 && "GetModuleFileName() failed"); libpath[sizeof(libpath) - 1] = 0; cc_debugerror_postinfo("cc_dl_open", "Opened library '%s'", libpath); #elif defined (HAVE_DL_LIB) || defined (HAVE_DLD_LIB) cc_debugerror_postinfo("cc_dl_open", "Opening library '%s'", h->libname.getString()); #endif } } if (cc_dl_debugging() && h) { cc_debugerror_postinfo("cc_dl_open", "\"%s\" success => cc_libhandle==%p, nativehnd==%p", h->libname.getString(), h, h->nativehnd); } return h; }
GdkGLProc _gdk_x11_gl_get_proc_address (const char *proc_name) { #ifdef __APPLE__ #define _GDK_GL_LIBGL_PATH "/usr/X11R6/lib/libGL.1.dylib" #define _GDK_GL_LIBGLU_PATH "/usr/X11R6/lib/libGLU.1.dylib" typedef GdkGLProc (*__glXGetProcAddressProc) (const GLubyte *); static __glXGetProcAddressProc glx_get_proc_address = (__glXGetProcAddressProc) -1; const char *image_name; static const struct mach_header *libgl_image = NULL; static const struct mach_header *libglu_image = NULL; NSSymbol symbol; char *symbol_name; GdkGLProc proc_address; GDK_GL_NOTE_FUNC (); if (strncmp ("glu", proc_name, 3) != 0) { /* libGL */ if (libgl_image == NULL) { image_name = g_getenv ("GDK_GL_LIBGL_PATH"); if (image_name == NULL) image_name = _GDK_GL_LIBGL_PATH; GDK_GL_NOTE (MISC, g_message (" - Add Mach-O image %s", image_name)); libgl_image = NSAddImage (image_name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (libgl_image == NULL) { g_warning ("Cannot add Mach-O image %s", image_name); return NULL; } } if (glx_get_proc_address == (__glXGetProcAddressProc) -1) { /* * Look up glXGetProcAddress () function. */ symbol = NSLookupSymbolInImage (libgl_image, "_glXGetProcAddress", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); if (symbol == NULL) { symbol = NSLookupSymbolInImage (libgl_image, "_glXGetProcAddressARB", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); if (symbol == NULL) { symbol = NSLookupSymbolInImage (libgl_image, "_glXGetProcAddressEXT", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); } } GDK_GL_NOTE (MISC, g_message (" - glXGetProcAddress () - %s", symbol ? "supported" : "not supported")); if (symbol != NULL) glx_get_proc_address = NSAddressOfSymbol (symbol); else glx_get_proc_address = NULL; } /* Try glXGetProcAddress () */ if (glx_get_proc_address != NULL) { proc_address = glx_get_proc_address ((unsigned char *) proc_name); GDK_GL_NOTE (IMPL, g_message (" ** glXGetProcAddress () - %s", proc_address ? "succeeded" : "failed")); if (proc_address != NULL) return proc_address; } /* Try Mach-O dyld */ symbol_name = g_strconcat ("_", proc_name, NULL); symbol = NSLookupSymbolInImage (libgl_image, symbol_name, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); GDK_GL_NOTE (MISC, g_message (" - NSLookupSymbolInImage () - %s", symbol ? "succeeded" : "failed")); g_free (symbol_name); if (symbol != NULL) return NSAddressOfSymbol (symbol); } else { /* libGLU */ if (libglu_image == NULL) { image_name = g_getenv ("GDK_GL_LIBGLU_PATH"); if (image_name == NULL) image_name = _GDK_GL_LIBGLU_PATH; GDK_GL_NOTE (MISC, g_message (" - Add Mach-O image %s", image_name)); libglu_image = NSAddImage (image_name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (libglu_image == NULL) { g_warning ("Cannot add Mach-O image %s", image_name); return NULL; } } symbol_name = g_strconcat ("_", proc_name, NULL); symbol = NSLookupSymbolInImage (libglu_image, symbol_name, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); GDK_GL_NOTE (MISC, g_message (" - NSLookupSymbolInImage () - %s", symbol ? "succeeded" : "failed")); g_free (symbol_name); if (symbol != NULL) return NSAddressOfSymbol (symbol); } return NULL; #else /* __APPLE__ */ typedef GdkGLProc (*__glXGetProcAddressProc) (const GLubyte *); static __glXGetProcAddressProc glx_get_proc_address = (__glXGetProcAddressProc) -1; gchar *file_name; GModule *module; GdkGLProc proc_address = NULL; GDK_GL_NOTE_FUNC (); if (strncmp ("glu", proc_name, 3) != 0) { if (glx_get_proc_address == (__glXGetProcAddressProc) -1) { /* * Look up glXGetProcAddress () function. */ file_name = g_module_build_path (NULL, "GL"); GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); module = g_module_open (file_name, G_MODULE_BIND_LAZY); g_free (file_name); if (module != NULL) { g_module_symbol (module, "glXGetProcAddress", (gpointer) &glx_get_proc_address); if (glx_get_proc_address == NULL) { g_module_symbol (module, "glXGetProcAddressARB", (gpointer) &glx_get_proc_address); if (glx_get_proc_address == NULL) { g_module_symbol (module, "glXGetProcAddressEXT", (gpointer) &glx_get_proc_address); } } GDK_GL_NOTE (MISC, g_message (" - glXGetProcAddress () - %s", glx_get_proc_address ? "supported" : "not supported")); g_module_close (module); } else { g_warning ("Cannot open %s", file_name); glx_get_proc_address = NULL; return NULL; } } /* Try glXGetProcAddress () */ if (glx_get_proc_address != NULL) { proc_address = glx_get_proc_address ((unsigned char *) proc_name); GDK_GL_NOTE (IMPL, g_message (" ** glXGetProcAddress () - %s", proc_address ? "succeeded" : "failed")); if (proc_address != NULL) return proc_address; } /* Try g_module_symbol () */ /* libGL */ file_name = g_module_build_path (NULL, "GL"); GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); module = g_module_open (file_name, G_MODULE_BIND_LAZY); g_free (file_name); if (module != NULL) { g_module_symbol (module, proc_name, (gpointer) &proc_address); GDK_GL_NOTE (MISC, g_message (" - g_module_symbol () - %s", proc_address ? "succeeded" : "failed")); g_module_close (module); } else { g_warning ("Cannot open %s", file_name); } if (proc_address == NULL) { /* libGLcore */ file_name = g_module_build_path (NULL, "GLcore"); GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); module = g_module_open (file_name, G_MODULE_BIND_LAZY); g_free (file_name); if (module != NULL) { g_module_symbol (module, proc_name, (gpointer) &proc_address); GDK_GL_NOTE (MISC, g_message (" - g_module_symbol () - %s", proc_address ? "succeeded" : "failed")); g_module_close (module); } } } else { /* libGLU */ file_name = g_module_build_path (NULL, "GLU"); GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); module = g_module_open (file_name, G_MODULE_BIND_LAZY); g_free (file_name); if (module != NULL) { g_module_symbol (module, proc_name, (gpointer) &proc_address); GDK_GL_NOTE (MISC, g_message (" - g_module_symbol () - %s", proc_address ? "succeeded" : "failed")); g_module_close (module); } else { g_warning ("Cannot open %s", file_name); } } return proc_address; #endif /* __APPLE__ */ }
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; }
const void* dlopen(const char* filename, int flags) { static char has_callback = 0; if (!has_callback) { _dyld_register_func_for_add_image(dlshim_image_callback); } if (!filename) { return &dl_self; } else { const struct mach_header* img = NULL; if (!img) img = NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (!img) img = NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING); if (!img) { NSObjectFileImage fileImage; callback_count = 0; last_header = NULL; if (NSCreateObjectFileImageFromFile(filename, &fileImage) == NSObjectFileImageSuccess) { NSLinkModule(fileImage, filename, NSLINKMODULE_OPTION_BINDNOW | ((flags & RTLD_GLOBAL)?NSLINKMODULE_OPTION_PRIVATE:0) | NSLINKMODULE_OPTION_RETURN_ON_ERROR); if (callback_count && last_header) img = last_header; } } if (!img) { NSObjectFileImage fileImage; int i, maxi; const char* prefixfilename; maxi = lib_path_count(); for (i = 0; i < maxi && !img; i++) { prefixfilename = lib_path_prefixify(i, filename); callback_count = 0; last_header = NULL; if (NSCreateObjectFileImageFromFile(prefixfilename, &fileImage) == NSObjectFileImageSuccess) { NSLinkModule(fileImage, filename, NSLINKMODULE_OPTION_BINDNOW | ((flags & RTLD_GLOBAL)?NSLINKMODULE_OPTION_PRIVATE:0) | NSLINKMODULE_OPTION_RETURN_ON_ERROR); if (callback_count && last_header) img = last_header; } } } if (img) { if (flags & RTLD_NOW) { NSLookupSymbolInImage(img, "", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); } if (NSIsSymbolNameDefinedInImage(img, "__init")) { NSSymbol initsymbol; void (*initfunc) (void); initsymbol = NSLookupSymbolInImage(img, "__init", 0); initfunc = NSAddressOfSymbol(initsymbol); initfunc(); } } else last_error = DLOPEN_ERROR; return img; } }
priv::SO_LOADER::SO_LOADER() { p1 = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); }
GdkGLProc gdk_gl_get_proc_address (const char *proc_name) { typedef GdkGLProc (*__glXGetProcAddressProc) (const GLubyte *); static __glXGetProcAddressProc glx_get_proc_address = (__glXGetProcAddressProc) -1; const char *image_name; static const struct mach_header *libgl_image = NULL; static const struct mach_header *libglu_image = NULL; NSSymbol symbol; char *symbol_name; GdkGLProc proc_address; GDK_GL_NOTE_FUNC (); if (strncmp ("glu", proc_name, 3) != 0) { /* libGL */ if (libgl_image == NULL) { image_name = g_getenv ("GDK_GL_LIBGL_PATH"); if (image_name == NULL) image_name = _GDK_GL_LIBGL_PATH; GDK_GL_NOTE (MISC, g_message (" - Add Mach-O image %s", image_name)); libgl_image = NSAddImage (image_name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (libgl_image == NULL) { g_warning ("Cannot add Mach-O image %s", image_name); return NULL; } } if (glx_get_proc_address == (__glXGetProcAddressProc) -1) { /* * Look up glXGetProcAddress () function. */ symbol = NSLookupSymbolInImage (libgl_image, "_glXGetProcAddress", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); if (symbol == NULL) { symbol = NSLookupSymbolInImage (libgl_image, "_glXGetProcAddressARB", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); if (symbol == NULL) { symbol = NSLookupSymbolInImage (libgl_image, "_glXGetProcAddressEXT", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); } } GDK_GL_NOTE (MISC, g_message (" - glXGetProcAddress () - %s", symbol ? "supported" : "not supported")); if (symbol != NULL) glx_get_proc_address = NSAddressOfSymbol (symbol); else glx_get_proc_address = NULL; } /* Try glXGetProcAddress () */ if (glx_get_proc_address != NULL) { proc_address = glx_get_proc_address (proc_name); GDK_GL_NOTE (IMPL, g_message (" ** glXGetProcAddress () - %s", proc_address ? "succeeded" : "failed")); if (proc_address != NULL) return proc_address; } /* Try Mach-O dyld */ symbol_name = g_strconcat ("_", proc_name, NULL); symbol = NSLookupSymbolInImage (libgl_image, symbol_name, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); GDK_GL_NOTE (MISC, g_message (" - NSLookupSymbolInImage () - %s", symbol ? "succeeded" : "failed")); g_free (symbol_name); if (symbol != NULL) return NSAddressOfSymbol (symbol); } else { /* libGLU */ if (libglu_image == NULL) { image_name = g_getenv ("GDK_GL_LIBGLU_PATH"); if (image_name == NULL) image_name = _GDK_GL_LIBGLU_PATH; GDK_GL_NOTE (MISC, g_message (" - Add Mach-O image %s", image_name)); libglu_image = NSAddImage (image_name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (libglu_image == NULL) { g_warning ("Cannot add Mach-O image %s", image_name); return NULL; } } symbol_name = g_strconcat ("_", proc_name, NULL); symbol = NSLookupSymbolInImage (libglu_image, symbol_name, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); GDK_GL_NOTE (MISC, g_message (" - NSLookupSymbolInImage () - %s", symbol ? "succeeded" : "failed")); g_free (symbol_name); if (symbol != NULL) return NSAddressOfSymbol (symbol); } return NULL; }