On arm64, automatically record all the registers if the frame pointer
mode is on. They will be used to do a dwarf unwind to find the caller
of the leaf frame if the frame pointer was omitted.

Signed-off-by: Alexandre Truong <[email protected]>
Cc: John Garry <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Mathieu Poirier <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Alexander Shishkin <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Kemeng Shi <[email protected]>
Cc: Ian Rogers <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Kan Liang <[email protected]>
Cc: Jin Yao <[email protected]>
Cc: Adrian Hunter <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Al Grant <[email protected]>
Cc: James Clark <[email protected]>
Cc: Wilco Dijkstra <[email protected]>
---
 tools/perf/arch/arm64/util/machine.c | 5 +++++
 tools/perf/builtin-record.c          | 7 +++++++
 tools/perf/util/callchain.h          | 2 ++
 3 files changed, 14 insertions(+)

diff --git a/tools/perf/arch/arm64/util/machine.c 
b/tools/perf/arch/arm64/util/machine.c
index d41b27e781d3..6ba1d356a20c 100644
--- a/tools/perf/arch/arm64/util/machine.c
+++ b/tools/perf/arch/arm64/util/machine.c
@@ -25,3 +25,8 @@ void arch__symbols__fixup_end(struct symbol *p, struct symbol 
*c)
                p->end = c->start;
        pr_debug4("%s sym:%s end:%#lx\n", __func__, p->name, p->end);
 }
+
+void arch__add_leaf_frame_record_opts(struct record_opts *opts)
+{
+       opts->sample_user_regs = arch__user_reg_mask();
+}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 7bb10e9863bd..a5161f54b838 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -2243,6 +2243,10 @@ static int record__parse_mmap_pages(const struct option 
*opt,
        return ret;
 }
 
+void __weak arch__add_leaf_frame_record_opts(struct record_opts *opts 
__maybe_unused)
+{
+}
+
 static int parse_control_option(const struct option *opt,
                                const char *str,
                                int unset __maybe_unused)
@@ -2810,6 +2814,9 @@ int cmd_record(int argc, const char **argv)
        /* Enable ignoring missing threads when -u/-p option is defined. */
        rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || 
rec->opts.target.pid;
 
+       if (callchain_param.enabled && callchain_param.record_mode == 
CALLCHAIN_FP)
+               arch__add_leaf_frame_record_opts(&rec->opts);
+
        err = -ENOMEM;
        if (evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
                usage_with_options(record_usage, record_options);
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 5824134f983b..77fba053c677 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -280,6 +280,8 @@ static inline int arch_skip_callchain_idx(struct thread 
*thread __maybe_unused,
 }
 #endif
 
+void arch__add_leaf_frame_record_opts(struct record_opts *opts);
+
 char *callchain_list__sym_name(struct callchain_list *cl,
                               char *bf, size_t bfsize, bool show_dso);
 char *callchain_node__scnprintf_value(struct callchain_node *node,
-- 
2.23.0

Reply via email to