Re: [PATCH v3] libgcc: Add a backchain fallback to _Unwind_Backtrace() on PowerPC

2021-10-06 Thread Segher Boessenkool
On Wed, Oct 06, 2021 at 10:09:31AM -0300, Raphael M Zinsly wrote:
> On 05/10/2021 19:03, Segher Boessenkool wrote:
> >So what is new or different in v3 compared to v2?
> 
> gcc/testsuite/gcc.target/powerpc/unwind-backchain.c:
>   - Added a comment explaining why test only on *-linux targets.
>   - Changed the dejagnu target from powerpc*-*-linux* to *-*-linux*.

I said in v2 that it is fine with that changed, so: okay for trunk :-)
Thanks!


Segher


Re: [PATCH v3] libgcc: Add a backchain fallback to _Unwind_Backtrace() on PowerPC

2021-10-06 Thread Raphael M Zinsly via Gcc-patches

On 05/10/2021 19:03, Segher Boessenkool wrote:

On Tue, Oct 05, 2021 at 03:32:52PM -0300, Raphael Moreira Zinsly wrote:

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.
---
  .../gcc.target/powerpc/unwind-backchain.c |  24 +
  libgcc/config/rs6000/linux-unwind.h   | 102 +++---
  libgcc/unwind.inc |  14 ++-
  3 files changed, 124 insertions(+), 16 deletions(-)
  create mode 100644 gcc/testsuite/gcc.target/powerpc/unwind-backchain.c


So what is new or different in v3 compared to v2?



gcc/testsuite/gcc.target/powerpc/unwind-backchain.c:
- Added a comment explaining why test only on *-linux targets.
- Changed the dejagnu target from powerpc*-*-linux* to *-*-linux*.

--
Raphael Moreira Zinsly


Re: [PATCH v3] libgcc: Add a backchain fallback to _Unwind_Backtrace() on PowerPC

2021-10-05 Thread Segher Boessenkool
On Tue, Oct 05, 2021 at 03:32:52PM -0300, Raphael Moreira Zinsly wrote:
> 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.
> ---
>  .../gcc.target/powerpc/unwind-backchain.c |  24 +
>  libgcc/config/rs6000/linux-unwind.h   | 102 +++---
>  libgcc/unwind.inc |  14 ++-
>  3 files changed, 124 insertions(+), 16 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/unwind-backchain.c

So what is new or different in v3 compared to v2?


Segher


[PATCH v3] libgcc: Add a backchain fallback to _Unwind_Backtrace() on PowerPC

2021-10-05 Thread Raphael Moreira Zinsly via Gcc-patches
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.
---
 .../gcc.target/powerpc/unwind-backchain.c |  24 +
 libgcc/config/rs6000/linux-unwind.h   | 102 +++---
 libgcc/unwind.inc |  14 ++-
 3 files changed, 124 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/unwind-backchain.c

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 000..affa9b2efec
--- /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 
+
+void
+test_backtrace()
+{
+  int addresses;
+  void *buffer[10];
+
+  addresses = backtrace(buffer, 10);
+  if(addresses != 4)
+__builtin_abort();
+}
+
+int
+main()
+{
+  test_backtrace();
+  return 0;
+}
diff --git a/libgcc/config/rs6000/linux-unwind.h 
b/libgcc/config/rs6000/linux-unwind.h
index acdc948f85d..8deccc1d650 100644
--- a/libgcc/config/rs6000/linux-unwind.h
+++ b/libgcc/config/rs6000/linux-unwind.h
@@ -94,6 +94,15 @@ struct gcc_ucontext
 
 enum { SIGNAL_FRAMESIZE = 128 };
 
+struct rt_sigframe {
+  char gap[SIGNAL_FRAMESIZE];
+  struct gcc_ucontext uc;
+  unsigned long pad[2];
+  int tramp[6];
+  void *pinfo;
+  struct gcc_ucontext *puc;
+};
+
 /* If PC is at a sigreturn trampoline, return a pointer to the
regs.  Otherwise return NULL.  */
 
@@ -136,14 +145,7 @@ get_regs (struct _Unwind_Context *context)
 #endif
{
  /* This works for 2.4.21 and later kernels.  */
- struct rt_sigframe {
-   char gap[SIGNAL_FRAMESIZE];
-   struct gcc_ucontext uc;
-   unsigned long pad[2];
-   int tramp[6];
-   void *pinfo;
-   struct gcc_ucontext *puc;
- } *frame = (struct rt_sigframe *) context->cfa;
+ struct rt_sigframe *frame = (struct rt_sigframe *) context->cfa;
  return frame->uc.regs;
}
 }
@@ -154,6 +156,12 @@ get_regs (struct _Unwind_Context *context)
 
 enum { SIGNAL_FRAMESIZE = 64 };
 
+struct rt_sigframe {
+  char gap[SIGNAL_FRAMESIZE + 16];
+  char siginfo[128];
+  struct gcc_ucontext uc;
+};
+
 static struct gcc_regs *
 get_regs (struct _Unwind_Context *context)
 {
@@ -176,11 +184,7 @@ get_regs (struct _Unwind_Context *context)
 }
   else if (pc[0] == 0x3800 || pc[0] == 0x38AC)
 {
-  struct rt_sigframe {
-   char gap[SIGNAL_FRAMESIZE + 16];
-   char siginfo[128];
-   struct gcc_ucontext uc;
-  } *frame = (struct rt_sigframe *) context->cfa;
+  struct rt_sigframe *frame = (struct rt_sigframe *) context->cfa;
   return frame->uc.regs;
 }
   return NULL;
@@ -203,7 +207,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
   int i;
 
   if (regs == NULL)
-return _URC_END_OF_STACK;
+return _URC_NORMAL_STOP;
 
   new_cfa = regs->gpr[__LIBGCC_STACK_POINTER_REGNUM__];
   fs->regs.cfa_how = CFA_REG_OFFSET;
@@ -352,3 +356,73 @@ frob_update_context (struct _Unwind_Context *context, 
_Unwind_FrameState *fs ATT
 }
 #endif
 }
+
+#define MD_BACKCHAIN_FALLBACK ppc_backchain_fallback
+
+struct trace_arg
+{
+  /* Stores the list of addresses.  */
+  void **array;
+  struct unwind_link *unwind_link;
+  _Unwind_Word cfa;
+  /* Number of addresses currently stored.  */
+  int count;
+  /* Maximum number of addresses.  */
+  int size;
+};
+
+/* This is the stack layout we see with every stack frame.
+   Note that every routine is required by the ABI to lay out the stack
+   like this.
+
+   +++-+
+%r1  -> | previous frame> | previous frame--->...  --> NULL
+   ||| |
+   | cr save|| cr save |
+   ||| |
+   | (unused)   || lr save |
+   +++-+
+
+  The CR save is only present