summaryrefslogtreecommitdiff
path: root/tools/perf/util/map.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-02-28 10:20:25 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2010-02-28 10:20:25 -0800
commit6556a6743549defc32e5f90ee2cb1ecd833a44c3 (patch)
tree622306583d4a3c13235a8bfc012854c125c597f1 /tools/perf/util/map.c
parente0d272429a34ff143bfa04ee8e29dd4eed2964c7 (diff)
parent1dd2980d990068e20045b90c424518cc7f3657ff (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (172 commits) perf_event, amd: Fix spinlock initialization perf_event: Fix preempt warning in perf_clock() perf tools: Flush maps on COMM events perf_events, x86: Split PMU definitions into separate files perf annotate: Handle samples not at objdump output addr boundaries perf_events, x86: Remove superflous MSR writes perf_events: Simplify code by removing cpu argument to hw_perf_group_sched_in() perf_events, x86: AMD event scheduling perf_events: Add new start/stop PMU callbacks perf_events: Report the MMAP pgoff value in bytes perf annotate: Defer allocating sym_priv->hist array perf symbols: Improve debugging information about symtab origins perf top: Use a macro instead of a constant variable perf symbols: Check the right return variable perf/scripts: Tag syscall_name helper as not yet available perf/scripts: Add perf-trace-python Documentation perf/scripts: Remove unnecessary PyTuple resizes perf/scripts: Add syscall tracing scripts perf/scripts: Add Python scripting engine perf/scripts: Remove check-perf-trace from listed scripts ... Fix trivial conflict in tools/perf/util/probe-event.c
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r--tools/perf/util/map.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index c4d55a0da2e..e509cd59c67 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -5,6 +5,11 @@
#include <stdio.h>
#include "debug.h"
+const char *map_type__name[MAP__NR_TYPES] = {
+ [MAP__FUNCTION] = "Functions",
+ [MAP__VARIABLE] = "Variables",
+};
+
static inline int is_anon_memory(const char *filename)
{
return strcmp(filename, "//anon") == 0;
@@ -68,8 +73,13 @@ struct map *map__new(struct mmap_event *event, enum map_type type,
map__init(self, type, event->start, event->start + event->len,
event->pgoff, dso);
- if (self->dso == vdso || anon)
+ if (anon) {
+set_identity:
self->map_ip = self->unmap_ip = identity__map_ip;
+ } else if (strcmp(filename, "[vdso]") == 0) {
+ dso__set_loaded(dso, self->type);
+ goto set_identity;
+ }
}
return self;
out_delete:
@@ -104,8 +114,7 @@ void map__fixup_end(struct map *self)
#define DSO__DELETED "(deleted)"
-int map__load(struct map *self, struct perf_session *session,
- symbol_filter_t filter)
+int map__load(struct map *self, symbol_filter_t filter)
{
const char *name = self->dso->long_name;
int nr;
@@ -113,7 +122,7 @@ int map__load(struct map *self, struct perf_session *session,
if (dso__loaded(self->dso, self->type))
return 0;
- nr = dso__load(self->dso, self, session, filter);
+ nr = dso__load(self->dso, self, filter);
if (nr < 0) {
if (self->dso->has_build_id) {
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -144,24 +153,29 @@ int map__load(struct map *self, struct perf_session *session,
return -1;
}
+ /*
+ * Only applies to the kernel, as its symtabs aren't relative like the
+ * module ones.
+ */
+ if (self->dso->kernel)
+ map__reloc_vmlinux(self);
return 0;
}
-struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
- u64 addr, symbol_filter_t filter)
+struct symbol *map__find_symbol(struct map *self, u64 addr,
+ symbol_filter_t filter)
{
- if (map__load(self, session, filter) < 0)
+ if (map__load(self, filter) < 0)
return NULL;
return dso__find_symbol(self->dso, self->type, addr);
}
struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
- struct perf_session *session,
symbol_filter_t filter)
{
- if (map__load(self, session, filter) < 0)
+ if (map__load(self, filter) < 0)
return NULL;
if (!dso__sorted_by_name(self->dso, self->type))
@@ -201,3 +215,23 @@ size_t map__fprintf(struct map *self, FILE *fp)
return fprintf(fp, " %Lx-%Lx %Lx %s\n",
self->start, self->end, self->pgoff, self->dso->name);
}
+
+/*
+ * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
+ * map->dso->adjust_symbols==1 for ET_EXEC-like cases.
+ */
+u64 map__rip_2objdump(struct map *map, u64 rip)
+{
+ u64 addr = map->dso->adjust_symbols ?
+ map->unmap_ip(map, rip) : /* RIP -> IP */
+ rip;
+ return addr;
+}
+
+u64 map__objdump_2ip(struct map *map, u64 addr)
+{
+ u64 ip = map->dso->adjust_symbols ?
+ addr :
+ map->unmap_ip(map, addr); /* RIP -> IP */
+ return ip;
+}