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