diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c
index 152670ed5d2fe75cceb160ca0f78a6cced82f316..925d96ea3b99f4e1c8032531f898b7551750e96f 100644
--- a/pressure-vessel/runtime.c
+++ b/pressure-vessel/runtime.c
@@ -2675,6 +2675,493 @@ collect_vulkan_layers (PvRuntime *self,
   return TRUE;
 }
 
+/*
+ * @self: the runtime
+ * @arch: An architecture
+ * @ld_so_in_runtime: (out) (nullable) (not optional): Used to return
+ *  the path to the architecture's ld.so in the runtime, or to
+ *  return %NULL if there is none.
+ * @error: Used to raise an error on failure
+ *
+ * Get the path to the ld.so in the runtime, which is either absolute
+ * or relative to the sysroot.
+ *
+ * Returns: %TRUE on success (possibly yielding %NULL via @ld_so_in_runtime)
+ */
+static gboolean
+pv_runtime_get_ld_so (PvRuntime *self,
+                      RuntimeArchitecture *arch,
+                      gchar **ld_so_in_runtime,
+                      GError **error)
+{
+  if (self->mutable_sysroot != NULL)
+    {
+      glnx_autofd int fd = -1;
+
+      fd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd,
+                                    arch->ld_so,
+                                    SRT_RESOLVE_FLAGS_NONE,
+                                    ld_so_in_runtime,
+                                    NULL);
+
+      /* Ignore fd, and just let it close: we're resolving
+       * the path for its side-effect of populating
+       * ld_so_in_runtime. */
+    }
+  else
+    {
+      g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
+      g_autofree gchar *etc = NULL;
+      g_autofree gchar *provider_etc = NULL;
+      g_autofree gchar *provider_etc_dest = NULL;
+
+      /* Do it the hard way, by asking a process running in the
+       * container (or at least a container resembling the one we
+       * are going to use) to resolve it for us */
+      temp_bwrap = flatpak_bwrap_new (NULL);
+      flatpak_bwrap_add_args (temp_bwrap,
+                              self->bubblewrap,
+                              NULL);
+
+      if (!pv_bwrap_bind_usr (temp_bwrap,
+                              self->runtime_files_on_host,
+                              self->runtime_files,
+                              "/",
+                              error))
+        return FALSE;
+
+      etc = g_build_filename (self->runtime_files_on_host,
+                              "etc", NULL);
+      flatpak_bwrap_add_args (temp_bwrap,
+                              "--ro-bind",
+                              etc,
+                              "/etc",
+                              NULL);
+
+      if (!pv_bwrap_bind_usr (temp_bwrap,
+                              self->provider_in_host_namespace,
+                              self->provider_in_current_namespace,
+                              self->provider_in_container_namespace,
+                              error))
+        return FALSE;
+
+      provider_etc = g_build_filename (self->provider_in_host_namespace,
+                                       "etc", NULL);
+      provider_etc_dest = g_build_filename (self->provider_in_container_namespace,
+                                            "etc", NULL);
+      flatpak_bwrap_add_args (temp_bwrap,
+                              "--ro-bind",
+                              provider_etc,
+                              provider_etc_dest,
+                              NULL);
+
+      flatpak_bwrap_set_env (temp_bwrap, "PATH", "/usr/bin:/bin", TRUE);
+      flatpak_bwrap_add_args (temp_bwrap,
+                              "readlink", "-e", arch->ld_so,
+                              NULL);
+      flatpak_bwrap_finish (temp_bwrap);
+
+      *ld_so_in_runtime = pv_capture_output (
+          (const char * const *) temp_bwrap->argv->pdata, NULL);
+    }
+
+  return TRUE;
+}
+
+static gboolean
+pv_runtime_collect_graphics_libraries (PvRuntime *self,
+                                       RuntimeArchitecture *arch,
+                                       GError **error)
+{
+  g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
+
+  temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
+  flatpak_bwrap_add_args (temp_bwrap,
+                          "--dest", arch->libdir_in_current_namespace,
+                          /* Mesa GLX, etc. */
+                          "gl:",
+                          /* Vulkan */
+                          "if-exists:if-same-abi:soname:libvulkan.so.1",
+                          /* VDPAU */
+                          "if-exists:if-same-abi:soname:libvdpau.so.1",
+                          /* VA-API */
+                          "if-exists:if-same-abi:soname:libva.so.1",
+                          "if-exists:if-same-abi:soname:libva-drm.so.1",
+                          "if-exists:if-same-abi:soname:libva-glx.so.1",
+                          "if-exists:if-same-abi:soname:libva-x11.so.1",
+                          "if-exists:if-same-abi:soname:libva.so.2",
+                          "if-exists:if-same-abi:soname:libva-drm.so.2",
+                          "if-exists:if-same-abi:soname:libva-glx.so.2",
+                          "if-exists:if-same-abi:soname:libva-x11.so.2",
+                          /* NVIDIA proprietary stack */
+                          "if-exists:even-if-older:soname-match:libEGL.so.*",
+                          "if-exists:even-if-older:soname-match:libEGL_nvidia.so.*",
+                          "if-exists:even-if-older:soname-match:libGL.so.*",
+                          "if-exists:even-if-older:soname-match:libGLESv1_CM.so.*",
+                          "if-exists:even-if-older:soname-match:libGLESv1_CM_nvidia.so.*",
+                          "if-exists:even-if-older:soname-match:libGLESv2.so.*",
+                          "if-exists:even-if-older:soname-match:libGLESv2_nvidia.so.*",
+                          "if-exists:even-if-older:soname-match:libGLX.so.*",
+                          "if-exists:even-if-older:soname-match:libGLX_nvidia.so.*",
+                          "if-exists:even-if-older:soname-match:libGLX_indirect.so.*",
+                          "if-exists:even-if-older:soname-match:libGLdispatch.so.*",
+                          "if-exists:even-if-older:soname-match:libOpenGL.so.*",
+                          "if-exists:even-if-older:soname-match:libcuda.so.*",
+                          "if-exists:even-if-older:soname-match:libglx.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-cbl.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-cfg.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-compiler.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-egl-wayland.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-eglcore.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-encode.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-fatbinaryloader.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-fbc.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-glcore.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-glsi.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-glvkspirv.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-ifr.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-ml.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-opencl.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-opticalflow.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-ptxjitcompiler.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-rtcore.so.*",
+                          "if-exists:even-if-older:soname-match:libnvidia-tls.so.*",
+                          "if-exists:even-if-older:soname-match:libOpenCL.so.*",
+                          "if-exists:even-if-older:soname-match:libvdpau_nvidia.so.*",
+                          NULL);
+  flatpak_bwrap_finish (temp_bwrap);
+
+  return pv_bwrap_run_sync (temp_bwrap, NULL, error);
+}
+
+static gboolean
+pv_runtime_collect_libc_family (PvRuntime *self,
+                                RuntimeArchitecture *arch,
+                                FlatpakBwrap *bwrap,
+                                const char *libc,
+                                const char *ld_so_in_runtime,
+                                const char *provider_in_container_namespace_guarded,
+                                GHashTable *gconv_in_provider,
+                                GError **error)
+{
+  g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
+  g_autofree char *libc_target = NULL;
+
+  if (!pv_runtime_take_ld_so_from_provider (self, arch,
+                                            ld_so_in_runtime,
+                                            bwrap, error))
+    return FALSE;
+
+  /* Collect miscellaneous libraries that libc might dlopen. */
+  temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
+  flatpak_bwrap_add_args (temp_bwrap,
+                          "--dest", arch->libdir_in_current_namespace,
+                          "if-exists:libidn2.so.0",
+                          "if-exists:even-if-older:soname-match:libnss_compat.so.*",
+                          "if-exists:even-if-older:soname-match:libnss_db.so.*",
+                          "if-exists:even-if-older:soname-match:libnss_dns.so.*",
+                          "if-exists:even-if-older:soname-match:libnss_files.so.*",
+                          NULL);
+  flatpak_bwrap_finish (temp_bwrap);
+
+  if (!pv_bwrap_run_sync (temp_bwrap, NULL, error))
+    return FALSE;
+
+  g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
+
+  libc_target = glnx_readlinkat_malloc (-1, libc, NULL, NULL);
+  if (libc_target != NULL)
+    {
+      g_autofree gchar *dir = NULL;
+      g_autofree gchar *gconv_dir_in_provider = NULL;
+      gboolean found = FALSE;
+
+      dir = g_path_get_dirname (libc_target);
+
+      if (g_str_has_prefix (dir, provider_in_container_namespace_guarded))
+        memmove (dir,
+                 dir + strlen (self->provider_in_container_namespace),
+                 strlen (dir) - strlen (self->provider_in_container_namespace) + 1);
+
+      /* We are assuming that in the glibc "Makeconfig", $(libdir) was the same as
+       * $(slibdir) (this is the upstream default) or the same as "/usr$(slibdir)"
+       * (like in Debian without the mergerd /usr). We also assume that $(gconvdir)
+       * had its default value "$(libdir)/gconv".
+       * We check /usr first because otherwise, if the host is merged-/usr and the
+       * container is not, we might end up binding /lib instead of /usr/lib
+       * and that could cause issues. */
+      if (g_str_has_prefix (dir, "/usr/"))
+        memmove (dir, dir + strlen ("/usr"), strlen (dir) - strlen ("/usr") + 1);
+
+      gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
+
+      if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
+                                     -1,
+                                     gconv_dir_in_provider,
+                                     G_FILE_TEST_IS_DIR))
+        {
+          g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
+          found = TRUE;
+        }
+
+      if (!found)
+        {
+          /* Try again without hwcaps subdirectories.
+           * For example, libc6-i386 on SteamOS 2 'brewmaster'
+           * contains /lib/i386-linux-gnu/i686/cmov/libc.so.6,
+           * for which we want gconv modules from
+           * /usr/lib/i386-linux-gnu/gconv, not from
+           * /usr/lib/i386-linux-gnu/i686/cmov/gconv. */
+          while (g_str_has_suffix (dir, "/cmov") ||
+                 g_str_has_suffix (dir, "/i686") ||
+                 g_str_has_suffix (dir, "/sse2") ||
+                 g_str_has_suffix (dir, "/tls") ||
+                 g_str_has_suffix (dir, "/x86_64"))
+            {
+              char *slash = strrchr (dir, '/');
+
+              g_assert (slash != NULL);
+              *slash = '\0';
+            }
+
+          g_clear_pointer (&gconv_dir_in_provider, g_free);
+          gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
+
+          if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
+                                         -1,
+                                         gconv_dir_in_provider,
+                                         G_FILE_TEST_IS_DIR))
+            {
+              g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
+              found = TRUE;
+            }
+        }
+
+      if (!found)
+        {
+          g_debug ("We were expecting to have the gconv modules directory in the "
+                   "provider to be located in \"%s/gconv\", but instead it is missing",
+                   dir);
+        }
+    }
+
+  return TRUE;
+}
+
+static void
+pv_runtime_collect_libdrm_data (PvRuntime *self,
+                                RuntimeArchitecture *arch,
+                                const char *libdrm,
+                                const char *provider_in_container_namespace_guarded,
+                                GHashTable *libdrm_data_in_provider)
+{
+  g_autofree char *target = NULL;
+  target = glnx_readlinkat_malloc (-1, libdrm, NULL, NULL);
+
+  if (target != NULL)
+    {
+      g_autofree gchar *dir = NULL;
+      g_autofree gchar *lib_multiarch = NULL;
+      g_autofree gchar *libdrm_dir_in_provider = NULL;
+
+      dir = g_path_get_dirname (target);
+
+      lib_multiarch = g_build_filename ("/lib", arch->details->tuple, NULL);
+      if (g_str_has_suffix (dir, lib_multiarch))
+        dir[strlen (dir) - strlen (lib_multiarch)] = '\0';
+      else if (g_str_has_suffix (dir, "/lib64"))
+        dir[strlen (dir) - strlen ("/lib64")] = '\0';
+      else if (g_str_has_suffix (dir, "/lib32"))
+        dir[strlen (dir) - strlen ("/lib32")] = '\0';
+      else if (g_str_has_suffix (dir, "/lib"))
+        dir[strlen (dir) - strlen ("/lib")] = '\0';
+
+      if (g_str_has_prefix (dir, provider_in_container_namespace_guarded))
+        memmove (dir,
+                 dir + strlen (self->provider_in_container_namespace),
+                 strlen (dir) - strlen (self->provider_in_container_namespace) + 1);
+
+      libdrm_dir_in_provider = g_build_filename (dir, "share", "libdrm", NULL);
+
+      if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
+                                     -1,
+                                     libdrm_dir_in_provider,
+                                     G_FILE_TEST_IS_DIR))
+        {
+          g_hash_table_add (libdrm_data_in_provider,
+                            g_steal_pointer (&libdrm_dir_in_provider));
+        }
+      else
+        {
+          g_debug ("We were expecting to have the libdrm directory "
+                   "in the provider to be located in "
+                   "\"%s/share/libdrm\", but instead it is missing",
+                   dir);
+        }
+    }
+}
+
+static gboolean
+pv_runtime_finish_libdrm_data (PvRuntime *self,
+                               FlatpakBwrap *bwrap,
+                               gboolean all_libdrm_from_provider,
+                               GHashTable *libdrm_data_in_provider,
+                               GError **error)
+{
+  g_autofree gchar *best_libdrm_data_in_provider = NULL;
+
+  if (g_hash_table_size (libdrm_data_in_provider) > 0 && !all_libdrm_from_provider)
+    {
+      /* See the explanation in the similar
+       * "any_libc_from_provider && !all_libc_from_provider" case, above */
+      g_warning ("Using libdrm.so.2 from provider system for some but not all "
+                 "architectures! Will take /usr/share/libdrm from provider.");
+    }
+
+  if (g_hash_table_size (libdrm_data_in_provider) == 1)
+    {
+      best_libdrm_data_in_provider = g_strdup (
+        pv_hash_table_get_arbitrary_key (libdrm_data_in_provider));
+    }
+  else if (g_hash_table_size (libdrm_data_in_provider) > 1)
+    {
+      g_warning ("Found more than one possible libdrm data directory from provider");
+      /* Prioritize "/usr/share/libdrm" if available. Otherwise randomly pick
+       * the first directory in the hash table */
+      if (g_hash_table_contains (libdrm_data_in_provider, "/usr/share/libdrm"))
+        best_libdrm_data_in_provider = g_strdup ("/usr/share/libdrm");
+      else
+        best_libdrm_data_in_provider = g_strdup (
+          pv_hash_table_get_arbitrary_key (libdrm_data_in_provider));
+    }
+
+  if (best_libdrm_data_in_provider != NULL)
+    {
+      return pv_runtime_take_from_provider (self, bwrap,
+                                            best_libdrm_data_in_provider,
+                                            "/usr/share/libdrm",
+                                            TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
+                                            error);
+    }
+  else
+    {
+      return TRUE;
+    }
+}
+
+static gboolean
+pv_runtime_finish_libc_family (PvRuntime *self,
+                               FlatpakBwrap *bwrap,
+                               GHashTable *gconv_in_provider,
+                               GError **error)
+{
+  g_autofree gchar *localedef = NULL;
+  g_autofree gchar *ldconfig = NULL;
+  g_autofree gchar *locale = NULL;
+  GHashTableIter iter;
+  const gchar *gconv_path;
+
+  if (self->any_libc_from_provider && !self->all_libc_from_provider)
+    {
+      /*
+       * This shouldn't happen. It would mean that there exist at least
+       * two architectures (let's say aaa and bbb) for which we have:
+       * provider libc6:aaa < container libc6 < provider libc6:bbb
+       * (we know that the container's libc6:aaa and libc6:bbb are
+       * constrained to be the same version because that's how multiarch
+       * works).
+       *
+       * If the provider system locales work OK with both the aaa and bbb
+       * versions, let's assume they will also work with the intermediate
+       * version from the container...
+       */
+      g_warning ("Using glibc from provider system for some but not all "
+                 "architectures! Arbitrarily using provider locales.");
+    }
+
+  if (self->any_libc_from_provider)
+    {
+      g_debug ("Making provider locale data visible in container");
+
+      if (!pv_runtime_take_from_provider (self, bwrap,
+                                          "/usr/lib/locale",
+                                          "/usr/lib/locale",
+                                          TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS,
+                                          error))
+        return FALSE;
+
+      if (!pv_runtime_take_from_provider (self, bwrap,
+                                          "/usr/share/i18n",
+                                          "/usr/share/i18n",
+                                          TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS,
+                                          error))
+        return FALSE;
+
+      localedef = pv_runtime_search_in_path_and_bin (self, "localedef");
+
+      if (localedef == NULL)
+        {
+          g_warning ("Cannot find localedef");
+        }
+      else if (!pv_runtime_take_from_provider (self, bwrap, localedef,
+                                               "/usr/bin/localedef",
+                                               TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
+                                               error))
+        {
+          return FALSE;
+        }
+
+      locale = pv_runtime_search_in_path_and_bin (self, "locale");
+
+      if (locale == NULL)
+        {
+          g_warning ("Cannot find locale");
+        }
+      else if (!pv_runtime_take_from_provider (self, bwrap, locale,
+                                               "/usr/bin/locale",
+                                               TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
+                                               error))
+        {
+          return FALSE;
+        }
+
+      ldconfig = pv_runtime_search_in_path_and_bin (self, "ldconfig");
+
+      if (ldconfig == NULL)
+        {
+          g_warning ("Cannot find ldconfig");
+        }
+      else if (!pv_runtime_take_from_provider (self, bwrap,
+                                               ldconfig,
+                                               "/sbin/ldconfig",
+                                               TAKE_FROM_PROVIDER_FLAGS_NONE,
+                                               error))
+        {
+          return FALSE;
+        }
+
+      g_debug ("Making provider gconv modules visible in container");
+
+      g_hash_table_iter_init (&iter, gconv_in_provider);
+      while (g_hash_table_iter_next (&iter, (gpointer *)&gconv_path, NULL))
+        {
+          if (!pv_runtime_take_from_provider (self, bwrap,
+                                              gconv_path,
+                                              gconv_path,
+                                              TAKE_FROM_PROVIDER_FLAGS_IF_DIR,
+                                              error))
+            return FALSE;
+        }
+    }
+  else
+    {
+      g_debug ("Using included locale data from container");
+      g_debug ("Using included gconv modules from container");
+    }
+
+  return TRUE;
+}
+
 static gboolean
 pv_runtime_use_provider_graphics_stack (PvRuntime *self,
                                         FlatpakBwrap *bwrap,
@@ -2692,9 +3179,6 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
   g_autoptr(GString) vulkan_imp_layer_path = g_string_new ("");
   g_autoptr(GString) va_api_path = g_string_new ("");
   gboolean any_architecture_works = FALSE;
-  g_autofree gchar *localedef = NULL;
-  g_autofree gchar *ldconfig = NULL;
-  g_autofree gchar *locale = NULL;
   g_autoptr(SrtSystemInfo) system_info = srt_system_info_new (NULL);
   g_autoptr(SrtObjectList) egl_icds = NULL;
   g_autoptr(SrtObjectList) vulkan_icds = NULL;
@@ -2714,9 +3198,6 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
                                                                          g_free, NULL);
   g_autoptr(GHashTable) gconv_in_provider = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                                      g_free, NULL);
-  g_autofree gchar *best_libdrm_data_in_provider = NULL;
-  GHashTableIter iter;
-  const gchar *gconv_path;
   g_autofree gchar *provider_in_container_namespace_guarded = NULL;
   if (g_str_has_suffix (self->provider_in_container_namespace, "/"))
     provider_in_container_namespace_guarded =
@@ -2871,7 +3352,6 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
       if (runtime_architecture_init (arch, self))
         {
           g_autoptr(GPtrArray) dirs = NULL;
-          g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
           g_autofree gchar *this_dri_path_on_host = g_build_filename (arch->libdir_in_current_namespace,
                                                                       "dri", NULL);
           g_autofree gchar *this_dri_path_in_container = g_build_filename (arch->libdir_in_container,
@@ -2883,76 +3363,8 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
           g_autoptr(SrtObjectList) vdpau_drivers = NULL;
           g_autoptr(SrtObjectList) va_api_drivers = NULL;
 
-          if (self->mutable_sysroot != NULL)
-            {
-              glnx_autofd int fd = -1;
-
-              fd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd,
-                                            arch->ld_so,
-                                            SRT_RESOLVE_FLAGS_NONE,
-                                            &ld_so_in_runtime,
-                                            error);
-
-              if (fd < 0)
-                return FALSE;
-            }
-          else
-            {
-              g_autofree gchar *etc = NULL;
-              g_autofree gchar *provider_etc = NULL;
-              g_autofree gchar *provider_etc_dest = NULL;
-
-              /* Do it the hard way, by asking a process running in the
-               * container (or at least a container resembling the one we
-               * are going to use) to resolve it for us */
-              temp_bwrap = flatpak_bwrap_new (NULL);
-              flatpak_bwrap_add_args (temp_bwrap,
-                                      self->bubblewrap,
-                                      NULL);
-
-              if (!pv_bwrap_bind_usr (temp_bwrap,
-                                      self->runtime_files_on_host,
-                                      self->runtime_files,
-                                      "/",
-                                      error))
-                return FALSE;
-
-              etc = g_build_filename (self->runtime_files_on_host,
-                                      "etc", NULL);
-              flatpak_bwrap_add_args (temp_bwrap,
-                                      "--ro-bind",
-                                      etc,
-                                      "/etc",
-                                      NULL);
-
-              if (!pv_bwrap_bind_usr (temp_bwrap,
-                                      self->provider_in_host_namespace,
-                                      self->provider_in_current_namespace,
-                                      self->provider_in_container_namespace,
-                                      error))
-                return FALSE;
-
-              provider_etc = g_build_filename (self->provider_in_host_namespace,
-                                               "etc", NULL);
-              provider_etc_dest = g_build_filename (self->provider_in_container_namespace,
-                                                    "etc", NULL);
-              flatpak_bwrap_add_args (temp_bwrap,
-                                      "--ro-bind",
-                                      provider_etc,
-                                      provider_etc_dest,
-                                      NULL);
-
-              flatpak_bwrap_set_env (temp_bwrap, "PATH", "/usr/bin:/bin", TRUE);
-              flatpak_bwrap_add_args (temp_bwrap,
-                                      "readlink", "-e", arch->ld_so,
-                                      NULL);
-              flatpak_bwrap_finish (temp_bwrap);
-
-              ld_so_in_runtime = pv_capture_output (
-                  (const char * const *) temp_bwrap->argv->pdata, NULL);
-
-              g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
-            }
+          if (!pv_runtime_get_ld_so (self, arch, &ld_so_in_runtime, error))
+            return FALSE;
 
           if (ld_so_in_runtime == NULL)
             {
@@ -2973,67 +3385,9 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
 
           g_debug ("Collecting graphics drivers from provider system...");
 
-          temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
-          flatpak_bwrap_add_args (temp_bwrap,
-                                  "--dest", arch->libdir_in_current_namespace,
-                                  /* Mesa GLX, etc. */
-                                  "gl:",
-                                  /* Vulkan */
-                                  "if-exists:if-same-abi:soname:libvulkan.so.1",
-                                  /* VDPAU */
-                                  "if-exists:if-same-abi:soname:libvdpau.so.1",
-                                  /* VA-API */
-                                  "if-exists:if-same-abi:soname:libva.so.1",
-                                  "if-exists:if-same-abi:soname:libva-drm.so.1",
-                                  "if-exists:if-same-abi:soname:libva-glx.so.1",
-                                  "if-exists:if-same-abi:soname:libva-x11.so.1",
-                                  "if-exists:if-same-abi:soname:libva.so.2",
-                                  "if-exists:if-same-abi:soname:libva-drm.so.2",
-                                  "if-exists:if-same-abi:soname:libva-glx.so.2",
-                                  "if-exists:if-same-abi:soname:libva-x11.so.2",
-                                  /* NVIDIA proprietary stack */
-                                  "if-exists:even-if-older:soname-match:libEGL.so.*",
-                                  "if-exists:even-if-older:soname-match:libEGL_nvidia.so.*",
-                                  "if-exists:even-if-older:soname-match:libGL.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLESv1_CM.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLESv1_CM_nvidia.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLESv2.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLESv2_nvidia.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLX.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLX_nvidia.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLX_indirect.so.*",
-                                  "if-exists:even-if-older:soname-match:libGLdispatch.so.*",
-                                  "if-exists:even-if-older:soname-match:libOpenGL.so.*",
-                                  "if-exists:even-if-older:soname-match:libcuda.so.*",
-                                  "if-exists:even-if-older:soname-match:libglx.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-cbl.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-cfg.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-compiler.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-egl-wayland.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-eglcore.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-encode.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-fatbinaryloader.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-fbc.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-glcore.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-glsi.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-glvkspirv.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-ifr.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-ml.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-opencl.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-opticalflow.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-ptxjitcompiler.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-rtcore.so.*",
-                                  "if-exists:even-if-older:soname-match:libnvidia-tls.so.*",
-                                  "if-exists:even-if-older:soname-match:libOpenCL.so.*",
-                                  "if-exists:even-if-older:soname-match:libvdpau_nvidia.so.*",
-                                  NULL);
-          flatpak_bwrap_finish (temp_bwrap);
-
-          if (!pv_bwrap_run_sync (temp_bwrap, NULL, error))
+          if (!pv_runtime_collect_graphics_libraries (self, arch, error))
             return FALSE;
 
-          g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
-
           g_debug ("Collecting %s EGL drivers from host system...",
                    arch->details->tuple);
 
@@ -3134,107 +3488,13 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
            * then we have to use its ld.so too. */
           if (g_file_test (libc, G_FILE_TEST_IS_SYMLINK))
             {
-              g_autofree char *libc_target = NULL;
-
-              if (!pv_runtime_take_ld_so_from_provider (self, arch,
-                                                        ld_so_in_runtime,
-                                                        bwrap, error))
-                return FALSE;
-
-              /* Collect miscellaneous libraries that libc might dlopen. */
-              g_assert (temp_bwrap == NULL);
-              temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
-              flatpak_bwrap_add_args (temp_bwrap,
-                                      "--dest", arch->libdir_in_current_namespace,
-                                      "if-exists:libidn2.so.0",
-                                      "if-exists:even-if-older:soname-match:libnss_compat.so.*",
-                                      "if-exists:even-if-older:soname-match:libnss_db.so.*",
-                                      "if-exists:even-if-older:soname-match:libnss_dns.so.*",
-                                      "if-exists:even-if-older:soname-match:libnss_files.so.*",
-                                      NULL);
-              flatpak_bwrap_finish (temp_bwrap);
-
-              if (!pv_bwrap_run_sync (temp_bwrap, NULL, error))
+              if (!pv_runtime_collect_libc_family (self, arch, bwrap,
+                                                   libc, ld_so_in_runtime,
+                                                   provider_in_container_namespace_guarded,
+                                                   gconv_in_provider,
+                                                   error))
                 return FALSE;
 
-              g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
-
-              libc_target = glnx_readlinkat_malloc (-1, libc, NULL, NULL);
-              if (libc_target != NULL)
-                {
-                  g_autofree gchar *dir = NULL;
-                  g_autofree gchar *gconv_dir_in_provider = NULL;
-                  gboolean found = FALSE;
-
-                  dir = g_path_get_dirname (libc_target);
-
-                  if (g_str_has_prefix (dir, provider_in_container_namespace_guarded))
-                    memmove (dir,
-                             dir + strlen (self->provider_in_container_namespace),
-                             strlen (dir) - strlen (self->provider_in_container_namespace) + 1);
-
-                  /* We are assuming that in the glibc "Makeconfig", $(libdir) was the same as
-                   * $(slibdir) (this is the upstream default) or the same as "/usr$(slibdir)"
-                   * (like in Debian without the mergerd /usr). We also assume that $(gconvdir)
-                   * had its default value "$(libdir)/gconv".
-                   * We check /usr first because otherwise, if the host is merged-/usr and the
-                   * container is not, we might end up binding /lib instead of /usr/lib
-                   * and that could cause issues. */
-                  if (g_str_has_prefix (dir, "/usr/"))
-                    memmove (dir, dir + strlen ("/usr"), strlen (dir) - strlen ("/usr") + 1);
-
-                  gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
-
-                  if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
-                                                 -1,
-                                                 gconv_dir_in_provider,
-                                                 G_FILE_TEST_IS_DIR))
-                    {
-                      g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
-                      found = TRUE;
-                    }
-
-                  if (!found)
-                    {
-                      /* Try again without hwcaps subdirectories.
-                       * For example, libc6-i386 on SteamOS 2 'brewmaster'
-                       * contains /lib/i386-linux-gnu/i686/cmov/libc.so.6,
-                       * for which we want gconv modules from
-                       * /usr/lib/i386-linux-gnu/gconv, not from
-                       * /usr/lib/i386-linux-gnu/i686/cmov/gconv. */
-                      while (g_str_has_suffix (dir, "/cmov") ||
-                             g_str_has_suffix (dir, "/i686") ||
-                             g_str_has_suffix (dir, "/sse2") ||
-                             g_str_has_suffix (dir, "/tls") ||
-                             g_str_has_suffix (dir, "/x86_64"))
-                        {
-                          char *slash = strrchr (dir, '/');
-
-                          g_assert (slash != NULL);
-                          *slash = '\0';
-                        }
-
-                      g_clear_pointer (&gconv_dir_in_provider, g_free);
-                      gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
-
-                      if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
-                                                     -1,
-                                                     gconv_dir_in_provider,
-                                                     G_FILE_TEST_IS_DIR))
-                        {
-                          g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
-                          found = TRUE;
-                        }
-                    }
-
-                  if (!found)
-                    {
-                      g_debug ("We were expecting to have the gconv modules directory in the "
-                               "provider to be located in \"%s/gconv\", but instead it is missing",
-                               dir);
-                    }
-                }
-
               self->any_libc_from_provider = TRUE;
             }
           else
@@ -3249,50 +3509,9 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
            * the absolute path of libdrm.so.2 */
           if (g_file_test (libdrm, G_FILE_TEST_IS_SYMLINK))
             {
-              g_autofree char *target = NULL;
-              target = glnx_readlinkat_malloc (-1, libdrm, NULL, NULL);
-
-              if (target != NULL)
-                {
-                  g_autofree gchar *dir = NULL;
-                  g_autofree gchar *lib_multiarch = NULL;
-                  g_autofree gchar *libdrm_dir_in_provider = NULL;
-
-                  dir = g_path_get_dirname (target);
-
-                  lib_multiarch = g_build_filename ("/lib", arch->details->tuple, NULL);
-                  if (g_str_has_suffix (dir, lib_multiarch))
-                    dir[strlen (dir) - strlen (lib_multiarch)] = '\0';
-                  else if (g_str_has_suffix (dir, "/lib64"))
-                    dir[strlen (dir) - strlen ("/lib64")] = '\0';
-                  else if (g_str_has_suffix (dir, "/lib32"))
-                    dir[strlen (dir) - strlen ("/lib32")] = '\0';
-                  else if (g_str_has_suffix (dir, "/lib"))
-                    dir[strlen (dir) - strlen ("/lib")] = '\0';
-
-                  if (g_str_has_prefix (dir, provider_in_container_namespace_guarded))
-                    memmove (dir,
-                             dir + strlen (self->provider_in_container_namespace),
-                             strlen (dir) - strlen (self->provider_in_container_namespace) + 1);
-
-                  libdrm_dir_in_provider = g_build_filename (dir, "share", "libdrm", NULL);
-
-                  if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
-                                                 -1,
-                                                 libdrm_dir_in_provider,
-                                                 G_FILE_TEST_IS_DIR))
-                    {
-                      g_hash_table_add (libdrm_data_in_provider,
-                                        g_steal_pointer (&libdrm_dir_in_provider));
-                    }
-                  else
-                    {
-                      g_debug ("We were expecting to have the libdrm directory "
-                               "in the provider to be located in "
-                               "\"%s/share/libdrm\", but instead it is missing",
-                               dir);
-                    }
-                }
+              pv_runtime_collect_libdrm_data (self, arch, libdrm,
+                                              provider_in_container_namespace_guarded,
+                                              libdrm_data_in_provider);
             }
           else
             {
@@ -3369,138 +3588,12 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
       return FALSE;
     }
 
-  if (self->any_libc_from_provider && !self->all_libc_from_provider)
-    {
-      /*
-       * This shouldn't happen. It would mean that there exist at least
-       * two architectures (let's say aaa and bbb) for which we have:
-       * provider libc6:aaa < container libc6 < provider libc6:bbb
-       * (we know that the container's libc6:aaa and libc6:bbb are
-       * constrained to be the same version because that's how multiarch
-       * works).
-       *
-       * If the provider system locales work OK with both the aaa and bbb
-       * versions, let's assume they will also work with the intermediate
-       * version from the container...
-       */
-      g_warning ("Using glibc from provider system for some but not all "
-                 "architectures! Arbitrarily using provider locales.");
-    }
-
-  if (self->any_libc_from_provider)
-    {
-      g_debug ("Making provider locale data visible in container");
-
-      if (!pv_runtime_take_from_provider (self, bwrap,
-                                          "/usr/lib/locale",
-                                          "/usr/lib/locale",
-                                          TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS,
-                                          error))
-        return FALSE;
-
-      if (!pv_runtime_take_from_provider (self, bwrap,
-                                          "/usr/share/i18n",
-                                          "/usr/share/i18n",
-                                          TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS,
-                                          error))
-        return FALSE;
-
-      localedef = pv_runtime_search_in_path_and_bin (self, "localedef");
-
-      if (localedef == NULL)
-        {
-          g_warning ("Cannot find localedef");
-        }
-      else if (!pv_runtime_take_from_provider (self, bwrap, localedef,
-                                               "/usr/bin/localedef",
-                                               TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
-                                               error))
-        {
-          return FALSE;
-        }
-
-      locale = pv_runtime_search_in_path_and_bin (self, "locale");
-
-      if (locale == NULL)
-        {
-          g_warning ("Cannot find locale");
-        }
-      else if (!pv_runtime_take_from_provider (self, bwrap, locale,
-                                               "/usr/bin/locale",
-                                               TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
-                                               error))
-        {
-          return FALSE;
-        }
-
-      ldconfig = pv_runtime_search_in_path_and_bin (self, "ldconfig");
-
-      if (ldconfig == NULL)
-        {
-          g_warning ("Cannot find ldconfig");
-        }
-      else if (!pv_runtime_take_from_provider (self, bwrap,
-                                               ldconfig,
-                                               "/sbin/ldconfig",
-                                               TAKE_FROM_PROVIDER_FLAGS_NONE,
-                                               error))
-        {
-          return FALSE;
-        }
-
-      g_debug ("Making provider gconv modules visible in container");
-
-      g_hash_table_iter_init (&iter, gconv_in_provider);
-      while (g_hash_table_iter_next (&iter, (gpointer *)&gconv_path, NULL))
-        {
-          if (!pv_runtime_take_from_provider (self, bwrap,
-                                              gconv_path,
-                                              gconv_path,
-                                              TAKE_FROM_PROVIDER_FLAGS_IF_DIR,
-                                              error))
-            return FALSE;
-        }
-    }
-  else
-    {
-      g_debug ("Using included locale data from container");
-      g_debug ("Using included gconv modules from container");
-    }
-
-  if (g_hash_table_size (libdrm_data_in_provider) > 0 && !all_libdrm_from_provider)
-    {
-      /* See the explanation in the similar
-       * "any_libc_from_provider && !all_libc_from_provider" case, above */
-      g_warning ("Using libdrm.so.2 from provider system for some but not all "
-                 "architectures! Will take /usr/share/libdrm from provider.");
-    }
-
-  if (g_hash_table_size (libdrm_data_in_provider) == 1)
-    {
-      best_libdrm_data_in_provider = g_strdup (
-        pv_hash_table_get_arbitrary_key (libdrm_data_in_provider));
-    }
-  else if (g_hash_table_size (libdrm_data_in_provider) > 1)
-    {
-      g_warning ("Found more than one possible libdrm data directory from provider");
-      /* Prioritize "/usr/share/libdrm" if available. Otherwise randomly pick
-       * the first directory in the hash table */
-      if (g_hash_table_contains (libdrm_data_in_provider, "/usr/share/libdrm"))
-        best_libdrm_data_in_provider = g_strdup ("/usr/share/libdrm");
-      else
-        best_libdrm_data_in_provider = g_strdup (
-          pv_hash_table_get_arbitrary_key (libdrm_data_in_provider));
-    }
+  if (!pv_runtime_finish_libc_family (self, bwrap, gconv_in_provider, error))
+    return FALSE;
 
-  if (best_libdrm_data_in_provider != NULL)
-    {
-      if (!pv_runtime_take_from_provider (self, bwrap,
-                                          best_libdrm_data_in_provider,
-                                          "/usr/share/libdrm",
-                                          TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
-                                          error))
-        return FALSE;
-    }
+  if (!pv_runtime_finish_libdrm_data (self, bwrap, all_libdrm_from_provider,
+                                      libdrm_data_in_provider, error))
+    return FALSE;
 
   g_debug ("Setting up EGL ICD JSON...");