tm.texi (MD_UNWIND_SUPPORT): Document.

* 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.

From-SVN: r87167
This commit is contained in:
Alan Modra 2004-09-08 00:17:19 +00:00 committed by Alan Modra
parent a9e10feb68
commit 8662eb14c0
31 changed files with 1448 additions and 1353 deletions

View File

@ -1,3 +1,37 @@
2004-09-08 Alan Modra <amodra@bigpond.net.au>
* 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.
2004-09-07 Jan Hubicka <jh@suse.cz>
* cse.c (fold_rtx): Avoid building of

View File

@ -23,4 +23,4 @@
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
/* FIXME: Is a Hurd-specific fallback mechanism necessary? */
#undef MD_FALLBACK_FRAME_STATE_FOR
#undef MD_UNWIND_SUPPORT

View File

@ -0,0 +1,74 @@
/* DWARF2 EH unwinding support for Alpha 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>
#define MD_FALLBACK_FRAME_STATE_FOR alpha_fallback_frame_state
static _Unwind_Reason_Code
alpha_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned int *pc = context->ra;
struct sigcontext *sc;
long new_cfa, i;
if (pc[0] != 0x47fe0410 /* mov $30,$16 */
|| pc[2] != 0x00000083 /* callsys */)
return _URC_END_OF_STACK;
if (context->cfa == 0)
return _URC_END_OF_STACK;
if (pc[1] == 0x201f0067) /* lda $0,NR_sigreturn */
sc = context->cfa;
else if (pc[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */
{
struct rt_sigframe {
struct siginfo info;
struct ucontext uc;
} *rt_ = context->cfa;
sc = &rt_->uc.uc_mcontext;
}
else
return _URC_END_OF_STACK;
new_cfa = sc->sc_regs[30];
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 30;
fs->cfa_offset = new_cfa - (long) context->cfa;
for (i = 0; i < 30; ++i)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (long)&sc->sc_regs[i] - new_cfa;
}
for (i = 0; i < 31; ++i)
{
fs->regs.reg[i+32].how = REG_SAVED_OFFSET;
fs->regs.reg[i+32].loc.offset
= (long)&sc->sc_fpregs[i] - new_cfa;
}
fs->regs.reg[64].how = REG_SAVED_OFFSET;
fs->regs.reg[64].loc.offset = (long)&sc->sc_pc - new_cfa;
fs->retaddr_column = 64;
return _URC_NO_REASON;
}

View File

@ -76,55 +76,4 @@ Boston, MA 02111-1307, USA. */
#define USE_LD_AS_NEEDED 1
#endif
/* 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>
#endif
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned int *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_, i_; \
\
if (pc_[0] != 0x47fe0410 /* mov $30,$16 */ \
|| pc_[2] != 0x00000083 /* callsys */) \
break; \
if ((CONTEXT)->cfa == 0) \
break; \
if (pc_[1] == 0x201f0067) /* lda $0,NR_sigreturn */ \
sc_ = (CONTEXT)->cfa; \
else if (pc_[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ \
{ \
struct rt_sigframe { \
struct siginfo info; \
struct ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = &rt_->uc.uc_mcontext; \
} \
else \
break; \
new_cfa_ = sc_->sc_regs[30]; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 30; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
for (i_ = 0; i_ < 30; ++i_) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (long)&sc_->sc_regs[i_] - new_cfa_; \
} \
for (i_ = 0; i_ < 31; ++i_) \
{ \
(FS)->regs.reg[i_+32].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_+32].loc.offset \
= (long)&sc_->sc_fpregs[i_] - new_cfa_; \
} \
(FS)->regs.reg[64].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[64].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
(FS)->retaddr_column = 64; \
goto SUCCESS; \
} while (0)
#define MD_UNWIND_SUPPORT "config/alpha/linux-unwind.h"

View File

@ -0,0 +1,72 @@
/* DWARF2 EH unwinding support for Alpha VMS.
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. */
#include <pdscdef.h>
#define MD_FALLBACK_FRAME_STATE_FOR alpha_fallback_frame_state
static _Unwind_Reason_Code
alpha_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
PDSCDEF *pv = *((PDSCDEF **) context->reg [29]);
if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */
pv = *(PDSCDEF **) pv;
if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK))
{
int i, j;
fs->cfa_offset = pv->pdsc$l_size;
fs->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
fs->retaddr_column = 26;
fs->cfa_how = CFA_REG_OFFSET;
fs->regs.reg[27].loc.offset = -pv->pdsc$l_size;
fs->regs.reg[27].how = REG_SAVED_OFFSET;
fs->regs.reg[26].loc.offset
= -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset);
fs->regs.reg[26].how = REG_SAVED_OFFSET;
for (i = 0, j = 0; i < 32; i++)
if (1<<i & pv->pdsc$l_ireg_mask)
{
fs->regs.reg[i].loc.offset
= -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j);
fs->regs.reg[i].how = REG_SAVED_OFFSET;
}
return _URC_NO_REASON;
}
else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER))
{
fs->cfa_offset = pv->pdsc$l_size;
fs->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
fs->retaddr_column = 26;
fs->cfa_how = CFA_REG_OFFSET;
fs->regs.reg[26].loc.reg = pv->pdsc$b_save_ra;
fs->regs.reg[26].how = REG_SAVED_REG;
fs->regs.reg[29].loc.reg = pv->pdsc$b_save_fp;
fs->regs.reg[29].how = REG_SAVED_REG;
return _URC_NO_REASON;
}
return _URC_END_OF_STACK;
}

View File

@ -318,55 +318,7 @@ do { \
#define LINK_EH_SPEC "vms-dwarf2eh.o%s "
#ifdef IN_LIBGCC2
#include <pdscdef.h>
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
PDSCDEF *pv = *((PDSCDEF **) (CONTEXT)->reg [29]); \
\
if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */ \
pv = *(PDSCDEF **) pv; \
\
if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK)) \
{ \
int i, j; \
\
(FS)->cfa_offset = pv->pdsc$l_size; \
(FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
(FS)->retaddr_column = 26; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->regs.reg[27].loc.offset = -pv->pdsc$l_size; \
(FS)->regs.reg[27].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[26].loc.offset \
= -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset); \
(FS)->regs.reg[26].how = REG_SAVED_OFFSET; \
\
for (i = 0, j = 0; i < 32; i++) \
if (1<<i & pv->pdsc$l_ireg_mask) \
{ \
(FS)->regs.reg[i].loc.offset \
= -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j); \
(FS)->regs.reg[i].how = REG_SAVED_OFFSET; \
} \
\
goto SUCCESS; \
} \
else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER)) \
{ \
(FS)->cfa_offset = pv->pdsc$l_size; \
(FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
(FS)->retaddr_column = 26; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->regs.reg[26].loc.reg = pv->pdsc$b_save_ra; \
(FS)->regs.reg[26].how = REG_SAVED_REG; \
(FS)->regs.reg[29].loc.reg = pv->pdsc$b_save_fp; \
(FS)->regs.reg[29].how = REG_SAVED_REG; \
\
goto SUCCESS; \
} \
} while (0)
#endif
#define MD_UNWIND_SUPPORT "config/alpha/vms-unwind.h"
/* This is how to output an assembler line
that says to advance the location counter

View File

@ -40,4 +40,4 @@
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
/* FIXME: Is a Hurd-specific fallback mechanism necessary? */
#undef MD_FALLBACK_FRAME_STATE_FOR
#undef MD_UNWIND_SUPPORT

View File

@ -0,0 +1,165 @@
/* DWARF2 EH unwinding support for AMD x86-64 and x86.
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.
Don't use this at all if inhibit_libc is used. */
#ifndef inhibit_libc
#ifdef __x86_64__
#include <signal.h>
#include <sys/ucontext.h>
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
static _Unwind_Reason_Code
x86_64_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned char *pc = context->ra;
struct sigcontext *sc;
long new_cfa;
/* movq __NR_rt_sigreturn, %rax ; syscall */
if (*(unsigned char *)(pc+0) == 0x48
&& *(unsigned long *)(pc+1) == 0x050f0000000fc0c7)
{
struct ucontext *uc_ = context->cfa;
sc = (struct sigcontext *) &uc_->uc_mcontext;
}
else
return _URC_END_OF_STACK;
new_cfa = sc->rsp;
fs->cfa_how = CFA_REG_OFFSET;
/* Register 7 is rsp */
fs->cfa_reg = 7;
fs->cfa_offset = new_cfa - (long) context->cfa;
/* The SVR4 register numbering macros aren't usable in libgcc. */
fs->regs.reg[0].how = REG_SAVED_OFFSET;
fs->regs.reg[0].loc.offset = (long)&sc->rax - new_cfa;
fs->regs.reg[1].how = REG_SAVED_OFFSET;
fs->regs.reg[1].loc.offset = (long)&sc->rdx - new_cfa;
fs->regs.reg[2].how = REG_SAVED_OFFSET;
fs->regs.reg[2].loc.offset = (long)&sc->rcx - new_cfa;
fs->regs.reg[3].how = REG_SAVED_OFFSET;
fs->regs.reg[3].loc.offset = (long)&sc->rbx - new_cfa;
fs->regs.reg[4].how = REG_SAVED_OFFSET;
fs->regs.reg[4].loc.offset = (long)&sc->rsi - new_cfa;
fs->regs.reg[5].how = REG_SAVED_OFFSET;
fs->regs.reg[5].loc.offset = (long)&sc->rdi - new_cfa;
fs->regs.reg[6].how = REG_SAVED_OFFSET;
fs->regs.reg[6].loc.offset = (long)&sc->rbp - new_cfa;
fs->regs.reg[8].how = REG_SAVED_OFFSET;
fs->regs.reg[8].loc.offset = (long)&sc->r8 - new_cfa;
fs->regs.reg[9].how = REG_SAVED_OFFSET;
fs->regs.reg[9].loc.offset = (long)&sc->r9 - new_cfa;
fs->regs.reg[10].how = REG_SAVED_OFFSET;
fs->regs.reg[10].loc.offset = (long)&sc->r10 - new_cfa;
fs->regs.reg[11].how = REG_SAVED_OFFSET;
fs->regs.reg[11].loc.offset = (long)&sc->r11 - new_cfa;
fs->regs.reg[12].how = REG_SAVED_OFFSET;
fs->regs.reg[12].loc.offset = (long)&sc->r12 - new_cfa;
fs->regs.reg[13].how = REG_SAVED_OFFSET;
fs->regs.reg[13].loc.offset = (long)&sc->r13 - new_cfa;
fs->regs.reg[14].how = REG_SAVED_OFFSET;
fs->regs.reg[14].loc.offset = (long)&sc->r14 - new_cfa;
fs->regs.reg[15].how = REG_SAVED_OFFSET;
fs->regs.reg[15].loc.offset = (long)&sc->r15 - new_cfa;
fs->regs.reg[16].how = REG_SAVED_OFFSET;
fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
fs->retaddr_column = 16;
return _URC_NO_REASON;
}
#else /* ifdef __x86_64__ */
/* There's no sys/ucontext.h for glibc 2.0, so no
signal-turned-exceptions for them. There's also no configure-run for
the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
target libc version macro should be enough. */
#if !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
#include <signal.h>
#include <sys/ucontext.h>
#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
static _Unwind_Reason_Code
x86_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned char *pc = context->ra;
struct sigcontext *sc;
long new_cfa;
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */
if (*(unsigned short *)(pc+0) == 0xb858
&& *(unsigned int *)(pc+2) == 119
&& *(unsigned short *)(pc+6) == 0x80cd)
sc = context->cfa + 4;
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */
else if (*(unsigned char *)(pc+0) == 0xb8
&& *(unsigned int *)(pc+1) == 173
&& *(unsigned short *)(pc+5) == 0x80cd)
{
struct rt_sigframe {
int sig;
struct siginfo *pinfo;
void *puc;
struct siginfo info;
struct ucontext uc;
} *rt_ = context->cfa;
sc = (struct sigcontext *) &rt_->uc.uc_mcontext;
}
else
return _URC_END_OF_STACK;
new_cfa = sc->esp;
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 4;
fs->cfa_offset = new_cfa - (long) context->cfa;
/* The SVR4 register numbering macros aren't usable in libgcc. */
fs->regs.reg[0].how = REG_SAVED_OFFSET;
fs->regs.reg[0].loc.offset = (long)&sc->eax - new_cfa;
fs->regs.reg[3].how = REG_SAVED_OFFSET;
fs->regs.reg[3].loc.offset = (long)&sc->ebx - new_cfa;
fs->regs.reg[1].how = REG_SAVED_OFFSET;
fs->regs.reg[1].loc.offset = (long)&sc->ecx - new_cfa;
fs->regs.reg[2].how = REG_SAVED_OFFSET;
fs->regs.reg[2].loc.offset = (long)&sc->edx - new_cfa;
fs->regs.reg[6].how = REG_SAVED_OFFSET;
fs->regs.reg[6].loc.offset = (long)&sc->esi - new_cfa;
fs->regs.reg[7].how = REG_SAVED_OFFSET;
fs->regs.reg[7].loc.offset = (long)&sc->edi - new_cfa;
fs->regs.reg[5].how = REG_SAVED_OFFSET;
fs->regs.reg[5].loc.offset = (long)&sc->ebp - new_cfa;
fs->regs.reg[8].how = REG_SAVED_OFFSET;
fs->regs.reg[8].loc.offset = (long)&sc->eip - new_cfa;
fs->retaddr_column = 8;
return _URC_NO_REASON;
}
#endif /* not glibc 2.0 */
#endif /* ifdef __x86_64__ */
#endif /* ifdef inhibit_libc */

View File

@ -181,72 +181,4 @@ Boston, MA 02111-1307, USA. */
#undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 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
/* There's no sys/ucontext.h for glibc 2.0, so no
signal-turned-exceptions for them. There's also no configure-run for
the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
target libc version macro should be enough. */
#if !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
#include <signal.h>
#include <sys/ucontext.h>
#define REG_NAME(reg) reg
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
\
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \
if (*(unsigned short *)(pc_+0) == 0xb858 \
&& *(unsigned int *)(pc_+2) == 119 \
&& *(unsigned short *)(pc_+6) == 0x80cd) \
sc_ = (CONTEXT)->cfa + 4; \
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \
else if (*(unsigned char *)(pc_+0) == 0xb8 \
&& *(unsigned int *)(pc_+1) == 173 \
&& *(unsigned short *)(pc_+5) == 0x80cd) \
{ \
struct rt_sigframe { \
int sig; \
struct siginfo *pinfo; \
void *puc; \
struct siginfo info; \
struct ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->REG_NAME(esp); \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 4; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = (long)&sc_->REG_NAME(eax) - new_cfa_; \
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[3].loc.offset = (long)&sc_->REG_NAME(ebx) - new_cfa_; \
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[1].loc.offset = (long)&sc_->REG_NAME(ecx) - new_cfa_; \
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[2].loc.offset = (long)&sc_->REG_NAME(edx) - new_cfa_; \
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[6].loc.offset = (long)&sc_->REG_NAME(esi) - new_cfa_; \
(FS)->regs.reg[7].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[7].loc.offset = (long)&sc_->REG_NAME(edi) - new_cfa_; \
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[5].loc.offset = (long)&sc_->REG_NAME(ebp) - new_cfa_; \
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[8].loc.offset = (long)&sc_->REG_NAME(eip) - new_cfa_; \
(FS)->retaddr_column = 8; \
goto SUCCESS; \
} while (0)
#endif /* not glibc 2.0 */
#endif /* IN_LIBGCC2 */
#define MD_UNWIND_SUPPORT "config/i386/linux-unwind.h"

View File

@ -69,128 +69,4 @@ Boston, MA 02111-1307, USA. */
#undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 1
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs.
Don't use this at all if inhibit_libc is used. */
#ifndef inhibit_libc
#ifdef IN_LIBGCC2
#include <signal.h>
#include <sys/ucontext.h>
#endif
#ifdef __x86_64__
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
\
/* movq __NR_rt_sigreturn, %rax ; syscall */ \
if (*(unsigned char *)(pc_+0) == 0x48 \
&& *(unsigned long *)(pc_+1) == 0x050f0000000fc0c7) \
{ \
struct ucontext *uc_ = (CONTEXT)->cfa; \
sc_ = (struct sigcontext *) &uc_->uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->rsp; \
(FS)->cfa_how = CFA_REG_OFFSET; \
/* Register 7 is rsp */ \
(FS)->cfa_reg = 7; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = (long)&sc_->rax - new_cfa_; \
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[1].loc.offset = (long)&sc_->rdx - new_cfa_; \
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[2].loc.offset = (long)&sc_->rcx - new_cfa_; \
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[3].loc.offset = (long)&sc_->rbx - new_cfa_; \
(FS)->regs.reg[4].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[4].loc.offset = (long)&sc_->rsi - new_cfa_; \
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[5].loc.offset = (long)&sc_->rdi - new_cfa_; \
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[6].loc.offset = (long)&sc_->rbp - new_cfa_; \
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[8].loc.offset = (long)&sc_->r8 - new_cfa_; \
(FS)->regs.reg[9].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[9].loc.offset = (long)&sc_->r9 - new_cfa_; \
(FS)->regs.reg[10].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[10].loc.offset = (long)&sc_->r10 - new_cfa_; \
(FS)->regs.reg[11].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[11].loc.offset = (long)&sc_->r11 - new_cfa_; \
(FS)->regs.reg[12].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[12].loc.offset = (long)&sc_->r12 - new_cfa_; \
(FS)->regs.reg[13].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[13].loc.offset = (long)&sc_->r13 - new_cfa_; \
(FS)->regs.reg[14].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[14].loc.offset = (long)&sc_->r14 - new_cfa_; \
(FS)->regs.reg[15].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[15].loc.offset = (long)&sc_->r15 - new_cfa_; \
(FS)->regs.reg[16].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[16].loc.offset = (long)&sc_->rip - new_cfa_; \
(FS)->retaddr_column = 16; \
goto SUCCESS; \
} while (0)
#else /* ifdef __x86_64__ */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
\
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \
if (*(unsigned short *)(pc_+0) == 0xb858 \
&& *(unsigned int *)(pc_+2) == 119 \
&& *(unsigned short *)(pc_+6) == 0x80cd) \
sc_ = (CONTEXT)->cfa + 4; \
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \
else if (*(unsigned char *)(pc_+0) == 0xb8 \
&& *(unsigned int *)(pc_+1) == 173 \
&& *(unsigned short *)(pc_+5) == 0x80cd) \
{ \
struct rt_sigframe { \
int sig; \
struct siginfo *pinfo; \
void *puc; \
struct siginfo info; \
struct ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->esp; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 4; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \
(FS)->regs.reg[7].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \
(FS)->retaddr_column = 8; \
goto SUCCESS; \
} while (0)
#endif /* ifdef __x86_64__ */
#endif /* ifdef inhibit_libc */
#define MD_UNWIND_SUPPORT "config/i386/linux-unwind.h"

View File

@ -0,0 +1,185 @@
/* DWARF2 EH unwinding support for IA64 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. */
/* This works only for glibc-2.3 and later, because sigcontext is different
in glibc-2.2.4. */
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
#include <signal.h>
#include <sys/ucontext.h>
#define IA64_GATE_AREA_START 0xa000000000000100LL
#define IA64_GATE_AREA_END 0xa000000000030000LL
#define MD_FALLBACK_FRAME_STATE_FOR ia64_fallback_frame_state
static _Unwind_Reason_Code
ia64_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
if (context->rp >= IA64_GATE_AREA_START
&& context->rp < IA64_GATE_AREA_END)
{
struct sigframe {
char scratch[16];
unsigned long sig_number;
struct siginfo *info;
struct sigcontext *sc;
} *frame_ = (struct sigframe *)context->psp;
struct sigcontext *sc = frame_->sc;
/* Restore scratch registers in case the unwinder needs to
refer to a value stored in one of them. */
{
int i;
for (i = 2; i < 4; i++)
context->ireg[i - 2].loc = &sc->sc_gr[i];
for (i = 8; i < 12; i++)
context->ireg[i - 2].loc = &sc->sc_gr[i];
for (i = 14; i < 32; i++)
context->ireg[i - 2].loc = &sc->sc_gr[i];
}
context->fpsr_loc = &(sc->sc_ar_fpsr);
context->pfs_loc = &(sc->sc_ar_pfs);
context->lc_loc = &(sc->sc_ar_lc);
context->unat_loc = &(sc->sc_ar_unat);
context->br_loc[0] = &(sc->sc_br[0]);
context->br_loc[6] = &(sc->sc_br[6]);
context->br_loc[7] = &(sc->sc_br[7]);
context->pr = sc->sc_pr;
context->psp = sc->sc_gr[12];
context->gp = sc->sc_gr[1];
/* Signal frame doesn't have an associated reg. stack frame
other than what we adjust for below. */
fs -> no_reg_stack_frame = 1;
if (sc->sc_rbs_base)
{
/* Need to switch from alternate register backing store. */
long ndirty, loadrs = sc->sc_loadrs >> 16;
unsigned long alt_bspstore = context->bsp - loadrs;
unsigned long bspstore;
unsigned long *ar_bsp = (unsigned long *)(sc->sc_ar_bsp);
ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore,
(unsigned long *) context->bsp);
bspstore = (unsigned long)
ia64_rse_skip_regs (ar_bsp, -ndirty);
ia64_copy_rbs (context, bspstore, alt_bspstore, loadrs,
sc->sc_ar_rnat);
}
/* Don't touch the branch registers o.t. b0, b6 and b7.
The kernel doesn't pass the preserved branch registers
in the sigcontext but leaves them intact, so there's no
need to do anything with them here. */
{
unsigned long sof = sc->sc_cfm & 0x7f;
context->bsp = (unsigned long)
ia64_rse_skip_regs ((unsigned long *)(sc->sc_ar_bsp), -sof);
}
fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL;
fs->curr.reg[UNW_REG_RP].val
= (unsigned long)&(sc->sc_ip) - context->psp;
fs->curr.reg[UNW_REG_RP].when = -1;
return _URC_NO_REASON;
}
return _URC_END_OF_STACK;
}
#define MD_HANDLE_UNWABI ia64_handle_unwabi
static void
ia64_handle_unwabi (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
if (fs->unwabi == ((3 << 8) | 's')
|| fs->unwabi == ((0 << 8) | 's'))
{
struct sigframe {
char scratch[16];
unsigned long sig_number;
struct siginfo *info;
struct sigcontext *sc;
} *frame = (struct sigframe *)context->psp;
struct sigcontext *sc = frame->sc;
/* Restore scratch registers in case the unwinder needs to
refer to a value stored in one of them. */
{
int i;
for (i = 2; i < 4; i++)
context->ireg[i - 2].loc = &sc->sc_gr[i];
for (i = 8; i < 12; i++)
context->ireg[i - 2].loc = &sc->sc_gr[i];
for (i = 14; i < 32; i++)
context->ireg[i - 2].loc = &sc->sc_gr[i];
}
context->pfs_loc = &(sc->sc_ar_pfs);
context->lc_loc = &(sc->sc_ar_lc);
context->unat_loc = &(sc->sc_ar_unat);
context->br_loc[0] = &(sc->sc_br[0]);
context->br_loc[6] = &(sc->sc_br[6]);
context->br_loc[7] = &(sc->sc_br[7]);
context->pr = sc->sc_pr;
context->gp = sc->sc_gr[1];
/* Signal frame doesn't have an associated reg. stack frame
other than what we adjust for below. */
fs -> no_reg_stack_frame = 1;
if (sc->sc_rbs_base)
{
/* Need to switch from alternate register backing store. */
long ndirty, loadrs = sc->sc_loadrs >> 16;
unsigned long alt_bspstore = context->bsp - loadrs;
unsigned long bspstore;
unsigned long *ar_bsp = (unsigned long *)(sc->sc_ar_bsp);
ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore,
(unsigned long *) context->bsp);
bspstore = (unsigned long) ia64_rse_skip_regs (ar_bsp, -ndirty);
ia64_copy_rbs (context, bspstore, alt_bspstore, loadrs,
sc->sc_ar_rnat);
}
/* Don't touch the branch registers o.t. b0, b6 and b7.
The kernel doesn't pass the preserved branch registers
in the sigcontext but leaves them intact, so there's no
need to do anything with them here. */
{
unsigned long sof = sc->sc_cfm & 0x7f;
context->bsp = (unsigned long)
ia64_rse_skip_regs ((unsigned long *)(sc->sc_ar_bsp), -sof);
}
/* pfs_loc already set above. Without this pfs_loc would point
incorrectly to sc_cfm instead of sc_ar_pfs. */
fs->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE;
}
}
#endif /* glibc-2.3 or better */

View File

@ -55,161 +55,4 @@ do { \
#undef LINK_EH_SPEC
#define LINK_EH_SPEC ""
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
/* This works only for glibc-2.3 and later, because sigcontext is different
in glibc-2.2.4. */
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
#ifdef IN_LIBGCC2
#include <signal.h>
#include <sys/ucontext.h>
#define IA64_GATE_AREA_START 0xa000000000000100LL
#define IA64_GATE_AREA_END 0xa000000000030000LL
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
if ((CONTEXT)->rp >= IA64_GATE_AREA_START \
&& (CONTEXT)->rp < IA64_GATE_AREA_END) \
{ \
struct sigframe { \
char scratch[16]; \
unsigned long sig_number; \
struct siginfo *info; \
struct sigcontext *sc; \
} *frame_ = (struct sigframe *)(CONTEXT)->psp; \
struct sigcontext *sc_ = frame_->sc; \
\
/* Restore scratch registers in case the unwinder needs to \
refer to a value stored in one of them. */ \
{ \
int i_; \
\
for (i_ = 2; i_ < 4; i_++) \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
for (i_ = 8; i_ < 12; i_++) \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
for (i_ = 14; i_ < 32; i_++) \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
} \
\
(CONTEXT)->fpsr_loc = &(sc_->sc_ar_fpsr); \
(CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
(CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
(CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
(CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
(CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
(CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
(CONTEXT)->pr = sc_->sc_pr; \
(CONTEXT)->psp = sc_->sc_gr[12]; \
(CONTEXT)->gp = sc_->sc_gr[1]; \
/* Signal frame doesn't have an associated reg. stack frame \
other than what we adjust for below. */ \
(FS) -> no_reg_stack_frame = 1; \
\
if (sc_->sc_rbs_base) \
{ \
/* Need to switch from alternate register backing store. */ \
long ndirty, loadrs = sc_->sc_loadrs >> 16; \
unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
unsigned long bspstore; \
unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
\
ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
(unsigned long *) (CONTEXT)->bsp);\
bspstore = (unsigned long) \
ia64_rse_skip_regs (ar_bsp, -ndirty); \
ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
sc_->sc_ar_rnat); \
} \
\
/* Don't touch the branch registers o.t. b0, b6 and b7. \
The kernel doesn't pass the preserved branch registers \
in the sigcontext but leaves them intact, so there's no \
need to do anything with them here. */ \
{ \
unsigned long sof = sc_->sc_cfm & 0x7f; \
(CONTEXT)->bsp = (unsigned long) \
ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
} \
\
(FS)->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL; \
(FS)->curr.reg[UNW_REG_RP].val \
= (unsigned long)&(sc_->sc_ip) - (CONTEXT)->psp; \
(FS)->curr.reg[UNW_REG_RP].when = -1; \
\
goto SUCCESS; \
}
#define MD_HANDLE_UNWABI(CONTEXT, FS) \
if ((FS)->unwabi == ((3 << 8) | 's') \
|| (FS)->unwabi == ((0 << 8) | 's')) \
{ \
struct sigframe { \
char scratch[16]; \
unsigned long sig_number; \
struct siginfo *info; \
struct sigcontext *sc; \
} *frame_ = (struct sigframe *)(CONTEXT)->psp; \
struct sigcontext *sc_ = frame_->sc; \
\
/* Restore scratch registers in case the unwinder needs to \
refer to a value stored in one of them. */ \
{ \
int i_; \
\
for (i_ = 2; i_ < 4; i_++) \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
for (i_ = 8; i_ < 12; i_++) \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
for (i_ = 14; i_ < 32; i_++) \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
} \
\
(CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
(CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
(CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
(CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
(CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
(CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
(CONTEXT)->pr = sc_->sc_pr; \
(CONTEXT)->gp = sc_->sc_gr[1]; \
/* Signal frame doesn't have an associated reg. stack frame \
other than what we adjust for below. */ \
(FS) -> no_reg_stack_frame = 1; \
\
if (sc_->sc_rbs_base) \
{ \
/* Need to switch from alternate register backing store. */ \
long ndirty, loadrs = sc_->sc_loadrs >> 16; \
unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
unsigned long bspstore; \
unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
\
ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
(unsigned long *) (CONTEXT)->bsp);\
bspstore = (unsigned long) \
ia64_rse_skip_regs (ar_bsp, -ndirty); \
ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
sc_->sc_ar_rnat); \
} \
\
/* Don't touch the branch registers o.t. b0, b6 and b7. \
The kernel doesn't pass the preserved branch registers \
in the sigcontext but leaves them intact, so there's no \
need to do anything with them here. */ \
{ \
unsigned long sof = sc_->sc_cfm & 0x7f; \
(CONTEXT)->bsp = (unsigned long) \
ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
} \
\
/* pfs_loc already set above. Without this pfs_loc would point \
incorrectly to sc_cfm instead of sc_ar_pfs. */ \
(FS)->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE; \
}
#endif /* IN_LIBGCC2 */
#endif /* glibc-2.3 or better */
#define MD_UNWIND_SUPPORT "config/ia64/linux-unwind.h"

View File

@ -44,6 +44,7 @@
#undef ENABLE_MALLOC_CHECKING
#ifndef __USING_SJLJ_EXCEPTIONS__
#define UNW_VER(x) ((x) >> 48)
#define UNW_FLAG_MASK 0x0000ffff00000000
#define UNW_FLAG_OSMASK 0x0000f00000000000
@ -1754,6 +1755,9 @@ _Unwind_GetBSP (struct _Unwind_Context *context)
return (_Unwind_Ptr) context->bsp;
}
#ifdef MD_UNWIND_SUPPORT
#include MD_UNWIND_SUPPORT
#endif
static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
@ -1777,7 +1781,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
os-specific fallback mechanism. This will necessarily
not provide a personality routine or LSDA. */
#ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON)
return _URC_NO_REASON;
/* [SCRA 11.4.1] A leaf function with no memory stack, no exception
handlers, and which keeps the return value in B0 does not need
@ -1792,15 +1797,10 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
fs->curr.reg[UNW_REG_RP].when = -1;
fs->curr.reg[UNW_REG_RP].val = 0;
goto success;
return _URC_NO_REASON;
}
return _URC_END_OF_STACK;
success:
return _URC_NO_REASON;
#else
return _URC_END_OF_STACK;
#endif
return _URC_END_OF_STACK;
}
context->region_start = ent->start_offset + segment_base;

View File

@ -0,0 +1,93 @@
/* DWARF2 EH unwinding support for MIPS 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. */
#ifndef inhibit_libc
/* 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>
/* The third parameter to the signal handler points to something with
* this structure defined in asm/ucontext.h, but the name clashes with
* struct ucontext from sys/ucontext.h so this private copy is used. */
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct _sig_ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} _sig_ucontext_t;
#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
static _Unwind_Reason_Code
mips_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
u_int32_t *pc = (u_int32_t *) context->ra;
struct sigcontext *sc;
_Unwind_Ptr new_cfa;
int i;
/* 24021061 li v0, 0x1061 (rt_sigreturn)*/
/* 0000000c syscall */
/* or */
/* 24021017 li v0, 0x1017 (sigreturn) */
/* 0000000c syscall */
if (*(pc + 1) != 0x0000000c)
return _URC_END_OF_STACK;
if (*(pc + 0) == 0x24021017)
{
struct sigframe {
u_int32_t trampoline[2];
struct sigcontext sigctx;
} *rt_ = context->ra;
sc = &rt_->sigctx;
}
else if (*(pc + 0) == 0x24021061)
{
struct rt_sigframe {
u_int32_t trampoline[2];
struct siginfo info;
_sig_ucontext_t uc;
} *rt_ = context->ra;
sc = &rt_->uc.uc_mcontext;
}
else
return _URC_END_OF_STACK;
new_cfa = (_Unwind_Ptr)sc;
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = STACK_POINTER_REGNUM;
fs->cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
for (i = 0; i < 32; i++) {
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (_Unwind_Ptr)&(sc->sc_regs[i]) - new_cfa;
}
fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET;
fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset
= (_Unwind_Ptr)&(sc->sc_pc) - new_cfa;
fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
return _URC_NO_REASON;
}
#endif

View File

@ -183,74 +183,4 @@ Boston, MA 02111-1307, USA. */
%{!shared: %{pthread:-lpthread} \
%{profile:-lc_p} %{!profile: -lc}}"
#ifndef inhibit_libc
/* 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>
/* The third parameter to the signal handler points to something with
* this structure defined in asm/ucontext.h, but the name clashes with
* struct ucontext from sys/ucontext.h so this private copy is used. */
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct _sig_ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} _sig_ucontext_t;
#endif /* IN_LIBGCC2 */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
u_int32_t *pc_ = (u_int32_t *) (CONTEXT)->ra; \
struct sigcontext *sc_; \
_Unwind_Ptr new_cfa_; \
int i_; \
\
/* 24021061 li v0, 0x1061 (rt_sigreturn)*/ \
/* 0000000c syscall */ \
/* or */ \
/* 24021017 li v0, 0x1017 (sigreturn) */ \
/* 0000000c syscall */ \
if (*(pc_ + 1) != 0x0000000c) \
break; \
if (*(pc_ + 0) == 0x24021017) \
{ \
struct sigframe { \
u_int32_t trampoline[2]; \
struct sigcontext sigctx; \
} *rt_ = (CONTEXT)->ra; \
sc_ = &rt_->sigctx; \
} \
else if (*(pc_ + 0) == 0x24021061) \
{ \
struct rt_sigframe { \
u_int32_t trampoline[2]; \
struct siginfo info; \
_sig_ucontext_t uc; \
} *rt_ = (CONTEXT)->ra; \
sc_ = &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = (_Unwind_Ptr)sc_; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
(FS)->cfa_offset = new_cfa_ - (_Unwind_Ptr) (CONTEXT)->cfa; \
\
for (i_ = 0; i_ < 32; i_++) { \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (_Unwind_Ptr)&(sc_->sc_regs[i_]) - new_cfa_; \
} \
(FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset \
= (_Unwind_Ptr)&(sc_->sc_pc) - new_cfa_; \
(FS)->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN; \
\
goto SUCCESS; \
} while (0)
#endif
#define MD_UNWIND_SUPPORT "config/mips/linux-unwind.h"

View File

@ -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;
}

View File

@ -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"

View File

@ -0,0 +1,35 @@
/* DWARF2 EH unwinding support for Darwin.
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.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
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. */
extern bool _Unwind_fallback_frame_state_for
(struct _Unwind_Context *context, _Unwind_FrameState *fs);
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS) \
(_Unwind_fallback_frame_state_for (CONTEXT, FS) \
? _URC_NO_REASON : _URC_END_OF_STACK)

View File

@ -371,14 +371,7 @@ extern const char *darwin_one_byte_bool;
#include <stdbool.h>
#endif
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
{ \
extern bool _Unwind_fallback_frame_state_for \
(struct _Unwind_Context *context, _Unwind_FrameState *fs); \
\
if (_Unwind_fallback_frame_state_for (CONTEXT, FS)) \
goto SUCCESS; \
}
#define MD_UNWIND_SUPPORT "config/rs6000/darwin-unwind.h"
#define HAS_MD_FALLBACK_FRAME_STATE_FOR 1

View File

@ -0,0 +1,186 @@
/* DWARF2 EH unwinding support for PowerPC and PowerPC64 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. */
/* This file defines our own versions of various kernel and user
structs, so that system headers are not needed, which otherwise
can make bootstrapping a new toolchain difficult. Do not use
these structs elsewhere; Many fields are missing, particularly
from the end of the structures. */
struct gcc_pt_regs
{
unsigned long gpr[32];
unsigned long nip;
unsigned long msr;
unsigned long orig_gpr3;
unsigned long ctr;
unsigned long link;
};
struct gcc_sigcontext
{
unsigned long pad[7];
struct gcc_pt_regs *regs;
};
struct gcc_ucontext
{
#ifdef __powerpc64__
unsigned long pad[21];
#else
unsigned long pad[5];
#endif
struct gcc_sigcontext uc_mcontext;
};
#ifdef __powerpc64__
enum { SIGNAL_FRAMESIZE = 128 };
/* If the current unwind info (FS) does not contain explicit info
saving R2, then we have to do a minor amount of code reading to
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
#define MD_FROB_UPDATE_CONTEXT frob_update_context
static void
frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
if (fs->regs.reg[2].how == REG_UNSAVED)
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
if (*insn == 0xE8410028)
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
}
}
/* If PC is at a sigreturn trampoline, return a pointer to the
sigcontext. Otherwise return NULL. */
static struct gcc_sigcontext *
get_sigcontext (struct _Unwind_Context *context)
{
const unsigned char *pc = context->ra;
/* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */
/* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */
if (*(unsigned int *) (pc+0) != 0x38210000 + SIGNAL_FRAMESIZE
|| *(unsigned int *) (pc+8) != 0x44000002)
return NULL;
if (*(unsigned int *) (pc+4) == 0x38000077)
{
struct sigframe {
char gap[SIGNAL_FRAMESIZE];
struct gcc_sigcontext sigctx;
} *rt_ = context->cfa;
return &rt_->sigctx;
}
else if (*(unsigned int *) (pc+4) == 0x380000AC)
{
struct rt_sigframe {
int tramp[6];
void *pinfo;
struct gcc_ucontext *puc;
} *rt_ = (struct rt_sigframe *) pc;
return &rt_->puc->uc_mcontext;
}
return NULL;
}
#else /* !__powerpc64__ */
enum { SIGNAL_FRAMESIZE = 64 };
static struct gcc_sigcontext *
get_sigcontext (struct _Unwind_Context *context)
{
const unsigned char *pc = context->ra;
/* li r0, 0x7777; sc (sigreturn old) */
/* li r0, 0x0077; sc (sigreturn new) */
/* li r0, 0x6666; sc (rt_sigreturn old) */
/* li r0, 0x00AC; sc (rt_sigreturn new) */
if (*(unsigned int *) (pc+4) != 0x44000002)
return NULL;
if (*(unsigned int *) (pc+0) == 0x38007777
|| *(unsigned int *) (pc+0) == 0x38000077)
{
struct sigframe {
char gap[SIGNAL_FRAMESIZE];
struct gcc_sigcontext sigctx;
} *rt_ = context->cfa;
return &rt_->sigctx;
}
else if (*(unsigned int *) (pc+0) == 0x38006666
|| *(unsigned int *) (pc+0) == 0x380000AC)
{
struct rt_sigframe {
char gap[SIGNAL_FRAMESIZE + 16];
char siginfo[128];
struct gcc_ucontext uc;
} *rt_ = context->cfa;
return &rt_->uc.uc_mcontext;
}
return NULL;
}
#endif
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
#define MD_FALLBACK_FRAME_STATE_FOR ppc_fallback_frame_state
static _Unwind_Reason_Code
ppc_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
struct gcc_sigcontext *sc = get_sigcontext (context);
long new_cfa;
int i;
if (sc == NULL)
return _URC_END_OF_STACK;
new_cfa = sc->regs->gpr[STACK_POINTER_REGNUM];
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = STACK_POINTER_REGNUM;
fs->cfa_offset = new_cfa - (long) context->cfa;
for (i = 0; i < 32; i++)
if (i != STACK_POINTER_REGNUM)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (long)&(sc->regs->gpr[i]) - new_cfa;
}
fs->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;
fs->regs.reg[LINK_REGISTER_REGNUM].loc.offset
= (long)&(sc->regs->link) - new_cfa;
fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
fs->regs.reg[ARG_POINTER_REGNUM].loc.offset
= (long)&(sc->regs->nip) - new_cfa;
fs->retaddr_column = ARG_POINTER_REGNUM;
return _URC_NO_REASON;
}

View File

@ -98,88 +98,6 @@
#define TARGET_HAS_F_SETLKW
/* 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>
/* During the 2.5 kernel series the kernel ucontext was changed, but
the new layout is compatible with the old one, so we just define
and use the old one here for simplicity and compatibility. */
struct kernel_old_ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext_struct uc_mcontext;
sigset_t uc_sigmask;
};
enum { SIGNAL_FRAMESIZE = 64 };
#endif
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
int i_; \
\
/* li r0, 0x7777; sc (sigreturn old) */ \
/* li r0, 0x0077; sc (sigreturn new) */ \
/* li r0, 0x6666; sc (rt_sigreturn old) */ \
/* li r0, 0x00AC; sc (rt_sigreturn new) */ \
if (*(unsigned int *) (pc_+4) != 0x44000002) \
break; \
if (*(unsigned int *) (pc_+0) == 0x38007777 \
|| *(unsigned int *) (pc_+0) == 0x38000077) \
{ \
struct sigframe { \
char gap[SIGNAL_FRAMESIZE]; \
struct sigcontext sigctx; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = &rt_->sigctx; \
} \
else if (*(unsigned int *) (pc_+0) == 0x38006666 \
|| *(unsigned int *) (pc_+0) == 0x380000AC) \
{ \
struct rt_sigframe { \
char gap[SIGNAL_FRAMESIZE]; \
unsigned long _unused[2]; \
struct siginfo *pinfo; \
void *puc; \
struct siginfo info; \
struct kernel_old_ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
for (i_ = 0; i_ < 32; i_++) \
if (i_ != STACK_POINTER_REGNUM) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
} \
\
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
= (long)&(sc_->regs->link) - new_cfa_; \
\
(FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[CR0_REGNO].loc.offset \
= (long)&(sc_->regs->nip) - new_cfa_; \
(FS)->retaddr_column = CR0_REGNO; \
goto SUCCESS; \
} while (0)
#define MD_UNWIND_SUPPORT "config/rs6000/linux-unwind.h"
#define OS_MISSING_POWERPC64 1

View File

@ -557,185 +557,6 @@ while (0)
#define USE_LD_AS_NEEDED 1
#endif
#ifdef IN_LIBGCC2
/* This file defines our own versions of various kernel and user
structs, so that system headers are not needed, which otherwise
can make bootstrapping a new toolchain difficult. Do not use
these structs elsewhere; Many fields are missing, particularly
from the end of the structures. */
struct gcc_pt_regs
{
unsigned long gpr[32];
unsigned long nip;
unsigned long msr;
unsigned long orig_gpr3;
unsigned long ctr;
unsigned long link;
};
struct gcc_sigcontext
{
unsigned long pad[7];
struct gcc_pt_regs *regs;
};
struct gcc_ucontext
{
#ifdef __powerpc64__
unsigned long pad[21];
#else
unsigned long pad[5];
#endif
struct gcc_sigcontext uc_mcontext;
};
#ifdef __powerpc64__
enum { SIGNAL_FRAMESIZE = 128 };
/* If the current unwind info (FS) does not contain explicit info
saving R2, then we have to do a minor amount of code reading to
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
do { \
if ((FS)->regs.reg[2].how == REG_UNSAVED) \
{ \
unsigned int *insn \
= (unsigned int *) \
_Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
if (*insn == 0xE8410028) \
_Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
} \
} while (0)
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct gcc_sigcontext *sc_; \
long new_cfa_; \
int i_; \
\
/* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
/* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE \
|| *(unsigned int *) (pc_+8) != 0x44000002) \
break; \
if (*(unsigned int *) (pc_+4) == 0x38000077) \
{ \
struct sigframe { \
char gap[SIGNAL_FRAMESIZE]; \
struct gcc_sigcontext sigctx; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = &rt_->sigctx; \
} \
else if (*(unsigned int *) (pc_+4) == 0x380000AC) \
{ \
struct rt_sigframe { \
int tramp[6]; \
void *pinfo; \
struct gcc_ucontext *puc; \
} *rt_ = (struct rt_sigframe *) pc_; \
sc_ = &rt_->puc->uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
for (i_ = 0; i_ < 32; i_++) \
if (i_ != STACK_POINTER_REGNUM) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
} \
\
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
= (long)&(sc_->regs->link) - new_cfa_; \
\
(FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset \
= (long)&(sc_->regs->nip) - new_cfa_; \
(FS)->retaddr_column = ARG_POINTER_REGNUM; \
goto SUCCESS; \
} while (0)
#else /* !__powerpc64__ */
enum { SIGNAL_FRAMESIZE = 64 };
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct gcc_sigcontext *sc_; \
long new_cfa_; \
int i_; \
\
/* li r0, 0x7777; sc (sigreturn old) */ \
/* li r0, 0x0077; sc (sigreturn new) */ \
/* li r0, 0x6666; sc (rt_sigreturn old) */ \
/* li r0, 0x00AC; sc (rt_sigreturn new) */ \
if (*(unsigned int *) (pc_+4) != 0x44000002) \
break; \
if (*(unsigned int *) (pc_+0) == 0x38007777 \
|| *(unsigned int *) (pc_+0) == 0x38000077) \
{ \
struct sigframe { \
char gap[SIGNAL_FRAMESIZE]; \
struct gcc_sigcontext sigctx; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = &rt_->sigctx; \
} \
else if (*(unsigned int *) (pc_+0) == 0x38006666 \
|| *(unsigned int *) (pc_+0) == 0x380000AC) \
{ \
struct rt_sigframe { \
char gap[SIGNAL_FRAMESIZE + 16]; \
char siginfo[128]; \
struct gcc_ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
for (i_ = 0; i_ < 32; i_++) \
if (i_ != STACK_POINTER_REGNUM) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
} \
\
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
= (long)&(sc_->regs->link) - new_cfa_; \
\
(FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[CR0_REGNO].loc.offset \
= (long)&(sc_->regs->nip) - new_cfa_; \
(FS)->retaddr_column = CR0_REGNO; \
goto SUCCESS; \
} while (0)
#endif
#endif /* LIBGCC2 */
#define MD_UNWIND_SUPPORT "config/rs6000/linux-unwind.h"
#define OS_MISSING_POWERPC64 !TARGET_64BIT

View File

@ -0,0 +1,131 @@
/* DWARF2 EH unwinding support for S/390 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. */
#define MD_FALLBACK_FRAME_STATE_FOR s390_fallback_frame_state
static _Unwind_Reason_Code
s390_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned char *pc = context->ra;
long new_cfa;
int i;
typedef struct
{
unsigned long psw_mask;
unsigned long psw_addr;
unsigned long gprs[16];
unsigned int acrs[16];
unsigned int fpc;
unsigned int __pad;
double fprs[16];
} __attribute__ ((__aligned__ (8))) sigregs_;
sigregs_ *regs;
int *signo = NULL;
/* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */
if (pc[0] != 0x0a || (pc[1] != 119 && pc[1] != 173))
return _URC_END_OF_STACK;
/* New-style RT frame:
retcode + alignment (8 bytes)
siginfo (128 bytes)
ucontext (contains sigregs) */
if (context->ra == context->cfa)
{
struct ucontext_
{
unsigned long uc_flags;
struct ucontext_ *uc_link;
unsigned long uc_stack[3];
sigregs_ uc_mcontext;
} *uc = context->cfa + 8 + 128;
regs = &uc->uc_mcontext;
signo = context->cfa + sizeof(long);
}
/* Old-style RT frame and all non-RT frames:
old signal mask (8 bytes)
pointer to sigregs */
else
{
regs = *(sigregs_ **)(context->cfa + 8);
/* Recent kernels store the signal number immediately after
the sigregs; old kernels have the return trampoline at
this location. */
if ((void *)(regs + 1) != context->ra)
signo = (int *)(regs + 1);
}
new_cfa = regs->gprs[15] + 16*sizeof(long) + 32;
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 15;
fs->cfa_offset =
new_cfa - (long) context->cfa + 16*sizeof(long) + 32;
for (i = 0; i < 16; i++)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset =
(long)&regs->gprs[i] - new_cfa;
}
for (i = 0; i < 16; i++)
{
fs->regs.reg[16+i].how = REG_SAVED_OFFSET;
fs->regs.reg[16+i].loc.offset =
(long)&regs->fprs[i] - new_cfa;
}
/* Load return addr from PSW into dummy register 32. */
fs->regs.reg[32].how = REG_SAVED_OFFSET;
fs->regs.reg[32].loc.offset = (long)&regs->psw_addr - new_cfa;
fs->retaddr_column = 32;
/* If we got a SIGSEGV or a SIGBUS, the PSW address points *to*
the faulting instruction, not after it. This causes the logic
in unwind-dw2.c that decrements the RA to determine the correct
CFI region to get confused. To fix that, we *increment* the RA
here in that case. Note that we cannot modify the RA in place,
and the frame state wants a *pointer*, not a value; thus we put
the modified RA value into the unused register 33 slot of FS and
have the register 32 save address point to that slot.
Unfortunately, for regular signals on old kernels, we don't know
the signal number. We default to not fiddling with the RA;
that can fail in rare cases. Upgrade your kernel. */
if (signo && (*signo == 11 || *signo == 7))
{
fs->regs.reg[33].loc.exp =
(unsigned char *)regs->psw_addr + 1;
fs->regs.reg[32].loc.offset =
(long)&fs->regs.reg[33].loc.exp - new_cfa;
}
return _URC_NO_REASON;
}

View File

@ -92,112 +92,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
long new_cfa_; \
int i_; \
\
typedef struct \
{ \
unsigned long psw_mask; \
unsigned long psw_addr; \
unsigned long gprs[16]; \
unsigned int acrs[16]; \
unsigned int fpc; \
unsigned int __pad; \
double fprs[16]; \
} __attribute__ ((__aligned__ (8))) sigregs_; \
\
sigregs_ *regs_; \
int *signo_ = NULL; \
\
/* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */ \
if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173)) \
break; \
\
/* New-style RT frame: \
retcode + alignment (8 bytes) \
siginfo (128 bytes) \
ucontext (contains sigregs) */ \
if ((CONTEXT)->ra == (CONTEXT)->cfa) \
{ \
struct ucontext_ \
{ \
unsigned long uc_flags; \
struct ucontext_ *uc_link; \
unsigned long uc_stack[3]; \
sigregs_ uc_mcontext; \
} *uc_ = (CONTEXT)->cfa + 8 + 128; \
\
regs_ = &uc_->uc_mcontext; \
signo_ = (CONTEXT)->cfa + sizeof(long); \
} \
\
/* Old-style RT frame and all non-RT frames: \
old signal mask (8 bytes) \
pointer to sigregs */ \
else \
{ \
regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8); \
\
/* Recent kernels store the signal number immediately after \
the sigregs; old kernels have the return trampoline at \
this location. */ \
if ((void *)(regs_ + 1) != (CONTEXT)->ra) \
signo_ = (int *)(regs_ + 1); \
} \
\
new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 15; \
(FS)->cfa_offset = \
new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32; \
\
for (i_ = 0; i_ < 16; i_++) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset = \
(long)&regs_->gprs[i_] - new_cfa_; \
} \
for (i_ = 0; i_ < 16; i_++) \
{ \
(FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[16+i_].loc.offset = \
(long)&regs_->fprs[i_] - new_cfa_; \
} \
\
/* Load return addr from PSW into dummy register 32. */ \
\
(FS)->regs.reg[32].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[32].loc.offset = (long)&regs_->psw_addr - new_cfa_; \
(FS)->retaddr_column = 32; \
\
/* If we got a SIGSEGV or a SIGBUS, the PSW address points *to* \
the faulting instruction, not after it. This causes the logic \
in unwind-dw2.c that decrements the RA to determine the correct \
CFI region to get confused. To fix that, we *increment* the RA \
here in that case. Note that we cannot modify the RA in place, \
and the frame state wants a *pointer*, not a value; thus we put \
the modified RA value into the unused register 33 slot of FS and \
have the register 32 save address point to that slot. \
\
Unfortunately, for regular signals on old kernels, we don't know \
the signal number. We default to not fiddling with the RA; \
that can fail in rare cases. Upgrade your kernel. */ \
\
if (signo_ && (*signo_ == 11 || *signo_ == 7)) \
{ \
(FS)->regs.reg[33].loc.exp = \
(unsigned char *)regs_->psw_addr + 1; \
(FS)->regs.reg[32].loc.offset = \
(long)&(FS)->regs.reg[33].loc.exp - new_cfa_; \
} \
\
goto SUCCESS; \
} while (0)
#define MD_UNWIND_SUPPORT "config/s390/linux-unwind.h"
#endif

View File

@ -0,0 +1,167 @@
/* DWARF2 EH unwinding support for SH 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 this program; 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>
#include "insn-constants.h"
# if defined (__SH5__)
#define SH_DWARF_FRAME_GP0 0
#define SH_DWARF_FRAME_FP0 (__SH5__ == 32 ? 245 : 77)
#define SH_DWARF_FRAME_XD0 289
#define SH_DWARF_FRAME_BT0 68
#define SH_DWARF_FRAME_PR 241
#define SH_DWARF_FRAME_PR_MEDIA 18
#define SH_DWARF_FRAME_GBR 238
#define SH_DWARF_FRAME_MACH 239
#define SH_DWARF_FRAME_MACL 240
#define SH_DWARF_FRAME_PC 64
#define SH_DWARF_FRAME_SR 65
#define SH_DWARF_FRAME_FPUL 244
#define SH_DWARF_FRAME_FPSCR 243
#else
#define SH_DWARF_FRAME_GP0 0
#define SH_DWARF_FRAME_FP0 25
#define SH_DWARF_FRAME_XD0 87
#define SH_DWARF_FRAME_PR 17
#define SH_DWARF_FRAME_GBR 19
#define SH_DWARF_FRAME_MACH 20
#define SH_DWARF_FRAME_MACL 21
#define SH_DWARF_FRAME_PC 16
#define SH_DWARF_FRAME_SR 22
#define SH_DWARF_FRAME_FPUL 23
#define SH_DWARF_FRAME_FPSCR 24
#endif /* defined (__SH5__) */
#if defined (__SH5__)
/* MD_FALLBACK_FRAME_STATE_FOR is not yet defined for SHMEDIA. */
#else /* defined (__SH5__) */
#define MD_FALLBACK_FRAME_STATE_FOR sh_fallback_frame_state
static _Unwind_Reason_Code
sh_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned char *pc = context->ra;
struct sigcontext *sc;
long new_cfa;
int i;
#if defined (__SH3E__) || defined (__SH4__)
int r;
#endif
/* mov.w 1f,r3; trapa #0x10; 1: .short 0x77 (sigreturn) */
/* mov.w 1f,r3; trapa #0x10; 1: .short 0xad (rt_sigreturn) */
/* Newer kernel uses pad instructions to avoid an SH-4 core bug. */
/* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
or r0,r0; 1: .short 0x77 (sigreturn) */
/* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
or r0,r0; 1: .short 0xad (rt_sigreturn) */
if (((*(unsigned short *) (pc+0) == 0x9300)
&& (*(unsigned short *) (pc+2) == 0xc310)
&& (*(unsigned short *) (pc+4) == 0x0077))
|| (((*(unsigned short *) (pc+0) == 0x9305)
&& (*(unsigned short *) (pc+2) == 0xc310)
&& (*(unsigned short *) (pc+14) == 0x0077))))
sc = context->cfa;
else if (((*(unsigned short *) (pc+0) == 0x9300)
&& (*(unsigned short *) (pc+2) == 0xc310)
&& (*(unsigned short *) (pc+4) == 0x00ad))
|| (((*(unsigned short *) (pc+0) == 0x9305)
&& (*(unsigned short *) (pc+2) == 0xc310)
&& (*(unsigned short *) (pc+14) == 0x00ad))))
{
struct rt_sigframe {
struct siginfo info;
struct ucontext uc;
} *rt_ = context->cfa;
sc = (struct sigcontext *) &rt_->uc.uc_mcontext;
}
else
return _URC_END_OF_STACK;
new_cfa = sc->sc_regs[15];
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 15;
fs->cfa_offset = new_cfa - (long) context->cfa;
for (i = 0; i < 15; i++)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (long)&(sc->sc_regs[i]) - new_cfa;
}
fs->regs.reg[SH_DWARF_FRAME_PR].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_PR].loc.offset
= (long)&(sc->sc_pr) - new_cfa;
fs->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_SR].loc.offset
= (long)&(sc->sc_sr) - new_cfa;
fs->regs.reg[SH_DWARF_FRAME_GBR].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_GBR].loc.offset
= (long)&(sc->sc_gbr) - new_cfa;
fs->regs.reg[SH_DWARF_FRAME_MACH].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_MACH].loc.offset
= (long)&(sc->sc_mach) - new_cfa;
fs->regs.reg[SH_DWARF_FRAME_MACL].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_MACL].loc.offset
= (long)&(sc->sc_macl) - new_cfa;
#if defined (__SH3E__) || defined (__SH4__)
r = SH_DWARF_FRAME_FP0;
for (i = 0; i < 16; i++)
{
fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
fs->regs.reg[r+i].loc.offset
= (long)&(sc->sc_fpregs[i]) - new_cfa;
}
r = SH_DWARF_FRAME_XD0;
for (i = 0; i < 8; i++)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (long)&(sc->sc_xfpregs[2*i]) - new_cfa;
}
fs->regs.reg[SH_DWARF_FRAME_FPUL].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_FPUL].loc.offset
= (long)&(sc->sc_fpul) - new_cfa;
fs->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset
= (long)&(sc->sc_fpscr) - new_cfa;
#endif
/* The unwinder expects the PC to point to the following insn,
whereas the kernel returns the address of the actual
faulting insn. */
sc->sc_pc += 2;
fs->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_PC].loc.offset
= (long)&(sc->sc_pc) - new_cfa;
fs->retaddr_column = SH_DWARF_FRAME_PC;
return _URC_NO_REASON;
}
#endif /* defined (__SH5__) */

View File

@ -147,159 +147,7 @@ do { \
fprintf (STREAM, "2:\tlds.l\t@r15+,pr\n"); \
} while (0)
/* 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>
#include "insn-constants.h"
# if defined (__SH5__)
#define SH_DWARF_FRAME_GP0 0
#define SH_DWARF_FRAME_FP0 (__SH5__ == 32 ? 245 : 77)
#define SH_DWARF_FRAME_XD0 289
#define SH_DWARF_FRAME_BT0 68
#define SH_DWARF_FRAME_PR 241
#define SH_DWARF_FRAME_PR_MEDIA 18
#define SH_DWARF_FRAME_GBR 238
#define SH_DWARF_FRAME_MACH 239
#define SH_DWARF_FRAME_MACL 240
#define SH_DWARF_FRAME_PC 64
#define SH_DWARF_FRAME_SR 65
#define SH_DWARF_FRAME_FPUL 244
#define SH_DWARF_FRAME_FPSCR 243
#else
#define SH_DWARF_FRAME_GP0 0
#define SH_DWARF_FRAME_FP0 25
#define SH_DWARF_FRAME_XD0 87
#define SH_DWARF_FRAME_PR 17
#define SH_DWARF_FRAME_GBR 19
#define SH_DWARF_FRAME_MACH 20
#define SH_DWARF_FRAME_MACL 21
#define SH_DWARF_FRAME_PC 16
#define SH_DWARF_FRAME_SR 22
#define SH_DWARF_FRAME_FPUL 23
#define SH_DWARF_FRAME_FPSCR 24
#endif /* defined (__SH5__) */
#if defined (__SH5__)
/* MD_FALLBACK_FRAME_STATE_FOR is not yet defined for SHMEDIA. */
#else /* defined (__SH5__) */
#if defined (__SH3E__) || defined (__SH4__)
#define SH_FALLBACK_FRAME_FLOAT_STATE(SC, FS, CFA) \
do { \
int i_, r_; \
\
r_ = SH_DWARF_FRAME_FP0; \
for (i_ = 0; i_ < 16; i_++) \
{ \
(FS)->regs.reg[r_+i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[r_+i_].loc.offset \
= (long)&((SC)->sc_fpregs[i_]) - (CFA); \
} \
\
r_ = SH_DWARF_FRAME_XD0 ; \
for (i_ = 0; i_ < 8; i_++) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (long)&((SC)->sc_xfpregs[2*i_]) - (CFA); \
} \
\
(FS)->regs.reg[SH_DWARF_FRAME_FPUL].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_FPUL].loc.offset \
= (long)&((SC)->sc_fpul) - (CFA); \
(FS)->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset \
= (long)&((SC)->sc_fpscr) - (CFA); \
} while (0)
#else
#define SH_FALLBACK_FRAME_FLOAT_STATE(SC, FS, CFA)
#endif
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
int i_; \
\
/* mov.w 1f,r3; trapa #0x10; 1: .short 0x77 (sigreturn) */ \
/* mov.w 1f,r3; trapa #0x10; 1: .short 0xad (rt_sigreturn) */ \
/* Newer kernel uses pad instructions to avoid an SH-4 core bug. */\
/* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;\
or r0,r0; 1: .short 0x77 (sigreturn) */ \
/* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;\
or r0,r0; 1: .short 0xad (rt_sigreturn) */ \
if (((*(unsigned short *) (pc_+0) == 0x9300) \
&& (*(unsigned short *) (pc_+2) == 0xc310) \
&& (*(unsigned short *) (pc_+4) == 0x0077)) \
|| (((*(unsigned short *) (pc_+0) == 0x9305) \
&& (*(unsigned short *) (pc_+2) == 0xc310) \
&& (*(unsigned short *) (pc_+14) == 0x0077)))) \
sc_ = (CONTEXT)->cfa; \
else if (((*(unsigned short *) (pc_+0) == 0x9300) \
&& (*(unsigned short *) (pc_+2) == 0xc310) \
&& (*(unsigned short *) (pc_+4) == 0x00ad)) \
|| (((*(unsigned short *) (pc_+0) == 0x9305) \
&& (*(unsigned short *) (pc_+2) == 0xc310) \
&& (*(unsigned short *) (pc_+14) == 0x00ad)))) \
{ \
struct rt_sigframe { \
struct siginfo info; \
struct ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->sc_regs[15]; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 15; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
for (i_ = 0; i_ < 15; i_++) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset \
= (long)&(sc_->sc_regs[i_]) - new_cfa_; \
} \
\
(FS)->regs.reg[SH_DWARF_FRAME_PR].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_PR].loc.offset \
= (long)&(sc_->sc_pr) - new_cfa_; \
(FS)->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_SR].loc.offset \
= (long)&(sc_->sc_sr) - new_cfa_; \
(FS)->regs.reg[SH_DWARF_FRAME_GBR].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_GBR].loc.offset \
= (long)&(sc_->sc_gbr) - new_cfa_; \
(FS)->regs.reg[SH_DWARF_FRAME_MACH].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_MACH].loc.offset \
= (long)&(sc_->sc_mach) - new_cfa_; \
(FS)->regs.reg[SH_DWARF_FRAME_MACL].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_MACL].loc.offset \
= (long)&(sc_->sc_macl) - new_cfa_; \
\
SH_FALLBACK_FRAME_FLOAT_STATE(sc_, (FS), new_cfa_); \
\
/* The unwinder expects the PC to point to the following insn, \
whereas the kernel returns the address of the actual \
faulting insn. */ \
sc_->sc_pc += 2; \
(FS)->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[SH_DWARF_FRAME_PC].loc.offset \
= (long)&(sc_->sc_pc) - new_cfa_; \
(FS)->retaddr_column = SH_DWARF_FRAME_PC; \
goto SUCCESS; \
} while (0)
#endif /* defined (__SH5__) */
#endif /* IN_LIBGCC2 */
#define MD_UNWIND_SUPPORT "config/sh/linux-unwind.h"
/* For SH3 and SH4, we use a slot of the unwind frame which correspond
to a fake register number 16 as a placeholder for the return address

View File

@ -0,0 +1,150 @@
/* DWARF2 EH unwinding support for SPARC Linux.
Copyright 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. */
/* Handle multilib correctly. */
#if defined(__arch64__)
/* 64-bit SPARC version */
#define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
static _Unwind_Reason_Code
sparc64_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned int *pc = context->ra;
long new_cfa, i;
long regs_off, fpu_save_off;
long this_cfa, fpu_save;
if (pc[0] != 0x82102065 /* mov NR_rt_sigreturn, %g1 */
|| pc[1] != 0x91d0206d) /* ta 0x6d */
return _URC_END_OF_STACK;
regs_off = 192 + 128;
fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4);
this_cfa = (long) context->cfa;
new_cfa = *(long *)((context->cfa) + (regs_off + (14 * 8)));
new_cfa += 2047; /* Stack bias */
fpu_save = *(long *)((this_cfa) + (fpu_save_off));
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 14;
fs->cfa_offset = new_cfa - (long) context->cfa;
for (i = 1; i < 16; ++i)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset =
this_cfa + (regs_off + (i * 8)) - new_cfa;
}
for (i = 0; i < 16; ++i)
{
fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
fs->regs.reg[i + 16].loc.offset =
this_cfa + (i * 8) - new_cfa;
}
if (fpu_save)
{
for (i = 0; i < 64; ++i)
{
if (i > 32 && (i & 0x1))
continue;
fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
fs->regs.reg[i + 32].loc.offset =
(fpu_save + (i * 4)) - new_cfa;
}
}
/* Stick return address into %g0, same trick Alpha uses. */
fs->regs.reg[0].how = REG_SAVED_OFFSET;
fs->regs.reg[0].loc.offset =
this_cfa + (regs_off + (16 * 8) + 8) - new_cfa;
fs->retaddr_column = 0;
return _URC_NO_REASON;
}
#else
/* 32-bit SPARC version */
#define MD_FALLBACK_FRAME_STATE_FOR sparc_fallback_frame_state
static _Unwind_Reason_Code
sparc_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned int *pc = context->ra;
int new_cfa, i, oldstyle;
int regs_off, fpu_save_off;
int fpu_save, this_cfa;
if (pc[1] != 0x91d02010) /* ta 0x10 */
return _URC_END_OF_STACK;
if (pc[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */
oldstyle = 1;
else if (pc[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */
oldstyle = 0;
else
return _URC_END_OF_STACK;
if (oldstyle)
{
regs_off = 96;
fpu_save_off = regs_off + (4 * 4) + (16 * 4);
}
else
{
regs_off = 96 + 128;
fpu_save_off = regs_off + (4 * 4) + (16 * 4) + (2 * 4);
}
this_cfa = (int) context->cfa;
new_cfa = *(int *)((context->cfa) + (regs_off+(4*4)+(14 * 4)));
fpu_save = *(int *)((this_cfa) + (fpu_save_off));
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 14;
fs->cfa_offset = new_cfa - (int) context->cfa;
for (i = 1; i < 16; ++i)
{
if (i == 14)
continue;
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset =
this_cfa + (regs_off+(4 * 4)+(i * 4)) - new_cfa;
}
for (i = 0; i < 16; ++i)
{
fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
fs->regs.reg[i + 16].loc.offset =
this_cfa + (i * 4) - new_cfa;
}
if (fpu_save)
{
for (i = 0; i < 32; ++i)
{
fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
fs->regs.reg[i + 32].loc.offset =
(fpu_save + (i * 4)) - new_cfa;
}
}
/* Stick return address into %g0, same trick Alpha uses. */
fs->regs.reg[0].how = REG_SAVED_OFFSET;
fs->regs.reg[0].loc.offset = this_cfa+(regs_off+4)-new_cfa;
fs->retaddr_column = 0;
return _URC_NO_REASON;
}
#endif

View File

@ -228,66 +228,4 @@ do { \
#define USE_LD_AS_NEEDED 1
#endif
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned int *pc_ = (CONTEXT)->ra; \
int new_cfa_, i_, oldstyle_; \
int regs_off_, fpu_save_off_; \
int fpu_save_, this_cfa_; \
\
if (pc_[1] != 0x91d02010) /* ta 0x10 */ \
break; \
if (pc_[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */ \
oldstyle_ = 1; \
else if (pc_[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */ \
oldstyle_ = 0; \
else \
break; \
if (oldstyle_) \
{ \
regs_off_ = 96; \
fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4); \
} \
else \
{ \
regs_off_ = 96 + 128; \
fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4); \
} \
this_cfa_ = (int) (CONTEXT)->cfa; \
new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4))); \
fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_)); \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 14; \
(FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa; \
for (i_ = 1; i_ < 16; ++i_) \
{ \
if (i_ == 14) \
continue; \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset = \
this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_; \
} \
for (i_ = 0; i_ < 16; ++i_) \
{ \
(FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_ + 16].loc.offset = \
this_cfa_ + (i_ * 4) - new_cfa_; \
} \
if (fpu_save_) \
{ \
for (i_ = 0; i_ < 32; ++i_) \
{ \
(FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_ + 32].loc.offset = \
(fpu_save_ + (i_ * 4)) - new_cfa_; \
} \
} \
/* Stick return address into %g0, same trick Alpha uses. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_; \
(FS)->retaddr_column = 0; \
goto SUCCESS; \
} while (0)
#define MD_UNWIND_SUPPORT "config/sparc/linux-unwind.h"

View File

@ -366,121 +366,4 @@ do { \
#define USE_LD_AS_NEEDED 1
#endif
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
/* Handle multilib correctly. */
#if defined(__arch64__)
/* 64-bit SPARC version */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned int *pc_ = (CONTEXT)->ra; \
long new_cfa_, i_; \
long regs_off_, fpu_save_off_; \
long this_cfa_, fpu_save_; \
\
if (pc_[0] != 0x82102065 /* mov NR_rt_sigreturn, %g1 */ \
|| pc_[1] != 0x91d0206d) /* ta 0x6d */ \
break; \
regs_off_ = 192 + 128; \
fpu_save_off_ = regs_off_ + (16 * 8) + (3 * 8) + (2 * 4); \
this_cfa_ = (long) (CONTEXT)->cfa; \
new_cfa_ = *(long *)(((CONTEXT)->cfa) + (regs_off_ + (14 * 8))); \
new_cfa_ += 2047; /* Stack bias */ \
fpu_save_ = *(long *)((this_cfa_) + (fpu_save_off_)); \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 14; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
for (i_ = 1; i_ < 16; ++i_) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset = \
this_cfa_ + (regs_off_ + (i_ * 8)) - new_cfa_; \
} \
for (i_ = 0; i_ < 16; ++i_) \
{ \
(FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_ + 16].loc.offset = \
this_cfa_ + (i_ * 8) - new_cfa_; \
} \
if (fpu_save_) \
{ \
for (i_ = 0; i_ < 64; ++i_) \
{ \
if (i_ > 32 && (i_ & 0x1)) \
continue; \
(FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_ + 32].loc.offset = \
(fpu_save_ + (i_ * 4)) - new_cfa_; \
} \
} \
/* Stick return address into %g0, same trick Alpha uses. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = \
this_cfa_ + (regs_off_ + (16 * 8) + 8) - new_cfa_; \
(FS)->retaddr_column = 0; \
goto SUCCESS; \
} while (0)
#else
/* 32-bit SPARC version */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned int *pc_ = (CONTEXT)->ra; \
int new_cfa_, i_, oldstyle_; \
int regs_off_, fpu_save_off_; \
int fpu_save_, this_cfa_; \
\
if (pc_[1] != 0x91d02010) /* ta 0x10 */ \
break; \
if (pc_[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */ \
oldstyle_ = 1; \
else if (pc_[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */ \
oldstyle_ = 0; \
else \
break; \
if (oldstyle_) \
{ \
regs_off_ = 96; \
fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4); \
} \
else \
{ \
regs_off_ = 96 + 128; \
fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4); \
} \
this_cfa_ = (int) (CONTEXT)->cfa; \
new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4))); \
fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_)); \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 14; \
(FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa; \
for (i_ = 1; i_ < 16; ++i_) \
{ \
if (i_ == 14) \
continue; \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset = \
this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_; \
} \
for (i_ = 0; i_ < 16; ++i_) \
{ \
(FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_ + 16].loc.offset = \
this_cfa_ + (i_ * 4) - new_cfa_; \
} \
if (fpu_save_) \
{ \
for (i_ = 0; i_ < 32; ++i_) \
{ \
(FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_ + 32].loc.offset = \
(fpu_save_ + (i_ * 4)) - new_cfa_; \
} \
} \
/* Stick return address into %g0, same trick Alpha uses. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_; \
(FS)->retaddr_column = 0; \
goto SUCCESS; \
} while (0)
#endif
#define MD_UNWIND_SUPPORT "config/sparc/linux-unwind.h"

View File

@ -3094,7 +3094,12 @@ of bytes that the format occupies, @var{addr} is the @code{SYMBOL_REF}
to be emitted.
@end defmac
@defmac MD_FALLBACK_FRAME_STATE_FOR (@var{context}, @var{fs}, @var{success})
@defmac MD_UNWIND_SUPPORT
A string specifying a file to be #include'd in unwind-dw2.c. The file
so included typically defines @code{MD_FALLBACK_FRAME_STATE_FOR}.
@end defmac
@defmac MD_FALLBACK_FRAME_STATE_FOR (@var{context}, @var{fs})
This macro allows the target to add cpu and operating system specific
code to the call-frame unwinder for use when there is no unwind data
available. The most common reason to implement this macro is to unwind
@ -3105,9 +3110,9 @@ and @file{unwind-ia64.c}. @var{context} is an @code{_Unwind_Context};
@var{fs} is an @code{_Unwind_FrameState}. Examine @code{context->ra}
for the address of the code being executed and @code{context->cfa} for
the stack pointer value. If the frame can be decoded, the register save
addresses should be updated in @var{fs} and the macro should branch to
@var{success}. If the frame cannot be decoded, the macro should do
nothing.
addresses should be updated in @var{fs} and the macro should evaluate to
@code{_URC_NO_REASON}. If the frame cannot be decoded, the macro should
evaluate to @code{_URC_END_OF_STACK}.
For proper signal handling in Java this macro is accompanied by
@code{MAKE_THROW_FRAME}, defined in @file{libjava/include/*-signal.h} headers.

View File

@ -60,11 +60,6 @@
#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
#endif
/* A target can do some update context frobbing. */
#ifndef MD_FROB_UPDATE_CONTEXT
#define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
#endif
/* This is the register and unwind state for a particular frame. This
provides the information necessary to unwind up past a frame and return
to its caller. */
@ -252,6 +247,10 @@ _Unwind_GetTextRelBase (struct _Unwind_Context *context)
return (_Unwind_Ptr) context->bases.tbase;
}
#endif
#ifdef MD_UNWIND_SUPPORT
#include MD_UNWIND_SUPPORT
#endif
/* Extract any interesting information from the CIE for the translation
unit F belongs to. Return a pointer to the byte after the augmentation,
@ -963,14 +962,11 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
if (fde == NULL)
{
#ifdef MD_FALLBACK_FRAME_STATE_FOR
/* Couldn't find frame unwind info for this function. Try a
target-specific fallback mechanism. This will necessarily
not provide a personality routine or LSDA. */
#ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
return _URC_END_OF_STACK;
success:
return _URC_NO_REASON;
return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
#else
return _URC_END_OF_STACK;
#endif
@ -1176,7 +1172,9 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
break;
}
#ifdef MD_FROB_UPDATE_CONTEXT
MD_FROB_UPDATE_CONTEXT (context, fs);
#endif
}
/* CONTEXT describes the unwind state for a frame, and FS describes the FDE