linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-16  9:17 [PATCH v2 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
@ 2013-09-16  9:17 ` Jean Pihet
  0 siblings, 0 replies; 14+ messages in thread
From: Jean Pihet @ 2013-09-16  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

On ARM the debug info is not present in the .eh_frame sections but
in .debug_frame instead, in the dwarf format.
Use libunwind to load and parse the debug info.

Dependencies:
 . if present, libunwind >= 1.1 is needed to prevent a segfault when
   parsing the dwarf info,
 . libunwind needs to be configured with --enable-debug-frame
   to prevent a linkage error. Note: --enable-debug-frame is automatically
   selected on ARM).

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
 tools/perf/config/Makefile |  2 +-
 tools/perf/util/unwind.c   | 71 +++++++++++++++++++++++++++++++++++-----------
 2 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 2f891f7..429a99c 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -39,6 +39,15 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
 
 #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
 
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+				 unw_word_t ip,
+				 unw_word_t segbase,
+				 const char *obj_name, unw_word_t start,
+				 unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
 #define DW_EH_PE_FORMAT_MASK	0x0f	/* format of the encoded value */
 #define DW_EH_PE_APPL_MASK	0x70	/* how the value is to be applied */
 
@@ -245,8 +254,9 @@ static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
 	return 0;
 }
 
-static int read_unwind_spec(struct dso *dso, struct machine *machine,
-			    u64 *table_data, u64 *segbase, u64 *fde_count)
+static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
+				     u64 *table_data, u64 *segbase,
+				     u64 *fde_count)
 {
 	int ret = -EINVAL, fd;
 	u64 offset;
@@ -255,6 +265,7 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
 	if (fd < 0)
 		return -EINVAL;
 
+	/* Check the .eh_frame section for unwinding info */
 	offset = elf_section_offset(fd, ".eh_frame_hdr");
 	close(fd);
 
@@ -263,10 +274,27 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
 					  table_data, segbase,
 					  fde_count);
 
-	/* TODO .debug_frame check if eh_frame_hdr fails */
 	return ret;
 }
 
+static int read_unwind_spec_debug_frame(struct dso *dso,
+					struct machine *machine, u64 *offset)
+{
+	int fd = dso__data_fd(dso, machine);
+
+	if (fd < 0)
+		return -EINVAL;
+
+	/* Check the .debug_frame section for unwinding info */
+	*offset = elf_section_offset(fd, ".debug_frame");
+	close(fd);
+
+	if (*offset)
+		return 0;
+
+	return -EINVAL;
+}
+
 static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
 {
 	struct addr_location al;
@@ -291,20 +319,31 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
 
 	pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
 
-	if (read_unwind_spec(map->dso, ui->machine,
-			     &table_data, &segbase, &fde_count))
-		return -EINVAL;
+	/* Check the .eh_frame section for unwinding info */
+	if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
+				       &table_data, &segbase, &fde_count)) {
+		memset(&di, 0, sizeof(di));
+		di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
+		di.start_ip = map->start;
+		di.end_ip   = map->end;
+		di.u.rti.segbase    = map->start + segbase;
+		di.u.rti.table_data = map->start + table_data;
+		di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
+				      / sizeof(unw_word_t);
+		return dwarf_search_unwind_table(as, ip, &di, pi,
+						 need_unwind_info, arg);
+	}
+
+	/* Check the .debug_frame section for unwinding info */
+	if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
+		memset(&di, 0, sizeof(di));
+		dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
+				       map->start, map->end);
+		return dwarf_search_unwind_table(as, ip, &di, pi,
+						 need_unwind_info, arg);
+	}
 
-	memset(&di, 0, sizeof(di));
-	di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
-	di.start_ip = map->start;
-	di.end_ip   = map->end;
-	di.u.rti.segbase    = map->start + segbase;
-	di.u.rti.table_data = map->start + table_data;
-	di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
-			      / sizeof(unw_word_t);
-	return dwarf_search_unwind_table(as, ip, &di, pi,
-					 need_unwind_info, arg);
+	return -EINVAL;
 }
 
 static int access_fpreg(unw_addr_space_t __maybe_unused as,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section
@ 2013-09-26 11:36 Jean Pihet
  2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

On ARM the debug info is not present in the .eh_frame sections but
in .debug_frame instead, in dwarf format.

This patch set uses libunwind to load and parse the dwarf debug info from
the .debug_frame section if no .eh_frame_hdr section is found; also it
sets the hooks in the perf_regs and libunwind code for ARMv7.

Dependencies:
 . if present, libunwind >= 1.1 is needed to prevent a segfault when
   parsing the dwarf info,
 . libunwind needs to be configured with --enable-debug-frame. Note:
   --enable-debug-frame is automatically selected on ARM.

The generated perf binary has been tested on ARMv7 (OMAP4, Marvell
Armada XP) and x86_64, using the following commands:
 perf record -g [dwarf] -- <binary>
 perf report --sort symbol --call-graph --stdio


Jean Pihet (2):
  perf tools: Check libunwind for availability of dwarf parsing feature
  perf: parse the .debug_frame section in case .eh_frame is not present

Will Deacon (2):
  ARM: perf: add support for perf registers API
  ARM: perf: wire up perf_regs and unwind support for ARM

 arch/arm/Kconfig                        |  2 +
 arch/arm/include/uapi/asm/Kbuild        |  1 +
 arch/arm/include/uapi/asm/perf_regs.h   | 23 ++++++++++
 arch/arm/kernel/Makefile                |  1 +
 arch/arm/kernel/perf_regs.c             | 30 +++++++++++++
 tools/perf/arch/arm/Makefile            |  3 ++
 tools/perf/arch/arm/include/perf_regs.h | 54 ++++++++++++++++++++++++
 tools/perf/arch/arm/util/unwind.c       | 48 +++++++++++++++++++++
 tools/perf/config/Makefile              | 13 ++++--
 tools/perf/config/feature-tests.mak     | 21 ++++++++-
 tools/perf/util/unwind.c                | 75 ++++++++++++++++++++++++++-------
 11 files changed, 251 insertions(+), 20 deletions(-)
 create mode 100644 arch/arm/include/uapi/asm/perf_regs.h
 create mode 100644 arch/arm/kernel/perf_regs.c
 create mode 100644 tools/perf/arch/arm/include/perf_regs.h
 create mode 100644 tools/perf/arch/arm/util/unwind.c

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/4] ARM: perf: add support for perf registers API
  2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
@ 2013-09-26 11:36 ` Jean Pihet
  2013-09-26 11:36 ` [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

This patch implements the functions required for the perf registers API,
allowing the perf tool to interface kernel register dumps with libunwind
in order to provide userspace backtracing.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
---
 arch/arm/Kconfig                      |  2 ++
 arch/arm/include/uapi/asm/Kbuild      |  1 +
 arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++++++++++++++
 arch/arm/kernel/Makefile              |  1 +
 arch/arm/kernel/perf_regs.c           | 30 ++++++++++++++++++++++++++++++
 5 files changed, 57 insertions(+)
 create mode 100644 arch/arm/include/uapi/asm/perf_regs.h
 create mode 100644 arch/arm/kernel/perf_regs.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3f7714d..5595888 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -51,6 +51,8 @@ config ARM
 	select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
 	select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
 	select HAVE_PERF_EVENTS
+	select HAVE_PERF_REGS
+	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
index 18d76fd..70a1c9d 100644
--- a/arch/arm/include/uapi/asm/Kbuild
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -7,6 +7,7 @@ header-y += hwcap.h
 header-y += ioctls.h
 header-y += kvm_para.h
 header-y += mman.h
+header-y += perf_regs.h
 header-y += posix_types.h
 header-y += ptrace.h
 header-y += setup.h
diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..ce59448
--- /dev/null
+++ b/arch/arm/include/uapi/asm/perf_regs.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_ARM_PERF_REGS_H
+#define _ASM_ARM_PERF_REGS_H
+
+enum perf_event_arm_regs {
+	PERF_REG_ARM_R0,
+	PERF_REG_ARM_R1,
+	PERF_REG_ARM_R2,
+	PERF_REG_ARM_R3,
+	PERF_REG_ARM_R4,
+	PERF_REG_ARM_R5,
+	PERF_REG_ARM_R6,
+	PERF_REG_ARM_R7,
+	PERF_REG_ARM_R8,
+	PERF_REG_ARM_R9,
+	PERF_REG_ARM_R10,
+	PERF_REG_ARM_FP,
+	PERF_REG_ARM_IP,
+	PERF_REG_ARM_SP,
+	PERF_REG_ARM_LR,
+	PERF_REG_ARM_PC,
+	PERF_REG_ARM_MAX,
+};
+#endif /* _ASM_ARM_PERF_REGS_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5140df5f..9b818ca 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o perf_event_cpu.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c
new file mode 100644
index 0000000..6e4379c
--- /dev/null
+++ b/arch/arm/kernel/perf_regs.c
@@ -0,0 +1,30 @@
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX))
+		return 0;
+
+	return regs->uregs[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1))
+
+int perf_reg_validate(u64 mask)
+{
+	if (!mask || mask & REG_RESERVED)
+		return -EINVAL;
+
+	return 0;
+}
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+	return PERF_SAMPLE_REGS_ABI_32;
+}
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM
  2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
  2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet
@ 2013-09-26 11:36 ` Jean Pihet
  2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet
  2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
  3 siblings, 0 replies; 14+ messages in thread
From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

This patch hooks in the perf_regs and libunwind code for ARM.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
---
 tools/perf/arch/arm/Makefile            |  3 ++
 tools/perf/arch/arm/include/perf_regs.h | 54 +++++++++++++++++++++++++++++++++
 tools/perf/arch/arm/util/unwind.c       | 48 +++++++++++++++++++++++++++++
 tools/perf/config/Makefile              |  7 +++--
 4 files changed, 110 insertions(+), 2 deletions(-)
 create mode 100644 tools/perf/arch/arm/include/perf_regs.h
 create mode 100644 tools/perf/arch/arm/util/unwind.c

diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 15130b5..fe9b61e 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -2,3 +2,6 @@ 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/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
new file mode 100644
index 0000000..2a1cfde
--- /dev/null
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -0,0 +1,54 @@
+#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_ARM_MAX) - 1)
+#define PERF_REG_IP	PERF_REG_ARM_PC
+#define PERF_REG_SP	PERF_REG_ARM_SP
+
+static inline const char *perf_reg_name(int id)
+{
+	switch (id) {
+	case PERF_REG_ARM_R0:
+		return "r0";
+	case PERF_REG_ARM_R1:
+		return "r1";
+	case PERF_REG_ARM_R2:
+		return "r2";
+	case PERF_REG_ARM_R3:
+		return "r3";
+	case PERF_REG_ARM_R4:
+		return "r4";
+	case PERF_REG_ARM_R5:
+		return "r5";
+	case PERF_REG_ARM_R6:
+		return "r6";
+	case PERF_REG_ARM_R7:
+		return "r7";
+	case PERF_REG_ARM_R8:
+		return "r8";
+	case PERF_REG_ARM_R9:
+		return "r9";
+	case PERF_REG_ARM_R10:
+		return "r10";
+	case PERF_REG_ARM_FP:
+		return "fp";
+	case PERF_REG_ARM_IP:
+		return "ip";
+	case PERF_REG_ARM_SP:
+		return "sp";
+	case PERF_REG_ARM_LR:
+		return "lr";
+	case PERF_REG_ARM_PC:
+		return "pc";
+	default:
+		return NULL;
+	}
+
+	return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/arm/util/unwind.c b/tools/perf/arch/arm/util/unwind.c
new file mode 100644
index 0000000..da3dc95
--- /dev/null
+++ b/tools/perf/arch/arm/util/unwind.c
@@ -0,0 +1,48 @@
+
+#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_ARM_R0:
+		return PERF_REG_ARM_R0;
+	case UNW_ARM_R1:
+		return PERF_REG_ARM_R1;
+	case UNW_ARM_R2:
+		return PERF_REG_ARM_R2;
+	case UNW_ARM_R3:
+		return PERF_REG_ARM_R3;
+	case UNW_ARM_R4:
+		return PERF_REG_ARM_R4;
+	case UNW_ARM_R5:
+		return PERF_REG_ARM_R5;
+	case UNW_ARM_R6:
+		return PERF_REG_ARM_R6;
+	case UNW_ARM_R7:
+		return PERF_REG_ARM_R7;
+	case UNW_ARM_R8:
+		return PERF_REG_ARM_R8;
+	case UNW_ARM_R9:
+		return PERF_REG_ARM_R9;
+	case UNW_ARM_R10:
+		return PERF_REG_ARM_R10;
+	case UNW_ARM_R11:
+		return PERF_REG_ARM_FP;
+	case UNW_ARM_R12:
+		return PERF_REG_ARM_IP;
+	case UNW_ARM_R13:
+		return PERF_REG_ARM_SP;
+	case UNW_ARM_R14:
+		return PERF_REG_ARM_LR;
+	case UNW_ARM_R15:
+		return PERF_REG_ARM_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 214e17e..4b65710 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -29,6 +29,10 @@ ifeq ($(ARCH),x86_64)
   NO_PERF_REGS := 0
   LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
 endif
+ifeq ($(ARCH),arm)
+  NO_PERF_REGS := 0
+  LIBUNWIND_LIBS = -lunwind -lunwind-arm
+endif
 
 ifeq ($(NO_PERF_REGS),0)
   CFLAGS += -DHAVE_PERF_REGS
@@ -205,8 +209,7 @@ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
 endif # try-cc
 endif # NO_LIBELF
 
-# There's only x86 (both 32 and 64) support for CFI unwind so far
-ifneq ($(ARCH),x86)
+ifeq ($(LIBUNWIND_LIBS),)
   NO_LIBUNWIND := 1
 endif
 
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
  2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet
  2013-09-26 11:36 ` [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet
@ 2013-09-26 11:36 ` Jean Pihet
  2013-09-26 12:48   ` Jiri Olsa
  2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
  3 siblings, 1 reply; 14+ messages in thread
From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

The newly added dwarf unwinding feature [1] requires:
. a recent version (>= 1.1) of libunwind,
. libunwind to be configured with --enable-debug-frame.

[1] http://www.spinics.net/lists/kernel/msg1598951.html

Add the corresponding API tests in the feature check list.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
 tools/perf/config/Makefile          |  6 +++++-
 tools/perf/config/feature-tests.mak | 21 ++++++++++++++++++++-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 4b65710..bbaeb04 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -223,9 +223,13 @@ endif
 
 FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
 ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
-  msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+  msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
   NO_LIBUNWIND := 1
 endif # Libunwind support
+ifneq ($(call try-cc,$(SOURCE_LIBUNWIND_DEBUG_FRAME),$(FLAGS_UNWIND),libunwind debug_frame),y)
+  msg := $(warning No debug_frame support found in libunwind);
+CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
+endif # debug_frame support in libunwind
 endif # NO_LIBUNWIND
 
 ifndef NO_LIBUNWIND
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index 708fb8e..cde75f5 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -176,7 +176,6 @@ extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
                                       unw_proc_info_t *pi,
                                       int need_unwind_info, void *arg);
 
-
 #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
 
 int main(void)
@@ -188,6 +187,26 @@ int main(void)
 	return 0;
 }
 endef
+
+define SOURCE_LIBUNWIND_DEBUG_FRAME
+#include <libunwind.h>
+#include <stdlib.h>
+
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+				 unw_word_t ip, unw_word_t segbase,
+				 const char *obj_name, unw_word_t start,
+				 unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
+int main(void)
+{
+	dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
+	return 0;
+}
+endef
+
 endif
 
 ifndef NO_BACKTRACE
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
                   ` (2 preceding siblings ...)
  2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet
@ 2013-09-26 11:36 ` Jean Pihet
  2013-09-26 12:49   ` Jiri Olsa
  3 siblings, 1 reply; 14+ messages in thread
From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

On ARM the debug info is not present in the .eh_frame sections but
in .debug_frame instead, in dwarf format.
Use libunwind to load and parse the debug info.

Dependencies:
 . if present, libunwind >= 1.1 is needed to prevent a segfault when
   parsing the dwarf info,
 . libunwind needs to be configured with --enable-debug-frame. Note:
   --enable-debug-frame is automatically selected on ARM.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
 tools/perf/util/unwind.c | 75 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 59 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 2f891f7..5390d0b 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -39,6 +39,15 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
 
 #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
 
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+				 unw_word_t ip,
+				 unw_word_t segbase,
+				 const char *obj_name, unw_word_t start,
+				 unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
 #define DW_EH_PE_FORMAT_MASK	0x0f	/* format of the encoded value */
 #define DW_EH_PE_APPL_MASK	0x70	/* how the value is to be applied */
 
@@ -245,8 +254,9 @@ static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
 	return 0;
 }
 
-static int read_unwind_spec(struct dso *dso, struct machine *machine,
-			    u64 *table_data, u64 *segbase, u64 *fde_count)
+static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
+				     u64 *table_data, u64 *segbase,
+				     u64 *fde_count)
 {
 	int ret = -EINVAL, fd;
 	u64 offset;
@@ -255,6 +265,7 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
 	if (fd < 0)
 		return -EINVAL;
 
+	/* Check the .eh_frame section for unwinding info */
 	offset = elf_section_offset(fd, ".eh_frame_hdr");
 	close(fd);
 
@@ -263,10 +274,29 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
 					  table_data, segbase,
 					  fde_count);
 
-	/* TODO .debug_frame check if eh_frame_hdr fails */
 	return ret;
 }
 
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+static int read_unwind_spec_debug_frame(struct dso *dso,
+					struct machine *machine, u64 *offset)
+{
+	int fd = dso__data_fd(dso, machine);
+
+	if (fd < 0)
+		return -EINVAL;
+
+	/* Check the .debug_frame section for unwinding info */
+	*offset = elf_section_offset(fd, ".debug_frame");
+	close(fd);
+
+	if (*offset)
+		return 0;
+
+	return -EINVAL;
+}
+#endif
+
 static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
 {
 	struct addr_location al;
@@ -291,20 +321,33 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
 
 	pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
 
-	if (read_unwind_spec(map->dso, ui->machine,
-			     &table_data, &segbase, &fde_count))
-		return -EINVAL;
+	/* Check the .eh_frame section for unwinding info */
+	if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
+				       &table_data, &segbase, &fde_count)) {
+		memset(&di, 0, sizeof(di));
+		di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
+		di.start_ip = map->start;
+		di.end_ip   = map->end;
+		di.u.rti.segbase    = map->start + segbase;
+		di.u.rti.table_data = map->start + table_data;
+		di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
+				      / sizeof(unw_word_t);
+		return dwarf_search_unwind_table(as, ip, &di, pi,
+						 need_unwind_info, arg);
+	}
+
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+	/* Check the .debug_frame section for unwinding info */
+	if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
+		memset(&di, 0, sizeof(di));
+		dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
+				       map->start, map->end);
+		return dwarf_search_unwind_table(as, ip, &di, pi,
+						 need_unwind_info, arg);
+	}
+#endif
 
-	memset(&di, 0, sizeof(di));
-	di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
-	di.start_ip = map->start;
-	di.end_ip   = map->end;
-	di.u.rti.segbase    = map->start + segbase;
-	di.u.rti.table_data = map->start + table_data;
-	di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
-			      / sizeof(unw_word_t);
-	return dwarf_search_unwind_table(as, ip, &di, pi,
-					 need_unwind_info, arg);
+	return -EINVAL;
 }
 
 static int access_fpreg(unw_addr_space_t __maybe_unused as,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet
@ 2013-09-26 12:48   ` Jiri Olsa
  2013-10-08 10:44     ` Jean Pihet
  0 siblings, 1 reply; 14+ messages in thread
From: Jiri Olsa @ 2013-09-26 12:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote:
> The newly added dwarf unwinding feature [1] requires:
> . a recent version (>= 1.1) of libunwind,
> . libunwind to be configured with --enable-debug-frame.
> 
> [1] http://www.spinics.net/lists/kernel/msg1598951.html
> 
> Add the corresponding API tests in the feature check list.

Acked-by: Jiri Olsa <jolsa@redhat.com>

thanks,
jirka

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
@ 2013-09-26 12:49   ` Jiri Olsa
  2013-10-08 10:44     ` Jean Pihet
  0 siblings, 1 reply; 14+ messages in thread
From: Jiri Olsa @ 2013-09-26 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 26, 2013 at 01:36:38PM +0200, Jean Pihet wrote:
> On ARM the debug info is not present in the .eh_frame sections but
> in .debug_frame instead, in dwarf format.
> Use libunwind to load and parse the debug info.
> 
> Dependencies:
>  . if present, libunwind >= 1.1 is needed to prevent a segfault when
>    parsing the dwarf info,
>  . libunwind needs to be configured with --enable-debug-frame. Note:
>    --enable-debug-frame is automatically selected on ARM.

Acked-by: Jiri Olsa <jolsa@redhat.com>

thanks,
jirka

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-09-26 12:48   ` Jiri Olsa
@ 2013-10-08 10:44     ` Jean Pihet
  2013-10-08 10:47       ` Peter Zijlstra
  0 siblings, 1 reply; 14+ messages in thread
From: Jean Pihet @ 2013-10-08 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote:
> On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote:
>> The newly added dwarf unwinding feature [1] requires:
>> . a recent version (>= 1.1) of libunwind,
>> . libunwind to be configured with --enable-debug-frame.
>>
>> [1] http://www.spinics.net/lists/kernel/msg1598951.html
>>
>> Add the corresponding API tests in the feature check list.
>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
>
> thanks,
> jirka

Thanks for the ack!

Is it possible to get an ack from the perf core maintainers?
Also, is the patch going in Will's tree?

Regards,
Jean

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-26 12:49   ` Jiri Olsa
@ 2013-10-08 10:44     ` Jean Pihet
  0 siblings, 0 replies; 14+ messages in thread
From: Jean Pihet @ 2013-10-08 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 26 September 2013 14:49, Jiri Olsa <jolsa@redhat.com> wrote:
> On Thu, Sep 26, 2013 at 01:36:38PM +0200, Jean Pihet wrote:
>> On ARM the debug info is not present in the .eh_frame sections but
>> in .debug_frame instead, in dwarf format.
>> Use libunwind to load and parse the debug info.
>>
>> Dependencies:
>>  . if present, libunwind >= 1.1 is needed to prevent a segfault when
>>    parsing the dwarf info,
>>  . libunwind needs to be configured with --enable-debug-frame. Note:
>>    --enable-debug-frame is automatically selected on ARM.
>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
>
> thanks,
> jirka


Thanks for the ack!

Is it possible to get an ack from the perf core maintainers?
Also, is the patch going in Will's tree?

Regards,
Jean

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-10-08 10:44     ` Jean Pihet
@ 2013-10-08 10:47       ` Peter Zijlstra
  2013-10-08 14:15         ` Jean Pihet
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2013-10-08 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 08, 2013 at 12:44:32PM +0200, Jean Pihet wrote:
> Hi,
> 
> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote:
> > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote:
> >> The newly added dwarf unwinding feature [1] requires:
> >> . a recent version (>= 1.1) of libunwind,
> >> . libunwind to be configured with --enable-debug-frame.
> >>
> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html
> >>
> >> Add the corresponding API tests in the feature check list.
> >
> > Acked-by: Jiri Olsa <jolsa@redhat.com>
> >
> > thanks,
> > jirka
> 
> Thanks for the ack!
> 
> Is it possible to get an ack from the perf core maintainers?
> Also, is the patch going in Will's tree?

This being a tools patch you'd have to ask acme; also I know next to
nothing about all this unwind business except that its stupid expensive
;-)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-10-08 10:47       ` Peter Zijlstra
@ 2013-10-08 14:15         ` Jean Pihet
  2013-10-08 14:28           ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 14+ messages in thread
From: Jean Pihet @ 2013-10-08 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 8 October 2013 12:47, Peter Zijlstra <peterz@infradead.org> wrote:
> On Tue, Oct 08, 2013 at 12:44:32PM +0200, Jean Pihet wrote:
>> Hi,
>>
>> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote:
>> > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote:
>> >> The newly added dwarf unwinding feature [1] requires:
>> >> . a recent version (>= 1.1) of libunwind,
>> >> . libunwind to be configured with --enable-debug-frame.
>> >>
>> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html
>> >>
>> >> Add the corresponding API tests in the feature check list.
>> >
>> > Acked-by: Jiri Olsa <jolsa@redhat.com>
>> >
>> > thanks,
>> > jirka
>>
>> Thanks for the ack!
>>
>> Is it possible to get an ack from the perf core maintainers?
>> Also, is the patch going in Will's tree?
>
> This being a tools patch you'd have to ask acme; also I know next to
> nothing about all this unwind business except that its stupid expensive
> ;-)
You are right! It brings some more info on the trace though.

-- adding Arnaldo in the loop --
Arnaldo, are you OK with the changes [1]? Jiri acked the patches
already; Will is willing (no pun intended) to take the ARM specific
patches [2] in his tree.

[1] http://www.spinics.net/lists/kernel/msg1608921.html and
http://www.spinics.net/lists/kernel/msg1608922.html
[2] http://www.spinics.net/lists/kernel/msg1608920.html and
http://www.spinics.net/lists/kernel/msg1608923.html

Regards,
Jean

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-10-08 14:15         ` Jean Pihet
@ 2013-10-08 14:28           ` Arnaldo Carvalho de Melo
  2013-10-08 14:31             ` Will Deacon
  0 siblings, 1 reply; 14+ messages in thread
From: Arnaldo Carvalho de Melo @ 2013-10-08 14:28 UTC (permalink / raw)
  To: linux-arm-kernel

Em Tue, Oct 08, 2013 at 04:15:40PM +0200, Jean Pihet escreveu:
> On 8 October 2013 12:47, Peter Zijlstra <peterz@infradead.org> wrote:
> > On Tue, Oct 08, 2013 at 12:44:32PM +0200, Jean Pihet wrote:
> >> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote:
> >> > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote:
> >> >> The newly added dwarf unwinding feature [1] requires:
> >> >> . a recent version (>= 1.1) of libunwind,
> >> >> . libunwind to be configured with --enable-debug-frame.

> >> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html

> >> >> Add the corresponding API tests in the feature check list.

> >> > Acked-by: Jiri Olsa <jolsa@redhat.com>

> >> Thanks for the ack!

> >> Is it possible to get an ack from the perf core maintainers?
> >> Also, is the patch going in Will's tree?

> > This being a tools patch you'd have to ask acme; also I know next to
> > nothing about all this unwind business except that its stupid expensive
> > ;-)
> You are right! It brings some more info on the trace though.

> -- adding Arnaldo in the loop --
> Arnaldo, are you OK with the changes [1]? Jiri acked the patches
> already; Will is willing (no pun intended) to take the ARM specific
> patches [2] in his tree.

As Jiri acked, go ahead and pick as much as you can via Will's tree, I'd
say. :-)

- Arnaldo
 
> [1] http://www.spinics.net/lists/kernel/msg1608921.html and
> http://www.spinics.net/lists/kernel/msg1608922.html
> [2] http://www.spinics.net/lists/kernel/msg1608920.html and
> http://www.spinics.net/lists/kernel/msg1608923.html
> 
> Regards,
> Jean

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature
  2013-10-08 14:28           ` Arnaldo Carvalho de Melo
@ 2013-10-08 14:31             ` Will Deacon
  0 siblings, 0 replies; 14+ messages in thread
From: Will Deacon @ 2013-10-08 14:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 08, 2013 at 03:28:30PM +0100, Arnaldo Carvalho de Melo wrote:
> Em Tue, Oct 08, 2013 at 04:15:40PM +0200, Jean Pihet escreveu:
> > >> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote:
> 
> > >> > Acked-by: Jiri Olsa <jolsa@redhat.com>
> 
> > -- adding Arnaldo in the loop --
> > Arnaldo, are you OK with the changes [1]? Jiri acked the patches
> > already; Will is willing (no pun intended) to take the ARM specific
> > patches [2] in his tree.
> 
> As Jiri acked, go ahead and pick as much as you can via Will's tree, I'd
> say. :-)

Cheers guys, that suits me!

Will

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-10-08 14:31 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet
2013-09-26 11:36 ` [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet
2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet
2013-09-26 12:48   ` Jiri Olsa
2013-10-08 10:44     ` Jean Pihet
2013-10-08 10:47       ` Peter Zijlstra
2013-10-08 14:15         ` Jean Pihet
2013-10-08 14:28           ` Arnaldo Carvalho de Melo
2013-10-08 14:31             ` Will Deacon
2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
2013-09-26 12:49   ` Jiri Olsa
2013-10-08 10:44     ` Jean Pihet
  -- strict thread matches above, loose matches on Subject: below --
2013-09-16  9:17 [PATCH v2 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
2013-09-16  9:17 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present 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).