annotate src/loadso/macosx/SDL_loadso.c @ 1207:c9ec00d3e8bc

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