aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
downloadydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch')
-rw-r--r--contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch293
1 files changed, 293 insertions, 0 deletions
diff --git a/contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch b/contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch
new file mode 100644
index 0000000000..7584edf033
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch
@@ -0,0 +1,293 @@
+diff --git a/src/support/runtime/exception_pointer_msvc.ipp b/src/support/runtime/exception_pointer_msvc.ipp
+index 9e7f392..300acbf 100644
+--- a/src/support/runtime/exception_pointer_msvc.ipp
++++ b/src/support/runtime/exception_pointer_msvc.ipp
+@@ -7,70 +7,242 @@
+ //
+ //===----------------------------------------------------------------------===//
+
+-#include <stdio.h>
+-#include <stdlib.h>
+-
+-_LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrCreate(void*);
+-_LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrDestroy(void*);
+-_LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrCopy(void*, const void*);
+-_LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrAssign(void*, const void*);
+-_LIBCPP_CRT_FUNC bool __cdecl __ExceptionPtrCompare(const void*, const void*);
+-_LIBCPP_CRT_FUNC bool __cdecl __ExceptionPtrToBool(const void*);
+-_LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrSwap(void*, void*);
+-_LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrCurrentException(void*);
+-[[noreturn]] _LIBCPP_CRT_FUNC void __cdecl __ExceptionPtrRethrow(const void*);
+-_LIBCPP_CRT_FUNC void __cdecl
+-__ExceptionPtrCopyException(void*, const void*, const void*);
++#include <atomic>
++#include <cstdint>
++#include <cstring>
++#include <malloc.h>
++#include <windows.h> // For RtlPcToFileHeader function
+
+-namespace std {
++struct EHCatchableType {
++ uint32_t properties;
++ int32_t type_info;
++ uint32_t non_virtual_adjustment;
++ uint32_t offset_to_virtual_base_ptr;
++ uint32_t virtual_base_table_index;
++ uint32_t size;
++ int32_t copy_function;
++};
+
+-exception_ptr::exception_ptr() noexcept { __ExceptionPtrCreate(this); }
+-exception_ptr::exception_ptr(nullptr_t) noexcept { __ExceptionPtrCreate(this); }
++struct EHCatchableTypeArray {
++ uint32_t catchable_types;
++ // It is variable size but we only need the first element of this array
++ int32_t array_of_catchable_types[1];
++};
+
+-exception_ptr::exception_ptr(const exception_ptr& __other) noexcept {
+- __ExceptionPtrCopy(this, &__other);
+-}
+-exception_ptr& exception_ptr::operator=(const exception_ptr& __other) noexcept {
+- __ExceptionPtrAssign(this, &__other);
+- return *this;
+-}
++struct EHThrowInfo {
++ uint32_t attributes;
++ int32_t unwind;
++ int32_t forward_compat;
++ int32_t catchable_type_array;
++};
+
+-exception_ptr& exception_ptr::operator=(nullptr_t) noexcept {
+- exception_ptr dummy;
+- __ExceptionPtrAssign(this, &dummy);
+- return *this;
+-}
++struct EHParameters {
++ uint32_t magic_number;
++ void* exception_object;
++ EHThrowInfo* throw_info;
++#ifdef _M_AMD64
++ uintptr_t throw_image_base;
++#endif
++};
+
+-exception_ptr::~exception_ptr() noexcept { __ExceptionPtrDestroy(this); }
++struct EHExceptionRecord {
++ uint32_t exception_code;
++ uint32_t exception_flags;
++ void* exception_record;
++ void* exception_address;
++ uint32_t number_of_parameters;
++ EHParameters parameters;
++};
+
+-exception_ptr::operator bool() const noexcept {
+- return __ExceptionPtrToBool(this);
+-}
++// defined in vcruntime<ver>.dll
++extern "C" EHExceptionRecord** __current_exception();
++
++// This is internal compiler definition for MSVC but not for clang.
++// We use our own EHThrowInfo because _ThrowInfo doesn't match actual
++// compiler-generated structures in 64-bit mode.
++#ifdef __clang__
++struct _ThrowInfo;
++// defined in vcruntime<ver>.dll
++_LIBCPP_NORETURN extern "C" void __stdcall _CxxThrowException(
++ void* __exc, _ThrowInfo* __throw_info);
++#endif
++
++namespace {
++struct ExceptionPtr {
++ void* exception_object;
++ const EHThrowInfo* throw_info;
++ std::atomic<size_t> counter;
++#ifdef _M_AMD64
++ PVOID image_base;
++#endif
++ template <class T>
++ T convert(int32_t offset) {
++#ifdef _M_AMD64
++ uintptr_t value = reinterpret_cast<uintptr_t>(image_base) +
++ static_cast<uintptr_t>(offset);
++#else
++ uintptr_t value = static_cast<uintptr_t>(offset);
++#endif
++ T res;
++ static_assert(
++ sizeof(value) == sizeof(res),
++ "Can only convert to pointers or pointers to member functions");
++ memcpy(&res, &value, sizeof(value));
++ return res;
++ }
++
++ void copy(void* dst, const void* src, const EHCatchableType* exc_type) {
++ struct Temp {};
++ constexpr uint32_t virtual_base = 4;
++ if (exc_type->copy_function == 0) {
++ memcpy(dst, src, exc_type->size);
++ } else if (exc_type->properties & virtual_base) {
++ auto copy_constructor =
++ convert<void (Temp::*)(const void*, int)>(exc_type->copy_function);
++ ((Temp*)dst->*copy_constructor)(src, 1);
++ } else {
++ auto copy_constructor =
++ convert<void (Temp::*)(const void*)>(exc_type->copy_function);
++ ((Temp*)dst->*copy_constructor)(src);
++ }
++ }
++
++ EHCatchableType* exception_type() {
++ return convert<EHCatchableType*>(
++ convert<EHCatchableTypeArray*>(throw_info->catchable_type_array)
++ ->array_of_catchable_types[0]);
++ }
++
++ ExceptionPtr(const void* exception_object_, const EHThrowInfo* throw_info_)
++ : exception_object(nullptr), throw_info(throw_info_), counter(1) {
++#ifdef _M_AMD64
++ RtlPcToFileHeader(
++ reinterpret_cast<PVOID>(const_cast<EHThrowInfo*>(throw_info)),
++ &image_base);
++#endif
++ EHCatchableType* exc_type = exception_type();
++ this->exception_object = malloc(exc_type->size);
++ if (this->exception_object == nullptr) {
++ throw std::bad_alloc();
++ }
++ copy(exception_object, exception_object_, exc_type);
++ }
++
++ ~ExceptionPtr() {
++ if (throw_info->unwind && exception_object) {
++ struct Temp {};
++ auto destructor = convert<void (Temp::*)()>(throw_info->unwind);
++ ((Temp*)exception_object->*destructor)();
++ }
++ free(exception_object);
++ }
+
+-bool operator==(const exception_ptr& __x, const exception_ptr& __y) noexcept {
+- return __ExceptionPtrCompare(&__x, &__y);
++ // _bad_alloc_storage must be initialized before bad_alloc, so we declare and define it first.
++ static std::bad_alloc _bad_alloc_storage;
++ static ExceptionPtr bad_alloc;
++ //static ExceptionPtr bad_exception;
++};
++
++#ifdef __clang__
++#pragma clang diagnostic push
++#pragma clang diagnostic ignored "-Waddress-of-temporary"
++#endif
++
++std::bad_alloc ExceptionPtr::_bad_alloc_storage;
++
++ExceptionPtr ExceptionPtr::bad_alloc(
++ &ExceptionPtr::_bad_alloc_storage,
++ reinterpret_cast<const EHThrowInfo*>(__GetExceptionInfo(ExceptionPtr::_bad_alloc_storage)));
++
++/* ExceptionPtr
++ExceptionPtr::bad_exception(&std::bad_exception(),
++ reinterpret_cast<const EHThrowInfo*>(
++ __GetExceptionInfo(std::bad_exception()))); */
++
++#ifdef __clang__
++#pragma clang diagnostic pop
++#endif
++
++} // namespace
++
++namespace std {
++
++exception_ptr::exception_ptr(const exception_ptr& __other) noexcept
++ : __ptr_(__other.__ptr_) {
++ if (__ptr_) {
++ reinterpret_cast<ExceptionPtr*>(__ptr_)->counter.fetch_add(1);
++ }
+ }
+
++exception_ptr& exception_ptr::
++operator=(const exception_ptr& __other) noexcept {
++ auto before = __ptr_;
++ __ptr_ = __other.__ptr_;
++ if (__ptr_) {
++ reinterpret_cast<ExceptionPtr*>(__ptr_)->counter.fetch_add(1);
++ }
++ if (before) {
++ if (reinterpret_cast<ExceptionPtr*>(before)->counter.fetch_sub(1) == 1) {
++ delete reinterpret_cast<ExceptionPtr*>(before);
++ }
++ }
++ return *this;
++}
+
+-void swap(exception_ptr& lhs, exception_ptr& rhs) noexcept {
+- __ExceptionPtrSwap(&rhs, &lhs);
++exception_ptr::~exception_ptr() noexcept {
++ if (__ptr_) {
++ if (reinterpret_cast<ExceptionPtr*>(__ptr_)->counter.fetch_sub(1) == 1) {
++ delete reinterpret_cast<ExceptionPtr*>(__ptr_);
++ }
++ }
+ }
+
+-exception_ptr __copy_exception_ptr(void* __except, const void* __ptr) {
+- exception_ptr __ret = nullptr;
+- if (__ptr)
+- __ExceptionPtrCopyException(&__ret, __except, __ptr);
+- return __ret;
++exception_ptr __copy_exception_ptr(void* exception_object,
++ const void* throw_info) {
++ ExceptionPtr* ptr;
++ try {
++ ptr = new ExceptionPtr(exception_object,
++ reinterpret_cast<const EHThrowInfo*>(throw_info));
++ } catch (const std::bad_alloc&) {
++ ptr = &ExceptionPtr::bad_alloc;
++ ptr->counter.fetch_add(1);
++ } catch (...) {
++ //ptr = &ExceptionPtr::bad_exception;
++ //ptr->counter.fetch_add(1);
++ std::terminate();
++ }
++ exception_ptr res;
++ memcpy(&res, &ptr, sizeof(ptr));
++ return res;
+ }
+
+ exception_ptr current_exception() noexcept {
+- exception_ptr __ret;
+- __ExceptionPtrCurrentException(&__ret);
+- return __ret;
++ EHExceptionRecord** record = __current_exception();
++ if (*record && !std::uncaught_exception()) {
++ return __copy_exception_ptr((*record)->parameters.exception_object,
++ (*record)->parameters.throw_info);
++ }
++ return exception_ptr();
+ }
+
+ _LIBCPP_NORETURN
+-void rethrow_exception(exception_ptr p) { __ExceptionPtrRethrow(&p); }
++void rethrow_exception(exception_ptr p) {
++ if (!p) {
++ throw std::bad_exception();
++ }
++ ExceptionPtr* exc_ptr = reinterpret_cast<ExceptionPtr*>(p.__ptr_);
++ EHCatchableType* exc_type = exc_ptr->exception_type();
++ // _CxxThrowException doesn't call free on exception object so we must
++ // allocate it on the stack.
++ void* dst = _alloca(exc_type->size);
++ exc_ptr->copy(dst, exc_ptr->exception_object, exc_type);
++ auto throw_info = reinterpret_cast<_ThrowInfo*>(
++ const_cast<EHThrowInfo*>(exc_ptr->throw_info));
++ // For some reason clang doesn't call p destructor during unwinding.
++ // So we must clear it ourselves.
++ p = nullptr;
++ _CxxThrowException(dst, throw_info);
++}
+
+ nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
+