This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch repost] libgcc __terminate_func ABI issue.
- To: gcc-patches at gcc dot gnu dot org
- Subject: [patch repost] libgcc __terminate_func ABI issue.
- From: cgd at sibyte dot com (Chris G. Demetriou)
- Date: 23 Jan 2001 11:50:56 -0800
This is a re-post of the patch presented in messages:
http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00967.html
http://gcc.gnu.org/ml/gcc-patches/2000-11/msg00764.html
I've verified that the patch still applies to the current GCC sources,
but haven't done any additional verification of the patch other than
what's described below (which was done back in october), plus running
with it in my source tree for a couple of months. Unfortunately, I
don't have any time to do anything additional with this patch at this
time.
I'm bringing up this again because if it's not resolved, it will
probably cause an ABI issue later on...
On many MIPS targets, libgcc2 is compiled with -G 0, and libstdc++
(old or v3) is compiled with the default -G value (typically -G 8).
Libstdc++ currently attempts to access a pointer variable
(__terminate_func) defined in libgcc2 directly. Because of the
different -G values, this variable isn't placed in the 'small data'
section when compiling libgcc2, but libstdc++ assumes that it will be
in the small data section, and thus accessable off of the GP.
Without this patch, the trivial program:
#include <iostream.h>
main()
{
cout << "Hello World! (from C++)\n";
}
won't link in a cross-build environment (based on mips64-elf, with
newlib) due to truncated GP-relative relocations, trying to reference
__terminate_func in a GP-relative manner.
At the time the patch was originally written, the gcc source tree I
was using defaulted to libstdc++ (it was from gcc sources dated
approx. 2000-10-10). The new source tree I'm using (based on gcc
2001-01-03 srcs) defaults to libstdc++-v3. I've verified correct
linking and operation of the abovementioned program with the old
tools, and correct linking with the new tools (I can't easily test
running right now, but it should work as well).
patch applies in top level (i.e. dir containing gcc and libstdc++).
changlogs below broken out by dir.
It would be great if somebody could throw this into their source tree
the next time they do a bootstrap/regression run...
chris
==============================================================================
for gcc/ChangeLog:
2000-10-28 Chris Demetriou <cgd@sibyte.com>
* optabs.c (init_optabs): Initialize terminate_set_func_libfunc.
* libgcc-std.ver (GCC_3.0): Add __terminate_func_set to list
of EH symbols.
* libgcc2.c (__terminate_func): Make variable static.
(__terminate_set_func): New function to set __terminate_func.
* libgcc2.h (__terminate_func_ptr): New typedef.
(__terminate_set_func): New function.
for libstdc++/ChangeLog:
2000-10-28 Chris Demetriou <cgd@sibyte.com>
* exception.cc (__terminate_func): Remove declaration.
(__terminate_func_ptr): New typedef.
(__terminate, __terminate_set_func): New extern function
prototypes.
(std::terminate): Use __terminate function.
(std::set_terminate): Use __terminate_set_func function.
for libstdc++-v3/ChangeLog:
2000-10-28 Chris Demetriou <cgd@sibyte.com>
* libsupc++/exception_support.cc (__terminate_func): Remove
declaration.
(__terminate_func_ptr): New typedef.
(__terminate, __terminate_set_func): New extern function
prototypes.
(std::terminate): Use __terminate function.
(std::set_terminate): Use __terminate_set_func function.
Index: gcc/optabs.c
===================================================================
RCS file: /cvsroot/systemsw/tools/src/gcc/gcc/optabs.c,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -c -r1.1.1.2 -r1.3
*** optabs.c 2000/10/21 05:31:56 1.1.1.2
--- optabs.c 2000/10/29 00:35:47 1.3
***************
*** 4708,4713 ****
--- 4708,4714 ----
sjthrow_libfunc = init_one_libfunc ("__sjthrow");
sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
terminate_libfunc = init_one_libfunc ("__terminate");
+ terminate_set_func_libfunc = init_one_libfunc ("__terminate_set_func");
eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
#ifndef DONT_USE_BUILTIN_SETJMP
setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
Index: gcc/libgcc-std.ver
===================================================================
RCS file: /cvsroot/systemsw/tools/src/gcc/gcc/libgcc-std.ver,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** libgcc-std.ver 2000/10/21 05:31:45 1.1.1.1
--- libgcc-std.ver 2000/10/29 00:35:38 1.2
***************
*** 123,128 ****
--- 123,129 ----
__sjpopnthrow
__sjthrow
__terminate
+ __terminate_set_func
__throw
__throw_type_match
__unwinding_cleanup
Index: gcc/libgcc2.c
===================================================================
RCS file: /cvsroot/systemsw/tools/src/gcc/gcc/libgcc2.c,v
retrieving revision 1.1.1.2
retrieving revision 1.5
diff -c -r1.1.1.2 -r1.5
*** libgcc2.c 2000/10/21 05:31:47 1.1.1.2
--- libgcc2.c 2000/10/29 00:35:39 1.5
***************
*** 2987,2999 ****
abort ();
}
! void (*__terminate_func)(void) __attribute__ ((__noreturn__)) =
__default_terminate;
void __attribute__((__noreturn__))
__terminate (void)
{
(*__terminate_func)();
}
void *
--- 2987,3008 ----
abort ();
}
! static __terminate_func_ptr __terminate_func =
__default_terminate;
void __attribute__((__noreturn__))
__terminate (void)
{
(*__terminate_func)();
+ }
+
+ __terminate_func_ptr
+ __terminate_set_func (__terminate_func_ptr newfunc)
+ {
+ __terminate_func_ptr oldfunc = __terminate_func;
+
+ __terminate_func = newfunc;
+ return (oldfunc);
}
void *
Index: gcc/libgcc2.h
===================================================================
RCS file: /cvsroot/systemsw/tools/src/gcc/gcc/libgcc2.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** libgcc2.h 2000/10/21 05:31:47 1.1.1.1
--- libgcc2.h 2000/10/29 00:35:40 1.2
***************
*** 22,33 ****
--- 22,36 ----
#ifndef __LIBGCC2_H__
#define __LIBGCC2_H__
+ typedef void (*__terminate_func_ptr)(void) __attribute__ ((__noreturn__));
+
extern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t);
extern void *__builtin_saveregs (void);
extern void __dummy (void);
extern void __clear_cache (char *, char *);
extern void __pure_virtual (void) __attribute__ ((__noreturn__));
extern void __terminate (void) __attribute__ ((__noreturn__));
+ extern __terminate_func_ptr __terminate_set_func (__terminate_func_ptr);
extern void __default_terminate (void) __attribute__ ((__noreturn__));
extern void *__throw_type_match (void *, void *, void *);
extern void __empty (void);
Index: libstdc++/exception.cc
===================================================================
RCS file: /cvsroot/systemsw/tools/src/gcc/libstdc++/exception.cc,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** exception.cc 2000/10/21 05:42:41 1.1.1.1
--- exception.cc 2000/10/29 01:10:34 1.2
***************
*** 38,50 ****
/* Define terminate, unexpected, set_terminate, set_unexpected as
well as the default terminate func and default unexpected func. */
! extern std::terminate_handler __terminate_func __attribute__((__noreturn__));
using std::terminate;
void
std::terminate ()
{
! __terminate_func ();
}
void
--- 38,54 ----
/* Define terminate, unexpected, set_terminate, set_unexpected as
well as the default terminate func and default unexpected func. */
! /* __terminate and __terminate_set_func, defined in libgcc2. */
! typedef void (*__terminate_func_ptr)(void) __attribute__ ((__noreturn__));
! extern "C" void __terminate (void) __attribute__ ((__noreturn__));
! extern "C" __terminate_func_ptr __terminate_set_func (__terminate_func_ptr);
!
using std::terminate;
void
std::terminate ()
{
! __terminate ();
}
void
***************
*** 59,68 ****
std::terminate_handler
std::set_terminate (std::terminate_handler func)
{
! std::terminate_handler old = __terminate_func;
!
! __terminate_func = func;
! return old;
}
std::unexpected_handler
--- 63,69 ----
std::terminate_handler
std::set_terminate (std::terminate_handler func)
{
! return __terminate_set_func (func);
}
std::unexpected_handler
Index: libstdc++-v3/libsupc++/exception_support.cc
===================================================================
RCS file: /cvsroot/systemsw/tools/src/gcc/libstdc++-v3/libsupc++/exception_support.cc,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** exception.cc 2000/10/21 05:43:22 1.1.1.1
--- exception.cc 2000/10/29 01:24:53 1.3
***************
*** 38,50 ****
/* Define terminate, unexpected, set_terminate, set_unexpected as
well as the default terminate func and default unexpected func. */
! extern std::terminate_handler __terminate_func __attribute__((__noreturn__));
using std::terminate;
void
std::terminate ()
{
! __terminate_func ();
}
void
--- 38,54 ----
/* Define terminate, unexpected, set_terminate, set_unexpected as
well as the default terminate func and default unexpected func. */
! /* __terminate and __terminate_set_func, defined in libgcc2. */
! typedef void (*__terminate_func_ptr)(void) __attribute__ ((__noreturn__));
! extern "C" void __terminate (void) __attribute__ ((__noreturn__));
! extern "C" __terminate_func_ptr __terminate_set_func (__terminate_func_ptr);
!
using std::terminate;
void
std::terminate ()
{
! __terminate ();
}
void
***************
*** 59,68 ****
std::terminate_handler
std::set_terminate (std::terminate_handler func)
{
! std::terminate_handler old = __terminate_func;
!
! __terminate_func = func;
! return old;
}
std::unexpected_handler
--- 63,69 ----
std::terminate_handler
std::set_terminate (std::terminate_handler func)
{
! return __terminate_set_func (func);
}
std::unexpected_handler