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.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index c1c556825343..94ca95073c40 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -20,16 +20,27 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen)
20 return n; 20 return n;
21} 21}
22 22
23struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, 23void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
24 unsigned int sym_priv_size, symbol_filter_t filter) 24 struct dso *dso)
25{
26 self->start = start;
27 self->end = end;
28 self->pgoff = pgoff;
29 self->dso = dso;
30 self->map_ip = map__map_ip;
31 self->unmap_ip = map__unmap_ip;
32 RB_CLEAR_NODE(&self->rb_node);
33}
34
35struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
25{ 36{
26 struct map *self = malloc(sizeof(*self)); 37 struct map *self = malloc(sizeof(*self));
27 38
28 if (self != NULL) { 39 if (self != NULL) {
29 const char *filename = event->filename; 40 const char *filename = event->filename;
30 char newfilename[PATH_MAX]; 41 char newfilename[PATH_MAX];
42 struct dso *dso;
31 int anon; 43 int anon;
32 bool new_dso;
33 44
34 if (cwd) { 45 if (cwd) {
35 int n = strcommon(filename, cwd, cwdlen); 46 int n = strcommon(filename, cwd, cwdlen);
@@ -48,33 +59,15 @@ struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen,
48 filename = newfilename; 59 filename = newfilename;
49 } 60 }
50 61
51 self->start = event->start; 62 dso = dsos__findnew(filename);
52 self->end = event->start + event->len; 63 if (dso == NULL)
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; 64 goto out_delete;
58 65
59 if (new_dso) { 66 map__init(self, event->start, event->start + event->len,
60 int nr = dso__load(self->dso, self, filter); 67 event->pgoff, dso);
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 68
72 if (self->dso == vdso || anon) 69 if (self->dso == vdso || anon)
73 self->map_ip = self->unmap_ip = identity__map_ip; 70 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 } 71 }
79 return self; 72 return self;
80out_delete: 73out_delete:
@@ -82,6 +75,47 @@ out_delete:
82 return NULL; 75 return NULL;
83} 76}
84 77
78#define DSO__DELETED "(deleted)"
79
80struct symbol *
81map__find_symbol(struct map *self, u64 ip, symbol_filter_t filter)
82{
83 if (!self->dso->loaded) {
84 int nr = dso__load(self->dso, self, filter);
85
86 if (nr < 0) {
87 if (self->dso->has_build_id) {
88 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
89
90 build_id__sprintf(self->dso->build_id,
91 sizeof(self->dso->build_id),
92 sbuild_id);
93 pr_warning("%s with build id %s not found",
94 self->dso->long_name, sbuild_id);
95 } else
96 pr_warning("Failed to open %s",
97 self->dso->long_name);
98 pr_warning(", continuing without symbols\n");
99 return NULL;
100 } else if (nr == 0) {
101 const char *name = self->dso->long_name;
102 const size_t len = strlen(name);
103 const size_t real_len = len - sizeof(DSO__DELETED);
104
105 if (len > sizeof(DSO__DELETED) &&
106 strcmp(name + real_len + 1, DSO__DELETED) == 0) {
107 pr_warning("%.*s was updated, restart the long running apps that use it!\n",
108 (int)real_len, name);
109 } else {
110 pr_warning("no symbols found in %s, maybe install a debug package?\n", name);
111 }
112 return NULL;
113 }
114 }
115
116 return self->dso->find_symbol(self->dso, ip);
117}
118
85struct map *map__clone(struct map *self) 119struct map *map__clone(struct map *self)
86{ 120{
87 struct map *map = malloc(sizeof(*self)); 121 struct map *map = malloc(sizeof(*self));