Author: theraven
Date: Fri Nov 25 15:48:30 2011
New Revision: 227973
URL: http://svn.freebsd.org/changeset/base/227973

Log:
  libcxxrt version snapshot created.
  
  Approved by:  dim (mentor)

Added:
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/
     - copied from r227971, vendor/libcxxrt/dist/
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/unwind-arm.h
     - copied unchanged from r227972, vendor/libcxxrt/dist/unwind-arm.h
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/unwind-itanium.h
     - copied unchanged from r227972, vendor/libcxxrt/dist/unwind-itanium.h
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/unwind.h
     - copied unchanged from r227972, vendor/libcxxrt/dist/unwind.h
Replaced:
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/cxxabi.h
     - copied unchanged from r227972, vendor/libcxxrt/dist/cxxabi.h
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/dwarf_eh.h
     - copied unchanged from r227972, vendor/libcxxrt/dist/dwarf_eh.h
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/exception.cc
     - copied unchanged from r227972, vendor/libcxxrt/dist/exception.cc
  vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/guard.cc
     - copied unchanged from r227972, vendor/libcxxrt/dist/guard.cc

Copied: vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/cxxabi.h (from 
r227972, vendor/libcxxrt/dist/cxxabi.h)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/cxxabi.h   Fri Nov 
25 15:48:30 2011        (r227973, copy of r227972, 
vendor/libcxxrt/dist/cxxabi.h)
@@ -0,0 +1,219 @@
+#ifndef __CXXABI_H_
+#define __CXXABI_H_
+#include <stdint.h>
+#include "unwind.h"
+namespace std 
+{
+       class type_info;
+}
+/*
+ * The cxxabi.h header provides a set of public definitions for types and
+ * functions defined by the Itanium C++ ABI specification.  For reference, see
+ * the ABI specification here:
+ *
+ * http://sourcery.mentor.com/public/cxx-abi/abi.html
+ *
+ * All deviations from this specification, unless otherwise noted, are
+ * accidental.
+ */
+
+#ifdef __cplusplus
+namespace __cxxabiv1 {
+extern "C" {
+#endif
+/**
+ * Function type to call when an unexpected exception is encountered.
+ */
+typedef void (*unexpected_handler)();
+/**
+ * Function type to call when an unrecoverable condition is encountered.
+ */
+typedef void (*terminate_handler)();
+
+
+/**
+ * Structure used as a header on thrown exceptions.  This is the same layout as
+ * defined by the Itanium ABI spec, so should be interoperable with any other
+ * implementation of this spec, such as GNU libsupc++.
+ *
+ * This structure is allocated when an exception is thrown.  Unwinding happens
+ * in two phases, the first looks for a handler and the second installs the
+ * context.  This structure stores a cache of the handler location between
+ * phase 1 and phase 2.  Unfortunately, cleanup information is not cached, so
+ * must be looked up in both phases.  This happens for two reasons.  The first
+ * is that we don't know how many frames containing cleanups there will be, and
+ * we should avoid dynamic allocation during unwinding (the exception may be
+ * reporting that we've run out of memory).  The second is that finding
+ * cleanups is much cheaper than finding handlers, because we don't have to
+ * look at the type table at all.
+ *
+ * Note: Several fields of this structure have not-very-informative names.
+ * These are taken from the ABI spec and have not been changed to make it
+ * easier for people referring to to the spec while reading this code.
+ */
+struct __cxa_exception
+{
+#if __LP64__
+       /**
+        * Reference count.  Used to support the C++11 exception_ptr class.  
This
+        * is prepended to the structure in 64-bit mode and squeezed in to the
+        * padding left before the 64-bit aligned _Unwind_Exception at the end 
in
+        * 32-bit mode.
+        *
+        * Note that it is safe to extend this structure at the beginning, 
rather
+        * than the end, because the public API for creating it returns the 
address
+        * of the end (where the exception object can be stored).
+        */
+       uintptr_t referenceCount;
+#endif
+       /** Type info for the thrown object. */
+       std::type_info *exceptionType;
+       /** Destructor for the object, if one exists. */
+       void (*exceptionDestructor) (void *); 
+       /** Handler called when an exception specification is violated. */
+       unexpected_handler unexpectedHandler;
+       /** Hander called to terminate. */
+       terminate_handler terminateHandler;
+       /**
+        * Next exception in the list.  If an exception is thrown inside a catch
+        * block and caught in a nested catch, this points to the exception that
+        * will be handled after the inner catch block completes.
+        */
+       __cxa_exception *nextException;
+       /**
+        * The number of handlers that currently have references to this
+        * exception.  The top (non-sign) bit of this is used as a flag to 
indicate
+        * that the exception is being rethrown, so should not be deleted when 
its
+        * handler count reaches 0 (which it doesn't with the top bit set).
+        */
+       int handlerCount;
+#ifdef __arm__
+       /**
+        * 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
+        * them.
+        */
+       _Unwind_Exception *nextCleanup;
+       /**
+        * The number of cleanups that are currently being run on this 
exception. 
+        */
+       int cleanupCount;
+#endif
+       /**
+        * The selector value to be returned when installing the catch handler.
+        * Used at the call site to determine which catch() block should 
execute.
+        * This is found in phase 1 of unwinding then installed in phase 2.
+        */
+       int handlerSwitchValue;
+       /**
+        * The action record for the catch.  This is cached during phase 1
+        * unwinding.
+        */
+       const char *actionRecord;
+       /**
+        * Pointer to the language-specific data area (LSDA) for the handler
+        * frame.  This is unused in this implementation, but set for ABI
+        * compatibility in case we want to mix code in very weird ways.
+        */
+       const char *languageSpecificData;
+       /** The cached landing pad for the catch handler.*/
+       void *catchTemp;
+       /**
+        * The pointer that will be returned as the pointer to the object.  When
+        * throwing a class and catching a virtual superclass (for example), we
+        * need to adjust the thrown pointer to make it all work correctly.
+        */
+       void *adjustedPtr;
+#if !__LP64__
+       /**
+        * Reference count.  Used to support the C++11 exception_ptr class.  
This
+        * is prepended to the structure in 64-bit mode and squeezed in to the
+        * padding left before the 64-bit aligned _Unwind_Exception at the end 
in
+        * 32-bit mode.
+        *
+        * Note that it is safe to extend this structure at the beginning, 
rather
+        * than the end, because the public API for creating it returns the 
address
+        * of the end (where the exception object can be stored) 
+        */
+       uintptr_t referenceCount;
+#endif
+       /** The language-agnostic part of the exception header. */
+       _Unwind_Exception unwindHeader;
+};
+
+/**
+ * ABI-specified globals structure.  Returned by the __cxa_get_globals()
+ * function and its fast variant.  This is a per-thread structure - every
+ * thread will have one lazily allocated.
+ *
+ * This structure is defined by the ABI, so may be used outside of this
+ * library.
+ */
+struct __cxa_eh_globals
+{
+       /**
+        * A linked list of exceptions that are currently caught.  There may be
+        * several of these in nested catch() blocks.
+        */
+       __cxa_exception *caughtExceptions;
+       /**
+        * The number of uncaught exceptions.
+        */
+       unsigned int uncaughtExceptions;
+};
+/**
+ * ABI function returning the __cxa_eh_globals structure.
+ */
+__cxa_eh_globals *__cxa_get_globals(void);
+/**
+ * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already
+ * been called at least once by this thread.
+ */
+__cxa_eh_globals *__cxa_get_globals_fast(void);
+
+/**
+ * Throws an exception returned by __cxa_current_primary_exception().  This
+ * exception may have been caught in another thread.
+ */
+void __cxa_rethrow_primary_exception(void* thrown_exception);
+/**
+ * Returns the current exception in a form that can be stored in an
+ * exception_ptr object and then rethrown by a call to
+ * __cxa_rethrow_primary_exception().
+ */
+void *__cxa_current_primary_exception(void);
+/**
+ * Increments the reference count of an exception.  Called when an
+ * exception_ptr is copied.
+ */
+void __cxa_increment_exception_refcount(void* thrown_exception);
+/**
+ * Decrements the reference count of an exception.  Called when an
+ * exception_ptr is deleted.
+ */
+void __cxa_decrement_exception_refcount(void* thrown_exception);
+/**
+ * Demangles a C++ symbol or type name.  The buffer, if non-NULL, must be
+ * allocated with malloc() and must be *n bytes or more long.  This function
+ * may call realloc() on the value pointed to by buf, and will return the
+ * length of the string via *n.
+ *
+ * The value pointed to by status is set to one of the following:
+ *
+ * 0: success
+ * -1: memory allocation failure
+ * -2: invalid mangled name
+ * -3: invalid arguments
+ */
+char* __cxa_demangle(const char* mangled_name,
+                     char* buf,
+                     size_t* n,
+                     int* status);
+#ifdef __cplusplus
+} // extern "C"
+} // namespace
+
+namespace abi = __cxxabiv1;
+
+#endif /* __cplusplus */
+#endif /* __CXXABI_H_ */

Copied: vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/dwarf_eh.h 
(from r227972, vendor/libcxxrt/dist/dwarf_eh.h)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/dwarf_eh.h Fri Nov 
25 15:48:30 2011        (r227973, copy of r227972, 
vendor/libcxxrt/dist/dwarf_eh.h)
@@ -0,0 +1,454 @@
+/**
+ * dwarf_eh.h - Defines some helper functions for parsing DWARF exception
+ * handling tables.
+ *
+ * This file contains various helper functions that are independent of the
+ * language-specific code.  It can be used in any personality function for the
+ * Itanium ABI.
+ */
+#include <assert.h>
+
+// TODO: Factor out Itanium / ARM differences.  We probably want an itanium.h
+// and arm.h that can be included by this file depending on the target ABI.
+
+// _GNU_SOURCE must be defined for unwind.h to expose some of the functions
+// that we want.  If it isn't, then we define it and undefine it to make sure
+// that it doesn't impact the rest of the program.
+#ifndef _GNU_SOURCE
+#      define _GNU_SOURCE 1
+#      include "unwind.h"
+#      undef _GNU_SOURCE
+#else
+#      include "unwind.h"
+#endif
+
+#include <stdint.h>
+
+/// Type used for pointers into DWARF data
+typedef unsigned char *dw_eh_ptr_t;
+
+// Flag indicating a signed quantity
+#define DW_EH_PE_signed 0x08
+/// DWARF data encoding types.  
+enum dwarf_data_encoding
+{
+       /// Unsigned, little-endian, base 128-encoded (variable length).
+       DW_EH_PE_uleb128 = 0x01,
+       /// Unsigned 16-bit integer.
+       DW_EH_PE_udata2  = 0x02,
+       /// Unsigned 32-bit integer.
+       DW_EH_PE_udata4  = 0x03,
+       /// Unsigned 64-bit integer.
+       DW_EH_PE_udata8  = 0x04,
+       /// Signed, little-endian, base 128-encoded (variable length)
+       DW_EH_PE_sleb128 = DW_EH_PE_uleb128 | DW_EH_PE_signed,
+       /// Signed 16-bit integer.
+       DW_EH_PE_sdata2  = DW_EH_PE_udata2 | DW_EH_PE_signed,
+       /// Signed 32-bit integer.
+       DW_EH_PE_sdata4  = DW_EH_PE_udata4 | DW_EH_PE_signed,
+       /// Signed 32-bit integer.
+       DW_EH_PE_sdata8  = DW_EH_PE_udata8 | DW_EH_PE_signed
+};
+
+/**
+ * Returns the encoding for a DWARF EH table entry.  The encoding is stored in
+ * the low four of an octet.  The high four bits store the addressing mode.
+ */
+static inline enum dwarf_data_encoding get_encoding(unsigned char x)
+{
+       return (enum dwarf_data_encoding)(x & 0xf);
+}
+
+/**
+ * DWARF addressing mode constants.  When reading a pointer value from a DWARF
+ * exception table, you must know how it is stored and what the addressing mode
+ * is.  The low four bits tell you the encoding, allowing you to decode a
+ * number.  The high four bits tell you the addressing mode, allowing you to
+ * turn that number into an address in memory.
+ */
+enum dwarf_data_relative
+{
+       /// 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
+       DW_EH_PE_textrel  = 0x20,
+       /// Value relative to the data segment
+       DW_EH_PE_datarel  = 0x30,
+       /// Value relative to the start of the function
+       DW_EH_PE_funcrel  = 0x40,
+       /// Aligned pointer (Not supported yet - are they actually used?)
+       DW_EH_PE_aligned  = 0x50,
+       /// Pointer points to address of real value
+       DW_EH_PE_indirect = 0x80
+};
+/**
+ * Returns the addressing mode component of this encoding.
+ */
+static inline enum dwarf_data_relative get_base(unsigned char x)
+{
+       return (enum dwarf_data_relative)(x & 0x70);
+}
+/**
+ * Returns whether an encoding represents an indirect address.
+ */
+static int is_indirect(unsigned char x)
+{
+       return ((x & DW_EH_PE_indirect) == DW_EH_PE_indirect);
+}
+
+/**
+ * Returns the size of a fixed-size encoding.  This function will abort if
+ * called with a value that is not a fixed-size encoding.
+ */
+static inline int dwarf_size_of_fixed_size_field(unsigned char type)
+{
+       switch (get_encoding(type))
+       {
+               default: abort();
+               case DW_EH_PE_sdata2: 
+               case DW_EH_PE_udata2: return 2;
+               case DW_EH_PE_sdata4:
+               case DW_EH_PE_udata4: return 4;
+               case DW_EH_PE_sdata8:
+               case DW_EH_PE_udata8: return 8;
+               case DW_EH_PE_absptr: return sizeof(void*);
+       }
+}
+
+/** 
+ * Read an unsigned, little-endian, base-128, DWARF value.  Updates *data to
+ * point to the end of the value.  Stores the number of bits read in the value
+ * pointed to by b, allowing you to determine the value of the highest bit, and
+ * therefore the sign of a signed value.
+ *
+ * This function is not intended to be called directly.  Use read_sleb128() or
+ * read_uleb128() for reading signed and unsigned versions, respectively.
+ */
+static uint64_t read_leb128(dw_eh_ptr_t *data, int *b)
+{
+       uint64_t uleb = 0;
+       unsigned int bit = 0;
+       unsigned char digit = 0;
+       // We have to read at least one octet, and keep reading until we get to 
one
+       // with the high bit unset
+       do
+       {
+               // This check is a bit too strict - we should also check the 
highest
+               // bit of the digit.
+               assert(bit < sizeof(uint64_t) * 8);
+               // Get the base 128 digit 
+               digit = (**data) & 0x7f;
+               // Add it to the current value
+               uleb += digit << bit;
+               // Increase the shift value
+               bit += 7;
+               // Proceed to the next octet
+               (*data)++;
+               // Terminate when we reach a value that does not have the high 
bit set
+               // (i.e. which was not modified when we mask it with 0x7f)
+       } while ((*(*data - 1)) != digit);
+       *b = bit;
+
+       return uleb;
+}
+
+/**
+ * Reads an unsigned little-endian base-128 value starting at the address
+ * pointed to by *data.  Updates *data to point to the next byte after the end
+ * of the variable-length value.
+ */
+static int64_t read_uleb128(dw_eh_ptr_t *data)
+{
+       int b;
+       return read_leb128(data, &b);
+}
+
+/**
+ * Reads a signed little-endian base-128 value starting at the address pointed
+ * to by *data.  Updates *data to point to the next byte after the end of the
+ * variable-length value.
+ */
+static int64_t read_sleb128(dw_eh_ptr_t *data)
+{
+       int bits;
+       // Read as if it's signed
+       uint64_t uleb = read_leb128(data, &bits);
+       // If the most significant bit read is 1, then we need to sign extend it
+       if ((uleb >> (bits-1)) == 1)
+       {
+               // Sign extend by setting all bits in front of it to 1
+               uleb |= ((int64_t)-1) << bits;
+       }
+       return (int64_t)uleb;
+}
+/**
+ * Reads a value using the specified encoding from the address pointed to by
+ * *data.  Updates the value of *data to point to the next byte after the end
+ * of the data.
+ */
+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;
+               READ(DW_EH_PE_udata2, uint16_t)
+               READ(DW_EH_PE_udata4, uint32_t)
+               READ(DW_EH_PE_udata8, uint64_t)
+               READ(DW_EH_PE_sdata2, int16_t)
+               READ(DW_EH_PE_sdata4, int32_t)
+               READ(DW_EH_PE_sdata8, int64_t)
+               READ(DW_EH_PE_absptr, intptr_t)
+#undef READ
+               // Read variable-length types
+               case DW_EH_PE_sleb128:
+                       v = read_sleb128(data);
+                       break;
+               case DW_EH_PE_uleb128:
+                       v = read_uleb128(data);
+                       break;
+               default: abort();
+       }
+
+       return v;
+}
+
+/**
+ * Resolves an indirect value.  This expects an unwind context, an encoding, a
+ * decoded value, and the start of the region as arguments.  The returned value
+ * is a pointer to the address identified by the encoded value.
+ *
+ * If the encoding does not specify an indirect value, then this returns v.
+ */
+static uint64_t resolve_indirect_value(_Unwind_Context *c,
+                                       unsigned char encoding,
+                                       int64_t v,
+                                       dw_eh_ptr_t start)
+{
+       switch (get_base(encoding))
+       {
+               case DW_EH_PE_pcrel:
+                       v += (uint64_t)start;
+                       break;
+               case DW_EH_PE_textrel:
+                       v += (uint64_t)_Unwind_GetTextRelBase(c);
+                       break;
+               case DW_EH_PE_datarel:
+                       v += (uint64_t)_Unwind_GetDataRelBase(c);
+                       break;
+               case DW_EH_PE_funcrel:
+                       v += (uint64_t)_Unwind_GetRegionStart(c);
+               default:
+                       break;
+       }
+       // If this is an indirect value, then it is really the address of the 
real
+       // value
+       // TODO: Check whether this should really always be a pointer - it 
seems to
+       // be a GCC extensions, so not properly documented...
+       if (is_indirect(encoding))
+       {
+               v = (uint64_t)(uintptr_t)*(void**)v;
+       }
+       return v;
+}
+
+
+/**
+ * Reads an encoding and a value, updating *data to point to the next byte.  
+ */
+static inline void read_value_with_encoding(_Unwind_Context *context,
+                                            dw_eh_ptr_t *data,
+                                            uint64_t *out)
+{
+       dw_eh_ptr_t start = *data;
+       unsigned char encoding = *((*data)++);
+       // If this value is omitted, skip it and don't touch the output value
+       if (encoding == DW_EH_PE_omit) { return; }
+
+       *out = read_value(encoding, data);
+       *out = resolve_indirect_value(context, encoding, *out, start);
+}
+
+/**
+ * Structure storing a decoded language-specific data area.  Use parse_lsda()
+ * to generate an instance of this structure from the address returned by the
+ * generic unwind library.  
+ *
+ * You should not need to inspect the fields of this structure directly if you
+ * are just using this header.  The structure stores the locations of the
+ * various tables used for unwinding exceptions and is used by the functions
+ * for reading values from these tables.
+ */
+struct dwarf_eh_lsda
+{
+       /// The start of the region.  This is a cache of the value returned by
+       /// _Unwind_GetRegionStart().
+       dw_eh_ptr_t region_start;
+       /// The start of the landing pads table.
+       dw_eh_ptr_t landing_pads;
+       /// The start of the type table.
+       dw_eh_ptr_t type_table;
+       /// The encoding used for entries in the type tables.
+       unsigned char type_table_encoding;
+       /// The location of the call-site table.
+       dw_eh_ptr_t call_site_table;
+       /// The location of the action table.
+       dw_eh_ptr_t action_table;
+       /// The encoding used for entries in the call-site table.
+       unsigned char callsite_encoding;
+};
+
+/**
+ * Parse the header on the language-specific data area and return a structure
+ * containing the addresses and encodings of the various tables.
+ */
+static inline struct dwarf_eh_lsda parse_lsda(_Unwind_Context *context,
+                                              unsigned char *data)
+{
+       struct dwarf_eh_lsda lsda;
+
+       lsda.region_start = 
(dw_eh_ptr_t)(uintptr_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;
+       read_value_with_encoding(context, &data, &v);
+       lsda.landing_pads = (dw_eh_ptr_t)(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
+       // whether the leading byte is DW_EH_PE_omit (0xff), which is not what 
the
+       // spec says, but does seem to be how G++ indicates this.
+       lsda.type_table = 0;
+       lsda.type_table_encoding = *data++;
+       if (lsda.type_table_encoding != DW_EH_PE_omit)
+       {
+               v = read_uleb128(&data);
+               dw_eh_ptr_t type_table = data;
+               type_table += v;
+               lsda.type_table = type_table;
+               //lsda.type_table = (uintptr_t*)(data + v);
+       }
+#if __arm__
+       lsda.type_table_encoding = (DW_EH_PE_pcrel | DW_EH_PE_indirect);
+#endif
+
+       lsda.callsite_encoding = (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);
+       lsda.action_table = data + callsite_size;
+       // Call site table is immediately after the header
+       lsda.call_site_table = (dw_eh_ptr_t)data;
+
+
+       return lsda;
+}
+
+/**
+ * Structure representing an action to be performed while unwinding.  This
+ * contains the address that should be unwound to and the action record that
+ * provoked this action.
+ */
+struct dwarf_eh_action
+{
+       /** 
+        * The address that this action directs should be the new program 
counter
+        * value after unwinding.
+        */
+       dw_eh_ptr_t landing_pad;
+       /// The address of the action record.
+       dw_eh_ptr_t action_record;
+};
+
+/**
+ * Look up the landing pad that corresponds to the current invoke.
+ * Returns true if record exists.  The context is provided by the generic
+ * unwind library and the lsda should be the result of a call to parse_lsda().
+ *
+ * The action record is returned via the result parameter.  
+ */
+static bool dwarf_eh_find_callsite(struct _Unwind_Context *context,
+                                   struct dwarf_eh_lsda *lsda,
+                                   struct dwarf_eh_action *result)
+{
+       result->action_record = 0;
+       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;
+
+       while (callsite_table <= lsda->action_table)
+       {
+               // Once again, the layout deviates from the spec.
+               uint64_t call_site_start, call_site_size, landing_pad, action;
+               call_site_start = read_value(lsda->callsite_encoding, 
&callsite_table);
+               call_site_size = read_value(lsda->callsite_encoding, 
&callsite_table);
+
+               // Call site entries are sorted, so if we find a call site 
that's after
+               // the current instruction pointer then there is no action 
associated
+               // with this call and we should unwind straight through this 
frame
+               // without doing anything.
+               if (call_site_start > ip) { break; }
+
+               // Read the address of the landing pad and the action from the 
call
+               // site table.
+               landing_pad = read_value(lsda->callsite_encoding, 
&callsite_table);
+               action = read_uleb128(&callsite_table);
+
+               // We should not include the call_site_start (beginning of the 
region)
+               // address in the ip range. For each call site:
+               //
+               // address1: call proc
+               // address2: next instruction
+               //
+               // The call stack contains address2 and not address1, address1 
can be
+               // at the end of another EH region.
+               if (call_site_start < ip && ip <= call_site_start + 
call_site_size)
+               {
+                       if (action)
+                       {
+                               // Action records are 1-biased so both 
no-record and zeroth
+                               // record can be stored.
+                               result->action_record = lsda->action_table + 
action - 1;
+                       }
+                       // No landing pad means keep unwinding.
+                       if (landing_pad)
+                       {
+                               // Landing pad is the offset from the value in 
the header
+                               result->landing_pad = lsda->landing_pads + 
landing_pad;
+                       }
+                       return true;
+               }
+       }
+       return false;
+}
+
+/// 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))
+
+#define GENERIC_EXCEPTION_CLASS(e,f,g,h) \
+        ((uint32_t)e << 24) +\
+        ((uint32_t)f << 16) +\
+        ((uint32_t)g << 8) +\
+        ((uint32_t)h)

Copied: vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/exception.cc 
(from r227972, vendor/libcxxrt/dist/exception.cc)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/libcxxrt/1be67aa8295314fb794c4e933d9bb7c7c33e0ca4/exception.cc       
Fri Nov 25 15:48:30 2011        (r227973, copy of r227972, 
vendor/libcxxrt/dist/exception.cc)
@@ -0,0 +1,1421 @@
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <pthread.h>
+#include "typeinfo.h"
+#include "dwarf_eh.h"
+#include "cxxabi.h"
+
+using namespace ABI_NAMESPACE;
+
+/**
+ * Saves the result of the landing pad that we have found.  For ARM, this is
+ * stored in the generic unwind structure, while on other platforms it is
+ * stored in the C++ exception.
+ */
+static void saveLandingPad(struct _Unwind_Context *context,
+                           struct _Unwind_Exception *ucb,
+                           struct __cxa_exception *ex,
+                           int selector,
+                           dw_eh_ptr_t landingPad)
+{
+#ifdef __arm__
+       // 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;
+#endif
+       // Cache the results for the phase 2 unwind, if we found a handler
+       // and this is not a foreign exception.  
+       if (ex)
+       {
+               ex->handlerSwitchValue = selector;
+               ex->catchTemp = landingPad;
+       }
+}
+
+/**
+ * Loads the saved landing pad.  Returns 1 on success, 0 on failure.
+ */
+static int loadLandingPad(struct _Unwind_Context *context,
+                          struct _Unwind_Exception *ucb,
+                          struct __cxa_exception *ex,
+                          unsigned long *selector,
+                          dw_eh_ptr_t *landingPad)
+{
+#ifdef __arm__
+       *selector = ucb->barrier_cache.bitpattern[1];
+       *landingPad = (dw_eh_ptr_t)ucb->barrier_cache.bitpattern[3];
+       return 1;
+#else
+       if (ex)
+       {
+               *selector = ex->handlerSwitchValue;
+               *landingPad = (dw_eh_ptr_t)ex->catchTemp;
+               return 0;
+       }
+       return 0;
+#endif
+}
+
+static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception 
*ex,
+                                                    struct _Unwind_Context 
*context)
+{
+#ifdef __arm__
+       if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; }
+#endif
+       return _URC_CONTINUE_UNWIND;
+}
+
+
+extern "C" void __cxa_free_exception(void *thrown_exception);
+extern "C" void __cxa_free_dependent_exception(void *thrown_exception);
+extern "C" void* __dynamic_cast(const void *sub,
+                                const __class_type_info *src,
+                                const __class_type_info *dst,
+                                ptrdiff_t src2dst_offset);
+
+/**
+ * The type of a handler that has been found.
+ */
+typedef enum
+{
+       /** No handler. */
+       handler_none,
+       /**
+        * A cleanup - the exception will propagate through this frame, but code
+        * must be run when this happens.
+        */
+       handler_cleanup,
+       /**
+        * A catch statement.  The exception will not propagate past this frame
+        * (without an explicit rethrow).
+        */
+       handler_catch
+} handler_type;
+
+/**
+ * Per-thread info required by the runtime.  We store a single structure
+ * pointer in thread-local storage, because this tends to be a scarce resource
+ * and it's impolite to steal all of it and not leave any for the rest of the
+ * program.
+ *
+ * Instances of this structure are allocated lazily - at most one per thread -
+ * and are destroyed on thread termination.
+ */
+struct __cxa_thread_info
+{
+       /** The termination handler for this thread. */
+       terminate_handler terminateHandler;
+       /** The unexpected exception handler for this thread. */
+       unexpected_handler unexpectedHandler;
+       /**
+        * The number of emergency buffers held by this thread.  This is 0 in
+        * normal operation - the emergency buffers are only used when malloc()
+        * fails to return memory for allocating an exception.  Threads are not
+        * permitted to hold more than 4 emergency buffers (as per 
recommendation
+        * in ABI spec [3.3.1]).
+        */
+       int emergencyBuffersHeld;
+       /**
+        * The exception currently running in a cleanup.
+        */
+       _Unwind_Exception *currentCleanup;
+       /**
+        * The public part of this structure, accessible from outside of this
+        * module.
+        */
+       __cxa_eh_globals globals;
+};
+/**
+ * Dependent exception.  This 
+ */
+struct __cxa_dependent_exception
+{
+#if __LP64__
+       void *primaryException;
+#endif
+       std::type_info *exceptionType;
+       void (*exceptionDestructor) (void *); 
+       unexpected_handler unexpectedHandler;
+       terminate_handler terminateHandler;
+       __cxa_exception *nextException;
+       int handlerCount;
+#ifdef __arm__
+       _Unwind_Exception *nextCleanup;
+       int cleanupCount;
+#endif
+       int handlerSwitchValue;
+       const char *actionRecord;
+       const char *languageSpecificData;
+       void *catchTemp;
+       void *adjustedPtr;
+#if !__LP64__
+       void *primaryException;
+#endif
+       _Unwind_Exception unwindHeader;
+};
+
+
+namespace std
+{
+       void unexpected();
+       class exception
+       {
+               public:
+                       virtual ~exception() throw();
+                       virtual const char* what() const throw();
+       };
+
+}
+
+extern "C" std::type_info *__cxa_current_exception_type();
+
+/**
+ * Class of exceptions to distinguish between this and other exception types.
+ *
+ * The first four characters are the vendor ID.  Currently, we use GNUC,
+ * because we aim for ABI-compatibility with the GNU implementation, and
+ * various checks may test for equality of the class, which is incorrect.
+ */
+static const uint64_t exception_class =
+       EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\0');
+/**
+ * Class used for dependent exceptions.  
+ */
+static const uint64_t dependent_exception_class =
+       EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\x01');
+/**
+ * The low four bytes of the exception class, indicating that we conform to the
+ * Itanium C++ ABI.  This is currently unused, but should be used in the future
+ * if we change our exception class, to allow this library and libsupc++ to be
+ * linked to the same executable and both to interoperate.
+ */
+static const uint32_t abi_exception_class = 
+       GENERIC_EXCEPTION_CLASS('C', '+', '+', '\0');
+
+static bool isCXXException(uint64_t cls)
+{
+       return (cls == exception_class) || (cls == dependent_exception_class);
+}
+
+static bool isDependentException(uint64_t cls)
+{
+       return cls == dependent_exception_class;
+}
+
+static __cxa_exception *exceptionFromPointer(void *ex)
+{
+       return (__cxa_exception*)((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;
+}
+
+
+namespace std
+{
+       // Forward declaration of standard library terminate() function used to
+       // abort execution.
+       void terminate(void);
+}
+
+using namespace ABI_NAMESPACE;
+
+
+
+/** The global termination handler. */
+static terminate_handler terminateHandler = abort;
+/** The global unexpected exception handler. */
+static unexpected_handler unexpectedHandler = std::terminate;
+
+/** Key used for thread-local data. */
+static pthread_key_t eh_key;
+
+
+/**
+ * Cleanup function, allowing foreign exception handlers to correctly destroy
+ * this exception if they catch it.
+ */
+static void exception_cleanup(_Unwind_Reason_Code reason, 
+                              struct _Unwind_Exception *ex)
+{
+       __cxa_free_exception((void*)ex);
+}
+static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 
+                              struct _Unwind_Exception *ex)
+{
+
+       __cxa_free_dependent_exception((void*)ex);
+}
+
+/**
+ * Recursively walk a list of exceptions and delete them all in post-order.
+ */
+static void free_exception_list(__cxa_exception *ex)
+{
+       if (0 != ex->nextException)
+       {
+               free_exception_list(ex->nextException);
+       }
+       // __cxa_free_exception() expects to be passed the thrown object, which
+       // immediately follows the exception, not the exception itself
+       __cxa_free_exception(ex+1);
+}
+
+/**
+ * Cleanup function called when a thread exists to make certain that all of the
+ * per-thread data is deleted.
+ */
+static void thread_cleanup(void* thread_info)
+{
+       __cxa_thread_info *info = (__cxa_thread_info*)thread_info;
+       if (info->globals.caughtExceptions)
+       {
+               free_exception_list(info->globals.caughtExceptions);
+       }
+       free(thread_info);
+}
+
+
+/**
+ * Once control used to protect the key creation.
+ */
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+
+/**
+ * Initialise eh_key.
+ */
+static void init_key(void)
+{
+       pthread_key_create(&eh_key, thread_cleanup);
+}
+
+/**
+ * Returns the thread info structure, creating it if it is not already created.
+ */
+static __cxa_thread_info *thread_info()
+{
+       pthread_once(&once_control, init_key);
+       __cxa_thread_info *info = 
(__cxa_thread_info*)pthread_getspecific(eh_key);
+       if (0 == info)
+       {
+               info = (__cxa_thread_info*)calloc(1, sizeof(__cxa_thread_info));
+               pthread_setspecific(eh_key, info);
+       }
+       return info;
+}
+/**
+ * Fast version of thread_info().  May fail if thread_info() is not called on
+ * this thread at least once already.
+ */
+static __cxa_thread_info *thread_info_fast()
+{

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to