Patchwork [trans-mem,darwin] PR/52042 find tm_clone_table with PIE

login
register
mail settings
Submitter Patrick Marlier
Date Feb. 9, 2012, 1:54 p.m.
Message ID <4F33D006.6020708@gmail.com>
Download mbox | patch
Permalink /patch/140381/
State New
Headers show

Comments

Patrick Marlier - Feb. 9, 2012, 1:54 p.m.
Hi Iain,

On 02/09/2012 07:26 AM, Iain Sandoe wrote:
> apologies for
> (a) the extra loop - I missed a deprecation warning when I built your
> last version ...
Thanks! Actually, I saw the depreciation but I didn't found that dladdr.

> (b) rolling two things into one mail ...
> ... (point 1 is related the pie issue, point 2 to linkage hassles).
>
> On 9 Feb 2012, at 08:36, Iain Sandoe wrote:
>>>
>>> I think refs (from libstdc++) should be satisfied at link time with
>>> -lstdc++ but probably I am missing something?
>>
>> when you link c++ code, that is what is required .. but obv. we don't
>> want lstdc++ on the link line for c (because the library *will* be
>> found @ runtime - and thus the routines would be called).
>>
>> I have an idea ... perhaps we supply (yet another) crt that is linked
>> last on the line and provides the dummies. That way the linkage will
>> be satisfied from libstd++ for c++ and the dummies for c.
>>
>> will try and see if I can fit a trial of that idea in on D9 & D10.
Thanks for the explanation.

> Point 2 below... now I look at this again, I wonder why the current
> scheme doesn't cause a problem for Rainer on c++ as well?
Yep, this confuses me too.

> 2/ I've moved the dummy routines to the [Darwin] tm crt endfile ..
>
> +/* Provide dummy functions to satisfy linkage for versions of the
> Darwin tool-chain that
> + that can't handle undefined weak refs at the link stage. */
> +
> +extern void *__cxa_allocate_exception (size_t) WEAK;
> +extern void __cxa_throw (void *, void *, void *) WEAK;
> +extern void *__cxa_begin_catch (void *) WEAK;
> +extern void *__cxa_end_catch (void) WEAK;
> +extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
> +
> +void *__cxa_allocate_exception (size_t s UNUSED) { return NULL; }
> +void __cxa_throw (void * a UNUSED, void * b UNUSED, void * c UNUSED)
> +{ return; }
> +void *__cxa_begin_catch (void * a UNUSED) { return NULL; }
> +void *__cxa_end_catch (void) { return NULL; }
> +void __cxa_tm_cleanup (void * a UNUSED, void * b UNUSED, unsigned int c
> UNUSED)
> +{ return; }
> +

Note you should also do the same for alloc_cpp.cc:
#if !defined (HAVE_ELF_STYLE_WEAKREF)
void *_ZnwX (size_t) { return NULL; }
void _ZdlPv (void *) { return; }
void *_ZnaX (size_t) { return NULL; }
void _ZdaPv (void *) { return; }

void *_ZnwXRKSt9nothrow_t (size_t, c_nothrow_p) { return NULL; }
void _ZdlPvRKSt9nothrow_t (void *, c_nothrow_p) { return; }
void *_ZnaXRKSt9nothrow_t (size_t, c_nothrow_p) { return NULL; }
void _ZdaPvRKSt9nothrow_t (void *, c_nothrow_p) { return; }
#endif /* HAVE_ELF_STYLE_WEAKREF */



Native configuration is x86_64-apple-darwin10.8.0

                 === libitm tests ===

Schedule of variations:
     unix

Running target unix
Using /usr/local/share/dejagnu/baseboards/unix.exp as board description 
file for target.
Using /usr/local/share/dejagnu/config/unix.exp as generic interface file 
for target.
Using /Users/patrick/gcc/trunk/libitm/testsuite/config/default.exp as 
tool-and-target-specific interface file.
Running /Users/patrick/gcc/trunk/libitm/testsuite/libitm.c/c.exp ...
Running /Users/patrick/gcc/trunk/libitm/testsuite/libitm.c++/c++.exp ...

                 === libitm Summary ===

# of expected passes            26
# of expected failures          3
# of unsupported tests          1

Tested with XCode 4.0. I do not have any darwin 11.

Thanks.
--
Patrick.
Jack Howarth - Feb. 9, 2012, 4:34 p.m.
On Thu, Feb 09, 2012 at 08:54:14AM -0500, Patrick Marlier wrote:
> Hi Iain,
>
> On 02/09/2012 07:26 AM, Iain Sandoe wrote:
>> apologies for
>> (a) the extra loop - I missed a deprecation warning when I built your
>> last version ...
> Thanks! Actually, I saw the depreciation but I didn't found that dladdr.
>
>> (b) rolling two things into one mail ...
>> ... (point 1 is related the pie issue, point 2 to linkage hassles).
>>
>> On 9 Feb 2012, at 08:36, Iain Sandoe wrote:
>>>>
>>>> I think refs (from libstdc++) should be satisfied at link time with
>>>> -lstdc++ but probably I am missing something?
>>>
>>> when you link c++ code, that is what is required .. but obv. we don't
>>> want lstdc++ on the link line for c (because the library *will* be
>>> found @ runtime - and thus the routines would be called).
>>>
>>> I have an idea ... perhaps we supply (yet another) crt that is linked
>>> last on the line and provides the dummies. That way the linkage will
>>> be satisfied from libstd++ for c++ and the dummies for c.
>>>
>>> will try and see if I can fit a trial of that idea in on D9 & D10.
> Thanks for the explanation.
>
>> Point 2 below... now I look at this again, I wonder why the current
>> scheme doesn't cause a problem for Rainer on c++ as well?
> Yep, this confuses me too.
>
>> 2/ I've moved the dummy routines to the [Darwin] tm crt endfile ..
>>
>> +/* Provide dummy functions to satisfy linkage for versions of the
>> Darwin tool-chain that
>> + that can't handle undefined weak refs at the link stage. */
>> +
>> +extern void *__cxa_allocate_exception (size_t) WEAK;
>> +extern void __cxa_throw (void *, void *, void *) WEAK;
>> +extern void *__cxa_begin_catch (void *) WEAK;
>> +extern void *__cxa_end_catch (void) WEAK;
>> +extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
>> +
>> +void *__cxa_allocate_exception (size_t s UNUSED) { return NULL; }
>> +void __cxa_throw (void * a UNUSED, void * b UNUSED, void * c UNUSED)
>> +{ return; }
>> +void *__cxa_begin_catch (void * a UNUSED) { return NULL; }
>> +void *__cxa_end_catch (void) { return NULL; }
>> +void __cxa_tm_cleanup (void * a UNUSED, void * b UNUSED, unsigned int c
>> UNUSED)
>> +{ return; }
>> +
>
> Note you should also do the same for alloc_cpp.cc:
> #if !defined (HAVE_ELF_STYLE_WEAKREF)
> void *_ZnwX (size_t) { return NULL; }
> void _ZdlPv (void *) { return; }
> void *_ZnaX (size_t) { return NULL; }
> void _ZdaPv (void *) { return; }
>
> void *_ZnwXRKSt9nothrow_t (size_t, c_nothrow_p) { return NULL; }
> void _ZdlPvRKSt9nothrow_t (void *, c_nothrow_p) { return; }
> void *_ZnaXRKSt9nothrow_t (size_t, c_nothrow_p) { return NULL; }
> void _ZdaPvRKSt9nothrow_t (void *, c_nothrow_p) { return; }
> #endif /* HAVE_ELF_STYLE_WEAKREF */
>
>
>
> Native configuration is x86_64-apple-darwin10.8.0
>
>                 === libitm tests ===
>
> Schedule of variations:
>     unix
>
> Running target unix
> Using /usr/local/share/dejagnu/baseboards/unix.exp as board description  
> file for target.
> Using /usr/local/share/dejagnu/config/unix.exp as generic interface file  
> for target.
> Using /Users/patrick/gcc/trunk/libitm/testsuite/config/default.exp as  
> tool-and-target-specific interface file.
> Running /Users/patrick/gcc/trunk/libitm/testsuite/libitm.c/c.exp ...
> Running /Users/patrick/gcc/trunk/libitm/testsuite/libitm.c++/c++.exp ...
>
>                 === libitm Summary ===
>
> # of expected passes            26
> # of expected failures          3
> # of unsupported tests          1
>
> Tested with XCode 4.0. I do not have any darwin 11.
>
> Thanks.

Patrick,
    The results for this new patch applied to r184045 on x86_64-apple-darwin11
using Xcode 4.2.1 are below.

Native configuration is x86_64-apple-darwin11.3.0

		=== libitm tests ===


Running target unix/-m32

		=== libitm Summary for unix/-m32 ===

# of expected passes		26
# of expected failures		3
# of unsupported tests		1

Running target unix/-m64

		=== libitm Summary for unix/-m64 ===

# of expected passes		26
# of expected failures		3
# of unsupported tests		1

		=== libitm Summary ===

# of expected passes		52
# of expected failures		6
# of unsupported tests		2

Compiler version: gcc libitm 
Platform: x86_64-apple-darwin11.3.0
configure flags: --prefix=/sw --prefix=/sw/lib/gcc4.7 --mandir=/sw/share/man --infodir=/sw/lib/gcc4.7/info --with-build-config=bootstrap-lto --enable-stage1-languages=c,lto --enable-languages=c,c++,fortran,lto,objc,obj-c++,java --with-gmp=/sw --with-libiconv-prefix=/sw --with-ppl=/sw --with-cloog=/sw --with-mpc=/sw --with-system-zlib --x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib --program-suffix=-fsf-4.7 --enable-checking=release --enable-cloog-backend=isl

Since we may never see the weakref linker fix available for Xcode 4.x on Snow Leopard
(as that will be Xcode 4.4 or later), we might as well avoid weakref in libitm on darwin.
           Jack

> --
> Patrick.

> Index: libitm/alloc_cpp.cc
> ===================================================================
> --- libitm/alloc_cpp.cc	(revision 183968)
> +++ libitm/alloc_cpp.cc	(working copy)
> @@ -60,7 +60,7 @@ extern void _ZdlPvRKSt9nothrow_t (void *, c_nothro
>  extern void *_ZnaXRKSt9nothrow_t (size_t, c_nothrow_p) __attribute__((weak));
>  extern void _ZdaPvRKSt9nothrow_t (void *, c_nothrow_p) __attribute__((weak));
>  
> -#if !defined (HAVE_ELF_STYLE_WEAKREF)
> +#if !defined (HAVE_ELF_STYLE_WEAKREF) && !defined (__MACH__)
>  void *_ZnwX (size_t) { return NULL; }
>  void _ZdlPv (void *) { return; }
>  void *_ZnaX (size_t) { return NULL; }
> Index: libitm/eh_cpp.cc
> ===================================================================
> --- libitm/eh_cpp.cc	(revision 183968)
> +++ libitm/eh_cpp.cc	(working copy)
> @@ -39,7 +39,7 @@ extern void *__cxa_begin_catch (void *) WEAK;
>  extern void *__cxa_end_catch (void) WEAK;
>  extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
>  
> -#if !defined (HAVE_ELF_STYLE_WEAKREF)
> +#if !defined (HAVE_ELF_STYLE_WEAKREF) && !defined (__MACH__)
>  void *__cxa_allocate_exception (size_t) { return NULL; }
>  void __cxa_throw (void *, void *, void *) { return; }
>  void *__cxa_begin_catch (void *) { return NULL; }
> Index: libgcc/config/darwin-crt-tm.c
> ===================================================================
> --- libgcc/config/darwin-crt-tm.c	(revision 183968)
> +++ libgcc/config/darwin-crt-tm.c	(working copy)
> @@ -23,33 +23,68 @@ a copy of the GCC Runtime Library Exception along
>  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  <http://www.gnu.org/licenses/>.  */
>  
> +#include "tsystem.h"
> +#include <stddef.h>
> +#include <dlfcn.h>
>  #include <mach-o/dyld.h>
> +#include <mach-o/getsect.h>
>  
> -/* not listed in mach-o/dyld.h for some reason.  */
> -extern char * getsectdata (const char*,const char*,unsigned long*); 
> +#ifdef __LP64__
> +#define GET_DATA_TMCT(mh,size) \
> +  getsectdatafromheader_64 ((struct mach_header_64*) mh, \
> +			    "__DATA", "__tm_clone_table", (uint64_t *)size)
> +#else
> +#define GET_DATA_TMCT(mh,size) \
> +  getsectdatafromheader (mh, "__DATA", "__tm_clone_table", (uint32_t *)size)
> +#endif
>  
>  #define WEAK __attribute__((weak))
> +#define UNUSED __attribute__((unused))
>  
>  extern void _ITM_registerTMCloneTable (void *, size_t) WEAK;
>  extern void _ITM_deregisterTMCloneTable (void *) WEAK;
>  
> +#if defined(START) || defined(END)
> +static inline void *getTMCloneTable (const void *f, size_t *tmct_siz)
> +{
> +  char *tmct_fixed, *tmct = NULL;
> +  unsigned int i, img_count; 
> +  struct mach_header *mh;
> +  Dl_info info;
> +  
> +  if (! dladdr (f, &info) || info.dli_fbase == NULL)
> +    abort ();
> +  
> +  mh = (struct mach_header *) info.dli_fbase;
> +  tmct_fixed = GET_DATA_TMCT (mh, tmct_siz);
> +  *tmct_siz /= (sizeof (size_t) * 2);
> +  /* No tm_clone_table or no clones. */
> +  if (tmct_fixed == NULL || *tmct_siz == 0)
> +    return NULL; 
> +
> +  img_count = _dyld_image_count();
> +  for (i = 0; i < img_count && tmct == NULL; i++)
> +    {
> +      if (mh == _dyld_get_image_header(i))
> +	tmct = tmct_fixed + (unsigned long)_dyld_get_image_vmaddr_slide(i); 
> +    }
> +
> +  return tmct;
> +}
> +#endif
> +
>  #ifdef START
>  
>  void __doTMRegistrations (void) __attribute__ ((constructor));
>  
>  void __doTMRegistrations (void)
>  {
> -  char * tm_clone_table_sect_data;
> -  unsigned long tmct_siz;
> -  
> -  tm_clone_table_sect_data = getsectdata ("__DATA",
> -					  "__tm_clone_table",
> -					  &tmct_siz);
> -  tmct_siz /= (sizeof (size_t) * 2);
> -  if (_ITM_registerTMCloneTable != NULL
> -      && tm_clone_table_sect_data != NULL
> -      && tmct_siz > 0)
> -    _ITM_registerTMCloneTable (tm_clone_table_sect_data, (size_t)tmct_siz);
> +  size_t tmct_siz;
> +  void *tmct;
> +
> +  tmct = getTMCloneTable ((const void *)&__doTMRegistrations, &tmct_siz);
> +  if (_ITM_registerTMCloneTable != NULL && tmct != NULL)
> +    _ITM_registerTMCloneTable (tmct, (size_t)tmct_siz);
>  }
>  
>  #endif
> @@ -60,18 +95,53 @@ void __doTMdeRegistrations (void) __attribute__ ((
>  
>  void __doTMdeRegistrations (void)
>  {
> -  char * tm_clone_table_sect_data;
> -  unsigned long tmct_siz;
> -  
> -  tm_clone_table_sect_data = getsectdata ("__DATA",
> -					  "__tm_clone_table",
> -					  &tmct_siz);
> -  
> -  if (_ITM_deregisterTMCloneTable != NULL
> -      && tm_clone_table_sect_data != NULL
> -      && tmct_siz > 0)
> -    _ITM_deregisterTMCloneTable (tm_clone_table_sect_data);
> +  size_t tmct_siz;
> +  void *tmct;
>  
> +  tmct = getTMCloneTable ((const void *)&__doTMdeRegistrations, &tmct_siz);
> +  if (_ITM_deregisterTMCloneTable != NULL && tmct != NULL)
> +    _ITM_deregisterTMCloneTable (tmct);
>  }
>  
> +/* Provide dummy functions to satisfy linkage for versions of the Darwin tool-chain that
> +   that can't handle undefined weak refs at the link stage.  */
> +
> +extern void *__cxa_allocate_exception (size_t) WEAK;
> +extern void __cxa_throw (void *, void *, void *) WEAK;
> +extern void *__cxa_begin_catch (void *) WEAK;
> +extern void *__cxa_end_catch (void) WEAK;
> +extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
> +
> +void *__cxa_allocate_exception (size_t s UNUSED) { return NULL; }
> +void __cxa_throw (void * a UNUSED, void * b UNUSED, void * c UNUSED)
> +{ return; }
> +void *__cxa_begin_catch (void * a UNUSED) { return NULL; }
> +void *__cxa_end_catch (void) { return NULL; }
> +void __cxa_tm_cleanup (void * a UNUSED, void * b UNUSED,  unsigned int c UNUSED)
> +{ return; }
> +
> +extern void *_ZnwX (size_t) WEAK;
> +extern void _ZdlPv (void *) WEAK;
> +extern void *_ZnaX (size_t) WEAK;
> +extern void _ZdaPv (void *) WEAK;
> +
> +typedef const struct nothrow_t { } *c_nothrow_p;
> +
> +extern void *_ZnwXRKSt9nothrow_t (size_t, c_nothrow_p) WEAK;
> +extern void _ZdlPvRKSt9nothrow_t (void *, c_nothrow_p) WEAK;
> +extern void *_ZnaXRKSt9nothrow_t (size_t, c_nothrow_p) WEAK;
> +extern void _ZdaPvRKSt9nothrow_t (void *, c_nothrow_p) WEAK;
> +
> +void *_ZnwX (size_t s UNUSED) { return NULL; }
> +void _ZdlPv (void * a UNUSED) { return; }
> +void *_ZnaX (size_t s UNUSED) { return NULL; }
> +void _ZdaPv (void * a UNUSED) { return; }
> +
> +void *_ZnwXRKSt9nothrow_t (size_t s UNUSED, c_nothrow_p b UNUSED)
> +  { return NULL; }
> +void _ZdlPvRKSt9nothrow_t (void * a UNUSED, c_nothrow_p b UNUSED)  { return; }
> +void *_ZnaXRKSt9nothrow_t (size_t s UNUSED, c_nothrow_p b UNUSED)
> + { return NULL; }
> +void _ZdaPvRKSt9nothrow_t (void * a UNUSED, c_nothrow_p b UNUSED) { return; }
> +
>  #endif

Patch

Index: libitm/alloc_cpp.cc
===================================================================
--- libitm/alloc_cpp.cc	(revision 183968)
+++ libitm/alloc_cpp.cc	(working copy)
@@ -60,7 +60,7 @@  extern void _ZdlPvRKSt9nothrow_t (void *, c_nothro
 extern void *_ZnaXRKSt9nothrow_t (size_t, c_nothrow_p) __attribute__((weak));
 extern void _ZdaPvRKSt9nothrow_t (void *, c_nothrow_p) __attribute__((weak));
 
-#if !defined (HAVE_ELF_STYLE_WEAKREF)
+#if !defined (HAVE_ELF_STYLE_WEAKREF) && !defined (__MACH__)
 void *_ZnwX (size_t) { return NULL; }
 void _ZdlPv (void *) { return; }
 void *_ZnaX (size_t) { return NULL; }
Index: libitm/eh_cpp.cc
===================================================================
--- libitm/eh_cpp.cc	(revision 183968)
+++ libitm/eh_cpp.cc	(working copy)
@@ -39,7 +39,7 @@  extern void *__cxa_begin_catch (void *) WEAK;
 extern void *__cxa_end_catch (void) WEAK;
 extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
 
-#if !defined (HAVE_ELF_STYLE_WEAKREF)
+#if !defined (HAVE_ELF_STYLE_WEAKREF) && !defined (__MACH__)
 void *__cxa_allocate_exception (size_t) { return NULL; }
 void __cxa_throw (void *, void *, void *) { return; }
 void *__cxa_begin_catch (void *) { return NULL; }
Index: libgcc/config/darwin-crt-tm.c
===================================================================
--- libgcc/config/darwin-crt-tm.c	(revision 183968)
+++ libgcc/config/darwin-crt-tm.c	(working copy)
@@ -23,33 +23,68 @@  a copy of the GCC Runtime Library Exception along
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
+#include "tsystem.h"
+#include <stddef.h>
+#include <dlfcn.h>
 #include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
 
-/* not listed in mach-o/dyld.h for some reason.  */
-extern char * getsectdata (const char*,const char*,unsigned long*); 
+#ifdef __LP64__
+#define GET_DATA_TMCT(mh,size) \
+  getsectdatafromheader_64 ((struct mach_header_64*) mh, \
+			    "__DATA", "__tm_clone_table", (uint64_t *)size)
+#else
+#define GET_DATA_TMCT(mh,size) \
+  getsectdatafromheader (mh, "__DATA", "__tm_clone_table", (uint32_t *)size)
+#endif
 
 #define WEAK __attribute__((weak))
+#define UNUSED __attribute__((unused))
 
 extern void _ITM_registerTMCloneTable (void *, size_t) WEAK;
 extern void _ITM_deregisterTMCloneTable (void *) WEAK;
 
+#if defined(START) || defined(END)
+static inline void *getTMCloneTable (const void *f, size_t *tmct_siz)
+{
+  char *tmct_fixed, *tmct = NULL;
+  unsigned int i, img_count; 
+  struct mach_header *mh;
+  Dl_info info;
+  
+  if (! dladdr (f, &info) || info.dli_fbase == NULL)
+    abort ();
+  
+  mh = (struct mach_header *) info.dli_fbase;
+  tmct_fixed = GET_DATA_TMCT (mh, tmct_siz);
+  *tmct_siz /= (sizeof (size_t) * 2);
+  /* No tm_clone_table or no clones. */
+  if (tmct_fixed == NULL || *tmct_siz == 0)
+    return NULL; 
+
+  img_count = _dyld_image_count();
+  for (i = 0; i < img_count && tmct == NULL; i++)
+    {
+      if (mh == _dyld_get_image_header(i))
+	tmct = tmct_fixed + (unsigned long)_dyld_get_image_vmaddr_slide(i); 
+    }
+
+  return tmct;
+}
+#endif
+
 #ifdef START
 
 void __doTMRegistrations (void) __attribute__ ((constructor));
 
 void __doTMRegistrations (void)
 {
-  char * tm_clone_table_sect_data;
-  unsigned long tmct_siz;
-  
-  tm_clone_table_sect_data = getsectdata ("__DATA",
-					  "__tm_clone_table",
-					  &tmct_siz);
-  tmct_siz /= (sizeof (size_t) * 2);
-  if (_ITM_registerTMCloneTable != NULL
-      && tm_clone_table_sect_data != NULL
-      && tmct_siz > 0)
-    _ITM_registerTMCloneTable (tm_clone_table_sect_data, (size_t)tmct_siz);
+  size_t tmct_siz;
+  void *tmct;
+
+  tmct = getTMCloneTable ((const void *)&__doTMRegistrations, &tmct_siz);
+  if (_ITM_registerTMCloneTable != NULL && tmct != NULL)
+    _ITM_registerTMCloneTable (tmct, (size_t)tmct_siz);
 }
 
 #endif
@@ -60,18 +95,53 @@  void __doTMdeRegistrations (void) __attribute__ ((
 
 void __doTMdeRegistrations (void)
 {
-  char * tm_clone_table_sect_data;
-  unsigned long tmct_siz;
-  
-  tm_clone_table_sect_data = getsectdata ("__DATA",
-					  "__tm_clone_table",
-					  &tmct_siz);
-  
-  if (_ITM_deregisterTMCloneTable != NULL
-      && tm_clone_table_sect_data != NULL
-      && tmct_siz > 0)
-    _ITM_deregisterTMCloneTable (tm_clone_table_sect_data);
+  size_t tmct_siz;
+  void *tmct;
 
+  tmct = getTMCloneTable ((const void *)&__doTMdeRegistrations, &tmct_siz);
+  if (_ITM_deregisterTMCloneTable != NULL && tmct != NULL)
+    _ITM_deregisterTMCloneTable (tmct);
 }
 
+/* Provide dummy functions to satisfy linkage for versions of the Darwin tool-chain that
+   that can't handle undefined weak refs at the link stage.  */
+
+extern void *__cxa_allocate_exception (size_t) WEAK;
+extern void __cxa_throw (void *, void *, void *) WEAK;
+extern void *__cxa_begin_catch (void *) WEAK;
+extern void *__cxa_end_catch (void) WEAK;
+extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
+
+void *__cxa_allocate_exception (size_t s UNUSED) { return NULL; }
+void __cxa_throw (void * a UNUSED, void * b UNUSED, void * c UNUSED)
+{ return; }
+void *__cxa_begin_catch (void * a UNUSED) { return NULL; }
+void *__cxa_end_catch (void) { return NULL; }
+void __cxa_tm_cleanup (void * a UNUSED, void * b UNUSED,  unsigned int c UNUSED)
+{ return; }
+
+extern void *_ZnwX (size_t) WEAK;
+extern void _ZdlPv (void *) WEAK;
+extern void *_ZnaX (size_t) WEAK;
+extern void _ZdaPv (void *) WEAK;
+
+typedef const struct nothrow_t { } *c_nothrow_p;
+
+extern void *_ZnwXRKSt9nothrow_t (size_t, c_nothrow_p) WEAK;
+extern void _ZdlPvRKSt9nothrow_t (void *, c_nothrow_p) WEAK;
+extern void *_ZnaXRKSt9nothrow_t (size_t, c_nothrow_p) WEAK;
+extern void _ZdaPvRKSt9nothrow_t (void *, c_nothrow_p) WEAK;
+
+void *_ZnwX (size_t s UNUSED) { return NULL; }
+void _ZdlPv (void * a UNUSED) { return; }
+void *_ZnaX (size_t s UNUSED) { return NULL; }
+void _ZdaPv (void * a UNUSED) { return; }
+
+void *_ZnwXRKSt9nothrow_t (size_t s UNUSED, c_nothrow_p b UNUSED)
+  { return NULL; }
+void _ZdlPvRKSt9nothrow_t (void * a UNUSED, c_nothrow_p b UNUSED)  { return; }
+void *_ZnaXRKSt9nothrow_t (size_t s UNUSED, c_nothrow_p b UNUSED)
+ { return NULL; }
+void _ZdaPvRKSt9nothrow_t (void * a UNUSED, c_nothrow_p b UNUSED) { return; }
+
 #endif