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

@ -10,3 +10,9 @@
#define TYPE_DIRECTIVE(symbol, symboltype) #define TYPE_DIRECTIVE(symbol, symboltype)
#endif #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), _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); _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector);
DEBUG_LOG("Installing context, selector %d\n", (int)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; return _URC_INSTALL_CONTEXT;
} }
OBJC_PUBLIC
BEGIN_PERSONALITY_FUNCTION(__gnu_objc_personality_v0) BEGIN_PERSONALITY_FUNCTION(__gnu_objc_personality_v0)
return internal_objc_personality(version, actions, exceptionClass, return internal_objc_personality(version, actions, exceptionClass,
exceptionObject, context, NO); exceptionObject, context, NO);
} }
OBJC_PUBLIC
BEGIN_PERSONALITY_FUNCTION(__gnustep_objc_personality_v0) BEGIN_PERSONALITY_FUNCTION(__gnustep_objc_personality_v0)
return internal_objc_personality(version, actions, exceptionClass, return internal_objc_personality(version, actions, exceptionClass,
exceptionObject, context, YES); exceptionObject, context, YES);
} }
OBJC_PUBLIC
BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0) BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0)
#ifndef NO_OBJCXX #ifndef NO_OBJCXX
if (cxx_exception_class == 0) 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 // 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. // 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; exceptionObject = ex->cxx_exception;
exceptionClass = cxx_exception_class; exceptionClass = cxx_exception_class;
int ret = CALL_PERSONALITY_FUNCTION(__gxx_personality_v0); 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) if (ret == _URC_INSTALL_CONTEXT)
{ {
get_thread_data()->cxxCaughtException = YES; get_thread_data()->cxxCaughtException = YES;
@ -599,7 +603,7 @@ BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0)
return CALL_PERSONALITY_FUNCTION(__gxx_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(); struct thread_data *td = get_thread_data();
DEBUG_LOG("Beginning catch %p\n", exceptionObject); 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)); 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(); struct thread_data *td = get_thread_data_fast();
// If this is a boxed foreign exception then the boxing class is // 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(); struct thread_data *td = get_thread_data_fast();
// If this is an Objective-C exception, then // 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); OBJC_PUBLIC extern IMP (*__objc_msg_forward2)(id, SEL);
#ifndef _WIN32 #ifndef _MSC_VER
/** /**
* Hook defined for handling unhandled exceptions. If the unwind library * Hook defined for handling unhandled exceptions. If the unwind library
* reaches the end of the stack without finding a handler then this hook is * reaches the end of the stack without finding a handler then this hook is

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

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

@ -218,7 +218,7 @@ namespace gnustep
/** /**
* Superclass for the type info for Objective-C exceptions. * 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. * Constructor that sets the name.
@ -266,7 +266,7 @@ namespace gnustep
/** /**
* Singleton type info for the `id` type. * 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 * The `id` type is mangled to `@id`, which is not a valid mangling
@ -278,7 +278,7 @@ namespace gnustep
void **obj, void **obj,
unsigned outer) const; 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 ~__objc_class_type_info();
virtual bool __do_catch(const type_info *thrownType, virtual bool __do_catch(const type_info *thrownType,

@ -79,8 +79,12 @@ struct _Unwind_Exception
{ {
uint64_t exception_class; uint64_t exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup; _Unwind_Exception_Cleanup_Fn exception_cleanup;
#ifdef __SEH__
uintptr_t private_[6];
#else
uintptr_t private_1; uintptr_t private_1;
uintptr_t private_2; uintptr_t private_2;
#endif
} __attribute__((__aligned__)); } __attribute__((__aligned__));
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); 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 *); _Unwind_Stop_Fn, void *);
extern void _Unwind_Resume (struct _Unwind_Exception *); extern void _Unwind_Resume (struct _Unwind_Exception *);
extern void _Unwind_DeleteException (struct _Unwind_Exception *); extern void _Unwind_DeleteException (struct _Unwind_Exception *);
extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); extern uintptr_t _Unwind_GetGR (struct _Unwind_Context *, int);
extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long); extern void _Unwind_SetGR (struct _Unwind_Context *, int, uintptr_t);
extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); extern uintptr_t _Unwind_GetIP (struct _Unwind_Context *);
extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *); extern uintptr_t _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long); extern void _Unwind_SetIP (struct _Unwind_Context *, uintptr_t);
extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*); extern uintptr_t _Unwind_GetLanguageSpecificData (struct _Unwind_Context*);
extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *); extern uintptr_t _Unwind_GetRegionStart (struct _Unwind_Context *);
#ifdef _GNU_SOURCE #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 /* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why
_Unwind_GetBSP() exists. */ _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. /* Return the "canonical frame address" for the given context.
This is used by NPTL... */ 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. */ /* 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. */ /* 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 /* Call _Unwind_Trace_Fn once for each stack-frame, without doing any
cleanup. The first frame for which the callback is invoked is the 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) #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) \ #define COPY_EXCEPTION(dst, src) \
(dst)->private_1 = (src)->private_1; \ do { \
(dst)->private_2 = (src)->private_2; (dst)->private_1 = (src)->private_1; \
(dst)->private_2 = (src)->private_2; \
} while(0)
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _UNWIND_H */ #endif /* _UNWIND_H */
Loading…
Cancel
Save