diff options
author | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-09-08 00:17:19 +0000 |
---|---|---|
committer | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-09-08 00:17:19 +0000 |
commit | aebd6cb6ec855cc4f9a07a694847b4a19fe5759a (patch) | |
tree | f6927bd90fe84c682dd04619d255d6355aac36d5 /gcc/config/i386 | |
parent | 97307e4d7dc6478c0d70de1816c9009a100f5542 (diff) | |
download | gcc-aebd6cb6ec855cc4f9a07a694847b4a19fe5759a.tar.gz |
* doc/tm.texi (MD_UNWIND_SUPPORT): Document.
(MD_FALLBACK_FRAME_STATE_FOR): Update.
* unwind-dw2.c (MD_UNWIND_SUPPORT): #include if defined.
(uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation.
(MD_FROB_UPDATE_CONTEXT): Remove default.
(uw_update_context_1): Instead #ifdef invocation.
* config/ia64/unwind-ia64.c (MD_UNWIND_SUPPORT): #include if defined.
(uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation.
* config/alpha/gnu.h (MD_FALLBACK_FRAME_STATE_FOR): Don't undef.
(MD_UNWIND_SUPPORT): Undefine this instead.
* config/i386/gnu.h: Likewise.
* config/alpha/linux-unwind.h: New file, macro converted to
function, extracted from..
* config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): ..this.
(MD_UNWIND_SUPPORT): Define.
* config/alpha/vms-unwind.h, config/alpha/vms.h: Likewise.
* config/i386/linux-unwind.h, config/i386/linux.h,
config/i386/linux64.h: Likewise.
* config/ia64/linux-unwind.h, config/ia64/linux.h: Likewise.
MD_HANDLE_UNWABI too.
* config/mips/linux-unwind.h, config/mips/linux.h: Likewise.
* config/pa/linux-unwind.h, config/pa/pa32-linux.h: Likewise.
* config/rs6000/darwin-unwind.h, config/rs6000/darwin.h: Likewise.
* config/s390/linux-unwind.h, config/s390/linux.h: Likewise.
* config/sparc/linux-unwind.h, config/sparc/linux.h,
config/sparc/linux64.h: Likewise.
* config/sh/linux-unwind.h, config/sh/linux.h: Likewise, but merge
SH_FALLBACK_FRAME_FLOAT_STATE into sh_fallback_frame_state.
* config/rs6000/linux-unwind.h, config/rs6000/linux.h,
config/rs6000/linux64.h: Likewise. Split out get_sigcontext
function. Use ARG_POINTER_REGNUM for 32-bit temp reg too.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@87167 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386')
-rw-r--r-- | gcc/config/i386/gnu.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/linux-unwind.h | 165 | ||||
-rw-r--r-- | gcc/config/i386/linux.h | 70 | ||||
-rw-r--r-- | gcc/config/i386/linux64.h | 126 |
4 files changed, 168 insertions, 195 deletions
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h index cc9994bcaed..ce80c9821fd 100644 --- a/gcc/config/i386/gnu.h +++ b/gcc/config/i386/gnu.h @@ -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 diff --git a/gcc/config/i386/linux-unwind.h b/gcc/config/i386/linux-unwind.h new file mode 100644 index 00000000000..ecbce1d337c --- /dev/null +++ b/gcc/config/i386/linux-unwind.h @@ -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 */ diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h index 08b859ac310..e31c5114e93 100644 --- a/gcc/config/i386/linux.h +++ b/gcc/config/i386/linux.h @@ -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" diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h index 98536c19bd3..4838cf8fa8e 100644 --- a/gcc/config/i386/linux64.h +++ b/gcc/config/i386/linux64.h @@ -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" |