summaryrefslogtreecommitdiff
path: root/gcc/config/pa
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2004-09-08 00:17:19 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2004-09-08 00:17:19 +0000
commitaebd6cb6ec855cc4f9a07a694847b4a19fe5759a (patch)
treef6927bd90fe84c682dd04619d255d6355aac36d5 /gcc/config/pa
parent97307e4d7dc6478c0d70de1816c9009a100f5542 (diff)
downloadgcc-aebd6cb6ec855cc4f9a07a694847b4a19fe5759a.tar.gz
* doc/tm.texi (MD_UNWIND_SUPPORT): Document.
(MD_FALLBACK_FRAME_STATE_FOR): Update. * unwind-dw2.c (MD_UNWIND_SUPPORT): #include if defined. (uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation. (MD_FROB_UPDATE_CONTEXT): Remove default. (uw_update_context_1): Instead #ifdef invocation. * config/ia64/unwind-ia64.c (MD_UNWIND_SUPPORT): #include if defined. (uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation. * config/alpha/gnu.h (MD_FALLBACK_FRAME_STATE_FOR): Don't undef. (MD_UNWIND_SUPPORT): Undefine this instead. * config/i386/gnu.h: Likewise. * config/alpha/linux-unwind.h: New file, macro converted to function, extracted from.. * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): ..this. (MD_UNWIND_SUPPORT): Define. * config/alpha/vms-unwind.h, config/alpha/vms.h: Likewise. * config/i386/linux-unwind.h, config/i386/linux.h, config/i386/linux64.h: Likewise. * config/ia64/linux-unwind.h, config/ia64/linux.h: Likewise. MD_HANDLE_UNWABI too. * config/mips/linux-unwind.h, config/mips/linux.h: Likewise. * config/pa/linux-unwind.h, config/pa/pa32-linux.h: Likewise. * config/rs6000/darwin-unwind.h, config/rs6000/darwin.h: Likewise. * config/s390/linux-unwind.h, config/s390/linux.h: Likewise. * config/sparc/linux-unwind.h, config/sparc/linux.h, config/sparc/linux64.h: Likewise. * config/sh/linux-unwind.h, config/sh/linux.h: Likewise, but merge SH_FALLBACK_FRAME_FLOAT_STATE into sh_fallback_frame_state. * config/rs6000/linux-unwind.h, config/rs6000/linux.h, config/rs6000/linux64.h: Likewise. Split out get_sigcontext function. Use ARG_POINTER_REGNUM for 32-bit temp reg too. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@87167 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/pa')
-rw-r--r--gcc/config/pa/linux-unwind.h115
-rw-r--r--gcc/config/pa/pa32-linux.h94
2 files changed, 116 insertions, 93 deletions
diff --git a/gcc/config/pa/linux-unwind.h b/gcc/config/pa/linux-unwind.h
new file mode 100644
index 00000000000..41ec61caa9e
--- /dev/null
+++ b/gcc/config/pa/linux-unwind.h
@@ -0,0 +1,115 @@
+/* DWARF2 EH unwinding support for PA Linux.
+ Copyright (C) 2004 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 2, 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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#include <signal.h>
+#include <sys/ucontext.h>
+
+/* Unfortunately, because of various bugs and changes to the kernel,
+ we have several cases to deal with.
+
+ In 2.4, the signal trampoline is 4 words, and (CONTEXT)->ra should
+ point directly at the beginning of the trampoline and struct rt_sigframe.
+
+ In <= 2.6.5-rc2-pa3, the signal trampoline is 9 words, and
+ (CONTEXT)->ra points at the 4th word in the trampoline structure. This
+ is wrong, it should point at the 5th word. This is fixed in 2.6.5-rc2-pa4.
+
+ To detect these cases, we first take (CONTEXT)->ra, align it to 64-bytes
+ to get the beginning of the signal frame, and then check offsets 0, 4
+ and 5 to see if we found the beginning of the trampoline. This will
+ tell us how to locate the sigcontext structure.
+
+ Note that with a 2.4 64-bit kernel, the signal context is not properly
+ passed back to userspace so the unwind will not work correctly. */
+
+#define MD_FALLBACK_FRAME_STATE_FOR pa32_fallback_frame_state
+
+static _Unwind_Reason_Code
+pa32_fallback_frame_state (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ unsigned long sp = (unsigned long)context->ra & ~63;
+ unsigned int *pc = (unsigned int *)sp;
+ unsigned long off;
+ _Unwind_Ptr new_cfa;
+ int i;
+ struct sigcontext *sc;
+ struct rt_sigframe {
+ struct siginfo info;
+ struct ucontext uc;
+ } *frame;
+
+ /* rt_sigreturn trampoline:
+ 3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2)
+ 3414015a ldi __NR_rt_sigreturn, %r20
+ e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
+ 08000240 nop */
+
+ if (pc[0] == 0x34190000 || pc[0] == 0x34190002)
+ off = 4*4;
+ else if (pc[4] == 0x34190000 || pc[4] == 0x34190002)
+ {
+ pc += 4;
+ off = 10 * 4;
+ }
+ else if (pc[5] == 0x34190000 || pc[5] == 0x34190002)
+ {
+ pc += 5;
+ off = 10 * 4;
+ }
+ else
+ return _URC_END_OF_STACK;
+ if (pc[1] != 0x3414015a
+ || pc[2] != 0xe4008200
+ || pc[3] != 0x08000240)
+ return _URC_END_OF_STACK;
+
+ frame = (struct rt_sigframe *)(sp + off);
+ sc = &frame->uc.uc_mcontext;
+
+ new_cfa = sc->sc_gr[30];
+ fs->cfa_how = CFA_REG_OFFSET;
+ fs->cfa_reg = 30;
+ fs->cfa_offset = new_cfa - (long) context->cfa;
+ for (i = 1; i <= 31; i++)
+ {
+ fs->regs.reg[i].how = REG_SAVED_OFFSET;
+ fs->regs.reg[i].loc.offset = (long)&sc->sc_gr[i] - new_cfa;
+ }
+ for (i = 4; i <= 31; i++)
+ {
+ /* FP regs have left and right halves */
+ fs->regs.reg[2*i+24].how = REG_SAVED_OFFSET;
+ fs->regs.reg[2*i+24].loc.offset
+ = (long)&sc->sc_fr[i] - new_cfa;
+ fs->regs.reg[2*i+24+1].how = REG_SAVED_OFFSET;
+ fs->regs.reg[2*i+24+1].loc.offset
+ = (long)&sc->sc_fr[i] + 4 - new_cfa;
+ }
+ fs->regs.reg[88].how = REG_SAVED_OFFSET;
+ fs->regs.reg[88].loc.offset = (long) &sc->sc_sar - new_cfa;
+ fs->regs.reg[2].how = REG_SAVED_OFFSET;
+ fs->regs.reg[2].loc.offset = (long) &sc->sc_iaoq[0] - new_cfa;
+ fs->retaddr_column = 2;
+ return _URC_NO_REASON;
+}
diff --git a/gcc/config/pa/pa32-linux.h b/gcc/config/pa/pa32-linux.h
index 14cc2cf9159..07b680de88a 100644
--- a/gcc/config/pa/pa32-linux.h
+++ b/gcc/config/pa/pa32-linux.h
@@ -36,96 +36,4 @@ Boston, MA 02111-1307, USA. */
aligned(sizeof(func_ptr)))) \
= { (func_ptr) (-1) }
-/* Do code reading to identify a signal frame, and set the frame
- state data appropriately. See unwind-dw2.c for the structs. */
-
-#ifdef IN_LIBGCC2
-#include <signal.h>
-#include <sys/ucontext.h>
-
-/* Unfortunately, because of various bugs and changes to the kernel,
- we have several cases to deal with.
-
- In 2.4, the signal trampoline is 4 words, and (CONTEXT)->ra should
- point directly at the beginning of the trampoline and struct rt_sigframe.
-
- In <= 2.6.5-rc2-pa3, the signal trampoline is 9 words, and
- (CONTEXT)->ra points at the 4th word in the trampoline structure. This
- is wrong, it should point at the 5th word. This is fixed in 2.6.5-rc2-pa4.
-
- To detect these cases, we first take (CONTEXT)->ra, align it to 64-bytes
- to get the beginning of the signal frame, and then check offsets 0, 4
- and 5 to see if we found the beginning of the trampoline. This will
- tell us how to locate the sigcontext structure.
-
- Note that with a 2.4 64-bit kernel, the signal context is not properly
- passed back to userspace so the unwind will not work correctly. */
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
- do { \
- unsigned long sp = (unsigned long)(CONTEXT)->ra & ~63; \
- unsigned int *pc = (unsigned int *)sp; \
- unsigned long off; \
- _Unwind_Ptr new_cfa; \
- int i; \
- struct sigcontext *sc; \
- struct rt_sigframe { \
- struct siginfo info; \
- struct ucontext uc; \
- } *frame; \
- \
- /* rt_sigreturn trampoline: \
- 3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2) \
- 3414015a ldi __NR_rt_sigreturn, %r20 \
- e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31 \
- 08000240 nop */ \
- \
- if (pc[0] == 0x34190000 || pc[0] == 0x34190002) \
- off = 4*4; \
- else if (pc[4] == 0x34190000 || pc[4] == 0x34190002) \
- { \
- pc += 4; \
- off = 10 * 4; \
- } \
- else if (pc[5] == 0x34190000 || pc[5] == 0x34190002) \
- { \
- pc += 5; \
- off = 10 * 4; \
- } \
- else \
- break; \
- if (pc[1] != 0x3414015a \
- || pc[2] != 0xe4008200 \
- || pc[3] != 0x08000240) \
- break; \
- \
- frame = (struct rt_sigframe *)(sp + off); \
- sc = &frame->uc.uc_mcontext; \
- \
- new_cfa = sc->sc_gr[30]; \
- (FS)->cfa_how = CFA_REG_OFFSET; \
- (FS)->cfa_reg = 30; \
- (FS)->cfa_offset = new_cfa - (long) (CONTEXT)->cfa; \
- for (i = 1; i <= 31; i++) \
- { \
- (FS)->regs.reg[i].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[i].loc.offset = (long)&sc->sc_gr[i] - new_cfa; \
- } \
- for (i = 4; i <= 31; i++) \
- { \
- /* FP regs have left and right halves */ \
- (FS)->regs.reg[2*i+24].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[2*i+24].loc.offset \
- = (long)&sc->sc_fr[i] - new_cfa; \
- (FS)->regs.reg[2*i+24+1].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[2*i+24+1].loc.offset \
- = (long)&sc->sc_fr[i] + 4 - new_cfa; \
- } \
- (FS)->regs.reg[88].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[88].loc.offset = (long) &sc->sc_sar - new_cfa; \
- (FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[2].loc.offset = (long) &sc->sc_iaoq[0] - new_cfa; \
- (FS)->retaddr_column = 2; \
- goto SUCCESS; \
- } while (0)
-
-#endif /* IN_LIBGCC2 */
+#define MD_UNWIND_SUPPORT "config/pa/linux-unwind.h"