summaryrefslogtreecommitdiff
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7f0537d1add8..e0e6a075489e 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -401,3 +401,49 @@ bool perf_session__has_traces(struct perf_session *self, const char *msg)
return true;
}
+
+int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
+ const char *symbol_name,
+ u64 addr)
+{
+ char *bracket;
+
+ self->ref_reloc_sym.name = strdup(symbol_name);
+ if (self->ref_reloc_sym.name == NULL)
+ return -ENOMEM;
+
+ bracket = strchr(self->ref_reloc_sym.name, ']');
+ if (bracket)
+ *bracket = '\0';
+
+ self->ref_reloc_sym.addr = addr;
+ return 0;
+}
+
+static u64 map__reloc_map_ip(struct map *map, u64 ip)
+{
+ return ip + (s64)map->pgoff;
+}
+
+static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
+{
+ return ip - (s64)map->pgoff;
+}
+
+void perf_session__reloc_vmlinux_maps(struct perf_session *self,
+ u64 unrelocated_addr)
+{
+ enum map_type type;
+ s64 reloc = unrelocated_addr - self->ref_reloc_sym.addr;
+
+ if (!reloc)
+ return;
+
+ for (type = 0; type < MAP__NR_TYPES; ++type) {
+ struct map *map = self->vmlinux_maps[type];
+
+ map->map_ip = map__reloc_map_ip;
+ map->unmap_ip = map__reloc_unmap_ip;
+ map->pgoff = reloc;
+ }
+}