summaryrefslogtreecommitdiffstats
path: root/src/loader/loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader/loader.c')
-rw-r--r--src/loader/loader.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/loader/loader.c b/src/loader/loader.c
index a5bd7692e6e..63b977aa743 100644
--- a/src/loader/loader.c
+++ b/src/loader/loader.c
@@ -67,6 +67,8 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <assert.h>
+#include <dlfcn.h>
#include "loader.h"
#ifndef __NOT_HAVE_DRM_H
@@ -92,11 +94,37 @@ static void (*log_)(int level, const char *fmt, ...) = default_logger;
#ifdef HAVE_LIBUDEV
#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 *
udev_device_new_from_fd(struct udev *udev, int fd)
{
struct udev_device *device;
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) {
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_device *device = NULL, *parent;
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;
@@ -240,6 +276,12 @@ loader_get_device_name_for_fd(int fd)
struct udev *udev;
struct udev_device *device;
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();
device = udev_device_new_from_fd(udev, fd);