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