VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/dll.c@ 30045

Last change on this file since 30045 was 26353, checked in by vboxsync, 15 years ago

GuestHost/crOpenGL: little extra logging info.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.1 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_mem.h"
8#include "cr_error.h"
9#include "cr_dll.h"
10#include "cr_string.h"
11#include "stdio.h"
12
13#ifndef IN_GUEST
14#include <string.h>
15#endif
16
17#if defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(DARWIN) || defined(SunOS) || defined(OSF1)
18#include <dlfcn.h>
19#endif
20
21#ifdef DARWIN
22
23#include <Carbon/Carbon.h>
24#include <mach-o/dyld.h>
25
26char *__frameworkErr=NULL;
27
28CFBundleRef LoadFramework( const char *frameworkName ) {
29 CFBundleRef bundle;
30 CFURLRef bundleURL;
31 char fullfile[8096];
32
33 if( frameworkName[0] != '/' ) {
34 /* load a system framework */
35 /* XXX \todo should this folder be retrieved from somewhere else? */
36 crStrcpy( fullfile, "/System/Library/Frameworks/" );
37 crStrcat( fullfile, frameworkName );
38 } else {
39 /* load any framework */
40 crStrcpy( fullfile, frameworkName );
41 }
42
43 bundleURL = CFURLCreateWithString( NULL, CFStringCreateWithCStringNoCopy(NULL, fullfile, CFStringGetSystemEncoding(), NULL), NULL );
44 if( !bundleURL ) {
45 __frameworkErr = "Could not create OpenGL Framework bundle URL";
46 return NULL;
47 }
48
49 bundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
50 CFRelease( bundleURL );
51
52 if( !bundle ) {
53 __frameworkErr = "Could not create OpenGL Framework bundle";
54 return NULL;
55 }
56
57 if( !CFBundleLoadExecutable(bundle) ) {
58 __frameworkErr = "Could not load MachO executable";
59 return NULL;
60 }
61
62 return bundle;
63}
64
65char *__bundleErr=NULL;
66
67void *LoadBundle( const char *filename ) {
68 NSObjectFileImage fileImage;
69 NSModule handle = NULL;
70 char _filename[PATH_MAX];
71
72 __bundleErr = NULL;
73
74 if( filename[0] != '/' ) {
75 /* default to a chromium bundle */
76 crStrcpy( _filename, "/cr/lib/Darwin/" );
77 crStrcat( _filename, filename );
78 } else {
79 crStrcpy( _filename, filename );
80 }
81
82 switch( NSCreateObjectFileImageFromFile(_filename, &fileImage) ) {
83 default:
84 case NSObjectFileImageFailure:
85 __bundleErr = "NSObjectFileImageFailure: Failure.";
86 break;
87
88 case NSObjectFileImageInappropriateFile:
89 __bundleErr = "NSObjectFileImageInappropriateFile: The specified file is not of a valid type.";
90 break;
91
92 case NSObjectFileImageArch:
93 __bundleErr = "NSObjectFileImageArch: The specified file is for a different CPU architecture.";
94 break;
95
96 case NSObjectFileImageFormat:
97 __bundleErr = "NSObjectFileImageFormat: The specified file does not appear to be a Mach-O file";
98 break;
99
100 case NSObjectFileImageAccess:
101 __bundleErr = "NSObjectFileImageAccess: Permission to create image denied.";
102 break;
103
104 case NSObjectFileImageSuccess:
105 handle = NSLinkModule( fileImage, _filename,
106 NSLINKMODULE_OPTION_RETURN_ON_ERROR |
107 NSLINKMODULE_OPTION_PRIVATE );
108 NSDestroyObjectFileImage( fileImage );
109 if( !handle ) {
110 NSLinkEditErrors c;
111 int n;
112 const char *name;
113 NSLinkEditError(&c, &n, &name, (const char**)&__bundleErr);
114 }
115 break;
116 }
117
118 return handle;
119}
120
121int check_extension( const char *name, const char *extension ) {
122 int nam_len = crStrlen( name );
123 int ext_len = crStrlen( extension );
124 char *pos = crStrstr( name, extension );
125 return ( pos == &(name[nam_len-ext_len]) );
126}
127
128enum {
129 CR_DLL_NONE,
130 CR_DLL_FRAMEWORK,
131 CR_DLL_DYLIB,
132 CR_DLL_BUNDLE,
133 CR_DLL_UNKNOWN
134};
135
136#define NS_ADD 0
137
138int get_dll_type( const char *name ) {
139 if( check_extension(name, ".framework") )
140 return CR_DLL_FRAMEWORK;
141 if( check_extension(name, ".bundle") )
142 return CR_DLL_BUNDLE;
143 if( check_extension(name, ".dylib") )
144 return CR_DLL_DYLIB;
145 return CR_DLL_DYLIB;
146}
147
148#endif
149
150
151/*
152 * Open the named shared library.
153 * If resolveGlobal is non-zero, unresolved symbols can be satisfied by
154 * any matching symbol already defined globally. Otherwise, if resolveGlobal
155 * is zero, unresolved symbols should be resolved using symbols in that
156 * object (in preference to global symbols).
157 * NOTE: this came about because we found that for libGL, we need the
158 * global-resolve option but for SPU's we need the non-global option (consider
159 * the state tracker duplicated in the array, tilesort, etc. SPUs).
160 */
161CRDLL *crDLLOpen( const char *dllname, int resolveGlobal )
162{
163 CRDLL *dll;
164 char *dll_err;
165
166 dll = (CRDLL *) crAlloc( sizeof( CRDLL ) );
167 dll->name = crStrdup( dllname );
168
169#if defined(WINDOWS)
170 (void) resolveGlobal;
171 dll->hinstLib = LoadLibrary( dllname );
172 dll_err = NULL;
173#elif defined(DARWIN)
174 /* XXX \todo Get better error handling in here */
175 dll->type = get_dll_type( dllname );
176 dll_err = NULL;
177
178 switch( dll->type ) {
179 case CR_DLL_FRAMEWORK:
180 dll->hinstLib = LoadFramework( dllname );
181 dll_err = __frameworkErr;
182 break;
183
184 case CR_DLL_BUNDLE:
185 dll->hinstLib = LoadBundle( dllname );
186 dll_err = __bundleErr;
187 break;
188
189 case CR_DLL_DYLIB:
190#if NS_ADD
191 dll->hinstLib = (void*)NSAddImage( dllname, NSADDIMAGE_OPTION_RETURN_ON_ERROR );
192#else
193 if( resolveGlobal )
194 dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL );
195 else
196 dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_LOCAL );
197 dll_err = (char*) dlerror();
198#endif
199 break;
200
201 default:
202 dll->hinstLib = NULL;
203 dll_err = "Unknown DLL type";
204 break;
205 };
206#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
207 if (resolveGlobal)
208 dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL );
209 else
210 dll->hinstLib = dlopen( dllname, RTLD_LAZY );
211 dll_err = (char*) dlerror();
212#else
213#error DSO
214#endif
215
216 if (!dll->hinstLib)
217 {
218 if (dll_err)
219 {
220 crDebug( "DLL_ERROR(%s): %s", dllname, dll_err );
221 }
222 crError( "DLL Loader couldn't find/open %s", dllname );
223 }
224 return dll;
225}
226
227CRDLLFunc crDLLGetNoError( CRDLL *dll, const char *symname )
228{
229#if defined(WINDOWS)
230 return (CRDLLFunc) GetProcAddress( dll->hinstLib, symname );
231#elif defined(DARWIN)
232 NSSymbol nssym;
233
234 if( dll->type == CR_DLL_FRAMEWORK )
235 return (CRDLLFunc) CFBundleGetFunctionPointerForName( (CFBundleRef) dll->hinstLib, CFStringCreateWithCStringNoCopy(NULL, symname, CFStringGetSystemEncoding(), NULL) );
236
237 if( dll->type == CR_DLL_DYLIB )
238#if NS_ADD
239 nssym = NSLookupSymbolInImage( dll->hinstLib, symname, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR );
240#else
241 return (CRDLLFunc) dlsym( dll->hinstLib, symname );
242#endif
243 else
244 nssym = NSLookupSymbolInModule( dll->hinstLib, symname );
245
246 if( !nssym ) {
247 char name[PATH_MAX];
248 crStrcpy( name, "_" );
249 crStrcat( name, symname );
250
251 if( dll->type == CR_DLL_DYLIB )
252 nssym = NSLookupSymbolInImage( dll->hinstLib, name, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR );
253 else
254 nssym = NSLookupSymbolInModule( dll->hinstLib, name );
255 }
256
257 return (CRDLLFunc) NSAddressOfSymbol( nssym );
258
259#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
260 return (CRDLLFunc) dlsym( dll->hinstLib, symname );
261#else
262#error CR DLL ARCHITETECTURE
263#endif
264}
265
266CRDLLFunc crDLLGet( CRDLL *dll, const char *symname )
267{
268 CRDLLFunc data = crDLLGetNoError( dll, symname );
269 if (!data)
270 {
271 /* Are you sure there isn't some C++ mangling messing you up? */
272 crWarning( "Couldn't get symbol \"%s\" in \"%s\"", symname, dll->name );
273 }
274 return data;
275}
276
277void crDLLClose( CRDLL *dll )
278{
279 int dll_err = 0;
280
281 if (!dll) return;
282
283#if defined(WINDOWS)
284 FreeLibrary( dll->hinstLib );
285#elif defined(DARWIN)
286 switch( dll->type ) {
287 case CR_DLL_FRAMEWORK:
288 CFBundleUnloadExecutable( dll->hinstLib );
289 CFRelease(dll->hinstLib);
290 dll->hinstLib = NULL;
291 break;
292
293 case CR_DLL_DYLIB:
294#if !NS_ADD
295 dlclose( dll->hinstLib );
296#endif
297 break;
298
299 case CR_DLL_BUNDLE:
300 NSUnLinkModule( (NSModule) dll->hinstLib, 0L );
301 break;
302 }
303#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
304 /*
305 * Unloading Nvidia's libGL will crash VirtualBox later during shutdown.
306 * Therefore we will skip unloading it. It will be unloaded later anway
307 * because we are already freeing all ressources and VirtualBox will terminate
308 * soon.
309 */
310#ifndef IN_GUEST
311 if (strncmp(dll->name, "libGL", 5))
312#endif
313 dll_err = dlclose( dll->hinstLib );
314#else
315#error DSO
316#endif
317
318 if (dll_err)
319 crWarning("Error closing DLL %s\n",dll->name);
320
321 crFree( dll->name );
322 crFree( dll );
323}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette