ObjFW  Check-in [26d0e98438]

Overview
Comment:Call the right C++ personality for SEH exceptions
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 26d0e98438615a562190e3c34f0a94cc08569205d6b8be1247bb5d481ef2e740
User & Date: js on 2017-03-26 14:02:18
Other Links: manifest | tags
Context
2017-03-26
16:46
ofzip: Add -C flag to change output directory check-in: 633d49030d user: js tags: trunk
14:02
Call the right C++ personality for SEH exceptions check-in: 26d0e98438 user: js tags: trunk
2017-03-20
22:50
of_explicit_memset(): Add explicit cast for C++ check-in: 1ff91c7491 user: js tags: trunk
Changes

Modified src/runtime/exception.m from [120b0cc0b1] to [e1815049b3].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#elif defined(HAVE_SJLJ_EXCEPTIONS)
# define PERSONALITY	 __gnu_objc_personality_sj0
# define CXX_PERSONALITY __gxx_personality_sj0
# define _Unwind_RaiseException _Unwind_SjLj_RaiseException
# define __builtin_eh_return_data_regno(i) (i)
#elif defined(HAVE_SEH_EXCEPTIONS)
# define PERSONALITY	 gnu_objc_personality
# define CXX_PERSONALITY __gxx_personality_v0
#else
# error Unknown exception type!
#endif

#if defined(OF_ARM) && !defined(__ARM_DWARF_EH__)
# define HAVE_ARM_EHABI_EXCEPTIONS
#endif







<







34
35
36
37
38
39
40

41
42
43
44
45
46
47
#elif defined(HAVE_SJLJ_EXCEPTIONS)
# define PERSONALITY	 __gnu_objc_personality_sj0
# define CXX_PERSONALITY __gxx_personality_sj0
# define _Unwind_RaiseException _Unwind_SjLj_RaiseException
# define __builtin_eh_return_data_regno(i) (i)
#elif defined(HAVE_SEH_EXCEPTIONS)
# define PERSONALITY	 gnu_objc_personality

#else
# error Unknown exception type!
#endif

#if defined(OF_ARM) && !defined(__ARM_DWARF_EH__)
# define HAVE_ARM_EHABI_EXCEPTIONS
#endif
211
212
213
214
215
216
217

218

219
220
221
222
223
224
225
_Unwind_SetIP(struct _Unwind_Context *ctx, uintptr_t value)
{
	uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1;
	_Unwind_SetGR(ctx, 15, (value | thumb));
}
#endif


extern PERSONALITY_FUNC(CXX_PERSONALITY) __attribute__((__weak__));


#ifdef HAVE_SEH_EXCEPTIONS
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void*,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code(*)(int, int, uint64_t,
    struct _Unwind_Exception*, struct _Unwind_Context*));
#endif








>

>







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
_Unwind_SetIP(struct _Unwind_Context *ctx, uintptr_t value)
{
	uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1;
	_Unwind_SetGR(ctx, 15, (value | thumb));
}
#endif

#ifdef CXX_PERSONALITY
extern PERSONALITY_FUNC(CXX_PERSONALITY) __attribute__((__weak__));
#endif

#ifdef HAVE_SEH_EXCEPTIONS
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void*,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code(*)(int, int, uint64_t,
    struct _Unwind_Exception*, struct _Unwind_Context*));
#endif

562
563
564
565
566
567
568

569
570
571
572
573

574
575
576
577
578
579
580
	struct lsda lsda;
	uintptr_t landingpad = 0;
	uint8_t found = 0;
	intptr_t filter = 0;

	if (foreign) {
		switch (ex_class) {

		case GNUCCXX0_EXCEPTION_CLASS:
		case CLNGCXX0_EXCEPTION_CLASS:
			if (CXX_PERSONALITY != NULL)
				return CALL_PERSONALITY(CXX_PERSONALITY);
			break;

		}

		/*
		 * None matched or none available - we'll try to handle it
		 * anyway, but will most likely fail.
		 */
	}







>





>







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
	struct lsda lsda;
	uintptr_t landingpad = 0;
	uint8_t found = 0;
	intptr_t filter = 0;

	if (foreign) {
		switch (ex_class) {
#ifdef CXX_PERSONALITY
		case GNUCCXX0_EXCEPTION_CLASS:
		case CLNGCXX0_EXCEPTION_CLASS:
			if (CXX_PERSONALITY != NULL)
				return CALL_PERSONALITY(CXX_PERSONALITY);
			break;
#endif
		}

		/*
		 * None matched or none available - we'll try to handle it
		 * anyway, but will most likely fail.
		 */
	}
688
689
690
691
692
693
694





















695
696
697
698











699
700
701
702
	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}

#ifdef HAVE_SEH_EXCEPTIONS





















EXCEPTION_DISPOSITION
__gnu_objc_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
    PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
{











	return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
	    ms_disp, PERSONALITY);
}
#endif







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>




691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}

#ifdef HAVE_SEH_EXCEPTIONS
typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void*,
    PCONTEXT, PDISPATCHER_CONTEXT);
static seh_personality_fn __gxx_personality_seh0 = NULL;

static void __attribute__((__constructor__))
gxx_personality_init(void)
{
	/*
	 * This only works if the application uses libstdc++-6.dll.
	 * There is unfortunately no other way, as Windows does not support
	 * proper weak linking.
	 */

	HMODULE module;
	if ((module = GetModuleHandle("libstdc++-6")) == NULL)
		return;

	__gxx_personality_seh0 = (seh_personality_fn)
	    GetProcAddress(module, "__gxx_personality_seh0");
}

EXCEPTION_DISPOSITION
__gnu_objc_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
    PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
{
	struct _Unwind_Exception *ex =
	    (struct _Unwind_Exception*)ms_exc->ExceptionInformation[0];

	switch (ex->class) {
	case GNUCCXX0_EXCEPTION_CLASS:
	case CLNGCXX0_EXCEPTION_CLASS:
		if (__gxx_personality_seh0 != NULL)
			return __gxx_personality_seh0(ms_exc, this_frame,
			    ms_orig_context, ms_disp);
	}

	return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
	    ms_disp, PERSONALITY);
}
#endif