public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
To: Olivier Hainque <hainque@adacore.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: unwinding fallback for mips-irix6 n32
Date: Fri, 10 Jun 2011 11:16:00 -0000	[thread overview]
Message-ID: <yddaadqaqxs.fsf@manam.CeBiTec.Uni-Bielefeld.DE> (raw)
In-Reply-To: <20101226094957.GA13777@cardhu.act-europe.fr> (Olivier Hainque's	message of "Sun, 26 Dec 2010 10:49:57 +0100")

Hello Olivier,

> We have been using an unwinding fallback on mips-irix6/n32 for a while
> (number of years) across different versions of GCC (3.4, 4.1, 4.3, and
> 4.5 lately).
>
> We haven't submitted this for inclusion so far because of the pretty
> limited range of supported configurations (irix 6, n32 abi only).
>
> Exchanges offlist suggested that it could be of interest nevertheless,
> so here it is.
>
> Our latest port was to gcc 4.5. The attached patch is a minor
> adaptation of that to mainline. I tested that a non bootstrap build
> proceeds fine and that a basic test involving SEGV in Ada works as
> expected.
>
> Rainer kindly offered to perform more thorough testing, to validate
> that this indeed reduces the amount of failures he has been observing.

I've finally gotten around to this.  Apart from some comment and code
cleanups along the lines of the sol2-unwind.h files, I had to minimally
adapt the N32 multithreaded code sequence for IRIX 6.5.30 that I'm
running here.  While I was at it, I added N64 support which proved to be
almost trivial.  You'll probably have to adapt this for the version of
IRIX 6.5 you're running, or we could simply skip the single varying
insn.

With this patch, a couple of gnat.dg tests are fixed:

* N32:

-FAIL: gnat.dg/null_pointer_deref1.adb execution test
-FAIL: gnat.dg/null_pointer_deref2.adb execution test
-FAIL: gnat.dg/stack_check1.adb execution test
-FAIL: gnat.dg/stack_check2.adb execution test

* N64:

-FAIL: gnat.dg/null_pointer_deref1.adb execution test
-FAIL: gnat.dg/null_pointer_deref2.adb execution test
-FAIL: gnat.dg/stack_check1.adb execution test

64-bit stack_check2.adb remains broken, though.  It SEGVs in memcpy, but
the stack is corrupted, so I cannot say yet what's going on.

I'll run a full bootstrap over the weekend.  It seems that the remaining
libjava failures are unrelated.

I may backport this to the 4.6 branch after some time (trivial apart
from the gcc -> libgcc move).  I will only try 4.5 if I manage to add
O32 support.  This might be a non-trivial excercise since the libc
implementation is quite different.

Thanks for providing the patch.  

	Rainer


2011-05-29  Olivier Hainque  <hainque@adacore.com>
	    Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libgcc:
	* config/mips/irix6-unwind.h: New file.
	* config.host (mips-sgi-irix6.5*): Set md_unwind_header.

diff --git a/libgcc/config.host b/libgcc/config.host
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -456,6 +456,7 @@ microblaze*-*-*)
 mips-sgi-irix6.5*)
 	tmake_file="mips/t-irix6 t-crtfm t-slibgcc mips/t-slibgcc-irix"
 	extra_parts="crtbegin.o crtend.o crtfastmath.o irix-crti.o irix-crtn.o"
+	md_unwind_header=mips/irix6-unwind.h
 	;;
 mips*-*-netbsd*)			# NetBSD/mips, either endian.
 	;;
diff --git a/libgcc/config/mips/irix6-unwind.h b/libgcc/config/mips/irix6-unwind.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/mips/irix6-unwind.h
@@ -0,0 +1,180 @@
+/* DWARF2 EH unwinding support for MIPS IRIX 6.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+/* This code was developed-for and only tested-in limited ABI
+   configurations.  Characterize that.  */
+
+#if defined (_ABIN32) || defined (_ABI64)
+#define SUPPORTED_ABI 1
+#else
+#define SUPPORTED_ABI 0
+#endif
+
+#include <signal.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
+
+/* Look at the code around RA to see if it matches a sighandler caller with a
+   sigcontext_t * argument (SA_SIGINFO cleared).  Return that pointer argument
+   if it does match, or 0 otherwise.  */
+
+static sigcontext_t *
+sigcontext_for (unsigned int *ra, void *cfa)
+{
+  /* IRIX 6.5, mono-threaded application.  We're lucky enough to be able
+     to expect a short very sighandler specific sequence around.
+
+     <_sigtramp+124>:	li	v0,1088 (SYS_sigreturn)
+     <_sigtramp+128>:	syscall  */
+
+  if (   ra[6] == 0x24020440
+      && ra[7] == 0x0000000c)
+    return (sigcontext_t *)(cfa + 0x30);
+
+  /* IRIX 6.5 variants, multi-threaded application, pthreads.  Nothing really
+     sighandler specific handy, so match a fairly long constant sequence.  */
+
+#if _MIPS_SIM == _ABIN32
+  /* 
+     <sig_fixup_mask+40>:	sd	s0,0(sp)
+     <sig_fixup_mask+44>:	sll	ra,a0,0x2
+     <sig_fixup_mask+48>:	addiu	t9,t9,-28584/-28456/-28448
+     <sig_fixup_mask+52>:	lw	s0,3804(at)
+     <sig_fixup_mask+56>:	addu	t9,t9,ra
+     <sig_fixup_mask+60>:	lw	t9,0(t9)
+     <sig_fixup_mask+64>:	ld	at,3696(at)
+     <sig_fixup_mask+68>:	ld	s2,88(s0)
+     <sig_fixup_mask+72>:	jalr	t9
+     <sig_fixup_mask+76>:	sd	at,88(s0)  */
+   if (   ra[-10] == 0xffb00000
+      && ra[ -9] == 0x0004f880
+      && (ra[-8] == 0x27399058
+	  || ra[-8] == 0x273990d8
+	  || ra[-8] == 0x273990e0)
+      && ra[ -7] == 0x8c300edc
+      && ra[ -6] == 0x033fc821
+      && ra[ -5] == 0x8f390000
+      && ra[ -4] == 0xdc210e70
+      && ra[ -3] == 0xde120058
+      && ra[ -2] == 0x0320f809
+      && ra[ -1] == 0xfe010058)
+
+#elif _MIPS_SIM == _ABI64
+  /* 
+     <sig_fixup_mask+44>:	sd	s0,0(sp)
+     <sig_fixup_mask+48>:	daddu	t9,t9,ra
+     <sig_fixup_mask+52>:	dsll	ra,a0,0x3
+     <sig_fixup_mask+56>:	ld	s0,3880(at)
+     <sig_fixup_mask+60>:	daddu	t9,t9,ra
+     <sig_fixup_mask+64>:	ld	t9,0(t9)
+     <sig_fixup_mask+68>:	ld	at,3696(at)
+     <sig_fixup_mask+72>:	ld	s2,152(s0)
+     <sig_fixup_mask+76>:	jalr	t9
+     <sig_fixup_mask+80>:	sd	at,152(s0)  */
+  if (   ra[-10] == 0xffb00000
+      && ra[ -9] == 0x033fc82d
+      && ra[ -8] == 0x0004f8f8
+      && ra[ -7] == 0xdc300f28
+      && ra[ -6] == 0x033fc82d
+      && ra[ -5] == 0xdf390000
+      && ra[ -4] == 0xdc210e70
+      && ra[ -3] == 0xde120098
+      && ra[ -2] == 0x0320f809
+      && ra[ -1] == 0xfe010098)
+#endif
+    return (sigcontext_t *)(cfa + 0x60);
+
+  return 0;
+}
+
+#define SIGCTX_GREG_ADDR(REGNO,SIGCTX) \
+  ((void *) &(SIGCTX)->sc_regs[REGNO])
+
+#define SIGCTX_FPREG_ADDR(REGNO,SIGCTX) \
+  ((void *) &(SIGCTX)->sc_fpregs[REGNO])
+
+static _Unwind_Reason_Code
+mips_fallback_frame_state (struct _Unwind_Context *context,
+			   _Unwind_FrameState *fs)
+{
+  /* Return address and CFA of the frame we're attempting to unwind through,
+     possibly a signal handler.  */
+  void *ctx_ra  = (void *)context->ra;
+  void *ctx_cfa = (void *)context->cfa;
+
+  /* CFA of the intermediate abstract kernel frame between the interrupted
+     code and the signal handler, if we're indeed unwinding through a signal
+     handler.  */
+  void *k_cfa;
+
+  /* Pointer to the sigcontext_t structure pushed by the kernel when we're
+     unwinding through a signal handler setup with SA_SIGINFO cleared.  */
+  sigcontext_t *sigctx;
+  int i;
+
+  if (! SUPPORTED_ABI)
+    return _URC_END_OF_STACK;
+    
+  sigctx = sigcontext_for (ctx_ra, ctx_cfa);
+
+  if (sigctx == 0)
+    return _URC_END_OF_STACK;
+
+  /* The abstract kernel frame's CFA is extactly the stack pointer
+     value at the interruption point.  */
+  k_cfa = *(void **)SIGCTX_GREG_ADDR (CTX_SP, sigctx);
+
+  /* State the rules to compute the CFA we have the value of: use the
+     previous CFA and offset by the difference between the two.  See
+     uw_update_context_1 for the supporting details.  */
+  fs->regs.cfa_how = CFA_REG_OFFSET;
+  fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
+  fs->regs.cfa_offset = k_cfa - ctx_cfa;
+
+  /* Fill the internal frame_state structure with information stating where
+     each register of interest can be found from the CFA.  */
+  for (i = 0; i <= 31; i ++)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset = SIGCTX_GREG_ADDR (i, sigctx) - k_cfa;
+    }
+
+  for (i = 0; i <= 31; i ++)
+    {
+      fs->regs.reg[32+i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[32+i].loc.offset = SIGCTX_FPREG_ADDR (i, sigctx) - k_cfa;
+    }
+
+  /* State the rules to find the kernel's code "return address", which is the
+     address of the active instruction when the signal was caught.  */
+  fs->retaddr_column = DWARF_FRAME_RETURN_COLUMN;
+  fs->regs.reg[fs->retaddr_column].how = REG_SAVED_OFFSET;
+  fs->regs.reg[fs->retaddr_column].loc.offset = (void *)&sigctx->sc_pc - k_cfa;
+  fs->signal_frame = 1;
+
+  return _URC_NO_REASON;
+}


-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

  reply	other threads:[~2011-06-10 11:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-26 20:53 Olivier Hainque
2011-06-10 11:16 ` Rainer Orth [this message]
2011-06-16 13:10   ` Olivier Hainque
2011-06-17 13:57     ` Rainer Orth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=yddaadqaqxs.fsf@manam.CeBiTec.Uni-Bielefeld.DE \
    --to=ro@cebitec.uni-bielefeld.de \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hainque@adacore.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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 read-only IMAP folder(s) and NNTP newsgroup(s).