X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-signal-handler.h;h=4842cb8f72bb41bf5274c6fdac634bfd9832afa9;hb=82bc0ca4ced9d49ed9e1a483b415760ba8653500;hp=fbe798eeb0e6321667023429bfc88b4cb65bb1ce;hpb=c0216739390c37ea05a99a4cbc15e2222aac3f11;p=mono.git diff --git a/mono/utils/mono-signal-handler.h b/mono/utils/mono-signal-handler.h index fbe798eeb0e..4842cb8f72b 100644 --- a/mono/utils/mono-signal-handler.h +++ b/mono/utils/mono-signal-handler.h @@ -1,7 +1,9 @@ -/* - * mono-signal-handler.h: Handle signal handler differences across platforms +/** + * \file + * Handle signal handler differences across platforms * * Copyright (C) 2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SIGNAL_HANDLER_H__ @@ -9,8 +11,49 @@ #include "config.h" -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/utils/mono-signal-handler.h" +/* + * When a signal is delivered to a thread on a Krait Android device + * that's in the middle of skipping over an "IT" block, such as this + * one: + * + * 0x40184ef0 : ldr r1, [r3, #0] + * 0x40184ef2 : add.w r5, r12, r2, lsl #3 + * 0x40184ef6 : lsls.w r2, r0, r2 + * 0x40184efa : tst r2, r1 + * ### this is the IT instruction + * 0x40184efc : itt eq + * 0x40184efe : orreq r2, r1 + * ### signal arrives here + * 0x40184f00 : streq r2, [r3, #0] + * 0x40184f02 : beq.n 0x40184f1a + * 0x40184f04 : ldr r2, [r5, #8] + * 0x40184f06 : ldr r3, [r3, #16] + * + * then the first few (at most four, one would assume) instructions of + * the signal handler (!) might be skipped. They happen to be the + * push of the frame pointer and return address, so once the signal + * handler has done its work, it returns into a SIGSEGV. + */ + +#if defined (TARGET_ARM) && defined (HAVE_ARMV7) && defined (TARGET_ANDROID) +#define KRAIT_IT_BUG_WORKAROUND 1 +#endif + +#ifdef KRAIT_IT_BUG_WORKAROUND +#define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) \ + static void __krait_ ## name arglist; \ + __attribute__ ((__naked__)) access void \ + name arglist \ + { \ + asm volatile ( \ + "mov r0, r0\n\t" \ + "mov r0, r0\n\t" \ + "mov r0, r0\n\t" \ + "mov r0, r0\n\t" \ + "b __krait_" # name \ + "\n\t"); \ + } \ + static __attribute__ ((__used__)) void __krait_ ## name arglist #endif /* Don't use this */