diff options
| author | Courtney Goeltzenleuchter <courtney@LunarG.com> | 2014-08-01 14:18:11 -0600 |
|---|---|---|
| committer | Courtney Goeltzenleuchter <courtney@LunarG.com> | 2014-08-01 18:19:42 -0600 |
| commit | 44895fa9e1f8fc77b2005918c8bb54f2549d392f (patch) | |
| tree | 8fecd56fc5433504c62d9bfde1fc61df251a13dd /loader/loader.c | |
| parent | db2d9569882017bc555eb2e269facb701bce6729 (diff) | |
| download | usermoji-44895fa9e1f8fc77b2005918c8bb54f2549d392f.tar.xz | |
loader: Scans for libXGL libraries.
loader_icd_scan now scans the system default libraries
/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl
or the LIBXGL_DRIVERS_PATH environment variable looking
for a file of the form libXGL_. When found it will try to
dlopen the library and call the initialization and DbgRegister
calls to setup the ICD. The ICD is responsible for figuring out
what, if any, HW is on the system that it can manage.
Diffstat (limited to 'loader/loader.c')
| -rw-r--r-- | loader/loader.c | 112 |
1 files changed, 83 insertions, 29 deletions
diff --git a/loader/loader.c b/loader/loader.c index 4e5f231f..86087a2a 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -24,10 +24,14 @@ #include <stdio.h> #include <stdlib.h> +#include <dirent.h> #include <stdarg.h> #include <stdbool.h> #include <string.h> +#include <sys/syscall.h> +#include <unistd.h> + #include <dlfcn.h> #include <pthread.h> @@ -36,6 +40,8 @@ #include "loader.generated" +typedef XGL_RESULT (*LoadT)(); +typedef XGL_RESULT (*UnloadT)(); typedef XGL_RESULT (XGLAPI *InitAndEnumerateGpusT)(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, XGL_UINT maxGpus, XGL_UINT* pGpuCount, XGL_PHYSICAL_GPU* pGpus); typedef XGL_RESULT (XGLAPI *DbgRegisterMsgCallbackT)(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData); typedef XGL_RESULT (XGLAPI *DbgUnregisterMsgCallbackT)(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback); @@ -44,6 +50,8 @@ typedef XGL_RESULT (XGLAPI *DbgSetGlobalOptionT)(XGL_INT dbgOption, XGL_SIZE dat struct loader_icd { void *handle; + LoadT Load; + UnloadT Unload; InitAndEnumerateGpusT InitAndEnumerateGpus; DbgRegisterMsgCallbackT DbgRegisterMsgCallback; DbgUnregisterMsgCallbackT DbgUnregisterMsgCallback; @@ -171,6 +179,7 @@ static void loader_log(XGL_DBG_MSG_TYPE msg_type, XGL_INT msg_code, static void loader_icd_destroy(struct loader_icd *icd) { + icd->Unload(); dlclose(icd->handle); free(icd); } @@ -199,6 +208,8 @@ loader_icd_create(const char *filename) return NULL; \ } \ } while (0) + LOOKUP(icd, Load); + LOOKUP(icd, Unload); LOOKUP(icd, InitAndEnumerateGpus); LOOKUP(icd, DbgRegisterMsgCallback); LOOKUP(icd, DbgUnregisterMsgCallback); @@ -255,36 +266,79 @@ static XGL_RESULT loader_icd_set_global_options(const struct loader_icd *icd) return XGL_SUCCESS; } -static void -loader_icd_scan(void) -{ - /* XXX How to discover ICDs? */ - static const char *filenames[] = { - "libmesaxgl.so", - "libintelxgl.so", - "libxgl.so", - }; - int i; - - for (i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) { - struct loader_icd *icd; - - icd = loader_icd_create(filenames[i]); - if (!icd) { - continue; - } - - if (loader_icd_set_global_options(icd) != XGL_SUCCESS || - loader_icd_register_msg_callbacks(icd) != XGL_SUCCESS) { - loader_log(XGL_DBG_MSG_WARNING, 0, - "%s ignored: failed to migrate settings", filenames[i]); - loader_icd_destroy(icd); - continue; - } +#ifndef DEFAULT_XGL_DRIVERS_PATH +// TODO: Is this a good default location? +// Need to search for both 32bit and 64bit ICDs +#define DEFAULT_XGL_DRIVERS_PATH "/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl" +#endif - /* prepend to the list */ - icd->next = loader.icds; - loader.icds = icd; +/** + * Try to \c loader_icd_scan XGL driver(s). + * + * This function scans the default system path or path + * specified by the \c LIBXGL_DRIVERS_PATH environment variable in + * order to find loadable XGL ICDs with the name of libXGL_*. + * + * \returns + * void; but side effect is to set loader_icd_scanned to true + */ +static void loader_icd_scan(void) +{ + const char *libPaths, *p, *next; + DIR *sysdir; + struct dirent *dent; + char icd_library[1024]; + int len; + + libPaths = NULL; + if (geteuid() == getuid()) { + /* don't allow setuid apps to use LIBXGL_DRIVERS_PATH */ + libPaths = getenv("LIBXGL_DRIVERS_PATH"); + } + if (libPaths == NULL) + libPaths = DEFAULT_XGL_DRIVERS_PATH; + + for (p = libPaths; *p; p = next) { + next = strchr(p, ':'); + if (next == NULL) { + len = strlen(p); + next = p + len; + } + else { + len = next - p; + next++; + } + + sysdir = opendir(p); + if (sysdir) { + dent = readdir(sysdir); + while (dent) { + /* look for ICDs starting with "libXGL_" */ + if (!strncmp(dent->d_name, "libXGL_", 7)) { + struct loader_icd *icd; + + snprintf(icd_library, 1024, "%s/%s",p,dent->d_name); + + icd = loader_icd_create(icd_library); + if (icd) { + if (XGL_SUCCESS == icd->Load() && + XGL_SUCCESS == loader_icd_set_global_options(icd) && + XGL_SUCCESS == loader_icd_register_msg_callbacks(icd)) { + /* prepend to the list */ + icd->next = loader.icds; + loader.icds = icd; + } else { + loader_log(XGL_DBG_MSG_WARNING, 0, + "%s ignored: failed to migrate settings", icd_library); + loader_icd_destroy(icd); + } + } + } + + dent = readdir(sysdir); + } + closedir(sysdir); + } } /* we have nothing to log anymore */ |
