]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/perf/util/map.c
perf tools: Unify debug messages mechanisms
[karo-tx-linux.git] / tools / perf / util / map.c
1 #include "event.h"
2 #include "symbol.h"
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include "debug.h"
7
8 static inline int is_anon_memory(const char *filename)
9 {
10         return strcmp(filename, "//anon") == 0;
11 }
12
13 static int strcommon(const char *pathname, char *cwd, int cwdlen)
14 {
15         int n = 0;
16
17         while (n < cwdlen && pathname[n] == cwd[n])
18                 ++n;
19
20         return n;
21 }
22
23 struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen,
24                      unsigned int sym_priv_size, symbol_filter_t filter)
25 {
26         struct map *self = malloc(sizeof(*self));
27
28         if (self != NULL) {
29                 const char *filename = event->filename;
30                 char newfilename[PATH_MAX];
31                 int anon;
32                 bool new_dso;
33
34                 if (cwd) {
35                         int n = strcommon(filename, cwd, cwdlen);
36
37                         if (n == cwdlen) {
38                                 snprintf(newfilename, sizeof(newfilename),
39                                          ".%s", filename + n);
40                                 filename = newfilename;
41                         }
42                 }
43
44                 anon = is_anon_memory(filename);
45
46                 if (anon) {
47                         snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
48                         filename = newfilename;
49                 }
50
51                 self->start = event->start;
52                 self->end   = event->start + event->len;
53                 self->pgoff = event->pgoff;
54
55                 self->dso = dsos__findnew(filename, sym_priv_size, &new_dso);
56                 if (self->dso == NULL)
57                         goto out_delete;
58
59                 if (new_dso) {
60                         int nr = dso__load(self->dso, self, filter);
61
62                         if (nr < 0)
63                                 pr_warning("Failed to open %s, continuing "
64                                            "without symbols\n",
65                                            self->dso->long_name);
66                         else if (nr == 0)
67                                 pr_warning("No symbols found in %s, maybe "
68                                            "install a debug package?\n",
69                                            self->dso->long_name);
70                 }
71
72                 if (self->dso == vdso || anon)
73                         self->map_ip = self->unmap_ip = identity__map_ip;
74                 else {
75                         self->map_ip = map__map_ip;
76                         self->unmap_ip = map__unmap_ip;
77                 }
78         }
79         return self;
80 out_delete:
81         free(self);
82         return NULL;
83 }
84
85 struct map *map__clone(struct map *self)
86 {
87         struct map *map = malloc(sizeof(*self));
88
89         if (!map)
90                 return NULL;
91
92         memcpy(map, self, sizeof(*self));
93
94         return map;
95 }
96
97 int map__overlap(struct map *l, struct map *r)
98 {
99         if (l->start > r->start) {
100                 struct map *t = l;
101                 l = r;
102                 r = t;
103         }
104
105         if (l->end > r->start)
106                 return 1;
107
108         return 0;
109 }
110
111 size_t map__fprintf(struct map *self, FILE *fp)
112 {
113         return fprintf(fp, " %Lx-%Lx %Lx %s\n",
114                        self->start, self->end, self->pgoff, self->dso->name);
115 }