From f7f084f4d3c29b0f9877a32fc6e2feacd47695b9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 23 Sep 2014 10:01:42 +0900 Subject: perf callchain: Move some parser functions to callchain.c And rename record_callchain_parse() to parse_callchain_record_opt() in accordance to parse_callchain_report_opt(). Reviewed-by: David Ahern Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Milian Wolff Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1411434104-5307-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/callchain.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'tools/perf/util/callchain.c') 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 @@ __thread struct callchain_cursor callchain_cursor; +#ifdef HAVE_DWARF_UNWIND_SUPPORT +static int get_stack_size(const char *str, unsigned long *_size) +{ + char *endptr; + unsigned long size; + unsigned long max_size = round_down(USHRT_MAX, sizeof(u64)); + + size = strtoul(str, &endptr, 0); + + do { + if (*endptr) + break; + + size = round_up(size, sizeof(u64)); + if (!size || size > max_size) + break; + + *_size = size; + return 0; + + } while (0); + + pr_err("callchain: Incorrect stack dump size (max %ld): %s\n", + max_size, str); + return -1; +} +#endif /* HAVE_DWARF_UNWIND_SUPPORT */ + +int parse_callchain_record_opt(const char *arg) +{ + char *tok, *name, *saveptr = NULL; + char *buf; + int ret = -1; + + /* We need buffer that we know we can write to. */ + buf = malloc(strlen(arg) + 1); + if (!buf) + return -ENOMEM; + + strcpy(buf, arg); + + tok = strtok_r((char *)buf, ",", &saveptr); + name = tok ? : (char *)buf; + + do { + /* Framepointer style */ + if (!strncmp(name, "fp", sizeof("fp"))) { + if (!strtok_r(NULL, ",", &saveptr)) { + callchain_param.record_mode = CALLCHAIN_FP; + ret = 0; + } else + pr_err("callchain: No more arguments " + "needed for -g fp\n"); + break; + +#ifdef HAVE_DWARF_UNWIND_SUPPORT + /* Dwarf style */ + } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) { + const unsigned long default_stack_dump_size = 8192; + + ret = 0; + callchain_param.record_mode = CALLCHAIN_DWARF; + callchain_param.dump_size = default_stack_dump_size; + + tok = strtok_r(NULL, ",", &saveptr); + if (tok) { + unsigned long size = 0; + + ret = get_stack_size(tok, &size); + callchain_param.dump_size = size; + } +#endif /* HAVE_DWARF_UNWIND_SUPPORT */ + } else { + pr_err("callchain: Unknown --call-graph option " + "value: %s\n", arg); + break; + } + + } while (0); + + free(buf); + return ret; +} + int parse_callchain_report_opt(const char *arg) { -- cgit v1.2.3-55-g7522