diff options
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r-- | tools/perf/util/map.c | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index c4d55a0da2ea..e509cd59c67d 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -5,6 +5,11 @@ | |||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include "debug.h" | 6 | #include "debug.h" |
7 | 7 | ||
8 | const char *map_type__name[MAP__NR_TYPES] = { | ||
9 | [MAP__FUNCTION] = "Functions", | ||
10 | [MAP__VARIABLE] = "Variables", | ||
11 | }; | ||
12 | |||
8 | static inline int is_anon_memory(const char *filename) | 13 | static inline int is_anon_memory(const char *filename) |
9 | { | 14 | { |
10 | return strcmp(filename, "//anon") == 0; | 15 | return strcmp(filename, "//anon") == 0; |
@@ -68,8 +73,13 @@ struct map *map__new(struct mmap_event *event, enum map_type type, | |||
68 | map__init(self, type, event->start, event->start + event->len, | 73 | map__init(self, type, event->start, event->start + event->len, |
69 | event->pgoff, dso); | 74 | event->pgoff, dso); |
70 | 75 | ||
71 | if (self->dso == vdso || anon) | 76 | if (anon) { |
77 | set_identity: | ||
72 | self->map_ip = self->unmap_ip = identity__map_ip; | 78 | self->map_ip = self->unmap_ip = identity__map_ip; |
79 | } else if (strcmp(filename, "[vdso]") == 0) { | ||
80 | dso__set_loaded(dso, self->type); | ||
81 | goto set_identity; | ||
82 | } | ||
73 | } | 83 | } |
74 | return self; | 84 | return self; |
75 | out_delete: | 85 | out_delete: |
@@ -104,8 +114,7 @@ void map__fixup_end(struct map *self) | |||
104 | 114 | ||
105 | #define DSO__DELETED "(deleted)" | 115 | #define DSO__DELETED "(deleted)" |
106 | 116 | ||
107 | int map__load(struct map *self, struct perf_session *session, | 117 | int map__load(struct map *self, symbol_filter_t filter) |
108 | symbol_filter_t filter) | ||
109 | { | 118 | { |
110 | const char *name = self->dso->long_name; | 119 | const char *name = self->dso->long_name; |
111 | int nr; | 120 | int nr; |
@@ -113,7 +122,7 @@ int map__load(struct map *self, struct perf_session *session, | |||
113 | if (dso__loaded(self->dso, self->type)) | 122 | if (dso__loaded(self->dso, self->type)) |
114 | return 0; | 123 | return 0; |
115 | 124 | ||
116 | nr = dso__load(self->dso, self, session, filter); | 125 | nr = dso__load(self->dso, self, filter); |
117 | if (nr < 0) { | 126 | if (nr < 0) { |
118 | if (self->dso->has_build_id) { | 127 | if (self->dso->has_build_id) { |
119 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | 128 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; |
@@ -144,24 +153,29 @@ int map__load(struct map *self, struct perf_session *session, | |||
144 | 153 | ||
145 | return -1; | 154 | return -1; |
146 | } | 155 | } |
156 | /* | ||
157 | * Only applies to the kernel, as its symtabs aren't relative like the | ||
158 | * module ones. | ||
159 | */ | ||
160 | if (self->dso->kernel) | ||
161 | map__reloc_vmlinux(self); | ||
147 | 162 | ||
148 | return 0; | 163 | return 0; |
149 | } | 164 | } |
150 | 165 | ||
151 | struct symbol *map__find_symbol(struct map *self, struct perf_session *session, | 166 | struct symbol *map__find_symbol(struct map *self, u64 addr, |
152 | u64 addr, symbol_filter_t filter) | 167 | symbol_filter_t filter) |
153 | { | 168 | { |
154 | if (map__load(self, session, filter) < 0) | 169 | if (map__load(self, filter) < 0) |
155 | return NULL; | 170 | return NULL; |
156 | 171 | ||
157 | return dso__find_symbol(self->dso, self->type, addr); | 172 | return dso__find_symbol(self->dso, self->type, addr); |
158 | } | 173 | } |
159 | 174 | ||
160 | struct symbol *map__find_symbol_by_name(struct map *self, const char *name, | 175 | struct symbol *map__find_symbol_by_name(struct map *self, const char *name, |
161 | struct perf_session *session, | ||
162 | symbol_filter_t filter) | 176 | symbol_filter_t filter) |
163 | { | 177 | { |
164 | if (map__load(self, session, filter) < 0) | 178 | if (map__load(self, filter) < 0) |
165 | return NULL; | 179 | return NULL; |
166 | 180 | ||
167 | if (!dso__sorted_by_name(self->dso, self->type)) | 181 | if (!dso__sorted_by_name(self->dso, self->type)) |
@@ -201,3 +215,23 @@ size_t map__fprintf(struct map *self, FILE *fp) | |||
201 | return fprintf(fp, " %Lx-%Lx %Lx %s\n", | 215 | return fprintf(fp, " %Lx-%Lx %Lx %s\n", |
202 | self->start, self->end, self->pgoff, self->dso->name); | 216 | self->start, self->end, self->pgoff, self->dso->name); |
203 | } | 217 | } |
218 | |||
219 | /* | ||
220 | * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. | ||
221 | * map->dso->adjust_symbols==1 for ET_EXEC-like cases. | ||
222 | */ | ||
223 | u64 map__rip_2objdump(struct map *map, u64 rip) | ||
224 | { | ||
225 | u64 addr = map->dso->adjust_symbols ? | ||
226 | map->unmap_ip(map, rip) : /* RIP -> IP */ | ||
227 | rip; | ||
228 | return addr; | ||
229 | } | ||
230 | |||
231 | u64 map__objdump_2ip(struct map *map, u64 addr) | ||
232 | { | ||
233 | u64 ip = map->dso->adjust_symbols ? | ||
234 | addr : | ||
235 | map->unmap_ip(map, addr); /* RIP -> IP */ | ||
236 | return ip; | ||
237 | } | ||