From 72c21d74a19f5ca7848babfa00114acc8a30861f Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Wed, 4 Aug 2021 17:33:27 +0100 Subject: [PATCH] pv_wrap_append_preload: Cope with ${LIB}, ${PLATFORM} in loadable modules This partially resolves <https://github.com/ValveSoftware/steam-runtime/issues/435>, for the case where MangoHud was built with `-Dld_libdir_abs=true`, as in the upstream `build.sh` or upstream binary releases. Signed-off-by: Simon McVittie <smcv@collabora.com> --- pressure-vessel/wrap-setup.c | 101 ++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 6 deletions(-) diff --git a/pressure-vessel/wrap-setup.c b/pressure-vessel/wrap-setup.c index 65c525dae..ce51d6cc6 100644 --- a/pressure-vessel/wrap-setup.c +++ b/pressure-vessel/wrap-setup.c @@ -30,6 +30,7 @@ #include "bwrap.h" #include "flatpak-run-private.h" #include "flatpak-utils-private.h" +#include "supported-architectures.h" /* * Use code borrowed from Flatpak to share various bits of the @@ -336,6 +337,7 @@ pv_wrap_move_into_scope (const char *steam_app_id) static void append_preload_internal (GPtrArray *argv, const char *option, + const char *multiarch_tuple, const char *export_path, const char *original_path, GStrv env, @@ -356,14 +358,25 @@ append_preload_internal (GPtrArray *argv, adjusted_path = g_build_filename (target, original_path, NULL); g_debug ("%s -> %s", original_path, adjusted_path); - g_ptr_array_add (argv, g_strdup_printf ("%s=%s", - option, adjusted_path)); + if (multiarch_tuple != NULL) + g_ptr_array_add (argv, g_strdup_printf ("%s=%s:abi=%s", + option, adjusted_path, + multiarch_tuple)); + else + g_ptr_array_add (argv, g_strdup_printf ("%s=%s", + option, adjusted_path)); } else { g_debug ("%s -> unmodified", original_path); - g_ptr_array_add (argv, g_strdup_printf ("%s=%s", option, original_path)); + if (multiarch_tuple != NULL) + g_ptr_array_add (argv, g_strdup_printf ("%s=%s:abi=%s", + option, original_path, + multiarch_tuple)); + else + g_ptr_array_add (argv, g_strdup_printf ("%s=%s", + option, original_path)); if (exports != NULL && export_path != NULL && export_path[0] == '/') { @@ -458,6 +471,7 @@ append_preload_unsupported_token (GPtrArray *argv, append_preload_internal (argv, option, + NULL, export_path, preload, env, @@ -466,6 +480,69 @@ append_preload_unsupported_token (GPtrArray *argv, exports); } +/* + * Deal with a LD_PRELOAD or LD_AUDIT module that contains tokens whose + * expansion is ABI-dependent but otherwise fixed. We do these by + * breaking it up into several ABI-dependent LD_PRELOAD modules, which + * are recombined by pv-adverb. We have to do this because the expansion + * of the ABI-dependent tokens could be different in the container, due + * to using a different glibc. + * + * Arguments are the same as for pv_wrap_append_preload(). + */ +static void +append_preload_per_architecture (GPtrArray *argv, + const char *option, + const char *preload, + GStrv env, + PvAppendPreloadFlags flags, + PvRuntime *runtime, + FlatpakExports *exports) +{ + g_autoptr(SrtSystemInfo) system_info = srt_system_info_new (NULL); + gsize i; + + g_debug ("Found $LIB or $PLATFORM in \"%s\", splitting architectures", + preload); + + if (system_info == NULL) + system_info = srt_system_info_new (NULL); + + for (i = 0; i < PV_N_SUPPORTED_ARCHITECTURES; i++) + { + g_autoptr(GString) mock_path = NULL; + g_autoptr(SrtLibrary) details = NULL; + const char *path; + + srt_system_info_check_library (system_info, + pv_multiarch_details[i].tuple, + preload, + &details); + path = srt_library_get_absolute_path (details); + + if (path != NULL) + { + g_debug ("Found %s version of %s at %s", + pv_multiarch_details[i].tuple, preload, path); + append_preload_internal (argv, + option, + pv_multiarch_details[i].tuple, + path, + path, + env, + flags, + runtime, + exports); + } + else + { + g_info ("Unable to load %s version of %s", + pv_multiarch_details[i].tuple, + preload); + } + } +} + /** * pv_wrap_append_preload: * @argv: (element-type filename): Array of command-line options to populate @@ -533,6 +610,7 @@ pv_wrap_append_preload (GPtrArray *argv, append_preload_internal (argv, option, NULL, + NULL, preload, env, flags, @@ -553,13 +631,24 @@ pv_wrap_append_preload (GPtrArray *argv, runtime, exports); } - /* TODO: else if SRT_LOADABLE_FLAGS_ABI_DEPENDENT, ... */ + else if (loadable_flags & SRT_LOADABLE_FLAGS_ABI_DEPENDENT) + { + append_preload_per_architecture (argv, + option, + preload, + env, + flags, + runtime, + exports); + } else { - /* Assume preload is a filename: adjust the beginning if it's - * in /usr/ etc., and add it to the exports if absolute. */ + /* All dynamic tokens should be handled above, so we can + * assume that preload is a concrete filename */ + g_warn_if_fail ((loadable_flags & SRT_LOADABLE_FLAGS_DYNAMIC_TOKENS) == 0); append_preload_internal (argv, option, + NULL, preload, preload, env, -- GitLab