From 53ae0bbffe18072e4d8408bad5d8448d0b4392c3 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 1 May 2018 11:16:46 -0400 Subject: dispatch: Stop implicitly loading libraries from do_dlsym Mostly this is to get all the calls to get_dlopen_handle nicely isolated so they're easier to reason about. Signed-off-by: Adam Jackson --- src/dispatch_common.c | 87 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/src/dispatch_common.c b/src/dispatch_common.c index 244938b..085661f 100644 --- a/src/dispatch_common.c +++ b/src/dispatch_common.c @@ -175,6 +175,7 @@ #ifdef __APPLE__ #define GLX_LIB "/opt/X11/lib/libGL.1.dylib" +#define OPENGL_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" #elif defined(__ANDROID__) #define GLX_LIB "libGLESv2.so" #else @@ -190,6 +191,7 @@ #define EGL_LIB "libEGL.dll" #define GLES1_LIB "libGLES_CM.dll" #define GLES2_LIB "libGLESv2.dll" +#define OPENGL_LIB "OPENGL32" #else #define EGL_LIB "libEGL.so.1" #define GLES1_LIB "libGLESv1_CM.so.1" @@ -326,15 +328,11 @@ get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail) } static void * -do_dlsym(void **handle, const char *lib_name, const char *name, - bool exit_on_fail) +do_dlsym(void **handle, const char *name, bool exit_on_fail) { void *result; const char *error = ""; - if (!get_dlopen_handle(handle, lib_name, exit_on_fail)) - return NULL; - #ifdef _WIN32 result = GetProcAddress(*handle, name); #else @@ -343,7 +341,7 @@ do_dlsym(void **handle, const char *lib_name, const char *name, error = dlerror(); #endif if (!result && exit_on_fail) { - fprintf(stderr,"%s() not found in %s: %s\n", name, lib_name, error); + fprintf(stderr, "%s() not found: %s\n", name, error); exit(1); } @@ -552,16 +550,27 @@ epoxy_internal_has_gl_extension(const char *ext, bool invalid_op_mode) } } -void * -epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails) +static bool +epoxy_load_glx(bool exit_if_fails) { #ifdef GLVND_GLX_LIB /* prefer the glvnd library if it exists */ if (!api.glx_handle) get_dlopen_handle(&api.glx_handle, GLVND_GLX_LIB, false); #endif + if (!api.glx_handle) + get_dlopen_handle(&api.glx_handle, GLX_LIB, exit_if_fails); + + return api.glx_handle != NULL; +} + +void * +epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails) +{ + if (epoxy_load_glx(exit_if_fails)) + return do_dlsym(&api.glx_handle, name, exit_if_fails); - return do_dlsym(&api.glx_handle, GLX_LIB, name, exit_if_fails); + return NULL; } /** @@ -624,10 +633,19 @@ epoxy_conservative_has_gl_extension(const char *ext) return epoxy_internal_has_gl_extension(ext, true); } +static bool +epoxy_load_egl(bool exit_if_fails) +{ + return get_dlopen_handle(&api.egl_handle, EGL_LIB, exit_if_fails); +} + void * epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails) { - return do_dlsym(&api.egl_handle, EGL_LIB, name, exit_if_fails); + if (epoxy_load_egl(exit_if_fails)) + return do_dlsym(&api.egl_handle, name, exit_if_fails); + + return NULL; } void * @@ -642,31 +660,32 @@ epoxy_glx_dlsym(const char *name) return epoxy_conservative_glx_dlsym(name, true); } -void * -epoxy_gl_dlsym(const char *name) +static void +epoxy_load_gl(void) { -#ifdef _WIN32 - return do_dlsym(&api.gl_handle, "OPENGL32", name, true); -#elif defined(__APPLE__) - return do_dlsym(&api.gl_handle, - "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", - name, true); + if (api.gl_handle) + return; + +#if defined(_WIN32) || defined(__APPLE__) + get_dlopen_handle(&api.gl_handle, OPENGL_LIB, true); #else - void *sym; -# if defined(OPENGL_LIB) +#if defined(OPENGL_LIB) if (!api.gl_handle) get_dlopen_handle(&api.gl_handle, OPENGL_LIB, false); -# endif +#endif - if (api.gl_handle) - return do_dlsym(&api.gl_handle, NULL, name, true); + get_dlopen_handle(&api.glx_handle, GLX_LIB, true); + api.gl_handle = api.glx_handle; +#endif +} - sym = do_dlsym(&api.glx_handle, GLX_LIB, name, true); - api.gl_handle = api.glx_handle; /* skip the dlopen next time */ +void * +epoxy_gl_dlsym(const char *name) +{ + epoxy_load_gl(); - return sym; -#endif + return do_dlsym(&api.gl_handle, name, true); } void * @@ -675,7 +694,8 @@ epoxy_gles1_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - return do_dlsym(&api.gles1_handle, GLES1_LIB, name, true); + get_dlopen_handle(&api.gles1_handle, GLES1_LIB, true); + return do_dlsym(&api.gles1_handle, name, true); } } @@ -685,7 +705,8 @@ epoxy_gles2_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - return do_dlsym(&api.gles2_handle, GLES2_LIB, name, true); + get_dlopen_handle(&api.gles2_handle, GLES2_LIB, true); + return do_dlsym(&api.gles2_handle, name, true); } } @@ -705,10 +726,12 @@ epoxy_gles3_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - void *func = do_dlsym(&api.gles2_handle, GLES2_LIB, name, false); + if (get_dlopen_handle(&api.gles2_handle, GLES2_LIB, false)) { + void *func = do_dlsym(&api.gles2_handle, GLES2_LIB, false); - if (func) - return func; + if (func) + return func; + } return epoxy_get_proc_address(name); } -- cgit v1.2.1 From 90db0069b43f40c071510fa4e3b67f6affebd8e2 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 1 May 2018 11:34:23 -0400 Subject: dispatch: Load EGL/GLX provider lib from epoxy_has_{egl,glx}() Now that we're being conservative about probing libraries, these entrypoints would not succeed unless the caller had already dlopened stuff themselves, or had explicitly linked against the provider library. Both of those are exactly not what we want. Signed-off-by: Adam Jackson --- src/dispatch_common.c | 36 ++++++++++++++++++------------------ src/dispatch_common.h | 3 +++ src/dispatch_egl.c | 10 ++++++---- src/dispatch_glx.c | 14 ++++++++------ 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/dispatch_common.c b/src/dispatch_common.c index 085661f..dedf664 100644 --- a/src/dispatch_common.c +++ b/src/dispatch_common.c @@ -292,7 +292,7 @@ library_init(void) } static bool -get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail) +get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail, bool load) { if (*handle) return true; @@ -308,7 +308,7 @@ get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail) pthread_mutex_lock(&api.mutex); if (!*handle) { int flags = RTLD_LAZY | RTLD_LOCAL; - if (!exit_on_fail) + if (!load) flags |= RTLD_NOLOAD; *handle = dlopen(lib_name, flags); @@ -550,16 +550,16 @@ epoxy_internal_has_gl_extension(const char *ext, bool invalid_op_mode) } } -static bool -epoxy_load_glx(bool exit_if_fails) +bool +epoxy_load_glx(bool exit_if_fails, bool load) { #ifdef GLVND_GLX_LIB /* prefer the glvnd library if it exists */ if (!api.glx_handle) - get_dlopen_handle(&api.glx_handle, GLVND_GLX_LIB, false); + get_dlopen_handle(&api.glx_handle, GLVND_GLX_LIB, false, load); #endif if (!api.glx_handle) - get_dlopen_handle(&api.glx_handle, GLX_LIB, exit_if_fails); + get_dlopen_handle(&api.glx_handle, GLX_LIB, exit_if_fails, load); return api.glx_handle != NULL; } @@ -567,7 +567,7 @@ epoxy_load_glx(bool exit_if_fails) void * epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails) { - if (epoxy_load_glx(exit_if_fails)) + if (epoxy_load_glx(exit_if_fails, exit_if_fails)) return do_dlsym(&api.glx_handle, name, exit_if_fails); return NULL; @@ -633,16 +633,16 @@ epoxy_conservative_has_gl_extension(const char *ext) return epoxy_internal_has_gl_extension(ext, true); } -static bool -epoxy_load_egl(bool exit_if_fails) +bool +epoxy_load_egl(bool exit_if_fails, bool load) { - return get_dlopen_handle(&api.egl_handle, EGL_LIB, exit_if_fails); + return get_dlopen_handle(&api.egl_handle, EGL_LIB, exit_if_fails, load); } void * epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails) { - if (epoxy_load_egl(exit_if_fails)) + if (epoxy_load_egl(exit_if_fails, exit_if_fails)) return do_dlsym(&api.egl_handle, name, exit_if_fails); return NULL; @@ -667,15 +667,15 @@ epoxy_load_gl(void) return; #if defined(_WIN32) || defined(__APPLE__) - get_dlopen_handle(&api.gl_handle, OPENGL_LIB, true); + get_dlopen_handle(&api.gl_handle, OPENGL_LIB, true, true); #else #if defined(OPENGL_LIB) if (!api.gl_handle) - get_dlopen_handle(&api.gl_handle, OPENGL_LIB, false); + get_dlopen_handle(&api.gl_handle, OPENGL_LIB, false, true); #endif - get_dlopen_handle(&api.glx_handle, GLX_LIB, true); + get_dlopen_handle(&api.glx_handle, GLX_LIB, true, true); api.gl_handle = api.glx_handle; #endif } @@ -694,7 +694,7 @@ epoxy_gles1_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - get_dlopen_handle(&api.gles1_handle, GLES1_LIB, true); + get_dlopen_handle(&api.gles1_handle, GLES1_LIB, true, true); return do_dlsym(&api.gles1_handle, name, true); } } @@ -705,7 +705,7 @@ epoxy_gles2_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - get_dlopen_handle(&api.gles2_handle, GLES2_LIB, true); + get_dlopen_handle(&api.gles2_handle, GLES2_LIB, true, true); return do_dlsym(&api.gles2_handle, name, true); } } @@ -726,7 +726,7 @@ epoxy_gles3_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - if (get_dlopen_handle(&api.gles2_handle, GLES2_LIB, false)) { + if (get_dlopen_handle(&api.gles2_handle, GLES2_LIB, false, true)) { void *func = do_dlsym(&api.gles2_handle, GLES2_LIB, false); if (func) @@ -806,7 +806,7 @@ epoxy_get_bootstrap_proc_address(const char *name) * non-X11 ES2 context from loading a bunch of X11 junk). */ #if PLATFORM_HAS_EGL - get_dlopen_handle(&api.egl_handle, EGL_LIB, false); + get_dlopen_handle(&api.egl_handle, EGL_LIB, false, true); if (api.egl_handle) { int version = 0; switch (epoxy_egl_get_current_gl_context_api()) { diff --git a/src/dispatch_common.h b/src/dispatch_common.h index 9675cff..fc99635 100644 --- a/src/dispatch_common.h +++ b/src/dispatch_common.h @@ -172,6 +172,9 @@ bool epoxy_conservative_has_wgl_extension(const char *name); void *epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails); void *epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails); +bool epoxy_load_glx(bool exit_if_fails, bool load); +bool epoxy_load_egl(bool exit_if_fails, bool load); + #define glBegin_unwrapped epoxy_glBegin_unwrapped #define glEnd_unwrapped epoxy_glEnd_unwrapped extern void UNWRAPPED_PROTO(glBegin_unwrapped)(GLenum primtype); diff --git a/src/dispatch_egl.c b/src/dispatch_egl.c index f555a58..3f0c789 100644 --- a/src/dispatch_egl.c +++ b/src/dispatch_egl.c @@ -109,11 +109,13 @@ epoxy_has_egl(void) #if !PLATFORM_HAS_EGL return false; #else - EGLDisplay* (* pf_eglGetCurrentDisplay) (void); + if (epoxy_load_egl(false, true)) { + EGLDisplay* (* pf_eglGetCurrentDisplay) (void); - pf_eglGetCurrentDisplay = epoxy_conservative_egl_dlsym("eglGetCurrentDisplay", false); - if (pf_eglGetCurrentDisplay) - return true; + pf_eglGetCurrentDisplay = epoxy_conservative_egl_dlsym("eglGetCurrentDisplay", false); + if (pf_eglGetCurrentDisplay) + return true; + } return false; #endif /* PLATFORM_HAS_EGL */ diff --git a/src/dispatch_glx.c b/src/dispatch_glx.c index b5ad42e..e395564 100644 --- a/src/dispatch_glx.c +++ b/src/dispatch_glx.c @@ -158,12 +158,14 @@ epoxy_has_glx(Display *dpy) #if !PLATFORM_HAS_GLX return false; #else - Bool (* pf_glXQueryExtension) (Display *, int *, int *); - int error_base, event_base; - - pf_glXQueryExtension = epoxy_conservative_glx_dlsym("glXQueryExtension", false); - if (pf_glXQueryExtension && pf_glXQueryExtension(dpy, &error_base, &event_base)) - return true; + if (epoxy_load_glx(false, true)) { + Bool (* pf_glXQueryExtension) (Display *, int *, int *); + int error_base, event_base; + + pf_glXQueryExtension = epoxy_conservative_glx_dlsym("glXQueryExtension", false); + if (pf_glXQueryExtension && pf_glXQueryExtension(dpy, &error_base, &event_base)) + return true; + } return false; #endif /* !PLATFORM_HAS_GLX */ -- cgit v1.2.1