diff options
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 106 |
1 files changed, 94 insertions, 12 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index bfb3d872b9f5..4f3e7ef33b83 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -154,6 +154,36 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | int event__synthesize_modules(event__handler_t process, | ||
158 | struct perf_session *session) | ||
159 | { | ||
160 | struct rb_node *nd; | ||
161 | |||
162 | for (nd = rb_first(&session->kmaps.maps[MAP__FUNCTION]); | ||
163 | nd; nd = rb_next(nd)) { | ||
164 | event_t ev; | ||
165 | size_t size; | ||
166 | struct map *pos = rb_entry(nd, struct map, rb_node); | ||
167 | |||
168 | if (pos->dso->kernel) | ||
169 | continue; | ||
170 | |||
171 | size = ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); | ||
172 | memset(&ev, 0, sizeof(ev)); | ||
173 | ev.mmap.header.type = PERF_RECORD_MMAP; | ||
174 | ev.mmap.header.size = (sizeof(ev.mmap) - | ||
175 | (sizeof(ev.mmap.filename) - size)); | ||
176 | ev.mmap.start = pos->start; | ||
177 | ev.mmap.len = pos->end - pos->start; | ||
178 | |||
179 | memcpy(ev.mmap.filename, pos->dso->long_name, | ||
180 | pos->dso->long_name_len + 1); | ||
181 | process(&ev, session); | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
157 | int event__synthesize_thread(pid_t pid, event__handler_t process, | 187 | int event__synthesize_thread(pid_t pid, event__handler_t process, |
158 | struct perf_session *session) | 188 | struct perf_session *session) |
159 | { | 189 | { |
@@ -222,7 +252,9 @@ int event__synthesize_kernel_mmap(event__handler_t process, | |||
222 | "[kernel.kallsyms.%s]", symbol_name) + 1; | 252 | "[kernel.kallsyms.%s]", symbol_name) + 1; |
223 | size = ALIGN(size, sizeof(u64)); | 253 | size = ALIGN(size, sizeof(u64)); |
224 | ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size)); | 254 | ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size)); |
225 | ev.mmap.start = args.start; | 255 | ev.mmap.pgoff = args.start; |
256 | ev.mmap.start = session->vmlinux_maps[MAP__FUNCTION]->start; | ||
257 | ev.mmap.len = session->vmlinux_maps[MAP__FUNCTION]->end - ev.mmap.start ; | ||
226 | 258 | ||
227 | return process(&ev, session); | 259 | return process(&ev, session); |
228 | } | 260 | } |
@@ -280,7 +312,6 @@ int event__process_mmap(event_t *self, struct perf_session *session) | |||
280 | { | 312 | { |
281 | struct thread *thread; | 313 | struct thread *thread; |
282 | struct map *map; | 314 | struct map *map; |
283 | static const char kmmap_prefix[] = "[kernel.kallsyms."; | ||
284 | 315 | ||
285 | dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n", | 316 | dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n", |
286 | self->mmap.pid, self->mmap.tid, | 317 | self->mmap.pid, self->mmap.tid, |
@@ -289,13 +320,61 @@ int event__process_mmap(event_t *self, struct perf_session *session) | |||
289 | (void *)(long)self->mmap.pgoff, | 320 | (void *)(long)self->mmap.pgoff, |
290 | self->mmap.filename); | 321 | self->mmap.filename); |
291 | 322 | ||
292 | if (self->mmap.pid == 0 && | 323 | if (self->mmap.pid == 0) { |
293 | memcmp(self->mmap.filename, kmmap_prefix, | 324 | static const char kmmap_prefix[] = "[kernel.kallsyms."; |
294 | sizeof(kmmap_prefix) - 1) == 0) { | 325 | |
295 | const char *symbol_name = (self->mmap.filename + | 326 | if (self->mmap.filename[0] == '/') { |
296 | sizeof(kmmap_prefix) - 1); | 327 | char short_module_name[1024]; |
297 | perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name, | 328 | char *name = strrchr(self->mmap.filename, '/'), *dot; |
298 | self->mmap.start); | 329 | |
330 | if (name == NULL) | ||
331 | goto out_problem; | ||
332 | |||
333 | ++name; /* skip / */ | ||
334 | dot = strrchr(name, '.'); | ||
335 | if (dot == NULL) | ||
336 | goto out_problem; | ||
337 | |||
338 | snprintf(short_module_name, sizeof(short_module_name), | ||
339 | "[%.*s]", (int)(dot - name), name); | ||
340 | strxfrchar(short_module_name, '-', '_'); | ||
341 | |||
342 | map = perf_session__new_module_map(session, | ||
343 | self->mmap.start, | ||
344 | short_module_name); | ||
345 | if (map == NULL) | ||
346 | goto out_problem; | ||
347 | |||
348 | name = strdup(self->mmap.filename); | ||
349 | if (name == NULL) | ||
350 | goto out_problem; | ||
351 | |||
352 | dso__set_long_name(map->dso, name); | ||
353 | map->end = map->start + self->mmap.len; | ||
354 | } else if (memcmp(self->mmap.filename, kmmap_prefix, | ||
355 | sizeof(kmmap_prefix) - 1) == 0) { | ||
356 | const char *symbol_name = (self->mmap.filename + | ||
357 | sizeof(kmmap_prefix) - 1); | ||
358 | /* | ||
359 | * Should be there already, from the build-id table in | ||
360 | * the header. | ||
361 | */ | ||
362 | struct dso *kernel = __dsos__findnew(&dsos__kernel, | ||
363 | "[kernel.kallsyms]"); | ||
364 | if (kernel == NULL) | ||
365 | goto out_problem; | ||
366 | |||
367 | if (__map_groups__create_kernel_maps(&session->kmaps, | ||
368 | session->vmlinux_maps, | ||
369 | kernel) < 0) | ||
370 | goto out_problem; | ||
371 | |||
372 | session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start; | ||
373 | session->vmlinux_maps[MAP__FUNCTION]->end = self->mmap.start + self->mmap.len; | ||
374 | |||
375 | perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name, | ||
376 | self->mmap.pgoff); | ||
377 | } | ||
299 | return 0; | 378 | return 0; |
300 | } | 379 | } |
301 | 380 | ||
@@ -304,10 +383,13 @@ int event__process_mmap(event_t *self, struct perf_session *session) | |||
304 | session->cwd, session->cwdlen); | 383 | session->cwd, session->cwdlen); |
305 | 384 | ||
306 | if (thread == NULL || map == NULL) | 385 | if (thread == NULL || map == NULL) |
307 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | 386 | goto out_problem; |
308 | else | 387 | |
309 | thread__insert_map(thread, map); | 388 | thread__insert_map(thread, map); |
389 | return 0; | ||
310 | 390 | ||
391 | out_problem: | ||
392 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
311 | return 0; | 393 | return 0; |
312 | } | 394 | } |
313 | 395 | ||