]> Pileus Git - ~andy/linux/blob - tools/perf/util/map.c
Merge branch 'ttm-fixes-3.13' of git://people.freedesktop.org/~thomash/linux into...
[~andy/linux] / tools / perf / util / map.c
1 #include "symbol.h"
2 #include <errno.h>
3 #include <inttypes.h>
4 #include <limits.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include "map.h"
10 #include "thread.h"
11 #include "strlist.h"
12 #include "vdso.h"
13 #include "build-id.h"
14 #include <linux/string.h>
15
16 const char *map_type__name[MAP__NR_TYPES] = {
17         [MAP__FUNCTION] = "Functions",
18         [MAP__VARIABLE] = "Variables",
19 };
20
21 static inline int is_anon_memory(const char *filename)
22 {
23         return !strcmp(filename, "//anon") ||
24                !strcmp(filename, "/dev/zero (deleted)") ||
25                !strcmp(filename, "/anon_hugepage (deleted)");
26 }
27
28 static inline int is_no_dso_memory(const char *filename)
29 {
30         return !strncmp(filename, "[stack", 6) ||
31                !strcmp(filename, "[heap]");
32 }
33
34 void map__init(struct map *map, enum map_type type,
35                u64 start, u64 end, u64 pgoff, struct dso *dso)
36 {
37         map->type     = type;
38         map->start    = start;
39         map->end      = end;
40         map->pgoff    = pgoff;
41         map->dso      = dso;
42         map->map_ip   = map__map_ip;
43         map->unmap_ip = map__unmap_ip;
44         RB_CLEAR_NODE(&map->rb_node);
45         map->groups   = NULL;
46         map->referenced = false;
47         map->erange_warned = false;
48 }
49
50 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
51                      u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
52                      u64 ino_gen, char *filename,
53                      enum map_type type)
54 {
55         struct map *map = malloc(sizeof(*map));
56
57         if (map != NULL) {
58                 char newfilename[PATH_MAX];
59                 struct dso *dso;
60                 int anon, no_dso, vdso;
61
62                 anon = is_anon_memory(filename);
63                 vdso = is_vdso_map(filename);
64                 no_dso = is_no_dso_memory(filename);
65
66                 map->maj = d_maj;
67                 map->min = d_min;
68                 map->ino = ino;
69                 map->ino_generation = ino_gen;
70
71                 if (anon) {
72                         snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
73                         filename = newfilename;
74                 }
75
76                 if (vdso) {
77                         pgoff = 0;
78                         dso = vdso__dso_findnew(dsos__list);
79                 } else
80                         dso = __dsos__findnew(dsos__list, filename);
81
82                 if (dso == NULL)
83                         goto out_delete;
84
85                 map__init(map, type, start, start + len, pgoff, dso);
86
87                 if (anon || no_dso) {
88                         map->map_ip = map->unmap_ip = identity__map_ip;
89
90                         /*
91                          * Set memory without DSO as loaded. All map__find_*
92                          * functions still return NULL, and we avoid the
93                          * unnecessary map__load warning.
94                          */
95                         if (no_dso)
96                                 dso__set_loaded(dso, map->type);
97                 }
98         }
99         return map;
100 out_delete:
101         free(map);
102         return NULL;
103 }
104
105 /*
106  * Constructor variant for modules (where we know from /proc/modules where
107  * they are loaded) and for vmlinux, where only after we load all the
108  * symbols we'll know where it starts and ends.
109  */
110 struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
111 {
112         struct map *map = calloc(1, (sizeof(*map) +
113                                      (dso->kernel ? sizeof(struct kmap) : 0)));
114         if (map != NULL) {
115                 /*
116                  * ->end will be filled after we load all the symbols
117                  */
118                 map__init(map, type, start, 0, 0, dso);
119         }
120
121         return map;
122 }
123
124 void map__delete(struct map *map)
125 {
126         free(map);
127 }
128
129 void map__fixup_start(struct map *map)
130 {
131         struct rb_root *symbols = &map->dso->symbols[map->type];
132         struct rb_node *nd = rb_first(symbols);
133         if (nd != NULL) {
134                 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
135                 map->start = sym->start;
136         }
137 }
138
139 void map__fixup_end(struct map *map)
140 {
141         struct rb_root *symbols = &map->dso->symbols[map->type];
142         struct rb_node *nd = rb_last(symbols);
143         if (nd != NULL) {
144                 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
145                 map->end = sym->end;
146         }
147 }
148
149 #define DSO__DELETED "(deleted)"
150
151 int map__load(struct map *map, symbol_filter_t filter)
152 {
153         const char *name = map->dso->long_name;
154         int nr;
155
156         if (dso__loaded(map->dso, map->type))
157                 return 0;
158
159         nr = dso__load(map->dso, map, filter);
160         if (nr < 0) {
161                 if (map->dso->has_build_id) {
162                         char sbuild_id[BUILD_ID_SIZE * 2 + 1];
163
164                         build_id__sprintf(map->dso->build_id,
165                                           sizeof(map->dso->build_id),
166                                           sbuild_id);
167                         pr_warning("%s with build id %s not found",
168                                    name, sbuild_id);
169                 } else
170                         pr_warning("Failed to open %s", name);
171
172                 pr_warning(", continuing without symbols\n");
173                 return -1;
174         } else if (nr == 0) {
175 #ifdef HAVE_LIBELF_SUPPORT
176                 const size_t len = strlen(name);
177                 const size_t real_len = len - sizeof(DSO__DELETED);
178
179                 if (len > sizeof(DSO__DELETED) &&
180                     strcmp(name + real_len + 1, DSO__DELETED) == 0) {
181                         pr_warning("%.*s was updated (is prelink enabled?). "
182                                 "Restart the long running apps that use it!\n",
183                                    (int)real_len, name);
184                 } else {
185                         pr_warning("no symbols found in %s, maybe install "
186                                    "a debug package?\n", name);
187                 }
188 #endif
189                 return -1;
190         }
191
192         return 0;
193 }
194
195 struct symbol *map__find_symbol(struct map *map, u64 addr,
196                                 symbol_filter_t filter)
197 {
198         if (map__load(map, filter) < 0)
199                 return NULL;
200
201         return dso__find_symbol(map->dso, map->type, addr);
202 }
203
204 struct symbol *map__find_symbol_by_name(struct map *map, const char *name,
205                                         symbol_filter_t filter)
206 {
207         if (map__load(map, filter) < 0)
208                 return NULL;
209
210         if (!dso__sorted_by_name(map->dso, map->type))
211                 dso__sort_by_name(map->dso, map->type);
212
213         return dso__find_symbol_by_name(map->dso, map->type, name);
214 }
215
216 struct map *map__clone(struct map *map)
217 {
218         return memdup(map, sizeof(*map));
219 }
220
221 int map__overlap(struct map *l, struct map *r)
222 {
223         if (l->start > r->start) {
224                 struct map *t = l;
225                 l = r;
226                 r = t;
227         }
228
229         if (l->end > r->start)
230                 return 1;
231
232         return 0;
233 }
234
235 size_t map__fprintf(struct map *map, FILE *fp)
236 {
237         return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
238                        map->start, map->end, map->pgoff, map->dso->name);
239 }
240
241 size_t map__fprintf_dsoname(struct map *map, FILE *fp)
242 {
243         const char *dsoname = "[unknown]";
244
245         if (map && map->dso && (map->dso->name || map->dso->long_name)) {
246                 if (symbol_conf.show_kernel_path && map->dso->long_name)
247                         dsoname = map->dso->long_name;
248                 else if (map->dso->name)
249                         dsoname = map->dso->name;
250         }
251
252         return fprintf(fp, "%s", dsoname);
253 }
254
255 /**
256  * map__rip_2objdump - convert symbol start address to objdump address.
257  * @map: memory map
258  * @rip: symbol start address
259  *
260  * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
261  * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
262  * relative to section start.
263  *
264  * Return: Address suitable for passing to "objdump --start-address="
265  */
266 u64 map__rip_2objdump(struct map *map, u64 rip)
267 {
268         if (!map->dso->adjust_symbols)
269                 return rip;
270
271         if (map->dso->rel)
272                 return rip - map->pgoff;
273
274         return map->unmap_ip(map, rip);
275 }
276
277 /**
278  * map__objdump_2mem - convert objdump address to a memory address.
279  * @map: memory map
280  * @ip: objdump address
281  *
282  * Closely related to map__rip_2objdump(), this function takes an address from
283  * objdump and converts it to a memory address.  Note this assumes that @map
284  * contains the address.  To be sure the result is valid, check it forwards
285  * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
286  *
287  * Return: Memory address.
288  */
289 u64 map__objdump_2mem(struct map *map, u64 ip)
290 {
291         if (!map->dso->adjust_symbols)
292                 return map->unmap_ip(map, ip);
293
294         if (map->dso->rel)
295                 return map->unmap_ip(map, ip + map->pgoff);
296
297         return ip;
298 }
299
300 void map_groups__init(struct map_groups *mg)
301 {
302         int i;
303         for (i = 0; i < MAP__NR_TYPES; ++i) {
304                 mg->maps[i] = RB_ROOT;
305                 INIT_LIST_HEAD(&mg->removed_maps[i]);
306         }
307         mg->machine = NULL;
308 }
309
310 static void maps__delete(struct rb_root *maps)
311 {
312         struct rb_node *next = rb_first(maps);
313
314         while (next) {
315                 struct map *pos = rb_entry(next, struct map, rb_node);
316
317                 next = rb_next(&pos->rb_node);
318                 rb_erase(&pos->rb_node, maps);
319                 map__delete(pos);
320         }
321 }
322
323 static void maps__delete_removed(struct list_head *maps)
324 {
325         struct map *pos, *n;
326
327         list_for_each_entry_safe(pos, n, maps, node) {
328                 list_del(&pos->node);
329                 map__delete(pos);
330         }
331 }
332
333 void map_groups__exit(struct map_groups *mg)
334 {
335         int i;
336
337         for (i = 0; i < MAP__NR_TYPES; ++i) {
338                 maps__delete(&mg->maps[i]);
339                 maps__delete_removed(&mg->removed_maps[i]);
340         }
341 }
342
343 void map_groups__flush(struct map_groups *mg)
344 {
345         int type;
346
347         for (type = 0; type < MAP__NR_TYPES; type++) {
348                 struct rb_root *root = &mg->maps[type];
349                 struct rb_node *next = rb_first(root);
350
351                 while (next) {
352                         struct map *pos = rb_entry(next, struct map, rb_node);
353                         next = rb_next(&pos->rb_node);
354                         rb_erase(&pos->rb_node, root);
355                         /*
356                          * We may have references to this map, for
357                          * instance in some hist_entry instances, so
358                          * just move them to a separate list.
359                          */
360                         list_add_tail(&pos->node, &mg->removed_maps[pos->type]);
361                 }
362         }
363 }
364
365 struct symbol *map_groups__find_symbol(struct map_groups *mg,
366                                        enum map_type type, u64 addr,
367                                        struct map **mapp,
368                                        symbol_filter_t filter)
369 {
370         struct map *map = map_groups__find(mg, type, addr);
371
372         if (map != NULL) {
373                 if (mapp != NULL)
374                         *mapp = map;
375                 return map__find_symbol(map, map->map_ip(map, addr), filter);
376         }
377
378         return NULL;
379 }
380
381 struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
382                                                enum map_type type,
383                                                const char *name,
384                                                struct map **mapp,
385                                                symbol_filter_t filter)
386 {
387         struct rb_node *nd;
388
389         for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
390                 struct map *pos = rb_entry(nd, struct map, rb_node);
391                 struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
392
393                 if (sym == NULL)
394                         continue;
395                 if (mapp != NULL)
396                         *mapp = pos;
397                 return sym;
398         }
399
400         return NULL;
401 }
402
403 int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
404 {
405         if (ams->addr < ams->map->start || ams->addr > ams->map->end) {
406                 if (ams->map->groups == NULL)
407                         return -1;
408                 ams->map = map_groups__find(ams->map->groups, ams->map->type,
409                                             ams->addr);
410                 if (ams->map == NULL)
411                         return -1;
412         }
413
414         ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
415         ams->sym = map__find_symbol(ams->map, ams->al_addr, filter);
416
417         return ams->sym ? 0 : -1;
418 }
419
420 size_t __map_groups__fprintf_maps(struct map_groups *mg,
421                                   enum map_type type, int verbose, FILE *fp)
422 {
423         size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
424         struct rb_node *nd;
425
426         for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
427                 struct map *pos = rb_entry(nd, struct map, rb_node);
428                 printed += fprintf(fp, "Map:");
429                 printed += map__fprintf(pos, fp);
430                 if (verbose > 2) {
431                         printed += dso__fprintf(pos->dso, type, fp);
432                         printed += fprintf(fp, "--\n");
433                 }
434         }
435
436         return printed;
437 }
438
439 size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp)
440 {
441         size_t printed = 0, i;
442         for (i = 0; i < MAP__NR_TYPES; ++i)
443                 printed += __map_groups__fprintf_maps(mg, i, verbose, fp);
444         return printed;
445 }
446
447 static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
448                                                  enum map_type type,
449                                                  int verbose, FILE *fp)
450 {
451         struct map *pos;
452         size_t printed = 0;
453
454         list_for_each_entry(pos, &mg->removed_maps[type], node) {
455                 printed += fprintf(fp, "Map:");
456                 printed += map__fprintf(pos, fp);
457                 if (verbose > 1) {
458                         printed += dso__fprintf(pos->dso, type, fp);
459                         printed += fprintf(fp, "--\n");
460                 }
461         }
462         return printed;
463 }
464
465 static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
466                                                int verbose, FILE *fp)
467 {
468         size_t printed = 0, i;
469         for (i = 0; i < MAP__NR_TYPES; ++i)
470                 printed += __map_groups__fprintf_removed_maps(mg, i, verbose, fp);
471         return printed;
472 }
473
474 size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp)
475 {
476         size_t printed = map_groups__fprintf_maps(mg, verbose, fp);
477         printed += fprintf(fp, "Removed maps:\n");
478         return printed + map_groups__fprintf_removed_maps(mg, verbose, fp);
479 }
480
481 int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
482                                    int verbose, FILE *fp)
483 {
484         struct rb_root *root = &mg->maps[map->type];
485         struct rb_node *next = rb_first(root);
486         int err = 0;
487
488         while (next) {
489                 struct map *pos = rb_entry(next, struct map, rb_node);
490                 next = rb_next(&pos->rb_node);
491
492                 if (!map__overlap(pos, map))
493                         continue;
494
495                 if (verbose >= 2) {
496                         fputs("overlapping maps:\n", fp);
497                         map__fprintf(map, fp);
498                         map__fprintf(pos, fp);
499                 }
500
501                 rb_erase(&pos->rb_node, root);
502                 /*
503                  * Now check if we need to create new maps for areas not
504                  * overlapped by the new map:
505                  */
506                 if (map->start > pos->start) {
507                         struct map *before = map__clone(pos);
508
509                         if (before == NULL) {
510                                 err = -ENOMEM;
511                                 goto move_map;
512                         }
513
514                         before->end = map->start - 1;
515                         map_groups__insert(mg, before);
516                         if (verbose >= 2)
517                                 map__fprintf(before, fp);
518                 }
519
520                 if (map->end < pos->end) {
521                         struct map *after = map__clone(pos);
522
523                         if (after == NULL) {
524                                 err = -ENOMEM;
525                                 goto move_map;
526                         }
527
528                         after->start = map->end + 1;
529                         map_groups__insert(mg, after);
530                         if (verbose >= 2)
531                                 map__fprintf(after, fp);
532                 }
533 move_map:
534                 /*
535                  * If we have references, just move them to a separate list.
536                  */
537                 if (pos->referenced)
538                         list_add_tail(&pos->node, &mg->removed_maps[map->type]);
539                 else
540                         map__delete(pos);
541
542                 if (err)
543                         return err;
544         }
545
546         return 0;
547 }
548
549 /*
550  * XXX This should not really _copy_ te maps, but refcount them.
551  */
552 int map_groups__clone(struct map_groups *mg,
553                       struct map_groups *parent, enum map_type type)
554 {
555         struct rb_node *nd;
556         for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
557                 struct map *map = rb_entry(nd, struct map, rb_node);
558                 struct map *new = map__clone(map);
559                 if (new == NULL)
560                         return -ENOMEM;
561                 map_groups__insert(mg, new);
562         }
563         return 0;
564 }
565
566 void maps__insert(struct rb_root *maps, struct map *map)
567 {
568         struct rb_node **p = &maps->rb_node;
569         struct rb_node *parent = NULL;
570         const u64 ip = map->start;
571         struct map *m;
572
573         while (*p != NULL) {
574                 parent = *p;
575                 m = rb_entry(parent, struct map, rb_node);
576                 if (ip < m->start)
577                         p = &(*p)->rb_left;
578                 else
579                         p = &(*p)->rb_right;
580         }
581
582         rb_link_node(&map->rb_node, parent, p);
583         rb_insert_color(&map->rb_node, maps);
584 }
585
586 void maps__remove(struct rb_root *maps, struct map *map)
587 {
588         rb_erase(&map->rb_node, maps);
589 }
590
591 struct map *maps__find(struct rb_root *maps, u64 ip)
592 {
593         struct rb_node **p = &maps->rb_node;
594         struct rb_node *parent = NULL;
595         struct map *m;
596
597         while (*p != NULL) {
598                 parent = *p;
599                 m = rb_entry(parent, struct map, rb_node);
600                 if (ip < m->start)
601                         p = &(*p)->rb_left;
602                 else if (ip > m->end)
603                         p = &(*p)->rb_right;
604                 else
605                         return m;
606         }
607
608         return NULL;
609 }
610
611 struct map *maps__first(struct rb_root *maps)
612 {
613         struct rb_node *first = rb_first(maps);
614
615         if (first)
616                 return rb_entry(first, struct map, rb_node);
617         return NULL;
618 }
619
620 struct map *maps__next(struct map *map)
621 {
622         struct rb_node *next = rb_next(&map->rb_node);
623
624         if (next)
625                 return rb_entry(next, struct map, rb_node);
626         return NULL;
627 }