Even every module has loaded onto same addresses, some modules can be
changed and reloaded.  In that case it needs to access to the old module
in the build-id cache.

Cc: Adrian Hunter <[email protected]>
Cc: Wang Nan <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
 tools/perf/util/symbol.c | 45 +++++++++++++++++++++++----------------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ce79a51f25bf..fe46eb782297 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1155,6 +1155,7 @@ static int dso__load_kcore(struct dso *dso, struct map 
*map,
        int err, fd;
        char kcore_filename[PATH_MAX];
        struct symbol *sym;
+       struct map_groups old_mg;
 
        if (!kmaps)
                return -EINVAL;
@@ -1196,15 +1197,8 @@ static int dso__load_kcore(struct dso *dso, struct map 
*map,
                goto out_err;
        }
 
-       /* Remove old maps */
-       old_map = map_groups__first(kmaps, map->type);
-       while (old_map) {
-               struct map *next = map_groups__next(old_map);
-
-               if (old_map != map)
-                       map_groups__remove(kmaps, old_map);
-               old_map = next;
-       }
+       old_mg = *kmaps;
+       kmaps->maps[map->type].entries = RB_ROOT;
 
        /* Find the kernel map using the first symbol */
        sym = dso__first_symbol(dso, map->type);
@@ -1223,24 +1217,31 @@ static int dso__load_kcore(struct dso *dso, struct map 
*map,
        while (!list_empty(&md.maps)) {
                new_map = list_entry(md.maps.next, struct map, node);
                list_del_init(&new_map->node);
-               if (new_map == replacement_map) {
-                       map->start      = new_map->start;
-                       map->end        = new_map->end;
-                       map->pgoff      = new_map->pgoff;
-                       map->map_ip     = new_map->map_ip;
-                       map->unmap_ip   = new_map->unmap_ip;
-                       /* Ensure maps are correctly ordered */
-                       map__get(map);
-                       map_groups__remove(kmaps, map);
-                       map_groups__insert(kmaps, map);
-                       map__put(map);
-               } else {
-                       map_groups__insert(kmaps, new_map);
+
+               map_groups__insert(kmaps, new_map);
+
+               if (new_map != replacement_map) {
+                       old_map = map_groups__find(&old_mg, new_map->type, 
new_map->start);
+                       if (old_map && dso__loaded(old_map->dso, 
old_map->type)) {
+                               new_map->pgoff = old_map->pgoff;
+
+                               dso__put(new_map->dso);
+                               new_map->dso = dso__get(old_map->dso);
+                       }
                }
 
                map__put(new_map);
        }
 
+       /* Remove old maps */
+       old_map = map_groups__first(&old_mg, map->type);
+       while (old_map) {
+               struct map *next = map_groups__next(old_map);
+
+               map_groups__remove(&old_mg, old_map);
+               old_map = next;
+       }
+
        /*
         * Set the data type and long name so that kcore can be read via
         * dso__data_read_addr().
-- 
2.13.1

Reply via email to