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
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync#ifdef WINDOWS
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync#include <Shlwapi.h>
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync#endif
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync
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 * 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;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync#if defined(WINDOWS)
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync WCHAR szwPath[MAX_PATH];
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync UINT cwcPath = 0;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync (void) resolveGlobal;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync# ifndef CR_NO_GL_SYSTEM_PATH
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync if (PathIsRelative(dllname))
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync {
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync size_t cName = strlen(dllname) + 1;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync# ifdef IN_GUEST
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync cwcPath = GetSystemDirectoryW(szwPath, RT_ELEMENTS(szwPath));
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync if (!cwcPath || cwcPath >= MAX_PATH)
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync {
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync DWORD winEr = GetLastError();
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync crError("GetSystemDirectoryW failed err %d", winEr);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync SetLastError(winEr);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync return NULL;
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync }
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync# else
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync WCHAR * pszwSlashFile;
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync cwcPath = GetModuleFileNameW(NULL, szwPath, RT_ELEMENTS(szwPath));
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync if (!cwcPath || cwcPath >= MAX_PATH)
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync {
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync DWORD winEr = GetLastError();
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync crError("GetModuleFileNameW failed err %d", winEr);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync SetLastError(winEr);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync return NULL;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync }
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync pszwSlashFile = wcsrchr(szwPath, L'\\');
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync if (!pszwSlashFile)
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync {
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync crError("failed to match file name");
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync SetLastError(ERROR_PATH_NOT_FOUND);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync return NULL;
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync }
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync cwcPath = pszwSlashFile - szwPath;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync# endif
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync if (cwcPath + 1 + cName > MAX_PATH)
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync {
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync crError("invalid path specified");
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync SetLastError(ERROR_FILENAME_EXCED_RANGE);
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync return NULL;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync }
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync szwPath[cwcPath] = '\\';
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync ++cwcPath;
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync }
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, dllname, -1, &szwPath[cwcPath], MAX_PATH - cwcPath))
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync {
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync DWORD winEr = GetLastError();
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync crError("MultiByteToWideChar failed err %d", winEr);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync SetLastError(winEr);
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync return NULL;
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync }
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync# endif // CR_NO_GL_SYSTEM_PATH
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll = (CRDLL *) crAlloc( sizeof( CRDLL ) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dll->name = crStrdup( dllname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if defined(WINDOWS)
1d75f53dd4d0c5160736ac1d2fe4329e27a5dc84vboxsync dll->hinstLib = LoadLibraryW( szwPath );
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync if (!dll->hinstLib)
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync {
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync crError("failed to load dll %s", dllname);
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync }
10ca321f3be6e9e0ad484f4684cab6532bea20e2vboxsync 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 {
adb5e7872c1b297262ff6794f8a6ed3e4f026b16vboxsync crDebug( "DLL_ERROR(%s): %s", dllname, 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
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * because we are already freeing all resources 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}