* [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 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 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 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
* [PATCH 0/3] perf tools: Add libdw DWARF post unwind support for ARM @ 2014-03-03 9:53 Jean Pihet 2014-03-03 9:53 ` [PATCH 2/3] perf tests: Add dwarf unwind test on ARM Jean Pihet 0 siblings, 1 reply; 16+ messages in thread From: Jean Pihet @ 2014-03-03 9:53 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 | 51 +++++++++++++++++++++++++++ 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, 161 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 latest acme/perf/core git tree, - Tested on quad-core ARMv7 machine -- 1.7.11.7 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [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
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).