From: takahiro.akashi@linaro.org (AKASHI Takahiro)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6 6/6] arm64: ftrace: add a test of function prologue analyzer
Date: Wed, 18 Nov 2015 15:43:09 +0900 [thread overview]
Message-ID: <1447828989-4980-7-git-send-email-takahiro.akashi@linaro.org> (raw)
In-Reply-To: <1447828989-4980-1-git-send-email-takahiro.akashi@linaro.org>
The patch ("arm64: ftrace: add arch-specific stack tracer") introduced
a function prologue analyzer.
Given that there is no fixed template for a function prologue, at least
on gcc for aarch64, a function prologue analyzer may be rather heuristic.
So this patch adds a kernel command line option,
function_prologue_analyzer_test, in order to run a basic test at startup
by executing an analyzer against all the *traceable* functions.
For function_prologue_analyzer_test=2, the output looks like:
po sp fp symbol
== == == ======
0: 0 0x040 0x000 gic_handle_irq+0x20/0xa4
1: 0 0x040 0x000 gic_handle_irq+0x34/0x114
2: 0 0x030 0x000 run_init_process+0x14/0x48
3: 0 0x020 0x000 try_to_run_init_process+0x14/0x58
4: 0 0x080 0x000 do_one_initcall+0x1c/0x194
...
22959: 0 0x020 0x000 tty_lock_slave+0x14/0x3c
22960: 0 0x020 0x000 tty_unlock_slave+0x14/0x3c
function prologue analyzer test: 0 errors
"po" indicates a position of callsite of mcount(), and should be zero
if an analyzer has parsed a function prologue successfully and reached
a location where fp is properly updated.
"sp" is a final offset to a parent's fp at the exit of function prologue.
"fp" is also an ofset against sp at the exit of function prologue.
So normally,
<new sp> = <old fp> + <"sp">
<new fp> = <new sp> - <"fp">
And the last line shows the number of possible errors in the result.
For function_prologue_analyzer_test=1, only the last line will be shown.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/include/asm/insn.h | 2 +-
arch/arm64/kernel/stacktrace.c | 52 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 8d5c538..1dfae16 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -281,7 +281,7 @@ __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F)
__AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000)
__AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000)
__AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000)
-__AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F00E0)
+__AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0)
#undef __AARCH64_INSN_FUNCS
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1d18bc4..19dad62 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/ftrace.h>
+#include <linux/kallsyms.h>
#include <linux/sched.h>
#include <linux/stacktrace.h>
@@ -348,5 +349,56 @@ void save_stack_trace_sp(struct stack_trace *trace,
{
__save_stack_trace_tsk(current, trace, stack_dump_sp);
}
+
+static int start_analyzer_test __initdata;
+
+static int __init enable_analyzer_test(char *str)
+{
+ get_option(&str, &start_analyzer_test);
+ return 0;
+}
+early_param("function_prologue_analyzer_test", enable_analyzer_test);
+
+static void __init do_test_function_prologue_analyzer(void)
+{
+ extern unsigned long __start_mcount_loc[];
+ extern unsigned long __stop_mcount_loc[];
+ unsigned long count, i, errors;
+ int print_once;
+
+ count = __stop_mcount_loc - __start_mcount_loc;
+ errors = print_once = 0;
+ for (i = 0; i < count; i++) {
+ unsigned long addr, sp_off, fp_off;
+ int pos;
+ bool check;
+ char buf[60];
+
+ addr = __start_mcount_loc[i];
+ pos = analyze_function_prologue(addr, &sp_off, &fp_off);
+ check = ((pos != 0) || !sp_off || (sp_off <= fp_off));
+ if (check)
+ errors++;
+ if (check || (start_analyzer_test > 1)) {
+ if (!print_once) {
+ pr_debug(" po sp fp symbol\n");
+ pr_debug(" == == == ======\n");
+ print_once++;
+ }
+ sprint_symbol(buf, addr);
+ pr_debug("%5ld: %d 0x%03lx 0x%03lx %s\n",
+ i, pos, sp_off, fp_off, buf);
+ }
+ }
+ pr_debug("function prologue analyzer test: %ld errors\n", errors);
+}
+
+static int __init test_function_prologue_analyzer(void)
+{
+ if (start_analyzer_test)
+ do_test_function_prologue_analyzer();
+ return 0;
+}
+late_initcall(test_function_prologue_analyzer);
#endif /* CONFIG_STACK_TRACER */
#endif
--
1.7.9.5
next prev parent reply other threads:[~2015-11-18 6:43 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-18 6:43 [PATCH v6 0/6] arm64: ftrace: fix incorrect output from stack tracer AKASHI Takahiro
2015-11-18 6:43 ` [PATCH v6 1/6] arm64: ftrace: modify a stack frame in a safe way AKASHI Takahiro
2015-11-24 14:22 ` Jungseok Lee
2015-11-18 6:43 ` [PATCH v6 2/6] arm64: pass a task parameter to unwind_frame() AKASHI Takahiro
2015-11-24 13:42 ` Jungseok Lee
2015-11-25 4:39 ` AKASHI Takahiro
2015-12-02 13:22 ` Will Deacon
2015-12-02 15:33 ` Jungseok Lee
2015-12-10 6:33 ` AKASHI Takahiro
2015-11-18 6:43 ` [PATCH v6 3/6] arm64: ftrace: fix a stack tracer's output under function graph tracer AKASHI Takahiro
2015-11-24 13:37 ` Jungseok Lee
2015-11-25 5:29 ` AKASHI Takahiro
2015-11-25 11:48 ` Jungseok Lee
2015-11-26 3:05 ` AKASHI Takahiro
2015-11-26 14:05 ` Jungseok Lee
2015-11-18 6:43 ` [PATCH v6 4/6] arm64: insn: add instruction decoders for ldp/stp and add/sub AKASHI Takahiro
2015-12-08 18:15 ` Will Deacon
2015-12-08 23:17 ` Jungseok Lee
2015-12-10 7:10 ` AKASHI Takahiro
2015-11-18 6:43 ` [PATCH v6 5/6] arm64: ftrace: add arch-specific stack tracer AKASHI Takahiro
2015-11-18 6:43 ` AKASHI Takahiro [this message]
2015-11-24 13:50 ` [PATCH v6 6/6] arm64: ftrace: add a test of function prologue analyzer Jungseok Lee
2015-11-25 5:33 ` AKASHI Takahiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1447828989-4980-7-git-send-email-takahiro.akashi@linaro.org \
--to=takahiro.akashi@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).