xref: /openbsd-src/gnu/gcc/libstdc++-v3/libsupc++/vec.cc (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // New abi Support -*- C++ -*-
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
4*404b540aSrobert //
5*404b540aSrobert // This file is part of GCC.
6*404b540aSrobert //
7*404b540aSrobert // GCC is free software; you can redistribute it and/or modify
8*404b540aSrobert // it under the terms of the GNU General Public License as published by
9*404b540aSrobert // the Free Software Foundation; either version 2, or (at your option)
10*404b540aSrobert // any later version.
11*404b540aSrobert 
12*404b540aSrobert // GCC is distributed in the hope that it will be useful,
13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*404b540aSrobert // GNU General Public License for more details.
16*404b540aSrobert 
17*404b540aSrobert // You should have received a copy of the GNU General Public License
18*404b540aSrobert // along with GCC; see the file COPYING.  If not, write to
19*404b540aSrobert // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20*404b540aSrobert // Boston, MA 02110-1301, USA.
21*404b540aSrobert 
22*404b540aSrobert // As a special exception, you may use this file as part of a free software
23*404b540aSrobert // library without restriction.  Specifically, if other files instantiate
24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
25*404b540aSrobert // this file and link it with other files to produce an executable, this
26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
27*404b540aSrobert // the GNU General Public License.  This exception does not however
28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
29*404b540aSrobert // the GNU General Public License.
30*404b540aSrobert 
31*404b540aSrobert // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
32*404b540aSrobert 
33*404b540aSrobert #include <cxxabi.h>
34*404b540aSrobert #include <new>
35*404b540aSrobert #include <exception>
36*404b540aSrobert #include <exception_defines.h>
37*404b540aSrobert #include "unwind-cxx.h"
38*404b540aSrobert 
39*404b540aSrobert namespace __cxxabiv1
40*404b540aSrobert {
41*404b540aSrobert   namespace
42*404b540aSrobert   {
43*404b540aSrobert     struct uncatch_exception
44*404b540aSrobert     {
45*404b540aSrobert       uncatch_exception();
~uncatch_exception__cxxabiv1::__anoncf5cc0610111::uncatch_exception46*404b540aSrobert       ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); }
47*404b540aSrobert 
48*404b540aSrobert       __cxa_exception* p;
49*404b540aSrobert 
50*404b540aSrobert     private:
51*404b540aSrobert       uncatch_exception&
52*404b540aSrobert       operator=(const uncatch_exception&);
53*404b540aSrobert 
54*404b540aSrobert       uncatch_exception(const uncatch_exception&);
55*404b540aSrobert     };
56*404b540aSrobert 
uncatch_exception()57*404b540aSrobert     uncatch_exception::uncatch_exception() : p(0)
58*404b540aSrobert     {
59*404b540aSrobert       __cxa_eh_globals *globals = __cxa_get_globals_fast ();
60*404b540aSrobert 
61*404b540aSrobert       p = globals->caughtExceptions;
62*404b540aSrobert       p->handlerCount -= 1;
63*404b540aSrobert       globals->caughtExceptions = p->nextException;
64*404b540aSrobert       globals->uncaughtExceptions += 1;
65*404b540aSrobert     }
66*404b540aSrobert   }
67*404b540aSrobert 
68*404b540aSrobert   // Allocate and construct array.
69*404b540aSrobert   extern "C" void *
__cxa_vec_new(std::size_t element_count,std::size_t element_size,std::size_t padding_size,__cxa_cdtor_type constructor,__cxa_cdtor_type destructor)70*404b540aSrobert   __cxa_vec_new(std::size_t element_count,
71*404b540aSrobert 		std::size_t element_size,
72*404b540aSrobert 		std::size_t padding_size,
73*404b540aSrobert 		__cxa_cdtor_type constructor,
74*404b540aSrobert 		__cxa_cdtor_type destructor)
75*404b540aSrobert   {
76*404b540aSrobert     return __cxa_vec_new2(element_count, element_size, padding_size,
77*404b540aSrobert 			   constructor, destructor,
78*404b540aSrobert 			   &operator new[], &operator delete []);
79*404b540aSrobert   }
80*404b540aSrobert 
81*404b540aSrobert   extern "C" void *
__cxa_vec_new2(std::size_t element_count,std::size_t element_size,std::size_t padding_size,__cxa_cdtor_type constructor,__cxa_cdtor_type destructor,void * (* alloc)(std::size_t),void (* dealloc)(void *))82*404b540aSrobert   __cxa_vec_new2(std::size_t element_count,
83*404b540aSrobert 		 std::size_t element_size,
84*404b540aSrobert 		 std::size_t padding_size,
85*404b540aSrobert 		 __cxa_cdtor_type constructor,
86*404b540aSrobert 		 __cxa_cdtor_type destructor,
87*404b540aSrobert 		 void *(*alloc) (std::size_t),
88*404b540aSrobert 		 void (*dealloc) (void *))
89*404b540aSrobert   {
90*404b540aSrobert     std::size_t size = element_count * element_size + padding_size;
91*404b540aSrobert     char *base = static_cast <char *> (alloc (size));
92*404b540aSrobert     if (!base)
93*404b540aSrobert       return base;
94*404b540aSrobert 
95*404b540aSrobert     if (padding_size)
96*404b540aSrobert       {
97*404b540aSrobert 	base += padding_size;
98*404b540aSrobert 	reinterpret_cast <std::size_t *> (base)[-1] = element_count;
99*404b540aSrobert #ifdef _GLIBCXX_ELTSIZE_IN_COOKIE
100*404b540aSrobert 	reinterpret_cast <std::size_t *> (base)[-2] = element_size;
101*404b540aSrobert #endif
102*404b540aSrobert       }
103*404b540aSrobert     try
104*404b540aSrobert       {
105*404b540aSrobert 	__cxa_vec_ctor(base, element_count, element_size,
106*404b540aSrobert 		       constructor, destructor);
107*404b540aSrobert       }
108*404b540aSrobert     catch (...)
109*404b540aSrobert       {
110*404b540aSrobert 	{
111*404b540aSrobert 	  uncatch_exception ue;
112*404b540aSrobert 	  dealloc(base - padding_size);
113*404b540aSrobert 	}
114*404b540aSrobert 	__throw_exception_again;
115*404b540aSrobert       }
116*404b540aSrobert     return base;
117*404b540aSrobert   }
118*404b540aSrobert 
119*404b540aSrobert   extern "C" void *
__cxa_vec_new3(std::size_t element_count,std::size_t element_size,std::size_t padding_size,__cxa_cdtor_type constructor,__cxa_cdtor_type destructor,void * (* alloc)(std::size_t),void (* dealloc)(void *,std::size_t))120*404b540aSrobert   __cxa_vec_new3(std::size_t element_count,
121*404b540aSrobert 		 std::size_t element_size,
122*404b540aSrobert 		 std::size_t padding_size,
123*404b540aSrobert 		 __cxa_cdtor_type constructor,
124*404b540aSrobert 		 __cxa_cdtor_type destructor,
125*404b540aSrobert 		 void *(*alloc) (std::size_t),
126*404b540aSrobert 		 void (*dealloc) (void *, std::size_t))
127*404b540aSrobert   {
128*404b540aSrobert     std::size_t size = element_count * element_size + padding_size;
129*404b540aSrobert     char *base = static_cast<char *>(alloc (size));
130*404b540aSrobert     if (!base)
131*404b540aSrobert       return base;
132*404b540aSrobert 
133*404b540aSrobert     if (padding_size)
134*404b540aSrobert       {
135*404b540aSrobert 	base += padding_size;
136*404b540aSrobert 	reinterpret_cast<std::size_t *>(base)[-1] = element_count;
137*404b540aSrobert #ifdef _GLIBCXX_ELTSIZE_IN_COOKIE
138*404b540aSrobert 	reinterpret_cast <std::size_t *> (base)[-2] = element_size;
139*404b540aSrobert #endif
140*404b540aSrobert       }
141*404b540aSrobert     try
142*404b540aSrobert       {
143*404b540aSrobert 	__cxa_vec_ctor(base, element_count, element_size,
144*404b540aSrobert 		       constructor, destructor);
145*404b540aSrobert       }
146*404b540aSrobert     catch (...)
147*404b540aSrobert       {
148*404b540aSrobert 	{
149*404b540aSrobert 	  uncatch_exception ue;
150*404b540aSrobert 	  dealloc(base - padding_size, size);
151*404b540aSrobert 	}
152*404b540aSrobert 	__throw_exception_again;
153*404b540aSrobert       }
154*404b540aSrobert     return base;
155*404b540aSrobert   }
156*404b540aSrobert 
157*404b540aSrobert   // Construct array.
158*404b540aSrobert   extern "C" __cxa_vec_ctor_return_type
__cxa_vec_ctor(void * array_address,std::size_t element_count,std::size_t element_size,__cxa_cdtor_type constructor,__cxa_cdtor_type destructor)159*404b540aSrobert   __cxa_vec_ctor(void *array_address,
160*404b540aSrobert 		 std::size_t element_count,
161*404b540aSrobert 		 std::size_t element_size,
162*404b540aSrobert 		 __cxa_cdtor_type constructor,
163*404b540aSrobert 		 __cxa_cdtor_type destructor)
164*404b540aSrobert   {
165*404b540aSrobert     std::size_t ix = 0;
166*404b540aSrobert     char *ptr = static_cast<char *>(array_address);
167*404b540aSrobert 
168*404b540aSrobert     try
169*404b540aSrobert       {
170*404b540aSrobert 	if (constructor)
171*404b540aSrobert 	  for (; ix != element_count; ix++, ptr += element_size)
172*404b540aSrobert 	    constructor(ptr);
173*404b540aSrobert       }
174*404b540aSrobert     catch (...)
175*404b540aSrobert       {
176*404b540aSrobert 	{
177*404b540aSrobert 	  uncatch_exception ue;
178*404b540aSrobert 	  __cxa_vec_cleanup(array_address, ix, element_size, destructor);
179*404b540aSrobert 	}
180*404b540aSrobert 	__throw_exception_again;
181*404b540aSrobert       }
182*404b540aSrobert     _GLIBCXX_CXA_VEC_CTOR_RETURN (array_address);
183*404b540aSrobert   }
184*404b540aSrobert 
185*404b540aSrobert   // Construct an array by copying.
186*404b540aSrobert   extern "C" __cxa_vec_ctor_return_type
__cxa_vec_cctor(void * dest_array,void * src_array,std::size_t element_count,std::size_t element_size,__cxa_cdtor_return_type (* constructor)(void *,void *),__cxa_cdtor_type destructor)187*404b540aSrobert   __cxa_vec_cctor(void *dest_array,
188*404b540aSrobert 		  void *src_array,
189*404b540aSrobert 		  std::size_t element_count,
190*404b540aSrobert 		  std::size_t element_size,
191*404b540aSrobert 		  __cxa_cdtor_return_type (*constructor) (void *, void *),
192*404b540aSrobert 		  __cxa_cdtor_type destructor)
193*404b540aSrobert   {
194*404b540aSrobert     std::size_t ix = 0;
195*404b540aSrobert     char *dest_ptr = static_cast<char *>(dest_array);
196*404b540aSrobert     char *src_ptr = static_cast<char *>(src_array);
197*404b540aSrobert 
198*404b540aSrobert     try
199*404b540aSrobert       {
200*404b540aSrobert 	if (constructor)
201*404b540aSrobert 	  for (; ix != element_count;
202*404b540aSrobert 	       ix++, src_ptr += element_size, dest_ptr += element_size)
203*404b540aSrobert 	    constructor(dest_ptr, src_ptr);
204*404b540aSrobert       }
205*404b540aSrobert     catch (...)
206*404b540aSrobert       {
207*404b540aSrobert 	{
208*404b540aSrobert 	  uncatch_exception ue;
209*404b540aSrobert 	  __cxa_vec_cleanup(dest_array, ix, element_size, destructor);
210*404b540aSrobert 	}
211*404b540aSrobert 	__throw_exception_again;
212*404b540aSrobert       }
213*404b540aSrobert     _GLIBCXX_CXA_VEC_CTOR_RETURN (dest_array);
214*404b540aSrobert   }
215*404b540aSrobert 
216*404b540aSrobert   // Destruct array.
217*404b540aSrobert   extern "C" void
__cxa_vec_dtor(void * array_address,std::size_t element_count,std::size_t element_size,__cxa_cdtor_type destructor)218*404b540aSrobert   __cxa_vec_dtor(void *array_address,
219*404b540aSrobert 		 std::size_t element_count,
220*404b540aSrobert 		 std::size_t element_size,
221*404b540aSrobert 		 __cxa_cdtor_type destructor)
222*404b540aSrobert   {
223*404b540aSrobert     if (destructor)
224*404b540aSrobert       {
225*404b540aSrobert 	char *ptr = static_cast<char *>(array_address);
226*404b540aSrobert 	std::size_t ix = element_count;
227*404b540aSrobert 
228*404b540aSrobert 	ptr += element_count * element_size;
229*404b540aSrobert 
230*404b540aSrobert 	try
231*404b540aSrobert 	  {
232*404b540aSrobert 	    while (ix--)
233*404b540aSrobert 	      {
234*404b540aSrobert 		ptr -= element_size;
235*404b540aSrobert 		destructor(ptr);
236*404b540aSrobert 	      }
237*404b540aSrobert 	  }
238*404b540aSrobert 	catch (...)
239*404b540aSrobert 	  {
240*404b540aSrobert 	    {
241*404b540aSrobert 	      uncatch_exception ue;
242*404b540aSrobert 	      __cxa_vec_cleanup(array_address, ix, element_size, destructor);
243*404b540aSrobert 	    }
244*404b540aSrobert 	    __throw_exception_again;
245*404b540aSrobert 	  }
246*404b540aSrobert       }
247*404b540aSrobert   }
248*404b540aSrobert 
249*404b540aSrobert   // Destruct array as a result of throwing an exception.
250*404b540aSrobert   // [except.ctor]/3 If a destructor called during stack unwinding
251*404b540aSrobert   // exits with an exception, terminate is called.
252*404b540aSrobert   extern "C" void
__cxa_vec_cleanup(void * array_address,std::size_t element_count,std::size_t element_size,__cxa_cdtor_type destructor)253*404b540aSrobert   __cxa_vec_cleanup(void *array_address,
254*404b540aSrobert 		    std::size_t element_count,
255*404b540aSrobert 		    std::size_t element_size,
256*404b540aSrobert 		    __cxa_cdtor_type destructor)
257*404b540aSrobert   {
258*404b540aSrobert     if (destructor)
259*404b540aSrobert       {
260*404b540aSrobert 	char *ptr = static_cast <char *> (array_address);
261*404b540aSrobert 	std::size_t ix = element_count;
262*404b540aSrobert 
263*404b540aSrobert 	ptr += element_count * element_size;
264*404b540aSrobert 
265*404b540aSrobert 	try
266*404b540aSrobert 	  {
267*404b540aSrobert 	    while (ix--)
268*404b540aSrobert 	      {
269*404b540aSrobert 		ptr -= element_size;
270*404b540aSrobert 		destructor(ptr);
271*404b540aSrobert 	      }
272*404b540aSrobert 	  }
273*404b540aSrobert 	catch (...)
274*404b540aSrobert 	  {
275*404b540aSrobert 	    std::terminate();
276*404b540aSrobert 	  }
277*404b540aSrobert       }
278*404b540aSrobert   }
279*404b540aSrobert 
280*404b540aSrobert   // Destruct and release array.
281*404b540aSrobert   extern "C" void
__cxa_vec_delete(void * array_address,std::size_t element_size,std::size_t padding_size,__cxa_cdtor_type destructor)282*404b540aSrobert   __cxa_vec_delete(void *array_address,
283*404b540aSrobert 		   std::size_t element_size,
284*404b540aSrobert 		   std::size_t padding_size,
285*404b540aSrobert 		   __cxa_cdtor_type destructor)
286*404b540aSrobert   {
287*404b540aSrobert     __cxa_vec_delete2(array_address, element_size, padding_size,
288*404b540aSrobert 		       destructor,
289*404b540aSrobert 		       &operator delete []);
290*404b540aSrobert   }
291*404b540aSrobert 
292*404b540aSrobert   extern "C" void
__cxa_vec_delete2(void * array_address,std::size_t element_size,std::size_t padding_size,__cxa_cdtor_type destructor,void (* dealloc)(void *))293*404b540aSrobert   __cxa_vec_delete2(void *array_address,
294*404b540aSrobert 		    std::size_t element_size,
295*404b540aSrobert 		    std::size_t padding_size,
296*404b540aSrobert 		    __cxa_cdtor_type destructor,
297*404b540aSrobert 		    void (*dealloc) (void *))
298*404b540aSrobert   {
299*404b540aSrobert     if (!array_address)
300*404b540aSrobert       return;
301*404b540aSrobert 
302*404b540aSrobert     char* base = static_cast<char *>(array_address);
303*404b540aSrobert 
304*404b540aSrobert     if (padding_size)
305*404b540aSrobert       {
306*404b540aSrobert 	std::size_t element_count = reinterpret_cast<std::size_t *>(base)[-1];
307*404b540aSrobert 	base -= padding_size;
308*404b540aSrobert 	try
309*404b540aSrobert 	  {
310*404b540aSrobert 	    __cxa_vec_dtor(array_address, element_count, element_size,
311*404b540aSrobert 			   destructor);
312*404b540aSrobert 	  }
313*404b540aSrobert 	catch (...)
314*404b540aSrobert 	  {
315*404b540aSrobert 	    {
316*404b540aSrobert 	      uncatch_exception ue;
317*404b540aSrobert 	      dealloc(base);
318*404b540aSrobert 	    }
319*404b540aSrobert 	    __throw_exception_again;
320*404b540aSrobert 	  }
321*404b540aSrobert       }
322*404b540aSrobert     dealloc(base);
323*404b540aSrobert   }
324*404b540aSrobert 
325*404b540aSrobert   extern "C" void
__cxa_vec_delete3(void * array_address,std::size_t element_size,std::size_t padding_size,__cxa_cdtor_type destructor,void (* dealloc)(void *,std::size_t))326*404b540aSrobert   __cxa_vec_delete3(void *array_address,
327*404b540aSrobert 		    std::size_t element_size,
328*404b540aSrobert 		    std::size_t padding_size,
329*404b540aSrobert 		     __cxa_cdtor_type destructor,
330*404b540aSrobert 		    void (*dealloc) (void *, std::size_t))
331*404b540aSrobert   {
332*404b540aSrobert     if (!array_address)
333*404b540aSrobert       return;
334*404b540aSrobert 
335*404b540aSrobert     char* base = static_cast <char *> (array_address);
336*404b540aSrobert     std::size_t size = 0;
337*404b540aSrobert 
338*404b540aSrobert     if (padding_size)
339*404b540aSrobert       {
340*404b540aSrobert 	std::size_t element_count = reinterpret_cast<std::size_t *> (base)[-1];
341*404b540aSrobert 	base -= padding_size;
342*404b540aSrobert 	size = element_count * element_size + padding_size;
343*404b540aSrobert 	try
344*404b540aSrobert 	  {
345*404b540aSrobert 	    __cxa_vec_dtor(array_address, element_count, element_size,
346*404b540aSrobert 			   destructor);
347*404b540aSrobert 	  }
348*404b540aSrobert 	catch (...)
349*404b540aSrobert 	  {
350*404b540aSrobert 	    {
351*404b540aSrobert 	      uncatch_exception ue;
352*404b540aSrobert 	      dealloc(base, size);
353*404b540aSrobert 	    }
354*404b540aSrobert 	    __throw_exception_again;
355*404b540aSrobert 	  }
356*404b540aSrobert       }
357*404b540aSrobert     dealloc(base, size);
358*404b540aSrobert   }
359*404b540aSrobert } // namespace __cxxabiv1
360*404b540aSrobert 
361*404b540aSrobert #if defined(__arm__) && defined(__ARM_EABI__)
362*404b540aSrobert 
363*404b540aSrobert // The ARM C++ ABI requires that the library provide these additional
364*404b540aSrobert // helper functions.  There are placed in this file, despite being
365*404b540aSrobert // architecture-specifier, so that the compiler can inline the __cxa
366*404b540aSrobert // functions into these functions as appropriate.
367*404b540aSrobert 
368*404b540aSrobert namespace __aeabiv1
369*404b540aSrobert {
370*404b540aSrobert   extern "C" void *
__aeabi_vec_ctor_nocookie_nodtor(void * array_address,abi::__cxa_cdtor_type constructor,std::size_t element_size,std::size_t element_count)371*404b540aSrobert   __aeabi_vec_ctor_nocookie_nodtor (void *array_address,
372*404b540aSrobert 				    abi::__cxa_cdtor_type constructor,
373*404b540aSrobert 				    std::size_t element_size,
374*404b540aSrobert 				    std::size_t element_count)
375*404b540aSrobert   {
376*404b540aSrobert     return abi::__cxa_vec_ctor (array_address, element_count, element_size,
377*404b540aSrobert 				constructor, /*destructor=*/NULL);
378*404b540aSrobert   }
379*404b540aSrobert 
380*404b540aSrobert   extern "C" void *
__aeabi_vec_ctor_cookie_nodtor(void * array_address,abi::__cxa_cdtor_type constructor,std::size_t element_size,std::size_t element_count)381*404b540aSrobert   __aeabi_vec_ctor_cookie_nodtor (void *array_address,
382*404b540aSrobert 				  abi::__cxa_cdtor_type constructor,
383*404b540aSrobert 				  std::size_t element_size,
384*404b540aSrobert 				  std::size_t element_count)
385*404b540aSrobert   {
386*404b540aSrobert     if (array_address == NULL)
387*404b540aSrobert       return NULL;
388*404b540aSrobert 
389*404b540aSrobert     array_address = reinterpret_cast<std::size_t *>(array_address) + 2;
390*404b540aSrobert     reinterpret_cast<std::size_t *>(array_address)[-2] = element_size;
391*404b540aSrobert     reinterpret_cast<std::size_t *>(array_address)[-1] = element_count;
392*404b540aSrobert     return abi::__cxa_vec_ctor (array_address,
393*404b540aSrobert 				element_count, element_size,
394*404b540aSrobert 				constructor, /*destructor=*/NULL);
395*404b540aSrobert   }
396*404b540aSrobert 
397*404b540aSrobert   extern "C" void *
__aeabi_vec_cctor_nocookie_nodtor(void * dest_array,void * src_array,std::size_t element_size,std::size_t element_count,void * (* constructor)(void *,void *))398*404b540aSrobert   __aeabi_vec_cctor_nocookie_nodtor (void *dest_array,
399*404b540aSrobert 				     void *src_array,
400*404b540aSrobert 				     std::size_t element_size,
401*404b540aSrobert 				     std::size_t element_count,
402*404b540aSrobert 				     void *(*constructor) (void *, void *))
403*404b540aSrobert   {
404*404b540aSrobert     return abi::__cxa_vec_cctor (dest_array, src_array,
405*404b540aSrobert 				 element_count, element_size,
406*404b540aSrobert 				 constructor, NULL);
407*404b540aSrobert   }
408*404b540aSrobert 
409*404b540aSrobert   extern "C" void *
__aeabi_vec_new_cookie_noctor(std::size_t element_size,std::size_t element_count)410*404b540aSrobert   __aeabi_vec_new_cookie_noctor (std::size_t element_size,
411*404b540aSrobert 				 std::size_t element_count)
412*404b540aSrobert   {
413*404b540aSrobert     return abi::__cxa_vec_new(element_count, element_size,
414*404b540aSrobert 			      2 * sizeof (std::size_t),
415*404b540aSrobert 			      /*constructor=*/NULL, /*destructor=*/NULL);
416*404b540aSrobert   }
417*404b540aSrobert 
418*404b540aSrobert   extern "C" void *
__aeabi_vec_new_nocookie(std::size_t element_size,std::size_t element_count,abi::__cxa_cdtor_type constructor)419*404b540aSrobert   __aeabi_vec_new_nocookie (std::size_t element_size,
420*404b540aSrobert 			    std::size_t element_count,
421*404b540aSrobert 			    abi::__cxa_cdtor_type constructor)
422*404b540aSrobert   {
423*404b540aSrobert     return abi::__cxa_vec_new (element_count, element_size, 0, constructor,
424*404b540aSrobert 			       NULL);
425*404b540aSrobert   }
426*404b540aSrobert 
427*404b540aSrobert   extern "C" void *
__aeabi_vec_new_cookie_nodtor(std::size_t element_size,std::size_t element_count,abi::__cxa_cdtor_type constructor)428*404b540aSrobert   __aeabi_vec_new_cookie_nodtor (std::size_t element_size,
429*404b540aSrobert 				 std::size_t element_count,
430*404b540aSrobert 				 abi::__cxa_cdtor_type constructor)
431*404b540aSrobert   {
432*404b540aSrobert     return abi::__cxa_vec_new(element_count, element_size,
433*404b540aSrobert 			      2 * sizeof (std::size_t),
434*404b540aSrobert 			      constructor, NULL);
435*404b540aSrobert   }
436*404b540aSrobert 
437*404b540aSrobert   extern "C" void *
__aeabi_vec_new_cookie(std::size_t element_size,std::size_t element_count,abi::__cxa_cdtor_type constructor,abi::__cxa_cdtor_type destructor)438*404b540aSrobert   __aeabi_vec_new_cookie(std::size_t element_size,
439*404b540aSrobert 			 std::size_t element_count,
440*404b540aSrobert 			 abi::__cxa_cdtor_type constructor,
441*404b540aSrobert 			 abi::__cxa_cdtor_type destructor)
442*404b540aSrobert   {
443*404b540aSrobert     return abi::__cxa_vec_new (element_count, element_size,
444*404b540aSrobert 			       2 * sizeof (std::size_t),
445*404b540aSrobert 			       constructor, destructor);
446*404b540aSrobert   }
447*404b540aSrobert 
448*404b540aSrobert 
449*404b540aSrobert   extern "C" void *
__aeabi_vec_dtor(void * array_address,abi::__cxa_cdtor_type destructor,std::size_t element_size,std::size_t element_count)450*404b540aSrobert   __aeabi_vec_dtor (void *array_address,
451*404b540aSrobert 		    abi::__cxa_cdtor_type destructor,
452*404b540aSrobert 		    std::size_t element_size,
453*404b540aSrobert 		    std::size_t element_count)
454*404b540aSrobert   {
455*404b540aSrobert     abi::__cxa_vec_dtor (array_address, element_count, element_size,
456*404b540aSrobert 			 destructor);
457*404b540aSrobert     return reinterpret_cast<std::size_t*> (array_address) - 2;
458*404b540aSrobert   }
459*404b540aSrobert 
460*404b540aSrobert   extern "C" void *
__aeabi_vec_dtor_cookie(void * array_address,abi::__cxa_cdtor_type destructor)461*404b540aSrobert   __aeabi_vec_dtor_cookie (void *array_address,
462*404b540aSrobert 			   abi::__cxa_cdtor_type destructor)
463*404b540aSrobert   {
464*404b540aSrobert     abi::__cxa_vec_dtor (array_address,
465*404b540aSrobert 			 reinterpret_cast<std::size_t *>(array_address)[-1],
466*404b540aSrobert 			 reinterpret_cast<std::size_t *>(array_address)[-2],
467*404b540aSrobert 			 destructor);
468*404b540aSrobert     return reinterpret_cast<std::size_t*> (array_address) - 2;
469*404b540aSrobert   }
470*404b540aSrobert 
471*404b540aSrobert 
472*404b540aSrobert   extern "C" void
__aeabi_vec_delete(void * array_address,abi::__cxa_cdtor_type destructor)473*404b540aSrobert   __aeabi_vec_delete (void *array_address,
474*404b540aSrobert 		      abi::__cxa_cdtor_type destructor)
475*404b540aSrobert   {
476*404b540aSrobert     abi::__cxa_vec_delete (array_address,
477*404b540aSrobert 			   reinterpret_cast<std::size_t *>(array_address)[-2],
478*404b540aSrobert 			   2 * sizeof (std::size_t),
479*404b540aSrobert 			   destructor);
480*404b540aSrobert   }
481*404b540aSrobert 
482*404b540aSrobert   extern "C" void
__aeabi_vec_delete3(void * array_address,abi::__cxa_cdtor_type destructor,void (* dealloc)(void *,std::size_t))483*404b540aSrobert   __aeabi_vec_delete3 (void *array_address,
484*404b540aSrobert 		       abi::__cxa_cdtor_type destructor,
485*404b540aSrobert 		       void (*dealloc) (void *, std::size_t))
486*404b540aSrobert   {
487*404b540aSrobert     abi::__cxa_vec_delete3 (array_address,
488*404b540aSrobert 			    reinterpret_cast<std::size_t *>(array_address)[-2],
489*404b540aSrobert 			    2 * sizeof (std::size_t),
490*404b540aSrobert 			    destructor, dealloc);
491*404b540aSrobert   }
492*404b540aSrobert 
493*404b540aSrobert   extern "C" void
__aeabi_vec_delete3_nodtor(void * array_address,void (* dealloc)(void *,std::size_t))494*404b540aSrobert   __aeabi_vec_delete3_nodtor (void *array_address,
495*404b540aSrobert 			      void (*dealloc) (void *, std::size_t))
496*404b540aSrobert   {
497*404b540aSrobert     abi::__cxa_vec_delete3 (array_address,
498*404b540aSrobert 			    reinterpret_cast<std::size_t *>(array_address)[-2],
499*404b540aSrobert 			    2 * sizeof (std::size_t),
500*404b540aSrobert 			    /*destructor=*/NULL, dealloc);
501*404b540aSrobert   }
502*404b540aSrobert 
503*404b540aSrobert   extern "C" int
__aeabi_atexit(void * object,void (* destructor)(void *),void * dso_handle)504*404b540aSrobert   __aeabi_atexit (void *object,
505*404b540aSrobert 		  void (*destructor) (void *),
506*404b540aSrobert 		  void *dso_handle)
507*404b540aSrobert   {
508*404b540aSrobert     return abi::__cxa_atexit(destructor, object, dso_handle);
509*404b540aSrobert   }
510*404b540aSrobert } // namespace __aeabiv1
511*404b540aSrobert 
512*404b540aSrobert #endif // defined(__arm__) && defined(__ARM_EABI__)
513