35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
+
|
#ifdef __SEH__
# include <windows.h>
#endif
#if defined(__SEH__)
# define PERSONALITY gnu_objc_personality
# define CXX_PERSONALITY_STR "__gxx_personality_seh0"
#elif defined(__USING_SJLJ_EXCEPTIONS__)
# define PERSONALITY __gnu_objc_personality_sj0
# define CXX_PERSONALITY_STR "__gxx_personality_sj0"
# define _Unwind_RaiseException _Unwind_SjLj_RaiseException
# define __builtin_eh_return_data_regno(i) (i)
#else
# define PERSONALITY __gnu_objc_personality_v0
|
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
|
_Unwind_SetIP(struct _Unwind_Context *ctx, uintptr_t value)
{
uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1;
_Unwind_SetGR(ctx, 15, (value | thumb));
}
#endif
#if defined(OF_WINDOWS)
# ifdef __SEH__
static EXCEPTION_DISPOSITION (*cxx_personality)(PEXCEPTION_RECORD, void *,
PCONTEXT, PDISPATCHER_CONTEXT);
# else
static PERSONALITY_FUNC((*cxx_personality));
# endif
OF_CONSTRUCTOR()
{
/*
* This only works if the application uses libc++.dll or
* libstdc++-6.dll. There is unfortunately no other way, as Windows
* does not support proper weak linking.
*/
HMODULE module;
module = GetModuleHandle("libc++");
if (module == NULL)
module = GetModuleHandle("libstdc++-6");
if (module != NULL)
cxx_personality = (__typeof__(cxx_personality))
GetProcAddress(module, CXX_PERSONALITY_STR);
}
#if defined(CXX_PERSONALITY_STR) && !defined(OF_AMIGAOS_M68K)
#elif !defined(OF_AMIGAOS_M68K)
static PERSONALITY_FUNC(cxx_personality) OF_WEAK_REF(CXX_PERSONALITY_STR);
#endif
#ifdef __SEH__
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 *));
|
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
|
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
|
-
+
|
struct LSDA LSDA;
uintptr_t landingpad = 0;
uint8_t found = 0;
intptr_t filter = 0;
if (foreign) {
switch (exClass) {
#if defined(CXX_PERSONALITY_STR) && !defined(OF_AMIGAOS_M68K)
#if !defined(__SEH__) && !defined(OF_AMIGAOS_M68K)
case GNUCCXX0_EXCEPTION_CLASS:
case CLNGCXX0_EXCEPTION_CLASS:
if (cxx_personality != NULL)
return CALL_PERSONALITY(cxx_personality);
break;
#endif
}
|
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
|
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
|
objc_uncaught_exception_handler old = uncaughtExceptionHandler;
uncaughtExceptionHandler = handler;
return old;
}
#ifdef __SEH__
typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void *,
PCONTEXT, PDISPATCHER_CONTEXT);
static seh_personality_fn __gxx_personality_seh0;
OF_CONSTRUCTOR()
{
/*
* This only works if the application uses libc++.dll or
* libstdc++-6.dll. There is unfortunately no other way, as Windows
* does not support proper weak linking.
*/
HMODULE module;
module = GetModuleHandle("libc++");
if (module == NULL)
module = GetModuleHandle("libstdc++-6");
if (module != NULL)
__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,
if (cxx_personality != NULL)
return cxx_personality(ms_exc, this_frame,
ms_orig_context, ms_disp);
}
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
ms_disp, PERSONALITY);
}
#endif
|