aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c106
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
157int 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
157int event__synthesize_thread(pid_t pid, event__handler_t process, 187int 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
391out_problem:
392 dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
311 return 0; 393 return 0;
312} 394}
313 395