Skip to content

Commit

Permalink
Fill in some SDL 1.2 overrides we need.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Feb 8, 2013
1 parent 4a0f1ac commit 4c2bc5f
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 23 deletions.
4 changes: 4 additions & 0 deletions macelf/macelf.h
Expand Up @@ -37,6 +37,10 @@ int insert_symbol(const char *fn, void *ptr);
int remove_symbol(const char *fn);
void missing_symbol_called(const char *missing_symbol);
void warn_missing_native_symbol(const char *lib, const char *fn);
void *mactrampoline_dlopen(const char *fname, int flags);
void *mactrampoline_dlsym(void *lib, const char *sym);
int mactrampoline_dlclose(void *lib);
char *mactrampoline_dlerror(void);

#if MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12
void *load_native_sdl12(void);
Expand Down
9 changes: 5 additions & 4 deletions macelf/mactrampolines.c
Expand Up @@ -837,7 +837,8 @@ static pthread_mutex_t loader_mutex;
// Obviously we want to map dlopen and friends through MojoELF. We can't let
// you talk to Mach-O binaries directly in any case, due to calling
// convention differences.
static void *mactrampoline_dlopen(const char *fname, int flags)
// These aren't static, because other sources need to use them.
void *mactrampoline_dlopen(const char *fname, int flags)
{
STUBBED("trap a few libs like SDL, OpenGL, X11, OpenAL...");
STUBBED("flags are ignored");
Expand All @@ -847,23 +848,23 @@ static void *mactrampoline_dlopen(const char *fname, int flags)
return retval;
} // mactrampoline_dlopen

static void *mactrampoline_dlsym(void *lib, const char *sym)
void *mactrampoline_dlsym(void *lib, const char *sym)
{
pthread_mutex_lock(&loader_mutex);
void *retval = MOJOELF_dlsym(lib, sym);
pthread_mutex_unlock(&loader_mutex);
return retval;
} // mactrampoline_dlsym

static int mactrampoline_dlclose(void *lib)
int mactrampoline_dlclose(void *lib)
{
pthread_mutex_lock(&loader_mutex);
MOJOELF_dlclose(lib);
pthread_mutex_unlock(&loader_mutex);
return 0;
} // mactrampoline_dlclose

static char *mactrampoline_dlerror(void)
char *mactrampoline_dlerror(void)
{
STUBBED("This should make a temp copy if this is really non-const");
return (char *) MOJOELF_dlerror();
Expand Down
15 changes: 7 additions & 8 deletions macelf/mactrampolines_sdl12.h
Expand Up @@ -8,14 +8,13 @@

// Do not #pragma once this file, it's intentionally included multiple times.

//MACTRAMPOLINE(void *,SDL_LoadObject,(const char *a),(a),return)
//MACTRAMPOLINE(void *,SDL_LoadFunction,(void *a, const char *b),(a,b),return)
//MACTRAMPOLINE(void,SDL_UnloadObject,(void *a),(a),)
//MACTRAMPOLINE(int,SDL_GL_LoadLibrary,(const char *a),(a),return)
//MACTRAMPOLINE(void *,SDL_GL_GetProcAddress,(const char *a),(a),return)
//MACTRAMPOLINE(void,SDL_SetError,(const char *fmt, ...)

//MACTRAMPOLINE(int,SDL_Init,(Uint32 a),(a),return)
MACTRAMPOLINE_OVERRIDE(int,SDL_Init,(Uint32 a))
MACTRAMPOLINE_OVERRIDE(void *,SDL_LoadObject,(const char *a))
MACTRAMPOLINE_OVERRIDE(void *,SDL_LoadFunction,(void *a, const char *b))
MACTRAMPOLINE_OVERRIDE(void,SDL_UnloadObject,(void *a))
MACTRAMPOLINE_OVERRIDE(int,SDL_GL_LoadLibrary,(const char *a))
MACTRAMPOLINE_OVERRIDE(void *,SDL_GL_GetProcAddress,(const char *a))
MACTRAMPOLINE_OVERRIDE(void,SDL_SetError,(const char *fmt, ...))

MACTRAMPOLINE(int,SDL_InitSubSystem,(Uint32 a),(a),return)
MACTRAMPOLINE(void,SDL_QuitSubSystem,(Uint32 a),(a),)
Expand Down
95 changes: 84 additions & 11 deletions macelf/mactrampolines_sdl12.m
Expand Up @@ -8,31 +8,39 @@

// Native overrides for SDL 1.2...

// You absolutely must build this file with -mstackrealign.
// A lot of these functions are here only as a trampoline: the ELF code calls
// it, it aligns the stack to 16 bytes thanks to -mstackrealign, and then
// calls the actual function in the system library.

#include "macelf.h"

#if MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12

#include <stdio.h>
#include <stdarg.h>
#include <ApplicationServices/ApplicationServices.h>
#include <Cocoa/Cocoa.h>
#include <dlfcn.h>

#include "SDL.h"


#define MACTRAMPOLINE(typ,fn,params,args,ret) \
#define MACTRAMPOLINE_OVERRIDE(typ,fn,params) \
typedef typ (*nativefntype_sdl12_##fn) params; \
static nativefntype_sdl12_##fn pnativefn_sdl12_##fn = NULL; \
static nativefntype_sdl12_##fn pnativefn_sdl12_##fn = NULL;
#define MACTRAMPOLINE(typ,fn,params,args,ret) \
MACTRAMPOLINE_OVERRIDE(typ,fn,params) \
static typ mactrampoline_sdl12_##fn params { \
ret pnativefn_sdl12_##fn args; \
}
#include "mactrampolines_sdl12.h"
#undef MACTRAMPOLINE_OVERRIDE
#undef MACTRAMPOLINE


// override a few things...

// SDL_Init needs a little startup code, since we don't use SDLmain.
typedef int (*nativefntype_sdl12_SDL_Init)(Uint32 flags);
static nativefntype_sdl12_SDL_Init pnativefn_sdl12_SDL_Init = NULL;
static int mactrampoline_sdl12_SDL_Init(Uint32 flags)
{
static int first_call = 1;
Expand Down Expand Up @@ -62,6 +70,73 @@ static int mactrampoline_sdl12_SDL_Init(Uint32 flags)
return pnativefn_sdl12_SDL_Init(flags);
} // mactrampoline_sdl12_SDL_Init

// SDL's loadso functions have to go through our dlopen() trampoline.
// Otherwise, it can't load ELFs, respect our overrides, and have trampolines
// to align the stack, etc.
static void *mactrampoline_sdl12_SDL_LoadObject(const char *soname)
{
void *retval = mactrampoline_dlopen(soname, RTLD_NOW);
if (!retval)
pnativefn_sdl12_SDL_SetError("dlopen('%s') failed: %s", soname, mactrampoline_dlerror());
return retval;
} // mactrampoline_sdl12_SDL_LoadObject

static void *mactrampoline_sdl12_SDL_LoadFunction(void *lib, const char *sym)
{
void *retval = mactrampoline_dlsym(lib, sym);
if (!retval)
pnativefn_sdl12_SDL_SetError("dlsym('%s') failed: %s", sym, mactrampoline_dlerror());
return retval;
} // mactrampoline_sdl12_SDL_LoadFunction

static void mactrampoline_sdl12_SDL_UnloadObject(void *lib)
{
mactrampoline_dlclose(lib);
} // mactrampoline_sdl12_SDL_UnloadObject

// Let us use our native override for libGL (this would need to be more
// robust if Apple had a real OpenGL GetProcAddress function instead of just
// letting you dlsym() their library).
static void *gllib = NULL;
static int mactrampoline_sdl12_SDL_GL_LoadLibrary(const char *soname)
{
if (!pnativefn_sdl12_SDL_WasInit(SDL_INIT_VIDEO))
{
pnativefn_sdl12_SDL_SetError("%s", "Video subsystem has not been initialized");
return -1;
} // if

// we ignore (soname); you always get Apple's OpenGL (but we need to
// trampoline everything, of course).
if (gllib == NULL)
gllib = mactrampoline_sdl12_SDL_LoadObject("libGL.so.1"); // will trigger our native override.
return gllib ? 0 : -1;
} // mactrampoline_sdl12_SDL_GL_LoadLibrary

static void *mactrampoline_sdl12_SDL_GL_GetProcAddress(const char *sym)
{
if (gllib == NULL)
{
pnativefn_sdl12_SDL_SetError("%s", "No GL driver has been loaded");
return NULL;
} // if

return mactrampoline_sdl12_SDL_LoadFunction(gllib, sym);
} // mactrampoline_sdl12_SDL_GL_GetProcAddress

static void mactrampoline_sdl12_SDL_SetError(const char *fmt, ...)
{
// we had to override just because this has varargs.
va_list ap;
va_start(ap, fmt);
char *str = NULL;
const int rc = vasprintf(&str, fmt, ap);
va_end(ap);
if ((rc >= 0) && (str != NULL)) // if not, oh well.
pnativefn_sdl12_SDL_SetError("%s", str);
free(str);
} // mactrampoline_sdl12_SDL_SetError


void *load_native_sdl12(void)
{
Expand All @@ -71,9 +146,6 @@ static int mactrampoline_sdl12_SDL_Init(Uint32 flags)
fprintf(stderr, "WARNING: tried to load native SDL 1.2 and failed: %s\n", dlerror());
else
{
pnativefn_sdl12_SDL_Init = (nativefntype_sdl12_SDL_Init) dlsym(handle, "SDL_Init");
insert_symbol("SDL_Init", mactrampoline_sdl12_SDL_Init);

#define MACTRAMPOLINE(typ,fn,params,args,ret) { \
pnativefn_sdl12_##fn = (nativefntype_sdl12_##fn) dlsym(handle, #fn); \
if (pnativefn_sdl12_##fn == NULL) { \
Expand All @@ -82,8 +154,10 @@ static int mactrampoline_sdl12_SDL_Init(Uint32 flags)
insert_symbol(#fn, mactrampoline_sdl12_##fn); \
} \
}
#define MACTRAMPOLINE_OVERRIDE(typ,fn,params) MACTRAMPOLINE(typ,fn,params,XXX,XXX);
#include "mactrampolines_sdl12.h"
#undef MACTRAMPOLINE
#undef MACTRAMPOLINE_OVERRIDE
} // else

return handle;
Expand All @@ -97,11 +171,10 @@ void unload_native_sdl12(void *handle)
remove_symbol(#fn); \
pnativefn_sdl12_##fn = NULL; \
}
#define MACTRAMPOLINE_OVERRIDE(typ,fn,params) MACTRAMPOLINE(typ,fn,params,XXX,XXX);
#include "mactrampolines_sdl12.h"
#undef MACTRAMPOLINE

remove_symbol("SDL_Init");
pnativefn_sdl12_SDL_Init = NULL;
#undef MACTRAMPOLINE_OVERRIDE

dlclose(handle);
} // if
Expand Down

0 comments on commit 4c2bc5f

Please sign in to comment.