aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/util.c')
-rw-r--r--tools/perf/util/util.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index edc2d633b332..f7adf1203df1 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -566,6 +566,96 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
566 return (unsigned long) -1; 566 return (unsigned long) -1;
567} 567}
568 568
569int get_stack_size(const char *str, unsigned long *_size)
570{
571 char *endptr;
572 unsigned long size;
573 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
574
575 size = strtoul(str, &endptr, 0);
576
577 do {
578 if (*endptr)
579 break;
580
581 size = round_up(size, sizeof(u64));
582 if (!size || size > max_size)
583 break;
584
585 *_size = size;
586 return 0;
587
588 } while (0);
589
590 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
591 max_size, str);
592 return -1;
593}
594
595int parse_callchain_record(const char *arg, struct callchain_param *param)
596{
597 char *tok, *name, *saveptr = NULL;
598 char *buf;
599 int ret = -1;
600
601 /* We need buffer that we know we can write to. */
602 buf = malloc(strlen(arg) + 1);
603 if (!buf)
604 return -ENOMEM;
605
606 strcpy(buf, arg);
607
608 tok = strtok_r((char *)buf, ",", &saveptr);
609 name = tok ? : (char *)buf;
610
611 do {
612 /* Framepointer style */
613 if (!strncmp(name, "fp", sizeof("fp"))) {
614 if (!strtok_r(NULL, ",", &saveptr)) {
615 param->record_mode = CALLCHAIN_FP;
616 ret = 0;
617 } else
618 pr_err("callchain: No more arguments "
619 "needed for --call-graph fp\n");
620 break;
621
622#ifdef HAVE_DWARF_UNWIND_SUPPORT
623 /* Dwarf style */
624 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
625 const unsigned long default_stack_dump_size = 8192;
626
627 ret = 0;
628 param->record_mode = CALLCHAIN_DWARF;
629 param->dump_size = default_stack_dump_size;
630
631 tok = strtok_r(NULL, ",", &saveptr);
632 if (tok) {
633 unsigned long size = 0;
634
635 ret = get_stack_size(tok, &size);
636 param->dump_size = size;
637 }
638#endif /* HAVE_DWARF_UNWIND_SUPPORT */
639 } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
640 if (!strtok_r(NULL, ",", &saveptr)) {
641 param->record_mode = CALLCHAIN_LBR;
642 ret = 0;
643 } else
644 pr_err("callchain: No more arguments "
645 "needed for --call-graph lbr\n");
646 break;
647 } else {
648 pr_err("callchain: Unknown --call-graph option "
649 "value: %s\n", arg);
650 break;
651 }
652
653 } while (0);
654
655 free(buf);
656 return ret;
657}
658
569int filename__read_str(const char *filename, char **buf, size_t *sizep) 659int filename__read_str(const char *filename, char **buf, size_t *sizep)
570{ 660{
571 size_t size = 0, alloc_size = 0; 661 size_t size = 0, alloc_size = 0;