dll.c revision 4a65f82711f244289aed99b7bb0cc7e01b0ebcec
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Copyright (c) 2001, Stanford University
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * All rights reserved
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * See the file LICENSE.txt for information on redistributing this software.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_mem.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_error.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_dll.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_string.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "stdio.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
77d148a232adce564790a3b451f1895ff9c99634vboxsync#ifndef IN_GUEST
77d148a232adce564790a3b451f1895ff9c99634vboxsync#include <string.h>
77d148a232adce564790a3b451f1895ff9c99634vboxsync#endif
77d148a232adce564790a3b451f1895ff9c99634vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(DARWIN) || defined(SunOS) || defined(OSF1)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <dlfcn.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef DARWIN
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <Carbon/Carbon.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <mach-o/dyld.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncchar *__frameworkErr=NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncCFBundleRef LoadFramework( const char *frameworkName ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CFBundleRef bundle;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CFURLRef bundleURL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char fullfile[8096];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( frameworkName[0] != '/' ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* load a system framework */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* XXX \todo should this folder be retrieved from somewhere else? */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcpy( fullfile, "/System/Library/Frameworks/" );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcat( fullfile, frameworkName );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync } else {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* load any framework */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcpy( fullfile, frameworkName );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bundleURL = CFURLCreateWithString( NULL, CFStringCreateWithCStringNoCopy(NULL, fullfile, CFStringGetSystemEncoding(), NULL), NULL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( !bundleURL ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __frameworkErr = "Could not create OpenGL Framework bundle URL";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CFRelease( bundleURL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( !bundle ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __frameworkErr = "Could not create OpenGL Framework bundle";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( !CFBundleLoadExecutable(bundle) ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __frameworkErr = "Could not load MachO executable";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return bundle;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncchar *__bundleErr=NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid *LoadBundle( const char *filename ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSObjectFileImage fileImage;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSModule handle = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char _filename[PATH_MAX];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __bundleErr = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( filename[0] != '/' ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* default to a chromium bundle */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcpy( _filename, "/cr/lib/Darwin/" );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcat( _filename, filename );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync } else {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcpy( _filename, filename );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch( NSCreateObjectFileImageFromFile(_filename, &fileImage) ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case NSObjectFileImageFailure:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __bundleErr = "NSObjectFileImageFailure: Failure.";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case NSObjectFileImageInappropriateFile:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __bundleErr = "NSObjectFileImageInappropriateFile: The specified file is not of a valid type.";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case NSObjectFileImageArch:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __bundleErr = "NSObjectFileImageArch: The specified file is for a different CPU architecture.";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case NSObjectFileImageFormat:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __bundleErr = "NSObjectFileImageFormat: The specified file does not appear to be a Mach-O file";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case NSObjectFileImageAccess:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync __bundleErr = "NSObjectFileImageAccess: Permission to create image denied.";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case NSObjectFileImageSuccess:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync handle = NSLinkModule( fileImage, _filename,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSLINKMODULE_OPTION_RETURN_ON_ERROR |
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSLINKMODULE_OPTION_PRIVATE );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSDestroyObjectFileImage( fileImage );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( !handle ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSLinkEditErrors c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int n;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const char *name;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSLinkEditError(&c, &n, &name, (const char**)&__bundleErr);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return handle;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncint check_extension( const char *name, const char *extension ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int nam_len = crStrlen( name );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int ext_len = crStrlen( extension );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pos = crStrstr( name, extension );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return ( pos == &(name[nam_len-ext_len]) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncenum {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CR_DLL_NONE,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CR_DLL_FRAMEWORK,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CR_DLL_DYLIB,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CR_DLL_BUNDLE,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CR_DLL_UNKNOWN
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define NS_ADD 0
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncint get_dll_type( const char *name ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( check_extension(name, ".framework") )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return CR_DLL_FRAMEWORK;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( check_extension(name, ".bundle") )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return CR_DLL_BUNDLE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( check_extension(name, ".dylib") )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return CR_DLL_DYLIB;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return CR_DLL_DYLIB;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Open the named shared library.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * If resolveGlobal is non-zero, unresolved symbols can be satisfied by
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * any matching symbol already defined globally. Otherwise, if resolveGlobal
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * is zero, unresolved symbols should be resolved using symbols in that
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * object (in preference to global symbols).
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * NOTE: this came about because we found that for libGL, we need the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * global-resolve option but for SPU's we need the non-global option (consider
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * the state tracker duplicated in the array, tilesort, etc. SPUs).
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncCRDLL *crDLLOpen( const char *dllname, int resolveGlobal )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRDLL *dll;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *dll_err;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll = (CRDLL *) crAlloc( sizeof( CRDLL ) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->name = crStrdup( dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if defined(WINDOWS)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (void) resolveGlobal;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = LoadLibrary( dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#elif defined(DARWIN)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* XXX \todo Get better error handling in here */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->type = get_dll_type( dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch( dll->type ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CR_DLL_FRAMEWORK:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = LoadFramework( dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = __frameworkErr;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CR_DLL_BUNDLE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = LoadBundle( dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = __bundleErr;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CR_DLL_DYLIB:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if NS_ADD
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = (void*)NSAddImage( dllname, NSADDIMAGE_OPTION_RETURN_ON_ERROR );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( resolveGlobal )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_LOCAL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = (char*) dlerror();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = "Unknown DLL type";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync };
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (resolveGlobal)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = dlopen( dllname, RTLD_LAZY );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll_err = (char*) dlerror();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#error DSO
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!dll->hinstLib)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (dll_err)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crDebug( "DLL_ERROR: %s", dll_err );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "DLL Loader couldn't find/open %s", dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return dll;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncCRDLLFunc crDLLGetNoError( CRDLL *dll, const char *symname )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if defined(WINDOWS)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (CRDLLFunc) GetProcAddress( dll->hinstLib, symname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#elif defined(DARWIN)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSSymbol nssym;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( dll->type == CR_DLL_FRAMEWORK )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (CRDLLFunc) CFBundleGetFunctionPointerForName( (CFBundleRef) dll->hinstLib, CFStringCreateWithCStringNoCopy(NULL, symname, CFStringGetSystemEncoding(), NULL) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( dll->type == CR_DLL_DYLIB )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if NS_ADD
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync nssym = NSLookupSymbolInImage( dll->hinstLib, symname, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (CRDLLFunc) dlsym( dll->hinstLib, symname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync nssym = NSLookupSymbolInModule( dll->hinstLib, symname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( !nssym ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char name[PATH_MAX];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcpy( name, "_" );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStrcat( name, symname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if( dll->type == CR_DLL_DYLIB )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync nssym = NSLookupSymbolInImage( dll->hinstLib, name, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync nssym = NSLookupSymbolInModule( dll->hinstLib, name );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (CRDLLFunc) NSAddressOfSymbol( nssym );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (CRDLLFunc) dlsym( dll->hinstLib, symname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#error CR DLL ARCHITETECTURE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncCRDLLFunc crDLLGet( CRDLL *dll, const char *symname )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRDLLFunc data = crDLLGetNoError( dll, symname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!data)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Are you sure there isn't some C++ mangling messing you up? */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crWarning( "Couldn't get symbol \"%s\" in \"%s\"", symname, dll->name );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crDLLClose( CRDLL *dll )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int dll_err = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!dll) return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if defined(WINDOWS)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeLibrary( dll->hinstLib );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#elif defined(DARWIN)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch( dll->type ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CR_DLL_FRAMEWORK:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CFBundleUnloadExecutable( dll->hinstLib );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CFRelease(dll->hinstLib);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->hinstLib = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CR_DLL_DYLIB:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if !NS_ADD
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dlclose( dll->hinstLib );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CR_DLL_BUNDLE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync NSUnLinkModule( (NSModule) dll->hinstLib, 0L );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
4a65f82711f244289aed99b7bb0cc7e01b0ebcecvboxsync /*
4a65f82711f244289aed99b7bb0cc7e01b0ebcecvboxsync * Unloading Nvidia's libGL will crash VirtualBox later during shutdown.
4a65f82711f244289aed99b7bb0cc7e01b0ebcecvboxsync * Therefore we will skip unloading it. It will be unloaded later anway
4a65f82711f244289aed99b7bb0cc7e01b0ebcecvboxsync * because we are already freeing all ressources and VirtualBox will terminate
4a65f82711f244289aed99b7bb0cc7e01b0ebcecvboxsync * soon.
4a65f82711f244289aed99b7bb0cc7e01b0ebcecvboxsync */
77d148a232adce564790a3b451f1895ff9c99634vboxsync#ifndef IN_GUEST
77d148a232adce564790a3b451f1895ff9c99634vboxsync if (strncmp(dll->name, "libGL", 5))
77d148a232adce564790a3b451f1895ff9c99634vboxsync#endif
77d148a232adce564790a3b451f1895ff9c99634vboxsync dll_err = dlclose( dll->hinstLib );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#error DSO
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (dll_err)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crWarning("Error closing DLL %s\n",dll->name);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( dll->name );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( dll );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}