Skip to content

Commit

Permalink
Added native override for OpenGL, cleaned up native override code a l…
Browse files Browse the repository at this point in the history
…ittle.
  • Loading branch information
icculus committed Feb 8, 2013
1 parent 4c2bc5f commit 41879ad
Show file tree
Hide file tree
Showing 6 changed files with 2,870 additions and 20 deletions.
59 changes: 43 additions & 16 deletions macelf/macelf.c
Expand Up @@ -28,6 +28,10 @@ static int dependencies_missing = 0;
static int native_override_sdl12 = 1;
#endif

#if MACELF_SUPPORT_NATIVE_OVERRIDE_OPENGL
static int native_override_opengl = 1;
#endif

char *program_invocation_name = NULL;
const char *ld_library_path = NULL;

Expand Down Expand Up @@ -180,24 +184,30 @@ static void *mojoelf_loader(const char *soname, const char *rpath, const char *r
(strcmp(soname, "librt.so.1") == 0) )
return allocate_loaded_lib(soname, NULL);

#define DO_OVERRIDE(module, sonamestr) \
if ((native_override_##module) && (strcmp(soname, sonamestr) == 0)) { \
lib = allocate_loaded_lib(soname, NULL); \
if (lib) { \
lib->destruct = unload_native_##module; \
lib->opaque = load_native_##module(); \
if (!lib->opaque) { \
mojoelf_unloader(lib); \
lib = NULL; \
} \
} \
return lib; \
}

#if MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12
if ((native_override_sdl12) && (strcmp(soname, "libSDL-1.2.so.0") == 0))
{
lib = allocate_loaded_lib(soname, NULL);
if (lib)
{
lib->destruct = unload_native_sdl12;
lib->opaque = load_native_sdl12();
if (!lib->opaque)
{
mojoelf_unloader(lib);
lib = NULL;
} // if
} // if
return lib;
} // if
DO_OVERRIDE(sdl12, "libSDL-1.2.so.0");
#endif

#if MACELF_SUPPORT_NATIVE_OVERRIDE_OPENGL
DO_OVERRIDE(opengl, "libGL.so.1"); // oh, OpenGL. A hardware-specific SO in userspace. :/
#endif

#undef DO_OVERRIDE

//printf("Trying to load ELF soname '%s'!\n", soname);
int fd = find_soname_file(soname, rpath, runpath);
if (fd != -1)
Expand Down Expand Up @@ -406,11 +416,28 @@ static void setup_native_override(const char *item)
item++;
setting = 0;
} // if
else if (*item == '+')
{
item++;
setting = 1;
} // if

#define DO_OVERRIDE(module) \
if (strcmp(item, #module) == 0) { \
native_override_##module = setting; \
return; \
}

#if MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12
if (strcmp(item, "sdl12") == 0) { native_override_sdl12 = setting; return; }
DO_OVERRIDE(sdl12)
#endif

#if MACELF_SUPPORT_NATIVE_OVERRIDE_OPENGL
DO_OVERRIDE(opengl)
#endif

#undef DO_OVERRIDE

fprintf(stderr, "WARNING: ignoring unknown native override '%s'\n", item);
} // setup_native_override

Expand Down
15 changes: 11 additions & 4 deletions macelf/macelf.h
Expand Up @@ -13,10 +13,6 @@

// just some things shared between source files...

#ifndef MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12
#define MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12 1
#endif

#if 0
#define STUBBED(x) do {} while (0)
#else
Expand All @@ -42,11 +38,22 @@ void *mactrampoline_dlsym(void *lib, const char *sym);
int mactrampoline_dlclose(void *lib);
char *mactrampoline_dlerror(void);

#ifndef MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12
#define MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12 1
#endif
#if MACELF_SUPPORT_NATIVE_OVERRIDE_SDL12
void *load_native_sdl12(void);
void unload_native_sdl12(void *handle);
#endif

#ifndef MACELF_SUPPORT_NATIVE_OVERRIDE_OPENGL
#define MACELF_SUPPORT_NATIVE_OVERRIDE_OPENGL 1
#endif
#if MACELF_SUPPORT_NATIVE_OVERRIDE_OPENGL
void *load_native_opengl(void);
void unload_native_opengl(void *handle);
#endif

#endif

// end of macelf.h ...
107 changes: 107 additions & 0 deletions macelf/mactrampolines_opengl.c
@@ -0,0 +1,107 @@
/**
* MojoELF; load ELF binaries from a memory buffer.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/

// Native overrides for OpenGL...

// 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_OPENGL

#include <stdio.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>

// Deal with stuff that might not be in the Mac headers (yet).
#ifndef GL_NV_half_float
typedef unsigned short GLhalfNV;
#endif
#ifndef GL_OES_fixed_point
typedef GLint GLfixed;
#endif
#ifndef GL_ARB_cl_event
struct _cl_context;
struct _cl_event;
#endif
#ifndef GL_ARB_debug_output
typedef void (*GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#endif
#ifndef GL_AMD_debug_output
typedef void (*GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#endif
#ifndef GL_KHR_debug
typedef void (*GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#endif
#ifndef GL_NV_vdpau_interop
typedef GLintptr GLvdpauSurfaceNV;
#endif


#define MACTRAMPOLINE_OVERRIDE(typ,fn,params) \
typedef typ (*nativefntype_opengl_##fn) params; \
static nativefntype_opengl_##fn pnativefn_opengl_##fn = NULL;
#define MACTRAMPOLINE(typ,fn,params,args,ret) \
MACTRAMPOLINE_OVERRIDE(typ,fn,params) \
static typ mactrampoline_opengl_##fn params { \
ret pnativefn_opengl_##fn args; \
}
#include "mactrampolines_opengl.h"
#undef MACTRAMPOLINE_OVERRIDE
#undef MACTRAMPOLINE

void *load_native_opengl(void)
{
const char *libname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
void *handle = dlopen(libname, RTLD_NOW);
if (handle == NULL)
fprintf(stderr, "WARNING: tried to load native libGL and failed: %s\n", dlerror());
else
{
// if a symbol is missing, we don't care. We cast a wide net, and many are expected to not exist on Mac OS X.
#define MACTRAMPOLINE(typ,fn,params,args,ret) { \
pnativefn_opengl_##fn = (nativefntype_opengl_##fn) dlsym(handle, #fn); \
if (pnativefn_opengl_##fn != NULL) { \
insert_symbol(#fn, mactrampoline_opengl_##fn); \
} \
}
#define MACTRAMPOLINE_OVERRIDE(typ,fn,params) MACTRAMPOLINE(typ,fn,params,XXX,XXX);
#include "mactrampolines_opengl.h"
#undef MACTRAMPOLINE
#undef MACTRAMPOLINE_OVERRIDE
} // else

return handle;
} // load_native_opengl

void unload_native_opengl(void *handle)
{
if (handle != NULL)
{
#define MACTRAMPOLINE(typ,fn,params,args,ret) { \
remove_symbol(#fn); \
pnativefn_opengl_##fn = NULL; \
}
#define MACTRAMPOLINE_OVERRIDE(typ,fn,params) MACTRAMPOLINE(typ,fn,params,XXX,XXX);
#include "mactrampolines_opengl.h"
#undef MACTRAMPOLINE
#undef MACTRAMPOLINE_OVERRIDE

dlclose(handle);
} // if
} // unload_native_opengl

#endif

// end of mactrampolines_opengl.c ...

0 comments on commit 41879ad

Please sign in to comment.