VirtualBox

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

Last change on this file since 15532 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

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