aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/callchain.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/callchain.c')
-rw-r--r--tools/perf/util/callchain.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 08f0fbf5527c..ba7297230143 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,6 +25,90 @@
25 25
26__thread struct callchain_cursor callchain_cursor; 26__thread struct callchain_cursor callchain_cursor;
27 27
28#ifdef HAVE_DWARF_UNWIND_SUPPORT
29static int get_stack_size(const char *str, unsigned long *_size)
30{
31 char *endptr;
32 unsigned long size;
33 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
34
35 size = strtoul(str, &endptr, 0);
36
37 do {
38 if (*endptr)
39 break;
40
41 size = round_up(size, sizeof(u64));
42 if (!size || size > max_size)
43 break;
44
45 *_size = size;
46 return 0;
47
48 } while (0);
49
50 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
51 max_size, str);
52 return -1;
53}
54#endif /* HAVE_DWARF_UNWIND_SUPPORT */
55
56int parse_callchain_record_opt(const char *arg)
57{
58 char *tok, *name, *saveptr = NULL;
59 char *buf;
60 int ret = -1;
61
62 /* We need buffer that we know we can write to. */
63 buf = malloc(strlen(arg) + 1);
64 if (!buf)
65 return -ENOMEM;
66
67 strcpy(buf, arg);
68
69 tok = strtok_r((char *)buf, ",", &saveptr);
70 name = tok ? : (char *)buf;
71
72 do {
73 /* Framepointer style */
74 if (!strncmp(name, "fp", sizeof("fp"))) {
75 if (!strtok_r(NULL, ",", &saveptr)) {
76 callchain_param.record_mode = CALLCHAIN_FP;
77 ret = 0;
78 } else
79 pr_err("callchain: No more arguments "
80 "needed for -g fp\n");
81 break;
82
83#ifdef HAVE_DWARF_UNWIND_SUPPORT
84 /* Dwarf style */
85 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
86 const unsigned long default_stack_dump_size = 8192;
87
88 ret = 0;
89 callchain_param.record_mode = CALLCHAIN_DWARF;
90 callchain_param.dump_size = default_stack_dump_size;
91
92 tok = strtok_r(NULL, ",", &saveptr);
93 if (tok) {
94 unsigned long size = 0;
95
96 ret = get_stack_size(tok, &size);
97 callchain_param.dump_size = size;
98 }
99#endif /* HAVE_DWARF_UNWIND_SUPPORT */
100 } else {
101 pr_err("callchain: Unknown --call-graph option "
102 "value: %s\n", arg);
103 break;
104 }
105
106 } while (0);
107
108 free(buf);
109 return ret;
110}
111
28int 112int
29parse_callchain_report_opt(const char *arg) 113parse_callchain_report_opt(const char *arg)
30{ 114{