This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: target attributes for libgcc2 unwind functions
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Nigel Stephens <nigel at mips dot com>
- Date: Wed, 12 Sep 2007 11:44:50 -0400
- Subject: PATCH: target attributes for libgcc2 unwind functions
This patch is needed to fix problems in the mips*-sde-elf
configurations, which build multilibs for -mips16. Mips16 mode supports
the hard float ABI, but the hard float registers are not actually
accessible in mips16 mode, so it causes problems for programs containing
mixed mips16 and nomips16 code to be linked with mips16 library routines
that need to save/restore the FP registers, but can't. So, this patch
adds a hook for target-specific attributes on the unwind functions, and
makes the MIPS back end use it to attach an explicit nomips16 attribute
to those functions.
I did a bootstrap on i686 Linux as well as testing in a MIPS SDE
configuration.
OK to commit?
-Sandra
2007-09-12 Sandra Loosemore <sandra@codesourcery.com>
Nigel Stephens <nigel@mips.com>
gcc/
* doc/tm.texi (LIBGCC2_UNWIND_ATTRIBUTE): Document.
* unwind-generic.h (LIBGCC2_UNWIND_ATTRIBUTE): Define.
(_Unwind_RaiseException): Add LIBGCC2_UNWIND_ATTRIBUTE to
declaration.
(_Unwind_ForcedUnwind): Likewise.
(_Unwind_Resume): Likewise.
(_Unwind_Resume_or_Rethrow): Likewise.
(_Unwind_Backtrace): Likewise.
(_Unwind_SjLj_RaiseException): Likewise.
(_Unwind_SjLj_ForcedUnwind): Likewise.
(_Unwind_SjLj_Resume): Likewise.
(_Unwind_SjLj_Resume_or_Rethrow): Likewise.
* unwind.inc (_Unwind_RaiseException): Add LIBGCC2_UNWIND_ATTRIBUTE
to definition.
(_Unwind_ForcedUnwind): Likewise.
(_Unwind_Resume): Likewise.
(_Unwind_Resume_or_Rethrow): Likewise.
(_Unwind_Backtrace): Likewise.
* unwind-compat.c (_Unwind_Backtrace): Likewise.
(_Unwind_ForcedUnwind): Likewise.
(_Unwind_RaiseException): Likewise.
(_Unwind_Resume): Likewise.
(_Unwind_Resume_or_Rethrow): Likewise.
* config/mips/mips.h (LIBGCC2_UNWIND_ATTRIBUTE): Define to force
nomips16 mode when IN_LIBGCC2 with hard float.
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi (revision 128373)
--- gcc/doc/tm.texi (working copy)
*************** SUPPORTS_WEAK and TARGET_HAVE_NAMED_SECT
*** 10336,10338 ****
--- 10336,10345 ----
This macro determines the size of the objective C jump buffer for the
NeXT runtime. By default, OBJC_JBLEN is defined to an innocuous value.
@end defmac
+
+ @defmac LIBGCC2_UNWIND_ATTRIBUTE
+ Define this macro if any target-specific attributes need to be attached
+ to the functions in @file{libgcc2.a} that provide low-level support for
+ call stack unwinding. It is used in declarations in @file{unwind-generic.h}
+ and the associated definitions of those functions.
+ @end defmac
Index: gcc/unwind-generic.h
===================================================================
*** gcc/unwind-generic.h (revision 128373)
--- gcc/unwind-generic.h (working copy)
*************** typedef int _Unwind_Action;
*** 108,113 ****
--- 108,119 ----
#define _UA_FORCE_UNWIND 8
#define _UA_END_OF_STACK 16
+ /* The target can override this macro to define any back-end-specific
+ attributes required for the lowest-level stack frame. */
+ #ifndef LIBGCC2_UNWIND_ATTRIBUTE
+ #define LIBGCC2_UNWIND_ATTRIBUTE
+ #endif
+
/* This is an opaque type used to refer to a system-specific data
structure used by the system unwinder. This context is created and
destroyed by the system, and passed to the personality routine
*************** typedef int _Unwind_Action;
*** 115,121 ****
struct _Unwind_Context;
/* Raise an exception, passing along the given exception object. */
! extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
/* Raise an exception for forced unwinding. */
--- 121,128 ----
struct _Unwind_Context;
/* Raise an exception, passing along the given exception object. */
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_RaiseException (struct _Unwind_Exception *);
/* Raise an exception for forced unwinding. */
*************** typedef _Unwind_Reason_Code (*_Unwind_St
*** 123,142 ****
(int, _Unwind_Action, _Unwind_Exception_Class,
struct _Unwind_Exception *, struct _Unwind_Context *, void *);
! extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
! _Unwind_Stop_Fn,
! void *);
/* Helper to invoke the exception_cleanup routine. */
extern void _Unwind_DeleteException (struct _Unwind_Exception *);
/* Resume propagation of an existing exception. This is used after
e.g. executing cleanup code, and not to implement rethrowing. */
! extern void _Unwind_Resume (struct _Unwind_Exception *);
/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow
a normal exception that was handled. */
! extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
/* @@@ Use unwind data to perform a stack backtrace. The trace callback
is called for every stack frame in the call chain, but no cleanup
--- 130,150 ----
(int, _Unwind_Action, _Unwind_Exception_Class,
struct _Unwind_Exception *, struct _Unwind_Context *, void *);
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
/* Helper to invoke the exception_cleanup routine. */
extern void _Unwind_DeleteException (struct _Unwind_Exception *);
/* Resume propagation of an existing exception. This is used after
e.g. executing cleanup code, and not to implement rethrowing. */
! extern void LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_Resume (struct _Unwind_Exception *);
/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow
a normal exception that was handled. */
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
/* @@@ Use unwind data to perform a stack backtrace. The trace callback
is called for every stack frame in the call chain, but no cleanup
*************** extern _Unwind_Reason_Code _Unwind_Resum
*** 144,150 ****
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
(struct _Unwind_Context *, void *);
! extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
/* These functions are used for communicating information about the unwind
context (i.e. the unwind descriptors and the user register state) between
--- 152,159 ----
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
(struct _Unwind_Context *, void *);
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
/* These functions are used for communicating information about the unwind
context (i.e. the unwind descriptors and the user register state) between
*************** struct SjLj_Function_Context;
*** 191,202 ****
extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
! extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException
! (struct _Unwind_Exception *);
! extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind
! (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
! extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *);
! extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *);
/* @@@ The following provide access to the base addresses for text
and data-relative addressing in the LDSA. In order to stay link
--- 200,213 ----
extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_SjLj_RaiseException (struct _Unwind_Exception *);
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_SjLj_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
! extern void LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_SjLj_Resume (struct _Unwind_Exception *);
! extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
! _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *);
/* @@@ The following provide access to the base addresses for text
and data-relative addressing in the LDSA. In order to stay link
Index: gcc/unwind.inc
===================================================================
*** gcc/unwind.inc (revision 128373)
--- gcc/unwind.inc (working copy)
*************** _Unwind_RaiseException_Phase2(struct _Un
*** 82,88 ****
/* Raise an exception, passing along the given exception object. */
! _Unwind_Reason_Code
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
--- 82,88 ----
/* Raise an exception, passing along the given exception object. */
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
*************** _Unwind_ForcedUnwind_Phase2 (struct _Unw
*** 195,201 ****
/* Raise an exception for forced unwinding. */
! _Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
_Unwind_Stop_Fn stop, void * stop_argument)
{
--- 195,201 ----
/* Raise an exception for forced unwinding. */
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
_Unwind_Stop_Fn stop, void * stop_argument)
{
*************** _Unwind_ForcedUnwind (struct _Unwind_Exc
*** 219,225 ****
/* Resume propagation of an existing exception. This is used after
e.g. executing cleanup code, and not to implement rethrowing. */
! void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
--- 219,225 ----
/* Resume propagation of an existing exception. This is used after
e.g. executing cleanup code, and not to implement rethrowing. */
! void LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_Resume (struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
*************** _Unwind_Resume (struct _Unwind_Exception
*** 244,250 ****
/* Resume propagation of an FORCE_UNWIND exception, or to rethrow
a normal exception that was handled. */
! _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
--- 244,250 ----
/* Resume propagation of an FORCE_UNWIND exception, or to rethrow
a normal exception that was handled. */
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
struct _Unwind_Context this_context, cur_context;
*************** _Unwind_DeleteException (struct _Unwind_
*** 278,284 ****
/* Perform stack backtrace through unwind data. */
! _Unwind_Reason_Code
_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
{
struct _Unwind_Context context;
--- 278,284 ----
/* Perform stack backtrace through unwind data. */
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
{
struct _Unwind_Context context;
Index: gcc/unwind-compat.c
===================================================================
*** gcc/unwind-compat.c (revision 128373)
--- gcc/unwind-compat.c (working copy)
***************
*** 38,44 ****
extern _Unwind_Reason_Code __libunwind_Unwind_Backtrace
(_Unwind_Trace_Fn, void *);
! _Unwind_Reason_Code
_Unwind_Backtrace (_Unwind_Trace_Fn trace, void *trace_argument)
{
return __libunwind_Unwind_Backtrace (trace, trace_argument);
--- 38,44 ----
extern _Unwind_Reason_Code __libunwind_Unwind_Backtrace
(_Unwind_Trace_Fn, void *);
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_Backtrace (_Unwind_Trace_Fn trace, void *trace_argument)
{
return __libunwind_Unwind_Backtrace (trace, trace_argument);
*************** symver (_Unwind_FindEnclosingFunction, G
*** 67,73 ****
extern _Unwind_Reason_Code __libunwind_Unwind_ForcedUnwind
(struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
! _Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
_Unwind_Stop_Fn stop, void * stop_argument)
{
--- 67,73 ----
extern _Unwind_Reason_Code __libunwind_Unwind_ForcedUnwind
(struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
_Unwind_Stop_Fn stop, void * stop_argument)
{
*************** symver (_Unwind_GetRegionStart, GCC_3.0)
*** 166,172 ****
extern _Unwind_Reason_Code __libunwind_Unwind_RaiseException
(struct _Unwind_Exception *);
! _Unwind_Reason_Code
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
return __libunwind_Unwind_RaiseException (exc);
--- 166,172 ----
extern _Unwind_Reason_Code __libunwind_Unwind_RaiseException
(struct _Unwind_Exception *);
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
return __libunwind_Unwind_RaiseException (exc);
*************** symver (_Unwind_RaiseException, GCC_3.0)
*** 175,181 ****
extern void __libunwind_Unwind_Resume (struct _Unwind_Exception *);
! void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
__libunwind_Unwind_Resume (exc);
--- 175,181 ----
extern void __libunwind_Unwind_Resume (struct _Unwind_Exception *);
! void LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_Resume (struct _Unwind_Exception *exc)
{
__libunwind_Unwind_Resume (exc);
*************** symver (_Unwind_Resume, GCC_3.0);
*** 185,191 ****
extern _Unwind_Reason_Code __libunwind_Unwind_Resume_or_Rethrow
(struct _Unwind_Exception *);
! _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
return __libunwind_Unwind_Resume_or_Rethrow (exc);
--- 185,191 ----
extern _Unwind_Reason_Code __libunwind_Unwind_Resume_or_Rethrow
(struct _Unwind_Exception *);
! _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
return __libunwind_Unwind_Resume_or_Rethrow (exc);
Index: gcc/config/mips/mips.h
===================================================================
*** gcc/config/mips/mips.h (revision 128373)
--- gcc/config/mips/mips.h (working copy)
*************** extern enum mips_code_readable_setting m
*** 573,578 ****
--- 573,589 ----
#endif
#endif /* IN_LIBGCC2 */
+ /* Force the call stack unwinders in unwind.inc not to be MIPS16 code
+ when compiled with hardware floating point. This is because MIPS16
+ cannot save and restore the floating point registers, which will be
+ important if in a mixed MIPS16/non-MIPS16 environment. */
+
+ #ifdef IN_LIBGCC2
+ #if __mips_hard_float
+ #define LIBGCC2_UNWIND_ATTRIBUTE __attribute__((__nomips16__))
+ #endif
+ #endif /* IN_LIBGCC2 */
+
#define TARGET_LIBGCC_SDATA_SECTION ".sdata"
#ifndef MULTILIB_ENDIAN_DEFAULT