diff options
author | Franklin Wei <git@fwei.tk> | 2018-02-07 20:04:46 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2018-03-12 20:52:01 -0400 |
commit | 6039eb05ba6d82ef56f2868c96654c552d117bf9 (patch) | |
tree | 9db7016bcbf66cfdf7b9bc998d84c6eaff9c8378 /apps/plugins/sdl/src/loadso | |
parent | ef373c03b96b0be08babca581d9f10bccfd4931f (diff) | |
download | rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.tar.gz rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.zip |
sdl: remove non-rockbox drivers
We never use any of these other drivers, so having them around just takes
up space.
Change-Id: Iced812162df1fef3fd55522b7e700acb6c3bcd41
Diffstat (limited to 'apps/plugins/sdl/src/loadso')
-rw-r--r-- | apps/plugins/sdl/src/loadso/beos/SDL_sysloadso.c | 72 | ||||
-rw-r--r-- | apps/plugins/sdl/src/loadso/dlopen/SDL_sysloadso.c | 69 | ||||
-rw-r--r-- | apps/plugins/sdl/src/loadso/macos/SDL_sysloadso.c | 106 | ||||
-rw-r--r-- | apps/plugins/sdl/src/loadso/macosx/SDL_dlcompat.c | 1407 | ||||
-rw-r--r-- | apps/plugins/sdl/src/loadso/mint/SDL_sysloadso.c | 62 | ||||
-rw-r--r-- | apps/plugins/sdl/src/loadso/os2/SDL_sysloadso.c | 71 | ||||
-rw-r--r-- | apps/plugins/sdl/src/loadso/win32/SDL_sysloadso.c | 139 |
7 files changed, 0 insertions, 1926 deletions
diff --git a/apps/plugins/sdl/src/loadso/beos/SDL_sysloadso.c b/apps/plugins/sdl/src/loadso/beos/SDL_sysloadso.c deleted file mode 100644 index 28267b72b3..0000000000 --- a/apps/plugins/sdl/src/loadso/beos/SDL_sysloadso.c +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_BEOS | ||
25 | |||
26 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
27 | /* System dependent library loading routines */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #include <be/kernel/image.h> | ||
31 | |||
32 | #include "SDL_loadso.h" | ||
33 | |||
34 | void * | ||
35 | SDL_LoadObject(const char *sofile) | ||
36 | { | ||
37 | void *handle = NULL; | ||
38 | image_id library_id = load_add_on(sofile); | ||
39 | if (library_id < 0) { | ||
40 | SDL_SetError(strerror((int) library_id)); | ||
41 | } else { | ||
42 | handle = (void *) (library_id); | ||
43 | } | ||
44 | return (handle); | ||
45 | } | ||
46 | |||
47 | void * | ||
48 | SDL_LoadFunction(void *handle, const char *name) | ||
49 | { | ||
50 | void *sym = NULL; | ||
51 | image_id library_id = (image_id) handle; | ||
52 | status_t rc = get_image_symbol(library_id, name, B_SYMBOL_TYPE_TEXT, &sym); | ||
53 | if (rc != B_NO_ERROR) { | ||
54 | SDL_SetError(strerror(rc)); | ||
55 | } | ||
56 | return (sym); | ||
57 | } | ||
58 | |||
59 | void | ||
60 | SDL_UnloadObject(void *handle) | ||
61 | { | ||
62 | image_id library_id; | ||
63 | if (handle != NULL) { | ||
64 | library_id = (image_id) handle; | ||
65 | unload_add_on(library_id); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | #endif /* SDL_LOADSO_BEOS */ | ||
70 | |||
71 | /* vi: set ts=4 sw=4 expandtab: */ | ||
72 | |||
diff --git a/apps/plugins/sdl/src/loadso/dlopen/SDL_sysloadso.c b/apps/plugins/sdl/src/loadso/dlopen/SDL_sysloadso.c deleted file mode 100644 index 7985ee7f9d..0000000000 --- a/apps/plugins/sdl/src/loadso/dlopen/SDL_sysloadso.c +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_DLOPEN | ||
25 | |||
26 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
27 | /* System dependent library loading routines */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #include <dlfcn.h> | ||
31 | |||
32 | #include "SDL_loadso.h" | ||
33 | |||
34 | void *SDL_LoadObject(const char *sofile) | ||
35 | { | ||
36 | void *handle = dlopen(sofile, RTLD_NOW); | ||
37 | const char *loaderror = (char *)dlerror(); | ||
38 | if ( handle == NULL ) { | ||
39 | SDL_SetError("Failed loading %s: %s", sofile, loaderror); | ||
40 | } | ||
41 | return(handle); | ||
42 | } | ||
43 | |||
44 | void *SDL_LoadFunction(void *handle, const char *name) | ||
45 | { | ||
46 | void *symbol = dlsym(handle, name); | ||
47 | if ( symbol == NULL ) { | ||
48 | /* append an underscore for platforms that need that. */ | ||
49 | size_t len = 1+SDL_strlen(name)+1; | ||
50 | char *_name = SDL_stack_alloc(char, len); | ||
51 | _name[0] = '_'; | ||
52 | SDL_strlcpy(&_name[1], name, len); | ||
53 | symbol = dlsym(handle, _name); | ||
54 | SDL_stack_free(_name); | ||
55 | if ( symbol == NULL ) { | ||
56 | SDL_SetError("Failed loading %s: %s", name, (const char *)dlerror()); | ||
57 | } | ||
58 | } | ||
59 | return(symbol); | ||
60 | } | ||
61 | |||
62 | void SDL_UnloadObject(void *handle) | ||
63 | { | ||
64 | if ( handle != NULL ) { | ||
65 | dlclose(handle); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | #endif /* SDL_LOADSO_DLOPEN */ | ||
diff --git a/apps/plugins/sdl/src/loadso/macos/SDL_sysloadso.c b/apps/plugins/sdl/src/loadso/macos/SDL_sysloadso.c deleted file mode 100644 index c035b1786c..0000000000 --- a/apps/plugins/sdl/src/loadso/macos/SDL_sysloadso.c +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_MACOS | ||
25 | |||
26 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
27 | /* System dependent library loading routines */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #include <string.h> | ||
31 | #define OLDP2C 1 | ||
32 | #include <Strings.h> | ||
33 | #include <CodeFragments.h> | ||
34 | #include <Errors.h> | ||
35 | |||
36 | #include "SDL_loadso.h" | ||
37 | |||
38 | void *SDL_LoadObject(const char *sofile) | ||
39 | { | ||
40 | void *handle = NULL; | ||
41 | const char *loaderror = NULL; | ||
42 | CFragConnectionID library_id; | ||
43 | Ptr mainAddr; | ||
44 | Str255 errName; | ||
45 | OSErr error; | ||
46 | char psofile[512]; | ||
47 | |||
48 | SDL_strlcpy(psofile, sofile, SDL_arraysize(psofile)); | ||
49 | error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch, | ||
50 | kLoadCFrag, &library_id, &mainAddr, errName); | ||
51 | switch (error) { | ||
52 | case noErr: | ||
53 | loaderror = NULL; | ||
54 | break; | ||
55 | case cfragNoLibraryErr: | ||
56 | loaderror = "Library not found"; | ||
57 | break; | ||
58 | case cfragUnresolvedErr: | ||
59 | loaderror = "Unabled to resolve symbols"; | ||
60 | break; | ||
61 | case cfragNoPrivateMemErr: | ||
62 | case cfragNoClientMemErr: | ||
63 | loaderror = "Out of memory"; | ||
64 | break; | ||
65 | default: | ||
66 | loaderror = "Unknown Code Fragment Manager error"; | ||
67 | break; | ||
68 | } | ||
69 | if ( loaderror == NULL ) { | ||
70 | handle = (void *)(library_id); | ||
71 | } else { | ||
72 | SDL_SetError("Failed loading %s: %s", sofile, loaderror); | ||
73 | } | ||
74 | return(handle); | ||
75 | } | ||
76 | |||
77 | void *SDL_LoadFunction(void *handle, const char *name) | ||
78 | { | ||
79 | void *symbol = NULL; | ||
80 | const char *loaderror = NULL; | ||
81 | CFragSymbolClass class; | ||
82 | CFragConnectionID library_id = (CFragConnectionID)handle; | ||
83 | char pname[512]; | ||
84 | |||
85 | SDL_strlcpy(pname, name, SDL_arraysize(pname)); | ||
86 | if ( FindSymbol(library_id, C2PStr(pname), | ||
87 | (char **)&symbol, &class) != noErr ) { | ||
88 | loaderror = "Symbol not found"; | ||
89 | } | ||
90 | |||
91 | if ( symbol == NULL ) { | ||
92 | SDL_SetError("Failed loading %s: %s", name, loaderror); | ||
93 | } | ||
94 | return(symbol); | ||
95 | } | ||
96 | |||
97 | void SDL_UnloadObject(void *handle) | ||
98 | { | ||
99 | CFragConnectionID library_id; | ||
100 | if ( handle != NULL ) { | ||
101 | library_id = (CFragConnectionID)handle; | ||
102 | CloseConnection(&library_id); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | #endif /* SDL_LOADSO_MACOS */ | ||
diff --git a/apps/plugins/sdl/src/loadso/macosx/SDL_dlcompat.c b/apps/plugins/sdl/src/loadso/macosx/SDL_dlcompat.c deleted file mode 100644 index 091947f2dc..0000000000 --- a/apps/plugins/sdl/src/loadso/macosx/SDL_dlcompat.c +++ /dev/null | |||
@@ -1,1407 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_DLCOMPAT | ||
25 | |||
26 | /* Please note that dlcompat apparently ships in current Mac OS X versions | ||
27 | * as a system library that provides compatibility with the Unix "dlopen" | ||
28 | * interface. In order to allow SDL to work on older OS X releases and also | ||
29 | * not conflict with the system lib on newer versions, we include dlcompat | ||
30 | * in SDL and change the symbols to prevent symbol clash with any existing | ||
31 | * system libraries. --ryan. | ||
32 | */ | ||
33 | |||
34 | /* here is the dlcompat license: */ | ||
35 | |||
36 | /* | ||
37 | Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> & | ||
38 | Peter O'Gorman <ogorman@users.sourceforge.net> | ||
39 | |||
40 | Portions may be copyright others, see the AUTHORS file included with this | ||
41 | distribution. | ||
42 | |||
43 | Maintained by Peter O'Gorman <ogorman@users.sourceforge.net> | ||
44 | |||
45 | Bug Reports and other queries should go to <ogorman@users.sourceforge.net> | ||
46 | |||
47 | Permission is hereby granted, free of charge, to any person obtaining | ||
48 | a copy of this software and associated documentation files (the | ||
49 | "Software"), to deal in the Software without restriction, including | ||
50 | without limitation the rights to use, copy, modify, merge, publish, | ||
51 | distribute, sublicense, and/or sell copies of the Software, and to | ||
52 | permit persons to whom the Software is furnished to do so, subject to | ||
53 | the following conditions: | ||
54 | |||
55 | The above copyright notice and this permission notice shall be | ||
56 | included in all copies or substantial portions of the Software. | ||
57 | |||
58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
59 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
60 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
61 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
62 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
63 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
64 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
65 | */ | ||
66 | |||
67 | #include <pthread.h> | ||
68 | #include <sys/types.h> | ||
69 | #include <sys/stat.h> | ||
70 | #include <stdarg.h> | ||
71 | #include <limits.h> | ||
72 | #include <mach-o/dyld.h> | ||
73 | #include <mach-o/nlist.h> | ||
74 | #include <mach-o/getsect.h> | ||
75 | |||
76 | #include "SDL_stdinc.h" | ||
77 | |||
78 | /* Just playing to see if it would compile with the freebsd headers, it does, | ||
79 | * but because of the different values for RTLD_LOCAL etc, it would break binary | ||
80 | * compat... oh well | ||
81 | */ | ||
82 | #ifndef __BSD_VISIBLE | ||
83 | #define __BSD_VISIBLE 1 | ||
84 | #endif | ||
85 | |||
86 | /*include "dlfcn.h"*/ | ||
87 | #ifdef __cplusplus | ||
88 | extern "C" { | ||
89 | #endif | ||
90 | |||
91 | #if defined (__GNUC__) && __GNUC__ > 3 | ||
92 | #define dl_restrict __restrict | ||
93 | #else | ||
94 | #define dl_restrict | ||
95 | #endif | ||
96 | |||
97 | #if 0 | ||
98 | #ifndef _POSIX_SOURCE | ||
99 | /* | ||
100 | * Structure filled in by dladdr(). | ||
101 | */ | ||
102 | typedef struct SDL_OSX_dl_info { | ||
103 | const char *dli_fname; /* Pathname of shared object */ | ||
104 | void *dli_fbase; /* Base address of shared object */ | ||
105 | const char *dli_sname; /* Name of nearest symbol */ | ||
106 | void *dli_saddr; /* Address of nearest symbol */ | ||
107 | } SDL_OSX_Dl_info; | ||
108 | |||
109 | static int SDL_OSX_dladdr(const void * dl_restrict, SDL_OSX_Dl_info * dl_restrict); | ||
110 | #endif /* ! _POSIX_SOURCE */ | ||
111 | #endif /* 0 */ | ||
112 | |||
113 | static int SDL_OSX_dlclose(void * handle); | ||
114 | static const char * SDL_OSX_dlerror(void); | ||
115 | static void * SDL_OSX_dlopen(const char *path, int mode); | ||
116 | static void * SDL_OSX_dlsym(void * dl_restrict handle, const char * dl_restrict symbol); | ||
117 | |||
118 | #define RTLD_LAZY 0x1 | ||
119 | #define RTLD_NOW 0x2 | ||
120 | #define RTLD_LOCAL 0x4 | ||
121 | #define RTLD_GLOBAL 0x8 | ||
122 | |||
123 | #ifndef _POSIX_SOURCE | ||
124 | #define RTLD_NOLOAD 0x10 | ||
125 | #define RTLD_NODELETE 0x80 | ||
126 | |||
127 | /* | ||
128 | * Special handle arguments for SDL_OSX_dlsym(). | ||
129 | */ | ||
130 | #define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ | ||
131 | #define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ | ||
132 | #endif /* ! _POSIX_SOURCE */ | ||
133 | |||
134 | #ifdef __cplusplus | ||
135 | } | ||
136 | #endif | ||
137 | |||
138 | #ifndef dl_restrict | ||
139 | #define dl_restrict __restrict | ||
140 | #endif | ||
141 | /* This is not available on 10.1 */ | ||
142 | #ifndef LC_LOAD_WEAK_DYLIB | ||
143 | #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) | ||
144 | #endif | ||
145 | |||
146 | /* With this stuff here, this thing may actually compile/run on 10.0 systems | ||
147 | * Not that I have a 10.0 system to test it on anylonger | ||
148 | */ | ||
149 | #ifndef LC_REQ_DYLD | ||
150 | #define LC_REQ_DYLD 0x80000000 | ||
151 | #endif | ||
152 | #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED | ||
153 | #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 | ||
154 | #endif | ||
155 | #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR | ||
156 | #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 | ||
157 | #endif | ||
158 | #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | ||
159 | #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 | ||
160 | #endif | ||
161 | #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR | ||
162 | #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 | ||
163 | #endif | ||
164 | /* These symbols will be looked for in dyld */ | ||
165 | static const struct mach_header *(*dyld_NSAddImage) (const char *, unsigned long) = 0; | ||
166 | static int (*dyld_NSIsSymbolNameDefinedInImage) (const struct mach_header *, const char *) = 0; | ||
167 | static NSSymbol(*dyld_NSLookupSymbolInImage) | ||
168 | (const struct mach_header *, const char *, unsigned long) = 0; | ||
169 | |||
170 | /* Define this to make dlcompat reuse data block. This way in theory we save | ||
171 | * a little bit of overhead. However we then couldn't correctly catch excess | ||
172 | * calls to SDL_OSX_dlclose(). Hence we don't use this feature | ||
173 | */ | ||
174 | #undef REUSE_STATUS | ||
175 | |||
176 | /* Size of the internal error message buffer (used by dlerror()) */ | ||
177 | #define ERR_STR_LEN 251 | ||
178 | |||
179 | /* Maximum number of search paths supported by getSearchPath */ | ||
180 | #define MAX_SEARCH_PATHS 32 | ||
181 | |||
182 | |||
183 | #define MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF') | ||
184 | #define MAGIC_DYLIB_MOD ((NSModule) 'DYMO') | ||
185 | |||
186 | /* internal flags */ | ||
187 | #define DL_IN_LIST 0x01 | ||
188 | |||
189 | /* our mutex */ | ||
190 | static pthread_mutex_t dlcompat_mutex; | ||
191 | /* Our thread specific storage | ||
192 | */ | ||
193 | static pthread_key_t dlerror_key; | ||
194 | |||
195 | struct dlthread | ||
196 | { | ||
197 | int lockcnt; | ||
198 | unsigned char errset; | ||
199 | char errstr[ERR_STR_LEN]; | ||
200 | }; | ||
201 | |||
202 | /* This is our central data structure. Whenever a module is loaded via | ||
203 | * SDL_OSX_dlopen(), we create such a struct. | ||
204 | */ | ||
205 | struct dlstatus | ||
206 | { | ||
207 | struct dlstatus *next; /* pointer to next element in the linked list */ | ||
208 | NSModule module; | ||
209 | const struct mach_header *lib; | ||
210 | int refs; /* reference count */ | ||
211 | int mode; /* mode in which this module was loaded */ | ||
212 | dev_t device; | ||
213 | ino_t inode; | ||
214 | int flags; /* Any internal flags we may need */ | ||
215 | }; | ||
216 | |||
217 | /* Head node of the dlstatus list */ | ||
218 | static struct dlstatus mainStatus = { 0, MAGIC_DYLIB_MOD, NULL, -1, RTLD_GLOBAL, 0, 0, 0 }; | ||
219 | static struct dlstatus *stqueue = &mainStatus; | ||
220 | |||
221 | |||
222 | /* Storage for the last error message (used by dlerror()) */ | ||
223 | /* static char err_str[ERR_STR_LEN]; */ | ||
224 | /* static int err_filled = 0; */ | ||
225 | |||
226 | /* Prototypes to internal functions */ | ||
227 | static void debug(const char *fmt, ...); | ||
228 | static void error(const char *str, ...); | ||
229 | static const char *safegetenv(const char *s); | ||
230 | static const char *searchList(void); | ||
231 | static const char *getSearchPath(int i); | ||
232 | static const char *getFullPath(int i, const char *file); | ||
233 | static const struct stat *findFile(const char *file, const char **fullPath); | ||
234 | static int isValidStatus(struct dlstatus *status); | ||
235 | static inline int isFlagSet(int mode, int flag); | ||
236 | static struct dlstatus *lookupStatus(const struct stat *sbuf); | ||
237 | static void insertStatus(struct dlstatus *dls, const struct stat *sbuf); | ||
238 | static int promoteLocalToGlobal(struct dlstatus *dls); | ||
239 | static void *reference(struct dlstatus *dls, int mode); | ||
240 | static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError); | ||
241 | static struct dlstatus *allocStatus(void); | ||
242 | static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode); | ||
243 | static NSSymbol search_linked_libs(const struct mach_header *mh, const char *symbol); | ||
244 | static const char *get_lib_name(const struct mach_header *mh); | ||
245 | static const struct mach_header *get_mach_header_from_NSModule(NSModule mod); | ||
246 | static void dlcompat_init_func(void); | ||
247 | static inline void dlcompat_init_check(void); | ||
248 | static inline void dolock(void); | ||
249 | static inline void dounlock(void); | ||
250 | static void dlerrorfree(void *data); | ||
251 | static void resetdlerror(void); | ||
252 | static const struct mach_header *my_find_image(const char *name); | ||
253 | static const struct mach_header *image_for_address(const void *address); | ||
254 | static inline char *dyld_error_str(void); | ||
255 | |||
256 | #if FINK_BUILD | ||
257 | /* Two Global Functions */ | ||
258 | static void *dlsym_prepend_underscore(void *handle, const char *symbol); | ||
259 | static void *dlsym_auto_underscore(void *handle, const char *symbol); | ||
260 | |||
261 | /* And their _intern counterparts */ | ||
262 | static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol); | ||
263 | static void *dlsym_auto_underscore_intern(void *handle, const char *symbol); | ||
264 | #endif | ||
265 | |||
266 | /* Functions */ | ||
267 | |||
268 | static void debug(const char *fmt, ...) | ||
269 | { | ||
270 | #if DEBUG > 1 | ||
271 | va_list arg; | ||
272 | va_start(arg, fmt); | ||
273 | fprintf(stderr, "DLDEBUG: "); | ||
274 | vfprintf(stderr, fmt, arg); | ||
275 | fprintf(stderr, "\n"); | ||
276 | fflush(stderr); | ||
277 | va_end(arg); | ||
278 | #endif | ||
279 | } | ||
280 | |||
281 | static void error(const char *str, ...) | ||
282 | { | ||
283 | va_list arg; | ||
284 | struct dlthread *tss; | ||
285 | char * err_str; | ||
286 | va_start(arg, str); | ||
287 | tss = pthread_getspecific(dlerror_key); | ||
288 | err_str = tss->errstr; | ||
289 | SDL_strlcpy(err_str, "dlcompat: ", ERR_STR_LEN); | ||
290 | vsnprintf(err_str + 10, ERR_STR_LEN - 10, str, arg); | ||
291 | va_end(arg); | ||
292 | debug("ERROR: %s\n", err_str); | ||
293 | tss->errset = 1; | ||
294 | } | ||
295 | |||
296 | static void warning(const char *str) | ||
297 | { | ||
298 | #if DEBUG > 0 | ||
299 | fprintf(stderr, "WARNING: dlcompat: %s\n", str); | ||
300 | #endif | ||
301 | } | ||
302 | |||
303 | static const char *safegetenv(const char *s) | ||
304 | { | ||
305 | const char *ss = SDL_getenv(s); | ||
306 | return ss ? ss : ""; | ||
307 | } | ||
308 | |||
309 | /* because this is only used for debugging and error reporting functions, we | ||
310 | * don't really care about how elegant it is... it could use the load | ||
311 | * commands to find the install name of the library, but... | ||
312 | */ | ||
313 | static const char *get_lib_name(const struct mach_header *mh) | ||
314 | { | ||
315 | unsigned long count = _dyld_image_count(); | ||
316 | unsigned long i; | ||
317 | const char *val = NULL; | ||
318 | if (mh) | ||
319 | { | ||
320 | for (i = 0; i < count; i++) | ||
321 | { | ||
322 | if (mh == _dyld_get_image_header(i)) | ||
323 | { | ||
324 | val = _dyld_get_image_name(i); | ||
325 | break; | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | return val; | ||
330 | } | ||
331 | |||
332 | /* Returns the mach_header for the module bu going through all the loaded images | ||
333 | * and finding the one with the same name as the module. There really ought to be | ||
334 | * an api for doing this, would be faster, but there isn't one right now | ||
335 | */ | ||
336 | static const struct mach_header *get_mach_header_from_NSModule(NSModule mod) | ||
337 | { | ||
338 | const char *mod_name = NSNameOfModule(mod); | ||
339 | const struct mach_header *mh = NULL; | ||
340 | unsigned long count = _dyld_image_count(); | ||
341 | unsigned long i; | ||
342 | debug("Module name: %s", mod_name); | ||
343 | for (i = 0; i < count; i++) | ||
344 | { | ||
345 | if (!SDL_strcmp(mod_name, _dyld_get_image_name(i))) | ||
346 | { | ||
347 | mh = _dyld_get_image_header(i); | ||
348 | break; | ||
349 | } | ||
350 | } | ||
351 | return mh; | ||
352 | } | ||
353 | |||
354 | |||
355 | /* Compute and return a list of all directories that we should search when | ||
356 | * trying to locate a module. We first look at the values of LD_LIBRARY_PATH | ||
357 | * and DYLD_LIBRARY_PATH, and then finally fall back to looking into | ||
358 | * /usr/lib and /lib. Since both of the environments variables can contain a | ||
359 | * list of colon seperated paths, we simply concat them and the two other paths | ||
360 | * into one big string, which we then can easily parse. | ||
361 | * Splitting this string into the actual path list is done by getSearchPath() | ||
362 | */ | ||
363 | static const char *searchList() | ||
364 | { | ||
365 | size_t buf_size; | ||
366 | static char *buf=NULL; | ||
367 | const char *ldlp = safegetenv("LD_LIBRARY_PATH"); | ||
368 | const char *dyldlp = safegetenv("DYLD_LIBRARY_PATH"); | ||
369 | const char *stdpath = SDL_getenv("DYLD_FALLBACK_LIBRARY_PATH"); | ||
370 | if (!stdpath) | ||
371 | stdpath = "/usr/local/lib:/lib:/usr/lib"; | ||
372 | if (!buf) | ||
373 | { | ||
374 | buf_size = SDL_strlen(ldlp) + SDL_strlen(dyldlp) + SDL_strlen(stdpath) + 4; | ||
375 | buf = SDL_malloc(buf_size); | ||
376 | SDL_snprintf(buf, buf_size, "%s%s%s%s%s%c", dyldlp, (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""), | ||
377 | stdpath, '\0'); | ||
378 | } | ||
379 | return buf; | ||
380 | } | ||
381 | |||
382 | /* Returns the ith search path from the list as computed by searchList() */ | ||
383 | static const char *getSearchPath(int i) | ||
384 | { | ||
385 | static const char *list = 0; | ||
386 | static char **path = (char **)0; | ||
387 | static int end = 0; | ||
388 | static int numsize = MAX_SEARCH_PATHS; | ||
389 | static char **tmp; | ||
390 | /* So we can call SDL_free() in the "destructor" we use i=-1 to return the alloc'd array */ | ||
391 | if (i == -1) | ||
392 | { | ||
393 | return (const char*)path; | ||
394 | } | ||
395 | if (!path) | ||
396 | { | ||
397 | path = (char **)SDL_calloc(MAX_SEARCH_PATHS, sizeof(char **)); | ||
398 | } | ||
399 | if (!list && !end) | ||
400 | list = searchList(); | ||
401 | if (i >= (numsize)) | ||
402 | { | ||
403 | debug("Increasing size for long PATH"); | ||
404 | tmp = (char **)SDL_calloc((MAX_SEARCH_PATHS + numsize), sizeof(char **)); | ||
405 | if (tmp) | ||
406 | { | ||
407 | SDL_memcpy(tmp, path, sizeof(char **) * numsize); | ||
408 | SDL_free(path); | ||
409 | path = tmp; | ||
410 | numsize += MAX_SEARCH_PATHS; | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | return 0; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | while (!path[i] && !end) | ||
419 | { | ||
420 | path[i] = strsep((char **)&list, ":"); | ||
421 | |||
422 | if (path[i][0] == 0) | ||
423 | path[i] = 0; | ||
424 | end = (list == 0); | ||
425 | } | ||
426 | return path[i]; | ||
427 | } | ||
428 | |||
429 | static const char *getFullPath(int i, const char *file) | ||
430 | { | ||
431 | static char buf[PATH_MAX]; | ||
432 | const char *path = getSearchPath(i); | ||
433 | if (path) | ||
434 | { | ||
435 | SDL_snprintf(buf, PATH_MAX, "%s/%s", path, file); | ||
436 | } | ||
437 | return path ? buf : 0; | ||
438 | } | ||
439 | |||
440 | /* Given a file name, try to determine the full path for that file. Starts | ||
441 | * its search in the current directory, and then tries all paths in the | ||
442 | * search list in the order they are specified there. | ||
443 | */ | ||
444 | static const struct stat *findFile(const char *file, const char **fullPath) | ||
445 | { | ||
446 | int i = 0; | ||
447 | static struct stat sbuf; | ||
448 | char *fileName; | ||
449 | debug("finding file %s", file); | ||
450 | *fullPath = file; | ||
451 | if (0 == stat(file, &sbuf)) | ||
452 | return &sbuf; | ||
453 | if (SDL_strchr(file, '/')) | ||
454 | return 0; /* If the path had a / we don't look in env var places */ | ||
455 | fileName = NULL; | ||
456 | if (!fileName) | ||
457 | fileName = (char *)file; | ||
458 | while ((*fullPath = getFullPath(i++, fileName))) | ||
459 | { | ||
460 | if (0 == stat(*fullPath, &sbuf)) | ||
461 | return &sbuf; | ||
462 | } | ||
463 | ; | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /* Determine whether a given dlstatus is valid or not */ | ||
468 | static int isValidStatus(struct dlstatus *status) | ||
469 | { | ||
470 | /* Walk the list to verify status is contained in it */ | ||
471 | struct dlstatus *dls = stqueue; | ||
472 | while (dls && status != dls) | ||
473 | dls = dls->next; | ||
474 | if (dls == 0) | ||
475 | error("invalid handle"); | ||
476 | else if ((dls->module == 0) || (dls->refs == 0)) | ||
477 | error("handle to closed library"); | ||
478 | else | ||
479 | return TRUE; | ||
480 | return FALSE; | ||
481 | } | ||
482 | |||
483 | static inline int isFlagSet(int mode, int flag) | ||
484 | { | ||
485 | return (mode & flag) == flag; | ||
486 | } | ||
487 | |||
488 | static struct dlstatus *lookupStatus(const struct stat *sbuf) | ||
489 | { | ||
490 | struct dlstatus *dls = stqueue; | ||
491 | debug("looking for status"); | ||
492 | while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0 | ||
493 | || sbuf->st_dev != dls->device || sbuf->st_ino != dls->inode)) | ||
494 | dls = dls->next; | ||
495 | return dls; | ||
496 | } | ||
497 | |||
498 | static void insertStatus(struct dlstatus *dls, const struct stat *sbuf) | ||
499 | { | ||
500 | debug("inserting status"); | ||
501 | dls->inode = sbuf->st_ino; | ||
502 | dls->device = sbuf->st_dev; | ||
503 | dls->refs = 0; | ||
504 | dls->mode = 0; | ||
505 | if ((dls->flags & DL_IN_LIST) == 0) | ||
506 | { | ||
507 | dls->next = stqueue; | ||
508 | stqueue = dls; | ||
509 | dls->flags |= DL_IN_LIST; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | static struct dlstatus *allocStatus() | ||
514 | { | ||
515 | struct dlstatus *dls; | ||
516 | #ifdef REUSE_STATUS | ||
517 | dls = stqueue; | ||
518 | while (dls && dls->module) | ||
519 | dls = dls->next; | ||
520 | if (!dls) | ||
521 | #endif | ||
522 | dls = SDL_calloc(sizeof(*dls),1); | ||
523 | return dls; | ||
524 | } | ||
525 | |||
526 | static int promoteLocalToGlobal(struct dlstatus *dls) | ||
527 | { | ||
528 | static int (*p) (NSModule module) = 0; | ||
529 | debug("promoting"); | ||
530 | if (!p) | ||
531 | _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (void **)&p); | ||
532 | return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module)); | ||
533 | } | ||
534 | |||
535 | static void *reference(struct dlstatus *dls, int mode) | ||
536 | { | ||
537 | if (dls) | ||
538 | { | ||
539 | if (dls->module == MAGIC_DYLIB_MOD && isFlagSet(mode, RTLD_LOCAL)) | ||
540 | { | ||
541 | warning("trying to open a .dylib with RTLD_LOCAL"); | ||
542 | error("unable to open a .dylib with RTLD_LOCAL"); | ||
543 | return NULL; | ||
544 | } | ||
545 | if (isFlagSet(mode, RTLD_GLOBAL) && | ||
546 | !isFlagSet(dls->mode, RTLD_GLOBAL) && !promoteLocalToGlobal(dls)) | ||
547 | { | ||
548 | error("unable to promote local module to global"); | ||
549 | return NULL; | ||
550 | } | ||
551 | dls->mode |= mode; | ||
552 | dls->refs++; | ||
553 | } | ||
554 | else | ||
555 | debug("reference called with NULL argument"); | ||
556 | |||
557 | return dls; | ||
558 | } | ||
559 | |||
560 | static const struct mach_header *my_find_image(const char *name) | ||
561 | { | ||
562 | const struct mach_header *mh = 0; | ||
563 | const char *id = NULL; | ||
564 | int i = _dyld_image_count(); | ||
565 | int j; | ||
566 | mh = (struct mach_header *) | ||
567 | dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED | | ||
568 | NSADDIMAGE_OPTION_RETURN_ON_ERROR); | ||
569 | if (!mh) | ||
570 | { | ||
571 | for (j = 0; j < i; j++) | ||
572 | { | ||
573 | id = _dyld_get_image_name(j); | ||
574 | if (!SDL_strcmp(id, name)) | ||
575 | { | ||
576 | mh = _dyld_get_image_header(j); | ||
577 | break; | ||
578 | } | ||
579 | } | ||
580 | } | ||
581 | return mh; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * dyld adds libraries by first adding the directly dependant libraries in link order, and | ||
586 | * then adding the dependencies for those libraries, so we should do the same... but we don't | ||
587 | * bother adding the extra dependencies, if the symbols are neither in the loaded image nor | ||
588 | * any of it's direct dependencies, then it probably isn't there. | ||
589 | */ | ||
590 | static NSSymbol search_linked_libs(const struct mach_header * mh, const char *symbol) | ||
591 | { | ||
592 | unsigned int n; | ||
593 | struct load_command *lc = 0; | ||
594 | struct mach_header *wh; | ||
595 | NSSymbol nssym = 0; | ||
596 | if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) | ||
597 | { | ||
598 | lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); | ||
599 | for (n = 0; n < mh->ncmds; n++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | ||
600 | { | ||
601 | if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) | ||
602 | { | ||
603 | if ((wh = (struct mach_header *) | ||
604 | my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset + | ||
605 | (char *)lc)))) | ||
606 | { | ||
607 | if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol)) | ||
608 | { | ||
609 | nssym = dyld_NSLookupSymbolInImage(wh, | ||
610 | symbol, | ||
611 | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | ||
612 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | ||
613 | break; | ||
614 | } | ||
615 | } | ||
616 | } | ||
617 | } | ||
618 | if ((!nssym) && NSIsSymbolNameDefined(symbol)) | ||
619 | { | ||
620 | /* I've never seen this debug message...*/ | ||
621 | debug("Symbol \"%s\" is defined but was not found", symbol); | ||
622 | } | ||
623 | } | ||
624 | return nssym; | ||
625 | } | ||
626 | |||
627 | /* Up to the caller to SDL_free() returned string */ | ||
628 | static inline char *dyld_error_str() | ||
629 | { | ||
630 | NSLinkEditErrors dylder; | ||
631 | int dylderno; | ||
632 | const char *dylderrstr; | ||
633 | const char *dyldfile; | ||
634 | char* retStr = NULL; | ||
635 | NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr); | ||
636 | if (dylderrstr && *dylderrstr) | ||
637 | { | ||
638 | retStr = SDL_strdup(dylderrstr); | ||
639 | } | ||
640 | return retStr; | ||
641 | } | ||
642 | |||
643 | static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError) | ||
644 | { | ||
645 | NSSymbol nssym = 0; | ||
646 | #ifdef __GCC__ | ||
647 | void *caller = __builtin_return_address(1); /* Be *very* careful about inlining */ | ||
648 | #else | ||
649 | void *caller = NULL; | ||
650 | #endif | ||
651 | const struct mach_header *caller_mh = 0; | ||
652 | char *savedErrorStr = NULL; | ||
653 | resetdlerror(); | ||
654 | #ifndef RTLD_SELF | ||
655 | #define RTLD_SELF ((void *) -3) | ||
656 | #endif | ||
657 | if (NULL == dls) | ||
658 | dls = RTLD_SELF; | ||
659 | if ((RTLD_NEXT == dls) || (RTLD_SELF == dls)) | ||
660 | { | ||
661 | if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage && caller) | ||
662 | { | ||
663 | caller_mh = image_for_address(caller); | ||
664 | if (RTLD_SELF == dls) | ||
665 | { | ||
666 | /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE | ||
667 | * But it appears to work anyway, and looking at the code in dyld_libfuncs.c | ||
668 | * this is acceptable. | ||
669 | */ | ||
670 | if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol)) | ||
671 | { | ||
672 | nssym = dyld_NSLookupSymbolInImage(caller_mh, | ||
673 | symbol, | ||
674 | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | ||
675 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | ||
676 | } | ||
677 | } | ||
678 | if (!nssym) | ||
679 | { | ||
680 | if (RTLD_SELF == dls) | ||
681 | savedErrorStr = dyld_error_str(); | ||
682 | nssym = search_linked_libs(caller_mh, symbol); | ||
683 | } | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | if (canSetError) | ||
688 | error("RTLD_SELF and RTLD_NEXT are not supported"); | ||
689 | return NULL; | ||
690 | } | ||
691 | } | ||
692 | if (!nssym) | ||
693 | { | ||
694 | |||
695 | if (RTLD_DEFAULT == dls) | ||
696 | { | ||
697 | dls = &mainStatus; | ||
698 | } | ||
699 | if (!isValidStatus(dls)) | ||
700 | return NULL; | ||
701 | |||
702 | if (dls->module != MAGIC_DYLIB_MOD) | ||
703 | { | ||
704 | nssym = NSLookupSymbolInModule(dls->module, symbol); | ||
705 | if (!nssym && NSIsSymbolNameDefined(symbol)) | ||
706 | { | ||
707 | debug("Searching dependencies"); | ||
708 | savedErrorStr = dyld_error_str(); | ||
709 | nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol); | ||
710 | } | ||
711 | } | ||
712 | else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) | ||
713 | { | ||
714 | if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol)) | ||
715 | { | ||
716 | nssym = dyld_NSLookupSymbolInImage(dls->lib, | ||
717 | symbol, | ||
718 | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | ||
719 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | ||
720 | } | ||
721 | else if (NSIsSymbolNameDefined(symbol)) | ||
722 | { | ||
723 | debug("Searching dependencies"); | ||
724 | savedErrorStr = dyld_error_str(); | ||
725 | nssym = search_linked_libs(dls->lib, symbol); | ||
726 | } | ||
727 | } | ||
728 | else if (dls->module == MAGIC_DYLIB_MOD) | ||
729 | { | ||
730 | /* Global context, use NSLookupAndBindSymbol */ | ||
731 | if (NSIsSymbolNameDefined(symbol)) | ||
732 | { | ||
733 | /* There doesn't seem to be a return on error option for this call??? | ||
734 | this is potentially broken, if binding fails, it will improperly | ||
735 | exit the application. */ | ||
736 | nssym = NSLookupAndBindSymbol(symbol); | ||
737 | } | ||
738 | else | ||
739 | { | ||
740 | if (savedErrorStr) | ||
741 | SDL_free(savedErrorStr); | ||
742 | savedErrorStr = SDL_malloc(256); | ||
743 | SDL_snprintf(savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol); | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | /* Error reporting */ | ||
748 | if (!nssym) | ||
749 | { | ||
750 | if (!savedErrorStr || !SDL_strlen(savedErrorStr)) | ||
751 | { | ||
752 | if (savedErrorStr) | ||
753 | SDL_free(savedErrorStr); | ||
754 | savedErrorStr = SDL_malloc(256); | ||
755 | SDL_snprintf(savedErrorStr, 256,"Symbol \"%s\" not found",symbol); | ||
756 | } | ||
757 | if (canSetError) | ||
758 | { | ||
759 | error(savedErrorStr); | ||
760 | } | ||
761 | else | ||
762 | { | ||
763 | debug(savedErrorStr); | ||
764 | } | ||
765 | if (savedErrorStr) | ||
766 | SDL_free(savedErrorStr); | ||
767 | return NULL; | ||
768 | } | ||
769 | return NSAddressOfSymbol(nssym); | ||
770 | } | ||
771 | |||
772 | static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode) | ||
773 | { | ||
774 | NSObjectFileImage ofi = 0; | ||
775 | NSObjectFileImageReturnCode ofirc; | ||
776 | struct dlstatus *dls; | ||
777 | NSLinkEditErrors ler; | ||
778 | int lerno; | ||
779 | const char *errstr; | ||
780 | const char *file; | ||
781 | void (*init) (void); | ||
782 | |||
783 | ofirc = NSCreateObjectFileImageFromFile(path, &ofi); | ||
784 | switch (ofirc) | ||
785 | { | ||
786 | case NSObjectFileImageSuccess: | ||
787 | break; | ||
788 | case NSObjectFileImageInappropriateFile: | ||
789 | if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) | ||
790 | { | ||
791 | if (isFlagSet(mode, RTLD_LOCAL)) | ||
792 | { | ||
793 | warning("trying to open a .dylib with RTLD_LOCAL"); | ||
794 | error("unable to open this file with RTLD_LOCAL"); | ||
795 | return NULL; | ||
796 | } | ||
797 | } | ||
798 | else | ||
799 | { | ||
800 | error("opening this file is unsupported on this system"); | ||
801 | return NULL; | ||
802 | } | ||
803 | break; | ||
804 | case NSObjectFileImageFailure: | ||
805 | error("object file setup failure"); | ||
806 | return NULL; | ||
807 | case NSObjectFileImageArch: | ||
808 | error("no object for this architecture"); | ||
809 | return NULL; | ||
810 | case NSObjectFileImageFormat: | ||
811 | error("bad object file format"); | ||
812 | return NULL; | ||
813 | case NSObjectFileImageAccess: | ||
814 | error("can't read object file"); | ||
815 | return NULL; | ||
816 | default: | ||
817 | error("unknown error from NSCreateObjectFileImageFromFile()"); | ||
818 | return NULL; | ||
819 | } | ||
820 | dls = lookupStatus(sbuf); | ||
821 | if (!dls) | ||
822 | { | ||
823 | dls = allocStatus(); | ||
824 | } | ||
825 | if (!dls) | ||
826 | { | ||
827 | error("unable to allocate memory"); | ||
828 | return NULL; | ||
829 | } | ||
830 | // dls->lib = 0; | ||
831 | if (ofirc == NSObjectFileImageInappropriateFile) | ||
832 | { | ||
833 | if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) | ||
834 | { | ||
835 | debug("Dynamic lib loaded at %ld", dls->lib); | ||
836 | ofi = MAGIC_DYLIB_OFI; | ||
837 | dls->module = MAGIC_DYLIB_MOD; | ||
838 | ofirc = NSObjectFileImageSuccess; | ||
839 | /* Although it is possible with a bit of work to modify this so it works and | ||
840 | functions with RTLD_NOW, I don't deem it necessary at the moment */ | ||
841 | } | ||
842 | if (!(dls->module)) | ||
843 | { | ||
844 | NSLinkEditError(&ler, &lerno, &file, &errstr); | ||
845 | if (!errstr || (!SDL_strlen(errstr))) | ||
846 | error("Can't open this file type"); | ||
847 | else | ||
848 | error(errstr); | ||
849 | if ((dls->flags & DL_IN_LIST) == 0) | ||
850 | { | ||
851 | SDL_free(dls); | ||
852 | } | ||
853 | return NULL; | ||
854 | } | ||
855 | } | ||
856 | else | ||
857 | { | ||
858 | dls->module = NSLinkModule(ofi, path, | ||
859 | NSLINKMODULE_OPTION_RETURN_ON_ERROR | | ||
860 | NSLINKMODULE_OPTION_PRIVATE | | ||
861 | (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0)); | ||
862 | NSDestroyObjectFileImage(ofi); | ||
863 | if (dls->module) | ||
864 | { | ||
865 | dls->lib = get_mach_header_from_NSModule(dls->module); | ||
866 | } | ||
867 | } | ||
868 | if (!dls->module) | ||
869 | { | ||
870 | NSLinkEditError(&ler, &lerno, &file, &errstr); | ||
871 | if ((dls->flags & DL_IN_LIST) == 0) | ||
872 | { | ||
873 | SDL_free(dls); | ||
874 | } | ||
875 | error(errstr); | ||
876 | return NULL; | ||
877 | } | ||
878 | |||
879 | insertStatus(dls, sbuf); | ||
880 | dls = reference(dls, mode); | ||
881 | if ((init = dlsymIntern(dls, "__init", 0))) | ||
882 | { | ||
883 | debug("calling _init()"); | ||
884 | init(); | ||
885 | } | ||
886 | return dls; | ||
887 | } | ||
888 | |||
889 | inline static void dlcompat_init_check(void) | ||
890 | { | ||
891 | static pthread_mutex_t l = PTHREAD_MUTEX_INITIALIZER; | ||
892 | static int init_done = 0; | ||
893 | |||
894 | pthread_mutex_lock(&l); | ||
895 | if (!init_done) { | ||
896 | dlcompat_init_func(); | ||
897 | init_done = 1; | ||
898 | } | ||
899 | pthread_mutex_unlock(&l); | ||
900 | } | ||
901 | |||
902 | static void dlcompat_init_func(void) | ||
903 | { | ||
904 | _dyld_func_lookup("__dyld_NSAddImage", (void **)&dyld_NSAddImage); | ||
905 | _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", | ||
906 | (void **)&dyld_NSIsSymbolNameDefinedInImage); | ||
907 | _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void **)&dyld_NSLookupSymbolInImage); | ||
908 | if (pthread_mutex_init(&dlcompat_mutex, NULL)) | ||
909 | exit(1); | ||
910 | if (pthread_key_create(&dlerror_key, &dlerrorfree)) | ||
911 | exit(1); | ||
912 | } | ||
913 | |||
914 | static void resetdlerror() | ||
915 | { | ||
916 | struct dlthread *tss; | ||
917 | tss = pthread_getspecific(dlerror_key); | ||
918 | tss->errset = 0; | ||
919 | } | ||
920 | |||
921 | static void dlerrorfree(void *data) | ||
922 | { | ||
923 | SDL_free(data); | ||
924 | } | ||
925 | |||
926 | /* We kind of want a recursive lock here, but meet a little trouble | ||
927 | * because they are not available pre OS X 10.2, so we fake it | ||
928 | * using thread specific storage to keep a lock count | ||
929 | */ | ||
930 | static inline void dolock(void) | ||
931 | { | ||
932 | int err = 0; | ||
933 | struct dlthread *tss; | ||
934 | dlcompat_init_check(); | ||
935 | tss = pthread_getspecific(dlerror_key); | ||
936 | if (!tss) | ||
937 | { | ||
938 | tss = SDL_malloc(sizeof(struct dlthread)); | ||
939 | tss->lockcnt = 0; | ||
940 | tss->errset = 0; | ||
941 | if (pthread_setspecific(dlerror_key, tss)) | ||
942 | { | ||
943 | fprintf(stderr,"dlcompat: pthread_setspecific failed\n"); | ||
944 | exit(1); | ||
945 | } | ||
946 | } | ||
947 | if (!tss->lockcnt) | ||
948 | err = pthread_mutex_lock(&dlcompat_mutex); | ||
949 | tss->lockcnt = tss->lockcnt +1; | ||
950 | if (err) | ||
951 | exit(err); | ||
952 | } | ||
953 | |||
954 | static inline void dounlock(void) | ||
955 | { | ||
956 | int err = 0; | ||
957 | struct dlthread *tss; | ||
958 | tss = pthread_getspecific(dlerror_key); | ||
959 | tss->lockcnt = tss->lockcnt -1; | ||
960 | if (!tss->lockcnt) | ||
961 | err = pthread_mutex_unlock(&dlcompat_mutex); | ||
962 | if (err) | ||
963 | exit(err); | ||
964 | } | ||
965 | |||
966 | static void *SDL_OSX_dlopen(const char *path, int mode) | ||
967 | { | ||
968 | const struct stat *sbuf; | ||
969 | struct dlstatus *dls; | ||
970 | const char *fullPath; | ||
971 | |||
972 | dolock(); | ||
973 | resetdlerror(); | ||
974 | if (!path) | ||
975 | { | ||
976 | dls = &mainStatus; | ||
977 | goto dlopenok; | ||
978 | } | ||
979 | if (!(sbuf = findFile(path, &fullPath))) | ||
980 | { | ||
981 | error("file \"%s\" not found", path); | ||
982 | goto dlopenerror; | ||
983 | } | ||
984 | /* Now checks that it hasn't been closed already */ | ||
985 | if ((dls = lookupStatus(sbuf)) && (dls->refs > 0)) | ||
986 | { | ||
987 | /* debug("status found"); */ | ||
988 | dls = reference(dls, mode); | ||
989 | goto dlopenok; | ||
990 | } | ||
991 | #ifdef RTLD_NOLOAD | ||
992 | if (isFlagSet(mode, RTLD_NOLOAD)) | ||
993 | { | ||
994 | error("no existing handle and RTLD_NOLOAD specified"); | ||
995 | goto dlopenerror; | ||
996 | } | ||
997 | #endif | ||
998 | if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW)) | ||
999 | { | ||
1000 | error("how can I load something both RTLD_LAZY and RTLD_NOW?"); | ||
1001 | goto dlopenerror; | ||
1002 | } | ||
1003 | dls = loadModule(fullPath, sbuf, mode); | ||
1004 | |||
1005 | dlopenok: | ||
1006 | dounlock(); | ||
1007 | return (void *)dls; | ||
1008 | dlopenerror: | ||
1009 | dounlock(); | ||
1010 | return NULL; | ||
1011 | } | ||
1012 | |||
1013 | #if !FINK_BUILD | ||
1014 | static void *SDL_OSX_dlsym(void * dl_restrict handle, const char * dl_restrict symbol) | ||
1015 | { | ||
1016 | int sym_len = SDL_strlen(symbol); | ||
1017 | void *value = NULL; | ||
1018 | char *malloc_sym = NULL; | ||
1019 | dolock(); | ||
1020 | malloc_sym = SDL_malloc(sym_len + 2); | ||
1021 | if (malloc_sym) | ||
1022 | { | ||
1023 | SDL_snprintf(malloc_sym, sym_len+2, "_%s", symbol); | ||
1024 | value = dlsymIntern(handle, malloc_sym, 1); | ||
1025 | SDL_free(malloc_sym); | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | error("Unable to allocate memory"); | ||
1030 | goto dlsymerror; | ||
1031 | } | ||
1032 | dounlock(); | ||
1033 | return value; | ||
1034 | dlsymerror: | ||
1035 | dounlock(); | ||
1036 | return NULL; | ||
1037 | } | ||
1038 | #endif | ||
1039 | |||
1040 | #if FINK_BUILD | ||
1041 | |||
1042 | static void *dlsym_prepend_underscore(void *handle, const char *symbol) | ||
1043 | { | ||
1044 | void *answer; | ||
1045 | dolock(); | ||
1046 | answer = dlsym_prepend_underscore_intern(handle, symbol); | ||
1047 | dounlock(); | ||
1048 | return answer; | ||
1049 | } | ||
1050 | |||
1051 | static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol) | ||
1052 | { | ||
1053 | /* | ||
1054 | * A quick and easy way for porting packages which call dlsym(handle,"sym") | ||
1055 | * If the porter adds -Ddlsym=dlsym_prepend_underscore to the CFLAGS then | ||
1056 | * this function will be called, and will add the required underscore. | ||
1057 | * | ||
1058 | * Note that I haven't figured out yet which should be "standard", prepend | ||
1059 | * the underscore always, or not at all. These global functions need to go away | ||
1060 | * for opendarwin. | ||
1061 | */ | ||
1062 | int sym_len = SDL_strlen(symbol); | ||
1063 | void *value = NULL; | ||
1064 | char *malloc_sym = NULL; | ||
1065 | malloc_sym = SDL_malloc(sym_len + 2); | ||
1066 | if (malloc_sym) | ||
1067 | { | ||
1068 | SDL_snprintf(malloc_sym, sym_len+2, "_%s", symbol); | ||
1069 | value = dlsymIntern(handle, malloc_sym, 1); | ||
1070 | SDL_free(malloc_sym); | ||
1071 | } | ||
1072 | else | ||
1073 | { | ||
1074 | error("Unable to allocate memory"); | ||
1075 | } | ||
1076 | return value; | ||
1077 | } | ||
1078 | |||
1079 | static void *dlsym_auto_underscore(void *handle, const char *symbol) | ||
1080 | { | ||
1081 | void *answer; | ||
1082 | dolock(); | ||
1083 | answer = dlsym_auto_underscore_intern(handle, symbol); | ||
1084 | dounlock(); | ||
1085 | return answer; | ||
1086 | |||
1087 | } | ||
1088 | static void *dlsym_auto_underscore_intern(void *handle, const char *symbol) | ||
1089 | { | ||
1090 | struct dlstatus *dls = handle; | ||
1091 | void *addr = 0; | ||
1092 | addr = dlsymIntern(dls, symbol, 0); | ||
1093 | if (!addr) | ||
1094 | addr = dlsym_prepend_underscore_intern(handle, symbol); | ||
1095 | return addr; | ||
1096 | } | ||
1097 | |||
1098 | |||
1099 | static void *SDL_OSX_dlsym(void * dl_restrict handle, const char * dl_restrict symbol) | ||
1100 | { | ||
1101 | struct dlstatus *dls = handle; | ||
1102 | void *addr = 0; | ||
1103 | dolock(); | ||
1104 | addr = dlsymIntern(dls, symbol, 1); | ||
1105 | dounlock(); | ||
1106 | return addr; | ||
1107 | } | ||
1108 | #endif | ||
1109 | |||
1110 | static int SDL_OSX_dlclose(void *handle) | ||
1111 | { | ||
1112 | struct dlstatus *dls = handle; | ||
1113 | dolock(); | ||
1114 | resetdlerror(); | ||
1115 | if (!isValidStatus(dls)) | ||
1116 | { | ||
1117 | goto dlcloseerror; | ||
1118 | } | ||
1119 | if (dls->module == MAGIC_DYLIB_MOD) | ||
1120 | { | ||
1121 | const char *name; | ||
1122 | if (!dls->lib) | ||
1123 | { | ||
1124 | name = "global context"; | ||
1125 | } | ||
1126 | else | ||
1127 | { | ||
1128 | name = get_lib_name(dls->lib); | ||
1129 | } | ||
1130 | warning("trying to close a .dylib!"); | ||
1131 | error("Not closing \"%s\" - dynamic libraries cannot be closed", name); | ||
1132 | goto dlcloseerror; | ||
1133 | } | ||
1134 | if (!dls->module) | ||
1135 | { | ||
1136 | error("module already closed"); | ||
1137 | goto dlcloseerror; | ||
1138 | } | ||
1139 | |||
1140 | if (dls->refs == 1) | ||
1141 | { | ||
1142 | unsigned long options = 0; | ||
1143 | void (*fini) (void); | ||
1144 | if ((fini = dlsymIntern(dls, "__fini", 0))) | ||
1145 | { | ||
1146 | debug("calling _fini()"); | ||
1147 | fini(); | ||
1148 | } | ||
1149 | options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; | ||
1150 | #ifdef RTLD_NODELETE | ||
1151 | if (isFlagSet(dls->mode, RTLD_NODELETE)) | ||
1152 | options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; | ||
1153 | #endif | ||
1154 | if (!NSUnLinkModule(dls->module, options)) | ||
1155 | { | ||
1156 | error("unable to unlink module"); | ||
1157 | goto dlcloseerror; | ||
1158 | } | ||
1159 | dls->refs--; | ||
1160 | dls->module = 0; | ||
1161 | /* Note: the dlstatus struct dls is neither removed from the list | ||
1162 | * nor is the memory it occupies freed. This shouldn't pose a | ||
1163 | * problem in mostly all cases, though. | ||
1164 | */ | ||
1165 | } | ||
1166 | dounlock(); | ||
1167 | return 0; | ||
1168 | dlcloseerror: | ||
1169 | dounlock(); | ||
1170 | return 1; | ||
1171 | } | ||
1172 | |||
1173 | static const char *SDL_OSX_dlerror(void) | ||
1174 | { | ||
1175 | struct dlthread *tss; | ||
1176 | const char * err_str = NULL; | ||
1177 | dlcompat_init_check(); | ||
1178 | tss = pthread_getspecific(dlerror_key); | ||
1179 | if (tss != NULL && tss->errset != 0) { | ||
1180 | tss->errset = 0; | ||
1181 | err_str = tss->errstr; | ||
1182 | } | ||
1183 | return (err_str); | ||
1184 | } | ||
1185 | |||
1186 | /* Given an address, return the mach_header for the image containing it | ||
1187 | * or zero if the given address is not contained in any loaded images. | ||
1188 | */ | ||
1189 | static const struct mach_header *image_for_address(const void *address) | ||
1190 | { | ||
1191 | unsigned long i; | ||
1192 | unsigned long j; | ||
1193 | unsigned long count = _dyld_image_count(); | ||
1194 | const struct mach_header *mh = 0; | ||
1195 | struct load_command *lc = 0; | ||
1196 | unsigned long addr = 0; | ||
1197 | for (i = 0; i < count; i++) | ||
1198 | { | ||
1199 | addr = (unsigned long)address - _dyld_get_image_vmaddr_slide(i); | ||
1200 | mh = _dyld_get_image_header(i); | ||
1201 | if (mh) | ||
1202 | { | ||
1203 | lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); | ||
1204 | for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | ||
1205 | { | ||
1206 | if (LC_SEGMENT == lc->cmd && | ||
1207 | addr >= ((struct segment_command *)lc)->vmaddr && | ||
1208 | addr < | ||
1209 | ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) | ||
1210 | { | ||
1211 | goto image_found; | ||
1212 | } | ||
1213 | } | ||
1214 | } | ||
1215 | mh = 0; | ||
1216 | } | ||
1217 | image_found: | ||
1218 | return mh; | ||
1219 | } | ||
1220 | |||
1221 | #if 0 /* unused */ | ||
1222 | static int SDL_OSX_dladdr(const void * dl_restrict p, SDL_OSX_Dl_info * dl_restrict info) | ||
1223 | { | ||
1224 | /* | ||
1225 | FIXME: USe the routine image_for_address. | ||
1226 | */ | ||
1227 | unsigned long i; | ||
1228 | unsigned long j; | ||
1229 | unsigned long count = _dyld_image_count(); | ||
1230 | struct mach_header *mh = 0; | ||
1231 | struct load_command *lc = 0; | ||
1232 | unsigned long addr = NULL; | ||
1233 | unsigned long table_off = (unsigned long)0; | ||
1234 | int found = 0; | ||
1235 | if (!info) | ||
1236 | return 0; | ||
1237 | dolock(); | ||
1238 | resetdlerror(); | ||
1239 | info->dli_fname = 0; | ||
1240 | info->dli_fbase = 0; | ||
1241 | info->dli_sname = 0; | ||
1242 | info->dli_saddr = 0; | ||
1243 | /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com> | ||
1244 | * to darwin-development AT lists DOT apple DOT com and slightly modified | ||
1245 | */ | ||
1246 | for (i = 0; i < count; i++) | ||
1247 | { | ||
1248 | addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i); | ||
1249 | mh = _dyld_get_image_header(i); | ||
1250 | if (mh) | ||
1251 | { | ||
1252 | lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); | ||
1253 | for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | ||
1254 | { | ||
1255 | if (LC_SEGMENT == lc->cmd && | ||
1256 | addr >= ((struct segment_command *)lc)->vmaddr && | ||
1257 | addr < | ||
1258 | ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) | ||
1259 | { | ||
1260 | info->dli_fname = _dyld_get_image_name(i); | ||
1261 | info->dli_fbase = (void *)mh; | ||
1262 | found = 1; | ||
1263 | break; | ||
1264 | } | ||
1265 | } | ||
1266 | if (found) | ||
1267 | break; | ||
1268 | } | ||
1269 | } | ||
1270 | if (!found) | ||
1271 | { | ||
1272 | dounlock(); | ||
1273 | return 0; | ||
1274 | } | ||
1275 | lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); | ||
1276 | for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | ||
1277 | { | ||
1278 | if (LC_SEGMENT == lc->cmd) | ||
1279 | { | ||
1280 | if (!SDL_strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT")) | ||
1281 | break; | ||
1282 | } | ||
1283 | } | ||
1284 | table_off = | ||
1285 | ((unsigned long)((struct segment_command *)lc)->vmaddr) - | ||
1286 | ((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i); | ||
1287 | debug("table off %x", table_off); | ||
1288 | |||
1289 | lc = (struct load_command *)((char *)mh + sizeof(struct mach_header)); | ||
1290 | for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) | ||
1291 | { | ||
1292 | if (LC_SYMTAB == lc->cmd) | ||
1293 | { | ||
1294 | |||
1295 | struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off); | ||
1296 | unsigned long numsyms = ((struct symtab_command *)lc)->nsyms; | ||
1297 | struct nlist *nearest = NULL; | ||
1298 | unsigned long diff = 0xffffffff; | ||
1299 | unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off); | ||
1300 | debug("symtable %x", symtable); | ||
1301 | for (i = 0; i < numsyms; i++) | ||
1302 | { | ||
1303 | /* Ignore the following kinds of Symbols */ | ||
1304 | if ((!symtable->n_value) /* Undefined */ | ||
1305 | || (symtable->n_type >= N_PEXT) /* Debug symbol */ | ||
1306 | || (!(symtable->n_type & N_EXT)) /* Local Symbol */ | ||
1307 | ) | ||
1308 | { | ||
1309 | symtable++; | ||
1310 | continue; | ||
1311 | } | ||
1312 | if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr))) | ||
1313 | { | ||
1314 | diff = (unsigned long)symtable->n_value - addr; | ||
1315 | nearest = symtable; | ||
1316 | } | ||
1317 | symtable++; | ||
1318 | } | ||
1319 | if (nearest) | ||
1320 | { | ||
1321 | info->dli_saddr = nearest->n_value + ((void *)p - addr); | ||
1322 | info->dli_sname = (char *)(strtable + nearest->n_un.n_strx); | ||
1323 | } | ||
1324 | } | ||
1325 | } | ||
1326 | dounlock(); | ||
1327 | return 1; | ||
1328 | } | ||
1329 | #endif | ||
1330 | |||
1331 | /* | ||
1332 | * Implement the dlfunc() interface, which behaves exactly the same as | ||
1333 | * dlsym() except that it returns a function pointer instead of a data | ||
1334 | * pointer. This can be used by applications to avoid compiler warnings | ||
1335 | * about undefined behavior, and is intended as prior art for future | ||
1336 | * POSIX standardization. This function requires that all pointer types | ||
1337 | * have the same representation, which is true on all platforms FreeBSD | ||
1338 | * runs on, but is not guaranteed by the C standard. | ||
1339 | */ | ||
1340 | #if 0 | ||
1341 | static dlfunc_t SDL_OSX_dlfunc(void * dl_restrict handle, const char * dl_restrict symbol) | ||
1342 | { | ||
1343 | union | ||
1344 | { | ||
1345 | void *d; | ||
1346 | dlfunc_t f; | ||
1347 | } rv; | ||
1348 | int sym_len = SDL_strlen(symbol); | ||
1349 | char *malloc_sym = NULL; | ||
1350 | dolock(); | ||
1351 | malloc_sym = SDL_malloc(sym_len + 2); | ||
1352 | if (malloc_sym) | ||
1353 | { | ||
1354 | SDL_snprintf(malloc_sym, sym_len+2, "_%s", symbol); | ||
1355 | rv.d = dlsymIntern(handle, malloc_sym, 1); | ||
1356 | SDL_free(malloc_sym); | ||
1357 | } | ||
1358 | else | ||
1359 | { | ||
1360 | error("Unable to allocate memory"); | ||
1361 | goto dlfuncerror; | ||
1362 | } | ||
1363 | dounlock(); | ||
1364 | return rv.f; | ||
1365 | dlfuncerror: | ||
1366 | dounlock(); | ||
1367 | return NULL; | ||
1368 | } | ||
1369 | #endif | ||
1370 | |||
1371 | |||
1372 | |||
1373 | /* dlcompat ends, here's the SDL interface... --ryan. */ | ||
1374 | |||
1375 | |||
1376 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1377 | /* System dependent library loading routines */ | ||
1378 | |||
1379 | #include "SDL_loadso.h" | ||
1380 | |||
1381 | void *SDL_LoadObject(const char *sofile) | ||
1382 | { | ||
1383 | void *handle = SDL_OSX_dlopen(sofile, RTLD_NOW); | ||
1384 | const char *loaderror = SDL_OSX_dlerror(); | ||
1385 | if ( handle == NULL ) { | ||
1386 | SDL_SetError("Failed loading %s: %s", sofile, loaderror); | ||
1387 | } | ||
1388 | return(handle); | ||
1389 | } | ||
1390 | |||
1391 | void *SDL_LoadFunction(void *handle, const char *name) | ||
1392 | { | ||
1393 | void *symbol = SDL_OSX_dlsym(handle, name); | ||
1394 | if ( symbol == NULL ) { | ||
1395 | SDL_SetError("Failed loading %s: %s", name, SDL_OSX_dlerror()); | ||
1396 | } | ||
1397 | return(symbol); | ||
1398 | } | ||
1399 | |||
1400 | void SDL_UnloadObject(void *handle) | ||
1401 | { | ||
1402 | if ( handle != NULL ) { | ||
1403 | SDL_OSX_dlclose(handle); | ||
1404 | } | ||
1405 | } | ||
1406 | |||
1407 | #endif /* SDL_LOADSO_DLCOMPAT */ | ||
diff --git a/apps/plugins/sdl/src/loadso/mint/SDL_sysloadso.c b/apps/plugins/sdl/src/loadso/mint/SDL_sysloadso.c deleted file mode 100644 index d6dd732ca8..0000000000 --- a/apps/plugins/sdl/src/loadso/mint/SDL_sysloadso.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_LDG | ||
25 | |||
26 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
27 | /* System dependent library loading routines */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #include <gem.h> | ||
31 | #include <ldg.h> | ||
32 | |||
33 | #include "SDL_loadso.h" | ||
34 | |||
35 | void *SDL_LoadObject(const char *sofile) | ||
36 | { | ||
37 | const char *loaderror = "Unknown error"; | ||
38 | void *handle = (void *)ldg_open((char *)sofile, ldg_global); | ||
39 | if ( handle == NULL ) { | ||
40 | SDL_SetError("Failed loading %s: %s", sofile, loaderror); | ||
41 | } | ||
42 | return(handle); | ||
43 | } | ||
44 | |||
45 | void *SDL_LoadFunction(void *handle, const char *name) | ||
46 | { | ||
47 | const char *loaderror = "Unknown error"; | ||
48 | void *symbol = (void *)ldg_find((char *)name, (LDG *)handle); | ||
49 | if ( symbol == NULL ) { | ||
50 | SDL_SetError("Failed loading %s: %s", name, loaderror); | ||
51 | } | ||
52 | return(symbol); | ||
53 | } | ||
54 | |||
55 | void SDL_UnloadObject(void *handle) | ||
56 | { | ||
57 | if ( handle != NULL ) { | ||
58 | ldg_close((LDG *)handle, ldg_global); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | #endif /* SDL_LOADSO_LDG */ | ||
diff --git a/apps/plugins/sdl/src/loadso/os2/SDL_sysloadso.c b/apps/plugins/sdl/src/loadso/os2/SDL_sysloadso.c deleted file mode 100644 index 62ea536dd0..0000000000 --- a/apps/plugins/sdl/src/loadso/os2/SDL_sysloadso.c +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_OS2 | ||
25 | |||
26 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
27 | /* System dependent library loading routines */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #define INCL_DOSERRORS | ||
31 | #define INCL_DOSMODULEMGR | ||
32 | #include <os2.h> | ||
33 | |||
34 | #include "SDL_loadso.h" | ||
35 | |||
36 | void *SDL_LoadObject(const char *sofile) | ||
37 | { | ||
38 | HMODULE handle = NULL; | ||
39 | char buf[512]; | ||
40 | APIRET ulrc = DosLoadModule(buf, sizeof (buf), (char *) sofile, &handle); | ||
41 | |||
42 | /* Generate an error message if all loads failed */ | ||
43 | if ((ulrc != NO_ERROR) || (handle == NULL)) | ||
44 | SDL_SetError("Failed loading %s: %s", sofile, buf); | ||
45 | |||
46 | return((void *) handle); | ||
47 | } | ||
48 | |||
49 | void *SDL_LoadFunction(void *handle, const char *name) | ||
50 | { | ||
51 | const char *loaderror = "Unknown error"; | ||
52 | void *symbol = NULL; | ||
53 | APIRET ulrc = DosQueryProcAddr((HMODULE)handle, 0, (char *)name, &symbol); | ||
54 | if (ulrc == ERROR_INVALID_HANDLE) | ||
55 | loaderror = "Invalid module handle"; | ||
56 | else if (ulrc == ERROR_INVALID_NAME) | ||
57 | loaderror = "Symbol not found"; | ||
58 | |||
59 | if (symbol == NULL) | ||
60 | SDL_SetError("Failed loading %s: %s", name, loaderror); | ||
61 | |||
62 | return(symbol); | ||
63 | } | ||
64 | |||
65 | void SDL_UnloadObject(void *handle) | ||
66 | { | ||
67 | if ( handle != NULL ) | ||
68 | DosFreeModule((HMODULE) handle); | ||
69 | } | ||
70 | |||
71 | #endif /* SDL_LOADSO_OS2 */ | ||
diff --git a/apps/plugins/sdl/src/loadso/win32/SDL_sysloadso.c b/apps/plugins/sdl/src/loadso/win32/SDL_sysloadso.c deleted file mode 100644 index 784c7e7786..0000000000 --- a/apps/plugins/sdl/src/loadso/win32/SDL_sysloadso.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_LOADSO_WIN32 | ||
25 | |||
26 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
27 | /* System dependent library loading routines */ | ||
28 | |||
29 | #define WIN32_LEAN_AND_MEAN | ||
30 | #include <windows.h> | ||
31 | |||
32 | #include "SDL_loadso.h" | ||
33 | |||
34 | void *SDL_LoadObject(const char *sofile) | ||
35 | { | ||
36 | void *handle = NULL; | ||
37 | const char *loaderror = "Unknown error"; | ||
38 | |||
39 | #if defined(_WIN32_WCE) | ||
40 | char errbuf[512]; | ||
41 | |||
42 | wchar_t *errbuf_t = SDL_malloc(512 * sizeof(wchar_t)); | ||
43 | wchar_t *sofile_t = SDL_malloc((MAX_PATH+1) * sizeof(wchar_t)); | ||
44 | |||
45 | MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, MAX_PATH); | ||
46 | handle = (void *)LoadLibrary(sofile_t); | ||
47 | |||
48 | /* Generate an error message if all loads failed */ | ||
49 | if ( handle == NULL ) { | ||
50 | FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | | ||
51 | FORMAT_MESSAGE_FROM_SYSTEM), | ||
52 | NULL, GetLastError(), | ||
53 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
54 | errbuf_t, SDL_arraysize(errbuf), NULL); | ||
55 | WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); | ||
56 | loaderror = errbuf; | ||
57 | } | ||
58 | |||
59 | SDL_free(sofile_t); | ||
60 | SDL_free(errbuf_t); | ||
61 | |||
62 | #else /*if defined(__WIN32__)*/ | ||
63 | char errbuf[512]; | ||
64 | |||
65 | handle = (void *)LoadLibrary(sofile); | ||
66 | |||
67 | /* Generate an error message if all loads failed */ | ||
68 | if ( handle == NULL ) { | ||
69 | FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | | ||
70 | FORMAT_MESSAGE_FROM_SYSTEM), | ||
71 | NULL, GetLastError(), | ||
72 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
73 | errbuf, SDL_arraysize(errbuf), NULL); | ||
74 | loaderror = errbuf; | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | if ( handle == NULL ) { | ||
79 | SDL_SetError("Failed loading %s: %s", sofile, loaderror); | ||
80 | } | ||
81 | return(handle); | ||
82 | } | ||
83 | |||
84 | void *SDL_LoadFunction(void *handle, const char *name) | ||
85 | { | ||
86 | void *symbol = NULL; | ||
87 | const char *loaderror = "Unknown error"; | ||
88 | |||
89 | #if defined(_WIN32_WCE) | ||
90 | char errbuf[512]; | ||
91 | int length = SDL_strlen(name); | ||
92 | |||
93 | wchar_t *name_t = SDL_malloc((length + 1) * sizeof(wchar_t)); | ||
94 | wchar_t *errbuf_t = SDL_malloc(512 * sizeof(wchar_t)); | ||
95 | |||
96 | MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length+1); | ||
97 | |||
98 | symbol = (void *)GetProcAddress((HMODULE)handle, name_t); | ||
99 | if ( symbol == NULL ) { | ||
100 | FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | | ||
101 | FORMAT_MESSAGE_FROM_SYSTEM), | ||
102 | NULL, GetLastError(), | ||
103 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
104 | errbuf_t, SDL_arraysize(errbuf), NULL); | ||
105 | WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); | ||
106 | loaderror = errbuf; | ||
107 | } | ||
108 | |||
109 | SDL_free(name_t); | ||
110 | SDL_free(errbuf_t); | ||
111 | |||
112 | #else /*if defined(WIN32)*/ | ||
113 | char errbuf[512]; | ||
114 | |||
115 | symbol = (void *)GetProcAddress((HMODULE)handle, name); | ||
116 | if ( symbol == NULL ) { | ||
117 | FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | | ||
118 | FORMAT_MESSAGE_FROM_SYSTEM), | ||
119 | NULL, GetLastError(), | ||
120 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
121 | errbuf, SDL_arraysize(errbuf), NULL); | ||
122 | loaderror = errbuf; | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | if ( symbol == NULL ) { | ||
127 | SDL_SetError("Failed loading %s: %s", name, loaderror); | ||
128 | } | ||
129 | return(symbol); | ||
130 | } | ||
131 | |||
132 | void SDL_UnloadObject(void *handle) | ||
133 | { | ||
134 | if ( handle != NULL ) { | ||
135 | FreeLibrary((HMODULE)handle); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | #endif /* SDL_LOADSO_WIN32 */ | ||