Index: libcxxabi/include/zos/unwind.h =================================================================== --- /dev/null +++ libcxxabi/include/zos/unwind.h @@ -0,0 +1,72 @@ +//===--------------------------- zos/unwind.h -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _UNWIND_H +#define _UNWIND_H + +typedef enum { + _URC_NO_REASON = 0, + _URC_OK = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8, +} _Unwind_Reason_Code; + +typedef enum { + _UA_SEARCH_PHASE = 1, + _UA_CLEANUP_PHASE = 2, + _UA_HANDLER_FRAME = 4, + _UA_FORCE_UNWIND = 8, + _UA_END_OF_STACK = 16 // gcc extension to C++ ABI +} _Unwind_Action; + +struct _Unwind_Exception; +struct _Unwind_Context; + +typedef void (*_Unwind_Exception_Cleanup_Fn) + (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc); + +struct _Unwind_Exception { + char reserved[160] __attribute__ ((aligned(8))); + uint64_t exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; +}; + +#if __cplusplus +extern "C" +{ +#endif +_Unwind_Reason_Code _Unwind_RaiseException( struct _Unwind_Exception *exception_object ); +void _Unwind_Resume(struct _Unwind_Exception *exception_object); +void _Unwind_DeleteException(struct _Unwind_Exception *exception_object); +uintptr_t _Unwind_GetIP(void *context); +void _Unwind_SetIP(void *context, uint64_t new_value); +uintptr_t _Unwind_GetRegionStart(void *context); +uintptr_t _Unwind_GetLanguageSpecificData(void *context); + +void _Unwind_SetGR(struct _Unwind_Context *context, int index, uint64_t new_value); +uintptr_t _Unwind_GetGR(void *context, int index); + +void *_Unwind_StackPtr(void *context); +void* _Unwind_GetLandingPad(void *context); +void _Unwind_SetLandingPad(void *context, void *landingPad); +void *_Unwind_GetExceptionAddress(void *context); +void _Unwind_SetExceptionAddress(void *context, void *exception); +unsigned int _Unwind_GetTypeSelector(void *context); +void _Unwind_SetTypeSelector(void *context, unsigned int ttypeIndex); + +struct _Unwind_Exception *_UnwindZOS_PopException(); +#if __cplusplus +} +#endif +#endif Index: libcxxabi/src/CMakeLists.txt =================================================================== --- libcxxabi/src/CMakeLists.txt +++ libcxxabi/src/CMakeLists.txt @@ -46,6 +46,13 @@ ../include/cxxabi.h ) +if (ZOS) + list(APPEND LIBCXXABI_HEADERS + ../include/zos/unwind.h + ) + include_directories("../include/zos/") +endif() + # Add all the headers to the project for IDEs. if (MSVC_IDE OR XCODE) # Force them all into the headers dir on MSVC, otherwise they end up at Index: libcxxabi/src/cxa_exception.cpp =================================================================== --- libcxxabi/src/cxa_exception.cpp +++ libcxxabi/src/cxa_exception.cpp @@ -431,6 +431,11 @@ ( static_cast<_Unwind_Exception*>(unwind_exception) ); + +#if defined(__MVS__) + _UnwindZOS_PopException(); +#endif + if (native_exception) { // Increment the handler count, removing the flag about being rethrown Index: libcxxabi/src/cxa_personality.cpp =================================================================== --- libcxxabi/src/cxa_personality.cpp +++ libcxxabi/src/cxa_personality.cpp @@ -601,7 +601,7 @@ results.reason = _URC_FATAL_PHASE1_ERROR; return; } - // Start scan by getting exception table address + // Start scan by getting exception table address. const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context); if (lsda == 0) { @@ -883,6 +883,8 @@ _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code #ifdef __USING_SJLJ_EXCEPTIONS__ __gxx_personality_sj0 +#elif defined(__MVS__) +__zos_cxx_personality_v2 #else __gxx_personality_v0 #endif @@ -1070,7 +1072,14 @@ // Either we didn't do a phase 1 search (due to forced unwinding), or // phase 1 reported no catching-handlers. // Search for a (non-catching) cleanup - scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context); + if (is_force_unwinding) + scan_eh_tab( + results, + static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_FORCE_UNWIND), + native_exception, unwind_exception, context); + else + scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, + unwind_exception, context); if (results.reason == _URC_HANDLER_FOUND) { // Found a non-catching handler