First set of licensing changes
[mono.git] / mono / utils / mono-signal-handler.h
1 /*
2  * mono-signal-handler.h: Handle signal handler differences across platforms
3  *
4  * Copyright (C) 2013 Xamarin Inc
5  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6  */
7
8 #ifndef __MONO_SIGNAL_HANDLER_H__
9 #define __MONO_SIGNAL_HANDLER_H__
10
11 #include "config.h"
12
13 /*
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:
17  *
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]
30  *
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.
35  */
36
37 #if defined (TARGET_ARM) && defined (HAVE_ARMV7) && defined (TARGET_ANDROID)
38 #define KRAIT_IT_BUG_WORKAROUND 1
39 #endif
40
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                 asm volatile (                                          \
53                               "bx %0"                                   \
54                               : : "r" (__krait_ ## name));              \
55         }       \
56         static void __krait_ ## name arglist
57 #endif
58
59
60 /* Don't use this */
61 #ifndef MONO_SIGNAL_HANDLER_FUNC
62 #define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) access void name arglist
63 #endif
64
65 /*
66  * Macros to work around signal handler differences on various platforms.
67  *
68  * To declare a signal handler function:
69  * void MONO_SIG_HANDLER_SIGNATURE (handler_func)
70  * To define a signal handler function:
71  * MONO_SIG_HANDLER_FUNC(access, name)
72  * To call another signal handler function:
73  * handler_func (MONO_SIG_HANDLER_PARAMS);
74  * To obtain the signal number:
75  * int signo = MONO_SIG_HANDLER_GET_SIGNO ();
76  * To obtain the signal context:
77  * MONO_SIG_HANDLER_GET_CONTEXT ().
78  * This will define a variable name 'ctx'.
79  */
80
81 #ifdef HOST_WIN32
82 #define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *_info, void *context)
83 #define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, EXCEPTION_POINTERS *_info, void *context))
84 #define MONO_SIG_HANDLER_PARAMS _dummy, _info, context
85 #define MONO_SIG_HANDLER_GET_SIGNO() (_dummy)
86 #define MONO_SIG_HANDLER_GET_INFO() (_info)
87 #define MONO_SIG_HANDLER_INFO_TYPE EXCEPTION_POINTERS
88 /* seh_vectored_exception_handler () passes in a CONTEXT* */
89 #define MONO_SIG_HANDLER_GET_CONTEXT \
90     void *ctx = context;
91 #else
92 /* sigaction */
93 #define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, siginfo_t *_info, void *context)
94 #define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, siginfo_t *_info, void *context))
95 #define MONO_SIG_HANDLER_PARAMS _dummy, _info, context
96 #define MONO_SIG_HANDLER_GET_SIGNO() (_dummy)
97 #define MONO_SIG_HANDLER_GET_INFO() (_info)
98 #define MONO_SIG_HANDLER_INFO_TYPE siginfo_t
99 #define MONO_SIG_HANDLER_GET_CONTEXT \
100     void *ctx = context;
101 #endif
102
103 #endif