loader: Use dlsym to get our udev symbols instead of explicit linking.
Steam links against libudev.so.0, while we're linking against libudev.so.1. The result is that the symbol names (which are the same in the two libraries) end up conflicting, and some of the usage of .so.1 calls the .so.0 bits, which have different internal structures, and segfaults happen. By using a dlopen() with RTLD_LOCAL, we can explicitly look for the symbols we want, while they get the symbols they want. Reviewed-by: Keith Packard <keithp@keithp.com> Reviewed-by: Kristian Høgsberg <krh@bitplanet.net> Tested-by: Alexandre Demers <alexandre.f.demers@gmail.com> Tested-by: Mike Lothian <mike@fireburn.co.uk>
This commit is contained in:
parent
d51dbe048a
commit
4556c73470
|
@ -858,7 +858,7 @@ xyesno)
|
||||||
|
|
||||||
if test x"$enable_dri3$have_libudev" = xyesyes; then
|
if test x"$enable_dri3$have_libudev" = xyesyes; then
|
||||||
X11_INCLUDES="$X11_INCLUDES $LIBUDEV_CFLAGS"
|
X11_INCLUDES="$X11_INCLUDES $LIBUDEV_CFLAGS"
|
||||||
GL_LIB_DEPS="$GL_LIB_DEPS $LIBUDEV_LIBS"
|
GL_LIB_DEPS="$GL_LIB_DEPS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# need DRM libs, $PTHREAD_LIBS, etc.
|
# need DRM libs, $PTHREAD_LIBS, etc.
|
||||||
|
|
|
@ -112,7 +112,7 @@ if HAVE_EGL_DRIVER_DRI2
|
||||||
AM_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
|
AM_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
|
||||||
AM_CFLAGS += -DHAVE_XCB_DRI2
|
AM_CFLAGS += -DHAVE_XCB_DRI2
|
||||||
libEGL_la_LIBADD += ../drivers/dri2/libegl_dri2.la
|
libEGL_la_LIBADD += ../drivers/dri2/libegl_dri2.la
|
||||||
libEGL_la_LIBADD += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIBS)
|
libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Provide compatibility with scripts for the old Mesa build system for
|
# Provide compatibility with scripts for the old Mesa build system for
|
||||||
|
|
|
@ -29,9 +29,6 @@ libloader_la_CPPFLAGS = \
|
||||||
$(VISIBILITY_CFLAGS) \
|
$(VISIBILITY_CFLAGS) \
|
||||||
$(LIBUDEV_CFLAGS)
|
$(LIBUDEV_CFLAGS)
|
||||||
|
|
||||||
libloader_la_LIBADD = \
|
|
||||||
$(LIBUDEV_LIBS)
|
|
||||||
|
|
||||||
if !HAVE_LIBDRM
|
if !HAVE_LIBDRM
|
||||||
libloader_la_CPPFLAGS += \
|
libloader_la_CPPFLAGS += \
|
||||||
-D__NOT_HAVE_DRM_H
|
-D__NOT_HAVE_DRM_H
|
||||||
|
@ -39,7 +36,7 @@ else
|
||||||
libloader_la_CPPFLAGS += \
|
libloader_la_CPPFLAGS += \
|
||||||
$(LIBDRM_CFLAGS)
|
$(LIBDRM_CFLAGS)
|
||||||
|
|
||||||
libloader_la_LIBADD += \
|
libloader_la_LIBADD = \
|
||||||
$(LIBDRM_LIBS)
|
$(LIBDRM_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
|
||||||
#ifndef __NOT_HAVE_DRM_H
|
#ifndef __NOT_HAVE_DRM_H
|
||||||
|
@ -92,11 +94,37 @@ static void (*log_)(int level, const char *fmt, ...) = default_logger;
|
||||||
#ifdef HAVE_LIBUDEV
|
#ifdef HAVE_LIBUDEV
|
||||||
#include <libudev.h>
|
#include <libudev.h>
|
||||||
|
|
||||||
|
static void *udev_handle = NULL;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
udev_dlopen_handle(void)
|
||||||
|
{
|
||||||
|
if (!udev_handle) {
|
||||||
|
udev_handle = dlopen("libudev.so.1", RTLD_LOCAL | RTLD_LAZY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return udev_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
asserted_dlsym(void *dlopen_handle, const char *name)
|
||||||
|
{
|
||||||
|
void *result = dlsym(dlopen_handle, name);
|
||||||
|
assert(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UDEV_SYMBOL(ret, name, args) \
|
||||||
|
ret (*name) args = asserted_dlsym(udev_dlopen_handle(), #name);
|
||||||
|
|
||||||
|
|
||||||
static inline struct udev_device *
|
static inline struct udev_device *
|
||||||
udev_device_new_from_fd(struct udev *udev, int fd)
|
udev_device_new_from_fd(struct udev *udev, int fd)
|
||||||
{
|
{
|
||||||
struct udev_device *device;
|
struct udev_device *device;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
UDEV_SYMBOL(struct udev_device *, udev_device_new_from_devnum,
|
||||||
|
(struct udev *udev, char type, dev_t devnum));
|
||||||
|
|
||||||
if (fstat(fd, &buf) < 0) {
|
if (fstat(fd, &buf) < 0) {
|
||||||
log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d", fd);
|
log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d", fd);
|
||||||
|
@ -119,6 +147,14 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
|
||||||
struct udev *udev = NULL;
|
struct udev *udev = NULL;
|
||||||
struct udev_device *device = NULL, *parent;
|
struct udev_device *device = NULL, *parent;
|
||||||
const char *pci_id;
|
const char *pci_id;
|
||||||
|
UDEV_SYMBOL(struct udev *, udev_new, (void));
|
||||||
|
UDEV_SYMBOL(struct udev_device *, udev_device_get_parent,
|
||||||
|
(struct udev_device *));
|
||||||
|
UDEV_SYMBOL(const char *, udev_device_get_property_value,
|
||||||
|
(struct udev_device *, const char *));
|
||||||
|
UDEV_SYMBOL(struct udev_device *, udev_device_unref,
|
||||||
|
(struct udev_device *));
|
||||||
|
UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *));
|
||||||
|
|
||||||
*chip_id = -1;
|
*chip_id = -1;
|
||||||
|
|
||||||
|
@ -240,6 +276,12 @@ loader_get_device_name_for_fd(int fd)
|
||||||
struct udev *udev;
|
struct udev *udev;
|
||||||
struct udev_device *device;
|
struct udev_device *device;
|
||||||
const char *const_device_name;
|
const char *const_device_name;
|
||||||
|
UDEV_SYMBOL(struct udev *, udev_new, (void));
|
||||||
|
UDEV_SYMBOL(const char *, udev_device_get_devnode,
|
||||||
|
(struct udev_device *));
|
||||||
|
UDEV_SYMBOL(struct udev_device *, udev_device_unref,
|
||||||
|
(struct udev_device *));
|
||||||
|
UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *));
|
||||||
|
|
||||||
udev = udev_new();
|
udev = udev_new();
|
||||||
device = udev_device_new_from_fd(udev, fd);
|
device = udev_device_new_from_fd(udev, fd);
|
||||||
|
|
Loading…
Reference in New Issue