mips*-linux* signal unwinding for 64-bit ABIs

Richard Sandiford richard@codesourcery.com
Fri May 19 14:55:00 GMT 2006


The current version of config/mips/linux-unwind.h only handles signal
unwinding for o32.  (The numbers coded into its "li" instructions are
those of the o32 __NR_sigreturn and __NR_rt_sigreturn syscalls.)

Fortunately:

  - The traditional sigreturn is not implemented for n32 and n64.

  - The rt_sigreturn trampolines are just the same as for o32,
    except for the syscall number.

  - The relevant fields of the n32 and n64 rt_sigframe structures have
    the same type as their o32 counterparts.  (For completeness,
    the layouts of the types differ, but have enough source-level
    compatibility for our needs.)

This patch will only work if glibc's sigcontext matches the kernel's.
See: http://sources.redhat.com/ml/libc-ports/2006-05/msg00015.html
for details.

Tested on mips64-linux-gnu, where it fixes gcc.dg/cleanup-{8,9,10,11}.c
for -mabi=n32 and -mabi=64.  Applied to trunk.

Richard


	* config/mips/linux-unwind.h: Include <asm/unistd.h>
	(mips_fallback_frame_state): Use syscall numbers to determine
	the appropriate li instruction for the current ABI.  Only use
	__NR_sigreturn for o32.

Index: gcc/config/mips/linux-unwind.h
===================================================================
--- gcc/config/mips/linux-unwind.h	(revision 113576)
+++ gcc/config/mips/linux-unwind.h	(working copy)
@@ -31,6 +31,7 @@ file.  (The General Public License restr
    state data appropriately.  See unwind-dw2.c for the structs.  */
 
 #include <signal.h>
+#include <asm/unistd.h>
 
 /* The third parameter to the signal handler points to something with
  * this structure defined in asm/ucontext.h, but the name clashes with
@@ -59,20 +60,23 @@ mips_fallback_frame_state (struct _Unwin
   /*    or */
   /* 24021017 li v0, 0x1017 (sigreturn) */
   /* 0000000c syscall  */
-  if (*(pc + 1) != 0x0000000c)
+  if (pc[1] != 0x0000000c)
     return _URC_END_OF_STACK;
-  if (*(pc + 0) == 0x24021017)
+#if _MIPS_SIM == _ABIO32
+  if (pc[0] == (0x24020000 | __NR_sigreturn))
     {
       struct sigframe {
-	u_int32_t  trampoline[2];
+	u_int32_t trampoline[2];
 	struct sigcontext sigctx;
       } *rt_ = context->ra;
       sc = &rt_->sigctx;
     }
-  else if (*(pc + 0) == 0x24021061)
+  else
+#endif
+  if (pc[0] == (0x24020000 | __NR_rt_sigreturn))
     {
       struct rt_sigframe {
-	u_int32_t  trampoline[2];
+	u_int32_t trampoline[2];
 	struct siginfo info;
 	_sig_ucontext_t uc;
       } *rt_ = context->ra;



More information about the Gcc-patches mailing list