diff options
author | maxim-yurchuk <maxim-yurchuk@yandex-team.com> | 2024-10-09 12:29:46 +0300 |
---|---|---|
committer | maxim-yurchuk <maxim-yurchuk@yandex-team.com> | 2024-10-09 13:14:22 +0300 |
commit | 9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch) | |
tree | a8fb3181d5947c0d78cf402aa56e686130179049 /contrib/libs/cxxsupp/libcxxmsvc/.yandex_meta/patches/53-exception_pointer_msvc.patch | |
parent | a44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff) | |
download | ydb-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.patch | 293 |
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()) {} + |