From d971a4230d54069c996bca78b6ed6a6a23377821 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 Nov 2018 13:54:49 -0800 Subject: [PATCH] loader: Factor out the common driver opening logic from each loader. I copied the code from egl_dri2.c, but the functionality was equivalent between all the loaders other than their particular environment variables. v2: Drop the logging function equivalent to loader_default_logger() (requested by Eric, Emil). Move the SCons workaround across. Drop the now-unused driGetDriverExtensions() declaration that was lost in a rebase. Reviewed-by: Eric Engestrom (v1) Reviewed-by: Emil Velikov (v1) --- src/egl/Makefile.am | 3 +- src/egl/drivers/dri2/egl_dri2.c | 75 +++----------------------- src/egl/meson.build | 3 -- src/gbm/Makefile.am | 1 - src/gbm/backends/dri/gbm_dri.c | 84 +++++------------------------ src/gbm/meson.build | 1 - src/glx/Makefile.am | 1 - src/glx/SConscript | 2 - src/glx/dri_common.c | 94 +++------------------------------ src/glx/meson.build | 1 - src/loader/Makefile.am | 1 + src/loader/SConscript | 2 + src/loader/loader.c | 90 +++++++++++++++++++++++++++++++ src/loader/loader.h | 7 +++ src/loader/meson.build | 4 +- 15 files changed, 131 insertions(+), 238 deletions(-) diff --git a/src/egl/Makefile.am b/src/egl/Makefile.am index 24a8e96a8e1..7269912d96f 100644 --- a/src/egl/Makefile.am +++ b/src/egl/Makefile.am @@ -119,8 +119,7 @@ AM_CFLAGS += \ -I$(top_srcdir)/src/egl/drivers/dri2 \ -I$(top_srcdir)/src/gbm/backends/dri \ -I$(top_builddir)/src/egl/wayland/wayland-drm \ - -I$(top_srcdir)/src/egl/wayland/wayland-drm \ - -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" + -I$(top_srcdir)/src/egl/wayland/wayland-drm nodist_libEGL_common_la_SOURCES = \ $(dri2_backend_GENERATED_FILES) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index af2b3a6fa8f..0be9235835d 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -483,75 +483,14 @@ static const __DRIextension ** dri2_open_driver(_EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - const __DRIextension **extensions = NULL; - char path[PATH_MAX], *search_paths, *next, *end; - char *get_extensions_name; - const __DRIextension **(*get_extensions)(void); - - search_paths = NULL; - if (geteuid() == getuid()) { - /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ - search_paths = getenv("LIBGL_DRIVERS_PATH"); - } - if (search_paths == NULL) - search_paths = DEFAULT_DRIVER_DIR; - - dri2_dpy->driver = NULL; - end = search_paths + strlen(search_paths); - for (char *p = search_paths; p < end; p = next + 1) { - int len; - next = strchr(p, ':'); - if (next == NULL) - next = end; - - len = next - p; -#if GLX_USE_TLS - snprintf(path, sizeof path, - "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name); - dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); -#endif - if (dri2_dpy->driver == NULL) { - snprintf(path, sizeof path, - "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name); - dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - if (dri2_dpy->driver == NULL) - _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror()); - } - /* not need continue to loop all paths once the driver is found */ - if (dri2_dpy->driver != NULL) - break; - } - - if (dri2_dpy->driver == NULL) { - _eglLog(_EGL_WARNING, - "DRI2: failed to open %s (search paths %s)", - dri2_dpy->driver_name, search_paths); - return NULL; - } - - _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); - - get_extensions_name = loader_get_extensions_name(dri2_dpy->driver_name); - if (get_extensions_name) { - get_extensions = dlsym(dri2_dpy->driver, get_extensions_name); - if (get_extensions) { - extensions = get_extensions(); - } else { - _eglLog(_EGL_DEBUG, "driver does not expose %s(): %s\n", - get_extensions_name, dlerror()); - } - free(get_extensions_name); - } - - if (!extensions) - extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - _eglLog(_EGL_WARNING, - "DRI2: driver exports no extensions (%s)", dlerror()); - dlclose(dri2_dpy->driver); - } + static const char *search_path_vars[] = { + "LIBGL_DRIVERS_PATH", + NULL, + }; - return extensions; + return loader_open_driver(dri2_dpy->driver_name, + &dri2_dpy->driver, + search_path_vars); } EGLBoolean diff --git a/src/egl/meson.build b/src/egl/meson.build index 8c0ffea8b40..372842967d3 100644 --- a/src/egl/meson.build +++ b/src/egl/meson.build @@ -93,9 +93,6 @@ if with_dri2 'drivers/dri2/egl_dri2.h', 'drivers/dri2/egl_dri2_fallbacks.h', ) - c_args_for_egl += [ - '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path), - ] if with_platform_x11 files_egl += files('drivers/dri2/platform_x11.c') diff --git a/src/gbm/Makefile.am b/src/gbm/Makefile.am index 5097212cda0..bb246ecebf5 100644 --- a/src/gbm/Makefile.am +++ b/src/gbm/Makefile.am @@ -42,7 +42,6 @@ libgbm_la_SOURCES += \ $(gbm_dri_FILES) AM_CFLAGS += \ - -DDEFAULT_DRIVER_DIR='"$(DRI_DRIVER_SEARCH_DIR)"' \ $(LIBDRM_CFLAGS) \ $(PTHREADSTUBS_CFLAGS) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index f32c0cd9885..aeb13962cdc 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -304,28 +304,6 @@ dri_bind_extensions(struct gbm_dri_device *dri, static const __DRIextension ** dri_open_driver(struct gbm_dri_device *dri) { - const __DRIextension **extensions = NULL; - char path[PATH_MAX], *search_paths, *p, *next, *end; - char *get_extensions_name; - - search_paths = NULL; - /* don't allow setuid apps to use LIBGL_DRIVERS_PATH or GBM_DRIVERS_PATH */ - if (geteuid() == getuid()) { - /* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH - * is recommended over GBM_DRIVERS_PATH. - */ - search_paths = getenv("GBM_DRIVERS_PATH"); - - /* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set. - * LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH. - */ - if (search_paths == NULL) { - search_paths = getenv("LIBGL_DRIVERS_PATH"); - } - } - if (search_paths == NULL) - search_paths = DEFAULT_DRIVER_DIR; - /* Temporarily work around dri driver libs that need symbols in libglapi * but don't automatically link it in. */ @@ -334,56 +312,18 @@ dri_open_driver(struct gbm_dri_device *dri) */ dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL); - dri->driver = NULL; - end = search_paths + strlen(search_paths); - for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) { - int len; - next = strchr(p, ':'); - if (next == NULL) - next = end; - - len = next - p; -#if GLX_USE_TLS - snprintf(path, sizeof path, - "%.*s/tls/%s_dri.so", len, p, dri->driver_name); - dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); -#endif - if (dri->driver == NULL) { - snprintf(path, sizeof path, - "%.*s/%s_dri.so", len, p, dri->driver_name); - dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - } - /* not need continue to loop all paths once the driver is found */ - if (dri->driver != NULL) - break; - } - - if (dri->driver == NULL) { - fprintf(stderr, "gbm: failed to open any driver (search paths %s)\n", - search_paths); - fprintf(stderr, "gbm: Last dlopen error: %s\n", dlerror()); - return NULL; - } - - get_extensions_name = loader_get_extensions_name(dri->driver_name); - if (get_extensions_name) { - const __DRIextension **(*get_extensions)(void); - - get_extensions = dlsym(dri->driver, get_extensions_name); - free(get_extensions_name); - - if (get_extensions) - extensions = get_extensions(); - } - - if (!extensions) - extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror()); - dlclose(dri->driver); - } - - return extensions; + static const char *search_path_vars[] = { + /* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH + * is recommended over GBM_DRIVERS_PATH. + */ + "GBM_DRIVERS_PATH" + /* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set. + * LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH. + */ + "LIBGL_DRIVERS_PATH", + NULL + }; + return loader_open_driver(dri->driver_name, &dri->driver, search_path_vars); } static int diff --git a/src/gbm/meson.build b/src/gbm/meson.build index 719f9c1a9b8..007f50a9ae3 100644 --- a/src/gbm/meson.build +++ b/src/gbm/meson.build @@ -37,7 +37,6 @@ incs_gbm = [ if with_dri2 files_gbm += files('backends/dri/gbm_dri.c', 'backends/dri/gbm_driint.h') deps_gbm += dep_libdrm # TODO: pthread-stubs - args_gbm += '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path) endif if with_platform_wayland deps_gbm += dep_wayland_server diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am index 8f9d80c9f41..d208ce14bb7 100644 --- a/src/glx/Makefile.am +++ b/src/glx/Makefile.am @@ -40,7 +40,6 @@ AM_CFLAGS = \ $(VISIBILITY_CFLAGS) \ $(EXTRA_DEFINES_XF86VIDMODE) \ -D_REENTRANT \ - -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ $(DEFINES) \ $(LIBDRM_CFLAGS) \ $(DRI2PROTO_CFLAGS) \ diff --git a/src/glx/SConscript b/src/glx/SConscript index 83c62e22f8c..7555fb0568c 100644 --- a/src/glx/SConscript +++ b/src/glx/SConscript @@ -26,8 +26,6 @@ env.Append(CPPDEFINES = [ '_REENTRANT', ]) -env.Append(CPPDEFINES = ['DEFAULT_DRIVER_DIR=\\"/usr/local/lib/dri\\"']) - env.Prepend(LIBS = [ libloader, mesautil, diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index b4712a6038b..fb8a29f0993 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -77,9 +77,6 @@ dri_message(int level, const char *f, ...) #define GL_LIB_NAME "libGL.so.1" #endif -static const __DRIextension ** -driGetDriverExtensions(void *handle, const char *driver_name); - /** * Try to \c dlopen the named driver. * @@ -97,98 +94,23 @@ driGetDriverExtensions(void *handle, const char *driver_name); _X_HIDDEN const __DRIextension ** driOpenDriver(const char *driverName, void **out_driver_handle) { - void *glhandle, *handle; - const char *libPaths, *p, *next; - char realDriverName[200]; - int len; + void *glhandle; /* Attempt to make sure libGL symbols will be visible to the driver */ glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL); - libPaths = NULL; - if (geteuid() == getuid()) { - /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ - libPaths = getenv("LIBGL_DRIVERS_PATH"); - if (!libPaths) - libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */ - } - if (libPaths == NULL) - libPaths = DEFAULT_DRIVER_DIR; - - handle = NULL; - for (p = libPaths; *p; p = next) { - next = strchr(p, ':'); - if (next == NULL) { - len = strlen(p); - next = p + len; - } - else { - len = next - p; - next++; - } - -#ifdef GLX_USE_TLS - snprintf(realDriverName, sizeof realDriverName, - "%.*s/tls/%s_dri.so", len, p, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); -#endif - - if (handle == NULL) { - snprintf(realDriverName, sizeof realDriverName, - "%.*s/%s_dri.so", len, p, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); - } - - if (handle != NULL) - break; - else - InfoMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); - } + static const char *search_path_vars[] = { + "LIBGL_DRIVERS_PATH", + "LIBGL_DRIVERS_DIR", /* deprecated */ + NULL + }; - if (!handle) - ErrorMessageF("unable to load driver: %s_dri.so\n", driverName); + const __DRIextension **extensions = + loader_open_driver(driverName, out_driver_handle, search_path_vars); if (glhandle) dlclose(glhandle); - const __DRIextension **extensions = driGetDriverExtensions(handle, - driverName); - if (!extensions) { - dlclose(handle); - handle = NULL; - } - - *out_driver_handle = handle; - return extensions; -} - -static const __DRIextension ** -driGetDriverExtensions(void *handle, const char *driver_name) -{ - const __DRIextension **extensions = NULL; - const __DRIextension **(*get_extensions)(void); - char *get_extensions_name = loader_get_extensions_name(driver_name); - - if (get_extensions_name) { - get_extensions = dlsym(handle, get_extensions_name); - if (get_extensions) { - free(get_extensions_name); - return get_extensions(); - } else { - InfoMessageF("driver does not expose %s(): %s\n", - get_extensions_name, dlerror()); - free(get_extensions_name); - } - } - - extensions = dlsym(handle, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); - return NULL; - } - return extensions; } diff --git a/src/glx/meson.build b/src/glx/meson.build index dd8ba60ad80..1de35fca6bc 100644 --- a/src/glx/meson.build +++ b/src/glx/meson.build @@ -134,7 +134,6 @@ endif gl_lib_cargs = [ '-D_REENTRANT', - '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path), ] if dep_xxf86vm.found() diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am index 76252564281..3c22e0ae7e6 100644 --- a/src/loader/Makefile.am +++ b/src/loader/Makefile.am @@ -28,6 +28,7 @@ noinst_LTLIBRARIES = libloader.la AM_CPPFLAGS = \ -I$(top_builddir)/src/util/ \ -DUSE_DRICONF \ + -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ $(DEFINES) \ -I$(top_srcdir)/include \ -I$(top_srcdir)/include/drm-uapi \ diff --git a/src/loader/SConscript b/src/loader/SConscript index f70654f43ae..6a315642c2c 100644 --- a/src/loader/SConscript +++ b/src/loader/SConscript @@ -12,6 +12,8 @@ if env['drm']: env.PkgUseModules('DRM') env.Append(CPPDEFINES = ['HAVE_LIBDRM']) +env.Append(CPPDEFINES = ['DEFAULT_DRIVER_DIR=\\"/usr/local/lib/dri\\"']) + # parse Makefile.sources sources = env.ParseSourceList('Makefile.sources', 'LOADER_C_FILES') diff --git a/src/loader/loader.c b/src/loader/loader.c index 041a59212be..05140b6d18f 100644 --- a/src/loader/loader.c +++ b/src/loader/loader.c @@ -26,6 +26,7 @@ * Rob Clark */ +#include #include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #ifdef MAJOR_IN_MKDEV #include #endif @@ -510,3 +512,91 @@ loader_get_extensions_name(const char *driver_name) return name; } + +/** + * Opens a DRI driver using its driver name, returning the __DRIextension + * entrypoints. + * + * \param driverName - a name like "i965", "radeon", "nouveau", etc. + * \param out_driver - Address where the dlopen() return value will be stored. + * \param search_path_vars - NULL-terminated list of env vars that can be used + * to override the DEFAULT_DRIVER_DIR search path. + */ +const struct __DRIextensionRec ** +loader_open_driver(const char *driver_name, + void **out_driver_handle, + const char **search_path_vars) +{ + char path[PATH_MAX], *search_paths, *next, *end; + char *get_extensions_name; + const struct __DRIextensionRec **extensions = NULL; + const struct __DRIextensionRec **(*get_extensions)(void); + + search_paths = NULL; + if (geteuid() == getuid() && search_path_vars) { + for (int i = 0; search_path_vars[i] != NULL; i++) { + search_paths = getenv(search_path_vars[i]); + if (search_paths) + break; + } + } + if (search_paths == NULL) + search_paths = DEFAULT_DRIVER_DIR; + + void *driver = NULL; + end = search_paths + strlen(search_paths); + for (char *p = search_paths; p < end; p = next + 1) { + int len; + next = strchr(p, ':'); + if (next == NULL) + next = end; + + len = next - p; +#if GLX_USE_TLS + snprintf(path, sizeof(path), "%.*s/tls/%s_dri.so", len, p, driver_name); + driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); +#endif + if (driver == NULL) { + snprintf(path, sizeof(path), "%.*s/%s_dri.so", len, p, driver_name); + driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (driver == NULL) + log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n", + path, dlerror()); + } + /* not need continue to loop all paths once the driver is found */ + if (driver != NULL) + break; + } + + if (driver == NULL) { + log_(_LOADER_WARNING, "MESA-LOADER: failed to open %s (search paths %s)\n", + driver_name, search_paths); + *out_driver_handle = NULL; + return NULL; + } + + log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path); + + get_extensions_name = loader_get_extensions_name(driver_name); + if (get_extensions_name) { + get_extensions = dlsym(driver, get_extensions_name); + if (get_extensions) { + extensions = get_extensions(); + } else { + log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n", + get_extensions_name, dlerror()); + } + free(get_extensions_name); + } + + if (!extensions) + extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + log_(_LOADER_WARNING, + "MESA-LOADER: driver exports no extensions (%s)\n", dlerror()); + dlclose(driver); + } + + *out_driver_handle = driver; + return extensions; +} diff --git a/src/loader/loader.h b/src/loader/loader.h index 7b4dd01144f..779ec44b75d 100644 --- a/src/loader/loader.h +++ b/src/loader/loader.h @@ -33,6 +33,8 @@ extern "C" { #endif +struct __DRIextensionRec; + /* Helpers to figure out driver and device name, eg. from pci-id, etc. */ int @@ -47,6 +49,11 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id); char * loader_get_driver_for_fd(int fd); +const struct __DRIextensionRec ** +loader_open_driver(const char *driver_name, + void **out_driver_handle, + const char **search_path_vars); + char * loader_get_device_name_for_fd(int fd); diff --git a/src/loader/meson.build b/src/loader/meson.build index 76fcae2cb44..e280ba41cc2 100644 --- a/src/loader/meson.build +++ b/src/loader/meson.build @@ -39,7 +39,9 @@ libloader = static_library( 'loader', ['loader.c', 'loader.h', 'pci_id_driver_map.c', 'pci_id_driver_map.h', xmlpool_options_h], - c_args : [c_vis_args, '-DUSE_DRICONF'], + c_args : [c_vis_args, '-DUSE_DRICONF', + '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path), +], include_directories : [inc_include, inc_src, inc_util], dependencies : [dep_libdrm, dep_thread], build_by_default : false, -- 2.30.2