Split up src/SDL_loadso.c into platform directories.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 17 Nov 2005 03:15:05 +0000
changeset 1173e9cf8c1b4590
parent 1172 f69f4d25fb20
child 1174 8c43aceeed81
Split up src/SDL_loadso.c into platform directories.
configure.in
src/SDL_loadso.c
src/loadso/beos/SDL_loadso.c
src/loadso/dlopen/SDL_loadso.c
src/loadso/dummy/SDL_loadso.c
src/loadso/macos/SDL_loadso.c
src/loadso/macosx/SDL_loadso.c
src/loadso/mint/SDL_loadso.c
src/loadso/windows/SDL_loadso.c
     1.1 --- a/configure.in	Thu Nov 17 03:04:47 2005 +0000
     1.2 +++ b/configure.in	Thu Nov 17 03:15:05 2005 +0000
     1.3 @@ -304,11 +304,11 @@
     1.4              alsa_lib=`ls $alsa_lib_spec | sed 's/.*\/\(.*\)/\1/; q'`
     1.5              echo "-- $alsa_lib_spec -> $alsa_lib"
     1.6  
     1.7 -            if test x$use_dlopen != xyes && \
     1.8 +            if test x$have_loadso != xyes && \
     1.9                 test x$enable_alsa_shared = xyes; then
    1.10 -                AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option])
    1.11 +                AC_MSG_ERROR([You must have SDL_LoadObject() support])
    1.12              fi
    1.13 -            if test x$use_dlopen = xyes && \
    1.14 +            if test x$have_loadso = xyes && \
    1.15                 test x$enable_alsa_shared = xyes && test x$alsa_lib != x; then
    1.16                  CFLAGS="$CFLAGS -DALSA_SUPPORT -DALSA_DYNAMIC=\$(alsa_lib) $ALSA_CFLAGS"
    1.17                  AC_SUBST(alsa_lib)
    1.18 @@ -367,11 +367,11 @@
    1.19              esd_lib_spec=`echo $ESD_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libesd.so.*/'`
    1.20              esd_lib=`ls $esd_lib_spec | sed 's/.*\/\(.*\)/\1/; q'`
    1.21              echo "-- $esd_lib_spec -> $esd_lib"
    1.22 -            if test x$use_dlopen != xyes && \
    1.23 +            if test x$have_loadso != xyes && \
    1.24                 test x$enable_esd_shared = xyes; then
    1.25 -                AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option])
    1.26 +                AC_MSG_ERROR([You must have SDL_LoadObject() support])
    1.27              fi
    1.28 -            if test x$use_dlopen = xyes && \
    1.29 +            if test x$have_loadso = xyes && \
    1.30                 test x$enable_esd_shared = xyes && test x$esd_lib != x; then
    1.31                  CFLAGS="$CFLAGS -DESD_SUPPORT -DESD_DYNAMIC=\$(esd_lib) $ESD_CFLAGS"
    1.32                  AC_SUBST(esd_lib)
    1.33 @@ -418,11 +418,11 @@
    1.34                  arts_lib_spec="$ARTSC_PREFIX/lib/libartsc.so.*"
    1.35                  arts_lib=`ls $arts_lib_spec | sed 's/.*\/\(.*\)/\1/; q'`
    1.36                  echo "-- $arts_lib_spec -> $arts_lib"
    1.37 -                if test x$use_dlopen != xyes && \
    1.38 +                if test x$have_loadso != xyes && \
    1.39                     test x$enable_arts_shared = xyes; then
    1.40 -                    AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option])
    1.41 +                    AC_MSG_ERROR([You must have SDL_LoadObject() support])
    1.42                  fi
    1.43 -                if test x$use_dlopen = xyes && \
    1.44 +                if test x$have_loadso = xyes && \
    1.45                     test x$enable_arts_shared = xyes && test x$arts_lib != x; then
    1.46                      CFLAGS="$CFLAGS -DARTSC_SUPPORT -DARTSC_DYNAMIC=\$(arts_lib) $ARTSC_CFLAGS"
    1.47                      AC_SUBST(arts_lib)
    1.48 @@ -617,12 +617,12 @@
    1.49              x11_lib='libX11.so.6'
    1.50              x11ext_lib='libXext.so.6'
    1.51  
    1.52 -            if test x$use_dlopen != xyes && \
    1.53 +            if test x$have_loadso != xyes && \
    1.54                 test x$enable_x11_shared = xyes; then
    1.55 -                AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option])
    1.56 +                AC_MSG_ERROR([You must have SDL_LoadObject() support])
    1.57              fi
    1.58  
    1.59 -            if test x$use_dlopen = xyes && \
    1.60 +            if test x$have_loadso = xyes && \
    1.61                 test x$enable_x11_shared = xyes && test x$x11_lib != x && test x$x11ext_lib != x; then
    1.62                  CFLAGS="$CFLAGS $X_CFLAGS -DENABLE_X11 -DXTHREADS -DX11_DYNAMIC=\$(x11_lib) -DX11EXT_DYNAMIC=\$(x11ext_lib) -I$srcdir/include -I$srcdir/src/video"
    1.63                  SYSTEM_LIBS="$SYSTEM_LIBS $X_LIBS"
    1.64 @@ -1131,7 +1131,7 @@
    1.65          AC_MSG_RESULT($video_opengl)
    1.66          if test x$video_opengl = xyes; then
    1.67              CFLAGS="$CFLAGS -DHAVE_OPENGL"
    1.68 -            if test x$use_dlopen != xyes; then
    1.69 +            if test x$have_loadso != xyes; then
    1.70                  AC_CHECK_LIB(dl, dlopen, SYSTEM_LIBS="$SYSTEM_LIBS -ldl")
    1.71              fi
    1.72          fi
    1.73 @@ -1154,7 +1154,7 @@
    1.74          if test x$video_opengl = xyes; then
    1.75              CFLAGS="$CFLAGS -DHAVE_OPENGL"
    1.76              SYSTEM_LIBS="$SYSTEM_LIBS -lGL"
    1.77 -            if test x$use_dlopen != xyes; then
    1.78 +            if test x$have_loadso != xyes; then
    1.79                  AC_CHECK_LIB(c, dlopen, SYSTEM_LIBS="$SYSTEM_LIBS", AC_CHECK_LIB(ltdl, dlopen, SYSTEM_LIBS="$SYSTEM_LIBS -lltdl"))
    1.80              fi
    1.81          fi
    1.82 @@ -1778,16 +1778,16 @@
    1.83                    , enable_sdl_dlopen=yes)
    1.84      if test x$enable_sdl_dlopen = xyes; then
    1.85          AC_MSG_CHECKING(for dlopen)
    1.86 -        use_dlopen=no
    1.87 +        have_loadso=no
    1.88          AC_TRY_COMPILE([
    1.89           #include <dlfcn.h>
    1.90          ],[
    1.91          ],[
    1.92 -        use_dlopen=yes
    1.93 +        have_loadso=yes
    1.94          ])
    1.95 -        AC_MSG_RESULT($use_dlopen)
    1.96 +        AC_MSG_RESULT($have_loadso)
    1.97  
    1.98 -        if test x$use_dlopen = xyes; then
    1.99 +        if test x$have_loadso = xyes; then
   1.100              CFLAGS="$CFLAGS -DUSE_DLOPEN"
   1.101              AC_CHECK_LIB(c, dlopen, SYSTEM_LIBS="$SYSTEM_LIBS",
   1.102                 AC_CHECK_LIB(dl, dlopen, SYSTEM_LIBS="$SYSTEM_LIBS -ldl",
   1.103 @@ -1806,6 +1806,7 @@
   1.104          AC_CHECK_HEADER(ldg.h, have_ldg_hdr=yes)
   1.105          AC_CHECK_LIB(ldg, ldg_open, have_ldg_lib=yes, have_ldg_lib=no, -lgem)
   1.106          if test x$have_ldg_hdr = xyes -a x$have_ldg_lib = xyes; then
   1.107 +            have_loadso=yes
   1.108              CFLAGS="$CFLAGS -DENABLE_LDG"
   1.109              SYSTEM_LIBS="$SYSTEM_LIBS -lldg -lgem"
   1.110          fi
   1.111 @@ -1989,6 +1990,7 @@
   1.112                    , enable_rpath=yes)
   1.113  }
   1.114  
   1.115 +have_loadso=no
   1.116  case "$target" in
   1.117      arm-*-elf*)
   1.118  	ARCH=linux
   1.119 @@ -2560,6 +2562,7 @@
   1.120          ;;
   1.121      *-*-cygwin* | *-*-mingw32*)
   1.122          ARCH=win32
   1.123 +        have_loadso=yes
   1.124          if test "$build" != "$target"; then # cross-compiling
   1.125              # Default cross-compile location
   1.126              ac_default_prefix=/usr/local/cross-tools/i386-mingw32msvc
   1.127 @@ -2625,6 +2628,7 @@
   1.128      *-*-beos*)
   1.129          ARCH=beos
   1.130          ac_default_prefix=/boot/develop/tools/gnupro
   1.131 +        have_loadso=yes
   1.132          CheckDummyVideo
   1.133          CheckDiskAudio
   1.134          CheckNASM
   1.135 @@ -2668,6 +2672,7 @@
   1.136          # use it at present, but Apple is working on a X-to-9 compiler
   1.137          # for which this case would be handy.
   1.138          ARCH=macos
   1.139 +        have_loadso=yes
   1.140          CheckDummyVideo
   1.141          CheckDiskAudio
   1.142          CheckTOOLBOX
   1.143 @@ -2711,6 +2716,7 @@
   1.144          # just the OS X kernel sans upper layers like Carbon and Cocoa.
   1.145          # Next line is broken, and a few files below require Mac OS X (full)
   1.146          ARCH=macosx
   1.147 +        have_loadso=yes
   1.148          CheckDummyVideo
   1.149          CheckDiskAudio
   1.150          CheckCOCOA
     2.1 --- a/src/SDL_loadso.c	Thu Nov 17 03:04:47 2005 +0000
     2.2 +++ b/src/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     2.3 @@ -28,234 +28,23 @@
     2.4  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
     2.5  /* System dependent library loading routines                           */
     2.6  
     2.7 -#include <stdio.h>
     2.8 -#if defined(USE_DLOPEN)
     2.9 -# include <dlfcn.h>
    2.10 +/* !!! FIXME: includes so I don't have to update all the project files... */
    2.11 +#define SDL_INTERNAL_BUILDING_LOADSO 1
    2.12 +#if defined(USE_DUMMY_LOADSO)
    2.13 +# include "loadso/dummy/SDL_loadso.c"
    2.14 +#elif defined(MACOSX)
    2.15 +# include "loadso/macosx/SDL_loadso.c"
    2.16 +#elif defined(macintosh)
    2.17 +# include "loadso/macos/SDL_loadso.c"
    2.18 +#elif defined(USE_DLOPEN)
    2.19 +# include "loadso/dlopen/SDL_loadso.c"
    2.20  #elif defined(WIN32) || defined(_WIN32_WCE)
    2.21 -# include <windows.h>
    2.22 +# include "loadso/windows/SDL_loadso.c"
    2.23  #elif defined(__BEOS__)
    2.24 -# include <be/kernel/image.h>
    2.25 -#elif defined(macintosh)
    2.26 -# include <string.h>
    2.27 -#define OLDP2C 1
    2.28 -# include <Strings.h>
    2.29 -# include <CodeFragments.h>
    2.30 -# include <Errors.h>
    2.31 +# include "loadso/beos/SDL_loadso.c"
    2.32  #elif defined(__MINT__) && defined(ENABLE_LDG)
    2.33 -# include <gem.h>
    2.34 -# include <ldg.h>
    2.35 +# include "loadso/mint/SDL_loadso.c"
    2.36  #else
    2.37 -/*#error Unsupported dynamic link environment*/
    2.38 +# include "loadso/dummy/SDL_loadso.c"
    2.39  #endif /* system type */
    2.40  
    2.41 -#include "SDL_types.h"
    2.42 -#include "SDL_error.h"
    2.43 -#include "SDL_loadso.h"
    2.44 -
    2.45 -void *SDL_LoadObject(const char *sofile)
    2.46 -{
    2.47 -	void *handle = NULL;
    2.48 -	const char *loaderror = "SDL_LoadObject() not implemented";
    2.49 -#if defined(USE_DLOPEN)
    2.50 -/* * */
    2.51 -	handle = dlopen(sofile, RTLD_NOW);
    2.52 -	loaderror = (char *)dlerror();
    2.53 -#elif defined(_WIN32_WCE)
    2.54 -/* * */
    2.55 -	char errbuf[512];
    2.56 -
    2.57 -	wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t));
    2.58 -	wchar_t *sofile_t = malloc((MAX_PATH+1) * sizeof(wchar_t));
    2.59 -
    2.60 -	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, MAX_PATH);
    2.61 -	handle = (void *)LoadLibrary(sofile_t);
    2.62 -
    2.63 -	/* Generate an error message if all loads failed */
    2.64 -	if ( handle == NULL ) {
    2.65 -		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
    2.66 -					FORMAT_MESSAGE_FROM_SYSTEM),
    2.67 -				NULL, GetLastError(), 
    2.68 -				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    2.69 -				errbuf_t, SDL_TABLESIZE(errbuf), NULL);
    2.70 -		WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL);
    2.71 -		loaderror = errbuf;
    2.72 -	}
    2.73 -
    2.74 -	free(sofile_t);
    2.75 -	free(errbuf_t);
    2.76 -
    2.77 -#elif defined(WIN32)
    2.78 -/* * */
    2.79 -	char errbuf[512];
    2.80 -
    2.81 -	handle = (void *)LoadLibrary(sofile);
    2.82 -
    2.83 -	/* Generate an error message if all loads failed */
    2.84 -	if ( handle == NULL ) {
    2.85 -		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
    2.86 -					FORMAT_MESSAGE_FROM_SYSTEM),
    2.87 -				NULL, GetLastError(), 
    2.88 -				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    2.89 -				errbuf, SDL_TABLESIZE(errbuf), NULL);
    2.90 -		loaderror = errbuf;
    2.91 -	}
    2.92 -#elif defined(__BEOS__)
    2.93 -/* * */
    2.94 -	image_id library_id;
    2.95 -
    2.96 -	library_id = load_add_on(sofile);
    2.97 -	if ( library_id == B_ERROR ) {
    2.98 -		loaderror = "BeOS error";
    2.99 -	} else {
   2.100 -		handle = (void *)(library_id);
   2.101 -	}
   2.102 -#elif defined(macintosh)
   2.103 -/* * */
   2.104 -	CFragConnectionID library_id;
   2.105 -	Ptr mainAddr;
   2.106 -	Str255 errName;
   2.107 -	OSErr error;
   2.108 -	char psofile[512];
   2.109 -
   2.110 -	strncpy(psofile, sofile, SDL_TABLESIZE(psofile));
   2.111 -	psofile[SDL_TABLESIZE(psofile)-1] = '\0';
   2.112 -	error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch,
   2.113 -			kLoadCFrag, &library_id, &mainAddr, errName);
   2.114 -	switch (error) {
   2.115 -		case noErr:
   2.116 -			loaderror = NULL;
   2.117 -			break;
   2.118 -		case cfragNoLibraryErr:
   2.119 -			loaderror = "Library not found";
   2.120 -			break;
   2.121 -		case cfragUnresolvedErr:
   2.122 -			loaderror = "Unabled to resolve symbols";
   2.123 -			break;
   2.124 -		case cfragNoPrivateMemErr:
   2.125 -		case cfragNoClientMemErr:
   2.126 -			loaderror = "Out of memory";
   2.127 -			break;
   2.128 -		default:
   2.129 -			loaderror = "Unknown Code Fragment Manager error";
   2.130 -			break;
   2.131 -	}
   2.132 -	if ( loaderror == NULL ) {
   2.133 -		handle = (void *)(library_id);
   2.134 -	}
   2.135 -#elif defined(__MINT__) && defined(ENABLE_LDG)
   2.136 -/* * */
   2.137 -	handle = (void *)ldg_open((char *)sofile, ldg_global);
   2.138 -#endif /* system type */
   2.139 -
   2.140 -	if ( handle == NULL ) {
   2.141 -		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
   2.142 -	}
   2.143 -	return(handle);
   2.144 -}
   2.145 -
   2.146 -void *SDL_LoadFunction(void *handle, const char *name)
   2.147 -{
   2.148 -	void *symbol = NULL;
   2.149 -	const char *loaderror = "SDL_LoadFunction not implemented";
   2.150 -#if defined(USE_DLOPEN)
   2.151 -/* * */
   2.152 -	symbol = dlsym(handle, name);
   2.153 -	if ( symbol == NULL ) {
   2.154 -		loaderror = (char *)dlerror();
   2.155 -	}
   2.156 -#elif defined(_WIN32_WCE)
   2.157 -/* * */
   2.158 -	char errbuf[512];
   2.159 -	int length = strlen(name);
   2.160 -
   2.161 -	wchar_t *name_t = malloc((length + 1) * sizeof(wchar_t));
   2.162 -	wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t));
   2.163 -
   2.164 -	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length);
   2.165 -
   2.166 -	symbol = (void *)GetProcAddress((HMODULE)handle, name_t);
   2.167 -	if ( symbol == NULL ) {
   2.168 -		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
   2.169 -					FORMAT_MESSAGE_FROM_SYSTEM),
   2.170 -				NULL, GetLastError(), 
   2.171 -				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   2.172 -				errbuf_t, SDL_TABLESIZE(errbuf), NULL);
   2.173 -		WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL);
   2.174 -		loaderror = errbuf;
   2.175 -	}
   2.176 -
   2.177 -	free(name_t);
   2.178 -	free(errbuf_t);
   2.179 -
   2.180 -#elif defined(WIN32)
   2.181 -/* * */
   2.182 -	char errbuf[512];
   2.183 -
   2.184 -	symbol = (void *)GetProcAddress((HMODULE)handle, name);
   2.185 -	if ( symbol == NULL ) {
   2.186 -		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
   2.187 -					FORMAT_MESSAGE_FROM_SYSTEM),
   2.188 -				NULL, GetLastError(), 
   2.189 -				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   2.190 -				errbuf, SDL_TABLESIZE(errbuf), NULL);
   2.191 -		loaderror = errbuf;
   2.192 -	}
   2.193 -#elif defined(__BEOS__)
   2.194 -/* * */
   2.195 -	image_id library_id = (image_id)handle;
   2.196 -	if ( get_image_symbol(library_id,
   2.197 -		name, B_SYMBOL_TYPE_TEXT, &symbol) != B_NO_ERROR ) {
   2.198 -		loaderror = "Symbol not found";
   2.199 -	}
   2.200 -#elif defined(macintosh)
   2.201 -/* * */
   2.202 -	CFragSymbolClass class;
   2.203 -	CFragConnectionID library_id = (CFragConnectionID)handle;
   2.204 -	char pname[512];
   2.205 -
   2.206 -	strncpy(pname, name, SDL_TABLESIZE(pname));
   2.207 -	pname[SDL_TABLESIZE(pname)-1] = '\0';
   2.208 -	if ( FindSymbol(library_id, C2PStr(pname),
   2.209 -	                (char **)&symbol, &class) != noErr ) {
   2.210 -		loaderror = "Symbol not found";
   2.211 -	}
   2.212 -#elif defined(__MINT__) && defined(ENABLE_LDG)
   2.213 -/* * */
   2.214 -	symbol = (void *)ldg_find((char *)name, (LDG *)handle);
   2.215 -#endif /* system type */
   2.216 -
   2.217 -	if ( symbol == NULL ) {
   2.218 -		SDL_SetError("Failed loading %s: %s", name, loaderror);
   2.219 -	}
   2.220 -	return(symbol);
   2.221 -}
   2.222 -
   2.223 -void SDL_UnloadObject(void *handle)
   2.224 -{
   2.225 -#if defined(__BEOS__)
   2.226 -	image_id library_id;
   2.227 -#elif defined(macintosh)
   2.228 -	CFragConnectionID library_id;
   2.229 -#endif
   2.230 -	if ( handle == NULL ) {
   2.231 -		return;
   2.232 -	}
   2.233 -#if defined(USE_DLOPEN)
   2.234 -/* * */
   2.235 -	dlclose(handle);
   2.236 -#elif defined(WIN32)
   2.237 -/* * */
   2.238 -	FreeLibrary((HMODULE)handle);
   2.239 -#elif defined(__BEOS__)
   2.240 -/* * */
   2.241 -	library_id = (image_id)handle;
   2.242 -	unload_add_on(library_id);
   2.243 -#elif defined(macintosh)
   2.244 -/* * */
   2.245 -	library_id = (CFragConnectionID)handle;
   2.246 -	CloseConnection(&library_id);
   2.247 -#elif defined(__MINT__) && defined(ENABLE_LDG)
   2.248 -/* * */
   2.249 -	ldg_close((LDG *)handle, ldg_global);
   2.250 -#endif /* system type */
   2.251 -}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/loadso/beos/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     3.3 @@ -0,0 +1,87 @@
     3.4 +/*
     3.5 +    SDL - Simple DirectMedia Layer
     3.6 +    Copyright (C) 1997-2004 Sam Lantinga
     3.7 +
     3.8 +    This library is free software; you can redistribute it and/or
     3.9 +    modify it under the terms of the GNU Library General Public
    3.10 +    License as published by the Free Software Foundation; either
    3.11 +    version 2 of the License, or (at your option) any later version.
    3.12 +
    3.13 +    This library is distributed in the hope that it will be useful,
    3.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.16 +    Library General Public License for more details.
    3.17 +
    3.18 +    You should have received a copy of the GNU Library General Public
    3.19 +    License along with this library; if not, write to the Free
    3.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.21 +
    3.22 +    Sam Lantinga
    3.23 +    slouken@libsdl.org
    3.24 +*/
    3.25 +
    3.26 +#ifdef SAVE_RCSID
    3.27 +static char rcsid =
    3.28 + "@(#) $Id$";
    3.29 +#endif
    3.30 +
    3.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    3.32 +/* System dependent library loading routines                           */
    3.33 +
    3.34 +#if !SDL_INTERNAL_BUILDING_LOADSO
    3.35 +#error Do not compile directly...compile src/SDL_loadso.c instead!
    3.36 +#endif
    3.37 +
    3.38 +#if !defined(__BEOS__)
    3.39 +#error Compiling for the wrong platform?
    3.40 +#endif
    3.41 +
    3.42 +#include <stdio.h>
    3.43 +#include <be/kernel/image.h>
    3.44 +
    3.45 +#include "SDL_types.h"
    3.46 +#include "SDL_error.h"
    3.47 +#include "SDL_loadso.h"
    3.48 +
    3.49 +void *SDL_LoadObject(const char *sofile)
    3.50 +{
    3.51 +	void *handle = NULL;
    3.52 +	const char *loaderror = "Unknown error";
    3.53 +	image_id library_id = load_add_on(sofile);
    3.54 +	if ( library_id == B_ERROR ) {
    3.55 +		loaderror = "BeOS error";
    3.56 +	} else {
    3.57 +		handle = (void *)(library_id);
    3.58 +	}
    3.59 +
    3.60 +	if ( handle == NULL ) {
    3.61 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
    3.62 +	}
    3.63 +	return(handle);
    3.64 +}
    3.65 +
    3.66 +void *SDL_LoadFunction(void *handle, const char *name)
    3.67 +{
    3.68 +	void *symbol = NULL;
    3.69 +	const char *loaderror = "Unknown error";
    3.70 +	image_id library_id = (image_id)handle;
    3.71 +	if ( get_image_symbol(library_id,
    3.72 +		name, B_SYMBOL_TYPE_TEXT, &symbol) != B_NO_ERROR ) {
    3.73 +		loaderror = "Symbol not found";
    3.74 +	}
    3.75 +
    3.76 +	if ( symbol == NULL ) {
    3.77 +		SDL_SetError("Failed loading %s: %s", name, loaderror);
    3.78 +	}
    3.79 +	return(symbol);
    3.80 +}
    3.81 +
    3.82 +void SDL_UnloadObject(void *handle)
    3.83 +{
    3.84 +	image_id library_id;
    3.85 +	if ( handle != NULL ) {
    3.86 +		library_id = (image_id)handle;
    3.87 +		unload_add_on(library_id);
    3.88 +	}
    3.89 +}
    3.90 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/loadso/dlopen/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     4.3 @@ -0,0 +1,71 @@
     4.4 +/*
     4.5 +    SDL - Simple DirectMedia Layer
     4.6 +    Copyright (C) 1997-2004 Sam Lantinga
     4.7 +
     4.8 +    This library is free software; you can redistribute it and/or
     4.9 +    modify it under the terms of the GNU Library General Public
    4.10 +    License as published by the Free Software Foundation; either
    4.11 +    version 2 of the License, or (at your option) any later version.
    4.12 +
    4.13 +    This library is distributed in the hope that it will be useful,
    4.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 +    Library General Public License for more details.
    4.17 +
    4.18 +    You should have received a copy of the GNU Library General Public
    4.19 +    License along with this library; if not, write to the Free
    4.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.21 +
    4.22 +    Sam Lantinga
    4.23 +    slouken@libsdl.org
    4.24 +*/
    4.25 +
    4.26 +#ifdef SAVE_RCSID
    4.27 +static char rcsid =
    4.28 + "@(#) $Id$";
    4.29 +#endif
    4.30 +
    4.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    4.32 +/* System dependent library loading routines                           */
    4.33 +
    4.34 +#if !SDL_INTERNAL_BUILDING_LOADSO
    4.35 +#error Do not compile directly...compile src/SDL_loadso.c instead!
    4.36 +#endif
    4.37 +
    4.38 +#if !defined(USE_DLOPEN)
    4.39 +#error Compiling for the wrong platform?
    4.40 +#endif
    4.41 +
    4.42 +#include <stdio.h>
    4.43 +#include <dlfcn.h>
    4.44 +
    4.45 +#include "SDL_types.h"
    4.46 +#include "SDL_error.h"
    4.47 +#include "SDL_loadso.h"
    4.48 +
    4.49 +void *SDL_LoadObject(const char *sofile)
    4.50 +{
    4.51 +	void *handle = dlopen(sofile, RTLD_NOW);
    4.52 +	const char *loaderror = (char *)dlerror();
    4.53 +	if ( handle == NULL ) {
    4.54 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
    4.55 +	}
    4.56 +	return(handle);
    4.57 +}
    4.58 +
    4.59 +void *SDL_LoadFunction(void *handle, const char *name)
    4.60 +{
    4.61 +	void *symbol = dlsym(handle, name);
    4.62 +	if ( symbol == NULL ) {
    4.63 +		SDL_SetError("Failed loading %s: %s", name, (const char *)dlerror());
    4.64 +	}
    4.65 +	return(symbol);
    4.66 +}
    4.67 +
    4.68 +void SDL_UnloadObject(void *handle)
    4.69 +{
    4.70 +	if ( handle != NULL ) {
    4.71 +		dlclose(handle);
    4.72 +	}
    4.73 +}
    4.74 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/loadso/dummy/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     5.3 @@ -0,0 +1,57 @@
     5.4 +/*
     5.5 +    SDL - Simple DirectMedia Layer
     5.6 +    Copyright (C) 1997-2004 Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Library General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Library General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Library General Public
    5.19 +    License along with this library; if not, write to the Free
    5.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.21 +
    5.22 +    Sam Lantinga
    5.23 +    slouken@libsdl.org
    5.24 +*/
    5.25 +
    5.26 +#ifdef SAVE_RCSID
    5.27 +static char rcsid =
    5.28 + "@(#) $Id$";
    5.29 +#endif
    5.30 +
    5.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    5.32 +/* System dependent library loading routines                           */
    5.33 +
    5.34 +#if !SDL_INTERNAL_BUILDING_LOADSO
    5.35 +#error Do not compile directly...compile src/SDL_loadso.c instead!
    5.36 +#endif
    5.37 +
    5.38 +#include "SDL_types.h"
    5.39 +#include "SDL_error.h"
    5.40 +#include "SDL_loadso.h"
    5.41 +
    5.42 +void *SDL_LoadObject(const char *sofile)
    5.43 +{
    5.44 +	const char *loaderror = "SDL_LoadObject() not implemented";
    5.45 +	SDL_SetError("Failed loading %s: %s", sofile, loaderror);
    5.46 +	return(NULL);
    5.47 +}
    5.48 +
    5.49 +void *SDL_LoadFunction(void *handle, const char *name)
    5.50 +{
    5.51 +	const char *loaderror = "SDL_LoadFunction not implemented";
    5.52 +	SDL_SetError("Failed loading %s: %s", name, loaderror);
    5.53 +	return(NULL);
    5.54 +}
    5.55 +
    5.56 +void SDL_UnloadObject(void *handle)
    5.57 +{
    5.58 +    /* no-op. */
    5.59 +}
    5.60 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/loadso/macos/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     6.3 @@ -0,0 +1,119 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997-2004 Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Library General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Library General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Library General Public
    6.19 +    License along with this library; if not, write to the Free
    6.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +
    6.26 +#ifdef SAVE_RCSID
    6.27 +static char rcsid =
    6.28 + "@(#) $Id$";
    6.29 +#endif
    6.30 +
    6.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    6.32 +/* System dependent library loading routines                           */
    6.33 +
    6.34 +#if !SDL_INTERNAL_BUILDING_LOADSO
    6.35 +#error Do not compile directly...compile src/SDL_loadso.c instead!
    6.36 +#endif
    6.37 +
    6.38 +#if !defined(macintosh)
    6.39 +#error Compiling for the wrong platform?
    6.40 +#endif
    6.41 +
    6.42 +#include <stdio.h>
    6.43 +#include <string.h>
    6.44 +#define OLDP2C 1
    6.45 +#include <Strings.h>
    6.46 +#include <CodeFragments.h>
    6.47 +#include <Errors.h>
    6.48 +
    6.49 +#include "SDL_types.h"
    6.50 +#include "SDL_error.h"
    6.51 +#include "SDL_loadso.h"
    6.52 +
    6.53 +void *SDL_LoadObject(const char *sofile)
    6.54 +{
    6.55 +	void *handle = NULL;
    6.56 +	const char *loaderror = NULL;
    6.57 +	CFragConnectionID library_id;
    6.58 +	Ptr mainAddr;
    6.59 +	Str255 errName;
    6.60 +	OSErr error;
    6.61 +	char psofile[512];
    6.62 +
    6.63 +	strncpy(psofile, sofile, SDL_TABLESIZE(psofile));
    6.64 +	psofile[SDL_TABLESIZE(psofile)-1] = '\0';
    6.65 +	error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch,
    6.66 +			kLoadCFrag, &library_id, &mainAddr, errName);
    6.67 +	switch (error) {
    6.68 +		case noErr:
    6.69 +			loaderror = NULL;
    6.70 +			break;
    6.71 +		case cfragNoLibraryErr:
    6.72 +			loaderror = "Library not found";
    6.73 +			break;
    6.74 +		case cfragUnresolvedErr:
    6.75 +			loaderror = "Unabled to resolve symbols";
    6.76 +			break;
    6.77 +		case cfragNoPrivateMemErr:
    6.78 +		case cfragNoClientMemErr:
    6.79 +			loaderror = "Out of memory";
    6.80 +			break;
    6.81 +		default:
    6.82 +			loaderror = "Unknown Code Fragment Manager error";
    6.83 +			break;
    6.84 +	}
    6.85 +	if ( loaderror == NULL ) {
    6.86 +		handle = (void *)(library_id);
    6.87 +	} else {
    6.88 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
    6.89 +	}
    6.90 +	return(handle);
    6.91 +}
    6.92 +
    6.93 +void *SDL_LoadFunction(void *handle, const char *name)
    6.94 +{
    6.95 +	void *symbol = NULL;
    6.96 +	const char *loaderror = NULL;
    6.97 +	CFragSymbolClass class;
    6.98 +	CFragConnectionID library_id = (CFragConnectionID)handle;
    6.99 +	char pname[512];
   6.100 +
   6.101 +	strncpy(pname, name, SDL_TABLESIZE(pname));
   6.102 +	pname[SDL_TABLESIZE(pname)-1] = '\0';
   6.103 +	if ( FindSymbol(library_id, C2PStr(pname),
   6.104 +	                (char **)&symbol, &class) != noErr ) {
   6.105 +		loaderror = "Symbol not found";
   6.106 +	}
   6.107 +
   6.108 +	if ( symbol == NULL ) {
   6.109 +		SDL_SetError("Failed loading %s: %s", name, loaderror);
   6.110 +	}
   6.111 +	return(symbol);
   6.112 +}
   6.113 +
   6.114 +void SDL_UnloadObject(void *handle)
   6.115 +{
   6.116 +	CFragConnectionID library_id;
   6.117 +	if ( handle != NULL ) {
   6.118 +		library_id = (CFragConnectionID)handle;
   6.119 +		CloseConnection(&library_id);
   6.120 +	}
   6.121 +}
   6.122 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/loadso/macosx/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     7.3 @@ -0,0 +1,1419 @@
     7.4 +/*
     7.5 +    SDL - Simple DirectMedia Layer
     7.6 +    Copyright (C) 1997-2004 Sam Lantinga
     7.7 +
     7.8 +    This library is free software; you can redistribute it and/or
     7.9 +    modify it under the terms of the GNU Library General Public
    7.10 +    License as published by the Free Software Foundation; either
    7.11 +    version 2 of the License, or (at your option) any later version.
    7.12 +
    7.13 +    This library is distributed in the hope that it will be useful,
    7.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.16 +    Library General Public License for more details.
    7.17 +
    7.18 +    You should have received a copy of the GNU Library General Public
    7.19 +    License along with this library; if not, write to the Free
    7.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.21 +
    7.22 +    Sam Lantinga
    7.23 +    slouken@libsdl.org
    7.24 +*/
    7.25 +
    7.26 +#ifdef SAVE_RCSID
    7.27 +static char rcsid =
    7.28 + "@(#) $Id$";
    7.29 +#endif
    7.30 +
    7.31 +/* Please note that dlcompat apparently ships in current Mac OS X versions
    7.32 + *  as a system library that provides compatibility with the Unix "dlopen"
    7.33 + *  interface. In order to allow SDL to work on older OS X releases and also
    7.34 + *  not conflict with the system lib on newer versions, we include dlcompat
    7.35 + *  in SDL and change the symbols to prevent symbol clash with any existing
    7.36 + *  system libraries.  --ryan.
    7.37 + */
    7.38 +
    7.39 +/* here is the dlcompat license: */
    7.40 +
    7.41 +/*
    7.42 +Copyright (c) 2002 Jorge Acereda  <jacereda@users.sourceforge.net> &
    7.43 +                   Peter O'Gorman <ogorman@users.sourceforge.net>
    7.44 +                   
    7.45 +Portions may be copyright others, see the AUTHORS file included with this
    7.46 +distribution.
    7.47 +
    7.48 +Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
    7.49 +
    7.50 +Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
    7.51 +
    7.52 +Permission is hereby granted, free of charge, to any person obtaining
    7.53 +a copy of this software and associated documentation files (the
    7.54 +"Software"), to deal in the Software without restriction, including
    7.55 +without limitation the rights to use, copy, modify, merge, publish,
    7.56 +distribute, sublicense, and/or sell copies of the Software, and to
    7.57 +permit persons to whom the Software is furnished to do so, subject to
    7.58 +the following conditions:
    7.59 +
    7.60 +The above copyright notice and this permission notice shall be
    7.61 +included in all copies or substantial portions of the Software.
    7.62 +
    7.63 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    7.64 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    7.65 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    7.66 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    7.67 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    7.68 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    7.69 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    7.70 +*/
    7.71 +
    7.72 +#include <pthread.h>
    7.73 +#include <stdio.h>
    7.74 +#include <stdlib.h>
    7.75 +#include <string.h>
    7.76 +#include <sys/types.h>
    7.77 +#include <sys/stat.h>
    7.78 +#include <stdarg.h>
    7.79 +#include <limits.h>
    7.80 +#include <mach-o/dyld.h>
    7.81 +#include <mach-o/nlist.h>
    7.82 +#include <mach-o/getsect.h>
    7.83 +
    7.84 +/* Just playing to see if it would compile with the freebsd headers, it does,
    7.85 + * but because of the different values for RTLD_LOCAL etc, it would break binary
    7.86 + * compat... oh well
    7.87 + */
    7.88 +#ifndef __BSD_VISIBLE
    7.89 +#define __BSD_VISIBLE 1
    7.90 +#endif
    7.91 +
    7.92 +/*include "dlfcn.h"*/
    7.93 +#ifdef __cplusplus
    7.94 +extern "C" {
    7.95 +#endif
    7.96 +
    7.97 +#if defined (__GNUC__) && __GNUC__ > 3
    7.98 +#define dl_restrict __restrict
    7.99 +#else
   7.100 +#define dl_restrict
   7.101 +#endif
   7.102 +
   7.103 +#ifndef _POSIX_SOURCE
   7.104 +/*
   7.105 + * Structure filled in by dladdr().
   7.106 + */
   7.107 +typedef struct SDL_OSX_dl_info {
   7.108 +        const char      *dli_fname;     /* Pathname of shared object */
   7.109 +        void            *dli_fbase;     /* Base address of shared object */
   7.110 +        const char      *dli_sname;     /* Name of nearest symbol */
   7.111 +        void            *dli_saddr;     /* Address of nearest symbol */
   7.112 +} SDL_OSX_Dl_info;
   7.113 +
   7.114 +static int SDL_OSX_dladdr(const void * dl_restrict, SDL_OSX_Dl_info * dl_restrict);
   7.115 +#endif /* ! _POSIX_SOURCE */
   7.116 +
   7.117 +static int SDL_OSX_dlclose(void * handle);
   7.118 +static char * SDL_OSX_dlerror(void);
   7.119 +static void * SDL_OSX_dlopen(const char *path, int mode);
   7.120 +static void * SDL_OSX_dlsym(void * dl_restrict handle, const char * dl_restrict symbol);
   7.121 +
   7.122 +#define RTLD_LAZY	0x1
   7.123 +#define RTLD_NOW	0x2
   7.124 +#define RTLD_LOCAL	0x4
   7.125 +#define RTLD_GLOBAL	0x8
   7.126 +
   7.127 +#ifndef _POSIX_SOURCE
   7.128 +#define RTLD_NOLOAD	0x10
   7.129 +#define RTLD_NODELETE	0x80
   7.130 +
   7.131 +/*
   7.132 + * Special handle arguments for SDL_OSX_dlsym().
   7.133 + */
   7.134 +#define	RTLD_NEXT		((void *) -1)	/* Search subsequent objects. */
   7.135 +#define	RTLD_DEFAULT	((void *) -2)	/* Use default search algorithm. */
   7.136 +#endif /* ! _POSIX_SOURCE */
   7.137 +
   7.138 +#ifdef __cplusplus
   7.139 +}
   7.140 +#endif
   7.141 +
   7.142 +#ifndef dl_restrict
   7.143 +#define dl_restrict __restrict
   7.144 +#endif
   7.145 +/* This is not available on 10.1 */
   7.146 +#ifndef LC_LOAD_WEAK_DYLIB
   7.147 +#define	LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
   7.148 +#endif
   7.149 +
   7.150 +/* With this stuff here, this thing may actually compile/run on 10.0 systems
   7.151 + * Not that I have a 10.0 system to test it on anylonger
   7.152 + */
   7.153 +#ifndef LC_REQ_DYLD
   7.154 +#define LC_REQ_DYLD 0x80000000
   7.155 +#endif
   7.156 +#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
   7.157 +#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
   7.158 +#endif
   7.159 +#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
   7.160 +#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
   7.161 +#endif
   7.162 +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
   7.163 +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
   7.164 +#endif
   7.165 +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
   7.166 +#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
   7.167 +#endif
   7.168 +/* These symbols will be looked for in dyld */
   7.169 +static const struct mach_header *(*dyld_NSAddImage) (const char *, unsigned long) = 0;
   7.170 +static int (*dyld_NSIsSymbolNameDefinedInImage) (const struct mach_header *, const char *) = 0;
   7.171 +static NSSymbol(*dyld_NSLookupSymbolInImage)
   7.172 +	(const struct mach_header *, const char *, unsigned long) = 0;
   7.173 +
   7.174 +/* Define this to make dlcompat reuse data block. This way in theory we save
   7.175 + * a little bit of overhead. However we then couldn't correctly catch excess
   7.176 + * calls to SDL_OSX_dlclose(). Hence we don't use this feature
   7.177 + */
   7.178 +#undef REUSE_STATUS
   7.179 +
   7.180 +/* Size of the internal error message buffer (used by dlerror()) */
   7.181 +#define ERR_STR_LEN			251
   7.182 +
   7.183 +/* Maximum number of search paths supported by getSearchPath */
   7.184 +#define MAX_SEARCH_PATHS	32
   7.185 +
   7.186 +
   7.187 +#define MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF')
   7.188 +#define MAGIC_DYLIB_MOD ((NSModule) 'DYMO')
   7.189 +
   7.190 +/* internal flags */
   7.191 +#define DL_IN_LIST 0x01
   7.192 +
   7.193 +/* our mutex */
   7.194 +static pthread_mutex_t dlcompat_mutex;
   7.195 +/* Our thread specific storage
   7.196 + */
   7.197 +static pthread_key_t dlerror_key;
   7.198 +
   7.199 +struct dlthread
   7.200 +{
   7.201 +	int lockcnt;
   7.202 +	unsigned char errset;
   7.203 +	char errstr[ERR_STR_LEN];
   7.204 +};
   7.205 +
   7.206 +/* This is our central data structure. Whenever a module is loaded via
   7.207 + * SDL_OSX_dlopen(), we create such a struct.
   7.208 + */
   7.209 +struct dlstatus
   7.210 +{
   7.211 +	struct dlstatus *next;		/* pointer to next element in the linked list */
   7.212 +	NSModule module;
   7.213 +	const struct mach_header *lib;
   7.214 +	int refs;					/* reference count */
   7.215 +	int mode;					/* mode in which this module was loaded */
   7.216 +	dev_t device;
   7.217 +	ino_t inode;
   7.218 +	int flags;					/* Any internal flags we may need */
   7.219 +};
   7.220 +
   7.221 +/* Head node of the dlstatus list */
   7.222 +static struct dlstatus mainStatus = { 0, MAGIC_DYLIB_MOD, NULL, -1, RTLD_GLOBAL, 0, 0, 0 };
   7.223 +static struct dlstatus *stqueue = &mainStatus;
   7.224 +
   7.225 +
   7.226 +/* Storage for the last error message (used by dlerror()) */
   7.227 +/* static char err_str[ERR_STR_LEN]; */
   7.228 +/* static int err_filled = 0; */
   7.229 +
   7.230 +/* Prototypes to internal functions */
   7.231 +static void debug(const char *fmt, ...);
   7.232 +static void error(const char *str, ...);
   7.233 +static const char *safegetenv(const char *s);
   7.234 +static const char *searchList(void);
   7.235 +static const char *getSearchPath(int i);
   7.236 +static const char *getFullPath(int i, const char *file);
   7.237 +static const struct stat *findFile(const char *file, const char **fullPath);
   7.238 +static int isValidStatus(struct dlstatus *status);
   7.239 +static inline int isFlagSet(int mode, int flag);
   7.240 +static struct dlstatus *lookupStatus(const struct stat *sbuf);
   7.241 +static void insertStatus(struct dlstatus *dls, const struct stat *sbuf);
   7.242 +static int promoteLocalToGlobal(struct dlstatus *dls);
   7.243 +static void *reference(struct dlstatus *dls, int mode);
   7.244 +static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError);
   7.245 +static struct dlstatus *allocStatus(void);
   7.246 +static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode);
   7.247 +static NSSymbol *search_linked_libs(const struct mach_header *mh, const char *symbol);
   7.248 +static const char *get_lib_name(const struct mach_header *mh);
   7.249 +static const struct mach_header *get_mach_header_from_NSModule(NSModule * mod);
   7.250 +static void dlcompat_init_func(void);
   7.251 +static inline void dlcompat_init_check(void);
   7.252 +static inline void dolock(void);
   7.253 +static inline void dounlock(void);
   7.254 +static void dlerrorfree(void *data);
   7.255 +static void resetdlerror(void);
   7.256 +static const struct mach_header *my_find_image(const char *name);
   7.257 +static const struct mach_header *image_for_address(const void *address);
   7.258 +static inline const char *dyld_error_str(void);
   7.259 +
   7.260 +#if FINK_BUILD
   7.261 +/* Two Global Functions */
   7.262 +static void *dlsym_prepend_underscore(void *handle, const char *symbol);
   7.263 +static void *dlsym_auto_underscore(void *handle, const char *symbol);
   7.264 +
   7.265 +/* And their _intern counterparts */
   7.266 +static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol);
   7.267 +static void *dlsym_auto_underscore_intern(void *handle, const char *symbol);
   7.268 +#endif
   7.269 +
   7.270 +/* Functions */
   7.271 +
   7.272 +static void debug(const char *fmt, ...)
   7.273 +{
   7.274 +#if DEBUG > 1
   7.275 +	va_list arg;
   7.276 +	va_start(arg, fmt);
   7.277 +	fprintf(stderr, "DLDEBUG: ");
   7.278 +	vfprintf(stderr, fmt, arg);
   7.279 +	fprintf(stderr, "\n");
   7.280 +	fflush(stderr);
   7.281 +	va_end(arg);
   7.282 +#endif
   7.283 +}
   7.284 +
   7.285 +static void error(const char *str, ...)
   7.286 +{
   7.287 +	va_list arg;
   7.288 +	struct dlthread  *tss;
   7.289 +	char * err_str;
   7.290 +	va_start(arg, str);
   7.291 +	tss = pthread_getspecific(dlerror_key);
   7.292 +	err_str = tss->errstr;
   7.293 +	strncpy(err_str, "dlcompat: ", ERR_STR_LEN);
   7.294 +	vsnprintf(err_str + 10, ERR_STR_LEN - 10, str, arg);
   7.295 +	va_end(arg);
   7.296 +	debug("ERROR: %s\n", err_str);
   7.297 +	tss->errset = 1;
   7.298 +}
   7.299 +
   7.300 +static void warning(const char *str)
   7.301 +{
   7.302 +#if DEBUG > 0
   7.303 +	fprintf(stderr, "WARNING: dlcompat: %s\n", str);
   7.304 +#endif
   7.305 +}
   7.306 +
   7.307 +static const char *safegetenv(const char *s)
   7.308 +{
   7.309 +	const char *ss = getenv(s);
   7.310 +	return ss ? ss : "";
   7.311 +}
   7.312 +
   7.313 +/* because this is only used for debugging and error reporting functions, we
   7.314 + * don't really care about how elegant it is... it could use the load
   7.315 + * commands to find the install name of the library, but...
   7.316 + */
   7.317 +static const char *get_lib_name(const struct mach_header *mh)
   7.318 +{
   7.319 +	unsigned long count = _dyld_image_count();
   7.320 +	unsigned long i;
   7.321 +	const char *val = NULL;
   7.322 +	if (mh)
   7.323 +	{
   7.324 +		for (i = 0; i < count; i++)
   7.325 +		{
   7.326 +			if (mh == _dyld_get_image_header(i))
   7.327 +			{
   7.328 +				val = _dyld_get_image_name(i);
   7.329 +				break;
   7.330 +			}
   7.331 +		}
   7.332 +	}
   7.333 +	return val;
   7.334 +}
   7.335 +
   7.336 +/* Returns the mach_header for the module bu going through all the loaded images
   7.337 + * and finding the one with the same name as the module. There really ought to be
   7.338 + * an api for doing this, would be faster, but there isn't one right now
   7.339 + */
   7.340 +static const struct mach_header *get_mach_header_from_NSModule(NSModule * mod)
   7.341 +{
   7.342 +	const char *mod_name = NSNameOfModule(mod);
   7.343 +	struct mach_header *mh = NULL;
   7.344 +	unsigned long count = _dyld_image_count();
   7.345 +	unsigned long i;
   7.346 +	debug("Module name: %s", mod_name);
   7.347 +	for (i = 0; i < count; i++)
   7.348 +	{
   7.349 +		if (!strcmp(mod_name, _dyld_get_image_name(i)))
   7.350 +		{
   7.351 +			mh = _dyld_get_image_header(i);
   7.352 +			break;
   7.353 +		}
   7.354 +	}
   7.355 +	return mh;
   7.356 +}
   7.357 +
   7.358 +
   7.359 +/* Compute and return a list of all directories that we should search when
   7.360 + * trying to locate a module. We first look at the values of LD_LIBRARY_PATH
   7.361 + * and DYLD_LIBRARY_PATH, and then finally fall back to looking into
   7.362 + * /usr/lib and /lib. Since both of the environments variables can contain a
   7.363 + * list of colon seperated paths, we simply concat them and the two other paths
   7.364 + * into one big string, which we then can easily parse.
   7.365 + * Splitting this string into the actual path list is done by getSearchPath()
   7.366 + */
   7.367 +static const char *searchList()
   7.368 +{
   7.369 +	size_t buf_size;
   7.370 +	static char *buf=NULL;
   7.371 +	const char *ldlp = safegetenv("LD_LIBRARY_PATH");
   7.372 +	const char *dyldlp = safegetenv("DYLD_LIBRARY_PATH");
   7.373 +	const char *stdpath = getenv("DYLD_FALLBACK_LIBRARY_PATH");
   7.374 +	if (!stdpath)
   7.375 +		stdpath = "/usr/local/lib:/lib:/usr/lib";
   7.376 +	if (!buf)
   7.377 +	{	
   7.378 +		buf_size = strlen(ldlp) + strlen(dyldlp) + strlen(stdpath) + 4;
   7.379 +		buf = malloc(buf_size);
   7.380 +		snprintf(buf, buf_size, "%s%s%s%s%s%c", dyldlp, (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""),
   7.381 +				 stdpath, '\0');
   7.382 +	}
   7.383 +	return buf;
   7.384 +}
   7.385 +
   7.386 +/* Returns the ith search path from the list as computed by searchList() */
   7.387 +static const char *getSearchPath(int i)
   7.388 +{
   7.389 +	static const char *list = 0;
   7.390 +	static char **path = (char **)0;
   7.391 +	static int end = 0;
   7.392 +	static int numsize = MAX_SEARCH_PATHS;
   7.393 +	static char **tmp;
   7.394 +	/* So we can call free() in the "destructor" we use i=-1 to return the alloc'd array */
   7.395 +	if (i == -1)
   7.396 +	{
   7.397 +		return (const char*)path;
   7.398 +	}
   7.399 +	if (!path)
   7.400 +	{
   7.401 +		path = (char **)calloc(MAX_SEARCH_PATHS, sizeof(char **));
   7.402 +	}
   7.403 +	if (!list && !end)
   7.404 +		list = searchList();
   7.405 +	if (i >= (numsize))
   7.406 +	{
   7.407 +		debug("Increasing size for long PATH");
   7.408 +		tmp = (char **)calloc((MAX_SEARCH_PATHS + numsize), sizeof(char **));
   7.409 +		if (tmp)
   7.410 +		{
   7.411 +			memcpy(tmp, path, sizeof(char **) * numsize);
   7.412 +			free(path);
   7.413 +			path = tmp;
   7.414 +			numsize += MAX_SEARCH_PATHS;
   7.415 +		}
   7.416 +		else
   7.417 +		{
   7.418 +			return 0;
   7.419 +		}
   7.420 +	}
   7.421 +
   7.422 +	while (!path[i] && !end)
   7.423 +	{
   7.424 +		path[i] = strsep((char **)&list, ":");
   7.425 +
   7.426 +		if (path[i][0] == 0)
   7.427 +			path[i] = 0;
   7.428 +		end = (list == 0);
   7.429 +	}
   7.430 +	return path[i];
   7.431 +}
   7.432 +
   7.433 +static const char *getFullPath(int i, const char *file)
   7.434 +{
   7.435 +	static char buf[PATH_MAX];
   7.436 +	const char *path = getSearchPath(i);
   7.437 +	if (path)
   7.438 +	{
   7.439 +		snprintf(buf, PATH_MAX, "%s/%s", path, file);
   7.440 +	}
   7.441 +	return path ? buf : 0;
   7.442 +}
   7.443 +
   7.444 +/* Given a file name, try to determine the full path for that file. Starts
   7.445 + * its search in the current directory, and then tries all paths in the 
   7.446 + * search list in the order they are specified there.
   7.447 + */
   7.448 +static const struct stat *findFile(const char *file, const char **fullPath)
   7.449 +{
   7.450 +	int i = 0;
   7.451 +	static struct stat sbuf;
   7.452 +	char *fileName;
   7.453 +	debug("finding file %s", file);
   7.454 +	*fullPath = file;
   7.455 +	if (0 == stat(file, &sbuf))
   7.456 +		return &sbuf;
   7.457 +	if (strchr(file, '/'))
   7.458 +		return 0;				/* If the path had a / we don't look in env var places */
   7.459 +	fileName = NULL;
   7.460 +	if (!fileName)
   7.461 +		fileName = (char *)file;
   7.462 +	while ((*fullPath = getFullPath(i++, fileName)))
   7.463 +	{
   7.464 +		if (0 == stat(*fullPath, &sbuf))
   7.465 +			return &sbuf;
   7.466 +	}
   7.467 +	;
   7.468 +	return 0;
   7.469 +}
   7.470 +
   7.471 +/* Determine whether a given dlstatus is valid or not */
   7.472 +static int isValidStatus(struct dlstatus *status)
   7.473 +{
   7.474 +	/* Walk the list to verify status is contained in it */
   7.475 +	struct dlstatus *dls = stqueue;
   7.476 +	while (dls && status != dls)
   7.477 +		dls = dls->next;
   7.478 +	if (dls == 0)
   7.479 +		error("invalid handle");
   7.480 +	else if ((dls->module == 0) || (dls->refs == 0))
   7.481 +		error("handle to closed library");
   7.482 +	else
   7.483 +		return TRUE;
   7.484 +	return FALSE;
   7.485 +}
   7.486 +
   7.487 +static inline int isFlagSet(int mode, int flag)
   7.488 +{
   7.489 +	return (mode & flag) == flag;
   7.490 +}
   7.491 +
   7.492 +static struct dlstatus *lookupStatus(const struct stat *sbuf)
   7.493 +{
   7.494 +	struct dlstatus *dls = stqueue;
   7.495 +	debug("looking for status");
   7.496 +	while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0
   7.497 +				   || sbuf->st_dev != dls->device || sbuf->st_ino != dls->inode))
   7.498 +		dls = dls->next;
   7.499 +	return dls;
   7.500 +}
   7.501 +
   7.502 +static void insertStatus(struct dlstatus *dls, const struct stat *sbuf)
   7.503 +{
   7.504 +	debug("inserting status");
   7.505 +	dls->inode = sbuf->st_ino;
   7.506 +	dls->device = sbuf->st_dev;
   7.507 +	dls->refs = 0;
   7.508 +	dls->mode = 0;
   7.509 +	if ((dls->flags & DL_IN_LIST) == 0)
   7.510 +	{
   7.511 +		dls->next = stqueue;
   7.512 +		stqueue = dls;
   7.513 +		dls->flags |= DL_IN_LIST;
   7.514 +	}
   7.515 +}
   7.516 +
   7.517 +static struct dlstatus *allocStatus()
   7.518 +{
   7.519 +	struct dlstatus *dls;
   7.520 +#ifdef REUSE_STATUS
   7.521 +	dls = stqueue;
   7.522 +	while (dls && dls->module)
   7.523 +		dls = dls->next;
   7.524 +	if (!dls)
   7.525 +#endif
   7.526 +		dls = calloc(sizeof(*dls),1);
   7.527 +	return dls;
   7.528 +}
   7.529 +
   7.530 +static int promoteLocalToGlobal(struct dlstatus *dls)
   7.531 +{
   7.532 +	static int (*p) (NSModule module) = 0;
   7.533 +	debug("promoting");
   7.534 +	if (!p)
   7.535 +		_dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (unsigned long *)&p);
   7.536 +	return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module));
   7.537 +}
   7.538 +
   7.539 +static void *reference(struct dlstatus *dls, int mode)
   7.540 +{
   7.541 +	if (dls)
   7.542 +	{
   7.543 +		if (dls->module == MAGIC_DYLIB_MOD && isFlagSet(mode, RTLD_LOCAL))
   7.544 +		{
   7.545 +			warning("trying to open a .dylib with RTLD_LOCAL");
   7.546 +			error("unable to open a .dylib with RTLD_LOCAL");
   7.547 +			return NULL;
   7.548 +		}
   7.549 +		if (isFlagSet(mode, RTLD_GLOBAL) &&
   7.550 +			!isFlagSet(dls->mode, RTLD_GLOBAL) && !promoteLocalToGlobal(dls))
   7.551 +		{
   7.552 +			error("unable to promote local module to global");
   7.553 +			return NULL;
   7.554 +		}
   7.555 +		dls->mode |= mode;
   7.556 +		dls->refs++;
   7.557 +	}
   7.558 +	else
   7.559 +		debug("reference called with NULL argument");
   7.560 +
   7.561 +	return dls;
   7.562 +}
   7.563 +
   7.564 +static const struct mach_header *my_find_image(const char *name)
   7.565 +{
   7.566 +	const struct mach_header *mh = 0;
   7.567 +	const char *id = NULL;
   7.568 +	int i = _dyld_image_count();
   7.569 +	int j;
   7.570 +	mh = (struct mach_header *)
   7.571 +		dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
   7.572 +						NSADDIMAGE_OPTION_RETURN_ON_ERROR);
   7.573 +	if (!mh)
   7.574 +	{
   7.575 +		for (j = 0; j < i; j++)
   7.576 +		{
   7.577 +			id = _dyld_get_image_name(j);
   7.578 +			if (!strcmp(id, name))
   7.579 +			{
   7.580 +				mh = _dyld_get_image_header(j);
   7.581 +				break;
   7.582 +			}
   7.583 +		}
   7.584 +	}
   7.585 +	return mh;
   7.586 +}
   7.587 +
   7.588 +/*
   7.589 + * dyld adds libraries by first adding the directly dependant libraries in link order, and
   7.590 + * then adding the dependencies for those libraries, so we should do the same... but we don't
   7.591 + * bother adding the extra dependencies, if the symbols are neither in the loaded image nor
   7.592 + * any of it's direct dependencies, then it probably isn't there.
   7.593 + */
   7.594 +static NSSymbol *search_linked_libs(const struct mach_header * mh, const char *symbol)
   7.595 +{
   7.596 +	unsigned int n;
   7.597 +	struct load_command *lc = 0;
   7.598 +	struct mach_header *wh;
   7.599 +	NSSymbol *nssym = 0;
   7.600 +	if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
   7.601 +	{
   7.602 +		lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
   7.603 +		for (n = 0; n < mh->ncmds; n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
   7.604 +		{
   7.605 +			if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
   7.606 +			{
   7.607 +				if ((wh = (struct mach_header *)
   7.608 +					 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
   7.609 +											(char *)lc))))
   7.610 +				{
   7.611 +					if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol))
   7.612 +					{
   7.613 +						nssym = dyld_NSLookupSymbolInImage(wh,
   7.614 +														   symbol,
   7.615 +														   NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
   7.616 +														   NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
   7.617 +						break;
   7.618 +					}
   7.619 +				}
   7.620 +			}
   7.621 +		}
   7.622 +		if ((!nssym) && NSIsSymbolNameDefined(symbol))
   7.623 +		{
   7.624 +			/* I've never seen this debug message...*/
   7.625 +			debug("Symbol \"%s\" is defined but was not found", symbol);
   7.626 +		}
   7.627 +	}
   7.628 +	return nssym;
   7.629 +}
   7.630 +
   7.631 +/* Up to the caller to free() returned string */
   7.632 +static inline const char *dyld_error_str()
   7.633 +{
   7.634 +	NSLinkEditErrors dylder;
   7.635 +	int dylderno;
   7.636 +	const char *dylderrstr;
   7.637 +	const char *dyldfile;
   7.638 +	const char* retStr = NULL;
   7.639 +	NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr);
   7.640 +	if (dylderrstr && strlen(dylderrstr))
   7.641 +	{
   7.642 +		retStr = malloc(strlen(dylderrstr) +1);
   7.643 +		strcpy((char*)retStr,dylderrstr);
   7.644 +	}
   7.645 +	return retStr;
   7.646 +}
   7.647 +
   7.648 +static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError)
   7.649 +{
   7.650 +  NSSymbol *nssym = 0;
   7.651 +#ifdef __GCC__  
   7.652 +	void *caller = __builtin_return_address(1);	/* Be *very* careful about inlining */
   7.653 +#else
   7.654 +	void *caller = NULL;
   7.655 +#endif
   7.656 +	const struct mach_header *caller_mh = 0;
   7.657 +	const char* savedErrorStr = NULL;
   7.658 +	resetdlerror();
   7.659 +#ifndef RTLD_SELF
   7.660 +#define	RTLD_SELF		((void *) -3)
   7.661 +#endif
   7.662 +	if (NULL == dls)
   7.663 +		dls = RTLD_SELF;
   7.664 +	if ((RTLD_NEXT == dls) || (RTLD_SELF == dls))
   7.665 +	{
   7.666 +		if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage && caller)
   7.667 +		  {
   7.668 +			caller_mh = image_for_address(caller);
   7.669 +			if (RTLD_SELF == dls)
   7.670 +			{
   7.671 +				/* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE
   7.672 +				 * But it appears to work anyway, and looking at the code in dyld_libfuncs.c
   7.673 +				 * this is acceptable.
   7.674 +				 */
   7.675 +				if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol))
   7.676 +				{
   7.677 +					nssym = dyld_NSLookupSymbolInImage(caller_mh,
   7.678 +													   symbol,
   7.679 +													   NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
   7.680 +													   NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
   7.681 +				}
   7.682 +			}
   7.683 +			if (!nssym)
   7.684 +			{
   7.685 +				if (RTLD_SELF == dls)
   7.686 +					savedErrorStr = dyld_error_str();
   7.687 +				nssym = search_linked_libs(caller_mh, symbol);
   7.688 +			}
   7.689 +		}
   7.690 +		else
   7.691 +		{
   7.692 +			if (canSetError)
   7.693 +				error("RTLD_SELF and RTLD_NEXT are not supported");
   7.694 +			return NULL;
   7.695 +		}
   7.696 +	}
   7.697 +	if (!nssym)
   7.698 +	{
   7.699 +
   7.700 +		if (RTLD_DEFAULT == dls)
   7.701 +		{
   7.702 +			dls = &mainStatus;
   7.703 +		}
   7.704 +		if (!isValidStatus(dls))
   7.705 +			return NULL;
   7.706 +
   7.707 +		if (dls->module != MAGIC_DYLIB_MOD)
   7.708 +		{
   7.709 +			nssym = NSLookupSymbolInModule(dls->module, symbol);
   7.710 +			if (!nssym && NSIsSymbolNameDefined(symbol))
   7.711 +			{
   7.712 +				debug("Searching dependencies");
   7.713 +				savedErrorStr = dyld_error_str();
   7.714 +				nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol);
   7.715 +			}
   7.716 +		}
   7.717 +		else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
   7.718 +		{
   7.719 +			if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol))
   7.720 +			{
   7.721 +				nssym = dyld_NSLookupSymbolInImage(dls->lib,
   7.722 +												   symbol,
   7.723 +												   NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
   7.724 +												   NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
   7.725 +			}
   7.726 +			else if (NSIsSymbolNameDefined(symbol))
   7.727 +			{
   7.728 +				debug("Searching dependencies");
   7.729 +				savedErrorStr = dyld_error_str();
   7.730 +				nssym = search_linked_libs(dls->lib, symbol);
   7.731 +			}
   7.732 +		}
   7.733 +		else if (dls->module == MAGIC_DYLIB_MOD)
   7.734 +		{
   7.735 +			/* Global context, use NSLookupAndBindSymbol */
   7.736 +			if (NSIsSymbolNameDefined(symbol))
   7.737 +			{
   7.738 +				/* There doesn't seem to be a return on error option for this call???
   7.739 +				   this is potentially broken, if binding fails, it will improperly
   7.740 +				   exit the application. */
   7.741 +				nssym = NSLookupAndBindSymbol(symbol);
   7.742 +			}
   7.743 +			else
   7.744 +			{
   7.745 +				if (savedErrorStr)
   7.746 +					free((char*)savedErrorStr);			
   7.747 +				savedErrorStr = malloc(256);
   7.748 +				snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol);	
   7.749 +			}
   7.750 +		}
   7.751 +	}
   7.752 +	/* Error reporting */
   7.753 +	if (!nssym)
   7.754 +	{
   7.755 +		if (!savedErrorStr || !strlen(savedErrorStr))
   7.756 +		{
   7.757 +			if (savedErrorStr)
   7.758 +				free((char*)savedErrorStr);
   7.759 +			savedErrorStr = malloc(256);
   7.760 +			snprintf((char*)savedErrorStr, 256,"Symbol \"%s\" not found",symbol);
   7.761 +		}
   7.762 +		if (canSetError)
   7.763 +		{
   7.764 +			error(savedErrorStr);
   7.765 +		}
   7.766 +		else
   7.767 +		{
   7.768 +			debug(savedErrorStr);
   7.769 +		}
   7.770 +		if (savedErrorStr)
   7.771 +			free((char*)savedErrorStr);
   7.772 +		return NULL;
   7.773 +	}
   7.774 +	return NSAddressOfSymbol(nssym);
   7.775 +}
   7.776 +
   7.777 +static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode)
   7.778 +{
   7.779 +	NSObjectFileImage ofi = 0;
   7.780 +	NSObjectFileImageReturnCode ofirc;
   7.781 +	struct dlstatus *dls;
   7.782 +	NSLinkEditErrors ler;
   7.783 +	int lerno;
   7.784 +	const char *errstr;
   7.785 +	const char *file;
   7.786 +	void (*init) (void);
   7.787 +	ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
   7.788 +	switch (ofirc)
   7.789 +	{
   7.790 +		case NSObjectFileImageSuccess:
   7.791 +			break;
   7.792 +		case NSObjectFileImageInappropriateFile:
   7.793 +			if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
   7.794 +			{	
   7.795 +				if (isFlagSet(mode, RTLD_LOCAL))
   7.796 +				{
   7.797 +					warning("trying to open a .dylib with RTLD_LOCAL");
   7.798 +					error("unable to open this file with RTLD_LOCAL");
   7.799 +					return NULL;
   7.800 +				}
   7.801 +			}
   7.802 +			else
   7.803 +			{
   7.804 +				error("opening this file is unsupported on this system");
   7.805 +				return NULL;
   7.806 +			}
   7.807 +			break;
   7.808 +		case NSObjectFileImageFailure:
   7.809 +			error("object file setup failure");
   7.810 +			return NULL;
   7.811 +		case NSObjectFileImageArch:
   7.812 +			error("no object for this architecture");
   7.813 +			return NULL;
   7.814 +		case NSObjectFileImageFormat:
   7.815 +			error("bad object file format");
   7.816 +			return NULL;
   7.817 +		case NSObjectFileImageAccess:
   7.818 +			error("can't read object file");
   7.819 +			return NULL;
   7.820 +		default:
   7.821 +			error("unknown error from NSCreateObjectFileImageFromFile()");
   7.822 +			return NULL;
   7.823 +	}
   7.824 +	dls = lookupStatus(sbuf);
   7.825 +	if (!dls)
   7.826 +	{
   7.827 +		dls = allocStatus();
   7.828 +	}
   7.829 +	if (!dls)
   7.830 +	{
   7.831 +		error("unable to allocate memory");
   7.832 +		return NULL;
   7.833 +	}
   7.834 +	//	dls->lib = 0;
   7.835 +	if (ofirc == NSObjectFileImageInappropriateFile)
   7.836 +	{
   7.837 +		if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR)))
   7.838 +		{
   7.839 +			debug("Dynamic lib loaded at %ld", dls->lib);
   7.840 +			ofi = MAGIC_DYLIB_OFI;
   7.841 +			dls->module = MAGIC_DYLIB_MOD;
   7.842 +			ofirc = NSObjectFileImageSuccess;
   7.843 +			/* Although it is possible with a bit of work to modify this so it works and
   7.844 +			   functions with RTLD_NOW, I don't deem it necessary at the moment */
   7.845 +		}
   7.846 +		if (!(dls->module))
   7.847 +		{
   7.848 +			NSLinkEditError(&ler, &lerno, &file, &errstr);
   7.849 +			if (!errstr || (!strlen(errstr)))
   7.850 +				error("Can't open this file type");
   7.851 +			else
   7.852 +				error(errstr);
   7.853 +			if ((dls->flags & DL_IN_LIST) == 0)
   7.854 +			{
   7.855 +				free(dls);
   7.856 +			}
   7.857 +			return NULL;
   7.858 +		}
   7.859 +	}
   7.860 +	else
   7.861 +	{
   7.862 +		dls->module = NSLinkModule(ofi, path,
   7.863 +								   NSLINKMODULE_OPTION_RETURN_ON_ERROR |
   7.864 +								   NSLINKMODULE_OPTION_PRIVATE |
   7.865 +								   (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0));
   7.866 +		NSDestroyObjectFileImage(ofi);
   7.867 +		if (dls->module)
   7.868 +		{
   7.869 +			dls->lib = get_mach_header_from_NSModule(dls->module);
   7.870 +		}
   7.871 +	}
   7.872 +	if (!dls->module)
   7.873 +	{
   7.874 +		NSLinkEditError(&ler, &lerno, &file, &errstr);
   7.875 +		if ((dls->flags & DL_IN_LIST) == 0)
   7.876 +		{
   7.877 +			free(dls);
   7.878 +		}
   7.879 +		error(errstr);
   7.880 +		return NULL;
   7.881 +	}
   7.882 +
   7.883 +	insertStatus(dls, sbuf);
   7.884 +	dls = reference(dls, mode);
   7.885 +	if ((init = dlsymIntern(dls, "__init", 0)))
   7.886 +	{
   7.887 +		debug("calling _init()");
   7.888 +		init();
   7.889 +	}
   7.890 +	return dls;
   7.891 +}
   7.892 +
   7.893 +inline static void dlcompat_init_check(void)
   7.894 +{
   7.895 +	static pthread_mutex_t l = PTHREAD_MUTEX_INITIALIZER;
   7.896 +	static int init_done = 0;
   7.897 +
   7.898 +	pthread_mutex_lock(&l);
   7.899 +	if (!init_done) {
   7.900 +		dlcompat_init_func();
   7.901 +		init_done = 1;
   7.902 +	}
   7.903 +	pthread_mutex_unlock(&l);
   7.904 +}
   7.905 +
   7.906 +static void dlcompat_init_func(void)
   7.907 +{
   7.908 +        _dyld_func_lookup("__dyld_NSAddImage", (unsigned long *)&dyld_NSAddImage);
   7.909 +	_dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",
   7.910 +			  (unsigned long *)&dyld_NSIsSymbolNameDefinedInImage);
   7.911 +	_dyld_func_lookup("__dyld_NSLookupSymbolInImage", (unsigned long *)&dyld_NSLookupSymbolInImage);
   7.912 +	if (pthread_mutex_init(&dlcompat_mutex, NULL))
   7.913 +	    exit(1);
   7.914 +	if (pthread_key_create(&dlerror_key, &dlerrorfree))
   7.915 +	    exit(1);
   7.916 +}
   7.917 +
   7.918 +static void resetdlerror()
   7.919 +{
   7.920 +	struct dlthread *tss;
   7.921 +	tss = pthread_getspecific(dlerror_key);
   7.922 +	tss->errset = 0;
   7.923 +}
   7.924 +
   7.925 +static void dlerrorfree(void *data)
   7.926 +{
   7.927 +	free(data);
   7.928 +}
   7.929 +
   7.930 +/* We kind of want a recursive lock here, but meet a little trouble
   7.931 + * because they are not available pre OS X 10.2, so we fake it
   7.932 + * using thread specific storage to keep a lock count
   7.933 + */ 
   7.934 +static inline void dolock(void)
   7.935 +{
   7.936 +	int err = 0;
   7.937 +	struct dlthread *tss;
   7.938 +	dlcompat_init_check();
   7.939 +	tss = pthread_getspecific(dlerror_key);
   7.940 +	if (!tss)
   7.941 +	{
   7.942 +		tss = malloc(sizeof(struct dlthread));
   7.943 +		tss->lockcnt = 0;
   7.944 +		tss->errset = 0;
   7.945 +		if (pthread_setspecific(dlerror_key, tss))
   7.946 +		{
   7.947 +			fprintf(stderr,"dlcompat: pthread_setspecific failed\n");
   7.948 +			exit(1);
   7.949 +		}
   7.950 +	}
   7.951 +	if (!tss->lockcnt)
   7.952 +		err = pthread_mutex_lock(&dlcompat_mutex);
   7.953 +	tss->lockcnt = tss->lockcnt +1;	
   7.954 +	if (err)
   7.955 +		exit(err);
   7.956 +}
   7.957 +
   7.958 +static inline void dounlock(void)
   7.959 +{
   7.960 +	int err = 0;
   7.961 +	struct dlthread *tss;
   7.962 +	tss = pthread_getspecific(dlerror_key);
   7.963 +	tss->lockcnt = tss->lockcnt -1;
   7.964 +	if (!tss->lockcnt)
   7.965 +		err = pthread_mutex_unlock(&dlcompat_mutex);
   7.966 +	if (err)
   7.967 +		exit(err);
   7.968 +}
   7.969 +
   7.970 +static void *SDL_OSX_dlopen(const char *path, int mode)
   7.971 +{
   7.972 +	const struct stat *sbuf;
   7.973 +	struct dlstatus *dls;
   7.974 +	const char *fullPath;
   7.975 +
   7.976 +	dolock();
   7.977 +	resetdlerror();
   7.978 +	if (!path)
   7.979 +	{
   7.980 +		dls = &mainStatus;
   7.981 +		goto dlopenok;
   7.982 +	}
   7.983 +	if (!(sbuf = findFile(path, &fullPath)))
   7.984 +	{
   7.985 +		error("file \"%s\" not found", path);
   7.986 +		goto dlopenerror;
   7.987 +	}
   7.988 +	/* Now checks that it hasn't been closed already */
   7.989 +	if ((dls = lookupStatus(sbuf)) && (dls->refs > 0))
   7.990 +	{
   7.991 +		/* debug("status found"); */
   7.992 +		dls = reference(dls, mode);
   7.993 +		goto dlopenok;
   7.994 +	}
   7.995 +#ifdef 	RTLD_NOLOAD
   7.996 +	if (isFlagSet(mode, RTLD_NOLOAD))
   7.997 +	{
   7.998 +		error("no existing handle and RTLD_NOLOAD specified");
   7.999 +		goto dlopenerror;
  7.1000 +	}
  7.1001 +#endif
  7.1002 +	if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW))
  7.1003 +	{
  7.1004 +		error("how can I load something both RTLD_LAZY and RTLD_NOW?");
  7.1005 +		goto dlopenerror;
  7.1006 +	}
  7.1007 +	dls = loadModule(fullPath, sbuf, mode);
  7.1008 +	
  7.1009 +  dlopenok:
  7.1010 +	dounlock();
  7.1011 +	return (void *)dls;
  7.1012 +  dlopenerror:
  7.1013 +	dounlock();
  7.1014 +	return NULL;
  7.1015 +}
  7.1016 +
  7.1017 +#if !FINK_BUILD
  7.1018 +static void *SDL_OSX_dlsym(void * dl_restrict handle, const char * dl_restrict symbol)
  7.1019 +{
  7.1020 +	int sym_len = strlen(symbol);
  7.1021 +	void *value = NULL;
  7.1022 +	char *malloc_sym = NULL;
  7.1023 +	dolock();
  7.1024 +	malloc_sym = malloc(sym_len + 2);
  7.1025 +	if (malloc_sym)
  7.1026 +	{
  7.1027 +		sprintf(malloc_sym, "_%s", symbol);
  7.1028 +		value = dlsymIntern(handle, malloc_sym, 1);
  7.1029 +		free(malloc_sym);
  7.1030 +	}
  7.1031 +	else
  7.1032 +	{
  7.1033 +		error("Unable to allocate memory");
  7.1034 +		goto dlsymerror;
  7.1035 +	}
  7.1036 +	dounlock();
  7.1037 +	return value;
  7.1038 +  dlsymerror:
  7.1039 +	dounlock();
  7.1040 +	return NULL;
  7.1041 +}
  7.1042 +#endif
  7.1043 +
  7.1044 +#if FINK_BUILD
  7.1045 +
  7.1046 +static void *dlsym_prepend_underscore(void *handle, const char *symbol)
  7.1047 +{
  7.1048 +	void *answer;
  7.1049 +	dolock();
  7.1050 +	answer = dlsym_prepend_underscore_intern(handle, symbol);
  7.1051 +	dounlock();
  7.1052 +	return answer;
  7.1053 +}
  7.1054 +
  7.1055 +static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol)
  7.1056 +{
  7.1057 +/*
  7.1058 + *	A quick and easy way for porting packages which call dlsym(handle,"sym")
  7.1059 + *	If the porter adds -Ddlsym=dlsym_prepend_underscore to the CFLAGS then
  7.1060 + *	this function will be called, and will add the required underscore.
  7.1061 + *	
  7.1062 + *	Note that I haven't figured out yet which should be "standard", prepend
  7.1063 + *	the underscore always, or not at all. These global functions need to go away
  7.1064 + *	for opendarwin.
  7.1065 + */
  7.1066 +	int sym_len = strlen(symbol);
  7.1067 +	void *value = NULL;
  7.1068 +	char *malloc_sym = NULL;
  7.1069 +	malloc_sym = malloc(sym_len + 2);
  7.1070 +	if (malloc_sym)
  7.1071 +	{
  7.1072 +		sprintf(malloc_sym, "_%s", symbol);
  7.1073 +		value = dlsymIntern(handle, malloc_sym, 1);
  7.1074 +		free(malloc_sym);
  7.1075 +	}
  7.1076 +	else
  7.1077 +	{
  7.1078 +		error("Unable to allocate memory");
  7.1079 +	}
  7.1080 +	return value;
  7.1081 +}
  7.1082 +
  7.1083 +static void *dlsym_auto_underscore(void *handle, const char *symbol)
  7.1084 +{
  7.1085 +	void *answer;
  7.1086 +	dolock();
  7.1087 +	answer = dlsym_auto_underscore_intern(handle, symbol);
  7.1088 +	dounlock();
  7.1089 +	return answer;
  7.1090 +
  7.1091 +}
  7.1092 +static void *dlsym_auto_underscore_intern(void *handle, const char *symbol)
  7.1093 +{
  7.1094 +	struct dlstatus *dls = handle;
  7.1095 +	void *addr = 0;
  7.1096 +	addr = dlsymIntern(dls, symbol, 0);
  7.1097 +	if (!addr)
  7.1098 +		addr = dlsym_prepend_underscore_intern(handle, symbol);
  7.1099 +	return addr;
  7.1100 +}
  7.1101 +
  7.1102 +
  7.1103 +static void *SDL_OSX_dlsym(void * dl_restrict handle, const char * dl_restrict symbol)
  7.1104 +{
  7.1105 +	struct dlstatus *dls = handle;
  7.1106 +	void *addr = 0;
  7.1107 +	dolock();
  7.1108 +	addr = dlsymIntern(dls, symbol, 1);
  7.1109 +	dounlock();
  7.1110 +	return addr;
  7.1111 +}
  7.1112 +#endif
  7.1113 +
  7.1114 +static int SDL_OSX_dlclose(void *handle)
  7.1115 +{
  7.1116 +	struct dlstatus *dls = handle;
  7.1117 +	dolock();
  7.1118 +	resetdlerror();
  7.1119 +	if (!isValidStatus(dls))
  7.1120 +	{
  7.1121 +		goto dlcloseerror;
  7.1122 +	}
  7.1123 +	if (dls->module == MAGIC_DYLIB_MOD)
  7.1124 +	{
  7.1125 +		const char *name;
  7.1126 +		if (!dls->lib)
  7.1127 +		{
  7.1128 +			name = "global context";
  7.1129 +		}
  7.1130 +		else
  7.1131 +		{
  7.1132 +			name = get_lib_name(dls->lib);
  7.1133 +		}
  7.1134 +		warning("trying to close a .dylib!");
  7.1135 +		error("Not closing \"%s\" - dynamic libraries cannot be closed", name);
  7.1136 +		goto dlcloseerror;
  7.1137 +	}
  7.1138 +	if (!dls->module)
  7.1139 +	{
  7.1140 +		error("module already closed");
  7.1141 +		goto dlcloseerror;
  7.1142 +	}
  7.1143 +	
  7.1144 +	if (dls->refs == 1)
  7.1145 +	{
  7.1146 +		unsigned long options = 0;
  7.1147 +		void (*fini) (void);
  7.1148 +		if ((fini = dlsymIntern(dls, "__fini", 0)))
  7.1149 +		{
  7.1150 +			debug("calling _fini()");
  7.1151 +			fini();
  7.1152 +		}
  7.1153 +		options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
  7.1154 +#ifdef RTLD_NODELETE
  7.1155 +		if (isFlagSet(dls->mode, RTLD_NODELETE))
  7.1156 +			options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
  7.1157 +#endif
  7.1158 +		if (!NSUnLinkModule(dls->module, options))
  7.1159 +		{
  7.1160 +			error("unable to unlink module");
  7.1161 +			goto dlcloseerror;
  7.1162 +		}
  7.1163 +		dls->refs--;
  7.1164 +		dls->module = 0;
  7.1165 +		/* Note: the dlstatus struct dls is neither removed from the list
  7.1166 +		 * nor is the memory it occupies freed. This shouldn't pose a 
  7.1167 +		 * problem in mostly all cases, though.
  7.1168 +		 */
  7.1169 +	}
  7.1170 +	dounlock();
  7.1171 +	return 0;
  7.1172 +  dlcloseerror:
  7.1173 +	dounlock();
  7.1174 +	return 1;
  7.1175 +}
  7.1176 +
  7.1177 +static char *SDL_OSX_dlerror(void)
  7.1178 +{
  7.1179 +	struct dlthread  *tss;
  7.1180 +	const char * err_str = NULL;
  7.1181 +	dlcompat_init_check();
  7.1182 +	tss = pthread_getspecific(dlerror_key);
  7.1183 +	if (tss != NULL && tss->errset != 0) {
  7.1184 +		tss->errset = 0;	
  7.1185 +		err_str = tss->errstr;
  7.1186 +	}
  7.1187 +	return (err_str);
  7.1188 +}
  7.1189 +
  7.1190 +/* Given an address, return the mach_header for the image containing it
  7.1191 + * or zero if the given address is not contained in any loaded images.
  7.1192 + */
  7.1193 +static const struct mach_header *image_for_address(const void *address)
  7.1194 +{
  7.1195 +	unsigned long i;
  7.1196 +	unsigned long j;
  7.1197 +	unsigned long count = _dyld_image_count();
  7.1198 +	struct mach_header *mh = 0;
  7.1199 +	struct load_command *lc = 0;
  7.1200 +	unsigned long addr = NULL;
  7.1201 +	for (i = 0; i < count; i++)
  7.1202 +	{
  7.1203 +		addr = (unsigned long)address - _dyld_get_image_vmaddr_slide(i);
  7.1204 +		mh = _dyld_get_image_header(i);
  7.1205 +		if (mh)
  7.1206 +		{
  7.1207 +			lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
  7.1208 +			for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
  7.1209 +			{
  7.1210 +				if (LC_SEGMENT == lc->cmd &&
  7.1211 +					addr >= ((struct segment_command *)lc)->vmaddr &&
  7.1212 +					addr <
  7.1213 +					((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
  7.1214 +				{
  7.1215 +					goto image_found;
  7.1216 +				}
  7.1217 +			}
  7.1218 +		}
  7.1219 +		mh = 0;
  7.1220 +	}
  7.1221 +  image_found:
  7.1222 +	return mh;
  7.1223 +}
  7.1224 +
  7.1225 +static int SDL_OSX_dladdr(const void * dl_restrict p, SDL_OSX_Dl_info * dl_restrict info)
  7.1226 +{
  7.1227 +/*
  7.1228 +	FIXME: USe the routine image_for_address.
  7.1229 +*/
  7.1230 +	unsigned long i;
  7.1231 +	unsigned long j;
  7.1232 +	unsigned long count = _dyld_image_count();
  7.1233 +	struct mach_header *mh = 0;
  7.1234 +	struct load_command *lc = 0;
  7.1235 +	unsigned long addr = NULL;
  7.1236 +	unsigned long table_off = (unsigned long)0;
  7.1237 +	int found = 0;
  7.1238 +	if (!info)
  7.1239 +		return 0;
  7.1240 +	dolock();
  7.1241 +	resetdlerror();
  7.1242 +	info->dli_fname = 0;
  7.1243 +	info->dli_fbase = 0;
  7.1244 +	info->dli_sname = 0;
  7.1245 +	info->dli_saddr = 0;
  7.1246 +/* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com>
  7.1247 + * to darwin-development AT lists DOT apple DOT com and slightly modified
  7.1248 + */
  7.1249 +	for (i = 0; i < count; i++)
  7.1250 +	{
  7.1251 +		addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
  7.1252 +		mh = _dyld_get_image_header(i);
  7.1253 +		if (mh)
  7.1254 +		{
  7.1255 +			lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
  7.1256 +			for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
  7.1257 +			{
  7.1258 +				if (LC_SEGMENT == lc->cmd &&
  7.1259 +					addr >= ((struct segment_command *)lc)->vmaddr &&
  7.1260 +					addr <
  7.1261 +					((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
  7.1262 +				{
  7.1263 +					info->dli_fname = _dyld_get_image_name(i);
  7.1264 +					info->dli_fbase = (void *)mh;
  7.1265 +					found = 1;
  7.1266 +					break;
  7.1267 +				}
  7.1268 +			}
  7.1269 +			if (found)
  7.1270 +				break;
  7.1271 +		}
  7.1272 +	}
  7.1273 +	if (!found)
  7.1274 +	{
  7.1275 +		dounlock();
  7.1276 +		return 0;
  7.1277 +	}
  7.1278 +	lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
  7.1279 +	for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
  7.1280 +	{
  7.1281 +		if (LC_SEGMENT == lc->cmd)
  7.1282 +		{
  7.1283 +			if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT"))
  7.1284 +				break;
  7.1285 +		}
  7.1286 +	}
  7.1287 +	table_off =
  7.1288 +		((unsigned long)((struct segment_command *)lc)->vmaddr) -
  7.1289 +		((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
  7.1290 +	debug("table off %x", table_off);
  7.1291 +
  7.1292 +	lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
  7.1293 +	for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
  7.1294 +	{
  7.1295 +		if (LC_SYMTAB == lc->cmd)
  7.1296 +		{
  7.1297 +
  7.1298 +			struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off);
  7.1299 +			unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
  7.1300 +			struct nlist *nearest = NULL;
  7.1301 +			unsigned long diff = 0xffffffff;
  7.1302 +			unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off);
  7.1303 +			debug("symtable %x", symtable);
  7.1304 +			for (i = 0; i < numsyms; i++)
  7.1305 +			{
  7.1306 +				/* Ignore the following kinds of Symbols */
  7.1307 +				if ((!symtable->n_value)	/* Undefined */
  7.1308 +					|| (symtable->n_type >= N_PEXT)	/* Debug symbol */
  7.1309 +					|| (!(symtable->n_type & N_EXT))	/* Local Symbol */
  7.1310 +					)
  7.1311 +				{
  7.1312 +					symtable++;
  7.1313 +					continue;
  7.1314 +				}
  7.1315 +				if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
  7.1316 +				{
  7.1317 +					diff = (unsigned long)symtable->n_value - addr;
  7.1318 +					nearest = symtable;
  7.1319 +				}
  7.1320 +				symtable++;
  7.1321 +			}
  7.1322 +			if (nearest)
  7.1323 +			{
  7.1324 +				info->dli_saddr = nearest->n_value + ((void *)p - addr);
  7.1325 +				info->dli_sname = (char *)(strtable + nearest->n_un.n_strx);
  7.1326 +			}
  7.1327 +		}
  7.1328 +	}
  7.1329 +	dounlock();
  7.1330 +	return 1;
  7.1331 +}
  7.1332 +
  7.1333 +
  7.1334 +/*
  7.1335 + * Implement the dlfunc() interface, which behaves exactly the same as
  7.1336 + * dlsym() except that it returns a function pointer instead of a data
  7.1337 + * pointer.  This can be used by applications to avoid compiler warnings
  7.1338 + * about undefined behavior, and is intended as prior art for future
  7.1339 + * POSIX standardization.  This function requires that all pointer types
  7.1340 + * have the same representation, which is true on all platforms FreeBSD
  7.1341 + * runs on, but is not guaranteed by the C standard.
  7.1342 + */
  7.1343 +#if 0 
  7.1344 +static dlfunc_t SDL_OSX_dlfunc(void * dl_restrict handle, const char * dl_restrict symbol)
  7.1345 +{
  7.1346 +	union
  7.1347 +	{
  7.1348 +		void *d;
  7.1349 +		dlfunc_t f;
  7.1350 +	} rv;
  7.1351 +	int sym_len = strlen(symbol);
  7.1352 +	char *malloc_sym = NULL;
  7.1353 +	dolock();
  7.1354 +	malloc_sym = malloc(sym_len + 2);
  7.1355 +	if (malloc_sym)
  7.1356 +	{
  7.1357 +		sprintf(malloc_sym, "_%s", symbol);
  7.1358 +		rv.d = dlsymIntern(handle, malloc_sym, 1);
  7.1359 +		free(malloc_sym);
  7.1360 +	}
  7.1361 +	else
  7.1362 +	{
  7.1363 +		error("Unable to allocate memory");
  7.1364 +		goto dlfuncerror;
  7.1365 +	}
  7.1366 +	dounlock();
  7.1367 +	return rv.f;
  7.1368 +  dlfuncerror:
  7.1369 +	dounlock();
  7.1370 +	return NULL;
  7.1371 +}
  7.1372 +#endif
  7.1373 +
  7.1374 +
  7.1375 +
  7.1376 +/* dlcompat ends, here's the SDL interface...  --ryan.  */
  7.1377 +
  7.1378 +
  7.1379 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  7.1380 +/* System dependent library loading routines                           */
  7.1381 +
  7.1382 +#if !SDL_INTERNAL_BUILDING_LOADSO
  7.1383 +#error Do not compile directly...compile src/SDL_loadso.c instead!
  7.1384 +#endif
  7.1385 +
  7.1386 +#if !defined(MACOSX)
  7.1387 +#error Compiling for the wrong platform?
  7.1388 +#elif defined(USE_DLOPEN)
  7.1389 +#error Do not use USE_DLOPEN on Mac OS X.
  7.1390 +#endif
  7.1391 +
  7.1392 +#include "SDL_types.h"
  7.1393 +#include "SDL_error.h"
  7.1394 +#include "SDL_loadso.h"
  7.1395 +
  7.1396 +void *SDL_LoadObject(const char *sofile)
  7.1397 +{
  7.1398 +	void *handle = SDL_OSX_dlopen(sofile, RTLD_NOW);
  7.1399 +	const char *loaderror = (char *)SDL_OSX_dlerror();
  7.1400 +	if ( handle == NULL ) {
  7.1401 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
  7.1402 +	}
  7.1403 +	return(handle);
  7.1404 +}
  7.1405 +
  7.1406 +void *SDL_LoadFunction(void *handle, const char *name)
  7.1407 +{
  7.1408 +	void *symbol = SDL_OSX_dlsym(handle, name);
  7.1409 +	if ( symbol == NULL ) {
  7.1410 +		SDL_SetError("Failed loading %s: %s", name, (const char *)SDL_OSX_dlerror());
  7.1411 +	}
  7.1412 +	return(symbol);
  7.1413 +}
  7.1414 +
  7.1415 +void SDL_UnloadObject(void *handle)
  7.1416 +{
  7.1417 +	if ( handle != NULL ) {
  7.1418 +		SDL_OSX_dlclose(handle);
  7.1419 +	}
  7.1420 +}
  7.1421 +
  7.1422 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/loadso/mint/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     8.3 @@ -0,0 +1,74 @@
     8.4 +/*
     8.5 +    SDL - Simple DirectMedia Layer
     8.6 +    Copyright (C) 1997-2004 Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Library General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Library General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Library General Public
    8.19 +    License along with this library; if not, write to the Free
    8.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    slouken@libsdl.org
    8.24 +*/
    8.25 +
    8.26 +#ifdef SAVE_RCSID
    8.27 +static char rcsid =
    8.28 + "@(#) $Id$";
    8.29 +#endif
    8.30 +
    8.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    8.32 +/* System dependent library loading routines                           */
    8.33 +
    8.34 +#if !SDL_INTERNAL_BUILDING_LOADSO
    8.35 +#error Do not compile directly...compile src/SDL_loadso.c instead!
    8.36 +#endif
    8.37 +
    8.38 +/* please use the "dummy" driver if you don't have LDG support enabled. */
    8.39 +#if !defined(__MINT__) || !defined(ENABLE_LDG)
    8.40 +#error Compiling for the wrong platform?
    8.41 +#endif
    8.42 +
    8.43 +#include <stdio.h>
    8.44 +#include <gem.h>
    8.45 +#include <ldg.h>
    8.46 +
    8.47 +#include "SDL_types.h"
    8.48 +#include "SDL_error.h"
    8.49 +#include "SDL_loadso.h"
    8.50 +
    8.51 +void *SDL_LoadObject(const char *sofile)
    8.52 +{
    8.53 +	const char *loaderror = "Unknown error";
    8.54 +	void *handle = (void *)ldg_open((char *)sofile, ldg_global);
    8.55 +	if ( handle == NULL ) {
    8.56 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
    8.57 +	}
    8.58 +	return(handle);
    8.59 +}
    8.60 +
    8.61 +void *SDL_LoadFunction(void *handle, const char *name)
    8.62 +{
    8.63 +	const char *loaderror = "Unknown error";
    8.64 +	void *symbol = (void *)ldg_find((char *)name, (LDG *)handle);
    8.65 +	if ( symbol == NULL ) {
    8.66 +		SDL_SetError("Failed loading %s: %s", name, loaderror);
    8.67 +	}
    8.68 +	return(symbol);
    8.69 +}
    8.70 +
    8.71 +void SDL_UnloadObject(void *handle)
    8.72 +{
    8.73 +	if ( handle != NULL ) {
    8.74 +		ldg_close((LDG *)handle, ldg_global);
    8.75 +	}
    8.76 +}
    8.77 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/loadso/windows/SDL_loadso.c	Thu Nov 17 03:15:05 2005 +0000
     9.3 @@ -0,0 +1,150 @@
     9.4 +/*
     9.5 +    SDL - Simple DirectMedia Layer
     9.6 +    Copyright (C) 1997-2004 Sam Lantinga
     9.7 +
     9.8 +    This library is free software; you can redistribute it and/or
     9.9 +    modify it under the terms of the GNU Library General Public
    9.10 +    License as published by the Free Software Foundation; either
    9.11 +    version 2 of the License, or (at your option) any later version.
    9.12 +
    9.13 +    This library is distributed in the hope that it will be useful,
    9.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.16 +    Library General Public License for more details.
    9.17 +
    9.18 +    You should have received a copy of the GNU Library General Public
    9.19 +    License along with this library; if not, write to the Free
    9.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.21 +
    9.22 +    Sam Lantinga
    9.23 +    slouken@libsdl.org
    9.24 +*/
    9.25 +
    9.26 +#ifdef SAVE_RCSID
    9.27 +static char rcsid =
    9.28 + "@(#) $Id$";
    9.29 +#endif
    9.30 +
    9.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    9.32 +/* System dependent library loading routines                           */
    9.33 +
    9.34 +#if !SDL_INTERNAL_BUILDING_LOADSO
    9.35 +#error Do not compile directly...compile src/SDL_loadso.c instead!
    9.36 +#endif
    9.37 +
    9.38 +#if !defined(WIN32) && !defined(_WIN32_WCE)
    9.39 +#error Compiling for the wrong platform?
    9.40 +#endif
    9.41 +
    9.42 +#include <stdio.h>
    9.43 +#include <windows.h>
    9.44 +
    9.45 +#include "SDL_types.h"
    9.46 +#include "SDL_error.h"
    9.47 +#include "SDL_loadso.h"
    9.48 +
    9.49 +void *SDL_LoadObject(const char *sofile)
    9.50 +{
    9.51 +	void *handle = NULL;
    9.52 +	const char *loaderror = "Unknown error";
    9.53 +
    9.54 +#if defined(_WIN32_WCE)
    9.55 +	char errbuf[512];
    9.56 +
    9.57 +	wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t));
    9.58 +	wchar_t *sofile_t = malloc((MAX_PATH+1) * sizeof(wchar_t));
    9.59 +
    9.60 +	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, MAX_PATH);
    9.61 +	handle = (void *)LoadLibrary(sofile_t);
    9.62 +
    9.63 +	/* Generate an error message if all loads failed */
    9.64 +	if ( handle == NULL ) {
    9.65 +		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
    9.66 +					FORMAT_MESSAGE_FROM_SYSTEM),
    9.67 +				NULL, GetLastError(), 
    9.68 +				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    9.69 +				errbuf_t, SDL_TABLESIZE(errbuf), NULL);
    9.70 +		WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL);
    9.71 +		loaderror = errbuf;
    9.72 +	}
    9.73 +
    9.74 +	free(sofile_t);
    9.75 +	free(errbuf_t);
    9.76 +
    9.77 +#else /*if defined(WIN32)*/
    9.78 +	char errbuf[512];
    9.79 +
    9.80 +	handle = (void *)LoadLibrary(sofile);
    9.81 +
    9.82 +	/* Generate an error message if all loads failed */
    9.83 +	if ( handle == NULL ) {
    9.84 +		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
    9.85 +					FORMAT_MESSAGE_FROM_SYSTEM),
    9.86 +				NULL, GetLastError(), 
    9.87 +				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    9.88 +				errbuf, SDL_TABLESIZE(errbuf), NULL);
    9.89 +		loaderror = errbuf;
    9.90 +	}
    9.91 +#endif
    9.92 +
    9.93 +	if ( handle == NULL ) {
    9.94 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
    9.95 +	}
    9.96 +	return(handle);
    9.97 +}
    9.98 +
    9.99 +void *SDL_LoadFunction(void *handle, const char *name)
   9.100 +{
   9.101 +	void *symbol = NULL;
   9.102 +	const char *loaderror = "Unknown error";
   9.103 +
   9.104 +#if defined(_WIN32_WCE)
   9.105 +	char errbuf[512];
   9.106 +	int length = strlen(name);
   9.107 +
   9.108 +	wchar_t *name_t = malloc((length + 1) * sizeof(wchar_t));
   9.109 +	wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t));
   9.110 +
   9.111 +	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length);
   9.112 +
   9.113 +	symbol = (void *)GetProcAddress((HMODULE)handle, name_t);
   9.114 +	if ( symbol == NULL ) {
   9.115 +		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
   9.116 +					FORMAT_MESSAGE_FROM_SYSTEM),
   9.117 +				NULL, GetLastError(), 
   9.118 +				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   9.119 +				errbuf_t, SDL_TABLESIZE(errbuf), NULL);
   9.120 +		WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL);
   9.121 +		loaderror = errbuf;
   9.122 +	}
   9.123 +
   9.124 +	free(name_t);
   9.125 +	free(errbuf_t);
   9.126 +
   9.127 +#else /*if defined(WIN32)*/
   9.128 +	char errbuf[512];
   9.129 +
   9.130 +	symbol = (void *)GetProcAddress((HMODULE)handle, name);
   9.131 +	if ( symbol == NULL ) {
   9.132 +		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
   9.133 +					FORMAT_MESSAGE_FROM_SYSTEM),
   9.134 +				NULL, GetLastError(), 
   9.135 +				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   9.136 +				errbuf, SDL_TABLESIZE(errbuf), NULL);
   9.137 +		loaderror = errbuf;
   9.138 +	}
   9.139 +#endif
   9.140 +
   9.141 +	if ( symbol == NULL ) {
   9.142 +		SDL_SetError("Failed loading %s: %s", name, loaderror);
   9.143 +	}
   9.144 +	return(symbol);
   9.145 +}
   9.146 +
   9.147 +void SDL_UnloadObject(void *handle)
   9.148 +{
   9.149 +	if ( handle != NULL ) {
   9.150 +		FreeLibrary((HMODULE)handle);
   9.151 +	}
   9.152 +}
   9.153 +