Blame SOURCES/elfutils-0.168-ppc64-fallback-unwinder.patch

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