Commit 38bf94280b

Jakub Konka <kubkon@jakubkonka.com>
2020-12-16 11:55:25
Update libcxxabi
llvm commit b2851aea80e5a8f0cfd6c3c5a56a6b00fb28c6b6
1 parent f9a11fb
lib/libcxxabi/include/__cxxabi_config.h
@@ -18,6 +18,19 @@
 #define __has_attribute(_attribute_) 0
 #endif
 
+#if defined(__clang__)
+#  define _LIBCXXABI_COMPILER_CLANG
+#  ifndef __apple_build_version__
+#    define _LIBCXXABI_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
+#  endif
+#elif defined(__GNUC__)
+#  define _LIBCXXABI_COMPILER_GCC
+#elif defined(_MSC_VER)
+#  define _LIBCXXABI_COMPILER_MSVC
+#elif defined(__IBMCPP__)
+#  define _LIBCXXABI_COMPILER_IBM
+#endif
+
 #if defined(_WIN32)
  #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
   #define _LIBCXXABI_HIDDEN
@@ -53,7 +66,7 @@
  #endif
 #endif
 
-#if defined(_WIN32)
+#if defined(_LIBCXXABI_COMPILER_MSVC)
 #define _LIBCXXABI_WEAK
 #else
 #define _LIBCXXABI_WEAK __attribute__((__weak__))
@@ -72,7 +85,7 @@
 #endif
 
 // wasm32 follows the arm32 ABI convention of using 32-bit guard.
-#if defined(__arm__) || defined(__wasm32__)
+#if defined(__arm__) || defined(__wasm32__) || defined(__ARM64_ARCH_8_32__)
 #  define _LIBCXXABI_GUARD_ABI_ARM
 #endif
 
lib/libcxxabi/include/cxxabi.h
@@ -21,6 +21,7 @@
 
 #define _LIBCPPABI_VERSION 1002
 #define _LIBCXXABI_NORETURN  __attribute__((noreturn))
+#define _LIBCXXABI_ALWAYS_COLD __attribute__((cold))
 
 #ifdef __cplusplus
 
@@ -78,13 +79,13 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
 
 // 3.3.2 One-time Construction API
 #if defined(_LIBCXXABI_GUARD_ABI_ARM)
-extern _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(uint32_t *);
-extern _LIBCXXABI_FUNC_VIS void __cxa_guard_release(uint32_t *);
-extern _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(uint32_t *);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t *);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t *);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t *);
 #else
-extern _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(uint64_t *);
-extern _LIBCXXABI_FUNC_VIS void __cxa_guard_release(uint64_t *);
-extern _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(uint64_t *);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t *);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t *);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t *);
 #endif
 
 // 3.3.3 Array Construction and Destruction API
@@ -136,9 +137,9 @@ __cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
                 void (*destructor)(void *));
 
 // 3.3.5.3 Runtime API
-extern _LIBCXXABI_FUNC_VIS int __cxa_atexit(void (*f)(void *), void *p,
-                                            void *d);
-extern _LIBCXXABI_FUNC_VIS int __cxa_finalize(void *);
+// These functions are part of the C++ ABI, but they are not defined in libc++abi:
+//    int __cxa_atexit(void (*)(void *), void *, void *);
+//    void __cxa_finalize(void *);
 
 // 3.4 Demangler API
 extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
lib/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -82,6 +82,7 @@
     X(PostfixExpr) \
     X(ConditionalExpr) \
     X(MemberExpr) \
+    X(SubobjectExpr) \
     X(EnclosingExpr) \
     X(CastExpr) \
     X(SizeofParamPackExpr) \
@@ -91,6 +92,7 @@
     X(PrefixExpr) \
     X(FunctionParam) \
     X(ConversionExpr) \
+    X(PointerToMemberConversionExpr) \
     X(InitListExpr) \
     X(FoldExpr) \
     X(ThrowExpr) \
@@ -1656,6 +1658,40 @@ public:
   }
 };
 
+class SubobjectExpr : public Node {
+  const Node *Type;
+  const Node *SubExpr;
+  StringView Offset;
+  NodeArray UnionSelectors;
+  bool OnePastTheEnd;
+
+public:
+  SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
+                NodeArray UnionSelectors_, bool OnePastTheEnd_)
+      : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
+        UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
+
+  template<typename Fn> void match(Fn F) const {
+    F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
+  }
+
+  void printLeft(OutputStream &S) const override {
+    SubExpr->print(S);
+    S += ".<";
+    Type->print(S);
+    S += " at offset ";
+    if (Offset.empty()) {
+      S += "0";
+    } else if (Offset[0] == 'n') {
+      S += "-";
+      S += Offset.dropFront();
+    } else {
+      S += Offset;
+    }
+    S += ">";
+  }
+};
+
 class EnclosingExpr : public Node {
   const StringView Prefix;
   const Node *Infix;
@@ -1843,6 +1879,28 @@ public:
   }
 };
 
+class PointerToMemberConversionExpr : public Node {
+  const Node *Type;
+  const Node *SubExpr;
+  StringView Offset;
+
+public:
+  PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
+                                StringView Offset_)
+      : Node(KPointerToMemberConversionExpr), Type(Type_), SubExpr(SubExpr_),
+        Offset(Offset_) {}
+
+  template<typename Fn> void match(Fn F) const { F(Type, SubExpr, Offset); }
+
+  void printLeft(OutputStream &S) const override {
+    S += "(";
+    Type->print(S);
+    S += ")(";
+    SubExpr->print(S);
+    S += ")";
+  }
+};
+
 class InitListExpr : public Node {
   const Node *Ty;
   NodeArray Inits;
@@ -2313,9 +2371,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
     TemplateParamList Params;
 
   public:
-    ScopedTemplateParamList(AbstractManglingParser *Parser)
-        : Parser(Parser),
-          OldNumTemplateParamLists(Parser->TemplateParams.size()) {
+    ScopedTemplateParamList(AbstractManglingParser *TheParser)
+        : Parser(TheParser),
+          OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
       Parser->TemplateParams.push_back(&Params);
     }
     ~ScopedTemplateParamList() {
@@ -2437,6 +2495,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
   Node *parseConversionExpr();
   Node *parseBracedExpr();
   Node *parseFoldExpr();
+  Node *parsePointerToMemberConversionExpr();
+  Node *parseSubobjectExpr();
 
   /// Parse the <type> production.
   Node *parseType();
@@ -4404,6 +4464,50 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
   return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
 }
 
+// <expression> ::= mc <parameter type> <expr> [<offset number>] E
+//
+// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
+template <typename Derived, typename Alloc>
+Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr() {
+  Node *Ty = getDerived().parseType();
+  if (!Ty)
+    return nullptr;
+  Node *Expr = getDerived().parseExpr();
+  if (!Expr)
+    return nullptr;
+  StringView Offset = getDerived().parseNumber(true);
+  if (!consumeIf('E'))
+    return nullptr;
+  return make<PointerToMemberConversionExpr>(Ty, Expr, Offset);
+}
+
+// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
+// <union-selector> ::= _ [<number>]
+//
+// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
+template <typename Derived, typename Alloc>
+Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
+  Node *Ty = getDerived().parseType();
+  if (!Ty)
+    return nullptr;
+  Node *Expr = getDerived().parseExpr();
+  if (!Expr)
+    return nullptr;
+  StringView Offset = getDerived().parseNumber(true);
+  size_t SelectorsBegin = Names.size();
+  while (consumeIf('_')) {
+    Node *Selector = make<NameType>(parseNumber());
+    if (!Selector)
+      return nullptr;
+    Names.push_back(Selector);
+  }
+  bool OnePastTheEnd = consumeIf('p');
+  if (!consumeIf('E'))
+    return nullptr;
+  return make<SubobjectExpr>(
+      Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
+}
+
 // <expression> ::= <unary operator-name> <expression>
 //              ::= <binary operator-name> <expression> <expression>
 //              ::= <ternary operator-name> <expression> <expression> <expression>
@@ -4661,6 +4765,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
     return nullptr;
   case 'm':
     switch (First[1]) {
+    case 'c':
+      First += 2;
+      return parsePointerToMemberConversionExpr();
     case 'i':
       First += 2;
       return getDerived().parseBinaryExpr("-");
@@ -4808,6 +4915,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
         return Ex;
       return make<CastExpr>("static_cast", T, Ex);
     }
+    case 'o':
+      First += 2;
+      return parseSubobjectExpr();
     case 'p': {
       First += 2;
       Node *Child = getDerived().parseExpr();
@@ -4975,6 +5085,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
   switch (look()) {
   case 'T':
     switch (look(1)) {
+    // TA <template-arg>    # template parameter object
+    //
+    // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
+    case 'A': {
+      First += 2;
+      Node *Arg = getDerived().parseTemplateArg();
+      if (Arg == nullptr)
+        return nullptr;
+      return make<SpecialName>("template parameter object for ", Arg);
+    }
     // TV <type>    # virtual table
     case 'V': {
       First += 2;
@@ -5103,7 +5223,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
     decltype(TemplateParams) OldParams;
 
   public:
-    SaveTemplateParams(AbstractManglingParser *Parser) : Parser(Parser) {
+    SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
       OldParams = std::move(Parser->TemplateParams);
       Parser->TemplateParams.clear();
     }
@@ -5203,7 +5323,12 @@ struct FloatData<long double>
 #else
     static const size_t mangled_size = 20;  // May need to be adjusted to 16 or 24 on other platforms
 #endif
-    static const size_t max_demangled_size = 40;
+    // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
+    // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
+    // Negatives are one character longer than positives.
+    // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
+    // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
+    static const size_t max_demangled_size = 42;
     static constexpr const char *spec = "%LaL";
 };
 
lib/libcxxabi/src/demangle/Utility.h
@@ -52,7 +52,7 @@ class OutputStream {
     char *TempPtr = std::end(Temp);
 
     while (N) {
-      *--TempPtr = '0' + char(N % 10);
+      *--TempPtr = char('0' + N % 10);
       N /= 10;
     }
 
lib/libcxxabi/src/include/refstring.h
@@ -1,131 +0,0 @@
-//===------------------------ __refstring ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: This file is copied from libcxx/src/include/refstring.h. Instead of
-// duplicating the file in libc++abi we should require that the libc++ sources
-// are available when building libc++abi.
-
-#ifndef _LIBCPPABI_REFSTRING_H
-#define _LIBCPPABI_REFSTRING_H
-
-#include <__config>
-#include <stdexcept>
-#include <cstddef>
-#include <cstring>
-#ifdef __APPLE__
-#include <dlfcn.h>
-#include <mach-o/dyld.h>
-#endif
-#include "atomic_support.h"
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-namespace __refstring_imp { namespace {
-typedef int count_t;
-
-struct _Rep_base {
-    std::size_t len;
-    std::size_t cap;
-    count_t     count;
-};
-
-inline _Rep_base* rep_from_data(const char *data_) noexcept {
-    char *data = const_cast<char *>(data_);
-    return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));
-}
-
-inline char * data_from_rep(_Rep_base *rep) noexcept {
-    char *data = reinterpret_cast<char *>(rep);
-    return data + sizeof(*rep);
-}
-
-#if defined(__APPLE__)
-inline
-const char* compute_gcc_empty_string_storage() _NOEXCEPT
-{
-    void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
-    if (handle == nullptr)
-        return nullptr;
-    void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE");
-    if (sym == nullptr)
-        return nullptr;
-    return data_from_rep(reinterpret_cast<_Rep_base *>(sym));
-}
-
-inline
-const char*
-get_gcc_empty_string_storage() _NOEXCEPT
-{
-    static const char* p = compute_gcc_empty_string_storage();
-    return p;
-}
-#endif
-
-}} // namespace __refstring_imp
-
-using namespace __refstring_imp;
-
-inline
-__libcpp_refstring::__libcpp_refstring(const char* msg) {
-    std::size_t len = strlen(msg);
-    _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));
-    rep->len = len;
-    rep->cap = len;
-    rep->count = 0;
-    char *data = data_from_rep(rep);
-    std::memcpy(data, msg, len + 1);
-    __imp_ = data;
-}
-
-inline
-__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT
-    : __imp_(s.__imp_)
-{
-    if (__uses_refcount())
-        __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
-}
-
-inline
-__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
-    bool adjust_old_count = __uses_refcount();
-    struct _Rep_base *old_rep = rep_from_data(__imp_);
-    __imp_ = s.__imp_;
-    if (__uses_refcount())
-        __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
-    if (adjust_old_count)
-    {
-        if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
-        {
-            ::operator delete(old_rep);
-        }
-    }
-    return *this;
-}
-
-inline
-__libcpp_refstring::~__libcpp_refstring() {
-    if (__uses_refcount()) {
-        _Rep_base* rep = rep_from_data(__imp_);
-        if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
-            ::operator delete(rep);
-        }
-    }
-}
-
-inline
-bool __libcpp_refstring::__uses_refcount() const {
-#ifdef __APPLE__
-    return __imp_ != get_gcc_empty_string_storage();
-#else
-    return true;
-#endif
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif //_LIBCPPABI_REFSTRING_H
lib/libcxxabi/src/cxa_guard_impl.h
@@ -54,6 +54,14 @@
 #endif
 #endif
 
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wtautological-pointer-compare"
+#elif defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Waddress"
+#endif
+
 // To make testing possible, this header is included from both cxa_guard.cpp
 // and a number of tests.
 //
@@ -112,25 +120,25 @@ class AtomicInt {
 public:
   using MemoryOrder = std::__libcpp_atomic_order;
 
-  explicit AtomicInt(IntType *b) : b(b) {}
+  explicit AtomicInt(IntType *b) : b_(b) {}
   AtomicInt(AtomicInt const&) = delete;
   AtomicInt& operator=(AtomicInt const&) = delete;
 
   IntType load(MemoryOrder ord) {
-    return std::__libcpp_atomic_load(b, ord);
+    return std::__libcpp_atomic_load(b_, ord);
   }
   void store(IntType val, MemoryOrder ord) {
-    std::__libcpp_atomic_store(b, val, ord);
+    std::__libcpp_atomic_store(b_, val, ord);
   }
   IntType exchange(IntType new_val, MemoryOrder ord) {
-    return std::__libcpp_atomic_exchange(b, new_val, ord);
+    return std::__libcpp_atomic_exchange(b_, new_val, ord);
   }
   bool compare_exchange(IntType *expected, IntType desired, MemoryOrder ord_success, MemoryOrder ord_failure) {
-    return std::__libcpp_atomic_compare_exchange(b, expected, desired, ord_success, ord_failure);
+    return std::__libcpp_atomic_compare_exchange(b_, expected, desired, ord_success, ord_failure);
   }
 
 private:
-  IntType *b;
+  IntType *b_;
 };
 
 //===----------------------------------------------------------------------===//
@@ -154,14 +162,7 @@ constexpr uint32_t (*PlatformThreadID)() = nullptr;
 
 
 constexpr bool PlatformSupportsThreadID() {
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
-#endif
   return +PlatformThreadID != nullptr;
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
 }
 
 //===----------------------------------------------------------------------===//
@@ -375,18 +376,18 @@ private:
     LockGuard& operator=(LockGuard const&) = delete;
 
     explicit LockGuard(const char* calling_func)
-        : calling_func(calling_func)  {
+        : calling_func_(calling_func)  {
       if (global_mutex.lock())
-        ABORT_WITH_MESSAGE("%s failed to acquire mutex", calling_func);
+        ABORT_WITH_MESSAGE("%s failed to acquire mutex", calling_func_);
     }
 
     ~LockGuard() {
       if (global_mutex.unlock())
-        ABORT_WITH_MESSAGE("%s failed to release mutex", calling_func);
+        ABORT_WITH_MESSAGE("%s failed to release mutex", calling_func_);
     }
 
   private:
-    const char* const calling_func;
+    const char* const calling_func_;
   };
 };
 
@@ -411,14 +412,7 @@ constexpr void (*PlatformFutexWake)(int*) = nullptr;
 #endif
 
 constexpr bool PlatformSupportsFutex() {
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
-#endif
   return +PlatformFutexWait != nullptr;
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
 }
 
 /// InitByteFutex - Manages initialization using atomics and the futex syscall
@@ -589,4 +583,10 @@ using SelectedImplementation =
 } // end namespace
 } // end namespace __cxxabiv1
 
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#elif defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
+
 #endif // LIBCXXABI_SRC_INCLUDE_CXA_GUARD_IMPL_H
lib/libcxxabi/src/fallback_malloc.cpp
@@ -6,9 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Define _LIBCPP_BUILDING_LIBRARY to ensure _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
-// is only defined when libc aligned allocation is not available.
-#define _LIBCPP_BUILDING_LIBRARY
 #include "fallback_malloc.h"
 
 #include <__threading_support>
@@ -20,6 +17,7 @@
 
 #include <stdlib.h> // for malloc, calloc, free
 #include <string.h> // for memset
+#include <new> // for std::__libcpp_aligned_{alloc,free}
 
 //  A small, simple heap manager based (loosely) on
 //  the startup heap manager from FreeBSD, optimized for space.
@@ -144,29 +142,26 @@ void fallback_free(void* ptr) {
   mutexor mtx(&heap_mutex);
 
 #ifdef DEBUG_FALLBACK_MALLOC
-  std::cout << "Freeing item at " << offset_from_node(cp) << " of size "
-            << cp->len << std::endl;
+  std::printf("Freeing item at %d of size %d\n", offset_from_node(cp), cp->len);
 #endif
 
   for (p = freelist, prev = 0; p && p != list_end;
        prev = p, p = node_from_offset(p->next_node)) {
 #ifdef DEBUG_FALLBACK_MALLOC
-    std::cout << "  p, cp, after (p), after(cp) " << offset_from_node(p) << ' '
-              << offset_from_node(cp) << ' ' << offset_from_node(after(p))
-              << ' ' << offset_from_node(after(cp)) << std::endl;
+    std::printf("  p=%d, cp=%d, after(p)=%d, after(cp)=%d\n",
+      offset_from_node(p), offset_from_node(cp),
+      offset_from_node(after(p)), offset_from_node(after(cp)));
 #endif
     if (after(p) == cp) {
 #ifdef DEBUG_FALLBACK_MALLOC
-      std::cout << "  Appending onto chunk at " << offset_from_node(p)
-                << std::endl;
+      std::printf("  Appending onto chunk at %d\n", offset_from_node(p));
 #endif
       p->len = static_cast<heap_size>(
           p->len + cp->len); // make the free heap_node larger
       return;
     } else if (after(cp) == p) { // there's a free heap_node right after
 #ifdef DEBUG_FALLBACK_MALLOC
-      std::cout << "  Appending free chunk at " << offset_from_node(p)
-                << std::endl;
+      std::printf("  Appending free chunk at %d\n", offset_from_node(p));
 #endif
       cp->len = static_cast<heap_size>(cp->len + p->len);
       if (prev == 0) {
@@ -179,8 +174,7 @@ void fallback_free(void* ptr) {
   }
 //  Nothing to merge with, add it to the start of the free list
 #ifdef DEBUG_FALLBACK_MALLOC
-  std::cout << "  Making new free list entry " << offset_from_node(cp)
-            << std::endl;
+  std::printf("  Making new free list entry %d\n", offset_from_node(cp));
 #endif
   cp->next_node = offset_from_node(freelist);
   freelist = cp;
@@ -195,11 +189,11 @@ size_t print_free_list() {
 
   for (p = freelist, prev = 0; p && p != list_end;
        prev = p, p = node_from_offset(p->next_node)) {
-    std::cout << (prev == 0 ? "" : "  ") << "Offset: " << offset_from_node(p)
-              << "\tsize: " << p->len << " Next: " << p->next_node << std::endl;
+    std::printf("%sOffset: %d\tsize: %d Next: %d\n",
+      (prev == 0 ? "" : "  "), offset_from_node(p), p->len, p->next_node);
     total_free += p->len;
   }
-  std::cout << "Total Free space: " << total_free << std::endl;
+  std::printf("Total Free space: %d\n", total_free);
   return total_free;
 }
 #endif
@@ -211,7 +205,7 @@ struct __attribute__((aligned)) __aligned_type {};
 
 void* __aligned_malloc_with_fallback(size_t size) {
 #if defined(_WIN32)
-  if (void* dest = _aligned_malloc(size, alignof(__aligned_type)))
+  if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
     return dest;
 #elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
   if (void* dest = ::malloc(size))
@@ -219,8 +213,7 @@ void* __aligned_malloc_with_fallback(size_t size) {
 #else
   if (size == 0)
     size = 1;
-  void* dest;
-  if (::posix_memalign(&dest, __alignof(__aligned_type), size) == 0)
+  if (void* dest = std::__libcpp_aligned_alloc(__alignof(__aligned_type), size))
     return dest;
 #endif
   return fallback_malloc(size);
@@ -241,10 +234,10 @@ void __aligned_free_with_fallback(void* ptr) {
   if (is_fallback_ptr(ptr))
     fallback_free(ptr);
   else {
-#if defined(_WIN32)
-    ::_aligned_free(ptr);
-#else
+#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
     ::free(ptr);
+#else
+    std::__libcpp_aligned_free(ptr);
 #endif
   }
 }
lib/libcxxabi/src/private_typeinfo.cpp
@@ -61,6 +61,16 @@ is_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp)
     return x == y || strcmp(x->name(), y->name()) == 0;
 }
 
+static inline ptrdiff_t update_offset_to_base(const char* vtable,
+                                              ptrdiff_t offset_to_base) {
+#if __has_feature(cxx_abi_relative_vtable)
+  // VTable components are 32 bits in the relative vtables ABI.
+  return *reinterpret_cast<const int32_t*>(vtable + offset_to_base);
+#else
+  return *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+#endif
+}
+
 namespace __cxxabiv1
 {
 
@@ -297,7 +307,7 @@ __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
         if (__offset_flags & __virtual_mask)
         {
             const char* vtable = *static_cast<const char*const*>(adjustedPtr);
-            offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+            offset_to_base = update_offset_to_base(vtable, offset_to_base);
         }
     }
     __base_type->has_unambiguous_public_base(
@@ -615,10 +625,26 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
     // Possible future optimization:  Take advantage of src2dst_offset
 
     // Get (dynamic_ptr, dynamic_type) from static_ptr
+#if __has_feature(cxx_abi_relative_vtable)
+    // The vtable address will point to the first virtual function, which is 8
+    // bytes after the start of the vtable (4 for the offset from top + 4 for the typeinfo component).
+    const int32_t* vtable =
+        *reinterpret_cast<const int32_t* const*>(static_ptr);
+    int32_t offset_to_derived = vtable[-2];
+    const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
+
+    // The typeinfo component is now a relative offset to a proxy.
+    int32_t offset_to_ti_proxy = vtable[-1];
+    const uint8_t* ptr_to_ti_proxy =
+        reinterpret_cast<const uint8_t*>(vtable) + offset_to_ti_proxy;
+    const __class_type_info* dynamic_type =
+        *(reinterpret_cast<const __class_type_info* const*>(ptr_to_ti_proxy));
+#else
     void **vtable = *static_cast<void ** const *>(static_ptr);
     ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
     const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
     const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);
+#endif
 
     // Initialize answer to nullptr.  This will be changed from the search
     //    results if a non-null answer is found.  Regardless, this is what will
@@ -641,6 +667,7 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
         {
             // We get here only if there is some kind of visibility problem
             //   in client code.
+            static_assert(std::atomic<size_t>::is_always_lock_free, "");
             static std::atomic<size_t> error_count(0);
             size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
             if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
@@ -667,6 +694,7 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
         if (info.path_dst_ptr_to_static_ptr == unknown &&
             info.path_dynamic_ptr_to_static_ptr == unknown)
         {
+            static_assert(std::atomic<size_t>::is_always_lock_free, "");
             static std::atomic<size_t> error_count(0);
             size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
             if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
@@ -1265,7 +1293,7 @@ __base_class_type_info::search_above_dst(__dynamic_cast_info* info,
     if (__offset_flags & __virtual_mask)
     {
         const char* vtable = *static_cast<const char*const*>(current_ptr);
-        offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+        offset_to_base = update_offset_to_base(vtable, offset_to_base);
     }
     __base_type->search_above_dst(info, dst_ptr,
                                   static_cast<const char*>(current_ptr) + offset_to_base,
@@ -1285,7 +1313,7 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info,
     if (__offset_flags & __virtual_mask)
     {
         const char* vtable = *static_cast<const char*const*>(current_ptr);
-        offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+        offset_to_base = update_offset_to_base(vtable, offset_to_base);
     }
     __base_type->search_below_dst(info,
                                   static_cast<const char*>(current_ptr) + offset_to_base,
lib/libcxxabi/src/stdlib_exception.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_BUILDING_LIBRARY
 #include <new>
 #include <exception>
 
lib/libcxxabi/src/stdlib_new_delete.cpp
@@ -8,7 +8,6 @@
 // This file implements the new and delete operators.
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_BUILDING_LIBRARY
 #include "__cxxabi_config.h"
 #include <new>
 #include <cstdlib>
@@ -28,7 +27,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
     if (size == 0)
         size = 1;
     void* p;
-    while ((p = ::malloc(size)) == 0)
+    while ((p = ::malloc(size)) == nullptr)
     {
         // If malloc fails and there is a new_handler,
         // call it to try free up memory.
@@ -49,7 +48,7 @@ _LIBCXXABI_WEAK
 void*
 operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
 {
-    void* p = 0;
+    void* p = nullptr;
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
     try
     {
@@ -75,7 +74,7 @@ _LIBCXXABI_WEAK
 void*
 operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
 {
-    void* p = 0;
+    void* p = nullptr;
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
     try
     {
@@ -143,15 +142,16 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
         size = 1;
     if (static_cast<size_t>(alignment) < sizeof(void*))
       alignment = std::align_val_t(sizeof(void*));
+
+    // Try allocating memory. If allocation fails and there is a new_handler,
+    // call it to try free up memory, and try again until it succeeds, or until
+    // the new_handler decides to terminate.
+    //
+    // If allocation fails and there is no new_handler, we throw bad_alloc
+    // (or return nullptr if exceptions are disabled).
     void* p;
-#if defined(_LIBCPP_WIN32API)
-    while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
-#else
-    while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
-#endif
+    while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
     {
-        // If posix_memalign fails and there is a new_handler,
-        // call it to try free up memory.
         std::new_handler nh = std::get_new_handler();
         if (nh)
             nh();
@@ -159,7 +159,6 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
             throw std::bad_alloc();
 #else
-            p = nullptr; // posix_memalign doesn't initialize 'p' on failure
             break;
 #endif
         }
@@ -171,7 +170,7 @@ _LIBCXXABI_WEAK
 void*
 operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
 {
-    void* p = 0;
+    void* p = nullptr;
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
     try
     {
@@ -197,7 +196,7 @@ _LIBCXXABI_WEAK
 void*
 operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
 {
-    void* p = 0;
+    void* p = nullptr;
 #ifndef _LIBCXXABI_NO_EXCEPTIONS
     try
     {
@@ -216,12 +215,9 @@ _LIBCXXABI_WEAK
 void
 operator delete(void* ptr, std::align_val_t) _NOEXCEPT
 {
-    if (ptr)
-#if defined(_LIBCPP_WIN32API)
-        ::_aligned_free(ptr);
-#else
-        ::free(ptr);
-#endif
+    if (ptr) {
+        std::__libcpp_aligned_free(ptr);
+    }
 }
 
 _LIBCXXABI_WEAK
lib/libcxxabi/src/stdlib_stdexcept.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "include/refstring.h"
+#include "../../libcxx/src/include/refstring.h"
 #include "stdexcept"
 #include "new"
 #include <cstdlib>