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]
Other format: [Raw text]

PATCH: Fix linkage in libsupc++


With the new symbol visibility patches, we have to be careful not to
get incorrect linkage in the libraries; if the default visibility is
not "default" when we include the headers, things get confused.
Things are even worse for ports that use "hidden" visibility by
default; the ARM/Symbian OS port will be one such.

A tricky problem here was that this pattern was present in a lot of
the libsupc++ files:

  // cxxabi.h

  namespace __cxxabiv1 { 
     extern "C" void f();
  }

  // f.c

  #include <cxxabi.h>
  
  extern "C" void f() {}

This is *not* a definition of the function declared in the header;
it's just an overloaded function.  You must write "__cxxabiv1::f" or
put the definition inside the namespace.

I did not attempt to fix all of the V3 headers; I'm only concerned
with libsupc++ at the moment.  However, similar changes should
probably be made throughout V3.  Otherwise, linkage will be wrong if
people #include (say) <iostream> with a non-default symbol visibility.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-08-02  Mark Mitchell  <mark@codesourcery.com>

	* libsupc++/cxxabi.h: Make all declarations have default
	visibility.
	* libsupc++/exception: Likewise.
	* libsupc++/new: Likewise.
	* libsupc++/typeinfo: Likewise.
	* libsupc++/unwind-cxx.h: Likewise.
	* libsupc++/eh_alloc.cc (__cxa_allocate_exception): Put it into
	the __cxxabiv1 namespace.
	(__cxa_free_exception): Likewise.
	* libsupc++/eh_aux_runtime.cc (__cxa_bad_cast): Likewise.
	(__cxa_bad_typeid): Likewise.
	* libsupc++/eh_catch.cc (__cxa_begin_catch): Likewise.
	(__cxa_end_catch): Likewise.
	* libsupc++/eh_globals.cc (__cxa_get_globals_fast): Likewise.
	(__cxa_get_globals): Likewise.
	* libsupc++/eh_throw.cc (__cxa_throw): Likewise.
	(__cxa_rethrow): Likewise.
	* libsupc++/pure.cc (__cxa_pure_virtual): Likewise.
	* libsupc++/eh_type.cc: Include <cxxabi.h>.

Index: cxxabi.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/cxxabi.h,v
retrieving revision 1.18
diff -c -5 -p -r1.18 cxxabi.h
*** cxxabi.h	2 Jul 2004 23:40:16 -0000	1.18
--- cxxabi.h	3 Aug 2004 06:39:42 -0000
***************
*** 40,49 ****
--- 40,51 ----
     available in C, naturally enough.  */
  
  #ifndef _CXXABI_H
  #define _CXXABI_H 1
  
+ #pragma GCC visibility push(default)
+ 
  #include <stddef.h>
  #include <bits/cxxabi_tweaks.h>
   
  #ifdef __cplusplus
  namespace __cxxabiv1
*************** namespace __cxxabiv1
*** 521,526 ****
--- 523,530 ----
  // User programs should use the alias `abi'. 
  namespace abi = __cxxabiv1;
  
  #endif // __cplusplus
  
+ #pragma GCC visibility pop
+ 
  #endif // __CXXABI_H 
Index: eh_alloc.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_alloc.cc,v
retrieving revision 1.10
diff -c -5 -p -r1.10 eh_alloc.cc
*** eh_alloc.cc	2 Aug 2004 20:28:21 -0000	1.10
--- eh_alloc.cc	3 Aug 2004 06:39:42 -0000
*************** emergency_mutex_init ()
*** 105,115 ****
  #endif
  #endif
  
  
  extern "C" void *
! __cxa_allocate_exception(std::size_t thrown_size) throw()
  {
    void *ret;
  
    thrown_size += sizeof (__cxa_exception);
    ret = malloc (thrown_size);
--- 105,115 ----
  #endif
  #endif
  
  
  extern "C" void *
! __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw()
  {
    void *ret;
  
    thrown_size += sizeof (__cxa_exception);
    ret = malloc (thrown_size);
*************** __cxa_allocate_exception(std::size_t thr
*** 152,162 ****
    return (void *)((char *)ret + sizeof (__cxa_exception));
  }
  
  
  extern "C" void
! __cxa_free_exception(void *vptr) throw()
  {
    char *ptr = (char *) vptr;
    if (ptr >= &emergency_buffer[0][0]
        && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer))
      {
--- 152,162 ----
    return (void *)((char *)ret + sizeof (__cxa_exception));
  }
  
  
  extern "C" void
! __cxxabiv1::__cxa_free_exception(void *vptr) throw()
  {
    char *ptr = (char *) vptr;
    if (ptr >= &emergency_buffer[0][0]
        && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer))
      {
Index: eh_aux_runtime.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_aux_runtime.cc,v
retrieving revision 1.4
diff -c -5 -p -r1.4 eh_aux_runtime.cc
*** eh_aux_runtime.cc	7 Apr 2004 03:33:35 -0000	1.4
--- eh_aux_runtime.cc	3 Aug 2004 06:39:42 -0000
***************
*** 33,53 ****
  #include <cstdlib>
  #include "unwind-cxx.h"
  #include "exception_defines.h"
  
  extern "C" void
! __cxa_bad_cast ()
  {
  #ifdef __EXCEPTIONS  
    throw std::bad_cast();
  #else
    std::abort();
  #endif
  }
  
  extern "C" void
! __cxa_bad_typeid ()
  {
  #ifdef __EXCEPTIONS  
    throw std::bad_typeid();
  #else
    std::abort();
--- 33,53 ----
  #include <cstdlib>
  #include "unwind-cxx.h"
  #include "exception_defines.h"
  
  extern "C" void
! __cxxabiv1::__cxa_bad_cast ()
  {
  #ifdef __EXCEPTIONS  
    throw std::bad_cast();
  #else
    std::abort();
  #endif
  }
  
  extern "C" void
! __cxxabiv1::__cxa_bad_typeid ()
  {
  #ifdef __EXCEPTIONS  
    throw std::bad_typeid();
  #else
    std::abort();
Index: eh_catch.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_catch.cc,v
retrieving revision 1.7
diff -c -5 -p -r1.7 eh_catch.cc
*** eh_catch.cc	7 Apr 2004 03:33:35 -0000	1.7
--- eh_catch.cc	3 Aug 2004 06:39:42 -0000
***************
*** 33,43 ****
  
  using namespace __cxxabiv1;
  
  
  extern "C" void *
! __cxa_begin_catch (void *exc_obj_in) throw()
  {
    _Unwind_Exception *exceptionObject
      = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
    __cxa_eh_globals *globals = __cxa_get_globals ();
    __cxa_exception *prev = globals->caughtExceptions;
--- 33,43 ----
  
  using namespace __cxxabiv1;
  
  
  extern "C" void *
! __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) throw()
  {
    _Unwind_Exception *exceptionObject
      = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
    __cxa_eh_globals *globals = __cxa_get_globals ();
    __cxa_exception *prev = globals->caughtExceptions;
*************** __cxa_begin_catch (void *exc_obj_in) thr
*** 80,90 ****
    return header->adjustedPtr;
  }
  
  
  extern "C" void
! __cxa_end_catch ()
  {
    __cxa_eh_globals *globals = __cxa_get_globals_fast ();
    __cxa_exception *header = globals->caughtExceptions;
  
    // A rethrow of a foreign exception will be removed from the
--- 80,90 ----
    return header->adjustedPtr;
  }
  
  
  extern "C" void
! __cxxabiv1::__cxa_end_catch ()
  {
    __cxa_eh_globals *globals = __cxa_get_globals_fast ();
    __cxa_exception *header = globals->caughtExceptions;
  
    // A rethrow of a foreign exception will be removed from the
Index: eh_globals.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_globals.cc,v
retrieving revision 1.5
diff -c -5 -p -r1.5 eh_globals.cc
*** eh_globals.cc	7 Apr 2004 03:33:35 -0000	1.5
--- eh_globals.cc	3 Aug 2004 06:39:42 -0000
*************** get_globals_init_once ()
*** 67,77 ****
      use_thread_key = 0;
  }
  #endif
  
  extern "C" __cxa_eh_globals *
! __cxa_get_globals_fast () throw()
  {
  #if __GTHREADS
    if (use_thread_key)
      return (__cxa_eh_globals *) __gthread_getspecific (globals_key);
    else
--- 67,77 ----
      use_thread_key = 0;
  }
  #endif
  
  extern "C" __cxa_eh_globals *
! __cxxabiv1::__cxa_get_globals_fast () throw()
  {
  #if __GTHREADS
    if (use_thread_key)
      return (__cxa_eh_globals *) __gthread_getspecific (globals_key);
    else
*************** __cxa_get_globals_fast () throw()
*** 80,90 ****
    return &globals_static;
  #endif
  }
  
  extern "C" __cxa_eh_globals *
! __cxa_get_globals () throw()
  {
  #if __GTHREADS
    __cxa_eh_globals *g;
  
    if (use_thread_key == 0)
--- 80,90 ----
    return &globals_static;
  #endif
  }
  
  extern "C" __cxa_eh_globals *
! __cxxabiv1::__cxa_get_globals () throw()
  {
  #if __GTHREADS
    __cxa_eh_globals *g;
  
    if (use_thread_key == 0)
Index: eh_throw.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_throw.cc,v
retrieving revision 1.7
diff -c -5 -p -r1.7 eh_throw.cc
*** eh_throw.cc	5 Jul 2003 04:05:40 -0000	1.7
--- eh_throw.cc	3 Aug 2004 06:39:42 -0000
***************
*** 29,39 ****
  
  
  #include <bits/c++config.h>
  #include "unwind-cxx.h"
  
- 
  using namespace __cxxabiv1;
  
  
  static void
  __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
--- 29,38 ----
*************** __gxx_exception_cleanup (_Unwind_Reason_
*** 54,64 ****
    __cxa_free_exception (header + 1);
  }
  
  
  extern "C" void
! __cxa_throw (void *obj, std::type_info *tinfo, void (*dest) (void *))
  {
    __cxa_exception *header = __get_exception_header_from_obj (obj);
    header->exceptionType = tinfo;
    header->exceptionDestructor = dest;
    header->unexpectedHandler = __unexpected_handler;
--- 53,64 ----
    __cxa_free_exception (header + 1);
  }
  
  
  extern "C" void
! __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, 
! 			 void (*dest) (void *))
  {
    __cxa_exception *header = __get_exception_header_from_obj (obj);
    header->exceptionType = tinfo;
    header->exceptionDestructor = dest;
    header->unexpectedHandler = __unexpected_handler;
*************** __cxa_throw (void *obj, std::type_info *
*** 79,89 ****
    __cxa_begin_catch (&header->unwindHeader);
    std::terminate ();
  }
  
  extern "C" void
! __cxa_rethrow ()
  {
    __cxa_eh_globals *globals = __cxa_get_globals ();
    __cxa_exception *header = globals->caughtExceptions;
  
    // Watch for luser rethrowing with no active exception.
--- 79,89 ----
    __cxa_begin_catch (&header->unwindHeader);
    std::terminate ();
  }
  
  extern "C" void
! __cxxabiv1::__cxa_rethrow ()
  {
    __cxa_eh_globals *globals = __cxa_get_globals ();
    __cxa_exception *header = globals->caughtExceptions;
  
    // Watch for luser rethrowing with no active exception.
Index: eh_type.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_type.cc,v
retrieving revision 1.3
diff -c -5 -p -r1.3 eh_type.cc
*** eh_type.cc	24 May 2003 16:22:03 -0000	1.3
--- eh_type.cc	3 Aug 2004 06:39:42 -0000
***************
*** 27,36 ****
--- 27,37 ----
  // invalidate any other reasons why the executable file might be covered by
  // the GNU General Public License.
  
  
  #include <typeinfo>
+ #include <cxxabi.h>
  #include "unwind-cxx.h"
  
  namespace __cxxabiv1
  {
  
Index: exception
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/exception,v
retrieving revision 1.16
diff -c -5 -p -r1.16 exception
*** exception	24 May 2003 16:22:03 -0000	1.16
--- exception	3 Aug 2004 06:39:42 -0000
***************
*** 35,44 ****
--- 35,46 ----
   */
  
  #ifndef __EXCEPTION__
  #define __EXCEPTION__
  
+ #pragma GCC visibility push(default)
+ 
  extern "C++" {
  
  namespace std 
  {
    /**
*************** namespace __gnu_cxx
*** 115,120 ****
--- 117,124 ----
    void __verbose_terminate_handler ();
  } // namespace __gnu_cxx
    
  } // extern "C++"
  
+ #pragma GCC visibility pop
+ 
  #endif
Index: new
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/new,v
retrieving revision 1.17
diff -c -5 -p -r1.17 new
*** new	5 Jul 2003 04:05:40 -0000	1.17
--- new	3 Aug 2004 06:39:42 -0000
***************
*** 39,48 ****
--- 39,50 ----
  #define _NEW
  
  #include <cstddef>
  #include <exception>
  
+ #pragma GCC visibility push(default)
+ 
  extern "C++" {
  
  namespace std 
  {
    /**
*************** inline void* operator new[](std::size_t,
*** 96,101 ****
--- 98,105 ----
  inline void  operator delete  (void*, void*) throw() { }
  inline void  operator delete[](void*, void*) throw() { }
  //@}
  } // extern "C++"
  
+ #pragma GCC visibility pop
+ 
  #endif
Index: pure.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/pure.cc,v
retrieving revision 1.12
diff -c -5 -p -r1.12 pure.cc
*** pure.cc	2 Aug 2004 20:28:21 -0000	1.12
--- pure.cc	3 Aug 2004 06:39:42 -0000
***************
*** 26,35 ****
--- 26,36 ----
  // the GNU General Public License.  This exception does not however
  // invalidate any other reasons why the executable file might be covered by
  // the GNU General Public License.
  
  #include <bits/c++config.h>
+ #include <cxxabi.h>
  #include "unwind-cxx.h"
  
  #if _GLIBCXX_HOSTED
  #ifdef _GLIBCXX_HAVE_UNISTD_H
  # include <unistd.h>
***************
*** 46,55 ****
  #else
  # define writestr(str) /* Empty */
  #endif
  
  extern "C" void
! __cxa_pure_virtual (void)
  {
    writestr ("pure virtual method called\n");
    std::terminate ();
  }
--- 47,56 ----
  #else
  # define writestr(str) /* Empty */
  #endif
  
  extern "C" void
! __cxxabiv1::__cxa_pure_virtual (void)
  {
    writestr ("pure virtual method called\n");
    std::terminate ();
  }
Index: typeinfo
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/typeinfo,v
retrieving revision 1.16
diff -c -5 -p -r1.16 typeinfo
*** typeinfo	5 Jul 2003 04:05:40 -0000	1.16
--- typeinfo	3 Aug 2004 06:39:42 -0000
***************
*** 35,44 ****
--- 35,46 ----
  #ifndef _TYPEINFO
  #define _TYPEINFO
  
  #include <exception>
  
+ #pragma GCC visibility push(default)
+ 
  extern "C++" {
  
  namespace __cxxabiv1
  {
    class __class_type_info;
*************** namespace std 
*** 150,156 ****
--- 152,160 ----
      // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
      virtual ~bad_typeid() throw();
    };
  } // namespace std
  
+ #pragma GCC visibility pop
+ 
  } // extern "C++"
  #endif
Index: unwind-cxx.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/unwind-cxx.h,v
retrieving revision 1.6
diff -c -5 -p -r1.6 unwind-cxx.h
*** unwind-cxx.h	5 Jul 2003 04:05:41 -0000	1.6
--- unwind-cxx.h	3 Aug 2004 06:39:42 -0000
***************
*** 38,47 ****
--- 38,49 ----
  #include <typeinfo>
  #include <exception>
  #include <cstddef>
  #include "unwind.h"
  
+ #pragma GCC visibility push(default)
+ 
  namespace __cxxabiv1
  {
  
  // A C++ exception object consists of a header, which is a wrapper around
  // an unwind object header with additional C++ specific information,
*************** __get_exception_header_from_ue (_Unwind_
*** 166,171 ****
--- 168,175 ----
    return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
  }
  
  } /* namespace __cxxabiv1 */
  
+ #pragma GCC visibility pop
+ 
  #endif // _UNWIND_CXX_H


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