[Midnightbsd-cvs] src [7451] trunk/contrib/libcxxrt: sync version with freebsd 10 stable
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sun Feb 28 16:26:58 EST 2016
Revision: 7451
http://svnweb.midnightbsd.org/src/?rev=7451
Author: laffer1
Date: 2016-02-28 16:26:57 -0500 (Sun, 28 Feb 2016)
Log Message:
-----------
sync version with freebsd 10 stable
Modified Paths:
--------------
trunk/contrib/libcxxrt/auxhelper.cc
trunk/contrib/libcxxrt/cxxabi.h
trunk/contrib/libcxxrt/dwarf_eh.h
trunk/contrib/libcxxrt/dynamic_cast.cc
trunk/contrib/libcxxrt/exception.cc
trunk/contrib/libcxxrt/guard.cc
trunk/contrib/libcxxrt/libelftc_dem_gnu3.c
trunk/contrib/libcxxrt/memory.cc
trunk/contrib/libcxxrt/stdexcept.cc
trunk/contrib/libcxxrt/stdexcept.h
trunk/contrib/libcxxrt/typeinfo.cc
trunk/contrib/libcxxrt/typeinfo.h
trunk/contrib/libcxxrt/unwind-arm.h
trunk/contrib/libcxxrt/unwind-itanium.h
trunk/contrib/libcxxrt/unwind.h
Added Paths:
-----------
trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade
trunk/contrib/libcxxrt/atomic.h
Removed Paths:
-------------
trunk/contrib/libcxxrt/FREEBSD-upgrade
Deleted: trunk/contrib/libcxxrt/FREEBSD-upgrade
===================================================================
--- trunk/contrib/libcxxrt/FREEBSD-upgrade 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/FREEBSD-upgrade 2016-02-28 21:26:57 UTC (rev 7451)
@@ -1,6 +0,0 @@
-$FreeBSD$
-
-This is the FreeBSD copy of libcxxrt. It contains the src directory from the
-upstream repository.
-
-When updating, copy *.{c,cc,h} and typeinfo from the upstream src/.
Copied: trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade (from rev 7446, trunk/contrib/libcxxrt/FREEBSD-upgrade)
===================================================================
--- trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade (rev 0)
+++ trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade 2016-02-28 21:26:57 UTC (rev 7451)
@@ -0,0 +1,6 @@
+$MidnightBSD$
+
+This is the MidnightBSD copy of libcxxrt. It contains the src directory from
+the upstream repository.
+
+When updating, copy *.{c,cc,h} and typeinfo from the upstream src/.
Added: trunk/contrib/libcxxrt/atomic.h
===================================================================
--- trunk/contrib/libcxxrt/atomic.h (rev 0)
+++ trunk/contrib/libcxxrt/atomic.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -0,0 +1,30 @@
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+/**
+ * Swap macro that enforces a happens-before relationship with a corresponding
+ * ATOMIC_LOAD.
+ */
+#if __has_builtin(__c11_atomic_exchange)
+#define ATOMIC_SWAP(addr, val)\
+ __c11_atomic_exchange(reinterpret_cast<_Atomic(__typeof__(val))*>(addr), val, __ATOMIC_ACQ_REL)
+#elif __has_builtin(__sync_swap)
+#define ATOMIC_SWAP(addr, val)\
+ __sync_swap(addr, val)
+#else
+#define ATOMIC_SWAP(addr, val)\
+ __sync_lock_test_and_set(addr, val)
+#endif
+
+#if __has_builtin(__c11_atomic_load)
+#define ATOMIC_LOAD(addr)\
+ __c11_atomic_load(reinterpret_cast<_Atomic(__typeof__(*addr))*>(addr), __ATOMIC_ACQUIRE)
+#else
+#define ATOMIC_LOAD(addr)\
+ (__sync_synchronize(), *addr)
+#endif
+
Property changes on: trunk/contrib/libcxxrt/atomic.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/contrib/libcxxrt/auxhelper.cc
===================================================================
--- trunk/contrib/libcxxrt/auxhelper.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/auxhelper.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -65,3 +65,18 @@
abort();
}
+/**
+ * Compilers may (but are not required to) set any deleted-virtual function's
+ * vtable entry to this function. This makes debugging slightly easier, as
+ * users can add a breakpoint on this function to tell if they've accidentally
+ * called a deleted-virtual function.
+ */
+extern "C" void __cxa_deleted_virtual()
+{
+ abort();
+}
+
+extern "C" void __cxa_throw_bad_array_new_length()
+{
+ throw std::bad_array_new_length();
+}
Modified: trunk/contrib/libcxxrt/cxxabi.h
===================================================================
--- trunk/contrib/libcxxrt/cxxabi.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/cxxabi.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -22,6 +22,7 @@
#ifndef __CXXABI_H_
#define __CXXABI_H_
+#include <stddef.h>
#include <stdint.h>
#include "unwind.h"
namespace std
@@ -109,7 +110,7 @@
* handler count reaches 0 (which it doesn't with the top bit set).
*/
int handlerCount;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
/**
* The ARM EH ABI requires the unwind library to keep track of exceptions
* during cleanups. These support nesting, so we need to keep a list of
@@ -193,6 +194,8 @@
*/
__cxa_eh_globals *__cxa_get_globals_fast(void);
+std::type_info * __cxa_current_exception_type();
+
/**
* Throws an exception returned by __cxa_current_primary_exception(). This
* exception may have been caught in another thread.
Modified: trunk/contrib/libcxxrt/dwarf_eh.h
===================================================================
--- trunk/contrib/libcxxrt/dwarf_eh.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/dwarf_eh.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -57,6 +57,8 @@
/// DWARF data encoding types.
enum dwarf_data_encoding
{
+ /// Absolute pointer value
+ DW_EH_PE_absptr = 0x00,
/// Unsigned, little-endian, base 128-encoded (variable length).
DW_EH_PE_uleb128 = 0x01,
/// Unsigned 16-bit integer.
@@ -81,7 +83,7 @@
*/
static inline enum dwarf_data_encoding get_encoding(unsigned char x)
{
- return (enum dwarf_data_encoding)(x & 0xf);
+ return static_cast<enum dwarf_data_encoding>(x & 0xf);
}
/**
@@ -95,8 +97,6 @@
{
/// Value is omitted
DW_EH_PE_omit = 0xff,
- /// Absolute pointer value
- DW_EH_PE_absptr = 0x00,
/// Value relative to program counter
DW_EH_PE_pcrel = 0x10,
/// Value relative to the text segment
@@ -115,7 +115,7 @@
*/
static inline enum dwarf_data_relative get_base(unsigned char x)
{
- return (enum dwarf_data_relative)(x & 0x70);
+ return static_cast<enum dwarf_data_relative>(x & 0x70);
}
/**
* Returns whether an encoding represents an indirect address.
@@ -206,9 +206,9 @@
if ((uleb >> (bits-1)) == 1)
{
// Sign extend by setting all bits in front of it to 1
- uleb |= ((int64_t)-1) << bits;
+ uleb |= static_cast<int64_t>(-1) << bits;
}
- return (int64_t)uleb;
+ return static_cast<int64_t>(uleb);
}
/**
* Reads a value using the specified encoding from the address pointed to by
@@ -218,15 +218,17 @@
static uint64_t read_value(char encoding, dw_eh_ptr_t *data)
{
enum dwarf_data_encoding type = get_encoding(encoding);
- uint64_t v;
switch (type)
{
// Read fixed-length types
#define READ(dwarf, type) \
case dwarf:\
- v = (uint64_t)(*(type*)(*data));\
- *data += sizeof(type);\
- break;
+ {\
+ type t;\
+ memcpy(&t, *data, sizeof t);\
+ *data += sizeof t;\
+ return static_cast<uint64_t>(t);\
+ }
READ(DW_EH_PE_udata2, uint16_t)
READ(DW_EH_PE_udata4, uint32_t)
READ(DW_EH_PE_udata8, uint64_t)
@@ -237,15 +239,11 @@
#undef READ
// Read variable-length types
case DW_EH_PE_sleb128:
- v = read_sleb128(data);
- break;
+ return read_sleb128(data);
case DW_EH_PE_uleb128:
- v = read_uleb128(data);
- break;
+ return read_uleb128(data);
default: abort();
}
-
- return v;
}
/**
@@ -263,16 +261,16 @@
switch (get_base(encoding))
{
case DW_EH_PE_pcrel:
- v += (uint64_t)start;
+ v += reinterpret_cast<uint64_t>(start);
break;
case DW_EH_PE_textrel:
- v += (uint64_t)_Unwind_GetTextRelBase(c);
+ v += static_cast<uint64_t>(static_cast<uintptr_t>(_Unwind_GetTextRelBase(c)));
break;
case DW_EH_PE_datarel:
- v += (uint64_t)_Unwind_GetDataRelBase(c);
+ v += static_cast<uint64_t>(static_cast<uintptr_t>(_Unwind_GetDataRelBase(c)));
break;
case DW_EH_PE_funcrel:
- v += (uint64_t)_Unwind_GetRegionStart(c);
+ v += static_cast<uint64_t>(static_cast<uintptr_t>(_Unwind_GetRegionStart(c)));
default:
break;
}
@@ -282,7 +280,7 @@
// be a GCC extensions, so not properly documented...
if (is_indirect(encoding))
{
- v = (uint64_t)(uintptr_t)*(void**)v;
+ v = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(*reinterpret_cast<void**>(v)));
}
return v;
}
@@ -342,14 +340,14 @@
{
struct dwarf_eh_lsda lsda;
- lsda.region_start = (dw_eh_ptr_t)(uintptr_t)_Unwind_GetRegionStart(context);
+ lsda.region_start = reinterpret_cast<dw_eh_ptr_t>(_Unwind_GetRegionStart(context));
// If the landing pads are relative to anything other than the start of
// this region, find out where. This is @LPStart in the spec, although the
// encoding that GCC uses does not quite match the spec.
- uint64_t v = (uint64_t)(uintptr_t)lsda.region_start;
+ uint64_t v = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(lsda.region_start));
read_value_with_encoding(context, &data, &v);
- lsda.landing_pads = (dw_eh_ptr_t)(uintptr_t)v;
+ lsda.landing_pads = reinterpret_cast<dw_eh_ptr_t>(static_cast<uintptr_t>(v));
// If there is a type table, find out where it is. This is @TTBase in the
// spec. Note: we find whether there is a type table pointer by checking
@@ -365,18 +363,18 @@
lsda.type_table = type_table;
//lsda.type_table = (uintptr_t*)(data + v);
}
-#if __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
lsda.type_table_encoding = (DW_EH_PE_pcrel | DW_EH_PE_indirect);
#endif
- lsda.callsite_encoding = (enum dwarf_data_encoding)(*(data++));
+ lsda.callsite_encoding = static_cast<enum dwarf_data_encoding>(*(data++));
// Action table is immediately after the call site table
lsda.action_table = data;
- uintptr_t callsite_size = (uintptr_t)read_uleb128(&data);
+ uintptr_t callsite_size = static_cast<uintptr_t>(read_uleb128(&data));
lsda.action_table = data + callsite_size;
// Call site table is immediately after the header
- lsda.call_site_table = (dw_eh_ptr_t)data;
+ lsda.call_site_table = static_cast<dw_eh_ptr_t>(data);
return lsda;
@@ -413,7 +411,7 @@
result->landing_pad = 0;
// The current instruction pointer offset within the region
uint64_t ip = _Unwind_GetIP(context) - _Unwind_GetRegionStart(context);
- unsigned char *callsite_table = (unsigned char*)lsda->call_site_table;
+ unsigned char *callsite_table = static_cast<unsigned char*>(lsda->call_site_table);
while (callsite_table <= lsda->action_table)
{
@@ -463,17 +461,17 @@
/// Defines an exception class from 8 bytes (endian independent)
#define EXCEPTION_CLASS(a,b,c,d,e,f,g,h) \
- (((uint64_t)a << 56) +\
- ((uint64_t)b << 48) +\
- ((uint64_t)c << 40) +\
- ((uint64_t)d << 32) +\
- ((uint64_t)e << 24) +\
- ((uint64_t)f << 16) +\
- ((uint64_t)g << 8) +\
- ((uint64_t)h))
+ ((static_cast<uint64_t>(a) << 56) +\
+ (static_cast<uint64_t>(b) << 48) +\
+ (static_cast<uint64_t>(c) << 40) +\
+ (static_cast<uint64_t>(d) << 32) +\
+ (static_cast<uint64_t>(e) << 24) +\
+ (static_cast<uint64_t>(f) << 16) +\
+ (static_cast<uint64_t>(g) << 8) +\
+ (static_cast<uint64_t>(h)))
#define GENERIC_EXCEPTION_CLASS(e,f,g,h) \
- ((uint32_t)e << 24) +\
- ((uint32_t)f << 16) +\
- ((uint32_t)g << 8) +\
- ((uint32_t)h)
+ (static_cast<uint32_t>(e) << 24) +\
+ (static_cast<uint32_t>(f) << 16) +\
+ (static_cast<uint32_t>(g) << 8) +\
+ (static_cast<uint32_t>(h))
Modified: trunk/contrib/libcxxrt/dynamic_cast.cc
===================================================================
--- trunk/contrib/libcxxrt/dynamic_cast.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/dynamic_cast.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -44,7 +44,7 @@
* Simple macro that does pointer arithmetic in bytes but returns a value of
* the same type as the original.
*/
-#define ADD_TO_PTR(x, off) (__typeof__(x))(((char*)x) + off)
+#define ADD_TO_PTR(x, off) reinterpret_cast<__typeof__(x)>(reinterpret_cast<char*>(x) + off)
bool std::type_info::__do_catch(std::type_info const *ex_type,
void **exception_object,
@@ -166,7 +166,7 @@
if (info->isVirtual())
{
// Object's vtable
- ptrdiff_t *off = *(ptrdiff_t**)obj;
+ ptrdiff_t *off = *static_cast<ptrdiff_t**>(obj);
// Offset location in vtable
off = ADD_TO_PTR(off, offset);
offset = *off;
@@ -202,9 +202,9 @@
const __class_type_info *dst,
ptrdiff_t src2dst_offset)
{
- char *vtable_location = *(char**)sub;
+ const char *vtable_location = *static_cast<const char * const *>(sub);
const vtable_header *header =
- (const vtable_header*)(vtable_location - sizeof(vtable_header));
- void *leaf = ADD_TO_PTR((void*)sub, header->leaf_offset);
+ reinterpret_cast<const vtable_header*>(vtable_location - sizeof(vtable_header));
+ void *leaf = ADD_TO_PTR(const_cast<void *>(sub), header->leaf_offset);
return header->type->cast_to(leaf, dst);
}
Modified: trunk/contrib/libcxxrt/exception.cc
===================================================================
--- trunk/contrib/libcxxrt/exception.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/exception.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -32,6 +32,7 @@
#include <pthread.h>
#include "typeinfo.h"
#include "dwarf_eh.h"
+#include "atomic.h"
#include "cxxabi.h"
#pragma weak pthread_key_create
@@ -38,6 +39,24 @@
#pragma weak pthread_setspecific
#pragma weak pthread_getspecific
#pragma weak pthread_once
+#ifdef LIBCXXRT_WEAK_LOCKS
+#pragma weak pthread_mutex_lock
+#define pthread_mutex_lock(mtx) do {\
+ if (pthread_mutex_lock) pthread_mutex_lock(mtx);\
+ } while(0)
+#pragma weak pthread_mutex_unlock
+#define pthread_mutex_unlock(mtx) do {\
+ if (pthread_mutex_unlock) pthread_mutex_unlock(mtx);\
+ } while(0)
+#pragma weak pthread_cond_signal
+#define pthread_cond_signal(cv) do {\
+ if (pthread_cond_signal) pthread_cond_signal(cv);\
+ } while(0)
+#pragma weak pthread_cond_wait
+#define pthread_cond_wait(cv, mtx) do {\
+ if (pthread_cond_wait) pthread_cond_wait(cv, mtx);\
+ } while(0)
+#endif
using namespace ABI_NAMESPACE;
@@ -52,11 +71,11 @@
int selector,
dw_eh_ptr_t landingPad)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
// On ARM, we store the saved exception in the generic part of the structure
ucb->barrier_cache.sp = _Unwind_GetGR(context, 13);
- ucb->barrier_cache.bitpattern[1] = (uint32_t)selector;
- ucb->barrier_cache.bitpattern[3] = (uint32_t)landingPad;
+ ucb->barrier_cache.bitpattern[1] = static_cast<uint32_t>(selector);
+ ucb->barrier_cache.bitpattern[3] = reinterpret_cast<uint32_t>(landingPad);
#endif
// Cache the results for the phase 2 unwind, if we found a handler
// and this is not a foreign exception.
@@ -76,15 +95,15 @@
unsigned long *selector,
dw_eh_ptr_t *landingPad)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
*selector = ucb->barrier_cache.bitpattern[1];
- *landingPad = (dw_eh_ptr_t)ucb->barrier_cache.bitpattern[3];
+ *landingPad = reinterpret_cast<dw_eh_ptr_t>(ucb->barrier_cache.bitpattern[3]);
return 1;
#else
if (ex)
{
*selector = ex->handlerSwitchValue;
- *landingPad = (dw_eh_ptr_t)ex->catchTemp;
+ *landingPad = reinterpret_cast<dw_eh_ptr_t>(ex->catchTemp);
return 0;
}
return 0;
@@ -94,7 +113,7 @@
static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex,
struct _Unwind_Context *context)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; }
#endif
return _URC_CONTINUE_UNWIND;
@@ -155,6 +174,17 @@
*/
_Unwind_Exception *currentCleanup;
/**
+ * Our state with respect to foreign exceptions. Usually none, set to
+ * caught if we have just caught an exception and rethrown if we are
+ * rethrowing it.
+ */
+ enum
+ {
+ none,
+ caught,
+ rethrown
+ } foreign_exception_state;
+ /**
* The public part of this structure, accessible from outside of this
* module.
*/
@@ -174,7 +204,7 @@
terminate_handler terminateHandler;
__cxa_exception *nextException;
int handlerCount;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
_Unwind_Exception *nextCleanup;
int cleanupCount;
#endif
@@ -202,8 +232,6 @@
}
-extern "C" std::type_info *__cxa_current_exception_type();
-
/**
* Class of exceptions to distinguish between this and other exception types.
*
@@ -239,13 +267,13 @@
static __cxa_exception *exceptionFromPointer(void *ex)
{
- return (__cxa_exception*)((char*)ex -
+ return reinterpret_cast<__cxa_exception*>(static_cast<char*>(ex) -
offsetof(struct __cxa_exception, unwindHeader));
}
static __cxa_exception *realExceptionFromException(__cxa_exception *ex)
{
if (!isDependentException(ex->unwindHeader.exception_class)) { return ex; }
- return ((__cxa_exception*)(((__cxa_dependent_exception*)ex)->primaryException))-1;
+ return reinterpret_cast<__cxa_exception*>((reinterpret_cast<__cxa_dependent_exception*>(ex))->primaryException)-1;
}
@@ -276,13 +304,13 @@
static void exception_cleanup(_Unwind_Reason_Code reason,
struct _Unwind_Exception *ex)
{
- __cxa_free_exception((void*)ex);
+ __cxa_free_exception(static_cast<void*>(ex));
}
static void dependent_exception_cleanup(_Unwind_Reason_Code reason,
struct _Unwind_Exception *ex)
{
- __cxa_free_dependent_exception((void*)ex);
+ __cxa_free_dependent_exception(static_cast<void*>(ex));
}
/**
@@ -305,10 +333,19 @@
*/
static void thread_cleanup(void* thread_info)
{
- __cxa_thread_info *info = (__cxa_thread_info*)thread_info;
+ __cxa_thread_info *info = static_cast<__cxa_thread_info*>(thread_info);
if (info->globals.caughtExceptions)
{
- free_exception_list(info->globals.caughtExceptions);
+ // If this is a foreign exception, ask it to clean itself up.
+ if (info->foreign_exception_state != __cxa_thread_info::none)
+ {
+ _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions);
+ e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
+ }
+ else
+ {
+ free_exception_list(info->globals.caughtExceptions);
+ }
}
free(thread_info);
}
@@ -342,8 +379,8 @@
return;
}
pthread_key_create(&eh_key, thread_cleanup);
- pthread_setspecific(eh_key, (void*)0x42);
- fakeTLS = (pthread_getspecific(eh_key) != (void*)0x42);
+ pthread_setspecific(eh_key, reinterpret_cast<void *>(0x42));
+ fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast<void *>(0x42));
pthread_setspecific(eh_key, 0);
}
@@ -357,10 +394,10 @@
fakeTLS = true;
}
if (fakeTLS) { return &singleThreadInfo; }
- __cxa_thread_info *info = (__cxa_thread_info*)pthread_getspecific(eh_key);
+ __cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key));
if (0 == info)
{
- info = (__cxa_thread_info*)calloc(1, sizeof(__cxa_thread_info));
+ info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info)));
pthread_setspecific(eh_key, info);
}
return info;
@@ -372,7 +409,7 @@
static __cxa_thread_info *thread_info_fast()
{
if (fakeTLS) { return &singleThreadInfo; }
- return (__cxa_thread_info*)pthread_getspecific(eh_key);
+ return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key));
}
/**
* ABI function returning the __cxa_eh_globals structure.
@@ -435,7 +472,7 @@
if (0 != m)
{
pthread_mutex_unlock(&emergency_malloc_lock);
- return (char*)m;
+ return static_cast<char*>(m);
}
for (int i=0 ; i<16 ; i++)
{
@@ -473,18 +510,18 @@
// Find the buffer corresponding to this pointer.
for (int i=0 ; i<16 ; i++)
{
- if (ptr == (void*)(emergency_buffer + (1024 * i)))
+ if (ptr == static_cast<void*>(emergency_buffer + (1024 * i)))
{
buffer = i;
break;
}
}
- assert(buffer > 0 &&
+ assert(buffer >= 0 &&
"Trying to free something that is not an emergency buffer!");
// emergency_malloc() is expected to return 0-initialized data. We don't
// zero the buffer when allocating it, because the static buffers will
// begin life containing 0 values.
- memset((void*)ptr, 0, 1024);
+ memset(ptr, 0, 1024);
// Signal the condition variable to wake up any threads that are blocking
// waiting for some space in the emergency buffer
pthread_mutex_lock(&emergency_malloc_lock);
@@ -498,7 +535,7 @@
static char *alloc_or_die(size_t size)
{
- char *buffer = (char*)calloc(1, size);
+ char *buffer = static_cast<char*>(calloc(1, size));
// If calloc() doesn't want to give us any memory, try using an emergency
// buffer.
@@ -519,7 +556,7 @@
{
// If this allocation is within the address range of the emergency buffer,
// don't call free() because it was not allocated with malloc()
- if ((e > emergency_buffer) &&
+ if ((e >= emergency_buffer) &&
(e < (emergency_buffer + sizeof(emergency_buffer))))
{
emergency_malloc_free(e);
@@ -560,7 +597,7 @@
*/
extern "C" void __cxa_free_exception(void *thrown_exception)
{
- __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+ __cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1;
// Free the object that was thrown, calling its destructor
if (0 != ex->exceptionDestructor)
{
@@ -575,7 +612,7 @@
}
}
- free_exception((char*)ex);
+ free_exception(reinterpret_cast<char*>(ex));
}
static void releaseException(__cxa_exception *exception)
@@ -596,13 +633,13 @@
void __cxa_free_dependent_exception(void *thrown_exception)
{
- __cxa_dependent_exception *ex = ((__cxa_dependent_exception*)thrown_exception) - 1;
+ __cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(thrown_exception) - 1;
assert(isDependentException(ex->unwindHeader.exception_class));
if (ex->primaryException)
{
- releaseException(realExceptionFromException((__cxa_exception*)ex));
+ releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
}
- free_exception((char*)ex);
+ free_exception(reinterpret_cast<char*>(ex));
}
/**
@@ -617,8 +654,8 @@
{
Dl_info myinfo;
int mylookup =
- dladdr((void*)(uintptr_t)__cxa_current_exception_type, &myinfo);
- void *ip = (void*)_Unwind_GetIP(context);
+ dladdr(reinterpret_cast<void *>(__cxa_current_exception_type), &myinfo);
+ void *ip = reinterpret_cast<void*>(_Unwind_GetIP(context));
Dl_info info;
if (dladdr(ip, &info) != 0)
{
@@ -636,6 +673,11 @@
* If the failure happened by falling off the end of the stack without finding
* a handler, prints a back trace before aborting.
*/
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+extern "C" void *__cxa_begin_catch(void *e) throw();
+#else
+extern "C" void *__cxa_begin_catch(void *e);
+#endif
static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exception)
{
switch (err)
@@ -644,14 +686,16 @@
case _URC_FATAL_PHASE1_ERROR:
fprintf(stderr, "Fatal error during phase 1 unwinding\n");
break;
-#ifndef __arm__
+#if !defined(__arm__) || defined(__ARM_DWARF_EH__)
case _URC_FATAL_PHASE2_ERROR:
fprintf(stderr, "Fatal error during phase 2 unwinding\n");
break;
#endif
case _URC_END_OF_STACK:
+ __cxa_begin_catch (&(thrown_exception->unwindHeader));
+ std::terminate();
fprintf(stderr, "Terminating due to uncaught exception %p",
- (void*)thrown_exception);
+ static_cast<void*>(thrown_exception));
thrown_exception = realExceptionFromException(thrown_exception);
static const __class_type_info *e_ti =
static_cast<const __class_type_info*>(&typeid(std::exception));
@@ -660,8 +704,8 @@
if (throw_ti)
{
std::exception *e =
- (std::exception*)e_ti->cast_to((void*)(thrown_exception+1),
- throw_ti);
+ static_cast<std::exception*>(e_ti->cast_to(static_cast<void*>(thrown_exception+1),
+ throw_ti));
if (e)
{
fprintf(stderr, " '%s'", e->what());
@@ -669,16 +713,21 @@
}
size_t bufferSize = 128;
- char *demangled = (char*)malloc(bufferSize);
+ char *demangled = static_cast<char*>(malloc(bufferSize));
const char *mangled = thrown_exception->exceptionType->name();
int status;
demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
fprintf(stderr, " of type %s\n",
- status == 0 ? (const char*)demangled : mangled);
+ status == 0 ? demangled : mangled);
if (status == 0) { free(demangled); }
// Print a back trace if no handler is found.
// TODO: Make this optional
+#ifndef __arm__
_Unwind_Backtrace(trace, 0);
+#endif
+
+ // Just abort. No need to call std::terminate for the second time
+ abort();
break;
}
std::terminate();
@@ -716,7 +765,7 @@
std::type_info *tinfo,
void(*dest)(void*))
{
- __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+ __cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1;
ex->referenceCount = 1;
ex->exceptionType = tinfo;
@@ -734,7 +783,7 @@
if (NULL == thrown_exception) { return; }
__cxa_exception *original = exceptionFromPointer(thrown_exception);
- __cxa_dependent_exception *ex = ((__cxa_dependent_exception*)__cxa_allocate_dependent_exception())-1;
+ __cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception())-1;
ex->primaryException = thrown_exception;
__cxa_increment_exception_refcount(thrown_exception);
@@ -743,7 +792,7 @@
ex->unwindHeader.exception_class = dependent_exception_class;
ex->unwindHeader.exception_cleanup = dependent_exception_cleanup;
- throw_exception((__cxa_exception*)ex);
+ throw_exception(reinterpret_cast<__cxa_exception*>(ex));
}
extern "C" void *__cxa_current_primary_exception(void)
@@ -760,7 +809,7 @@
extern "C" void __cxa_increment_exception_refcount(void* thrown_exception)
{
if (NULL == thrown_exception) { return; }
- __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+ __cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1;
if (isDependentException(ex->unwindHeader.exception_class)) { return; }
__sync_fetch_and_add(&ex->referenceCount, 1);
}
@@ -767,7 +816,7 @@
extern "C" void __cxa_decrement_exception_refcount(void* thrown_exception)
{
if (NULL == thrown_exception) { return; }
- __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+ __cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1;
releaseException(ex);
}
@@ -780,7 +829,8 @@
*/
extern "C" void __cxa_rethrow()
{
- __cxa_eh_globals *globals = __cxa_get_globals();
+ __cxa_thread_info *ti = thread_info();
+ __cxa_eh_globals *globals = &ti->globals;
// Note: We don't remove this from the caught list here, because
// __cxa_end_catch will be called when we unwind out of the try block. We
// could probably make this faster by providing an alternative rethrow
@@ -795,6 +845,15 @@
std::terminate();
}
+ if (ti->foreign_exception_state != __cxa_thread_info::none)
+ {
+ ti->foreign_exception_state = __cxa_thread_info::rethrown;
+ _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ex);
+ _Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(e);
+ report_failure(err, ex);
+ return;
+ }
+
assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!");
// ex->handlerCount will be decremented in __cxa_end_catch in enclosing
@@ -832,8 +891,8 @@
if (offset == 0) { return 0; }
// ...so we need to resolve it
- return (std::type_info*)resolve_indirect_value(context,
- lsda->type_table_encoding, offset, start);
+ return reinterpret_cast<std::type_info*>(resolve_indirect_value(context,
+ lsda->type_table_encoding, offset, start));
}
@@ -847,13 +906,13 @@
const std::type_info *type,
void *&adjustedPtr)
{
- void *exception_ptr = (void*)(ex+1);
- const std::type_info *ex_type = ex->exceptionType;
+ void *exception_ptr = static_cast<void*>(ex+1);
+ const std::type_info *ex_type = ex ? ex->exceptionType : 0;
- bool is_ptr = ex_type->__is_pointer_p();
+ bool is_ptr = ex ? ex_type->__is_pointer_p() : false;
if (is_ptr)
{
- exception_ptr = *(void**)exception_ptr;
+ exception_ptr = *static_cast<void**>(exception_ptr);
}
// Always match a catchall, even with a foreign exception
//
@@ -911,8 +970,8 @@
action_record = displacement ?
action_record_offset_base + displacement : 0;
// We only check handler types for C++ exceptions - foreign exceptions
- // are only allowed for cleanup.
- if (filter > 0 && 0 != ex)
+ // are only allowed for cleanups and catchalls.
+ if (filter > 0)
{
std::type_info *handler_type = get_type_info_entry(context, lsda, filter);
if (check_type_signature(ex, handler_type, adjustedPtr))
@@ -925,7 +984,7 @@
{
bool matched = false;
*selector = filter;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
filter++;
std::type_info *handler_type = get_type_info_entry(context, lsda, filter--);
while (handler_type)
@@ -938,7 +997,7 @@
handler_type = get_type_info_entry(context, lsda, filter--);
}
#else
- unsigned char *type_index = ((unsigned char*)lsda->type_table - filter - 1);
+ unsigned char *type_index = reinterpret_cast<unsigned char*>(lsda->type_table) - filter - 1;
while (*type_index)
{
std::type_info *handler_type = get_type_info_entry(context, lsda, *(type_index++));
@@ -970,7 +1029,7 @@
static void pushCleanupException(_Unwind_Exception *exceptionObject,
__cxa_exception *ex)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
__cxa_thread_info *info = thread_info_fast();
if (ex)
{
@@ -1015,8 +1074,13 @@
realEx = realExceptionFromException(ex);
}
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
unsigned char *lsda_addr =
- (unsigned char*)_Unwind_GetLanguageSpecificData(context);
+ static_cast<unsigned char*>(_Unwind_GetLanguageSpecificData(context));
+#else
+ unsigned char *lsda_addr =
+ reinterpret_cast<unsigned char*>(static_cast<uintptr_t>(_Unwind_GetLanguageSpecificData(context)));
+#endif
// No LSDA implies no landing pads - try the next frame
if (0 == lsda_addr) { return continueUnwinding(exceptionObject, context); }
@@ -1065,8 +1129,8 @@
if (ex)
{
saveLandingPad(context, exceptionObject, ex, selector, action.landing_pad);
- ex->languageSpecificData = (const char*)lsda_addr;
- ex->actionRecord = (const char*)action.action_record;
+ ex->languageSpecificData = reinterpret_cast<const char*>(lsda_addr);
+ ex->actionRecord = reinterpret_cast<const char*>(action.action_record);
// ex->adjustedPtr is set when finding the action record.
}
return _URC_HANDLER_FOUND;
@@ -1112,9 +1176,9 @@
}
- _Unwind_SetIP(context, (unsigned long)action.landing_pad);
+ _Unwind_SetIP(context, reinterpret_cast<unsigned long>(action.landing_pad));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
- (unsigned long)exceptionObject);
+ reinterpret_cast<unsigned long>(exceptionObject));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector);
return _URC_INSTALL_CONTEXT;
@@ -1127,16 +1191,18 @@
* pointer to the caught exception, which is either the adjusted pointer (for
* C++ exceptions) of the unadjusted pointer (for foreign exceptions).
*/
-#if __GNUC__ > 3 && __GNUC_MINOR__ > 2
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
extern "C" void *__cxa_begin_catch(void *e) throw()
#else
extern "C" void *__cxa_begin_catch(void *e)
#endif
{
- // Decrement the uncaught exceptions count
- __cxa_eh_globals *globals = __cxa_get_globals();
+ // We can't call the fast version here, because if the first exception that
+ // we see is a foreign exception then we won't have called it yet.
+ __cxa_thread_info *ti = thread_info();
+ __cxa_eh_globals *globals = &ti->globals;
globals->uncaughtExceptions--;
- _Unwind_Exception *exceptionObject = (_Unwind_Exception*)e;
+ _Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(e);
if (isCXXException(exceptionObject->exception_class))
{
@@ -1177,12 +1243,25 @@
{
ex->handlerCount++;
}
+ ti->foreign_exception_state = __cxa_thread_info::none;
return ex->adjustedPtr;
}
+ else
+ {
+ // If this is a foreign exception, then we need to be able to
+ // store it. We can't chain foreign exceptions, so we give up
+ // if there are already some outstanding ones.
+ if (globals->caughtExceptions != 0)
+ {
+ std::terminate();
+ }
+ globals->caughtExceptions = reinterpret_cast<__cxa_exception*>(exceptionObject);
+ ti->foreign_exception_state = __cxa_thread_info::caught;
+ }
// exceptionObject is the pointer to the _Unwind_Exception within the
// __cxa_exception. The throw object is after this
- return ((char*)exceptionObject + sizeof(_Unwind_Exception));
+ return (reinterpret_cast<char*>(exceptionObject) + sizeof(_Unwind_Exception));
}
@@ -1195,10 +1274,23 @@
{
// We can call the fast version here because the slow version is called in
// __cxa_throw(), which must have been called before we end a catch block
- __cxa_eh_globals *globals = __cxa_get_globals_fast();
+ __cxa_thread_info *ti = thread_info_fast();
+ __cxa_eh_globals *globals = &ti->globals;
__cxa_exception *ex = globals->caughtExceptions;
assert(0 != ex && "Ending catch when no exception is on the stack!");
+
+ if (ti->foreign_exception_state != __cxa_thread_info::none)
+ {
+ globals->caughtExceptions = 0;
+ if (ti->foreign_exception_state != __cxa_thread_info::rethrown)
+ {
+ _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions);
+ e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
+ }
+ ti->foreign_exception_state = __cxa_thread_info::none;
+ return;
+ }
bool deleteException = true;
@@ -1255,7 +1347,7 @@
*/
extern "C" void __cxa_call_unexpected(void*exception)
{
- _Unwind_Exception *exceptionObject = (_Unwind_Exception*)exception;
+ _Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(exception);
if (exceptionObject->exception_class == exception_class)
{
__cxa_exception *ex = exceptionFromPointer(exceptionObject);
@@ -1328,7 +1420,7 @@
{
if (thread_local_handlers) { return pathscale::set_unexpected(f); }
- return __sync_lock_test_and_set(&unexpectedHandler, f);
+ return ATOMIC_SWAP(&unexpectedHandler, f);
}
/**
* Sets the function that is called to terminate the program.
@@ -1336,7 +1428,8 @@
terminate_handler set_terminate(terminate_handler f) throw()
{
if (thread_local_handlers) { return pathscale::set_terminate(f); }
- return __sync_lock_test_and_set(&terminateHandler, f);
+
+ return ATOMIC_SWAP(&terminateHandler, f);
}
/**
* Terminates the program, calling a custom terminate implementation if
@@ -1344,7 +1437,7 @@
*/
void terminate()
{
- static __cxa_thread_info *info = thread_info_fast();
+ static __cxa_thread_info *info = thread_info();
if (0 != info && 0 != info->terminateHandler)
{
info->terminateHandler();
@@ -1361,7 +1454,7 @@
*/
void unexpected()
{
- static __cxa_thread_info *info = thread_info_fast();
+ static __cxa_thread_info *info = thread_info();
if (0 != info && 0 != info->unexpectedHandler)
{
info->unexpectedHandler();
@@ -1390,7 +1483,7 @@
{
return info->unexpectedHandler;
}
- return unexpectedHandler;
+ return ATOMIC_LOAD(&unexpectedHandler);
}
/**
* Returns the current terminate handler.
@@ -1402,10 +1495,10 @@
{
return info->terminateHandler;
}
- return terminateHandler;
+ return ATOMIC_LOAD(&terminateHandler);
}
}
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
extern "C" _Unwind_Exception *__cxa_get_cleanup(void)
{
__cxa_thread_info *info = thread_info_fast();
Modified: trunk/contrib/libcxxrt/guard.cc
===================================================================
--- trunk/contrib/libcxxrt/guard.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/guard.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -41,104 +41,125 @@
* initialised.
*/
#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
#include <pthread.h>
#include <assert.h>
+#include "atomic.h"
-#ifdef __arm__
-// ARM ABI - 32-bit guards.
+// Older GCC doesn't define __LITTLE_ENDIAN__
+#ifndef __LITTLE_ENDIAN__
+ // If __BYTE_ORDER__ is defined, use that instead
+# ifdef __BYTE_ORDER__
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define __LITTLE_ENDIAN__
+# endif
+ // x86 and ARM are the most common little-endian CPUs, so let's have a
+ // special case for them (ARM is already special cased). Assume everything
+ // else is big endian.
+# elif defined(__x86_64) || defined(__i386)
+# define __LITTLE_ENDIAN__
+# endif
+#endif
-/**
- * Acquires a lock on a guard, returning 0 if the object has already been
- * initialised, and 1 if it has not. If the object is already constructed then
- * this function just needs to read a byte from memory and return.
- */
-extern "C" int __cxa_guard_acquire(volatile int32_t *guard_object)
-{
- if ((1<<31) == *guard_object) { return 0; }
- // If we can atomically move the value from 0 -> 1, then this is
- // uninitialised.
- if (__sync_bool_compare_and_swap(guard_object, 0, 1))
- {
- return 1;
- }
- // If the value is not 0, some other thread was initialising this. Spin
- // until it's finished.
- while (__sync_bool_compare_and_swap(guard_object, (1<<31), (1<<31)))
- {
- // If the other thread aborted, then we grab the lock
- if (__sync_bool_compare_and_swap(guard_object, 0, 1))
- {
- return 1;
- }
- sched_yield();
- }
- return 0;
-}
-/**
- * Releases the lock without marking the object as initialised. This function
- * is called if initialising a static causes an exception to be thrown.
+/*
+ * The least significant bit of the guard variable indicates that the object
+ * has been initialised, the most significant bit is used for a spinlock.
*/
-extern "C" void __cxa_guard_abort(int32_t *guard_object)
-{
- assert(__sync_bool_compare_and_swap(guard_object, 1, 0));
-}
-/**
- * Releases the guard and marks the object as initialised. This function is
- * called after successful initialisation of a static.
- */
-extern "C" void __cxa_guard_release(int32_t *guard_object)
-{
- assert(__sync_bool_compare_and_swap(guard_object, 1, (1<<31)));
-}
-
-
+#ifdef __arm__
+// ARM ABI - 32-bit guards.
+typedef uint32_t guard_t;
+typedef uint32_t guard_lock_t;
+static const uint32_t LOCKED = static_cast<guard_t>(1) << 31;
+static const uint32_t INITIALISED = 1;
+#define LOCK_PART(guard) (guard)
+#define INIT_PART(guard) (guard)
+#elif defined(_LP64)
+typedef uint64_t guard_t;
+typedef uint64_t guard_lock_t;
+# if defined(__LITTLE_ENDIAN__)
+static const guard_t LOCKED = static_cast<guard_t>(1) << 63;
+static const guard_t INITIALISED = 1;
+# else
+static const guard_t LOCKED = 1;
+static const guard_t INITIALISED = static_cast<guard_t>(1) << 56;
+# endif
+#define LOCK_PART(guard) (guard)
+#define INIT_PART(guard) (guard)
#else
-// Itanium ABI: 64-bit guards
+typedef uint32_t guard_lock_t;
+# if defined(__LITTLE_ENDIAN__)
+typedef struct {
+ uint32_t init_half;
+ uint32_t lock_half;
+} guard_t;
+static const uint32_t LOCKED = static_cast<guard_lock_t>(1) << 31;
+static const uint32_t INITIALISED = 1;
+# else
+typedef struct {
+ uint32_t init_half;
+ uint32_t lock_half;
+} guard_t;
+_Static_assert(sizeof(guard_t) == sizeof(uint64_t), "");
+static const uint32_t LOCKED = 1;
+static const uint32_t INITIALISED = static_cast<guard_lock_t>(1) << 24;
+# endif
+#define LOCK_PART(guard) (&(guard)->lock_half)
+#define INIT_PART(guard) (&(guard)->init_half)
+#endif
+static const guard_lock_t INITIAL = 0;
/**
- * Returns a pointer to the low 32 bits in a 64-bit value, respecting the
- * platform's byte order.
- */
-static int32_t *low_32_bits(volatile int64_t *ptr)
-{
- int32_t *low= (int32_t*)ptr;
- // Test if the machine is big endian - constant propagation at compile time
- // should eliminate this completely.
- int one = 1;
- if (*(char*)&one != 1)
- {
- low++;
- }
- return low;
-}
-
-/**
* Acquires a lock on a guard, returning 0 if the object has already been
* initialised, and 1 if it has not. If the object is already constructed then
* this function just needs to read a byte from memory and return.
*/
-extern "C" int __cxa_guard_acquire(volatile int64_t *guard_object)
+extern "C" int __cxa_guard_acquire(volatile guard_t *guard_object)
{
- char first_byte = (*guard_object) >> 56;
- if (1 == first_byte) { return 0; }
- int32_t *lock = low_32_bits(guard_object);
- // Simple spin lock using the low 32 bits. We assume that concurrent
- // attempts to initialize statics are very rare, so we don't need to
- // optimise for the case where we have lots of threads trying to acquire
- // the lock at the same time.
- while (!__sync_bool_compare_and_swap_4(lock, 0, 1))
+ guard_lock_t old;
+ // Not an atomic read, doesn't establish a happens-before relationship, but
+ // if one is already established and we end up seeing an initialised state
+ // then it's a fast path, otherwise we'll do something more expensive than
+ // this test anyway...
+ if (INITIALISED == *INIT_PART(guard_object))
+ return 0;
+ // Spin trying to do the initialisation
+ for (;;)
{
- if (1 == ((*guard_object) >> 56))
- {
- break;
+ // Loop trying to move the value of the guard from 0 (not
+ // locked, not initialised) to the locked-uninitialised
+ // position.
+ old = __sync_val_compare_and_swap(LOCK_PART(guard_object),
+ INITIAL, LOCKED);
+ if (old == INITIAL) {
+ // Lock obtained. If lock and init bit are
+ // in separate words, check for init race.
+ if (INIT_PART(guard_object) == LOCK_PART(guard_object))
+ return 1;
+ if (INITIALISED != *INIT_PART(guard_object))
+ return 1;
+
+ // No need for a memory barrier here,
+ // see first comment.
+ *LOCK_PART(guard_object) = INITIAL;
+ return 0;
}
+ // If lock and init bit are in the same word, check again
+ // if we are done.
+ if (INIT_PART(guard_object) == LOCK_PART(guard_object) &&
+ old == INITIALISED)
+ return 0;
+
+ assert(old == LOCKED);
+ // Another thread holds the lock.
+ // If lock and init bit are in different words, check
+ // if we are done before yielding and looping.
+ if (INIT_PART(guard_object) != LOCK_PART(guard_object) &&
+ INITIALISED == *INIT_PART(guard_object))
+ return 0;
sched_yield();
}
- // We have to test the guard again, in case another thread has performed
- // the initialisation while we were trying to acquire the lock.
- first_byte = (*guard_object) >> 56;
- return (1 != first_byte);
}
/**
@@ -145,20 +166,28 @@
* Releases the lock without marking the object as initialised. This function
* is called if initialising a static causes an exception to be thrown.
*/
-extern "C" void __cxa_guard_abort(int64_t *guard_object)
+extern "C" void __cxa_guard_abort(volatile guard_t *guard_object)
{
- int32_t *lock = low_32_bits(guard_object);
- *lock = 0;
+ __attribute__((unused))
+ bool reset = __sync_bool_compare_and_swap(LOCK_PART(guard_object),
+ LOCKED, INITIAL);
+ assert(reset);
}
/**
* Releases the guard and marks the object as initialised. This function is
* called after successful initialisation of a static.
*/
-extern "C" void __cxa_guard_release(int64_t *guard_object)
+extern "C" void __cxa_guard_release(volatile guard_t *guard_object)
{
- // Set the first byte to 1
- *guard_object |= ((int64_t)1) << 56;
- __cxa_guard_abort(guard_object);
+ guard_lock_t old;
+ if (INIT_PART(guard_object) == LOCK_PART(guard_object))
+ old = LOCKED;
+ else
+ old = INITIAL;
+ __attribute__((unused))
+ bool reset = __sync_bool_compare_and_swap(INIT_PART(guard_object),
+ old, INITIALISED);
+ assert(reset);
+ if (INIT_PART(guard_object) != LOCK_PART(guard_object))
+ *LOCK_PART(guard_object) = INITIAL;
}
-
-#endif
Modified: trunk/contrib/libcxxrt/libelftc_dem_gnu3.c
===================================================================
--- trunk/contrib/libcxxrt/libelftc_dem_gnu3.c 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/libelftc_dem_gnu3.c 2016-02-28 21:26:57 UTC (rev 7451)
@@ -59,7 +59,7 @@
enum type_qualifier {
TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,
- TYPE_CST
+ TYPE_CST, TYPE_VEC
};
struct vector_type_qualifier {
@@ -397,6 +397,8 @@
static int cpp_demangle_read_encoding(struct cpp_demangle_data *);
static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *);
static int cpp_demangle_read_expression(struct cpp_demangle_data *);
+static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *,
+ char **);
static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *,
const char *, size_t);
static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *,
@@ -405,10 +407,15 @@
const char *, size_t, const char *, size_t);
static int cpp_demangle_read_function(struct cpp_demangle_data *, int *,
struct vector_type_qualifier *);
+static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);
static int cpp_demangle_read_local_name(struct cpp_demangle_data *);
static int cpp_demangle_read_name(struct cpp_demangle_data *);
+static int cpp_demangle_read_name_flat(struct cpp_demangle_data *,
+ char**);
static int cpp_demangle_read_nested_name(struct cpp_demangle_data *);
static int cpp_demangle_read_number(struct cpp_demangle_data *, long *);
+static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *,
+ char **);
static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *);
static int cpp_demangle_read_offset(struct cpp_demangle_data *);
static int cpp_demangle_read_offset_number(struct cpp_demangle_data *);
@@ -422,6 +429,8 @@
static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);
static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);
static int cpp_demangle_read_type(struct cpp_demangle_data *, int);
+static int cpp_demangle_read_type_flat(struct cpp_demangle_data *,
+ char **);
static int cpp_demangle_read_uqname(struct cpp_demangle_data *);
static int cpp_demangle_read_v_offset(struct cpp_demangle_data *);
static char *decode_fp_to_double(const char *, size_t);
@@ -453,13 +462,22 @@
struct cpp_demangle_data ddata;
ssize_t org_len;
unsigned int limit;
- char *rtn;
+ char *rtn = NULL;
if (org == NULL)
return (NULL);
+ org_len = strlen(org);
+ if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
+ if ((rtn = malloc(org_len + 19)) == NULL)
+ return (NULL);
+ snprintf(rtn, org_len + 19,
+ "global constructors keyed to %s", org + 11);
+ return (rtn);
+ }
+
// Try demangling as a type for short encodings
- if (((org_len = strlen(org)) < 2) || (org[0] != '_' || org[1] != 'Z' )) {
+ if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) {
if (!cpp_demangle_data_init(&ddata, org))
return (NULL);
if (!cpp_demangle_read_type(&ddata, 0))
@@ -467,13 +485,6 @@
rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
goto clean;
}
- if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
- if ((rtn = malloc(org_len + 19)) == NULL)
- return (NULL);
- snprintf(rtn, org_len + 19,
- "global constructors keyed to %s", org + 11);
- return (rtn);
- }
if (!cpp_demangle_data_init(&ddata, org + 2))
@@ -598,19 +609,19 @@
fp = ddata->cur;
while (*ddata->cur != 'E')
++ddata->cur;
- ++ddata->cur;
if ((f = decoder(fp, ddata->cur - fp)) == NULL)
return (0);
rtn = 0;
- if ((len = strlen(f)) > 0 &&
- cpp_demangle_push_str(ddata, f, len))
- rtn = 1;
+ if ((len = strlen(f)) > 0)
+ rtn = cpp_demangle_push_str(ddata, f, len);
free(f);
- return (0);
+ ++ddata->cur;
+
+ return (rtn);
}
static int
@@ -655,6 +666,7 @@
return (0);
rtn = cpp_demangle_push_subst(ddata, str, str_len);
+
free(str);
return (rtn);
@@ -692,7 +704,8 @@
if (type_str != NULL) {
if (!vector_str_push(&subst_v, "*", 1))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
@@ -703,7 +716,8 @@
if (type_str != NULL) {
if (!vector_str_push(&subst_v, "&", 1))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
@@ -714,7 +728,8 @@
if (type_str != NULL) {
if (!vector_str_push(&subst_v, " complex", 8))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
@@ -723,24 +738,27 @@
if (!cpp_demangle_push_str(ddata, " imaginary", 10))
goto clean;
if (type_str != NULL) {
- if (!vector_str_push(&subst_v, " imaginary", 10))
+ if (!vector_str_push(&subst_v, " imaginary",
+ 10))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
case TYPE_EXT:
- if (e_idx > v->ext_name.size - 1)
+ if (v->ext_name.size == 0 ||
+ e_idx > v->ext_name.size - 1)
goto clean;
- if ((e_len = strlen(v->ext_name.container[e_idx])) == 0)
+ if ((e_len = strlen(v->ext_name.container[e_idx])) ==
+ 0)
goto clean;
- if ((buf = malloc(sizeof(char) * (e_len + 1))) == NULL)
+ if ((buf = malloc(e_len + 2)) == NULL)
goto clean;
+ snprintf(buf, e_len + 2, " %s",
+ v->ext_name.container[e_idx]);
- memcpy(buf, " ", 1);
- memcpy(buf + 1, v->ext_name.container[e_idx], e_len);
-
if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) {
free(buf);
goto clean;
@@ -752,7 +770,8 @@
free(buf);
goto clean;
}
- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) {
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v)) {
free(buf);
goto clean;
}
@@ -767,7 +786,8 @@
if (type_str != NULL) {
if (!vector_str_push(&subst_v, " restrict", 9))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
@@ -778,7 +798,8 @@
if (type_str != NULL) {
if (!vector_str_push(&subst_v, " volatile", 9))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
@@ -789,11 +810,42 @@
if (type_str != NULL) {
if (!vector_str_push(&subst_v, " const", 6))
goto clean;
- if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v))
goto clean;
}
break;
+ case TYPE_VEC:
+ if (v->ext_name.size == 0 ||
+ e_idx > v->ext_name.size - 1)
+ goto clean;
+ if ((e_len = strlen(v->ext_name.container[e_idx])) ==
+ 0)
+ goto clean;
+ if ((buf = malloc(e_len + 12)) == NULL)
+ goto clean;
+ snprintf(buf, e_len + 12, " __vector(%s)",
+ v->ext_name.container[e_idx]);
+ if (!cpp_demangle_push_str(ddata, buf, e_len + 11)) {
+ free(buf);
+ goto clean;
+ }
+ if (type_str != NULL) {
+ if (!vector_str_push(&subst_v, buf,
+ e_len + 11)) {
+ free(buf);
+ goto clean;
+ }
+ if (!cpp_demangle_push_subst_v(ddata,
+ &subst_v)) {
+ free(buf);
+ goto clean;
+ }
+ }
+ free(buf);
+ ++e_idx;
+ break;
};
--idx;
}
@@ -944,10 +996,14 @@
switch (*ddata->cur) {
case 'b':
+ if (*(ddata->cur + 2) != 'E')
+ return (0);
switch (*(++ddata->cur)) {
case '0':
+ ddata->cur += 2;
return (cpp_demangle_push_str(ddata, "false", 5));
case '1':
+ ddata->cur += 2;
return (cpp_demangle_push_str(ddata, "true", 4));
default:
return (0);
@@ -996,7 +1052,8 @@
++ddata->cur;
}
++ddata->cur;
- return (cpp_demangle_push_str(ddata, num, ddata->cur - num));
+ return (cpp_demangle_push_str(ddata, num,
+ ddata->cur - num - 1));
default:
return (0);
@@ -1288,6 +1345,38 @@
}
static int
+cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)
+{
+ struct vector_str *output;
+ size_t i, p_idx, idx, exp_len;
+ char *exp;
+
+ output = ddata->push_head > 0 ? &ddata->output_tmp :
+ &ddata->output;
+
+ p_idx = output->size;
+
+ if (!cpp_demangle_read_expression(ddata))
+ return (0);
+
+ if ((exp = vector_str_substr(output, p_idx, output->size - 1,
+ &exp_len)) == NULL)
+ return (0);
+
+ idx = output->size;
+ for (i = p_idx; i < idx; ++i) {
+ if (!vector_str_pop(output)) {
+ free(exp);
+ return (0);
+ }
+ }
+
+ *str = exp;
+
+ return (1);
+}
+
+static int
cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,
const char *name, size_t len)
{
@@ -1416,6 +1505,9 @@
static int
cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
{
+ char *name, *type, *num_str;
+ long offset;
+ int rtn;
if (ddata == NULL || *ddata->cur == '\0')
return (0);
@@ -1422,6 +1514,56 @@
/* special name */
switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
+ case SIMPLE_HASH('G', 'A'):
+ if (!cpp_demangle_push_str(ddata, "hidden alias for ", 17))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ return (cpp_demangle_read_encoding(ddata));
+
+ case SIMPLE_HASH('G', 'R'):
+ if (!cpp_demangle_push_str(ddata, "reference temporary #", 21))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ if (!cpp_demangle_read_name_flat(ddata, &name))
+ return (0);
+ rtn = 0;
+ if (!cpp_demangle_read_number_as_string(ddata, &num_str))
+ goto clean1;
+ if (!cpp_demangle_push_str(ddata, num_str, strlen(num_str)))
+ goto clean2;
+ if (!cpp_demangle_push_str(ddata, " for ", 5))
+ goto clean2;
+ if (!cpp_demangle_push_str(ddata, name, strlen(name)))
+ goto clean2;
+ rtn = 1;
+ clean2:
+ free(num_str);
+ clean1:
+ free(name);
+ return (rtn);
+
+ case SIMPLE_HASH('G', 'T'):
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ switch (*ddata->cur) {
+ case 'n':
+ if (!cpp_demangle_push_str(ddata,
+ "non-transaction clone for ", 26))
+ return (0);
+ case 't':
+ default:
+ if (!cpp_demangle_push_str(ddata,
+ "transaction clone for ", 22))
+ return (0);
+ }
+ ++ddata->cur;
+ return (cpp_demangle_read_encoding(ddata));
+
case SIMPLE_HASH('G', 'V'):
/* sentry object for 1 time init */
if (!cpp_demangle_push_str(ddata, "guard variable for ", 20))
@@ -1443,14 +1585,49 @@
return (0);
return (cpp_demangle_read_encoding(ddata));
+ case SIMPLE_HASH('T', 'C'):
+ /* construction vtable */
+ if (!cpp_demangle_push_str(ddata, "construction vtable for ",
+ 24))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ if (!cpp_demangle_read_type_flat(ddata, &type))
+ return (0);
+ rtn = 0;
+ if (!cpp_demangle_read_number(ddata, &offset))
+ goto clean3;
+ if (*ddata->cur++ != '_')
+ goto clean3;
+ if (!cpp_demangle_read_type(ddata, 0))
+ goto clean3;
+ if (!cpp_demangle_push_str(ddata, "-in-", 4))
+ goto clean3;
+ if (!cpp_demangle_push_str(ddata, type, strlen(type)))
+ goto clean3;
+ rtn = 1;
+ clean3:
+ free(type);
+ return (rtn);
+
case SIMPLE_HASH('T', 'D'):
/* typeinfo common proxy */
break;
+ case SIMPLE_HASH('T', 'F'):
+ /* typeinfo fn */
+ if (!cpp_demangle_push_str(ddata, "typeinfo fn for ", 16))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ return (cpp_demangle_read_type(ddata, 0));
+
case SIMPLE_HASH('T', 'h'):
/* virtual function non-virtual override thunk */
- if (cpp_demangle_push_str(ddata,
- "virtual function non-virtual override ", 38) == 0)
+ if (!cpp_demangle_push_str(ddata,
+ "virtual function non-virtual override ", 38))
return (0);
ddata->cur += 2;
if (*ddata->cur == '\0')
@@ -1459,17 +1636,42 @@
return (0);
return (cpp_demangle_read_encoding(ddata));
+ case SIMPLE_HASH('T', 'H'):
+ /* TLS init function */
+ if (!cpp_demangle_push_str(ddata, "TLS init function for ",
+ 22))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ break;
+
case SIMPLE_HASH('T', 'I'):
/* typeinfo structure */
- /* FALLTHROUGH */
+ if (!cpp_demangle_push_str(ddata, "typeinfo for ", 13))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ return (cpp_demangle_read_type(ddata, 0));
+
+ case SIMPLE_HASH('T', 'J'):
+ /* java class */
+ if (!cpp_demangle_push_str(ddata, "java Class for ", 15))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ return (cpp_demangle_read_type(ddata, 0));
+
case SIMPLE_HASH('T', 'S'):
/* RTTI name (NTBS) */
- if (!cpp_demangle_push_str(ddata, "typeinfo for ", 14))
+ if (!cpp_demangle_push_str(ddata, "typeinfo name for ", 18))
return (0);
ddata->cur += 2;
if (*ddata->cur == '\0')
return (0);
- return (cpp_demangle_read_type(ddata, 1));
+ return (cpp_demangle_read_type(ddata, 0));
case SIMPLE_HASH('T', 'T'):
/* VTT table */
@@ -1476,7 +1678,9 @@
if (!cpp_demangle_push_str(ddata, "VTT for ", 8))
return (0);
ddata->cur += 2;
- return (cpp_demangle_read_type(ddata, 1));
+ if (*ddata->cur == '\0')
+ return (0);
+ return (cpp_demangle_read_type(ddata, 0));
case SIMPLE_HASH('T', 'v'):
/* virtual function virtual override thunk */
@@ -1497,7 +1701,17 @@
ddata->cur += 2;
if (*ddata->cur == '\0')
return (0);
- return (cpp_demangle_read_type(ddata, 1));
+ return (cpp_demangle_read_type(ddata, 0));
+
+ case SIMPLE_HASH('T', 'W'):
+ /* TLS wrapper function */
+ if (!cpp_demangle_push_str(ddata, "TLS wrapper function for ",
+ 25))
+ return (0);
+ ddata->cur += 2;
+ if (*ddata->cur == '\0')
+ return (0);
+ break;
};
return (cpp_demangle_read_name(ddata));
@@ -1615,6 +1829,38 @@
}
static int
+cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)
+{
+ struct vector_str *output;
+ size_t i, p_idx, idx, name_len;
+ char *name;
+
+ output = ddata->push_head > 0 ? &ddata->output_tmp :
+ &ddata->output;
+
+ p_idx = output->size;
+
+ if (!cpp_demangle_read_name(ddata))
+ return (0);
+
+ if ((name = vector_str_substr(output, p_idx, output->size - 1,
+ &name_len)) == NULL)
+ return (0);
+
+ idx = output->size;
+ for (i = p_idx; i < idx; ++i) {
+ if (!vector_str_pop(output)) {
+ free(name);
+ return (0);
+ }
+ }
+
+ *str = name;
+
+ return (1);
+}
+
+static int
cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)
{
struct vector_str *output, v;
@@ -1740,6 +1986,24 @@
}
static int
+cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)
+{
+ long n;
+
+ if (!cpp_demangle_read_number(ddata, &n)) {
+ *str = NULL;
+ return (0);
+ }
+
+ if (asprintf(str, "%ld", n) < 0) {
+ *str = NULL;
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)
{
@@ -1868,11 +2132,20 @@
cpp_demangle_read_sname(struct cpp_demangle_data *ddata)
{
long len;
+ int err;
if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 ||
- len <= 0 || cpp_demangle_push_str(ddata, ddata->cur, len) == 0)
+ len <= 0)
return (0);
+ if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0))
+ err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21);
+ else
+ err = cpp_demangle_push_str(ddata, ddata->cur, len);
+
+ if (err == 0)
+ return (0);
+
assert(ddata->output.size > 0);
if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == 0)
ddata->last_sname =
@@ -2054,7 +2327,7 @@
free(subst_str);
vector_str_dest(&v);
- return (1);
+ return (rtn);
}
static int
@@ -2220,7 +2493,7 @@
size_t p_idx, type_str_len;
int extern_c, is_builtin;
long len;
- char *type_str;
+ char *type_str, *exp_str, *num_str;
if (ddata == NULL)
return (0);
@@ -2262,7 +2535,7 @@
extern_c = 0;
is_builtin = 1;
p_idx = output->size;
- type_str = NULL;
+ type_str = exp_str = num_str = NULL;
again:
/* builtin type */
switch (*ddata->cur) {
@@ -2308,6 +2581,82 @@
++ddata->cur;
goto rtn;
+ case 'D':
+ ++ddata->cur;
+ switch (*ddata->cur) {
+ case 'd':
+ /* IEEE 754r decimal floating point (64 bits) */
+ if (!cpp_demangle_push_str(ddata, "decimal64", 9))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 'e':
+ /* IEEE 754r decimal floating point (128 bits) */
+ if (!cpp_demangle_push_str(ddata, "decimal128", 10))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 'f':
+ /* IEEE 754r decimal floating point (32 bits) */
+ if (!cpp_demangle_push_str(ddata, "decimal32", 9))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 'h':
+ /* IEEE 754r half-precision floating point (16 bits) */
+ if (!cpp_demangle_push_str(ddata, "half", 4))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 'i':
+ /* char32_t */
+ if (!cpp_demangle_push_str(ddata, "char32_t", 8))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 'n':
+ /* std::nullptr_t (i.e., decltype(nullptr)) */
+ if (!cpp_demangle_push_str(ddata, "decltype(nullptr)",
+ 17))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 's':
+ /* char16_t */
+ if (!cpp_demangle_push_str(ddata, "char16_t", 8))
+ goto clean;
+ ++ddata->cur;
+ break;
+ case 'v':
+ /* gcc vector_size extension. */
+ ++ddata->cur;
+ if (*ddata->cur == '_') {
+ ++ddata->cur;
+ if (!cpp_demangle_read_expression_flat(ddata,
+ &exp_str))
+ goto clean;
+ if (!vector_str_push(&v.ext_name, exp_str,
+ strlen(exp_str)))
+ goto clean;
+ } else {
+ if (!cpp_demangle_read_number_as_string(ddata,
+ &num_str))
+ goto clean;
+ if (!vector_str_push(&v.ext_name, num_str,
+ strlen(num_str)))
+ goto clean;
+ }
+ if (*ddata->cur != '_')
+ goto clean;
+ ++ddata->cur;
+ if (!vector_type_qualifier_push(&v, TYPE_VEC))
+ goto clean;
+ goto again;
+ default:
+ goto clean;
+ }
+ goto rtn;
+
case 'e':
/* long double */
if (!cpp_demangle_push_str(ddata, "long double", 11))
@@ -2402,7 +2751,7 @@
case 'o':
/* unsigned __int128 */
- if (!cpp_demangle_push_str(ddata, "unsigned _;int128", 17))
+ if (!cpp_demangle_push_str(ddata, "unsigned __int128", 17))
goto clean;
++ddata->cur;
goto rtn;
@@ -2473,6 +2822,8 @@
if (!vector_str_push(&v.ext_name, ddata->cur, len))
return (0);
ddata->cur += len;
+ if (!vector_type_qualifier_push(&v, TYPE_EXT))
+ goto clean;
goto again;
case 'v':
@@ -2537,6 +2888,8 @@
goto clean;
free(type_str);
+ free(exp_str);
+ free(num_str);
vector_type_qualifier_dest(&v);
if (ddata->push_head > 0) {
@@ -2568,11 +2921,45 @@
return (1);
clean:
free(type_str);
+ free(exp_str);
+ free(num_str);
vector_type_qualifier_dest(&v);
return (0);
}
+static int
+cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)
+{
+ struct vector_str *output;
+ size_t i, p_idx, idx, type_len;
+ char *type;
+
+ output = ddata->push_head > 0 ? &ddata->output_tmp :
+ &ddata->output;
+
+ p_idx = output->size;
+
+ if (!cpp_demangle_read_type(ddata, 0))
+ return (0);
+
+ if ((type = vector_str_substr(output, p_idx, output->size - 1,
+ &type_len)) == NULL)
+ return (0);
+
+ idx = output->size;
+ for (i = p_idx; i < idx; ++i) {
+ if (!vector_str_pop(output)) {
+ free(type);
+ return (0);
+ }
+ }
+
+ *str = type;
+
+ return (1);
+}
+
/*
* read unqualified-name, unqualified name are operator-name, ctor-dtor-name,
* source-name
@@ -2996,10 +3383,43 @@
if (ELFTC_ISDIGIT(*ddata->cur) != 0)
return (cpp_demangle_read_sname(ddata));
+ /* local source name */
+ if (*ddata->cur == 'L')
+ return (cpp_demangle_local_source_name(ddata));
+
return (1);
}
+/*
+ * Read local source name.
+ *
+ * References:
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
+ * http://gcc.gnu.org/viewcvs?view=rev&revision=124467
+ */
static int
+cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)
+{
+ /* L */
+ if (ddata == NULL || *ddata->cur != 'L')
+ return (0);
+ ++ddata->cur;
+
+ /* source name */
+ if (!cpp_demangle_read_sname(ddata))
+ return (0);
+
+ /* discriminator */
+ if (*ddata->cur == '_') {
+ ++ddata->cur;
+ while (ELFTC_ISDIGIT(*ddata->cur) != 0)
+ ++ddata->cur;
+ }
+
+ return (1);
+}
+
+static int
cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)
{
Modified: trunk/contrib/libcxxrt/memory.cc
===================================================================
--- trunk/contrib/libcxxrt/memory.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/memory.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -36,15 +36,9 @@
#include <stddef.h>
#include <stdlib.h>
#include "stdexcept.h"
+#include "atomic.h"
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-#if !__has_builtin(__sync_swap)
-#define __sync_swap __sync_lock_test_and_set
-#endif
-
namespace std
{
struct nothrow_t {};
@@ -67,8 +61,13 @@
__attribute__((weak))
new_handler set_new_handler(new_handler handler)
{
- return __sync_swap(&new_handl, handler);
+ return ATOMIC_SWAP(&new_handl, handler);
}
+ __attribute__((weak))
+ new_handler get_new_handler(void)
+ {
+ return ATOMIC_LOAD(&new_handl);
+ }
}
@@ -75,12 +74,17 @@
__attribute__((weak))
void* operator new(size_t size)
{
+ if (0 == size)
+ {
+ size = 1;
+ }
void * mem = malloc(size);
while (0 == mem)
{
- if (0 != new_handl)
+ new_handler h = std::get_new_handler();
+ if (0 != h)
{
- new_handl();
+ h();
}
else
{
@@ -95,35 +99,21 @@
__attribute__((weak))
void* operator new(size_t size, const std::nothrow_t &) throw()
{
- void *mem = malloc(size);
- while (0 == mem)
- {
- if (0 != new_handl)
- {
- try
- {
- new_handl();
- }
- catch (...)
- {
- // nothrow operator new should return NULL in case of
- // std::bad_alloc exception in new handler
- return NULL;
- }
- }
- else
- {
- return NULL;
- }
- mem = malloc(size);
+ try {
+ return :: operator new(size);
+ } catch (...) {
+ // nothrow operator new should return NULL in case of
+ // std::bad_alloc exception in new handler
+ return NULL;
}
-
- return mem;
}
__attribute__((weak))
void operator delete(void * ptr)
+#if __cplusplus < 201000L
+throw()
+#endif
{
free(ptr);
}
@@ -131,6 +121,9 @@
__attribute__((weak))
void * operator new[](size_t size)
+#if __cplusplus < 201000L
+throw(std::bad_alloc)
+#endif
{
return ::operator new(size);
}
@@ -137,8 +130,24 @@
__attribute__((weak))
-void operator delete[](void * ptr) throw()
+void * operator new[](size_t size, const std::nothrow_t &) throw()
{
+ try {
+ return ::operator new[](size);
+ } catch (...) {
+ // nothrow operator new should return NULL in case of
+ // std::bad_alloc exception in new handler
+ return NULL;
+ }
+}
+
+
+__attribute__((weak))
+void operator delete[](void * ptr)
+#if __cplusplus < 201000L
+throw()
+#endif
+{
::operator delete(ptr);
}
Modified: trunk/contrib/libcxxrt/stdexcept.cc
===================================================================
--- trunk/contrib/libcxxrt/stdexcept.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/stdexcept.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -82,5 +82,18 @@
return "std::bad_typeid";
}
+bad_array_new_length::bad_array_new_length() throw() {}
+bad_array_new_length::~bad_array_new_length() {}
+bad_array_new_length::bad_array_new_length(const bad_array_new_length&) throw() {}
+bad_array_new_length& bad_array_new_length::operator=(const bad_array_new_length&) throw()
+{
+ return *this;
+}
+
+const char* bad_array_new_length::what() const throw()
+{
+ return "std::bad_array_new_length";
+}
+
} // namespace std
Modified: trunk/contrib/libcxxrt/stdexcept.h
===================================================================
--- trunk/contrib/libcxxrt/stdexcept.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/stdexcept.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -81,6 +81,15 @@
virtual const char* what() const throw();
};
+ class bad_array_new_length: public bad_alloc
+ {
+ public:
+ bad_array_new_length() throw();
+ bad_array_new_length(const bad_array_new_length&) throw();
+ bad_array_new_length& operator=(const bad_array_new_length&) throw();
+ virtual ~bad_array_new_length();
+ virtual const char *what() const throw();
+ };
} // namespace std
Modified: trunk/contrib/libcxxrt/typeinfo.cc
===================================================================
--- trunk/contrib/libcxxrt/typeinfo.cc 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/typeinfo.cc 2016-02-28 21:26:57 UTC (rev 7451)
@@ -86,7 +86,18 @@
if (NULL != demangled)
{
size_t len = strlen(demangled);
- buf = (char*)realloc(buf, len+1);
+ if (buf == NULL)
+ {
+ if (n)
+ {
+ *n = len;
+ }
+ return demangled;
+ }
+ if (*n < len+1)
+ {
+ buf = static_cast<char*>(realloc(buf, len+1));
+ }
if (0 != buf)
{
memcpy(buf, demangled, len);
Modified: trunk/contrib/libcxxrt/typeinfo.h
===================================================================
--- trunk/contrib/libcxxrt/typeinfo.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/typeinfo.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -70,6 +70,14 @@
*/
public:
/**
+ * Returns true if this is some pointer type, false otherwise.
+ */
+ virtual bool __is_pointer_p() const { return false; }
+ /**
+ * Returns true if this is some function type, false otherwise.
+ */
+ virtual bool __is_function_p() const { return false; }
+ /**
* Catch function. Allows external libraries to implement
* their own basic types. This is used, for example, in the
* GNUstep Objective-C runtime to allow Objective-C types to be
@@ -95,14 +103,6 @@
{
return false;
}
- /**
- * Returns true if this is some pointer type, false otherwise.
- */
- virtual bool __is_pointer_p() const { return false; }
- /**
- * Returns true if this is some function type, false otherwise.
- */
- virtual bool __is_function_p() const { return false; }
};
}
@@ -284,7 +284,6 @@
/** Pointer is a pointer to a member of an incomplete class. */
__incomplete_class_mask = 0x10
};
- virtual bool __is_pointer_p() const { return true; }
virtual bool __do_catch(const type_info *thrown_type,
void **thrown_object,
unsigned outer) const;
@@ -296,6 +295,7 @@
struct __pointer_type_info : public __pbase_type_info
{
virtual ~__pointer_type_info();
+ virtual bool __is_pointer_p() const { return true; }
};
/**
Modified: trunk/contrib/libcxxrt/unwind-arm.h
===================================================================
--- trunk/contrib/libcxxrt/unwind-arm.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/unwind-arm.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -36,6 +36,8 @@
_URC_FATAL_PHASE1_ERROR = _URC_FAILURE
} _Unwind_Reason_Code;
+typedef int _Unwind_Action;
+
typedef uint32_t _Unwind_State;
#ifdef __clang__
static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0;
@@ -218,6 +220,6 @@
break;\
}\
}\
- _Unwind_SetGR (context, 12, (unsigned long)exceptionObject);\
+ _Unwind_SetGR (context, 12, reinterpret_cast<unsigned long>(exceptionObject));\
#define CALL_PERSONALITY_FUNCTION(name) name(state,exceptionObject,context)
Modified: trunk/contrib/libcxxrt/unwind-itanium.h
===================================================================
--- trunk/contrib/libcxxrt/unwind-itanium.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/unwind-itanium.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -80,7 +80,7 @@
_Unwind_Exception_Cleanup_Fn exception_cleanup;
unsigned long private_1;
unsigned long private_2;
- } __attribute__((__aligned__));
+ } ;
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
Modified: trunk/contrib/libcxxrt/unwind.h
===================================================================
--- trunk/contrib/libcxxrt/unwind.h 2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/unwind.h 2016-02-28 21:26:57 UTC (rev 7451)
@@ -27,7 +27,7 @@
extern "C" {
#endif
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
#include "unwind-arm.h"
#else
#include "unwind-itanium.h"
More information about the Midnightbsd-cvs
mailing list