[Mesa-dev] [shaderdb 2/2] intel_stub: update stubbing logic for newer mesa

Lionel Landwerlin lionel.g.landwerlin at intel.com
Tue Jan 8 00:17:17 UTC 2019


DRI2 backend of Mesa started relying more on libdrm to open DRM
devices nodes and opening multiple fds on a single node. This change
keeps track of up to 10 fds so that stub works again.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
 intel_stub.c | 98 +++++++++++++++++++++++++---------------------------
 1 file changed, 48 insertions(+), 50 deletions(-)

diff --git a/intel_stub.c b/intel_stub.c
index 8b8db64..9ac8ad3 100644
--- a/intel_stub.c
+++ b/intel_stub.c
@@ -23,9 +23,11 @@
 
 #define _GNU_SOURCE /* for RTLD_NEXT */
 
+#include <assert.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdarg.h>
 #include <errno.h>
@@ -37,6 +39,8 @@
 #include <dlfcn.h>
 #include <i915_drm.h>
 
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
 static void *(*libc_mmap)(void *addr, size_t len, int prot, int flags,
                           int fildes, off_t off);
 static void *(*libc_mmap64)(void *addr, size_t len, int prot, int flags,
@@ -52,7 +56,39 @@ static int (*libc__fxstat64)(int ver, int fd, struct stat64 *buf);
 static int (*libc_fcntl)(int fd, int cmd, int param);
 static ssize_t (*libc_readlink)(const char *pathname, char *buf, size_t bufsiz);
 
-static int drm_fd = 0x0000BEEF;
+int open64(const char*, int, ...) __attribute__((alias("open")));
+int fcntl64(int fd, int cmd, ...) __attribute__((alias("fcntl")));
+void* mmap64(void*, size_t, int, int, int, off_t) __attribute__((alias("mmap")));
+
+static int drm_fds[10];
+static int n_drm_fds = 0;
+
+static int create_drm_fd(int flags, mode_t mode)
+{
+	assert(n_drm_fds < ARRAY_SIZE(drm_fds));
+	drm_fds[n_drm_fds++] = libc_open("/dev/null", flags, mode);
+	return drm_fds[n_drm_fds - 1];
+}
+
+static void remove_drm_fd(int fd)
+{
+	for (int i = 0; i < n_drm_fds; i++) {
+		if (fd == drm_fds[i]) {
+			for (int j = i + 1; j < n_drm_fds; j++)
+				drm_fds[j - 1] = drm_fds[j];
+			n_drm_fds--;
+			return;
+		}
+	}
+}
+
+static bool is_drm_fd(int fd)
+{
+	for (int i = 0; i < n_drm_fds; i++)
+		if (fd == drm_fds[i])
+			return true;
+	return false;
+}
 
 #define DRM_MAJOR 226
 
@@ -89,45 +125,27 @@ open(const char *path, int flags, ...)
        va_list args;
        mode_t mode;
 
-       if (strcmp(path, "/dev/dri/renderD128") == 0)
-	       return drm_fd;
-
        va_start(args, flags);
        mode = va_arg(args, int);
        va_end(args);
 
-       return libc_open(path, flags, mode);
-}
-
-__attribute__ ((visibility ("default"))) int
-open64(const char *path, int flags, ...)
-{
-       va_list args;
-       mode_t mode;
-
        if (strcmp(path, "/dev/dri/renderD128") == 0)
-	       return drm_fd;
-
-       va_start(args, flags);
-       mode = va_arg(args, int);
-       va_end(args);
+	       return create_drm_fd(flags, mode);
 
-       return libc_open64(path, flags, mode);
+       return libc_open(path, flags, mode);
 }
 
 __attribute__ ((visibility ("default"))) int
 close(int fd)
 {
-	if (fd == drm_fd)
-		return 0;
-
+	remove_drm_fd(fd);
 	return libc_close(fd);
 }
 
 __attribute__ ((visibility ("default"))) int
 fstat(int fd, struct stat *buf)
 {
-	if (fd == drm_fd) {
+	if (is_drm_fd(fd)) {
 		buf->st_mode = S_IFCHR |
 			(S_IRWXG | S_IRGRP |  S_IRWXU | S_IRUSR);
 		buf->st_uid = 0;
@@ -141,7 +159,7 @@ fstat(int fd, struct stat *buf)
 __attribute__ ((visibility ("default"))) int
 fstat64(int fd, struct stat64 *buf)
 {
-	if (fd == drm_fd) {
+	if (is_drm_fd(fd)) {
 		buf->st_mode = S_IFCHR |
 			(S_IRWXG | S_IRGRP |  S_IRWXU | S_IRUSR);
 		buf->st_uid = 0;
@@ -155,7 +173,7 @@ fstat64(int fd, struct stat64 *buf)
 __attribute__ ((visibility ("default"))) int
 __fxstat(int ver, int fd, struct stat *buf)
 {
-	if (fd == drm_fd) {
+	if (is_drm_fd(fd)) {
 		buf->st_mode = S_IFCHR |
 			(S_IRWXG | S_IRGRP |  S_IRWXU | S_IRUSR);
 		buf->st_rdev = makedev(DRM_MAJOR, 0);
@@ -170,7 +188,7 @@ __fxstat(int ver, int fd, struct stat *buf)
 __attribute__ ((visibility ("default"))) int
 __fxstat64(int ver, int fd, struct stat64 *buf)
 {
-	if (fd == drm_fd) {
+	if (is_drm_fd(fd)) {
 		buf->st_mode = S_IFCHR |
 			(S_IRWXG | S_IRGRP |  S_IRWXU | S_IRUSR);
 		buf->st_rdev = makedev(DRM_MAJOR, 0);
@@ -188,8 +206,8 @@ fcntl(int fd, int cmd, ...)
 	va_list args;
 	int param;
 
-	if (fd == drm_fd && cmd == F_DUPFD_CLOEXEC)
-		return drm_fd;
+	if (is_drm_fd(fd) && cmd == F_DUPFD_CLOEXEC)
+		return create_drm_fd(O_RDWR, O_CLOEXEC);
 
 	va_start(args, cmd);
 	param = va_arg(args, int);
@@ -202,7 +220,7 @@ __attribute__ ((visibility ("default"))) void *
 mmap(void *addr, size_t len, int prot, int flags,
      int fildes, off_t off)
 {
-        if (fildes == drm_fd) {
+        if (is_drm_fd(fildes)) {
                 return libc_mmap(NULL, len, prot, flags | MAP_ANONYMOUS,
                                  -1, 0);
         } else {
@@ -210,19 +228,6 @@ mmap(void *addr, size_t len, int prot, int flags,
         }
 }
 
-__attribute__ ((visibility ("default"))) void *
-mmap64(void *addr, size_t len, int prot, int flags,
-       int fildes, off_t off)
-{
-        if (fildes == drm_fd) {
-                return libc_mmap64(NULL, len, prot, flags | MAP_ANONYMOUS,
-                                   -1, 0);
-        } else {
-                return libc_mmap64(addr, len, prot, flags, fildes, off);
-        }
-}
-
-
 __attribute__ ((visibility ("default"))) ssize_t
 readlink(const char *pathname, char *buf, size_t bufsiz)
 {
@@ -237,20 +242,13 @@ ioctl(int fd, unsigned long request, ...)
 {
 	va_list args;
 	void *argp;
-	struct stat buf;
 	char *pci_id;
 
 	va_start(args, request);
 	argp = va_arg(args, void *);
 	va_end(args);
 
-	if (_IOC_TYPE(request) == DRM_IOCTL_BASE &&
-	    drm_fd != fd && libc_fstat(fd, &buf) == 0 &&
-	    (buf.st_mode & S_IFMT) == S_IFCHR && major(buf.st_rdev) == DRM_MAJOR) {
-		drm_fd = fd;
-	}
-
-	if (fd == drm_fd) {
+	if (is_drm_fd(fd)) {
 		switch (request) {
                 case DRM_IOCTL_VERSION:
 			return dispatch_version(fd, request, argp);
-- 
2.20.1



More information about the mesa-dev mailing list