This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix linkage in libsupc++
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Mon, 2 Aug 2004 23:57:35 -0700
- Subject: PATCH: Fix linkage in libsupc++
- Reply-to: mark at codesourcery dot com
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