perf tools: Add ARM64 perf_regs_load to support libunwind and enable testing
Newest libunwind does support ARM64, and perf is able to utilize it also. This patch enables the perf test dwarf unwind for arm64. Test result: # ./perf test unwind 25: Test dwarf unwind : Ok Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Link: http://lkml.kernel.org/r/1427461681-72971-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

gecommit door
Arnaldo Carvalho de Melo

bovenliggende
b236512280
commit
3237f28188
2
tools/perf/arch/arm64/tests/Build
Normal file
2
tools/perf/arch/arm64/tests/Build
Normal file
@@ -0,0 +1,2 @@
|
||||
libperf-y += regs_load.o
|
||||
libperf-y += dwarf-unwind.o
|
61
tools/perf/arch/arm64/tests/dwarf-unwind.c
Normal file
61
tools/perf/arch/arm64/tests/dwarf-unwind.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <string.h>
|
||||
#include "perf_regs.h"
|
||||
#include "thread.h"
|
||||
#include "map.h"
|
||||
#include "event.h"
|
||||
#include "debug.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_ARM64_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);
|
||||
}
|
46
tools/perf/arch/arm64/tests/regs_load.S
Normal file
46
tools/perf/arch/arm64/tests/regs_load.S
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.text
|
||||
.type perf_regs_load,%function
|
||||
#define STR_REG(r) str x##r, [x0, 8 * r]
|
||||
#define LDR_REG(r) ldr x##r, [x0, 8 * r]
|
||||
#define SP (8 * 31)
|
||||
#define PC (8 * 32)
|
||||
ENTRY(perf_regs_load)
|
||||
STR_REG(0)
|
||||
STR_REG(1)
|
||||
STR_REG(2)
|
||||
STR_REG(3)
|
||||
STR_REG(4)
|
||||
STR_REG(5)
|
||||
STR_REG(6)
|
||||
STR_REG(7)
|
||||
STR_REG(8)
|
||||
STR_REG(9)
|
||||
STR_REG(10)
|
||||
STR_REG(11)
|
||||
STR_REG(12)
|
||||
STR_REG(13)
|
||||
STR_REG(14)
|
||||
STR_REG(15)
|
||||
STR_REG(16)
|
||||
STR_REG(17)
|
||||
STR_REG(18)
|
||||
STR_REG(19)
|
||||
STR_REG(20)
|
||||
STR_REG(21)
|
||||
STR_REG(22)
|
||||
STR_REG(23)
|
||||
STR_REG(24)
|
||||
STR_REG(25)
|
||||
STR_REG(26)
|
||||
STR_REG(27)
|
||||
STR_REG(28)
|
||||
STR_REG(29)
|
||||
STR_REG(30)
|
||||
mov x1, sp
|
||||
str x1, [x0, #SP]
|
||||
str x30, [x0, #PC]
|
||||
LDR_REG(1)
|
||||
ret
|
||||
ENDPROC(perf_regs_load)
|
Verwijs in nieuw issue
Block a user