aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRaphael Moreira Zinsly <rzinsly@linux.ibm.com>2021-10-05 15:32:52 -0300
committerSegher Boessenkool <segher@kernel.crashing.org>2021-10-14 20:00:44 +0000
commitb7561b5d2443f1d5f54f5177f0fb1a13c4205856 (patch)
treeb146d395c0cf2844e5f122eae30920805ea723ea /gcc
parentb47490c572c5938f887b54240af6096a7c90f640 (diff)
downloadgcc-b7561b5d2443f1d5f54f5177f0fb1a13c4205856.zip
gcc-b7561b5d2443f1d5f54f5177f0fb1a13c4205856.tar.gz
gcc-b7561b5d2443f1d5f54f5177f0fb1a13c4205856.tar.bz2
libgcc: Add a backchain fallback to _Unwind_Backtrace() on PowerPC
Without dwarf2 unwind tables available _Unwind_Backtrace() is not able to return the full backtrace. This patch adds a fallback function on powerpc to get the backtrace by doing a backchain, this code was originally at glibc. libgcc/ChangeLog: * config/rs6000/linux-unwind.h (struct rt_sigframe): Move it to outside of get_regs() in order to use it in another function, this is done twice: for __powerpc64__ and for !__powerpc64__. (struct trace_arg): New struct. (struct layout): New struct. (ppc_backchain_fallback): New function. * unwind.inc (_Unwind_Backtrace): Look for _URC_NORMAL_STOP code state and call MD_BACKCHAIN_FALLBACK. gcc/testsuite/ChangeLog: * gcc.target/powerpc/unwind-backchain.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unwind-backchain.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/powerpc/unwind-backchain.c b/gcc/testsuite/gcc.target/powerpc/unwind-backchain.c
new file mode 100644
index 0000000..affa9b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unwind-backchain.c
@@ -0,0 +1,24 @@
+/* -linux* targets have a fallback for the absence of unwind tables, thus are
+ the only ones we can guarantee backtrace returns all addresses. */
+/* { dg-do run { target { *-*-linux* } } } */
+/* { dg-options "-fno-asynchronous-unwind-tables" } */
+
+#include <execinfo.h>
+
+void
+test_backtrace()
+{
+ int addresses;
+ void *buffer[10];
+
+ addresses = backtrace(buffer, 10);
+ if(addresses != 4)
+ __builtin_abort();
+}
+
+int
+main()
+{
+ test_backtrace();
+ return 0;
+}