Update ms-test-suite
[mono-project.git] / mono / utils / mono-signal-handler.h
bloba90affdd91e77599a111d92b393c5d0d530b928c
1 /*
2 * mono-signal-handler.h: Handle signal handler differences across platforms
4 * Copyright (C) 2013 Xamarin Inc
5 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 */
8 #ifndef __MONO_SIGNAL_HANDLER_H__
9 #define __MONO_SIGNAL_HANDLER_H__
11 #include "config.h"
14 * When a signal is delivered to a thread on a Krait Android device
15 * that's in the middle of skipping over an "IT" block, such as this
16 * one:
18 * 0x40184ef0 <dlfree+1308>: ldr r1, [r3, #0]
19 * 0x40184ef2 <dlfree+1310>: add.w r5, r12, r2, lsl #3
20 * 0x40184ef6 <dlfree+1314>: lsls.w r2, r0, r2
21 * 0x40184efa <dlfree+1318>: tst r2, r1
22 * ### this is the IT instruction
23 * 0x40184efc <dlfree+1320>: itt eq
24 * 0x40184efe <dlfree+1322>: orreq r2, r1
25 * ### signal arrives here
26 * 0x40184f00 <dlfree+1324>: streq r2, [r3, #0]
27 * 0x40184f02 <dlfree+1326>: beq.n 0x40184f1a <dlfree+1350>
28 * 0x40184f04 <dlfree+1328>: ldr r2, [r5, #8]
29 * 0x40184f06 <dlfree+1330>: ldr r3, [r3, #16]
31 * then the first few (at most four, one would assume) instructions of
32 * the signal handler (!) might be skipped. They happen to be the
33 * push of the frame pointer and return address, so once the signal
34 * handler has done its work, it returns into a SIGSEGV.
37 #if defined (TARGET_ARM) && defined (HAVE_ARMV7) && defined (TARGET_ANDROID)
38 #define KRAIT_IT_BUG_WORKAROUND 1
39 #endif
41 #ifdef KRAIT_IT_BUG_WORKAROUND
42 #define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) \
43 static void __krait_ ## name arglist; \
44 __attribute__ ((__naked__)) access void \
45 name arglist \
46 { \
47 asm volatile ( \
48 "mov r0, r0\n\t" \
49 "mov r0, r0\n\t" \
50 "mov r0, r0\n\t" \
51 "mov r0, r0\n\t" \
52 "b __krait_" # name \
53 "\n\t"); \
54 } \
55 static __attribute__ ((__used__)) void __krait_ ## name arglist
56 #endif
58 /* Don't use this */
59 #ifndef MONO_SIGNAL_HANDLER_FUNC
60 #define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) access void name arglist
61 #endif
64 * Macros to work around signal handler differences on various platforms.
66 * To declare a signal handler function:
67 * void MONO_SIG_HANDLER_SIGNATURE (handler_func)
68 * To define a signal handler function:
69 * MONO_SIG_HANDLER_FUNC(access, name)
70 * To call another signal handler function:
71 * handler_func (MONO_SIG_HANDLER_PARAMS);
72 * To obtain the signal number:
73 * int signo = MONO_SIG_HANDLER_GET_SIGNO ();
74 * To obtain the signal context:
75 * MONO_SIG_HANDLER_GET_CONTEXT ().
76 * This will define a variable name 'ctx'.
79 #ifdef HOST_WIN32
80 #define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *_info, void *context)
81 #define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, EXCEPTION_POINTERS *_info, void *context))
82 #define MONO_SIG_HANDLER_PARAMS _dummy, _info, context
83 #define MONO_SIG_HANDLER_GET_SIGNO() (_dummy)
84 #define MONO_SIG_HANDLER_GET_INFO() (_info)
85 #define MONO_SIG_HANDLER_INFO_TYPE EXCEPTION_POINTERS
86 /* seh_vectored_exception_handler () passes in a CONTEXT* */
87 #define MONO_SIG_HANDLER_GET_CONTEXT \
88 void *ctx = context;
89 #else
90 /* sigaction */
91 #define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, siginfo_t *_info, void *context)
92 #define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, siginfo_t *_info, void *context))
93 #define MONO_SIG_HANDLER_PARAMS _dummy, _info, context
94 #define MONO_SIG_HANDLER_GET_SIGNO() (_dummy)
95 #define MONO_SIG_HANDLER_GET_INFO() (_info)
96 #define MONO_SIG_HANDLER_INFO_TYPE siginfo_t
97 #define MONO_SIG_HANDLER_GET_CONTEXT \
98 void *ctx = context;
99 #endif
101 #endif