[sysprof] elf: use overlays to resolve library paths



commit 7e92b3e14bfd69c9eec0974bb25b7b2b9be3bd5f
Author: Christian Hergert <chergert redhat com>
Date:   Thu Feb 25 14:09:15 2021 -0800

    elf: use overlays to resolve library paths

 src/libsysprof/sysprof-elf-symbol-resolver.c | 34 +++++++++++++++++++++-------
 src/libsysprof/sysprof-map-lookaside.c       | 24 ++++++++++++++++----
 src/libsysprof/sysprof-map-lookaside.h       | 13 ++++++++---
 3 files changed, 55 insertions(+), 16 deletions(-)
---
diff --git a/src/libsysprof/sysprof-elf-symbol-resolver.c b/src/libsysprof/sysprof-elf-symbol-resolver.c
index e2ae1eb..2049e24 100644
--- a/src/libsysprof/sysprof-elf-symbol-resolver.c
+++ b/src/libsysprof/sysprof-elf-symbol-resolver.c
@@ -175,9 +175,7 @@ sysprof_elf_symbol_resolver_load (SysprofSymbolResolver *resolver,
               g_hash_table_insert (self->lookasides, GINT_TO_POINTER (ev->frame.pid), lookaside);
             }
 
-          /* FIXME: use dst to map to things other than / */
-          if (ev->dst_len == 1 && *dst == '/')
-            sysprof_map_lookaside_set_root (lookaside, src);
+          sysprof_map_lookaside_overlay (lookaside, src, dst);
         }
       else
         {
@@ -190,7 +188,8 @@ sysprof_elf_symbol_resolver_load (SysprofSymbolResolver *resolver,
 
 static bin_file_t *
 sysprof_elf_symbol_resolver_get_bin_file (SysprofElfSymbolResolver *self,
-                                          const gchar              *root,
+                                          const SysprofMapOverlay  *overlays,
+                                          guint                     n_overlays,
                                           const gchar              *filename)
 {
   bin_file_t *bin_file;
@@ -207,10 +206,21 @@ sysprof_elf_symbol_resolver_get_bin_file (SysprofElfSymbolResolver *self,
 
       dirs = (const gchar * const *)(gpointer)self->debug_dirs->data;
 
-      if (root && filename[0] != '/' && filename[0] != '[')
-        alternate = path = g_build_filename (root, filename, NULL);
+      if (overlays && filename[0] != '/' && filename[0] != '[')
+        {
+          for (guint i = 0; i < n_overlays; i++)
+            {
+              if (g_str_has_prefix (filename, overlays[i].dst+1))
+                {
+                  alternate = path = g_build_filename (overlays[i].src, filename, NULL);
+                  break;
+                }
+            }
+        }
       else if (is_flatpak () && g_str_has_prefix (filename, "/usr/"))
-        alternate = path = g_build_filename ("/var/run/host", alternate, NULL);
+        {
+          alternate = path = g_build_filename ("/var/run/host", alternate, NULL);
+        }
 
       bin_file = bin_file_new (alternate, dirs);
 
@@ -339,12 +349,14 @@ sysprof_elf_symbol_resolver_resolve_full (SysprofElfSymbolResolver *self,
                                           GQuark                   *tag)
 {
   SysprofMapLookaside *lookaside;
+  const SysprofMapOverlay *overlays = NULL;
   const bin_symbol_t *bin_sym;
   const gchar *bin_sym_name;
   const SysprofMap *map;
   bin_file_t *bin_file;
   gulong ubegin;
   gulong uend;
+  guint n_overlays = 0;
 
   g_assert (SYSPROF_IS_ELF_SYMBOL_RESOLVER (self));
   g_assert (name != NULL);
@@ -367,7 +379,13 @@ sysprof_elf_symbol_resolver_resolve_full (SysprofElfSymbolResolver *self,
   address -= map->start;
   address += map->offset;
 
-  bin_file = sysprof_elf_symbol_resolver_get_bin_file (self, lookaside->root, map->filename);
+  if (lookaside->overlays)
+    {
+      overlays = &g_array_index (lookaside->overlays, SysprofMapOverlay, 0);
+      n_overlays = lookaside->overlays->len;
+    }
+
+  bin_file = sysprof_elf_symbol_resolver_get_bin_file (self, overlays, n_overlays, map->filename);
 
   g_assert (bin_file != NULL);
 
diff --git a/src/libsysprof/sysprof-map-lookaside.c b/src/libsysprof/sysprof-map-lookaside.c
index 9881e4a..719b93c 100644
--- a/src/libsysprof/sysprof-map-lookaside.c
+++ b/src/libsysprof/sysprof-map-lookaside.c
@@ -67,9 +67,10 @@ sysprof_map_lookaside_new (void)
 {
   SysprofMapLookaside *ret;
 
-  ret = g_slice_new (SysprofMapLookaside);
+  ret = g_slice_new0 (SysprofMapLookaside);
   ret->seq = g_sequence_new (sysprof_map_free);
   ret->chunk = g_string_chunk_new (4096);
+  ret->overlays = NULL;
 
   return ret;
 }
@@ -101,14 +102,27 @@ sysprof_map_lookaside_insert (SysprofMapLookaside *self,
   g_sequence_insert_sorted (self->seq, copy, sysprof_map_compare, NULL);
 }
 
+
 void
-sysprof_map_lookaside_set_root (SysprofMapLookaside *self,
-                                const char          *root)
+sysprof_map_lookaside_overlay (SysprofMapLookaside *self,
+                               const gchar         *src,
+                               const gchar         *dst)
 {
+  SysprofMapOverlay overlay;
+
   g_assert (self != NULL);
-  g_assert (root != NULL);
+  g_assert (src != NULL);
+  g_assert (dst != NULL);
+
+  if (!src[0] || !dst[0])
+    return;
+
+  if (self->overlays == NULL)
+    self->overlays = g_array_new (FALSE, FALSE, sizeof (SysprofMapOverlay));
 
-  self->root = g_string_chunk_insert_const (self->chunk, root);
+  overlay.src = g_string_chunk_insert_const (self->chunk, src);
+  overlay.dst = g_string_chunk_insert_const (self->chunk, dst);
+  g_array_append_val (self->overlays, overlay);
 }
 
 const SysprofMap *
diff --git a/src/libsysprof/sysprof-map-lookaside.h b/src/libsysprof/sysprof-map-lookaside.h
index b91a03a..9cbc8b9 100644
--- a/src/libsysprof/sysprof-map-lookaside.h
+++ b/src/libsysprof/sysprof-map-lookaside.h
@@ -26,11 +26,17 @@
 
 G_BEGIN_DECLS
 
+typedef struct _SysprofMapOverlay
+{
+  const char *src;
+  const char *dst;
+} SysprofMapOverlay;
+
 typedef struct _SysprofMapLookaside
 {
   GSequence    *seq;
   GStringChunk *chunk;
-  const gchar  *root;
+  GArray       *overlays;
 } SysprofMapLookaside;
 
 typedef struct
@@ -45,8 +51,9 @@ typedef struct
 SysprofMapLookaside *sysprof_map_lookaside_new      (void);
 void                 sysprof_map_lookaside_insert   (SysprofMapLookaside    *self,
                                                      const SysprofMap       *map);
-void                 sysprof_map_lookaside_set_root (SysprofMapLookaside    *self,
-                                                     const gchar            *root);
+void                 sysprof_map_lookaside_overlay  (SysprofMapLookaside    *self,
+                                                     const gchar            *src,
+                                                     const gchar            *dst);
 const SysprofMap    *sysprof_map_lookaside_lookup   (SysprofMapLookaside    *self,
                                                      SysprofCaptureAddress   address);
 void                 sysprof_map_lookaside_free     (SysprofMapLookaside    *self);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]