Support compiling on mingw (no exception handling)

main
Frederik Carlier 2 years ago committed by David Chisnall
parent 4d9d930940
commit a61309b0d3

@ -114,12 +114,12 @@ set(libBlocksRuntime_COMPATIBILITY_HDRS
set(libobjc_CXX_SRCS
selector_table.cc
)
# Windows does not use DWARF EH
if (WIN32)
# Windows does not use DWARF EH, except when using the GNU ABI (MinGW)
if (WIN32 AND NOT MINGW)
list(APPEND libobjc_CXX_SRCS eh_win32_msvc.cc)
else ()
list(APPEND libobjc_C_SRCS eh_personality.c)
endif (WIN32)
endif (WIN32 AND NOT MINGW)
find_package(tsl-robin-map)
@ -132,7 +132,7 @@ if (NOT tls-robin-map_FOUND)
FetchContent_MakeAvailable(robinmap)
endif()
if (WIN32)
if (WIN32 AND NOT MINGW)
set(OLD_ABI_COMPAT_DEFAULT false)
else()
set(OLD_ABI_COMPAT_DEFAULT true)
@ -189,7 +189,7 @@ if(WIN32)
endif()
if (MSVC)
if (WIN32 AND NOT MINGW)
set(ASSEMBLER ${CMAKE_ASM_COMPILER} CACHE STRING "Assembler to use with Visual Studio (must be gcc / clang!)")
message(STATUS "Using custom build commands to work around CMake bugs")
message(STATUS "ASM compiler: ${ASSEMBLER}")
@ -210,7 +210,7 @@ endif()
if (WIN32)
if (WIN32 AND NOT MINGW)
message(STATUS "Using MSVC-compatible exception model")
else ()
separate_arguments(EH_PERSONALITY_FLAGS NATIVE_COMMAND ${CMAKE_CXX_FLAGS})
@ -234,7 +234,7 @@ target_sources(objc PRIVATE ${libobjc_CXX_SRCS})
include(FindThreads)
target_link_libraries(objc Threads::Threads)
# Link against ntdll.dll for RtlRaiseException
if (WIN32)
if (WIN32 AND NOT MINGW)
target_link_libraries(objc ntdll.dll)
endif()

@ -10,3 +10,9 @@
#define TYPE_DIRECTIVE(symbol, symboltype)
#endif
#if defined(_MSC_VER) && defined(__i386__)
#define STRINGIFY(a) #a
#define EXPORT_SYMBOL(symbol) .ascii " " STRINGIFY(/EXPORT:_##symbol)
#else
#define EXPORT_SYMBOL(symbol) .ascii " /EXPORT:" #symbol
#endif

@ -550,9 +550,9 @@ static inline _Unwind_Reason_Code internal_objc_personality(int version,
}
}
_Unwind_SetIP(context, (unsigned long)action.landing_pad);
_Unwind_SetIP(context, (uintptr_t)action.landing_pad);
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
(unsigned long)(isNew ? exceptionObject : object));
(uintptr_t)(isNew ? exceptionObject : object));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector);
DEBUG_LOG("Installing context, selector %d\n", (int)selector);
@ -560,15 +560,19 @@ static inline _Unwind_Reason_Code internal_objc_personality(int version,
return _URC_INSTALL_CONTEXT;
}
OBJC_PUBLIC
BEGIN_PERSONALITY_FUNCTION(__gnu_objc_personality_v0)
return internal_objc_personality(version, actions, exceptionClass,
exceptionObject, context, NO);
}
OBJC_PUBLIC
BEGIN_PERSONALITY_FUNCTION(__gnustep_objc_personality_v0)
return internal_objc_personality(version, actions, exceptionClass,
exceptionObject, context, YES);
}
OBJC_PUBLIC
BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0)
#ifndef NO_OBJCXX
if (cxx_exception_class == 0)
@ -584,11 +588,11 @@ BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0)
}
// We now have two copies of the _Unwind_Exception object (which stores
// state for the unwinder) in flight. Make sure that they're in sync.
COPY_EXCEPTION(ex->cxx_exception, exceptionObject)
COPY_EXCEPTION(ex->cxx_exception, exceptionObject);
exceptionObject = ex->cxx_exception;
exceptionClass = cxx_exception_class;
int ret = CALL_PERSONALITY_FUNCTION(__gxx_personality_v0);
COPY_EXCEPTION(exceptionObject, ex->cxx_exception)
COPY_EXCEPTION(exceptionObject, ex->cxx_exception);
if (ret == _URC_INSTALL_CONTEXT)
{
get_thread_data()->cxxCaughtException = YES;
@ -599,7 +603,7 @@ BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0)
return CALL_PERSONALITY_FUNCTION(__gxx_personality_v0);
}
id objc_begin_catch(struct _Unwind_Exception *exceptionObject)
OBJC_PUBLIC id objc_begin_catch(struct _Unwind_Exception *exceptionObject)
{
struct thread_data *td = get_thread_data();
DEBUG_LOG("Beginning catch %p\n", exceptionObject);
@ -671,7 +675,7 @@ id objc_begin_catch(struct _Unwind_Exception *exceptionObject)
return (id)((char*)exceptionObject + sizeof(struct _Unwind_Exception));
}
void objc_end_catch(void)
OBJC_PUBLIC void objc_end_catch(void)
{
struct thread_data *td = get_thread_data_fast();
// If this is a boxed foreign exception then the boxing class is
@ -717,7 +721,7 @@ void objc_end_catch(void)
}
}
void objc_exception_rethrow(struct _Unwind_Exception *e)
OBJC_PUBLIC void objc_exception_rethrow(struct _Unwind_Exception *e)
{
struct thread_data *td = get_thread_data_fast();
// If this is an Objective-C exception, then

@ -47,7 +47,7 @@ OBJC_PUBLIC extern struct objc_slot *(*__objc_msg_forward3)(id, SEL) OBJC_DEPREC
*/
OBJC_PUBLIC extern IMP (*__objc_msg_forward2)(id, SEL);
#ifndef _WIN32
#ifndef _MSC_VER
/**
* Hook defined for handling unhandled exceptions. If the unwind library
* reaches the end of the stack without finding a handler then this hook is

@ -37,7 +37,7 @@
test %eax, %eax
jz 5f # Nil slot - invoke some kind of forwarding mechanism
mov SLOT_OFFSET(%eax), %ecx
#ifdef _WIN32
#ifdef _MSC_VER
call *CDECL(__guard_check_icall_fptr)
#endif
jmp *%ecx
@ -62,7 +62,7 @@
add $12, %esp # restore the stack
#ifdef _WIN32
#ifdef _MSC_VER
mov %eax, %ecx
call *CDECL(__guard_check_icall_fptr)
jmp *%ecx
@ -126,7 +126,7 @@ CDECL(objc_msgSend_stret):
#ifdef _WIN32
.section .drectve,"yn"
.ascii " /EXPORT:_objc_msgSend"
.ascii " /EXPORT:_objc_msgSend_stret"
.ascii " /EXPORT:_objc_msgSend_fpret"
EXPORT_SYMBOL(objc_msgSend)
EXPORT_SYMBOL(objc_msgSend_stret)
EXPORT_SYMBOL(objc_msgSend_fpret)
#endif

@ -193,7 +193,7 @@
12:
#endif // WITH_TRACING
#ifdef _WIN64
#ifdef _MSC_VER
mov %r10, %rax
jmp *__guard_dispatch_icall_fptr(%rip)
#else
@ -295,9 +295,11 @@ TYPE_DIRECTIVE(CDECL(objc_msgSend_stret), @function)
CDECL(objc_msgSend_stret):
MSGSEND objc_msgSend_stret, %rdx, %r8
.section .drectve,"yn"
.ascii " /EXPORT:objc_msgSend"
.ascii " /EXPORT:objc_msgSend_fpret"
.ascii " /EXPORT:objc_msgSend_stret"
EXPORT_SYMBOL(objc_msgSend)
EXPORT_SYMBOL(objc_msgSend_fpret)
EXPORT_SYMBOL(objc_msgSend_stret)
#else
.globl CDECL(objc_msgSend)
TYPE_DIRECTIVE(CDECL(objc_msgSend), @function)

@ -218,7 +218,7 @@ namespace gnustep
/**
* Superclass for the type info for Objective-C exceptions.
*/
struct __objc_type_info : std::type_info
struct OBJC_PUBLIC __objc_type_info : std::type_info
{
/**
* Constructor that sets the name.
@ -266,7 +266,7 @@ namespace gnustep
/**
* Singleton type info for the `id` type.
*/
struct __objc_id_type_info : __objc_type_info
struct OBJC_PUBLIC __objc_id_type_info : __objc_type_info
{
/**
* The `id` type is mangled to `@id`, which is not a valid mangling
@ -278,7 +278,7 @@ namespace gnustep
void **obj,
unsigned outer) const;
};
struct __objc_class_type_info : __objc_type_info
struct OBJC_PUBLIC __objc_class_type_info : __objc_type_info
{
virtual ~__objc_class_type_info();
virtual bool __do_catch(const type_info *thrownType,

@ -79,8 +79,12 @@ struct _Unwind_Exception
{
uint64_t exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
#ifdef __SEH__
uintptr_t private_[6];
#else
uintptr_t private_1;
uintptr_t private_2;
#endif
} __attribute__((__aligned__));
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
@ -88,13 +92,13 @@ extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
_Unwind_Stop_Fn, void *);
extern void _Unwind_Resume (struct _Unwind_Exception *);
extern void _Unwind_DeleteException (struct _Unwind_Exception *);
extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int);
extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long);
extern unsigned long _Unwind_GetIP (struct _Unwind_Context *);
extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long);
extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*);
extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *);
extern uintptr_t _Unwind_GetGR (struct _Unwind_Context *, int);
extern void _Unwind_SetGR (struct _Unwind_Context *, int, uintptr_t);
extern uintptr_t _Unwind_GetIP (struct _Unwind_Context *);
extern uintptr_t _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
extern void _Unwind_SetIP (struct _Unwind_Context *, uintptr_t);
extern uintptr_t _Unwind_GetLanguageSpecificData (struct _Unwind_Context*);
extern uintptr_t _Unwind_GetRegionStart (struct _Unwind_Context *);
#ifdef _GNU_SOURCE
@ -115,17 +119,17 @@ extern _Unwind_Reason_Code
/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why
_Unwind_GetBSP() exists. */
extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *);
extern uintptr_t _Unwind_GetBSP (struct _Unwind_Context *);
/* Return the "canonical frame address" for the given context.
This is used by NPTL... */
extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *);
extern uintptr_t _Unwind_GetCFA (struct _Unwind_Context *);
/* Return the base-address for data references. */
extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *);
extern uintptr_t _Unwind_GetDataRelBase (struct _Unwind_Context *);
/* Return the base-address for text references. */
extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *);
extern uintptr_t _Unwind_GetTextRelBase (struct _Unwind_Context *);
/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any
cleanup. The first frame for which the callback is invoked is the
@ -164,12 +168,21 @@ _Unwind_Reason_Code name(int version,\
#define CALL_PERSONALITY_FUNCTION(name) name(version, actions, exceptionClass, exceptionObject, context)
#ifdef __SEH__
#define COPY_EXCEPTION(dst, src) \
do { \
memcpy((dst)->private_, (src)->private_, sizeof((src)->private_)); \
} while(0)
#else
#define COPY_EXCEPTION(dst, src) \
(dst)->private_1 = (src)->private_1; \
(dst)->private_2 = (src)->private_2;
do { \
(dst)->private_1 = (src)->private_1; \
(dst)->private_2 = (src)->private_2; \
} while(0)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _UNWIND_H */
#endif /* _UNWIND_H */
Loading…
Cancel
Save