|
|
8c60bf |
From 1b2cd3f4dc581eed0fc1ee98f97aa492a19873b0 Mon Sep 17 00:00:00 2001
|
|
|
8c60bf |
From: Mark Wielaard <mark@klomp.org>
|
|
|
8c60bf |
Date: Sun, 21 May 2017 23:33:15 +0200
|
|
|
8c60bf |
Subject: [PATCH] ppc64: Add minimal fallback unwinder.
|
|
|
8c60bf |
|
|
|
8c60bf |
This adds a minimal fallback unwinder for ppc64[le] in case we cannot find
|
|
|
8c60bf |
CFI for a particular address. It simply always sets the program counter to
|
|
|
8c60bf |
the link register, picks the previous stack pointer from the backchain,
|
|
|
8c60bf |
and the previous link register from the LR save area.
|
|
|
8c60bf |
|
|
|
8c60bf |
This is enough for some simple situations when we don't have CFI and
|
|
|
8c60bf |
seems to work nicely in the case of perf with libdw powerpc support:
|
|
|
8c60bf |
https://lkml.org/lkml/2017/5/18/998
|
|
|
8c60bf |
|
|
|
8c60bf |
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
8c60bf |
---
|
|
|
8c60bf |
|
|
|
8c60bf |
backends/Makefile.am | 2 +-
|
|
|
8c60bf |
backends/ppc64_init.c | 1 +
|
|
|
8c60bf |
backends/ppc64_unwind.c | 76 +++++++++++++++++++++++++++++++++
|
|
|
8c60bf |
|
|
|
8c60bf |
diff --git a/backends/Makefile.am b/backends/Makefile.am
|
|
|
8c60bf |
index ff80a82..ac45a45 100644
|
|
|
8c60bf |
--- a/backends/Makefile.am
|
|
|
8c60bf |
+++ b/backends/Makefile.am
|
|
|
8c60bf |
@@ -98,7 +98,7 @@ am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
|
|
|
8c60bf |
|
|
|
8c60bf |
ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
|
|
|
8c60bf |
ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
|
|
|
8c60bf |
- ppc_cfi.c ppc_initreg.c ppc64_resolve_sym.c
|
|
|
8c60bf |
+ ppc_cfi.c ppc_initreg.c ppc64_unwind.c ppc64_resolve_sym.c
|
|
|
8c60bf |
libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
|
|
|
8c60bf |
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
|
|
|
8c60bf |
|
|
|
8c60bf |
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
|
|
|
8c60bf |
index 11d3a77..e567033 100644
|
|
|
8c60bf |
--- a/backends/ppc64_init.c
|
|
|
8c60bf |
+++ b/backends/ppc64_init.c
|
|
|
8c60bf |
@@ -73,6 +73,7 @@ ppc64_init (Elf *elf __attribute__ ((unused)),
|
|
|
8c60bf |
eh->frame_nregs = (114 - 1) + 32;
|
|
|
8c60bf |
HOOK (eh, set_initial_registers_tid);
|
|
|
8c60bf |
HOOK (eh, dwarf_to_regno);
|
|
|
8c60bf |
+ HOOK (eh, unwind);
|
|
|
8c60bf |
HOOK (eh, resolve_sym_value);
|
|
|
8c60bf |
|
|
|
8c60bf |
/* Find the function descriptor .opd table for resolve_sym_value. */
|
|
|
8c60bf |
diff --git a/backends/ppc64_unwind.c b/backends/ppc64_unwind.c
|
|
|
8c60bf |
new file mode 100644
|
|
|
8c60bf |
index 0000000..4fa0b5a
|
|
|
8c60bf |
--- /dev/null
|
|
|
8c60bf |
+++ b/backends/ppc64_unwind.c
|
|
|
8c60bf |
@@ -0,0 +1,76 @@
|
|
|
8c60bf |
+/* Get previous frame state for an existing frame state.
|
|
|
8c60bf |
+ Copyright (C) 2017 Red Hat, Inc.
|
|
|
8c60bf |
+ This file is part of elfutils.
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ This file is free software; you can redistribute it and/or modify
|
|
|
8c60bf |
+ it under the terms of either
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ * the GNU Lesser General Public License as published by the Free
|
|
|
8c60bf |
+ Software Foundation; either version 3 of the License, or (at
|
|
|
8c60bf |
+ your option) any later version
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ or
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ * the GNU General Public License as published by the Free
|
|
|
8c60bf |
+ Software Foundation; either version 2 of the License, or (at
|
|
|
8c60bf |
+ your option) any later version
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ or both in parallel, as here.
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ elfutils is distributed in the hope that it will be useful, but
|
|
|
8c60bf |
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
8c60bf |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
8c60bf |
+ General Public License for more details.
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ You should have received copies of the GNU General Public License and
|
|
|
8c60bf |
+ the GNU Lesser General Public License along with this program. If
|
|
|
8c60bf |
+ not, see <http://www.gnu.org/licenses/>. */
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+#ifdef HAVE_CONFIG_H
|
|
|
8c60bf |
+# include <config.h>
|
|
|
8c60bf |
+#endif
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+#define BACKEND ppc64_
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+#define LR_REG 65 /* Not 108, see ppc_dwarf_to_regno. */
|
|
|
8c60bf |
+#define SP_REG 1
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+#define LR_OFFSET 16
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+#include "libebl_CPU.h"
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+/* Simplistic fallback frame unwinder. SP points to the backchain (contains
|
|
|
8c60bf |
+ address of previous stack pointer). At SP offset 16 is the LR save area
|
|
|
8c60bf |
+ (contains the value of the previous LR). */
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+bool
|
|
|
8c60bf |
+EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)),
|
|
|
8c60bf |
+ Dwarf_Addr pc __attribute__ ((unused)),
|
|
|
8c60bf |
+ ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
|
|
|
8c60bf |
+ ebl_pid_memory_read_t *readfunc, void *arg,
|
|
|
8c60bf |
+ bool *signal_framep __attribute__ ((unused)))
|
|
|
8c60bf |
+{
|
|
|
8c60bf |
+ Dwarf_Word sp, newSp, lr, newLr;
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ /* Stack pointer points to the backchain which contains the previous sp. */
|
|
|
8c60bf |
+ if (! getfunc (SP_REG, 1, &sp, arg))
|
|
|
8c60bf |
+ sp = 0;
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ /* Link register contains previous program counter. */
|
|
|
8c60bf |
+ if (! getfunc (LR_REG, 1, &lr, arg)
|
|
|
8c60bf |
+ || lr == 0
|
|
|
8c60bf |
+ || ! setfunc (-1, 1, &lr, arg))
|
|
|
8c60bf |
+ return false;
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ if (! readfunc(sp, &newSp, arg))
|
|
|
8c60bf |
+ newSp = 0;
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ if (! readfunc(newSp + LR_OFFSET, &newLr, arg))
|
|
|
8c60bf |
+ newLr = 0;
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ setfunc(SP_REG, 1, &newSp, arg);
|
|
|
8c60bf |
+ setfunc(LR_REG, 1, &newLr, arg);
|
|
|
8c60bf |
+
|
|
|
8c60bf |
+ /* Sanity check the stack grows down. */
|
|
|
8c60bf |
+ return newSp > sp;
|
|
|
8c60bf |
+}
|
|
|
8c60bf |
|
|
|
8c60bf |
diff -ur elfutils-0.168.orig/backends/Makefile.in elfutils-0.168/backends/Makefile.in
|
|
|
8c60bf |
--- elfutils-0.168.orig/backends/Makefile.in 2017-05-30 22:35:20.251108585 +0200
|
|
|
8c60bf |
+++ elfutils-0.168/backends/Makefile.in 2017-05-30 22:36:43.622531949 +0200
|
|
|
8c60bf |
@@ -158,7 +158,7 @@
|
|
|
8c60bf |
ppc64_retval.$(OBJEXT) ppc64_corenote.$(OBJEXT) \
|
|
|
8c60bf |
ppc_regs.$(OBJEXT) ppc_auxv.$(OBJEXT) ppc_attrs.$(OBJEXT) \
|
|
|
8c60bf |
ppc_syscall.$(OBJEXT) ppc_cfi.$(OBJEXT) ppc_initreg.$(OBJEXT) \
|
|
|
8c60bf |
- ppc64_resolve_sym.$(OBJEXT)
|
|
|
8c60bf |
+ ppc64_unwind.$(OBJEXT) ppc64_resolve_sym.$(OBJEXT)
|
|
|
8c60bf |
libebl_ppc64_pic_a_OBJECTS = $(am_libebl_ppc64_pic_a_OBJECTS)
|
|
|
8c60bf |
libebl_ppc_pic_a_AR = $(AR) $(ARFLAGS)
|
|
|
8c60bf |
libebl_ppc_pic_a_LIBADD =
|
|
|
8c60bf |
@@ -503,7 +503,7 @@
|
|
|
8c60bf |
am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
|
|
|
8c60bf |
ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
|
|
|
8c60bf |
ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
|
|
|
8c60bf |
- ppc_cfi.c ppc_initreg.c ppc64_resolve_sym.c
|
|
|
8c60bf |
+ ppc_cfi.c ppc_initreg.c ppc64_unwind.c ppc64_resolve_sym.c
|
|
|
8c60bf |
|
|
|
8c60bf |
libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
|
|
|
8c60bf |
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
|
|
|
8c60bf |
@@ -692,6 +692,7 @@
|
|
|
8c60bf |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_resolve_sym.Po@am__quote@
|
|
|
8c60bf |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_retval.Po@am__quote@
|
|
|
8c60bf |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_symbol.Po@am__quote@
|
|
|
8c60bf |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_unwind.Po@am__quote@
|
|
|
8c60bf |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_attrs.Po@am__quote@
|
|
|
8c60bf |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_auxv.Po@am__quote@
|
|
|
8c60bf |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_cfi.Po@am__quote@
|
|
|
8c60bf |
|
|
|
8c60bf |
--
|
|
|
8c60bf |
1.8.3.1
|
|
|
8c60bf |
--- elfutils-0.168/tests/backtrace-subr.sh.orig 2017-05-31 00:39:02.797260621 +0200
|
|
|
8c60bf |
+++ elfutils-0.168/tests/backtrace-subr.sh 2017-05-31 00:39:28.445782296 +0200
|
|
|
8c60bf |
@@ -46,7 +46,7 @@
|
|
|
8c60bf |
# Ignore it here as it is a bug of OS, not a bug of elfutils.
|
|
|
8c60bf |
check_err()
|
|
|
8c60bf |
{
|
|
|
8c60bf |
- if [ $(egrep -v <$1 'dwfl_thread_getframes: (No DWARF information found|no matching address range)$' \
|
|
|
8c60bf |
+ if [ $(egrep -v <$1 'dwfl_thread_getframes: (No DWARF information found|no matching address range|address out of range|Invalid register|\(null\))$' \
|
|
|
8c60bf |
| wc -c) \
|
|
|
8c60bf |
-eq 0 ]
|
|
|
8c60bf |
then
|