aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c107
1 files changed, 86 insertions, 21 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 93d355d27109..c3e399bcf18d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -288,7 +288,8 @@ struct branch_info *machine__resolve_bstack(struct machine *self,
288 return bi; 288 return bi;
289} 289}
290 290
291int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, 291int machine__resolve_callchain(struct machine *self,
292 struct perf_evsel *evsel __used,
292 struct thread *thread, 293 struct thread *thread,
293 struct ip_callchain *chain, 294 struct ip_callchain *chain,
294 struct symbol **parent) 295 struct symbol **parent)
@@ -297,7 +298,12 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel,
297 unsigned int i; 298 unsigned int i;
298 int err; 299 int err;
299 300
300 callchain_cursor_reset(&evsel->hists.callchain_cursor); 301 callchain_cursor_reset(&callchain_cursor);
302
303 if (chain->nr > PERF_MAX_STACK_DEPTH) {
304 pr_warning("corrupted callchain. skipping...\n");
305 return 0;
306 }
301 307
302 for (i = 0; i < chain->nr; i++) { 308 for (i = 0; i < chain->nr; i++) {
303 u64 ip; 309 u64 ip;
@@ -317,7 +323,14 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel,
317 case PERF_CONTEXT_USER: 323 case PERF_CONTEXT_USER:
318 cpumode = PERF_RECORD_MISC_USER; break; 324 cpumode = PERF_RECORD_MISC_USER; break;
319 default: 325 default:
320 break; 326 pr_debug("invalid callchain context: "
327 "%"PRId64"\n", (s64) ip);
328 /*
329 * It seems the callchain is corrupted.
330 * Discard all.
331 */
332 callchain_cursor_reset(&callchain_cursor);
333 return 0;
321 } 334 }
322 continue; 335 continue;
323 } 336 }
@@ -333,7 +346,7 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel,
333 break; 346 break;
334 } 347 }
335 348
336 err = callchain_cursor_append(&evsel->hists.callchain_cursor, 349 err = callchain_cursor_append(&callchain_cursor,
337 ip, al.map, al.sym); 350 ip, al.map, al.sym);
338 if (err) 351 if (err)
339 return err; 352 return err;
@@ -429,6 +442,16 @@ static void perf_tool__fill_defaults(struct perf_tool *tool)
429 tool->finished_round = process_finished_round_stub; 442 tool->finished_round = process_finished_round_stub;
430 } 443 }
431} 444}
445
446void mem_bswap_32(void *src, int byte_size)
447{
448 u32 *m = src;
449 while (byte_size > 0) {
450 *m = bswap_32(*m);
451 byte_size -= sizeof(u32);
452 ++m;
453 }
454}
432 455
433void mem_bswap_64(void *src, int byte_size) 456void mem_bswap_64(void *src, int byte_size)
434{ 457{
@@ -441,37 +464,65 @@ void mem_bswap_64(void *src, int byte_size)
441 } 464 }
442} 465}
443 466
444static void perf_event__all64_swap(union perf_event *event) 467static void swap_sample_id_all(union perf_event *event, void *data)
468{
469 void *end = (void *) event + event->header.size;
470 int size = end - data;
471
472 BUG_ON(size % sizeof(u64));
473 mem_bswap_64(data, size);
474}
475
476static void perf_event__all64_swap(union perf_event *event,
477 bool sample_id_all __used)
445{ 478{
446 struct perf_event_header *hdr = &event->header; 479 struct perf_event_header *hdr = &event->header;
447 mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); 480 mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr));
448} 481}
449 482
450static void perf_event__comm_swap(union perf_event *event) 483static void perf_event__comm_swap(union perf_event *event, bool sample_id_all)
451{ 484{
452 event->comm.pid = bswap_32(event->comm.pid); 485 event->comm.pid = bswap_32(event->comm.pid);
453 event->comm.tid = bswap_32(event->comm.tid); 486 event->comm.tid = bswap_32(event->comm.tid);
487
488 if (sample_id_all) {
489 void *data = &event->comm.comm;
490
491 data += ALIGN(strlen(data) + 1, sizeof(u64));
492 swap_sample_id_all(event, data);
493 }
454} 494}
455 495
456static void perf_event__mmap_swap(union perf_event *event) 496static void perf_event__mmap_swap(union perf_event *event,
497 bool sample_id_all)
457{ 498{
458 event->mmap.pid = bswap_32(event->mmap.pid); 499 event->mmap.pid = bswap_32(event->mmap.pid);
459 event->mmap.tid = bswap_32(event->mmap.tid); 500 event->mmap.tid = bswap_32(event->mmap.tid);
460 event->mmap.start = bswap_64(event->mmap.start); 501 event->mmap.start = bswap_64(event->mmap.start);
461 event->mmap.len = bswap_64(event->mmap.len); 502 event->mmap.len = bswap_64(event->mmap.len);
462 event->mmap.pgoff = bswap_64(event->mmap.pgoff); 503 event->mmap.pgoff = bswap_64(event->mmap.pgoff);
504
505 if (sample_id_all) {
506 void *data = &event->mmap.filename;
507
508 data += ALIGN(strlen(data) + 1, sizeof(u64));
509 swap_sample_id_all(event, data);
510 }
463} 511}
464 512
465static void perf_event__task_swap(union perf_event *event) 513static void perf_event__task_swap(union perf_event *event, bool sample_id_all)
466{ 514{
467 event->fork.pid = bswap_32(event->fork.pid); 515 event->fork.pid = bswap_32(event->fork.pid);
468 event->fork.tid = bswap_32(event->fork.tid); 516 event->fork.tid = bswap_32(event->fork.tid);
469 event->fork.ppid = bswap_32(event->fork.ppid); 517 event->fork.ppid = bswap_32(event->fork.ppid);
470 event->fork.ptid = bswap_32(event->fork.ptid); 518 event->fork.ptid = bswap_32(event->fork.ptid);
471 event->fork.time = bswap_64(event->fork.time); 519 event->fork.time = bswap_64(event->fork.time);
520
521 if (sample_id_all)
522 swap_sample_id_all(event, &event->fork + 1);
472} 523}
473 524
474static void perf_event__read_swap(union perf_event *event) 525static void perf_event__read_swap(union perf_event *event, bool sample_id_all)
475{ 526{
476 event->read.pid = bswap_32(event->read.pid); 527 event->read.pid = bswap_32(event->read.pid);
477 event->read.tid = bswap_32(event->read.tid); 528 event->read.tid = bswap_32(event->read.tid);
@@ -479,6 +530,9 @@ static void perf_event__read_swap(union perf_event *event)
479 event->read.time_enabled = bswap_64(event->read.time_enabled); 530 event->read.time_enabled = bswap_64(event->read.time_enabled);
480 event->read.time_running = bswap_64(event->read.time_running); 531 event->read.time_running = bswap_64(event->read.time_running);
481 event->read.id = bswap_64(event->read.id); 532 event->read.id = bswap_64(event->read.id);
533
534 if (sample_id_all)
535 swap_sample_id_all(event, &event->read + 1);
482} 536}
483 537
484static u8 revbyte(u8 b) 538static u8 revbyte(u8 b)
@@ -530,7 +584,8 @@ void perf_event__attr_swap(struct perf_event_attr *attr)
530 swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); 584 swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64));
531} 585}
532 586
533static void perf_event__hdr_attr_swap(union perf_event *event) 587static void perf_event__hdr_attr_swap(union perf_event *event,
588 bool sample_id_all __used)
534{ 589{
535 size_t size; 590 size_t size;
536 591
@@ -541,18 +596,21 @@ static void perf_event__hdr_attr_swap(union perf_event *event)
541 mem_bswap_64(event->attr.id, size); 596 mem_bswap_64(event->attr.id, size);
542} 597}
543 598
544static void perf_event__event_type_swap(union perf_event *event) 599static void perf_event__event_type_swap(union perf_event *event,
600 bool sample_id_all __used)
545{ 601{
546 event->event_type.event_type.event_id = 602 event->event_type.event_type.event_id =
547 bswap_64(event->event_type.event_type.event_id); 603 bswap_64(event->event_type.event_type.event_id);
548} 604}
549 605
550static void perf_event__tracing_data_swap(union perf_event *event) 606static void perf_event__tracing_data_swap(union perf_event *event,
607 bool sample_id_all __used)
551{ 608{
552 event->tracing_data.size = bswap_32(event->tracing_data.size); 609 event->tracing_data.size = bswap_32(event->tracing_data.size);
553} 610}
554 611
555typedef void (*perf_event__swap_op)(union perf_event *event); 612typedef void (*perf_event__swap_op)(union perf_event *event,
613 bool sample_id_all);
556 614
557static perf_event__swap_op perf_event__swap_ops[] = { 615static perf_event__swap_op perf_event__swap_ops[] = {
558 [PERF_RECORD_MMAP] = perf_event__mmap_swap, 616 [PERF_RECORD_MMAP] = perf_event__mmap_swap,
@@ -986,6 +1044,15 @@ static int perf_session__process_user_event(struct perf_session *session, union
986 } 1044 }
987} 1045}
988 1046
1047static void event_swap(union perf_event *event, bool sample_id_all)
1048{
1049 perf_event__swap_op swap;
1050
1051 swap = perf_event__swap_ops[event->header.type];
1052 if (swap)
1053 swap(event, sample_id_all);
1054}
1055
989static int perf_session__process_event(struct perf_session *session, 1056static int perf_session__process_event(struct perf_session *session,
990 union perf_event *event, 1057 union perf_event *event,
991 struct perf_tool *tool, 1058 struct perf_tool *tool,
@@ -994,9 +1061,8 @@ static int perf_session__process_event(struct perf_session *session,
994 struct perf_sample sample; 1061 struct perf_sample sample;
995 int ret; 1062 int ret;
996 1063
997 if (session->header.needs_swap && 1064 if (session->header.needs_swap)
998 perf_event__swap_ops[event->header.type]) 1065 event_swap(event, session->sample_id_all);
999 perf_event__swap_ops[event->header.type](event);
1000 1066
1001 if (event->header.type >= PERF_RECORD_HEADER_MAX) 1067 if (event->header.type >= PERF_RECORD_HEADER_MAX)
1002 return -EINVAL; 1068 return -EINVAL;
@@ -1428,7 +1494,6 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1428 int print_sym, int print_dso, int print_symoffset) 1494 int print_sym, int print_dso, int print_symoffset)
1429{ 1495{
1430 struct addr_location al; 1496 struct addr_location al;
1431 struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
1432 struct callchain_cursor_node *node; 1497 struct callchain_cursor_node *node;
1433 1498
1434 if (perf_event__preprocess_sample(event, machine, &al, sample, 1499 if (perf_event__preprocess_sample(event, machine, &al, sample,
@@ -1446,10 +1511,10 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1446 error("Failed to resolve callchain. Skipping\n"); 1511 error("Failed to resolve callchain. Skipping\n");
1447 return; 1512 return;
1448 } 1513 }
1449 callchain_cursor_commit(cursor); 1514 callchain_cursor_commit(&callchain_cursor);
1450 1515
1451 while (1) { 1516 while (1) {
1452 node = callchain_cursor_current(cursor); 1517 node = callchain_cursor_current(&callchain_cursor);
1453 if (!node) 1518 if (!node)
1454 break; 1519 break;
1455 1520
@@ -1460,12 +1525,12 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1460 } 1525 }
1461 if (print_dso) { 1526 if (print_dso) {
1462 printf(" ("); 1527 printf(" (");
1463 map__fprintf_dsoname(al.map, stdout); 1528 map__fprintf_dsoname(node->map, stdout);
1464 printf(")"); 1529 printf(")");
1465 } 1530 }
1466 printf("\n"); 1531 printf("\n");
1467 1532
1468 callchain_cursor_advance(cursor); 1533 callchain_cursor_advance(&callchain_cursor);
1469 } 1534 }
1470 1535
1471 } else { 1536 } else {