config.host (*-cygwin* |*-mingw* ): Add crtbegin.o, crtend.o to extra_parts.
ChangeLog/libgcc 2007-06-14 Danny Smith <dannysmith@users.sourceforge.net> * config.host(*-cygwin* |*-mingw* ): Add crtbegin.o, crtend.o to extra_parts. Add config/i386/t-cygming to tmake_file. * config/i386/t-cygming: New file with rules for crtbegin.o, crtend.o. ChangeLog/gcc 2007-06-14 Danny Smith <dannysmith@users.sourceforge.net> * config/i386/cygming.h (DWARF_FRAME_REGNUM): Define. (DWARF2_UNWIND_INFO): Override default if configured with SJLJ EH disabled. * config/i386/cygwin.h (STARTFILE_SPEC): Add crtbegin.o. (ENDFILE_SPEC): Add crtend.o. * config/i386/mingw32.h (STARTFILE_SEC): Add crtbegin.o. (ENDFILE_SPEC): Add crtend.o. (TARGET_USE_JCR_SECTION): Define. (MD_UNWIND_SUPPORT): Define for 32-bit target. * config/i386/cygming-crtbegin.c: New file. * config/i386/cygming-crtend.c: New file. 2007-06-14 Pascal Obry Pascal Obry <obry@adacore.com> * config/i386/w32-unwind.h: New file. From-SVN: r125696
This commit is contained in:
parent
ab47d43e01
commit
76f5e2005d
10 changed files with 509 additions and 9 deletions
|
@ -1,3 +1,22 @@
|
|||
2007-06-14 Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
* config/i386/cygming.h (DWARF_FRAME_REGNUM): Define.
|
||||
(DWARF2_UNWIND_INFO): Override default if configured with
|
||||
SJLJ EH disabled.
|
||||
* config/i386/cygwin.h (STARTFILE_SPEC): Add crtbegin.o.
|
||||
(ENDFILE_SPEC): Add crtend.o.
|
||||
* config/i386/mingw32.h (STARTFILE_SEC): Add crtbegin.o.
|
||||
(ENDFILE_SPEC): Add crtend.o.
|
||||
(TARGET_USE_JCR_SECTION): Define.
|
||||
(MD_UNWIND_SUPPORT): Define for 32-bit target.
|
||||
|
||||
* config/i386/cygming-crtbegin.c: New file.
|
||||
* config/i386/cygming-crtend.c: New file.
|
||||
|
||||
2007-06-14 Pascal Obry Pascal Obry <obry@adacore.com>
|
||||
|
||||
* config/i386/w32-unwind.h: New file.
|
||||
|
||||
2007-06-13 Eric Christopher <echristo@apple.com>
|
||||
|
||||
* config/i386/darwin.h (PREFERRED_STACK_BOUNDARY): Don't let
|
||||
|
|
140
gcc/config/i386/cygming-crtbegin.c
Executable file
140
gcc/config/i386/cygming-crtbegin.c
Executable file
|
@ -0,0 +1,140 @@
|
|||
/* crtbegin object for windows32 targets.
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
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 combine
|
||||
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. */
|
||||
|
||||
/* Target machine header files require this define. */
|
||||
#define IN_LIBGCC2
|
||||
|
||||
#include "auto-host.h"
|
||||
#include "tconfig.h"
|
||||
#include "tsystem.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef LIBGCC_SONAME
|
||||
#define LIBGCC_SONAME "libgcc_s.dll"
|
||||
#endif
|
||||
|
||||
#ifndef LIBGCJ_SONAME
|
||||
#define LIBGCJ_SONAME "libgcj_s.dll"
|
||||
#endif
|
||||
|
||||
|
||||
/* Make the declarations weak. This is critical for
|
||||
_Jv_RegisterClasses because it lives in libgcj.a */
|
||||
extern void __register_frame_info (const void *, struct object *)
|
||||
TARGET_ATTRIBUTE_WEAK;
|
||||
extern void *__deregister_frame_info (const void *)
|
||||
TARGET_ATTRIBUTE_WEAK;
|
||||
extern void _Jv_RegisterClasses (const void *) TARGET_ATTRIBUTE_WEAK;
|
||||
|
||||
#if defined(HAVE_LD_RO_RW_SECTION_MIXING)
|
||||
# define EH_FRAME_SECTION_CONST const
|
||||
#else
|
||||
# define EH_FRAME_SECTION_CONST
|
||||
#endif
|
||||
|
||||
/* Stick a label at the beginning of the frame unwind info so we can
|
||||
register/deregister it with the exception handling library code. */
|
||||
#if DWARF2_UNWIND_INFO
|
||||
static EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
|
||||
__attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
|
||||
= { };
|
||||
|
||||
static struct object obj;
|
||||
#endif
|
||||
|
||||
#if TARGET_USE_JCR_SECTION
|
||||
static void *__JCR_LIST__[]
|
||||
__attribute__ ((unused, section(JCR_SECTION_NAME), aligned(4)))
|
||||
= { };
|
||||
#endif
|
||||
|
||||
/* Pull in references from libgcc.a(unwind-dw2-fde.o) in the
|
||||
startfile. These are referenced by a ctor and dtor in crtend.o. */
|
||||
extern void __gcc_register_frame (void);
|
||||
extern void __gcc_deregister_frame (void);
|
||||
|
||||
void
|
||||
__gcc_register_frame (void)
|
||||
{
|
||||
#if DWARF2_UNWIND_INFO
|
||||
/* Weak undefined symbols won't be pulled in from dlls; hence
|
||||
we first test if the dll is already loaded and, if so,
|
||||
get the symbol's address at run-time. If the dll is not loaded,
|
||||
fallback to weak linkage to static archive. */
|
||||
|
||||
void (*register_frame_fn) (const void *, struct object *);
|
||||
HANDLE h = GetModuleHandle (LIBGCC_SONAME);
|
||||
if (h)
|
||||
register_frame_fn = (void (*) (const void *, struct object *))
|
||||
GetProcAddress (h, "__register_frame_info");
|
||||
else
|
||||
register_frame_fn = __register_frame_info;
|
||||
if (register_frame_fn)
|
||||
register_frame_fn (__EH_FRAME_BEGIN__, &obj);
|
||||
#endif
|
||||
|
||||
#if TARGET_USE_JCR_SECTION
|
||||
if (__JCR_LIST__[0])
|
||||
{
|
||||
void (*register_class_fn) (const void *);
|
||||
HANDLE h = GetModuleHandle (LIBGCJ_SONAME);
|
||||
if (h)
|
||||
register_class_fn = (void (*) (const void *))
|
||||
GetProcAddress (h, "_Jv_RegisterClasses");
|
||||
else
|
||||
register_class_fn = _Jv_RegisterClasses;
|
||||
|
||||
if (register_class_fn)
|
||||
register_class_fn (__JCR_LIST__);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
__gcc_deregister_frame (void)
|
||||
{
|
||||
#if DWARF2_UNWIND_INFO
|
||||
void * (*deregister_frame_fn) (const void *);
|
||||
HANDLE h = GetModuleHandle (LIBGCC_SONAME);
|
||||
if (h)
|
||||
deregister_frame_fn = (void* (*) (const void *))
|
||||
GetProcAddress (h, "__deregister_frame_info");
|
||||
else
|
||||
deregister_frame_fn = __deregister_frame_info;
|
||||
if (deregister_frame_fn)
|
||||
deregister_frame_fn (__EH_FRAME_BEGIN__);
|
||||
#endif
|
||||
}
|
86
gcc/config/i386/cygming-crtend.c
Executable file
86
gcc/config/i386/cygming-crtend.c
Executable file
|
@ -0,0 +1,86 @@
|
|||
/* crtend object for windows32 targets.
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
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 combine
|
||||
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. */
|
||||
|
||||
/* Target machine header files require this define. */
|
||||
#define IN_LIBGCC2
|
||||
|
||||
/* auto-host.h is needed by cygming.h for HAVE_GAS_WEAK and here
|
||||
for HAVE_LD_RO_RW_SECTION_MIXING. */
|
||||
#include "auto-host.h"
|
||||
#include "tconfig.h"
|
||||
#include "tsystem.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
|
||||
#if defined(HAVE_LD_RO_RW_SECTION_MIXING)
|
||||
# define EH_FRAME_SECTION_CONST const
|
||||
#else
|
||||
# define EH_FRAME_SECTION_CONST
|
||||
#endif
|
||||
|
||||
#if DWARF2_UNWIND_INFO
|
||||
/* Terminate the frame unwind info section with a 0 as a sentinel;
|
||||
this would be the 'length' field in a real FDE. */
|
||||
|
||||
static EH_FRAME_SECTION_CONST int __FRAME_END__[]
|
||||
__attribute__ ((unused, section(EH_FRAME_SECTION_NAME),
|
||||
aligned(4)))
|
||||
= { 0 };
|
||||
#endif
|
||||
|
||||
#if TARGET_USE_JCR_SECTION
|
||||
/* Null terminate the .jcr section array. */
|
||||
static void *__JCR_END__[1]
|
||||
__attribute__ ((unused, section(JCR_SECTION_NAME),
|
||||
aligned(sizeof(void *))))
|
||||
= { 0 };
|
||||
#endif
|
||||
|
||||
|
||||
extern void __gcc_register_frame (void);
|
||||
extern void __gcc_deregister_frame (void);
|
||||
|
||||
static void register_frame_ctor (void) __attribute__ ((constructor (0)));
|
||||
static void deregister_frame_dtor (void) __attribute__ ((destructor (0)));
|
||||
|
||||
|
||||
static void
|
||||
register_frame_ctor (void)
|
||||
{
|
||||
__gcc_register_frame ();
|
||||
}
|
||||
|
||||
static void
|
||||
deregister_frame_dtor (void)
|
||||
{
|
||||
__gcc_deregister_frame ();
|
||||
}
|
|
@ -51,6 +51,14 @@ Boston, MA 02110-1301, USA. */
|
|||
: (write_symbols == DWARF2_DEBUG \
|
||||
? svr4_dbx_register_map[n] : dbx_register_map[n]))
|
||||
|
||||
|
||||
/* Map gcc register number to DWARF 2 CFA column number. For 32 bit
|
||||
target, always use the svr4_dbx_register_map for DWARF .eh_frame
|
||||
even if we don't use DWARF .debug_frame. */
|
||||
#undef DWARF_FRAME_REGNUM
|
||||
#define DWARF_FRAME_REGNUM(n) TARGET_64BIT \
|
||||
? dbx64_register_map[(n)] : svr4_dbx_register_map[(n)]
|
||||
|
||||
/* Use section relative relocations for debugging offsets. Unlike
|
||||
other targets that fake this by putting the section VMA at 0, PE
|
||||
won't allow it. */
|
||||
|
@ -279,12 +287,15 @@ do { \
|
|||
#undef ASM_COMMENT_START
|
||||
#define ASM_COMMENT_START " #"
|
||||
|
||||
/* DWARF2 Unwinding doesn't work with exception handling yet. To make
|
||||
it work, we need to build a libgcc_s.dll, and dcrt0.o should be
|
||||
changed to call __register_frame_info/__deregister_frame_info. */
|
||||
#ifndef DWARF2_UNWIND_INFO
|
||||
/* If configured with --disable-sjlj-exceptions, use DWARF2, else
|
||||
default to SJLJ */
|
||||
#if defined (CONFIG_SJLJ_EXCEPTIONS) && !CONFIG_SJLJ_EXCEPTIONS
|
||||
#define DWARF2_UNWIND_INFO 1
|
||||
#else
|
||||
#define DWARF2_UNWIND_INFO 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Don't assume anything about the header files. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
||||
|
|
|
@ -38,11 +38,12 @@ Boston, MA 02110-1301, USA. */
|
|||
%{shared|mdll: %{mno-cygwin:dllcrt2%O%s}}\
|
||||
%{!shared: %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:crt2%O%s}\
|
||||
%{pg:gcrt0%O%s}}}\
|
||||
"
|
||||
crtbegin.o%s"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
|
||||
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}\
|
||||
crtend.o%s"
|
||||
|
||||
/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
|
||||
want to allow things to be added to it when installing new versions of
|
||||
|
|
|
@ -84,11 +84,13 @@ Boston, MA 02110-1301, USA. */
|
|||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
|
||||
%{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s}"
|
||||
%{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s} \
|
||||
crtbegin.o%s"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
|
||||
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
|
||||
crtend.o%s"
|
||||
|
||||
/* Override startfile prefix defaults. */
|
||||
#ifndef STANDARD_STARTFILE_PREFIX_1
|
||||
|
@ -141,3 +143,11 @@ do { \
|
|||
/* mingw32 atexit function is safe to use in shared libraries. Use it
|
||||
to register C++ static destructors. */
|
||||
#define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true
|
||||
|
||||
/* JCR_SECTION works on mingw32. */
|
||||
#undef TARGET_USE_JCR_SECTION
|
||||
#define TARGET_USE_JCR_SECTION 1
|
||||
|
||||
#if !TARGET_64BIT
|
||||
#define MD_UNWIND_SUPPORT "config/i386/w32-unwind.h"
|
||||
#endif
|
||||
|
|
215
gcc/config/i386/w32-unwind.h
Executable file
215
gcc/config/i386/w32-unwind.h
Executable file
|
@ -0,0 +1,215 @@
|
|||
/* Definitions for Dwarf2 EH unwind support for Windows32 targets
|
||||
Copyright (C) 2007
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Pascal Obry <obry@adacore.com>
|
||||
|
||||
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 with other programs, and to distribute
|
||||
those programs 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 another program.)
|
||||
|
||||
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 implements the md_fallback_frame_state_for routine for
|
||||
Windows, triggered when the GCC table based unwinding process hits a
|
||||
frame for which no unwind info has been registered. This typically
|
||||
occurs when raising an exception from a signal handler, because the
|
||||
handler is actually called from the OS kernel.
|
||||
|
||||
The basic idea is to detect that we are indeed trying to unwind past a
|
||||
signal handler and to fill out the GCC internal unwinding structures for
|
||||
the OS kernel frame as if it had been directly called from the
|
||||
interrupted context.
|
||||
|
||||
This is all assuming that the code to set the handler asked the kernel
|
||||
to pass a pointer to such context information.
|
||||
|
||||
There is three main parts.
|
||||
|
||||
1) The first thing to do is to check if we are in a signal context. If
|
||||
not we can just return as there is nothing to do. We are probably on
|
||||
some foreign code for which no unwind frame can be found. If this is
|
||||
a call from the Windows signal handler, then:
|
||||
|
||||
2) We must get the signal context information.
|
||||
|
||||
* With the standard exception filter:
|
||||
|
||||
This is on Windows pointed to by an EXCEPTION_POINTERS. We know that
|
||||
the signal handle will call an UnhandledExceptionFilter with this
|
||||
parameter. The spec for this routine is:
|
||||
|
||||
LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS*);
|
||||
|
||||
So the pointer to struct _EXCEPTION_POINTERS must be somewhere on the
|
||||
stack.
|
||||
|
||||
This was found experimentally to always be at offset 0 of the context
|
||||
frame in all cases handled by this implementation.
|
||||
|
||||
* With the SEH exception handler:
|
||||
|
||||
In this case the signal context is directly on the stack as the SEH
|
||||
exception handler has the following prototype:
|
||||
|
||||
DWORD
|
||||
SEH_error_handler (PEXCEPTION_RECORD ExceptionRecord,
|
||||
PVOID EstablisherFrame,
|
||||
PCONTEXT ContextRecord,
|
||||
PVOID DispatcherContext)
|
||||
|
||||
This was found experimentally to always be at offset 56 of the
|
||||
context frame in all cases handled by this implementation.
|
||||
|
||||
3) When we have the signal context we just have to save some registers
|
||||
and set the return address based on the program counter (Eip).
|
||||
|
||||
Note that this implementation follows closely the same principles as the
|
||||
GNU/Linux and OSF ones. */
|
||||
|
||||
#define WIN32_MEAN_AND_LEAN
|
||||
#include <windows.h>
|
||||
/* Patterns found experimentally to be on a Windows signal handler */
|
||||
|
||||
/* In a standard exception filter */
|
||||
|
||||
#define SIG_PAT1 \
|
||||
(pc_[-2] == 0xff && pc_[-1] == 0xd0 /* call %eax */ \
|
||||
&& pc_[0] == 0x83 && pc_[1] == 0xf8) /* cmp 0xdepl,%eax */
|
||||
|
||||
#define SIG_PAT2 \
|
||||
(pc_[-5] == 0xe8 && pc_[-4] == 0x68 /* call (depl16) */ \
|
||||
&& pc_[0] == 0xc3) /* ret */
|
||||
|
||||
/* In a Win32 SEH handler */
|
||||
|
||||
#define SIG_SEH1 \
|
||||
(pc_[-5] == 0xe8 /* call addr */ \
|
||||
&& pc_[0] == 0x83 && pc_[1] == 0xc4 /* add 0xval,%esp */ \
|
||||
&& pc_[3] == 0xb8) /* mov 0xval,%eax */
|
||||
|
||||
#define SIG_SEH2 \
|
||||
(pc_[-5] == 0x8b && pc_[-4] == 0x4d /* mov depl(%ebp),%ecx */ \
|
||||
&& pc_[0] == 0x64 && pc_[1] == 0x8b) /* mov %fs:(0),<reg> */ \
|
||||
|
||||
/* In the GCC alloca (stack probing) */
|
||||
|
||||
#define SIG_ALLOCA \
|
||||
(pc_[-1] == 0x83 /* orl $0x0,(%ecx) */ \
|
||||
&& pc_[0] == 0x9 && pc_[1] == 0 \
|
||||
&& pc_[2] == 0x2d && pc_[3] == 0 /* subl $0x1000,%eax */ \
|
||||
&& pc_[4] == 0x10 && pc_[5] == 0)
|
||||
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR i386_w32_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
i386_w32_fallback_frame_state (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
|
||||
{
|
||||
void * ctx_ra_ = (void *)(context->ra); /* return address */
|
||||
void * ctx_cfa_ = (void *)(context->cfa); /* context frame address */
|
||||
unsigned char * pc_ = (unsigned char *) ctx_ra_;
|
||||
|
||||
/* In the test below we look for two specific patterns found
|
||||
experimentally to be in the Windows signal handler. */
|
||||
|
||||
if (SIG_PAT1 || SIG_PAT2 || SIG_SEH1 || SIG_SEH2)
|
||||
{
|
||||
PEXCEPTION_POINTERS weinfo_;
|
||||
PCONTEXT proc_ctx_;
|
||||
long new_cfa_;
|
||||
|
||||
if (SIG_SEH1)
|
||||
proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 56));
|
||||
else if (SIG_SEH2)
|
||||
proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 8));
|
||||
else
|
||||
{
|
||||
weinfo_ = (PEXCEPTION_POINTERS) (*(int*)ctx_cfa_);
|
||||
proc_ctx_ = weinfo_->ContextRecord;
|
||||
}
|
||||
|
||||
/* The new context frame address is the stack pointer. */
|
||||
|
||||
new_cfa_ = proc_ctx_->Esp;
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = __builtin_dwarf_sp_column();
|
||||
fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;
|
||||
|
||||
/* Save some registers. */
|
||||
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&proc_ctx_->Eax - new_cfa_;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&proc_ctx_->Ebx - new_cfa_;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&proc_ctx_->Ecx - new_cfa_;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&proc_ctx_->Edx - new_cfa_;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&proc_ctx_->Esi - new_cfa_;
|
||||
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[7].loc.offset = (long)&proc_ctx_->Edi - new_cfa_;
|
||||
fs->regs.reg[9].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[9].loc.offset = (long)&proc_ctx_->Eip - new_cfa_;
|
||||
fs->regs.reg[4].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[4].loc.offset = (long)&proc_ctx_->Ebp - new_cfa_;
|
||||
|
||||
/* Set the return address to Eip + 1. As we can be called multiple
|
||||
times we use another register for this. */
|
||||
|
||||
proc_ctx_->Dr0 = proc_ctx_->Eip + 1;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&proc_ctx_->Dr0 - new_cfa_;
|
||||
fs->retaddr_column = 8;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
/* Unwinding through _alloca, propagating from a trap triggered by
|
||||
one of it's probes prior to the real SP adjustment. The only
|
||||
operations of interest performed is "pushl %ecx", followed by
|
||||
ecx clobbering. */
|
||||
|
||||
else if (SIG_ALLOCA)
|
||||
{
|
||||
/* Only one push between entry in _alloca and the probe trap. */
|
||||
long new_cfa_ = (long) ctx_cfa_ + 4;
|
||||
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = __builtin_dwarf_sp_column();
|
||||
fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;
|
||||
|
||||
/* The saved value of %ecx is at CFA - 4 */
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = -4;
|
||||
|
||||
/* and what is stored at the CFA is the return address. */
|
||||
fs->retaddr_column = 8;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = 0;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
else
|
||||
return _URC_END_OF_STACK;
|
||||
}
|
|
@ -1,3 +1,10 @@
|
|||
2007-06-14 Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
* config.host(*-cygwin* |*-mingw* ): Add crtbegin.o, crtend.o to
|
||||
extra_parts. Add config/i386/t-cygming to tmake_file.
|
||||
* config/i386/t-cygming: New file with rules for crtbegin.o, crtend.o.
|
||||
|
||||
|
||||
2007-05-29 Zuxy Meng <zuxy.meng@gmail.com>
|
||||
Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
|
|
|
@ -370,8 +370,8 @@ i[4567]86-wrs-vxworks|i[4567]86-wrs-vxworksae)
|
|||
i[34567]86-*-pe)
|
||||
;;
|
||||
i[34567]86-*-cygwin* | i[34567]86-*-mingw*)
|
||||
extra_parts="crtfastmath.o"
|
||||
tmake_file="i386/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o crtfastmath.o"
|
||||
tmake_file="i386/t-cygming i386/t-crtfm"
|
||||
;;
|
||||
x86_64-*-mingw*)
|
||||
;;
|
||||
|
|
11
libgcc/config/i386/t-cygming
Executable file
11
libgcc/config/i386/t-cygming
Executable file
|
@ -0,0 +1,11 @@
|
|||
CUSTOM_CRTSTUFF = yes
|
||||
|
||||
crtbegin.o: $(gcc_srcdir)/config/i386/cygming-crtbegin.c
|
||||
$(crt_compile) -fno-omit-frame-pointer -c \
|
||||
$(gcc_srcdir)/config/i386/cygming-crtbegin.c
|
||||
|
||||
# We intentionally use a implementation-reserved init priority of 0,
|
||||
# so allow the warning.
|
||||
crtend.o: $(gcc_srcdir)/config/i386/cygming-crtend.c
|
||||
$(crt_compile) -fno-omit-frame-pointer -Wno-error -c \
|
||||
$(gcc_srcdir)/config/i386/cygming-crtend.c
|
Loading…
Add table
Reference in a new issue