From caa8d546aea211396beaebf6f811314ff5979c14 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 21 Sep 2013 11:34:47 -0700 Subject: [PATCH] Implement glXGetProcAdddress (and glXGetProcAddressARB) Since applications can use these functions to find their symbols, it's important that Glaze intercept these and ensure that the appropriate wrapped symbols are returned. This implementation allows the wrapping library to optionally implement glXGetProcAddress itself. If it does, it's responsible for implementing it correctly. If the wrapping library does not implement glXGetProcAddress, then Glaze's version will return a symbol from the wrapper if any exists. Otherwise, it will defer to the underlying glXGetProcAddress to do whatever it needs to do. --- glaze-gl.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ specs/Makefile | 3 ++ specs/glx.def | 2 -- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/glaze-gl.c b/glaze-gl.c index 14d24d7..e7dd728 100644 --- a/glaze-gl.c +++ b/glaze-gl.c @@ -137,6 +137,84 @@ resolve (const char *name) return dlsym (libgl_handle, name); } +void +(*glXGetProcAddress (const unsigned char *name))(void); + +void +(*glXGetProcAddress (const unsigned char *name))(void) +{ + static int first_call = 1; + static typeof (&glXGetProcAddress) wrapper_glXGetProcAddress; + static typeof (&glXGetProcAddress) libgl_glXGetProcAddress; + void *symbol; + + /* On the first call, check if the wrapper provides an + * implementation of this function. */ + if (first_call) { + wrapper_glXGetProcAddress = dlsym (wrapper_handle, + "glXGetProcAddress"); + libgl_glXGetProcAddress = dlsym (libgl_handle, + "glXGetProcAddress"); + first_call = 0; + } + + /* If the wrapper implements glXGetProcAddress itself, then it + * had better know best what to do. Just let it. */ + if (wrapper_glXGetProcAddress) + return wrapper_glXGetProcAddress (name); + + /* Otherwise, we need to resolve the name. + * + * The wrapper gets first choice on all symbols. */ + symbol = dlsym (wrapper_handle, (char *) name); + if (symbol) + return symbol; + + /* The wrapper doesn't care, so defer to the underlying + * glXGetProcAddress */ + return libgl_glXGetProcAddress (name); + +} + +void +(*glXGetProcAddressARB (const unsigned char *name))(void); + +void +(*glXGetProcAddressARB (const unsigned char *name))(void) +{ + static int first_call = 1; + static typeof (&glXGetProcAddressARB) wrapper_glXGetProcAddressARB; + static typeof (&glXGetProcAddressARB) libgl_glXGetProcAddressARB; + void *symbol; + + /* On the first call, check if the wrapper provides an + * implementation of this function. */ + if (first_call) { + wrapper_glXGetProcAddressARB = dlsym (wrapper_handle, + "glXGetProcAddressARB"); + libgl_glXGetProcAddressARB = dlsym (libgl_handle, + "glXGetProcAddressARB"); + first_call = 0; + } + + /* If the wrapper implements glXGetProcAddressARB itself, then + * it had better know best what to do. Just let it. */ + if (wrapper_glXGetProcAddressARB) + return wrapper_glXGetProcAddressARB (name); + + /* Otherwise, we need to resolve the name. + * + * The wrapper gets first choice on all symbols. */ + symbol = dlsym (wrapper_handle, (char *) name); + if (symbol) + return symbol; + + /* The wrapper doesn't care, so defer to the underlying + * glXGetProcAddressARB */ + return libgl_glXGetProcAddressARB (name); + +} + #define GLAZE_API(name) \ void * name() __attribute__((ifunc(#name "_resolver"))); \ static void * \ diff --git a/specs/Makefile b/specs/Makefile index b48a944..ea316f1 100644 --- a/specs/Makefile +++ b/specs/Makefile @@ -5,5 +5,8 @@ all: $(TARGETS) %.def: %.xml ./xml2def $? > $@ +glx.def: glx.xml + ./xml2def $? | grep -v GetProcAddress > $@ + clean: rm *.def diff --git a/specs/glx.def b/specs/glx.def index 90c9caa..fe7f698 100644 --- a/specs/glx.def +++ b/specs/glx.def @@ -54,8 +54,6 @@ GLAZE_API(glXGetFBConfigAttribSGIX) GLAZE_API(glXGetFBConfigFromVisualSGIX) GLAZE_API(glXGetFBConfigs) GLAZE_API(glXGetMscRateOML) -GLAZE_API(glXGetProcAddress) -GLAZE_API(glXGetProcAddressARB) GLAZE_API(glXGetSelectedEvent) GLAZE_API(glXGetSelectedEventSGIX) GLAZE_API(glXGetSyncValuesOML) -- 2.43.0