aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r--tools/perf/util/map.c121
1 files changed, 58 insertions, 63 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 0328d45c4f2a..6fcb9de62340 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -11,6 +11,7 @@
11#include "strlist.h" 11#include "strlist.h"
12#include "vdso.h" 12#include "vdso.h"
13#include "build-id.h" 13#include "build-id.h"
14#include <linux/string.h>
14 15
15const char *map_type__name[MAP__NR_TYPES] = { 16const char *map_type__name[MAP__NR_TYPES] = {
16 [MAP__FUNCTION] = "Functions", 17 [MAP__FUNCTION] = "Functions",
@@ -19,7 +20,8 @@ const char *map_type__name[MAP__NR_TYPES] = {
19 20
20static inline int is_anon_memory(const char *filename) 21static inline int is_anon_memory(const char *filename)
21{ 22{
22 return strcmp(filename, "//anon") == 0; 23 return !strcmp(filename, "//anon") ||
24 !strcmp(filename, "/anon_hugepage (deleted)");
23} 25}
24 26
25static inline int is_no_dso_memory(const char *filename) 27static inline int is_no_dso_memory(const char *filename)
@@ -28,29 +30,29 @@ static inline int is_no_dso_memory(const char *filename)
28 !strcmp(filename, "[heap]"); 30 !strcmp(filename, "[heap]");
29} 31}
30 32
31void map__init(struct map *self, enum map_type type, 33void map__init(struct map *map, enum map_type type,
32 u64 start, u64 end, u64 pgoff, struct dso *dso) 34 u64 start, u64 end, u64 pgoff, struct dso *dso)
33{ 35{
34 self->type = type; 36 map->type = type;
35 self->start = start; 37 map->start = start;
36 self->end = end; 38 map->end = end;
37 self->pgoff = pgoff; 39 map->pgoff = pgoff;
38 self->dso = dso; 40 map->dso = dso;
39 self->map_ip = map__map_ip; 41 map->map_ip = map__map_ip;
40 self->unmap_ip = map__unmap_ip; 42 map->unmap_ip = map__unmap_ip;
41 RB_CLEAR_NODE(&self->rb_node); 43 RB_CLEAR_NODE(&map->rb_node);
42 self->groups = NULL; 44 map->groups = NULL;
43 self->referenced = false; 45 map->referenced = false;
44 self->erange_warned = false; 46 map->erange_warned = false;
45} 47}
46 48
47struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, 49struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
48 u64 pgoff, u32 pid, char *filename, 50 u64 pgoff, u32 pid, char *filename,
49 enum map_type type) 51 enum map_type type)
50{ 52{
51 struct map *self = malloc(sizeof(*self)); 53 struct map *map = malloc(sizeof(*map));
52 54
53 if (self != NULL) { 55 if (map != NULL) {
54 char newfilename[PATH_MAX]; 56 char newfilename[PATH_MAX];
55 struct dso *dso; 57 struct dso *dso;
56 int anon, no_dso, vdso; 58 int anon, no_dso, vdso;
@@ -73,10 +75,10 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
73 if (dso == NULL) 75 if (dso == NULL)
74 goto out_delete; 76 goto out_delete;
75 77
76 map__init(self, type, start, start + len, pgoff, dso); 78 map__init(map, type, start, start + len, pgoff, dso);
77 79
78 if (anon || no_dso) { 80 if (anon || no_dso) {
79 self->map_ip = self->unmap_ip = identity__map_ip; 81 map->map_ip = map->unmap_ip = identity__map_ip;
80 82
81 /* 83 /*
82 * Set memory without DSO as loaded. All map__find_* 84 * Set memory without DSO as loaded. All map__find_*
@@ -84,12 +86,12 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
84 * unnecessary map__load warning. 86 * unnecessary map__load warning.
85 */ 87 */
86 if (no_dso) 88 if (no_dso)
87 dso__set_loaded(dso, self->type); 89 dso__set_loaded(dso, map->type);
88 } 90 }
89 } 91 }
90 return self; 92 return map;
91out_delete: 93out_delete:
92 free(self); 94 free(map);
93 return NULL; 95 return NULL;
94} 96}
95 97
@@ -112,48 +114,48 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
112 return map; 114 return map;
113} 115}
114 116
115void map__delete(struct map *self) 117void map__delete(struct map *map)
116{ 118{
117 free(self); 119 free(map);
118} 120}
119 121
120void map__fixup_start(struct map *self) 122void map__fixup_start(struct map *map)
121{ 123{
122 struct rb_root *symbols = &self->dso->symbols[self->type]; 124 struct rb_root *symbols = &map->dso->symbols[map->type];
123 struct rb_node *nd = rb_first(symbols); 125 struct rb_node *nd = rb_first(symbols);
124 if (nd != NULL) { 126 if (nd != NULL) {
125 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 127 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
126 self->start = sym->start; 128 map->start = sym->start;
127 } 129 }
128} 130}
129 131
130void map__fixup_end(struct map *self) 132void map__fixup_end(struct map *map)
131{ 133{
132 struct rb_root *symbols = &self->dso->symbols[self->type]; 134 struct rb_root *symbols = &map->dso->symbols[map->type];
133 struct rb_node *nd = rb_last(symbols); 135 struct rb_node *nd = rb_last(symbols);
134 if (nd != NULL) { 136 if (nd != NULL) {
135 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 137 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
136 self->end = sym->end; 138 map->end = sym->end;
137 } 139 }
138} 140}
139 141
140#define DSO__DELETED "(deleted)" 142#define DSO__DELETED "(deleted)"
141 143
142int map__load(struct map *self, symbol_filter_t filter) 144int map__load(struct map *map, symbol_filter_t filter)
143{ 145{
144 const char *name = self->dso->long_name; 146 const char *name = map->dso->long_name;
145 int nr; 147 int nr;
146 148
147 if (dso__loaded(self->dso, self->type)) 149 if (dso__loaded(map->dso, map->type))
148 return 0; 150 return 0;
149 151
150 nr = dso__load(self->dso, self, filter); 152 nr = dso__load(map->dso, map, filter);
151 if (nr < 0) { 153 if (nr < 0) {
152 if (self->dso->has_build_id) { 154 if (map->dso->has_build_id) {
153 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 155 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
154 156
155 build_id__sprintf(self->dso->build_id, 157 build_id__sprintf(map->dso->build_id,
156 sizeof(self->dso->build_id), 158 sizeof(map->dso->build_id),
157 sbuild_id); 159 sbuild_id);
158 pr_warning("%s with build id %s not found", 160 pr_warning("%s with build id %s not found",
159 name, sbuild_id); 161 name, sbuild_id);
@@ -183,43 +185,36 @@ int map__load(struct map *self, symbol_filter_t filter)
183 * Only applies to the kernel, as its symtabs aren't relative like the 185 * Only applies to the kernel, as its symtabs aren't relative like the
184 * module ones. 186 * module ones.
185 */ 187 */
186 if (self->dso->kernel) 188 if (map->dso->kernel)
187 map__reloc_vmlinux(self); 189 map__reloc_vmlinux(map);
188 190
189 return 0; 191 return 0;
190} 192}
191 193
192struct symbol *map__find_symbol(struct map *self, u64 addr, 194struct symbol *map__find_symbol(struct map *map, u64 addr,
193 symbol_filter_t filter) 195 symbol_filter_t filter)
194{ 196{
195 if (map__load(self, filter) < 0) 197 if (map__load(map, filter) < 0)
196 return NULL; 198 return NULL;
197 199
198 return dso__find_symbol(self->dso, self->type, addr); 200 return dso__find_symbol(map->dso, map->type, addr);
199} 201}
200 202
201struct symbol *map__find_symbol_by_name(struct map *self, const char *name, 203struct symbol *map__find_symbol_by_name(struct map *map, const char *name,
202 symbol_filter_t filter) 204 symbol_filter_t filter)
203{ 205{
204 if (map__load(self, filter) < 0) 206 if (map__load(map, filter) < 0)
205 return NULL; 207 return NULL;
206 208
207 if (!dso__sorted_by_name(self->dso, self->type)) 209 if (!dso__sorted_by_name(map->dso, map->type))
208 dso__sort_by_name(self->dso, self->type); 210 dso__sort_by_name(map->dso, map->type);
209 211
210 return dso__find_symbol_by_name(self->dso, self->type, name); 212 return dso__find_symbol_by_name(map->dso, map->type, name);
211} 213}
212 214
213struct map *map__clone(struct map *self) 215struct map *map__clone(struct map *map)
214{ 216{
215 struct map *map = malloc(sizeof(*self)); 217 return memdup(map, sizeof(*map));
216
217 if (!map)
218 return NULL;
219
220 memcpy(map, self, sizeof(*self));
221
222 return map;
223} 218}
224 219
225int map__overlap(struct map *l, struct map *r) 220int map__overlap(struct map *l, struct map *r)
@@ -236,10 +231,10 @@ int map__overlap(struct map *l, struct map *r)
236 return 0; 231 return 0;
237} 232}
238 233
239size_t map__fprintf(struct map *self, FILE *fp) 234size_t map__fprintf(struct map *map, FILE *fp)
240{ 235{
241 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", 236 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
242 self->start, self->end, self->pgoff, self->dso->name); 237 map->start, map->end, map->pgoff, map->dso->name);
243} 238}
244 239
245size_t map__fprintf_dsoname(struct map *map, FILE *fp) 240size_t map__fprintf_dsoname(struct map *map, FILE *fp)
@@ -527,9 +522,9 @@ static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
527 return ip - (s64)map->pgoff; 522 return ip - (s64)map->pgoff;
528} 523}
529 524
530void map__reloc_vmlinux(struct map *self) 525void map__reloc_vmlinux(struct map *map)
531{ 526{
532 struct kmap *kmap = map__kmap(self); 527 struct kmap *kmap = map__kmap(map);
533 s64 reloc; 528 s64 reloc;
534 529
535 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr) 530 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
@@ -541,9 +536,9 @@ void map__reloc_vmlinux(struct map *self)
541 if (!reloc) 536 if (!reloc)
542 return; 537 return;
543 538
544 self->map_ip = map__reloc_map_ip; 539 map->map_ip = map__reloc_map_ip;
545 self->unmap_ip = map__reloc_unmap_ip; 540 map->unmap_ip = map__reloc_unmap_ip;
546 self->pgoff = reloc; 541 map->pgoff = reloc;
547} 542}
548 543
549void maps__insert(struct rb_root *maps, struct map *map) 544void maps__insert(struct rb_root *maps, struct map *map)
@@ -566,9 +561,9 @@ void maps__insert(struct rb_root *maps, struct map *map)
566 rb_insert_color(&map->rb_node, maps); 561 rb_insert_color(&map->rb_node, maps);
567} 562}
568 563
569void maps__remove(struct rb_root *self, struct map *map) 564void maps__remove(struct rb_root *maps, struct map *map)
570{ 565{
571 rb_erase(&map->rb_node, self); 566 rb_erase(&map->rb_node, maps);
572} 567}
573 568
574struct map *maps__find(struct rb_root *maps, u64 ip) 569struct map *maps__find(struct rb_root *maps, u64 ip)