VirtualBox

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

最後變更 在這個檔案從62812是 62812,由 vboxsync 提交於 9 年 前

GuestHost/OpenGL: warnings

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 9.9 KB
 
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 WINDOWS
22# ifdef VBOX
23# include <iprt/win/shlwapi.h>
24# else
25#include <Shlwapi.h>
26# endif
27#endif
28
29#ifdef DARWIN
30
31#include <Carbon/Carbon.h>
32#include <mach-o/dyld.h>
33
34char *__frameworkErr=NULL;
35
36CFBundleRef LoadFramework( const char *frameworkName ) {
37 CFBundleRef bundle;
38 CFURLRef bundleURL;
39 char fullfile[8096];
40
41 if( frameworkName[0] != '/' ) {
42 /* load a system framework */
43 /* XXX \todo should this folder be retrieved from somewhere else? */
44 crStrcpy( fullfile, "/System/Library/Frameworks/" );
45 crStrcat( fullfile, frameworkName );
46 } else {
47 /* load any framework */
48 crStrcpy( fullfile, frameworkName );
49 }
50
51 bundleURL = CFURLCreateWithString( NULL, CFStringCreateWithCStringNoCopy(NULL, fullfile, CFStringGetSystemEncoding(), NULL), NULL );
52 if( !bundleURL ) {
53 __frameworkErr = "Could not create OpenGL Framework bundle URL";
54 return NULL;
55 }
56
57 bundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
58 CFRelease( bundleURL );
59
60 if( !bundle ) {
61 __frameworkErr = "Could not create OpenGL Framework bundle";
62 return NULL;
63 }
64
65 if( !CFBundleLoadExecutable(bundle) ) {
66 __frameworkErr = "Could not load MachO executable";
67 return NULL;
68 }
69
70 return bundle;
71}
72
73char *__bundleErr=NULL;
74
75void *LoadBundle( const char *filename ) {
76 NSObjectFileImage fileImage;
77 NSModule handle = NULL;
78 char _filename[PATH_MAX];
79
80 __bundleErr = NULL;
81
82 if( filename[0] != '/' ) {
83 /* default to a chromium bundle */
84 crStrcpy( _filename, "/cr/lib/Darwin/" );
85 crStrcat( _filename, filename );
86 } else {
87 crStrcpy( _filename, filename );
88 }
89
90 switch( NSCreateObjectFileImageFromFile(_filename, &fileImage) ) {
91 default:
92 case NSObjectFileImageFailure:
93 __bundleErr = "NSObjectFileImageFailure: Failure.";
94 break;
95
96 case NSObjectFileImageInappropriateFile:
97 __bundleErr = "NSObjectFileImageInappropriateFile: The specified file is not of a valid type.";
98 break;
99
100 case NSObjectFileImageArch:
101 __bundleErr = "NSObjectFileImageArch: The specified file is for a different CPU architecture.";
102 break;
103
104 case NSObjectFileImageFormat:
105 __bundleErr = "NSObjectFileImageFormat: The specified file does not appear to be a Mach-O file";
106 break;
107
108 case NSObjectFileImageAccess:
109 __bundleErr = "NSObjectFileImageAccess: Permission to create image denied.";
110 break;
111
112 case NSObjectFileImageSuccess:
113 handle = NSLinkModule( fileImage, _filename,
114 NSLINKMODULE_OPTION_RETURN_ON_ERROR |
115 NSLINKMODULE_OPTION_PRIVATE );
116 NSDestroyObjectFileImage( fileImage );
117 if( !handle ) {
118 NSLinkEditErrors c;
119 int n;
120 const char *name;
121 NSLinkEditError(&c, &n, &name, (const char**)&__bundleErr);
122 }
123 break;
124 }
125
126 return handle;
127}
128
129int check_extension( const char *name, const char *extension ) {
130 int nam_len = crStrlen( name );
131 int ext_len = crStrlen( extension );
132 char *pos = crStrstr( name, extension );
133 return ( pos == &(name[nam_len-ext_len]) );
134}
135
136enum {
137 CR_DLL_NONE,
138 CR_DLL_FRAMEWORK,
139 CR_DLL_DYLIB,
140 CR_DLL_BUNDLE,
141 CR_DLL_UNKNOWN
142};
143
144#define NS_ADD 0
145
146int get_dll_type( const char *name ) {
147 if( check_extension(name, ".framework") )
148 return CR_DLL_FRAMEWORK;
149 if( check_extension(name, ".bundle") )
150 return CR_DLL_BUNDLE;
151 if( check_extension(name, ".dylib") )
152 return CR_DLL_DYLIB;
153 return CR_DLL_DYLIB;
154}
155
156#endif
157
158/*
159 * Open the named shared library.
160 * If resolveGlobal is non-zero, unresolved symbols can be satisfied by
161 * any matching symbol already defined globally. Otherwise, if resolveGlobal
162 * is zero, unresolved symbols should be resolved using symbols in that
163 * object (in preference to global symbols).
164 * NOTE: this came about because we found that for libGL, we need the
165 * global-resolve option but for SPU's we need the non-global option (consider
166 * the state tracker duplicated in the array, tilesort, etc. SPUs).
167 */
168CRDLL *crDLLOpen( const char *dllname, int resolveGlobal )
169{
170 CRDLL *dll;
171 char *dll_err;
172#if defined(WINDOWS)
173 WCHAR szwPath[MAX_PATH];
174 UINT cwcPath = 0;
175
176 (void) resolveGlobal;
177
178# ifndef CR_NO_GL_SYSTEM_PATH
179 if (PathIsRelative(dllname))
180 {
181 size_t cName = strlen(dllname) + 1;
182# ifdef IN_GUEST
183 cwcPath = GetSystemDirectoryW(szwPath, RT_ELEMENTS(szwPath));
184 if (!cwcPath || cwcPath >= MAX_PATH)
185 {
186 DWORD winEr = GetLastError();
187 crError("GetSystemDirectoryW failed err %d", winEr);
188 SetLastError(winEr);
189 return NULL;
190 }
191# else
192 WCHAR * pszwSlashFile;
193 cwcPath = GetModuleFileNameW(NULL, szwPath, RT_ELEMENTS(szwPath));
194 if (!cwcPath || cwcPath >= MAX_PATH)
195 {
196 DWORD winEr = GetLastError();
197 crError("GetModuleFileNameW failed err %d", winEr);
198 SetLastError(winEr);
199 return NULL;
200 }
201
202 pszwSlashFile = wcsrchr(szwPath, L'\\');
203 if (!pszwSlashFile)
204 {
205 crError("failed to match file name");
206 SetLastError(ERROR_PATH_NOT_FOUND);
207 return NULL;
208 }
209
210 cwcPath = pszwSlashFile - szwPath;
211# endif
212
213 if (cwcPath + 1 + cName > MAX_PATH)
214 {
215 crError("invalid path specified");
216 SetLastError(ERROR_FILENAME_EXCED_RANGE);
217 return NULL;
218 }
219 szwPath[cwcPath] = '\\';
220 ++cwcPath;
221 }
222
223 if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, dllname, -1, &szwPath[cwcPath], MAX_PATH - cwcPath))
224 {
225 DWORD winEr = GetLastError();
226 crError("MultiByteToWideChar failed err %d", winEr);
227 SetLastError(winEr);
228 return NULL;
229 }
230# endif // CR_NO_GL_SYSTEM_PATH
231#endif
232
233 dll = (CRDLL *) crAlloc( sizeof( CRDLL ) );
234 dll->name = crStrdup( dllname );
235
236#if defined(WINDOWS)
237 dll->hinstLib = LoadLibraryW( szwPath );
238 if (!dll->hinstLib)
239 {
240 crError("failed to load dll %s", dllname);
241 }
242 dll_err = NULL;
243#elif defined(DARWIN)
244 /* XXX \todo Get better error handling in here */
245 dll->type = get_dll_type( dllname );
246 dll_err = NULL;
247
248 switch( dll->type ) {
249 case CR_DLL_FRAMEWORK:
250 dll->hinstLib = LoadFramework( dllname );
251 dll_err = __frameworkErr;
252 break;
253
254 case CR_DLL_BUNDLE:
255 dll->hinstLib = LoadBundle( dllname );
256 dll_err = __bundleErr;
257 break;
258
259 case CR_DLL_DYLIB:
260#if NS_ADD
261 dll->hinstLib = (void*)NSAddImage( dllname, NSADDIMAGE_OPTION_RETURN_ON_ERROR );
262#else
263 if( resolveGlobal )
264 dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL );
265 else
266 dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_LOCAL );
267 dll_err = (char*) dlerror();
268#endif
269 break;
270
271 default:
272 dll->hinstLib = NULL;
273 dll_err = "Unknown DLL type";
274 break;
275 };
276#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
277 if (resolveGlobal)
278 dll->hinstLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL );
279 else
280 dll->hinstLib = dlopen( dllname, RTLD_LAZY );
281 dll_err = (char*) dlerror();
282#else
283#error DSO
284#endif
285
286 if (!dll->hinstLib)
287 {
288 if (dll_err)
289 {
290 crDebug( "DLL_ERROR(%s): %s", dllname, dll_err );
291 }
292 crError( "DLL Loader couldn't find/open %s", dllname );
293 }
294 return dll;
295}
296
297CRDLLFunc crDLLGetNoError( CRDLL *dll, const char *symname )
298{
299#if defined(WINDOWS)
300 return (CRDLLFunc) GetProcAddress( dll->hinstLib, symname );
301#elif defined(DARWIN)
302 NSSymbol nssym;
303
304 if( dll->type == CR_DLL_FRAMEWORK )
305 return (CRDLLFunc) CFBundleGetFunctionPointerForName( (CFBundleRef) dll->hinstLib, CFStringCreateWithCStringNoCopy(NULL, symname, CFStringGetSystemEncoding(), NULL) );
306
307 if( dll->type == CR_DLL_DYLIB )
308#if NS_ADD
309 nssym = NSLookupSymbolInImage( dll->hinstLib, symname, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR );
310#else
311 return (CRDLLFunc) dlsym( dll->hinstLib, symname );
312#endif
313 else
314 nssym = NSLookupSymbolInModule( dll->hinstLib, symname );
315
316 if( !nssym ) {
317 char name[PATH_MAX];
318 crStrcpy( name, "_" );
319 crStrcat( name, symname );
320
321 if( dll->type == CR_DLL_DYLIB )
322 nssym = NSLookupSymbolInImage( dll->hinstLib, name, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR );
323 else
324 nssym = NSLookupSymbolInModule( dll->hinstLib, name );
325 }
326
327 return (CRDLLFunc) NSAddressOfSymbol( nssym );
328
329#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
330 return (CRDLLFunc) dlsym( dll->hinstLib, symname );
331#else
332#error CR DLL ARCHITETECTURE
333#endif
334}
335
336CRDLLFunc crDLLGet( CRDLL *dll, const char *symname )
337{
338 CRDLLFunc data = crDLLGetNoError( dll, symname );
339 if (!data)
340 {
341 /* Are you sure there isn't some C++ mangling messing you up? */
342 crWarning( "Couldn't get symbol \"%s\" in \"%s\"", symname, dll->name );
343 }
344 return data;
345}
346
347void crDLLClose( CRDLL *dll )
348{
349 int dll_err = 0;
350
351 if (!dll) return;
352
353#if defined(WINDOWS)
354 FreeLibrary( dll->hinstLib );
355#elif defined(DARWIN)
356 switch( dll->type ) {
357 case CR_DLL_FRAMEWORK:
358 CFBundleUnloadExecutable( dll->hinstLib );
359 CFRelease(dll->hinstLib);
360 dll->hinstLib = NULL;
361 break;
362
363 case CR_DLL_DYLIB:
364#if !NS_ADD
365 dlclose( dll->hinstLib );
366#endif
367 break;
368
369 case CR_DLL_BUNDLE:
370 NSUnLinkModule( (NSModule) dll->hinstLib, 0L );
371 break;
372 }
373#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
374 /*
375 * Unloading Nvidia's libGL will crash VirtualBox later during shutdown.
376 * Therefore we will skip unloading it. It will be unloaded later anway
377 * because we are already freeing all resources and VirtualBox will terminate
378 * soon.
379 */
380#ifndef IN_GUEST
381 if (strncmp(dll->name, "libGL", 5))
382#endif
383 dll_err = dlclose( dll->hinstLib );
384#else
385#error DSO
386#endif
387
388 if (dll_err)
389 crWarning("Error closing DLL %s\n",dll->name);
390
391 crFree( dll->name );
392 crFree( dll );
393}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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