mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-25 07:48:24 +02:00
drm-shim: implement most readlink() without initializing the shim
This is to avoid a situation where jemalloc initialization calls readlink(), which then tries to use malloc during init_shim(). Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38350>
This commit is contained in:
parent
4bf8fd5121
commit
f3770643f6
1 changed files with 64 additions and 44 deletions
|
|
@ -96,14 +96,16 @@ REAL_FUNCTION_POINTER(fstat);
|
|||
REAL_FUNCTION_POINTER(fstat64);
|
||||
#endif
|
||||
|
||||
#define STRINGIZE2(x) #x
|
||||
#define STRINGIZE(x) STRINGIZE2(x)
|
||||
|
||||
static char render_node_dir[] = "/dev/dri/";
|
||||
/* Full path of /dev/dri/renderD* */
|
||||
static char *render_node_path;
|
||||
/* renderD* */
|
||||
static char *render_node_dirent_name;
|
||||
/* /sys/dev/char/major: */
|
||||
static int drm_device_path_len;
|
||||
static char *drm_device_path;
|
||||
static char drm_device_path[] = "/sys/dev/char/" STRINGIZE(DRM_MAJOR) ":";
|
||||
/* /sys/dev/char/major:minor/device */
|
||||
static int device_path_len;
|
||||
static char *device_path;
|
||||
|
|
@ -189,6 +191,43 @@ drm_shim_override_file(const char *contents, const char *path_format, ...)
|
|||
override->contents = strdup(contents);
|
||||
}
|
||||
|
||||
static uint32_t got_function_pointers = 0;
|
||||
|
||||
static void
|
||||
get_function_pointers(void)
|
||||
{
|
||||
if (p_atomic_cmpxchg(&got_function_pointers, 0, 1))
|
||||
return;
|
||||
|
||||
GET_FUNCTION_POINTER(access);
|
||||
GET_FUNCTION_POINTER(close);
|
||||
GET_FUNCTION_POINTER(closedir);
|
||||
GET_FUNCTION_POINTER(dup);
|
||||
GET_FUNCTION_POINTER(fcntl);
|
||||
GET_FUNCTION_POINTER(fopen);
|
||||
GET_FUNCTION_POINTER(ioctl);
|
||||
GET_FUNCTION_POINTER(mmap);
|
||||
GET_FUNCTION_POINTER(mmap64);
|
||||
GET_FUNCTION_POINTER(open);
|
||||
GET_FUNCTION_POINTER(opendir);
|
||||
GET_FUNCTION_POINTER(readdir);
|
||||
GET_FUNCTION_POINTER(readdir64);
|
||||
GET_FUNCTION_POINTER(readlink);
|
||||
GET_FUNCTION_POINTER(realpath);
|
||||
|
||||
#if HAS_XSTAT
|
||||
GET_FUNCTION_POINTER(__xstat);
|
||||
GET_FUNCTION_POINTER(__xstat64);
|
||||
GET_FUNCTION_POINTER(__fxstat);
|
||||
GET_FUNCTION_POINTER(__fxstat64);
|
||||
#else
|
||||
GET_FUNCTION_POINTER(stat);
|
||||
GET_FUNCTION_POINTER(stat64);
|
||||
GET_FUNCTION_POINTER(fstat);
|
||||
GET_FUNCTION_POINTER(fstat64);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t inited = 0;
|
||||
|
||||
static void
|
||||
|
|
@ -220,33 +259,7 @@ init_shim(void)
|
|||
_mesa_hash_string,
|
||||
_mesa_key_string_equal);
|
||||
|
||||
GET_FUNCTION_POINTER(access);
|
||||
GET_FUNCTION_POINTER(close);
|
||||
GET_FUNCTION_POINTER(closedir);
|
||||
GET_FUNCTION_POINTER(dup);
|
||||
GET_FUNCTION_POINTER(fcntl);
|
||||
GET_FUNCTION_POINTER(fopen);
|
||||
GET_FUNCTION_POINTER(ioctl);
|
||||
GET_FUNCTION_POINTER(mmap);
|
||||
GET_FUNCTION_POINTER(mmap64);
|
||||
GET_FUNCTION_POINTER(open);
|
||||
GET_FUNCTION_POINTER(opendir);
|
||||
GET_FUNCTION_POINTER(readdir);
|
||||
GET_FUNCTION_POINTER(readdir64);
|
||||
GET_FUNCTION_POINTER(readlink);
|
||||
GET_FUNCTION_POINTER(realpath);
|
||||
|
||||
#if HAS_XSTAT
|
||||
GET_FUNCTION_POINTER(__xstat);
|
||||
GET_FUNCTION_POINTER(__xstat64);
|
||||
GET_FUNCTION_POINTER(__fxstat);
|
||||
GET_FUNCTION_POINTER(__fxstat64);
|
||||
#else
|
||||
GET_FUNCTION_POINTER(stat);
|
||||
GET_FUNCTION_POINTER(stat64);
|
||||
GET_FUNCTION_POINTER(fstat);
|
||||
GET_FUNCTION_POINTER(fstat64);
|
||||
#endif
|
||||
get_function_pointers();
|
||||
|
||||
get_dri_render_node_minor();
|
||||
|
||||
|
|
@ -255,9 +268,6 @@ init_shim(void)
|
|||
render_node_path);
|
||||
}
|
||||
|
||||
drm_device_path_len =
|
||||
nfasprintf(&drm_device_path, "/sys/dev/char/%d:", DRM_MAJOR);
|
||||
|
||||
device_path_len =
|
||||
nfasprintf(&device_path,
|
||||
"/sys/dev/char/%d:%d/device",
|
||||
|
|
@ -272,30 +282,34 @@ init_shim(void)
|
|||
atexit(destroy_shim);
|
||||
}
|
||||
|
||||
static bool hide_drm_device_path(const char *path)
|
||||
static bool is_drm_device_path(const char *path)
|
||||
{
|
||||
if (render_node_minor == -1)
|
||||
return false;
|
||||
|
||||
/* String starts with /sys/dev/char/226: */
|
||||
if (strncmp(path, drm_device_path, sizeof(drm_device_path) - 1) == 0)
|
||||
return true;
|
||||
|
||||
/* String starts with /dev/dri/ */
|
||||
if (strncmp(path, render_node_dir, sizeof(render_node_dir) - 1) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool hide_drm_device_path(const char *path)
|
||||
{
|
||||
/* If the path looks like our fake render node device, then don't hide it.
|
||||
*/
|
||||
if (strncmp(path, device_path, device_path_len) == 0 ||
|
||||
strcmp(path, render_node_path) == 0)
|
||||
return false;
|
||||
|
||||
/* String starts with /sys/dev/char/226: but is not the fake render node.
|
||||
/* String looks like a device but is not the fake render node.
|
||||
* We want to hide all other drm devices for the shim.
|
||||
*/
|
||||
if (strncmp(path, drm_device_path, drm_device_path_len) == 0)
|
||||
return true;
|
||||
|
||||
/* String starts with /dev/dri/ but is not the fake render node. We want to
|
||||
* hide all other drm devices for the shim.
|
||||
*/
|
||||
if (strncmp(path, render_node_dir, sizeof(render_node_dir) - 1) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return is_drm_device_path(path);
|
||||
}
|
||||
|
||||
static int file_override_open(const char *path)
|
||||
|
|
@ -712,6 +726,12 @@ closedir(DIR *dir)
|
|||
PUBLIC ssize_t
|
||||
readlink(const char *path, char *buf, size_t size)
|
||||
{
|
||||
/* Shortcut to the real readlink so that jemalloc can use this. */
|
||||
if (!is_drm_device_path(path)) {
|
||||
get_function_pointers();
|
||||
return real_readlink(path, buf, size);
|
||||
}
|
||||
|
||||
init_shim();
|
||||
|
||||
if (hide_drm_device_path(path)) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue