Add LLVM libcxxabi (#1063)

* third_party: Add libcxxabi

Added libcxxabi from LLVM 17.0.6
The library implements the Itanium C++ exception handling ABI.

* third_party/libcxxabi: Enable __cxa_thread_atexit

Enable `__cxa_thread_atexit` from libcxxabi.
`__cxa_thread_atexit_impl` is still implemented by the cosmo libc.
The original `__cxa_thread_atexit` has been removed.

* third_party/libcxx: Build with exceptions

Build libcxx with exceptions enabled.

- Removed `_LIBCPP_NO_EXCEPTIONS` from `__config`.
- Switched the exception implementation to `libcxxabi`. These two files
are taken from the same `libcxx` version as mentioned in `README.cosmo`.
- Removed `new_handler_fallback` in favor of `libcxxabi` implementation.
- Enable `-fexceptions` and `-frtti` for `libcxx`.
- Removed `THIRD_PARTY_LIBCXX` dependency from `libcxxabi` and
`libunwind`. These libraries do not use any runtime `libcxx` functions,
just headers.

* libc: Remove remaining redundant cxa functions

- `__cxa_pure_virtual` in `libcxxabi` is also a stub similar to the
existing one.
- `__cxa_guard_*` from `libcxxabi` is used instead of the ones from
Android.

Now there should be no more duplicate implementations.
`__cxa_thread_atexit_impl`, `__cxa_atexit`, and related supporting
functions, are still left to other libraries as in `libcxxabi`.

`libcxxabi` is also now added to `cosmopolitan.a` to make up for the
removed functions.

Affected in-tree libraries (`third_party/double-conversion`) have been
updated.
This commit is contained in:
Trung Nguyen 2024-01-08 23:45:10 +07:00 committed by GitHub
parent 94bab1618d
commit 8b33204f37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 14606 additions and 372 deletions

View file

@ -70,8 +70,8 @@ THIRD_PARTY_LIBCXX_A_HDRS = \
third_party/libcxx/deque \
third_party/libcxx/errno.h \
third_party/libcxx/exception \
third_party/libcxx/exception_fallback.hh \
third_party/libcxx/exception_pointer_unimplemented.hh \
third_party/libcxx/exception_libcxxabi.hh \
third_party/libcxx/exception_pointer_cxxabi.hh \
third_party/libcxx/execution \
third_party/libcxx/experimental/__config \
third_party/libcxx/filesystem \
@ -99,7 +99,6 @@ THIRD_PARTY_LIBCXX_A_HDRS = \
third_party/libcxx/memory \
third_party/libcxx/mutex \
third_party/libcxx/new \
third_party/libcxx/new_handler_fallback.hh \
third_party/libcxx/numeric \
third_party/libcxx/optional \
third_party/libcxx/ostream \
@ -200,7 +199,9 @@ THIRD_PARTY_LIBCXX_A_DIRECTDEPS = \
LIBC_THREAD \
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_GDTOA
THIRD_PARTY_GDTOA \
THIRD_PARTY_LIBCXXABI \
THIRD_PARTY_LIBUNWIND
THIRD_PARTY_LIBCXX_A_DEPS := \
$(call uniq,$(foreach x,$(THIRD_PARTY_LIBCXX_A_DIRECTDEPS),$($(x))))
@ -217,7 +218,10 @@ $(THIRD_PARTY_LIBCXX_A).pkg: \
$(THIRD_PARTY_LIBCXX_A_OBJS): private \
CXXFLAGS += \
-ffunction-sections \
-fdata-sections
-fdata-sections \
-fexceptions \
-frtti \
-DLIBCXX_BUILDING_LIBCXXABI
THIRD_PARTY_LIBCXX_LIBS = $(foreach x,$(THIRD_PARTY_LIBCXX_ARTIFACTS),$($(x)))
THIRD_PARTY_LIBCXX_SRCS = $(foreach x,$(THIRD_PARTY_LIBCXX_ARTIFACTS),$($(x)_SRCS))

View file

@ -12,7 +12,6 @@
#include "libc/isystem/features.h"
#define _LIBCPP_ABI_UNSTABLE
#define _LIBCPP_NO_EXCEPTIONS
#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
#define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION

View file

@ -11,6 +11,11 @@
#include "third_party/libcxx/new"
#include "third_party/libcxx/typeinfo"
#include "third_party/libcxx/atomic_support.hh"
#include "third_party/libcxx/exception_fallback.hh"
#include "third_party/libcxx/exception_pointer_unimplemented.hh"
#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
#include "third_party/libcxxabi/include/cxxabi.h"
using namespace __cxxabiv1;
#define HAVE_DEPENDENT_EH_ABI 1
#endif
#include "third_party/libcxx/exception_libcxxabi.hh"
#include "third_party/libcxx/exception_pointer_cxxabi.hh"

View file

@ -1,111 +0,0 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "third_party/libcxx/exception"
#include "third_party/libcxx/cstdio"
#include "third_party/libcxx/atomic_support.hh"
namespace std {
_LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler;
#if _LIBCPP_STD_VER <= 14 || \
defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) || \
defined(_LIBCPP_BUILDING_LIBRARY)
_LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
// libcxxrt provides implementations of these functions itself.
unexpected_handler set_unexpected(unexpected_handler func) _NOEXCEPT {
return __libcpp_atomic_exchange(&__unexpected_handler, func);
}
unexpected_handler get_unexpected() _NOEXCEPT {
return __libcpp_atomic_load(&__unexpected_handler);
}
_LIBCPP_NORETURN
void unexpected() {
(*get_unexpected())();
// unexpected handler should not return
terminate();
}
#endif
terminate_handler set_terminate(terminate_handler func) _NOEXCEPT {
return __libcpp_atomic_exchange(&__terminate_handler, func);
}
terminate_handler get_terminate() _NOEXCEPT {
return __libcpp_atomic_load(&__terminate_handler);
}
#ifndef __EMSCRIPTEN__ // We provide this in JS
_LIBCPP_NORETURN
void terminate() _NOEXCEPT {
#ifndef _LIBCPP_NO_EXCEPTIONS
try {
#endif // _LIBCPP_NO_EXCEPTIONS
(*get_terminate())();
// handler should not return
fprintf(stderr, "terminate_handler unexpectedly returned\n");
::abort();
#ifndef _LIBCPP_NO_EXCEPTIONS
} catch (...) {
// handler should not throw exception
fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
::abort();
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
#endif // !__EMSCRIPTEN__
#if !defined(__EMSCRIPTEN__)
bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
int uncaught_exceptions() _NOEXCEPT {
// #warning uncaught_exception not yet implemented
fprintf(stderr, "uncaught_exceptions not yet implemented\n");
::abort();
}
#endif // !__EMSCRIPTEN__
exception::~exception() _NOEXCEPT {}
const char* exception::what() const _NOEXCEPT { return "std::exception"; }
bad_exception::~bad_exception() _NOEXCEPT {}
const char* bad_exception::what() const _NOEXCEPT {
return "std::bad_exception";
}
bad_alloc::bad_alloc() _NOEXCEPT {}
bad_alloc::~bad_alloc() _NOEXCEPT {}
const char* bad_alloc::what() const _NOEXCEPT { return "std::bad_alloc"; }
bad_array_new_length::bad_array_new_length() _NOEXCEPT {}
bad_array_new_length::~bad_array_new_length() _NOEXCEPT {}
const char* bad_array_new_length::what() const _NOEXCEPT {
return "bad_array_new_length";
}
bad_cast::bad_cast() _NOEXCEPT {}
bad_typeid::bad_typeid() _NOEXCEPT {}
bad_cast::~bad_cast() _NOEXCEPT {}
const char* bad_cast::what() const _NOEXCEPT { return "std::bad_cast"; }
bad_typeid::~bad_typeid() _NOEXCEPT {}
const char* bad_typeid::what() const _NOEXCEPT { return "std::bad_typeid"; }
} // namespace std

View file

@ -7,20 +7,21 @@
//
//===----------------------------------------------------------------------===//
#include "third_party/libcxx/__config"
#include "third_party/libcxx/new"
#include "third_party/libcxx/atomic_support.hh"
#include "third_party/libcxxabi/include/cxxabi.h"
#include "third_party/libcxx/exception"
using namespace __cxxabiv1;
namespace std {
_LIBCPP_SAFE_STATIC static std::new_handler __new_handler;
bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
new_handler set_new_handler(new_handler handler) _NOEXCEPT {
return __libcpp_atomic_exchange(&__new_handler, handler);
}
new_handler get_new_handler() _NOEXCEPT {
return __libcpp_atomic_load(&__new_handler);
int uncaught_exceptions() _NOEXCEPT
{
# if _LIBCPPABI_VERSION > 1001
return __cxa_uncaught_exceptions();
# else
return __cxa_uncaught_exception() ? 1 : 0;
# endif
}
} // namespace std

View file

@ -0,0 +1,73 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "third_party/libcxxabi/include/cxxabi.h"
#include "third_party/libcxx/exception"
using namespace __cxxabiv1;
namespace std {
exception_ptr::~exception_ptr() _NOEXCEPT {
__cxa_decrement_exception_refcount(__ptr_);
}
exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
: __ptr_(other.__ptr_)
{
__cxa_increment_exception_refcount(__ptr_);
}
exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
{
if (__ptr_ != other.__ptr_)
{
__cxa_increment_exception_refcount(other.__ptr_);
__cxa_decrement_exception_refcount(__ptr_);
__ptr_ = other.__ptr_;
}
return *this;
}
nested_exception::nested_exception() _NOEXCEPT
: __ptr_(current_exception())
{
}
nested_exception::~nested_exception() _NOEXCEPT
{
}
_LIBCPP_NORETURN
void
nested_exception::rethrow_nested() const
{
if (__ptr_ == nullptr)
terminate();
rethrow_exception(__ptr_);
}
exception_ptr current_exception() _NOEXCEPT
{
// be nicer if there was a constructor that took a ptr, then
// this whole function would be just:
// return exception_ptr(__cxa_current_primary_exception());
exception_ptr ptr;
ptr.__ptr_ = __cxa_current_primary_exception();
return ptr;
}
_LIBCPP_NORETURN
void rethrow_exception(exception_ptr p)
{
__cxa_rethrow_primary_exception(p.__ptr_);
// if p.__ptr_ is NULL, above returns so we terminate
terminate();
}
} // namespace std

View file

@ -1,68 +0,0 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "third_party/libcxx/stdio.h"
#include "third_party/libcxx/stdlib.h"
#include "third_party/libcxx/exception"
namespace std {
exception_ptr::~exception_ptr() _NOEXCEPT {
// #warning exception_ptr not yet implemented
fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
}
exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
: __ptr_(other.__ptr_) {
// #warning exception_ptr not yet implemented
fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
}
exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT {
// #warning exception_ptr not yet implemented
fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
}
nested_exception::nested_exception() _NOEXCEPT : __ptr_(current_exception()) {}
#if !defined(__GLIBCXX__)
nested_exception::~nested_exception() _NOEXCEPT {}
#endif
_LIBCPP_NORETURN
void nested_exception::rethrow_nested() const {
// #warning exception_ptr not yet implemented
fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
#if 0
if (__ptr_ == nullptr)
terminate();
rethrow_exception(__ptr_);
#endif // FIXME
}
exception_ptr current_exception() _NOEXCEPT {
// #warning exception_ptr not yet implemented
fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
}
_LIBCPP_NORETURN
void rethrow_exception(exception_ptr p) {
// #warning exception_ptr not yet implemented
fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
}
} // namespace std

View file

@ -10,7 +10,7 @@
#include "third_party/libcxx/new"
#include "third_party/libcxx/atomic_support.hh"
#include "third_party/libcxx/new_handler_fallback.hh"
#include "third_party/libcxxabi/include/cxxabi.h"
namespace std {