diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-12 05:07:25 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-12 06:37:37 -0400 |
commit | 66e274f3b8d7fc89d38997e85b900e188f8d5cc0 (patch) | |
tree | 5a0de899b891b2ce8440d2a3275b4ae7cb88b6c3 /tools/perf/builtin-report.c | |
parent | 1fe2c1066ce6a30bda7b27785ee3d9b8e62ffbbd (diff) |
perf tools: Factorize the map helpers
Factorize the dso mapping helpers into a single purpose common file
"util/map.c"
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Brice Goglin <Brice.Goglin@inria.fr>
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 124 |
1 files changed, 5 insertions, 119 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1efefcc2ffdf..93945ecdac86 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -67,6 +67,10 @@ static char callchain_default_opt[] = "fractal,0.5"; | |||
67 | 67 | ||
68 | static int callchain; | 68 | static int callchain; |
69 | 69 | ||
70 | static char __cwd[PATH_MAX]; | ||
71 | static char *cwd = __cwd; | ||
72 | static int cwdlen; | ||
73 | |||
70 | static | 74 | static |
71 | struct callchain_param callchain_param = { | 75 | struct callchain_param callchain_param = { |
72 | .mode = CHAIN_GRAPH_REL, | 76 | .mode = CHAIN_GRAPH_REL, |
@@ -102,124 +106,6 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...) | |||
102 | return n; | 106 | return n; |
103 | } | 107 | } |
104 | 108 | ||
105 | |||
106 | |||
107 | static char __cwd[PATH_MAX]; | ||
108 | static char *cwd = __cwd; | ||
109 | static int cwdlen; | ||
110 | |||
111 | static int strcommon(const char *pathname) | ||
112 | { | ||
113 | int n = 0; | ||
114 | |||
115 | while (n < cwdlen && pathname[n] == cwd[n]) | ||
116 | ++n; | ||
117 | |||
118 | return n; | ||
119 | } | ||
120 | |||
121 | struct map { | ||
122 | struct list_head node; | ||
123 | u64 start; | ||
124 | u64 end; | ||
125 | u64 pgoff; | ||
126 | u64 (*map_ip)(struct map *, u64); | ||
127 | struct dso *dso; | ||
128 | }; | ||
129 | |||
130 | static u64 map__map_ip(struct map *map, u64 ip) | ||
131 | { | ||
132 | return ip - map->start + map->pgoff; | ||
133 | } | ||
134 | |||
135 | static u64 vdso__map_ip(struct map *map __used, u64 ip) | ||
136 | { | ||
137 | return ip; | ||
138 | } | ||
139 | |||
140 | static inline int is_anon_memory(const char *filename) | ||
141 | { | ||
142 | return strcmp(filename, "//anon") == 0; | ||
143 | } | ||
144 | |||
145 | static struct map *map__new(struct mmap_event *event) | ||
146 | { | ||
147 | struct map *self = malloc(sizeof(*self)); | ||
148 | |||
149 | if (self != NULL) { | ||
150 | const char *filename = event->filename; | ||
151 | char newfilename[PATH_MAX]; | ||
152 | int anon; | ||
153 | |||
154 | if (cwd) { | ||
155 | int n = strcommon(filename); | ||
156 | |||
157 | if (n == cwdlen) { | ||
158 | snprintf(newfilename, sizeof(newfilename), | ||
159 | ".%s", filename + n); | ||
160 | filename = newfilename; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | anon = is_anon_memory(filename); | ||
165 | |||
166 | if (anon) { | ||
167 | snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid); | ||
168 | filename = newfilename; | ||
169 | } | ||
170 | |||
171 | self->start = event->start; | ||
172 | self->end = event->start + event->len; | ||
173 | self->pgoff = event->pgoff; | ||
174 | |||
175 | self->dso = dsos__findnew(filename); | ||
176 | if (self->dso == NULL) | ||
177 | goto out_delete; | ||
178 | |||
179 | if (self->dso == vdso || anon) | ||
180 | self->map_ip = vdso__map_ip; | ||
181 | else | ||
182 | self->map_ip = map__map_ip; | ||
183 | } | ||
184 | return self; | ||
185 | out_delete: | ||
186 | free(self); | ||
187 | return NULL; | ||
188 | } | ||
189 | |||
190 | static struct map *map__clone(struct map *self) | ||
191 | { | ||
192 | struct map *map = malloc(sizeof(*self)); | ||
193 | |||
194 | if (!map) | ||
195 | return NULL; | ||
196 | |||
197 | memcpy(map, self, sizeof(*self)); | ||
198 | |||
199 | return map; | ||
200 | } | ||
201 | |||
202 | static int map__overlap(struct map *l, struct map *r) | ||
203 | { | ||
204 | if (l->start > r->start) { | ||
205 | struct map *t = l; | ||
206 | l = r; | ||
207 | r = t; | ||
208 | } | ||
209 | |||
210 | if (l->end > r->start) | ||
211 | return 1; | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static size_t map__fprintf(struct map *self, FILE *fp) | ||
217 | { | ||
218 | return fprintf(fp, " %Lx-%Lx %Lx %s\n", | ||
219 | self->start, self->end, self->pgoff, self->dso->name); | ||
220 | } | ||
221 | |||
222 | |||
223 | struct thread { | 109 | struct thread { |
224 | struct rb_node rb_node; | 110 | struct rb_node rb_node; |
225 | struct list_head maps; | 111 | struct list_head maps; |
@@ -1474,7 +1360,7 @@ static int | |||
1474 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | 1360 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) |
1475 | { | 1361 | { |
1476 | struct thread *thread = threads__findnew(event->mmap.pid); | 1362 | struct thread *thread = threads__findnew(event->mmap.pid); |
1477 | struct map *map = map__new(&event->mmap); | 1363 | struct map *map = map__new(&event->mmap, cwd, cwdlen); |
1478 | 1364 | ||
1479 | dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n", | 1365 | dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n", |
1480 | (void *)(offset + head), | 1366 | (void *)(offset + head), |