loader: Factor out driver library loading code

Separate the path-building and dlopen() portion of
loader_open_driver() from the DRI extension
loading logic. The former will be shared by the
GBM backend loading logic in a subsequent change.

Signed-off-by: James Jones <jajones@nvidia.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9902>
This commit is contained in:
James Jones 2021-04-22 23:17:08 -07:00 committed by Marge Bot
parent 49e56c3c0d
commit bc343154f8
2 changed files with 56 additions and 20 deletions

View File

@ -517,23 +517,25 @@ loader_get_extensions_name(const char *driver_name)
}
/**
* Opens a DRI driver using its driver name, returning the __DRIextension
* entrypoints.
* Opens a driver or backend using its name, returning the library handle.
*
* \param driverName - a name like "i965", "radeon", "nouveau", etc.
* \param out_driver - Address where the dlopen() return value will be stored.
* \param lib_suffix - a suffix to append to the driver name to generate the
* full library name.
* \param search_path_vars - NULL-terminated list of env vars that can be used
* to override the DEFAULT_DRIVER_DIR search path.
* \param default_search_path - a colon-separted list of directories used if
* search_path_vars is NULL or none of the vars are set in the environment.
* \param warn_on_fail - Log a warning if the driver is not found.
*/
const struct __DRIextensionRec **
loader_open_driver(const char *driver_name,
void **out_driver_handle,
const char **search_path_vars)
void *
loader_open_driver_lib(const char *driver_name,
const char *lib_suffix,
const char **search_path_vars,
const char *default_search_path,
bool warn_on_fail)
{
char path[PATH_MAX], *search_paths, *next, *end;
char *get_extensions_name;
const struct __DRIextensionRec **extensions = NULL;
const struct __DRIextensionRec **(*get_extensions)(void);
char path[PATH_MAX];
const char *search_paths, *next, *end;
search_paths = NULL;
if (geteuid() == getuid() && search_path_vars) {
@ -544,12 +546,12 @@ loader_open_driver(const char *driver_name,
}
}
if (search_paths == NULL)
search_paths = DEFAULT_DRIVER_DIR;
search_paths = default_search_path;
void *driver = NULL;
char *dl_error = NULL;
const char *dl_error = NULL;
end = search_paths + strlen(search_paths);
for (char *p = search_paths; p < end; p = next + 1) {
for (const char *p = search_paths; p < end; p = next + 1) {
int len;
next = strchr(p, ':');
if (next == NULL)
@ -557,11 +559,13 @@ loader_open_driver(const char *driver_name,
len = next - p;
#if USE_ELF_TLS
snprintf(path, sizeof(path), "%.*s/tls/%s_dri.so", len, p, driver_name);
snprintf(path, sizeof(path), "%.*s/tls/%s%s.so", len,
p, driver_name, lib_suffix);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
if (driver == NULL) {
snprintf(path, sizeof(path), "%.*s/%s_dri.so", len, p, driver_name);
snprintf(path, sizeof(path), "%.*s/%s%s.so", len,
p, driver_name, lib_suffix);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (driver == NULL) {
dl_error = dlerror();
@ -575,14 +579,39 @@ loader_open_driver(const char *driver_name,
}
if (driver == NULL) {
log_(_LOADER_WARNING, "MESA-LOADER: failed to open %s: %s (search paths %s)\n",
driver_name, dl_error, search_paths);
*out_driver_handle = NULL;
if (warn_on_fail) {
log_(_LOADER_WARNING,
"MESA-LOADER: failed to open %s: %s (search paths %s, suffix %s)\n",
driver_name, dl_error, search_paths, lib_suffix);
}
return NULL;
}
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
return driver;
}
/**
* 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 *get_extensions_name;
const struct __DRIextensionRec **extensions = NULL;
const struct __DRIextensionRec **(*get_extensions)(void);
void *driver = loader_open_driver_lib(driver_name, "_dri", search_path_vars,
DEFAULT_DRIVER_DIR, true);
get_extensions_name = loader_get_extensions_name(driver_name);
if (get_extensions_name) {
get_extensions = dlsym(driver, get_extensions_name);

View File

@ -49,6 +49,13 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
char *
loader_get_driver_for_fd(int fd);
void *
loader_open_driver_lib(const char *driver_name,
const char *lib_suffix,
const char **search_path_vars,
const char *default_search_path,
bool warn_on_fail);
const struct __DRIextensionRec **
loader_open_driver(const char *driver_name,
void **out_driver_handle,