* [PATCH 2/3] perf tests: Add dwarf unwind test on ARM
2014-03-03 9:53 [PATCH 0/3] " Jean Pihet
@ 2014-03-03 9:53 ` Jean Pihet
0 siblings, 0 replies; 16+ messages in thread
From: Jean Pihet @ 2014-03-03 9:53 UTC (permalink / raw)
To: linux-arm-kernel
Adding dwarf unwind test, that setups live machine data over
the perf test thread and does the remote unwind.
Need to use -fno-optimize-sibling-calls for test compilation,
otherwise 'krava_*' function calls are optimized into jumps
and ommited from the stack unwind.
So far it was enabled only for x86.
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
tools/perf/Makefile.perf | 2 +-
tools/perf/arch/arm/Makefile | 1 +
tools/perf/arch/arm/include/perf_regs.h | 3 ++
tools/perf/arch/arm/tests/dwarf-unwind.c | 59 ++++++++++++++++++++++++++++++++
tools/perf/tests/builtin-test.c | 2 +-
tools/perf/tests/tests.h | 2 +-
6 files changed, 66 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/arch/arm/tests/dwarf-unwind.c
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 50d875d..f281c4f 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -410,7 +410,7 @@ LIB_OBJS += $(OUTPUT)tests/code-reading.o
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
ifndef NO_DWARF_UNWIND
-ifeq ($(ARCH),x86)
+ifeq ($(ARCH),$(filter $(ARCH),x86 arm))
LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o
endif
endif
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 9b8f87e..221f21d 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -5,4 +5,5 @@ endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o
endif
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
index 1476ae7..c2cefff 100644
--- a/tools/perf/arch/arm/include/perf_regs.h
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -8,6 +8,9 @@
void perf_regs_load(u64 *regs);
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
+#define PERF_REGS_MAX PERF_REG_ARM_MAX
+#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
+
#define PERF_REG_IP PERF_REG_ARM_PC
#define PERF_REG_SP PERF_REG_ARM_SP
diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c
new file mode 100644
index 0000000..87362f7
--- /dev/null
+++ b/tools/perf/arch/arm/tests/dwarf-unwind.c
@@ -0,0 +1,59 @@
+#include <string.h>
+#include "perf_regs.h"
+#include "thread.h"
+#include "map.h"
+#include "event.h"
+#include "tests/tests.h"
+
+#define STACK_SIZE 8192
+
+static int sample_ustack(struct perf_sample *sample,
+ struct thread *thread, u64 *regs)
+{
+ struct stack_dump *stack = &sample->user_stack;
+ struct map *map;
+ unsigned long sp;
+ u64 stack_size, *buf;
+
+ buf = malloc(STACK_SIZE);
+ if (!buf) {
+ pr_debug("failed to allocate sample uregs data\n");
+ return -1;
+ }
+
+ sp = (unsigned long) regs[PERF_REG_ARM_SP];
+
+ map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
+ if (!map) {
+ pr_debug("failed to get stack map\n");
+ return -1;
+ }
+
+ stack_size = map->end - sp;
+ stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size;
+
+ memcpy(buf, (void *) sp, stack_size);
+ stack->data = (char *) buf;
+ stack->size = stack_size;
+ return 0;
+}
+
+int test__arch_unwind_sample(struct perf_sample *sample,
+ struct thread *thread)
+{
+ struct regs_dump *regs = &sample->user_regs;
+ u64 *buf;
+
+ buf = calloc(1, sizeof(u64) * PERF_REGS_MAX);
+ if (!buf) {
+ pr_debug("failed to allocate sample uregs data\n");
+ return -1;
+ }
+
+ perf_regs_load(buf);
+ regs->abi = PERF_SAMPLE_REGS_ABI;
+ regs->regs = buf;
+ regs->mask = PERF_REGS_MASK;
+
+ return sample_ustack(sample, thread, buf);
+}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index b11bf8a..167d527 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -115,7 +115,7 @@ static struct test {
.desc = "Test parsing with no sample_id_all bit set",
.func = test__parse_no_sample_id_all,
},
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
{
.desc = "Test dwarf unwind",
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a24795c..0c89cfe 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -42,7 +42,7 @@ int test__keep_tracking(void);
int test__parse_no_sample_id_all(void);
int test__dwarf_unwind(void);
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
struct thread;
struct perf_sample;
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 0/3] perf tools: Add libdw DWARF post unwind support for ARM
@ 2014-05-06 15:26 Jean Pihet
2014-05-06 15:26 ` [PATCH 1/3] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Jean Pihet @ 2014-05-06 15:26 UTC (permalink / raw)
To: linux-arm-kernel
Adding libdw DWARF post unwind support, which is part
of elfutils-devel/libdw-dev package from version 0.158.
Also includes the test suite for dwarf unwinding, by adding the
arch specific test code and the perf_regs_load function.
Jean Pihet (3):
perf tests: Introduce perf_regs_load function on ARM
perf tests: Add dwarf unwind test on ARM
perf tools: Add libdw DWARF post unwind support for ARM
tools/perf/Makefile.perf | 2 +-
tools/perf/arch/arm/Makefile | 7 ++++
tools/perf/arch/arm/include/perf_regs.h | 5 +++
tools/perf/arch/arm/tests/dwarf-unwind.c | 59 +++++++++++++++++++++++++++++++
tools/perf/arch/arm/tests/regs_load.S | 60 ++++++++++++++++++++++++++++++++
tools/perf/arch/arm/util/unwind-libdw.c | 36 +++++++++++++++++++
tools/perf/tests/builtin-test.c | 2 +-
tools/perf/tests/tests.h | 2 +-
8 files changed, 170 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/arch/arm/tests/dwarf-unwind.c
create mode 100644 tools/perf/arch/arm/tests/regs_load.S
create mode 100644 tools/perf/arch/arm/util/unwind-libdw.c
---
Rebased on the latest jolsa/perf/core
--
1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/3] perf tests: Introduce perf_regs_load function on ARM
2014-05-06 15:26 [PATCH 0/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
@ 2014-05-06 15:26 ` Jean Pihet
2014-05-06 15:26 ` [PATCH 2/3] perf tests: Add dwarf unwind test " Jean Pihet
2014-05-06 15:26 ` [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2 siblings, 0 replies; 16+ messages in thread
From: Jean Pihet @ 2014-05-06 15:26 UTC (permalink / raw)
To: linux-arm-kernel
Introducing perf_regs_load function, which is going
to be used for dwarf unwind test in following patches.
It takes single argument as a pointer to the regs dump
buffer and populates it with current registers values.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
---
tools/perf/arch/arm/Makefile | 1 +
tools/perf/arch/arm/include/perf_regs.h | 2 ++
tools/perf/arch/arm/tests/regs_load.S | 60 +++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+)
create mode 100644 tools/perf/arch/arm/tests/regs_load.S
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 67e9b3d..9b8f87e 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -4,4 +4,5 @@ LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
endif
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
index 2a1cfde..1476ae7 100644
--- a/tools/perf/arch/arm/include/perf_regs.h
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -5,6 +5,8 @@
#include "../../util/types.h"
#include <asm/perf_regs.h>
+void perf_regs_load(u64 *regs);
+
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
#define PERF_REG_IP PERF_REG_ARM_PC
#define PERF_REG_SP PERF_REG_ARM_SP
diff --git a/tools/perf/arch/arm/tests/regs_load.S b/tools/perf/arch/arm/tests/regs_load.S
new file mode 100644
index 0000000..66a10b6
--- /dev/null
+++ b/tools/perf/arch/arm/tests/regs_load.S
@@ -0,0 +1,60 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#define R0 0x00
+#define R1 0x08
+#define R2 0x10
+#define R3 0x18
+#define R4 0x20
+#define R5 0x28
+#define R6 0x30
+#define R7 0x38
+#define R8 0x40
+#define R9 0x48
+#define SL 0x50
+#define FP 0x58
+#define IP 0x60
+#define SP 0x68
+#define LR 0x70
+#define PC 0x78
+
+/*
+ * Implementation of void perf_regs_load(u64 *regs);
+ *
+ * This functions fills in the 'regs' buffer from the actual registers values,
+ * in the way the perf built-in unwinding test expects them:
+ * - the return values (i.e. caller values) of fp, sp and lr are retrieved
+ * and stored from the fp, in order to skip the call to this function.
+ * The built-in unwinding test then unwinds the call stack from the dwarf
+ * information in unwind__get_entries.
+ *
+ * Notes:
+ * - the 8 bytes stride in the registers offsets comes from the fact
+ * that the registers are stored in an u64 array (u64 *regs),
+ * - since perf is built with -fno-omit-frame-pointer, the fp value can
+ * be used to retrieve the caller values of fp, sp, lr.
+ */
+
+.text
+ENTRY(perf_regs_load)
+ str r0, [r0, #R0]
+ str r1, [r0, #R1]
+ str r2, [r0, #R2]
+ str r3, [r0, #R3]
+ str r4, [r0, #R4]
+ str r5, [r0, #R5]
+ str r6, [r0, #R6]
+ str r7, [r0, #R7]
+ str r8, [r0, #R8]
+ str r9, [r0, #R9]
+ str sl, [r0, #SL]
+ ldr r2, [fp, #-12] @ retrieve and save return fp
+ str r2, [r0, #FP]
+ str ip, [r0, #IP]
+ ldr r2, [fp, #-8] @ retrieve and save return sp
+ str r2, [r0, #SP]
+ ldr r2, [fp, #-4] @ retrieve and save return lr
+ str r2, [r0, #LR]
+ str pc, [r0, #PC]
+ mov pc, lr
+ENDPROC(perf_regs_load)
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/3] perf tests: Add dwarf unwind test on ARM
2014-05-06 15:26 [PATCH 0/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2014-05-06 15:26 ` [PATCH 1/3] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
@ 2014-05-06 15:26 ` Jean Pihet
2014-05-07 12:06 ` Jiri Olsa
2014-05-06 15:26 ` [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2 siblings, 1 reply; 16+ messages in thread
From: Jean Pihet @ 2014-05-06 15:26 UTC (permalink / raw)
To: linux-arm-kernel
Adding dwarf unwind test, that setups live machine data over
the perf test thread and does the remote unwind.
Need to use -fno-optimize-sibling-calls for test compilation,
otherwise 'krava_*' function calls are optimized into jumps
and ommited from the stack unwind.
So far it was enabled only for x86.
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
tools/perf/Makefile.perf | 2 +-
tools/perf/arch/arm/Makefile | 1 +
tools/perf/arch/arm/include/perf_regs.h | 3 ++
tools/perf/arch/arm/tests/dwarf-unwind.c | 59 ++++++++++++++++++++++++++++++++
tools/perf/tests/builtin-test.c | 2 +-
tools/perf/tests/tests.h | 2 +-
6 files changed, 66 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/arch/arm/tests/dwarf-unwind.c
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2baf61c..dea2d633 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -411,7 +411,7 @@ LIB_OBJS += $(OUTPUT)tests/code-reading.o
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
ifndef NO_DWARF_UNWIND
-ifeq ($(ARCH),x86)
+ifeq ($(ARCH),$(filter $(ARCH),x86 arm))
LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o
endif
endif
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 9b8f87e..221f21d 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -5,4 +5,5 @@ endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o
endif
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
index 1476ae7..c2cefff 100644
--- a/tools/perf/arch/arm/include/perf_regs.h
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -8,6 +8,9 @@
void perf_regs_load(u64 *regs);
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
+#define PERF_REGS_MAX PERF_REG_ARM_MAX
+#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
+
#define PERF_REG_IP PERF_REG_ARM_PC
#define PERF_REG_SP PERF_REG_ARM_SP
diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c
new file mode 100644
index 0000000..d618f5f
--- /dev/null
+++ b/tools/perf/arch/arm/tests/dwarf-unwind.c
@@ -0,0 +1,59 @@
+#include <string.h>
+#include "perf_regs.h"
+#include "thread.h"
+#include "map.h"
+#include "event.h"
+#include "tests/tests.h"
+
+#define STACK_SIZE 8192
+
+static int sample_ustack(struct perf_sample *sample,
+ struct thread *thread, u64 *regs)
+{
+ struct stack_dump *stack = &sample->user_stack;
+ struct map *map;
+ unsigned long sp;
+ u64 stack_size, *buf;
+
+ buf = malloc(STACK_SIZE);
+ if (!buf) {
+ pr_debug("failed to allocate sample uregs data\n");
+ return -1;
+ }
+
+ sp = (unsigned long) regs[PERF_REG_ARM_SP];
+
+ map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
+ if (!map) {
+ pr_debug("failed to get stack map\n");
+ return -1;
+ }
+
+ stack_size = map->end - sp;
+ stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size;
+
+ memcpy(buf, (void *) sp, stack_size);
+ stack->data = (char *) buf;
+ stack->size = stack_size;
+ return 0;
+}
+
+int test__arch_unwind_sample(struct perf_sample *sample,
+ struct thread *thread)
+{
+ struct regs_dump *regs = &sample->user_regs;
+ u64 *buf;
+
+ buf = malloc(sizeof(u64) * PERF_REGS_MAX);
+ if (!buf) {
+ pr_debug("failed to allocate sample uregs data\n");
+ return -1;
+ }
+
+ perf_regs_load(buf);
+ regs->abi = PERF_SAMPLE_REGS_ABI;
+ regs->regs = buf;
+ regs->mask = PERF_REGS_MASK;
+
+ return sample_ustack(sample, thread, buf);
+}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0d5afaf..5e0764b 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -115,7 +115,7 @@ static struct test {
.desc = "Test parsing with no sample_id_all bit set",
.func = test__parse_no_sample_id_all,
},
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
{
.desc = "Test dwarf unwind",
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a9d7cb0..8f91fb0 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -45,7 +45,7 @@ int test__hists_filter(void);
int test__mmap_thread_lookup(void);
int test__thread_mg_share(void);
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
struct thread;
struct perf_sample;
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM
2014-05-06 15:26 [PATCH 0/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2014-05-06 15:26 ` [PATCH 1/3] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
2014-05-06 15:26 ` [PATCH 2/3] perf tests: Add dwarf unwind test " Jean Pihet
@ 2014-05-06 15:26 ` Jean Pihet
2014-05-06 17:56 ` Will Deacon
2 siblings, 1 reply; 16+ messages in thread
From: Jean Pihet @ 2014-05-06 15:26 UTC (permalink / raw)
To: linux-arm-kernel
Adding libdw DWARF post unwind support, which is part
of elfutils-devel/libdw-dev package from version 0.158.
The new code is contained in unwin-libdw.c object, and
implements unwind__get_entries unwind interface function.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: David Ahern <dsahern@gmail.com>
---
tools/perf/arch/arm/Makefile | 5 +++++
tools/perf/arch/arm/util/unwind-libdw.c | 36 +++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100644 tools/perf/arch/arm/util/unwind-libdw.c
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 221f21d..09d6215 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -4,6 +4,11 @@ LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
+endif
+ifndef NO_LIBDW_DWARF_UNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libdw.o
+endif
+ifndef NO_DWARF_UNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o
endif
diff --git a/tools/perf/arch/arm/util/unwind-libdw.c b/tools/perf/arch/arm/util/unwind-libdw.c
new file mode 100644
index 0000000..b4176c6
--- /dev/null
+++ b/tools/perf/arch/arm/util/unwind-libdw.c
@@ -0,0 +1,36 @@
+#include <elfutils/libdwfl.h>
+#include "../../util/unwind-libdw.h"
+#include "../../util/perf_regs.h"
+
+bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
+{
+ struct unwind_info *ui = arg;
+ struct regs_dump *user_regs = &ui->sample->user_regs;
+ Dwarf_Word dwarf_regs[PERF_REG_ARM_MAX];
+
+#define REG(r) ({ \
+ Dwarf_Word val = 0; \
+ perf_reg_value(&val, user_regs, PERF_REG_ARM_##r); \
+ val; \
+})
+
+ dwarf_regs[0] = REG(R0);
+ dwarf_regs[1] = REG(R1);
+ dwarf_regs[2] = REG(R2);
+ dwarf_regs[3] = REG(R3);
+ dwarf_regs[4] = REG(R4);
+ dwarf_regs[5] = REG(R5);
+ dwarf_regs[6] = REG(R6);
+ dwarf_regs[7] = REG(R7);
+ dwarf_regs[8] = REG(R8);
+ dwarf_regs[9] = REG(R9);
+ dwarf_regs[10] = REG(R10);
+ dwarf_regs[11] = REG(FP);
+ dwarf_regs[12] = REG(IP);
+ dwarf_regs[13] = REG(SP);
+ dwarf_regs[14] = REG(LR);
+ dwarf_regs[15] = REG(PC);
+
+ return dwfl_thread_state_registers(thread, 0, PERF_REG_ARM_MAX,
+ dwarf_regs);
+}
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM
2014-05-06 15:26 ` [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
@ 2014-05-06 17:56 ` Will Deacon
2014-05-07 9:52 ` Jean Pihet
0 siblings, 1 reply; 16+ messages in thread
From: Will Deacon @ 2014-05-06 17:56 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, May 06, 2014 at 04:26:19PM +0100, Jean Pihet wrote:
> Adding libdw DWARF post unwind support, which is part
> of elfutils-devel/libdw-dev package from version 0.158.
>
> The new code is contained in unwin-libdw.c object, and
> implements unwind__get_entries unwind interface function.
Reviewed-by: Will Deacon <will.deacon@arm.com>
Will
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM
2014-05-06 17:56 ` Will Deacon
@ 2014-05-07 9:52 ` Jean Pihet
2014-05-07 10:00 ` Will Deacon
0 siblings, 1 reply; 16+ messages in thread
From: Jean Pihet @ 2014-05-07 9:52 UTC (permalink / raw)
To: linux-arm-kernel
On 6 May 2014 19:56, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, May 06, 2014 at 04:26:19PM +0100, Jean Pihet wrote:
>> Adding libdw DWARF post unwind support, which is part
>> of elfutils-devel/libdw-dev package from version 0.158.
>>
>> The new code is contained in unwin-libdw.c object, and
>> implements unwind__get_entries unwind interface function.
>
> Reviewed-by: Will Deacon <will.deacon@arm.com>
Ok, thx!
Jiri, Arnaldo,
Can you take the series for ARM and ARM64?
Jean
>
> Will
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM
2014-05-07 9:52 ` Jean Pihet
@ 2014-05-07 10:00 ` Will Deacon
2014-05-07 10:14 ` Jean Pihet
0 siblings, 1 reply; 16+ messages in thread
From: Will Deacon @ 2014-05-07 10:00 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, May 07, 2014 at 10:52:05AM +0100, Jean Pihet wrote:
> On 6 May 2014 19:56, Will Deacon <will.deacon@arm.com> wrote:
> > On Tue, May 06, 2014 at 04:26:19PM +0100, Jean Pihet wrote:
> >> Adding libdw DWARF post unwind support, which is part
> >> of elfutils-devel/libdw-dev package from version 0.158.
> >>
> >> The new code is contained in unwin-libdw.c object, and
> >> implements unwind__get_entries unwind interface function.
> >
> > Reviewed-by: Will Deacon <will.deacon@arm.com>
>
> Ok, thx!
>
> Jiri, Arnaldo,
> Can you take the series for ARM and ARM64?
Wait: I thought you were going to add compat support for arm64? I haven't
acked that patch yet, because it's lacking those changes.
The 32-bit ARM patches look fine though.
Will
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM
2014-05-07 10:00 ` Will Deacon
@ 2014-05-07 10:14 ` Jean Pihet
2014-05-16 8:41 ` [PATCH 1/4] tools: perf: consolidate types.h for ARM and ARM64 Jean Pihet
0 siblings, 1 reply; 16+ messages in thread
From: Jean Pihet @ 2014-05-07 10:14 UTC (permalink / raw)
To: linux-arm-kernel
On 7 May 2014 12:00, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, May 07, 2014 at 10:52:05AM +0100, Jean Pihet wrote:
>> On 6 May 2014 19:56, Will Deacon <will.deacon@arm.com> wrote:
>> > On Tue, May 06, 2014 at 04:26:19PM +0100, Jean Pihet wrote:
>> >> Adding libdw DWARF post unwind support, which is part
>> >> of elfutils-devel/libdw-dev package from version 0.158.
>> >>
>> >> The new code is contained in unwin-libdw.c object, and
>> >> implements unwind__get_entries unwind interface function.
>> >
>> > Reviewed-by: Will Deacon <will.deacon@arm.com>
>>
>> Ok, thx!
>>
>> Jiri, Arnaldo,
>> Can you take the series for ARM and ARM64?
>
> Wait: I thought you were going to add compat support for arm64? I haven't
> acked that patch yet, because it's lacking those changes.
The compat mode is supported by libdw and _should_ work in principle.
I am following it up with Mark Wielaard on elfutils-devel.
Cf. [1] for the discussion and [2] for the compat mode support in libdw.
[1] https://lists.fedorahosted.org/pipermail/elfutils-devel/2014-March/003905.html
[2] https://lists.fedorahosted.org/pipermail/elfutils-devel/2014-March/003910.html
So in summary the kernel changes should be fine (it works ok with
libunwind), the problem lies somewhere in the libdw registers setup
and usage for compat mode.
>
> The 32-bit ARM patches look fine though.
Thx!
>
> Will
Jean
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/3] perf tests: Add dwarf unwind test on ARM
2014-05-06 15:26 ` [PATCH 2/3] perf tests: Add dwarf unwind test " Jean Pihet
@ 2014-05-07 12:06 ` Jiri Olsa
2014-05-07 12:24 ` Jean Pihet
0 siblings, 1 reply; 16+ messages in thread
From: Jiri Olsa @ 2014-05-07 12:06 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, May 06, 2014 at 05:26:18PM +0200, Jean Pihet wrote:
SNIP
> diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c
> new file mode 100644
> index 0000000..d618f5f
> --- /dev/null
> +++ b/tools/perf/arch/arm/tests/dwarf-unwind.c
> @@ -0,0 +1,59 @@
> +#include <string.h>
> +#include "perf_regs.h"
> +#include "thread.h"
> +#include "map.h"
> +#include "event.h"
> +#include "tests/tests.h"
> +
> +#define STACK_SIZE 8192
> +
> +static int sample_ustack(struct perf_sample *sample,
> + struct thread *thread, u64 *regs)
> +{
> + struct stack_dump *stack = &sample->user_stack;
> + struct map *map;
> + unsigned long sp;
> + u64 stack_size, *buf;
> +
> + buf = malloc(STACK_SIZE);
> + if (!buf) {
> + pr_debug("failed to allocate sample uregs data\n");
> + return -1;
> + }
> +
> + sp = (unsigned long) regs[PERF_REG_ARM_SP];
> +
> + map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
> + if (!map) {
> + pr_debug("failed to get stack map\n");
> + return -1;
> + }
there's a memory leak of 'buf' already fixed fox x86:
perf tests x86: Fix memory leak in sample_ustack()
commit 763d7f5f2718f085bab5a9e63308349728f3ad12
Author: Masanari Iida <standby24x7@gmail.com>
Date: Sun Apr 20 00:16:41 2014 +0900
jirka
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/3] perf tests: Add dwarf unwind test on ARM
2014-05-07 12:06 ` Jiri Olsa
@ 2014-05-07 12:24 ` Jean Pihet
2014-05-07 12:36 ` Jiri Olsa
0 siblings, 1 reply; 16+ messages in thread
From: Jean Pihet @ 2014-05-07 12:24 UTC (permalink / raw)
To: linux-arm-kernel
Hi Jiri,
On 7 May 2014 14:06, Jiri Olsa <jolsa@redhat.com> wrote:
> On Tue, May 06, 2014 at 05:26:18PM +0200, Jean Pihet wrote:
>
SNIP
>
> there's a memory leak of 'buf' already fixed fox x86:
>
> perf tests x86: Fix memory leak in sample_ustack()
> commit 763d7f5f2718f085bab5a9e63308349728f3ad12
> Author: Masanari Iida <standby24x7@gmail.com>
> Date: Sun Apr 20 00:16:41 2014 +0900
>
> jirka
Ok
Here is the diff between the x86 and the ARM implementations:
$ diff -urN tools/perf/arch/arm64/tests/dwarf-unwind.c
tools/perf/arch/x86/tests/dwarf-unwind.c
--- tools/perf/arch/arm64/tests/dwarf-unwind.c 2014-05-06
17:31:17.507961045 +0200
+++ tools/perf/arch/x86/tests/dwarf-unwind.c 2014-05-06
16:52:00.589776839 +0200
@@ -21,11 +21,12 @@
return -1;
}
- sp = (unsigned long) regs[PERF_REG_ARM64_SP];
+ sp = (unsigned long) regs[PERF_REG_X86_SP];
- map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
+ map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp);
if (!map) {
pr_debug("failed to get stack map\n");
+ free(buf);
return -1;
}
Which leads to a few questions:
- the map_groups__find parameters need to be fixed too, right?
- the free(buf) needs to be fixed,
- given that the remaining difference in the file is just a register
macro, it is worth to factor the code in a single file. Does that make
sense? If worthwhile I can do that once the ARM and ARM64 support is
merged in.
What do you think?
Regards,
Jean
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/3] perf tests: Add dwarf unwind test on ARM
2014-05-07 12:24 ` Jean Pihet
@ 2014-05-07 12:36 ` Jiri Olsa
0 siblings, 0 replies; 16+ messages in thread
From: Jiri Olsa @ 2014-05-07 12:36 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, May 07, 2014 at 02:24:53PM +0200, Jean Pihet wrote:
> Hi Jiri,
>
> On 7 May 2014 14:06, Jiri Olsa <jolsa@redhat.com> wrote:
> > On Tue, May 06, 2014 at 05:26:18PM +0200, Jean Pihet wrote:
> >
> SNIP
> >
> > there's a memory leak of 'buf' already fixed fox x86:
> >
> > perf tests x86: Fix memory leak in sample_ustack()
> > commit 763d7f5f2718f085bab5a9e63308349728f3ad12
> > Author: Masanari Iida <standby24x7@gmail.com>
> > Date: Sun Apr 20 00:16:41 2014 +0900
> >
> > jirka
>
> Ok
>
> Here is the diff between the x86 and the ARM implementations:
> $ diff -urN tools/perf/arch/arm64/tests/dwarf-unwind.c
> tools/perf/arch/x86/tests/dwarf-unwind.c
> --- tools/perf/arch/arm64/tests/dwarf-unwind.c 2014-05-06
> 17:31:17.507961045 +0200
> +++ tools/perf/arch/x86/tests/dwarf-unwind.c 2014-05-06
> 16:52:00.589776839 +0200
> @@ -21,11 +21,12 @@
> return -1;
> }
>
> - sp = (unsigned long) regs[PERF_REG_ARM64_SP];
> + sp = (unsigned long) regs[PERF_REG_X86_SP];
>
> - map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
> + map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp);
> if (!map) {
> pr_debug("failed to get stack map\n");
> + free(buf);
> return -1;
> }
>
> Which leads to a few questions:
> - the map_groups__find parameters need to be fixed too, right?
the reason for this is following commit:
6392b4e perf x86: Fix perf to use non-executable stack, again
which also adds global link flags: -Wl,-z,noexecstack
so I'm guessing arm is affected too
> - the free(buf) needs to be fixed,
> - given that the remaining difference in the file is just a register
> macro, it is worth to factor the code in a single file. Does that make
> sense? If worthwhile I can do that once the ARM and ARM64 support is
> merged in.
we can do the code factoring later here, np
thanks,
jirka
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/4] tools: perf: consolidate types.h for ARM and ARM64
2014-05-07 10:14 ` Jean Pihet
@ 2014-05-16 8:41 ` Jean Pihet
2014-05-16 8:41 ` [PATCH 2/4] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Jean Pihet @ 2014-05-16 8:41 UTC (permalink / raw)
To: linux-arm-kernel
Prevents a build breakage since commit d944c4eebcf4c0d5e5d9728fec110cbf0047ad7f
'tools: Consolidate types.h'
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
tools/perf/arch/arm/include/perf_regs.h | 2 +-
tools/perf/arch/arm64/include/perf_regs.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
index 2a1cfde..bcca511 100644
--- a/tools/perf/arch/arm/include/perf_regs.h
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -2,7 +2,7 @@
#define ARCH_PERF_REGS_H
#include <stdlib.h>
-#include "../../util/types.h"
+#include <linux/types.h>
#include <asm/perf_regs.h>
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h
index 2359546..e9441b9 100644
--- a/tools/perf/arch/arm64/include/perf_regs.h
+++ b/tools/perf/arch/arm64/include/perf_regs.h
@@ -2,7 +2,7 @@
#define ARCH_PERF_REGS_H
#include <stdlib.h>
-#include "../../util/types.h"
+#include <linux/types.h>
#include <asm/perf_regs.h>
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1)
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/4] perf tests: Introduce perf_regs_load function on ARM
2014-05-16 8:41 ` [PATCH 1/4] tools: perf: consolidate types.h for ARM and ARM64 Jean Pihet
@ 2014-05-16 8:41 ` Jean Pihet
2014-05-16 8:41 ` [PATCH 3/4] perf tests: Add dwarf unwind test " Jean Pihet
2014-05-16 8:41 ` [PATCH 4/4] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2 siblings, 0 replies; 16+ messages in thread
From: Jean Pihet @ 2014-05-16 8:41 UTC (permalink / raw)
To: linux-arm-kernel
Introducing perf_regs_load function, which is going
to be used for dwarf unwind test in following patches.
It takes single argument as a pointer to the regs dump
buffer and populates it with current registers values.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
---
tools/perf/arch/arm/Makefile | 1 +
tools/perf/arch/arm/include/perf_regs.h | 2 ++
tools/perf/arch/arm/tests/regs_load.S | 58 +++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
create mode 100644 tools/perf/arch/arm/tests/regs_load.S
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 67e9b3d..9b8f87e 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -4,4 +4,5 @@ LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
endif
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
index bcca511..33abcfa 100644
--- a/tools/perf/arch/arm/include/perf_regs.h
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -5,6 +5,8 @@
#include <linux/types.h>
#include <asm/perf_regs.h>
+void perf_regs_load(u64 *regs);
+
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
#define PERF_REG_IP PERF_REG_ARM_PC
#define PERF_REG_SP PERF_REG_ARM_SP
diff --git a/tools/perf/arch/arm/tests/regs_load.S b/tools/perf/arch/arm/tests/regs_load.S
new file mode 100644
index 0000000..e09e983
--- /dev/null
+++ b/tools/perf/arch/arm/tests/regs_load.S
@@ -0,0 +1,58 @@
+#include <linux/linkage.h>
+
+#define R0 0x00
+#define R1 0x08
+#define R2 0x10
+#define R3 0x18
+#define R4 0x20
+#define R5 0x28
+#define R6 0x30
+#define R7 0x38
+#define R8 0x40
+#define R9 0x48
+#define SL 0x50
+#define FP 0x58
+#define IP 0x60
+#define SP 0x68
+#define LR 0x70
+#define PC 0x78
+
+/*
+ * Implementation of void perf_regs_load(u64 *regs);
+ *
+ * This functions fills in the 'regs' buffer from the actual registers values,
+ * in the way the perf built-in unwinding test expects them:
+ * - the PC at the time at the call to this function. Since this function
+ * is called using a bl instruction, the PC value is taken from LR.
+ * The built-in unwinding test then unwinds the call stack from the dwarf
+ * information in unwind__get_entries.
+ *
+ * Notes:
+ * - the 8 bytes stride in the registers offsets comes from the fact
+ * that the registers are stored in an u64 array (u64 *regs),
+ * - the regs buffer needs to be zeroed before the call to this function,
+ * in this case using a calloc in dwarf-unwind.c.
+ */
+
+.text
+.type perf_regs_load,%function
+ENTRY(perf_regs_load)
+ str r0, [r0, #R0]
+ str r1, [r0, #R1]
+ str r2, [r0, #R2]
+ str r3, [r0, #R3]
+ str r4, [r0, #R4]
+ str r5, [r0, #R5]
+ str r6, [r0, #R6]
+ str r7, [r0, #R7]
+ str r8, [r0, #R8]
+ str r9, [r0, #R9]
+ str sl, [r0, #SL]
+ str fp, [r0, #FP]
+ str ip, [r0, #IP]
+ str sp, [r0, #SP]
+ str lr, [r0, #LR]
+ str lr, [r0, #PC] // store pc as lr in order to skip the call
+ // to this function
+ mov pc, lr
+ENDPROC(perf_regs_load)
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/4] perf tests: Add dwarf unwind test on ARM
2014-05-16 8:41 ` [PATCH 1/4] tools: perf: consolidate types.h for ARM and ARM64 Jean Pihet
2014-05-16 8:41 ` [PATCH 2/4] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
@ 2014-05-16 8:41 ` Jean Pihet
2014-05-16 8:41 ` [PATCH 4/4] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2 siblings, 0 replies; 16+ messages in thread
From: Jean Pihet @ 2014-05-16 8:41 UTC (permalink / raw)
To: linux-arm-kernel
Adding dwarf unwind test, that setups live machine data over
the perf test thread and does the remote unwind.
Need to use -fno-optimize-sibling-calls for test compilation,
otherwise 'krava_*' function calls are optimized into jumps
and ommited from the stack unwind.
So far it was enabled only for x86.
Reviewed-by: Will Deacon <will.deacon@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
tools/perf/Makefile.perf | 2 +-
tools/perf/arch/arm/Makefile | 1 +
tools/perf/arch/arm/include/perf_regs.h | 3 ++
tools/perf/arch/arm/tests/dwarf-unwind.c | 60 ++++++++++++++++++++++++++++++++
tools/perf/config/Makefile | 4 +--
tools/perf/tests/builtin-test.c | 2 +-
tools/perf/tests/tests.h | 2 +-
7 files changed, 69 insertions(+), 5 deletions(-)
create mode 100644 tools/perf/arch/arm/tests/dwarf-unwind.c
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2baf61c..dea2d633 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -411,7 +411,7 @@ LIB_OBJS += $(OUTPUT)tests/code-reading.o
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
ifndef NO_DWARF_UNWIND
-ifeq ($(ARCH),x86)
+ifeq ($(ARCH),$(filter $(ARCH),x86 arm))
LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o
endif
endif
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 9b8f87e..221f21d 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -5,4 +5,5 @@ endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o
endif
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
index 33abcfa..f619c9c 100644
--- a/tools/perf/arch/arm/include/perf_regs.h
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -8,6 +8,9 @@
void perf_regs_load(u64 *regs);
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
+#define PERF_REGS_MAX PERF_REG_ARM_MAX
+#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
+
#define PERF_REG_IP PERF_REG_ARM_PC
#define PERF_REG_SP PERF_REG_ARM_SP
diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c
new file mode 100644
index 0000000..9f870d2
--- /dev/null
+++ b/tools/perf/arch/arm/tests/dwarf-unwind.c
@@ -0,0 +1,60 @@
+#include <string.h>
+#include "perf_regs.h"
+#include "thread.h"
+#include "map.h"
+#include "event.h"
+#include "tests/tests.h"
+
+#define STACK_SIZE 8192
+
+static int sample_ustack(struct perf_sample *sample,
+ struct thread *thread, u64 *regs)
+{
+ struct stack_dump *stack = &sample->user_stack;
+ struct map *map;
+ unsigned long sp;
+ u64 stack_size, *buf;
+
+ buf = malloc(STACK_SIZE);
+ if (!buf) {
+ pr_debug("failed to allocate sample uregs data\n");
+ return -1;
+ }
+
+ sp = (unsigned long) regs[PERF_REG_ARM_SP];
+
+ map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp);
+ if (!map) {
+ pr_debug("failed to get stack map\n");
+ free(buf);
+ return -1;
+ }
+
+ stack_size = map->end - sp;
+ stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size;
+
+ memcpy(buf, (void *) sp, stack_size);
+ stack->data = (char *) buf;
+ stack->size = stack_size;
+ return 0;
+}
+
+int test__arch_unwind_sample(struct perf_sample *sample,
+ struct thread *thread)
+{
+ struct regs_dump *regs = &sample->user_regs;
+ u64 *buf;
+
+ buf = calloc(1, sizeof(u64) * PERF_REGS_MAX);
+ if (!buf) {
+ pr_debug("failed to allocate sample uregs data\n");
+ return -1;
+ }
+
+ perf_regs_load(buf);
+ regs->abi = PERF_SAMPLE_REGS_ABI;
+ regs->regs = buf;
+ regs->mask = PERF_REGS_MASK;
+
+ return sample_ustack(sample, thread, buf);
+}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index f2edc59..729bbdf 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -40,11 +40,11 @@ ifeq ($(ARCH),arm64)
LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
endif
-# So far there's only x86 libdw unwind support merged in perf.
+# So far there's only x86 and arm libdw unwind support merged in perf.
# Disable it on all other architectures in case libdw unwind
# support is detected in system. Add supported architectures
# to the check.
-ifneq ($(ARCH),x86)
+ifneq ($(ARCH),$(filter $(ARCH),x86 arm))
NO_LIBDW_DWARF_UNWIND := 1
endif
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0d5afaf..5e0764b 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -115,7 +115,7 @@ static struct test {
.desc = "Test parsing with no sample_id_all bit set",
.func = test__parse_no_sample_id_all,
},
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
{
.desc = "Test dwarf unwind",
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a9d7cb0..8f91fb0 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -45,7 +45,7 @@ int test__hists_filter(void);
int test__mmap_thread_lookup(void);
int test__thread_mg_share(void);
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT
struct thread;
struct perf_sample;
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/4] perf tools: Add libdw DWARF post unwind support for ARM
2014-05-16 8:41 ` [PATCH 1/4] tools: perf: consolidate types.h for ARM and ARM64 Jean Pihet
2014-05-16 8:41 ` [PATCH 2/4] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
2014-05-16 8:41 ` [PATCH 3/4] perf tests: Add dwarf unwind test " Jean Pihet
@ 2014-05-16 8:41 ` Jean Pihet
2 siblings, 0 replies; 16+ messages in thread
From: Jean Pihet @ 2014-05-16 8:41 UTC (permalink / raw)
To: linux-arm-kernel
Adding libdw DWARF post unwind support, which is part
of elfutils-devel/libdw-dev package from version 0.158.
The new code is contained in unwin-libdw.c object, and
implements unwind__get_entries unwind interface function.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: David Ahern <dsahern@gmail.com>
---
tools/perf/arch/arm/Makefile | 5 +++++
tools/perf/arch/arm/util/unwind-libdw.c | 36 +++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100644 tools/perf/arch/arm/util/unwind-libdw.c
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 221f21d..09d6215 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -4,6 +4,11 @@ LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
+endif
+ifndef NO_LIBDW_DWARF_UNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libdw.o
+endif
+ifndef NO_DWARF_UNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o
endif
diff --git a/tools/perf/arch/arm/util/unwind-libdw.c b/tools/perf/arch/arm/util/unwind-libdw.c
new file mode 100644
index 0000000..b4176c6
--- /dev/null
+++ b/tools/perf/arch/arm/util/unwind-libdw.c
@@ -0,0 +1,36 @@
+#include <elfutils/libdwfl.h>
+#include "../../util/unwind-libdw.h"
+#include "../../util/perf_regs.h"
+
+bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
+{
+ struct unwind_info *ui = arg;
+ struct regs_dump *user_regs = &ui->sample->user_regs;
+ Dwarf_Word dwarf_regs[PERF_REG_ARM_MAX];
+
+#define REG(r) ({ \
+ Dwarf_Word val = 0; \
+ perf_reg_value(&val, user_regs, PERF_REG_ARM_##r); \
+ val; \
+})
+
+ dwarf_regs[0] = REG(R0);
+ dwarf_regs[1] = REG(R1);
+ dwarf_regs[2] = REG(R2);
+ dwarf_regs[3] = REG(R3);
+ dwarf_regs[4] = REG(R4);
+ dwarf_regs[5] = REG(R5);
+ dwarf_regs[6] = REG(R6);
+ dwarf_regs[7] = REG(R7);
+ dwarf_regs[8] = REG(R8);
+ dwarf_regs[9] = REG(R9);
+ dwarf_regs[10] = REG(R10);
+ dwarf_regs[11] = REG(FP);
+ dwarf_regs[12] = REG(IP);
+ dwarf_regs[13] = REG(SP);
+ dwarf_regs[14] = REG(LR);
+ dwarf_regs[15] = REG(PC);
+
+ return dwfl_thread_state_registers(thread, 0, PERF_REG_ARM_MAX,
+ dwarf_regs);
+}
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2014-05-16 8:41 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-06 15:26 [PATCH 0/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2014-05-06 15:26 ` [PATCH 1/3] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
2014-05-06 15:26 ` [PATCH 2/3] perf tests: Add dwarf unwind test " Jean Pihet
2014-05-07 12:06 ` Jiri Olsa
2014-05-07 12:24 ` Jean Pihet
2014-05-07 12:36 ` Jiri Olsa
2014-05-06 15:26 ` [PATCH 3/3] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
2014-05-06 17:56 ` Will Deacon
2014-05-07 9:52 ` Jean Pihet
2014-05-07 10:00 ` Will Deacon
2014-05-07 10:14 ` Jean Pihet
2014-05-16 8:41 ` [PATCH 1/4] tools: perf: consolidate types.h for ARM and ARM64 Jean Pihet
2014-05-16 8:41 ` [PATCH 2/4] perf tests: Introduce perf_regs_load function on ARM Jean Pihet
2014-05-16 8:41 ` [PATCH 3/4] perf tests: Add dwarf unwind test " Jean Pihet
2014-05-16 8:41 ` [PATCH 4/4] perf tools: Add libdw DWARF post unwind support for ARM Jean Pihet
-- strict thread matches above, loose matches on Subject: below --
2014-03-03 9:53 [PATCH 0/3] " Jean Pihet
2014-03-03 9:53 ` [PATCH 2/3] perf tests: Add dwarf unwind test on ARM Jean Pihet
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).