diff options
| -rw-r--r-- | tools/perf/Makefile.perf | 2 | ||||
| -rw-r--r-- | tools/perf/arch/arm/Makefile | 1 | ||||
| -rw-r--r-- | tools/perf/arch/arm/include/perf_regs.h | 3 | ||||
| -rw-r--r-- | tools/perf/arch/arm/tests/dwarf-unwind.c | 60 | ||||
| -rw-r--r-- | tools/perf/config/Makefile | 4 | ||||
| -rw-r--r-- | tools/perf/tests/builtin-test.c | 2 | ||||
| -rw-r--r-- | tools/perf/tests/tests.h | 2 |
7 files changed, 69 insertions, 5 deletions
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 2baf61cec7ff..dea2d633c374 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -411,7 +411,7 @@ LIB_OBJS += $(OUTPUT)tests/code-reading.o | |||
| 411 | LIB_OBJS += $(OUTPUT)tests/sample-parsing.o | 411 | LIB_OBJS += $(OUTPUT)tests/sample-parsing.o |
| 412 | LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o | 412 | LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o |
| 413 | ifndef NO_DWARF_UNWIND | 413 | ifndef NO_DWARF_UNWIND |
| 414 | ifeq ($(ARCH),x86) | 414 | ifeq ($(ARCH),$(filter $(ARCH),x86 arm)) |
| 415 | LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o | 415 | LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o |
| 416 | endif | 416 | endif |
| 417 | endif | 417 | endif |
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile index 9b8f87e8c7b9..221f21d5ca28 100644 --- a/tools/perf/arch/arm/Makefile +++ b/tools/perf/arch/arm/Makefile | |||
| @@ -5,4 +5,5 @@ endif | |||
| 5 | ifndef NO_LIBUNWIND | 5 | ifndef NO_LIBUNWIND |
| 6 | LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o | 6 | LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o |
| 7 | LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o | 7 | LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o |
| 8 | LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o | ||
| 8 | endif | 9 | endif |
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h index 33abcfa3057c..f619c9c5a4bf 100644 --- a/tools/perf/arch/arm/include/perf_regs.h +++ b/tools/perf/arch/arm/include/perf_regs.h | |||
| @@ -8,6 +8,9 @@ | |||
| 8 | void perf_regs_load(u64 *regs); | 8 | void perf_regs_load(u64 *regs); |
| 9 | 9 | ||
| 10 | #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1) | 10 | #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1) |
| 11 | #define PERF_REGS_MAX PERF_REG_ARM_MAX | ||
| 12 | #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 | ||
| 13 | |||
| 11 | #define PERF_REG_IP PERF_REG_ARM_PC | 14 | #define PERF_REG_IP PERF_REG_ARM_PC |
| 12 | #define PERF_REG_SP PERF_REG_ARM_SP | 15 | #define PERF_REG_SP PERF_REG_ARM_SP |
| 13 | 16 | ||
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 000000000000..9f870d27cb39 --- /dev/null +++ b/tools/perf/arch/arm/tests/dwarf-unwind.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | #include <string.h> | ||
| 2 | #include "perf_regs.h" | ||
| 3 | #include "thread.h" | ||
| 4 | #include "map.h" | ||
| 5 | #include "event.h" | ||
| 6 | #include "tests/tests.h" | ||
| 7 | |||
| 8 | #define STACK_SIZE 8192 | ||
| 9 | |||
| 10 | static int sample_ustack(struct perf_sample *sample, | ||
| 11 | struct thread *thread, u64 *regs) | ||
| 12 | { | ||
| 13 | struct stack_dump *stack = &sample->user_stack; | ||
| 14 | struct map *map; | ||
| 15 | unsigned long sp; | ||
| 16 | u64 stack_size, *buf; | ||
| 17 | |||
| 18 | buf = malloc(STACK_SIZE); | ||
| 19 | if (!buf) { | ||
| 20 | pr_debug("failed to allocate sample uregs data\n"); | ||
| 21 | return -1; | ||
| 22 | } | ||
| 23 | |||
| 24 | sp = (unsigned long) regs[PERF_REG_ARM_SP]; | ||
| 25 | |||
| 26 | map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); | ||
| 27 | if (!map) { | ||
| 28 | pr_debug("failed to get stack map\n"); | ||
| 29 | free(buf); | ||
| 30 | return -1; | ||
| 31 | } | ||
| 32 | |||
| 33 | stack_size = map->end - sp; | ||
| 34 | stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; | ||
| 35 | |||
| 36 | memcpy(buf, (void *) sp, stack_size); | ||
| 37 | stack->data = (char *) buf; | ||
| 38 | stack->size = stack_size; | ||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | int test__arch_unwind_sample(struct perf_sample *sample, | ||
| 43 | struct thread *thread) | ||
| 44 | { | ||
| 45 | struct regs_dump *regs = &sample->user_regs; | ||
| 46 | u64 *buf; | ||
| 47 | |||
| 48 | buf = calloc(1, sizeof(u64) * PERF_REGS_MAX); | ||
| 49 | if (!buf) { | ||
| 50 | pr_debug("failed to allocate sample uregs data\n"); | ||
| 51 | return -1; | ||
| 52 | } | ||
| 53 | |||
| 54 | perf_regs_load(buf); | ||
| 55 | regs->abi = PERF_SAMPLE_REGS_ABI; | ||
| 56 | regs->regs = buf; | ||
| 57 | regs->mask = PERF_REGS_MASK; | ||
| 58 | |||
| 59 | return sample_ustack(sample, thread, buf); | ||
| 60 | } | ||
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index f2edc593a7a7..729bbdf5cec7 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
| @@ -40,11 +40,11 @@ ifeq ($(ARCH),arm64) | |||
| 40 | LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 | 40 | LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 |
| 41 | endif | 41 | endif |
| 42 | 42 | ||
| 43 | # So far there's only x86 libdw unwind support merged in perf. | 43 | # So far there's only x86 and arm libdw unwind support merged in perf. |
| 44 | # Disable it on all other architectures in case libdw unwind | 44 | # Disable it on all other architectures in case libdw unwind |
| 45 | # support is detected in system. Add supported architectures | 45 | # support is detected in system. Add supported architectures |
| 46 | # to the check. | 46 | # to the check. |
| 47 | ifneq ($(ARCH),x86) | 47 | ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) |
| 48 | NO_LIBDW_DWARF_UNWIND := 1 | 48 | NO_LIBDW_DWARF_UNWIND := 1 |
| 49 | endif | 49 | endif |
| 50 | 50 | ||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 0d5afaf72944..5e0764b09317 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
| @@ -115,7 +115,7 @@ static struct test { | |||
| 115 | .desc = "Test parsing with no sample_id_all bit set", | 115 | .desc = "Test parsing with no sample_id_all bit set", |
| 116 | .func = test__parse_no_sample_id_all, | 116 | .func = test__parse_no_sample_id_all, |
| 117 | }, | 117 | }, |
| 118 | #if defined(__x86_64__) || defined(__i386__) | 118 | #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) |
| 119 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | 119 | #ifdef HAVE_DWARF_UNWIND_SUPPORT |
| 120 | { | 120 | { |
| 121 | .desc = "Test dwarf unwind", | 121 | .desc = "Test dwarf unwind", |
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index a9d7cb019f9e..8f91fb051ef1 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h | |||
| @@ -45,7 +45,7 @@ int test__hists_filter(void); | |||
| 45 | int test__mmap_thread_lookup(void); | 45 | int test__mmap_thread_lookup(void); |
| 46 | int test__thread_mg_share(void); | 46 | int test__thread_mg_share(void); |
| 47 | 47 | ||
| 48 | #if defined(__x86_64__) || defined(__i386__) | 48 | #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) |
| 49 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | 49 | #ifdef HAVE_DWARF_UNWIND_SUPPORT |
| 50 | struct thread; | 50 | struct thread; |
| 51 | struct perf_sample; | 51 | struct perf_sample; |
