2014-02-03 18:17:28

by Jean Pihet

[permalink] [raw]
Subject: [PATCH] perf: ARM64: wire up perf_regs and unwind support

This patch hooks in the perf_regs and libunwind code for ARM64.
The tools/perf/arch/arm64 is created; it contains the arch specific
code for DWARF unwinding.

Signed-off-by: Jean Pihet <[email protected]>
Acked-by: Will Deacon <[email protected]>
---
tools/perf/arch/arm64/Makefile | 7 +++
tools/perf/arch/arm64/include/perf_regs.h | 88 +++++++++++++++++++++++++++++++
tools/perf/arch/arm64/util/dwarf-regs.c | 80 ++++++++++++++++++++++++++++
tools/perf/arch/arm64/util/unwind.c | 82 ++++++++++++++++++++++++++++
tools/perf/config/Makefile | 8 ++-
5 files changed, 264 insertions(+), 1 deletion(-)
create mode 100644 tools/perf/arch/arm64/Makefile
create mode 100644 tools/perf/arch/arm64/include/perf_regs.h
create mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c
create mode 100644 tools/perf/arch/arm64/util/unwind.c

diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
new file mode 100644
index 0000000..fe9b61e
--- /dev/null
+++ b/tools/perf/arch/arm64/Makefile
@@ -0,0 +1,7 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
+ifndef NO_LIBUNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
+endif
diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h
new file mode 100644
index 0000000..2359546
--- /dev/null
+++ b/tools/perf/arch/arm64/include/perf_regs.h
@@ -0,0 +1,88 @@
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include "../../util/types.h"
+#include <asm/perf_regs.h>
+
+#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1)
+#define PERF_REG_IP PERF_REG_ARM64_PC
+#define PERF_REG_SP PERF_REG_ARM64_SP
+
+static inline const char *perf_reg_name(int id)
+{
+ switch (id) {
+ case PERF_REG_ARM64_X0:
+ return "x0";
+ case PERF_REG_ARM64_X1:
+ return "x1";
+ case PERF_REG_ARM64_X2:
+ return "x2";
+ case PERF_REG_ARM64_X3:
+ return "x3";
+ case PERF_REG_ARM64_X4:
+ return "x4";
+ case PERF_REG_ARM64_X5:
+ return "x5";
+ case PERF_REG_ARM64_X6:
+ return "x6";
+ case PERF_REG_ARM64_X7:
+ return "x7";
+ case PERF_REG_ARM64_X8:
+ return "x8";
+ case PERF_REG_ARM64_X9:
+ return "x9";
+ case PERF_REG_ARM64_X10:
+ return "x10";
+ case PERF_REG_ARM64_X11:
+ return "x11";
+ case PERF_REG_ARM64_X12:
+ return "x12";
+ case PERF_REG_ARM64_X13:
+ return "x13";
+ case PERF_REG_ARM64_X14:
+ return "x14";
+ case PERF_REG_ARM64_X15:
+ return "x15";
+ case PERF_REG_ARM64_X16:
+ return "x16";
+ case PERF_REG_ARM64_X17:
+ return "x17";
+ case PERF_REG_ARM64_X18:
+ return "x18";
+ case PERF_REG_ARM64_X19:
+ return "x19";
+ case PERF_REG_ARM64_X20:
+ return "x20";
+ case PERF_REG_ARM64_X21:
+ return "x21";
+ case PERF_REG_ARM64_X22:
+ return "x22";
+ case PERF_REG_ARM64_X23:
+ return "x23";
+ case PERF_REG_ARM64_X24:
+ return "x24";
+ case PERF_REG_ARM64_X25:
+ return "x25";
+ case PERF_REG_ARM64_X26:
+ return "x26";
+ case PERF_REG_ARM64_X27:
+ return "x27";
+ case PERF_REG_ARM64_X28:
+ return "x28";
+ case PERF_REG_ARM64_X29:
+ return "x29";
+ case PERF_REG_ARM64_SP:
+ return "sp";
+ case PERF_REG_ARM64_LR:
+ return "lr";
+ case PERF_REG_ARM64_PC:
+ return "pc";
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
new file mode 100644
index 0000000..d49efeb
--- /dev/null
+++ b/tools/perf/arch/arm64/util/dwarf-regs.c
@@ -0,0 +1,80 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Will Deacon, ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stddef.h>
+#include <dwarf-regs.h>
+
+struct pt_regs_dwarfnum {
+ const char *name;
+ unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+ {.name = STR(%x##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+ GPR_DWARFNUM_NAME(0),
+ GPR_DWARFNUM_NAME(1),
+ GPR_DWARFNUM_NAME(2),
+ GPR_DWARFNUM_NAME(3),
+ GPR_DWARFNUM_NAME(4),
+ GPR_DWARFNUM_NAME(5),
+ GPR_DWARFNUM_NAME(6),
+ GPR_DWARFNUM_NAME(7),
+ GPR_DWARFNUM_NAME(8),
+ GPR_DWARFNUM_NAME(9),
+ GPR_DWARFNUM_NAME(10),
+ GPR_DWARFNUM_NAME(11),
+ GPR_DWARFNUM_NAME(12),
+ GPR_DWARFNUM_NAME(13),
+ GPR_DWARFNUM_NAME(14),
+ GPR_DWARFNUM_NAME(15),
+ GPR_DWARFNUM_NAME(16),
+ GPR_DWARFNUM_NAME(17),
+ GPR_DWARFNUM_NAME(18),
+ GPR_DWARFNUM_NAME(19),
+ GPR_DWARFNUM_NAME(20),
+ GPR_DWARFNUM_NAME(21),
+ GPR_DWARFNUM_NAME(22),
+ GPR_DWARFNUM_NAME(23),
+ GPR_DWARFNUM_NAME(24),
+ GPR_DWARFNUM_NAME(25),
+ GPR_DWARFNUM_NAME(26),
+ GPR_DWARFNUM_NAME(27),
+ GPR_DWARFNUM_NAME(28),
+ GPR_DWARFNUM_NAME(29),
+ REG_DWARFNUM_NAME("%lr", 30),
+ REG_DWARFNUM_NAME("%sp", 31),
+ REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n: the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+ const struct pt_regs_dwarfnum *roff;
+ for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+ if (roff->dwarfnum == n)
+ return roff->name;
+ return NULL;
+}
diff --git a/tools/perf/arch/arm64/util/unwind.c b/tools/perf/arch/arm64/util/unwind.c
new file mode 100644
index 0000000..8d37a4c
--- /dev/null
+++ b/tools/perf/arch/arm64/util/unwind.c
@@ -0,0 +1,82 @@
+
+#include <errno.h>
+#include <libunwind.h>
+#include "perf_regs.h"
+#include "../../util/unwind.h"
+
+int unwind__arch_reg_id(int regnum)
+{
+ switch (regnum) {
+ case UNW_AARCH64_X0:
+ return PERF_REG_ARM64_X0;
+ case UNW_AARCH64_X1:
+ return PERF_REG_ARM64_X1;
+ case UNW_AARCH64_X2:
+ return PERF_REG_ARM64_X2;
+ case UNW_AARCH64_X3:
+ return PERF_REG_ARM64_X3;
+ case UNW_AARCH64_X4:
+ return PERF_REG_ARM64_X4;
+ case UNW_AARCH64_X5:
+ return PERF_REG_ARM64_X5;
+ case UNW_AARCH64_X6:
+ return PERF_REG_ARM64_X6;
+ case UNW_AARCH64_X7:
+ return PERF_REG_ARM64_X7;
+ case UNW_AARCH64_X8:
+ return PERF_REG_ARM64_X8;
+ case UNW_AARCH64_X9:
+ return PERF_REG_ARM64_X9;
+ case UNW_AARCH64_X10:
+ return PERF_REG_ARM64_X10;
+ case UNW_AARCH64_X11:
+ return PERF_REG_ARM64_X11;
+ case UNW_AARCH64_X12:
+ return PERF_REG_ARM64_X12;
+ case UNW_AARCH64_X13:
+ return PERF_REG_ARM64_X13;
+ case UNW_AARCH64_X14:
+ return PERF_REG_ARM64_X14;
+ case UNW_AARCH64_X15:
+ return PERF_REG_ARM64_X15;
+ case UNW_AARCH64_X16:
+ return PERF_REG_ARM64_X16;
+ case UNW_AARCH64_X17:
+ return PERF_REG_ARM64_X17;
+ case UNW_AARCH64_X18:
+ return PERF_REG_ARM64_X18;
+ case UNW_AARCH64_X19:
+ return PERF_REG_ARM64_X19;
+ case UNW_AARCH64_X20:
+ return PERF_REG_ARM64_X20;
+ case UNW_AARCH64_X21:
+ return PERF_REG_ARM64_X21;
+ case UNW_AARCH64_X22:
+ return PERF_REG_ARM64_X22;
+ case UNW_AARCH64_X23:
+ return PERF_REG_ARM64_X23;
+ case UNW_AARCH64_X24:
+ return PERF_REG_ARM64_X24;
+ case UNW_AARCH64_X25:
+ return PERF_REG_ARM64_X25;
+ case UNW_AARCH64_X26:
+ return PERF_REG_ARM64_X26;
+ case UNW_AARCH64_X27:
+ return PERF_REG_ARM64_X27;
+ case UNW_AARCH64_X28:
+ return PERF_REG_ARM64_X28;
+ case UNW_AARCH64_X29:
+ return PERF_REG_ARM64_X29;
+ case UNW_AARCH64_X30:
+ return PERF_REG_ARM64_LR;
+ case UNW_AARCH64_SP:
+ return PERF_REG_ARM64_SP;
+ case UNW_AARCH64_PC:
+ return PERF_REG_ARM64_PC;
+ default:
+ pr_err("unwind: invalid reg id %d\n", regnum);
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c48d449..5c0a6ed 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -29,11 +29,17 @@ ifeq ($(ARCH),x86)
endif
NO_PERF_REGS := 0
endif
+
ifeq ($(ARCH),arm)
NO_PERF_REGS := 0
LIBUNWIND_LIBS = -lunwind -lunwind-arm
endif

+ifeq ($(ARCH),arm64)
+ NO_PERF_REGS := 0
+ LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
+endif
+
ifeq ($(LIBUNWIND_LIBS),)
NO_LIBUNWIND := 1
else
@@ -327,7 +333,7 @@ ifndef NO_LIBUNWIND
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
NO_LIBUNWIND := 1
else
- ifeq ($(ARCH),arm)
+ ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
$(call feature_check,libunwind-debug-frame)
ifneq ($(feature-libunwind-debug-frame), 1)
msg := $(warning No debug_frame support found in libunwind);
--
1.7.11.7


2014-02-12 08:46:40

by Jean Pihet

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support

Hi Arnaldo, Will,

Ping on this patch.

Regards,
Jean

On 3 February 2014 19:17, Jean Pihet <[email protected]> wrote:
> This patch hooks in the perf_regs and libunwind code for ARM64.
> The tools/perf/arch/arm64 is created; it contains the arch specific
> code for DWARF unwinding.
>
> Signed-off-by: Jean Pihet <[email protected]>
> Acked-by: Will Deacon <[email protected]>
> ---
> tools/perf/arch/arm64/Makefile | 7 +++
> tools/perf/arch/arm64/include/perf_regs.h | 88 +++++++++++++++++++++++++++++++
> tools/perf/arch/arm64/util/dwarf-regs.c | 80 ++++++++++++++++++++++++++++
> tools/perf/arch/arm64/util/unwind.c | 82 ++++++++++++++++++++++++++++
> tools/perf/config/Makefile | 8 ++-
> 5 files changed, 264 insertions(+), 1 deletion(-)
> create mode 100644 tools/perf/arch/arm64/Makefile
> create mode 100644 tools/perf/arch/arm64/include/perf_regs.h
> create mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c
> create mode 100644 tools/perf/arch/arm64/util/unwind.c
>
> diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
> new file mode 100644
> index 0000000..fe9b61e
> --- /dev/null
> +++ b/tools/perf/arch/arm64/Makefile
> @@ -0,0 +1,7 @@
> +ifndef NO_DWARF
> +PERF_HAVE_DWARF_REGS := 1
> +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
> +endif
> +ifndef NO_LIBUNWIND
> +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
> +endif
> diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h
> new file mode 100644
> index 0000000..2359546
> --- /dev/null
> +++ b/tools/perf/arch/arm64/include/perf_regs.h
> @@ -0,0 +1,88 @@
> +#ifndef ARCH_PERF_REGS_H
> +#define ARCH_PERF_REGS_H
> +
> +#include <stdlib.h>
> +#include "../../util/types.h"
> +#include <asm/perf_regs.h>
> +
> +#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1)
> +#define PERF_REG_IP PERF_REG_ARM64_PC
> +#define PERF_REG_SP PERF_REG_ARM64_SP
> +
> +static inline const char *perf_reg_name(int id)
> +{
> + switch (id) {
> + case PERF_REG_ARM64_X0:
> + return "x0";
> + case PERF_REG_ARM64_X1:
> + return "x1";
> + case PERF_REG_ARM64_X2:
> + return "x2";
> + case PERF_REG_ARM64_X3:
> + return "x3";
> + case PERF_REG_ARM64_X4:
> + return "x4";
> + case PERF_REG_ARM64_X5:
> + return "x5";
> + case PERF_REG_ARM64_X6:
> + return "x6";
> + case PERF_REG_ARM64_X7:
> + return "x7";
> + case PERF_REG_ARM64_X8:
> + return "x8";
> + case PERF_REG_ARM64_X9:
> + return "x9";
> + case PERF_REG_ARM64_X10:
> + return "x10";
> + case PERF_REG_ARM64_X11:
> + return "x11";
> + case PERF_REG_ARM64_X12:
> + return "x12";
> + case PERF_REG_ARM64_X13:
> + return "x13";
> + case PERF_REG_ARM64_X14:
> + return "x14";
> + case PERF_REG_ARM64_X15:
> + return "x15";
> + case PERF_REG_ARM64_X16:
> + return "x16";
> + case PERF_REG_ARM64_X17:
> + return "x17";
> + case PERF_REG_ARM64_X18:
> + return "x18";
> + case PERF_REG_ARM64_X19:
> + return "x19";
> + case PERF_REG_ARM64_X20:
> + return "x20";
> + case PERF_REG_ARM64_X21:
> + return "x21";
> + case PERF_REG_ARM64_X22:
> + return "x22";
> + case PERF_REG_ARM64_X23:
> + return "x23";
> + case PERF_REG_ARM64_X24:
> + return "x24";
> + case PERF_REG_ARM64_X25:
> + return "x25";
> + case PERF_REG_ARM64_X26:
> + return "x26";
> + case PERF_REG_ARM64_X27:
> + return "x27";
> + case PERF_REG_ARM64_X28:
> + return "x28";
> + case PERF_REG_ARM64_X29:
> + return "x29";
> + case PERF_REG_ARM64_SP:
> + return "sp";
> + case PERF_REG_ARM64_LR:
> + return "lr";
> + case PERF_REG_ARM64_PC:
> + return "pc";
> + default:
> + return NULL;
> + }
> +
> + return NULL;
> +}
> +
> +#endif /* ARCH_PERF_REGS_H */
> diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
> new file mode 100644
> index 0000000..d49efeb
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/dwarf-regs.c
> @@ -0,0 +1,80 @@
> +/*
> + * Mapping of DWARF debug register numbers into register names.
> + *
> + * Copyright (C) 2010 Will Deacon, ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <stddef.h>
> +#include <dwarf-regs.h>
> +
> +struct pt_regs_dwarfnum {
> + const char *name;
> + unsigned int dwarfnum;
> +};
> +
> +#define STR(s) #s
> +#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
> +#define GPR_DWARFNUM_NAME(num) \
> + {.name = STR(%x##num), .dwarfnum = num}
> +#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
> +
> +/*
> + * Reference:
> + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf
> + */
> +static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
> + GPR_DWARFNUM_NAME(0),
> + GPR_DWARFNUM_NAME(1),
> + GPR_DWARFNUM_NAME(2),
> + GPR_DWARFNUM_NAME(3),
> + GPR_DWARFNUM_NAME(4),
> + GPR_DWARFNUM_NAME(5),
> + GPR_DWARFNUM_NAME(6),
> + GPR_DWARFNUM_NAME(7),
> + GPR_DWARFNUM_NAME(8),
> + GPR_DWARFNUM_NAME(9),
> + GPR_DWARFNUM_NAME(10),
> + GPR_DWARFNUM_NAME(11),
> + GPR_DWARFNUM_NAME(12),
> + GPR_DWARFNUM_NAME(13),
> + GPR_DWARFNUM_NAME(14),
> + GPR_DWARFNUM_NAME(15),
> + GPR_DWARFNUM_NAME(16),
> + GPR_DWARFNUM_NAME(17),
> + GPR_DWARFNUM_NAME(18),
> + GPR_DWARFNUM_NAME(19),
> + GPR_DWARFNUM_NAME(20),
> + GPR_DWARFNUM_NAME(21),
> + GPR_DWARFNUM_NAME(22),
> + GPR_DWARFNUM_NAME(23),
> + GPR_DWARFNUM_NAME(24),
> + GPR_DWARFNUM_NAME(25),
> + GPR_DWARFNUM_NAME(26),
> + GPR_DWARFNUM_NAME(27),
> + GPR_DWARFNUM_NAME(28),
> + GPR_DWARFNUM_NAME(29),
> + REG_DWARFNUM_NAME("%lr", 30),
> + REG_DWARFNUM_NAME("%sp", 31),
> + REG_DWARFNUM_END,
> +};
> +
> +/**
> + * get_arch_regstr() - lookup register name from it's DWARF register number
> + * @n: the DWARF register number
> + *
> + * get_arch_regstr() returns the name of the register in struct
> + * regdwarfnum_table from it's DWARF register number. If the register is not
> + * found in the table, this returns NULL;
> + */
> +const char *get_arch_regstr(unsigned int n)
> +{
> + const struct pt_regs_dwarfnum *roff;
> + for (roff = regdwarfnum_table; roff->name != NULL; roff++)
> + if (roff->dwarfnum == n)
> + return roff->name;
> + return NULL;
> +}
> diff --git a/tools/perf/arch/arm64/util/unwind.c b/tools/perf/arch/arm64/util/unwind.c
> new file mode 100644
> index 0000000..8d37a4c
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/unwind.c
> @@ -0,0 +1,82 @@
> +
> +#include <errno.h>
> +#include <libunwind.h>
> +#include "perf_regs.h"
> +#include "../../util/unwind.h"
> +
> +int unwind__arch_reg_id(int regnum)
> +{
> + switch (regnum) {
> + case UNW_AARCH64_X0:
> + return PERF_REG_ARM64_X0;
> + case UNW_AARCH64_X1:
> + return PERF_REG_ARM64_X1;
> + case UNW_AARCH64_X2:
> + return PERF_REG_ARM64_X2;
> + case UNW_AARCH64_X3:
> + return PERF_REG_ARM64_X3;
> + case UNW_AARCH64_X4:
> + return PERF_REG_ARM64_X4;
> + case UNW_AARCH64_X5:
> + return PERF_REG_ARM64_X5;
> + case UNW_AARCH64_X6:
> + return PERF_REG_ARM64_X6;
> + case UNW_AARCH64_X7:
> + return PERF_REG_ARM64_X7;
> + case UNW_AARCH64_X8:
> + return PERF_REG_ARM64_X8;
> + case UNW_AARCH64_X9:
> + return PERF_REG_ARM64_X9;
> + case UNW_AARCH64_X10:
> + return PERF_REG_ARM64_X10;
> + case UNW_AARCH64_X11:
> + return PERF_REG_ARM64_X11;
> + case UNW_AARCH64_X12:
> + return PERF_REG_ARM64_X12;
> + case UNW_AARCH64_X13:
> + return PERF_REG_ARM64_X13;
> + case UNW_AARCH64_X14:
> + return PERF_REG_ARM64_X14;
> + case UNW_AARCH64_X15:
> + return PERF_REG_ARM64_X15;
> + case UNW_AARCH64_X16:
> + return PERF_REG_ARM64_X16;
> + case UNW_AARCH64_X17:
> + return PERF_REG_ARM64_X17;
> + case UNW_AARCH64_X18:
> + return PERF_REG_ARM64_X18;
> + case UNW_AARCH64_X19:
> + return PERF_REG_ARM64_X19;
> + case UNW_AARCH64_X20:
> + return PERF_REG_ARM64_X20;
> + case UNW_AARCH64_X21:
> + return PERF_REG_ARM64_X21;
> + case UNW_AARCH64_X22:
> + return PERF_REG_ARM64_X22;
> + case UNW_AARCH64_X23:
> + return PERF_REG_ARM64_X23;
> + case UNW_AARCH64_X24:
> + return PERF_REG_ARM64_X24;
> + case UNW_AARCH64_X25:
> + return PERF_REG_ARM64_X25;
> + case UNW_AARCH64_X26:
> + return PERF_REG_ARM64_X26;
> + case UNW_AARCH64_X27:
> + return PERF_REG_ARM64_X27;
> + case UNW_AARCH64_X28:
> + return PERF_REG_ARM64_X28;
> + case UNW_AARCH64_X29:
> + return PERF_REG_ARM64_X29;
> + case UNW_AARCH64_X30:
> + return PERF_REG_ARM64_LR;
> + case UNW_AARCH64_SP:
> + return PERF_REG_ARM64_SP;
> + case UNW_AARCH64_PC:
> + return PERF_REG_ARM64_PC;
> + default:
> + pr_err("unwind: invalid reg id %d\n", regnum);
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index c48d449..5c0a6ed 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -29,11 +29,17 @@ ifeq ($(ARCH),x86)
> endif
> NO_PERF_REGS := 0
> endif
> +
> ifeq ($(ARCH),arm)
> NO_PERF_REGS := 0
> LIBUNWIND_LIBS = -lunwind -lunwind-arm
> endif
>
> +ifeq ($(ARCH),arm64)
> + NO_PERF_REGS := 0
> + LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
> +endif
> +
> ifeq ($(LIBUNWIND_LIBS),)
> NO_LIBUNWIND := 1
> else
> @@ -327,7 +333,7 @@ ifndef NO_LIBUNWIND
> msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
> NO_LIBUNWIND := 1
> else
> - ifeq ($(ARCH),arm)
> + ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
> $(call feature_check,libunwind-debug-frame)
> ifneq ($(feature-libunwind-debug-frame), 1)
> msg := $(warning No debug_frame support found in libunwind);
> --
> 1.7.11.7
>

2014-02-12 10:10:58

by Will Deacon

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support

On Wed, Feb 12, 2014 at 08:46:38AM +0000, Jean Pihet wrote:
> Hi Arnaldo, Will,
>
> Ping on this patch.

This needs to go via the perf tree to avoid a repeat of the mess last time.

Will

2014-02-12 11:27:52

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support


* Will Deacon <[email protected]> wrote:

> On Wed, Feb 12, 2014 at 08:46:38AM +0000, Jean Pihet wrote:
> > Hi Arnaldo, Will,
> >
> > Ping on this patch.
>
> This needs to go via the perf tree to avoid a repeat of the mess last time.

If the tooling bits are fine with Arnaldo then I have no objections
either - once all the bits are acked please send a single series with
all 4(?) patches in it, for tip:perf/core inclusion.

Thanks,

Ingo

2014-02-12 11:31:27

by Will Deacon

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support

On Wed, Feb 12, 2014 at 11:27:44AM +0000, Ingo Molnar wrote:
> * Will Deacon <[email protected]> wrote:
> > This needs to go via the perf tree to avoid a repeat of the mess last time.
>
> If the tooling bits are fine with Arnaldo then I have no objections
> either - once all the bits are acked please send a single series with
> all 4(?) patches in it, for tip:perf/core inclusion.

I think it's just 1 patch -- the other 3 are under arch/arm64, so it would
be easier to take those via the arm64 tree and deal with any conflicts
there.

Will

2014-02-12 13:02:32

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support

Em Wed, Feb 12, 2014 at 11:30:18AM +0000, Will Deacon escreveu:
> On Wed, Feb 12, 2014 at 11:27:44AM +0000, Ingo Molnar wrote:
> > * Will Deacon <[email protected]> wrote:
> > > This needs to go via the perf tree to avoid a repeat of the mess last time.

> > If the tooling bits are fine with Arnaldo then I have no objections
> > either - once all the bits are acked please send a single series with
> > all 4(?) patches in it, for tip:perf/core inclusion.

> I think it's just 1 patch -- the other 3 are under arch/arm64, so it would
> be easier to take those via the arm64 tree and deal with any conflicts
> there.

I don't have a problem with arch specific bits, that don't touch the
tools at all, going thru the respective arch git tree.

Jiri, can you see anything problematic in this? From a quick look I
couldn't.

- Arnaldo

2014-02-12 13:10:23

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support

On Mon, Feb 03, 2014 at 07:17:07PM +0100, Jean Pihet wrote:
> This patch hooks in the perf_regs and libunwind code for ARM64.
> The tools/perf/arch/arm64 is created; it contains the arch specific
> code for DWARF unwinding.
>
> Signed-off-by: Jean Pihet <[email protected]>
> Acked-by: Will Deacon <[email protected]>

SNIP

> + */
> +const char *get_arch_regstr(unsigned int n)
> +{
> + const struct pt_regs_dwarfnum *roff;
> + for (roff = regdwarfnum_table; roff->name != NULL; roff++)
> + if (roff->dwarfnum == n)
> + return roff->name;
> + return NULL;
> +}
> diff --git a/tools/perf/arch/arm64/util/unwind.c b/tools/perf/arch/arm64/util/unwind.c
> new file mode 100644
> index 0000000..8d37a4c
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/unwind.c
> @@ -0,0 +1,82 @@
> +
> +#include <errno.h>
> +#include <libunwind.h>
> +#include "perf_regs.h"
> +#include "../../util/unwind.h"
> +
> +int unwind__arch_reg_id(int regnum)


I think this ^^^ wouldn't compile over acme/perf/core, bacause of
the recent code changes for the libdw unwind:

1d86598 perf callchain: Rename unwind__arch_reg_id into libunwind__arch_reg_id

jirka

2014-02-13 17:01:37

by Jean Pihet

[permalink] [raw]
Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support

Hi Jiri,


On 12 February 2014 14:09, Jiri Olsa <[email protected]> wrote:
> On Mon, Feb 03, 2014 at 07:17:07PM +0100, Jean Pihet wrote:
>> This patch hooks in the perf_regs and libunwind code for ARM64.
>> The tools/perf/arch/arm64 is created; it contains the arch specific
>> code for DWARF unwinding.
>>
>> Signed-off-by: Jean Pihet <[email protected]>
>> Acked-by: Will Deacon <[email protected]>
>
> SNIP
>
>> + */
>> +const char *get_arch_regstr(unsigned int n)
>> +{
>> + const struct pt_regs_dwarfnum *roff;
>> + for (roff = regdwarfnum_table; roff->name != NULL; roff++)
>> + if (roff->dwarfnum == n)
>> + return roff->name;
>> + return NULL;
>> +}
>> diff --git a/tools/perf/arch/arm64/util/unwind.c b/tools/perf/arch/arm64/util/unwind.c
>> new file mode 100644
>> index 0000000..8d37a4c
>> --- /dev/null
>> +++ b/tools/perf/arch/arm64/util/unwind.c
>> @@ -0,0 +1,82 @@
>> +
>> +#include <errno.h>
>> +#include <libunwind.h>
>> +#include "perf_regs.h"
>> +#include "../../util/unwind.h"
>> +
>> +int unwind__arch_reg_id(int regnum)
>
>
> I think this ^^^ wouldn't compile over acme/perf/core, bacause of
> the recent code changes for the libdw unwind:
>
> 1d86598 perf callchain: Rename unwind__arch_reg_id into libunwind__arch_reg_id
That is correct, the patch is for mainline.
Re-sending a rebased version on acme/perf/core in a bit.

> jirka

Thanks,
Jean