This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch] MIPS -G 0 libgcc vs. (default -G) stdc++ data problem.


Last night i reported an issue with libgcc fighting with libstdc++ in
a message to gcc-bugs:

	http://gcc.gnu.org/ml/gcc-bugs/2000-10/msg00568.html


In a nutshell, libstdc++ is compiled with default -G value on MIPS,
but libgcc is compiled with -G 0.  This causes libstdc++'s attempt to
directly access libgcc's internal variable __terminate_func to fail.

Without this patch, the trivial program:

	#include <iostream.h>

	main()
	{
	    cout << "Hello World! (from C++)\n";
	}

won't link due to truncated GP-relative relocations, trying to
reference __terminate_func in a GP-relative manner, in my mips
cross-build environment.

With it, the program will link and indeed even works correctly.
Unfortunately, that's about the extent of the testing I can give it.
8-)

I also couldn't easily test the libstdc++-v3 bits.  However, the
libstdc++ and libstdc++-v3 exception.cc files were identical before,
and I just copied my changes over and verified that they were
identical afterward, so my feeling is it should be safe.


My source tree is from the current trunk as of 2000-10-10 0:00 UTC,
but i've updated the patch below to apply to the very-current sources
as of a few minutes ago.  (The only thing that didn't apply was the
libstdc++-v3 change -- because the file it applied to was renamed.
8-)

patch applies in top level (i.e. dir containing gcc and libstdc++).
changlogs below broken out by dir.


btw, re: my question in that message:

> I could easily believe that there are other bugs like this running
> around, but I don't know what (data) variables are exported from
> libgcc.a for (erroneous) use elsewhere...

It looks like one other data symbol is exported from libgcc.a on a
mips-elf-like target: __shtab.  I couldn't find any uses of it in the
gcc src tree (at all!), though, and it's a 128 byte array, so even if
it is used it should be safe in my circumstances...


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]