From: Bernhard Urban Date: Fri, 21 Jun 2019 14:26:24 +0000 (+0200) Subject: [arm] set exception handling model to dwarf for iOS X-Git-Tag: submit/tizen/20210909.063632~10331^2~5^2~1087 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4926d7f8a7cce666f0481e4788f43c050ec5600a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [arm] set exception handling model to dwarf for iOS We recently switched the AOT compiler for iOS armv7 from 32bit host to 64bit host. At the same time we _also_ switched from LLVM 3.6 to the newer LLVM 6.0 fork we support. In a Xamarin.iOS Release build for iOS armv7 exception handling would crash. Specifically the problem was that the exception object wasn't properly injected into the handler block. The way it works is, that the exception handler machinery passes the pointer to the exception object via `r0`. With the newer LLVM the generated code of the exception handling block looks like this: ``` LBB1_15: @ %EH_CLAUSE0_BB3 Ltmp8: ldr r0, [sp, mono/mono#24] str r0, [sp, mono/mono#4] ldr r0, [sp, mono/mono#28] ldr r0, [sp, mono/mono#12] ldr r0, [r0] cmp r0, mono/mono#0 beq LBB1_17 ``` thus overwriting `r0`, so that the pointer to the exception object is lost. With the older LLVM 3.6 the generated code looks like this: ``` LBB1_8: @ %EH_CLAUSE0_BB3 Ltmp8: str r0, [sp, mono/mono#4] ldr r0, [r6] cmp r0, mono/mono#0 beq LBB1_10 ``` correctly storing the exception object into a stack slot for later usage. After some time I figured out that there are _different_ exception handling models. Depending on the model, the exception pointer is passed in `r0` or not: https://github.com/mono/llvm/blob/mono/mono@2bd2f1db1803f7b36687e5abf912c69baa848305/lib/Target/ARM/ARMISelLowering.cpp#L14416-L14428 `SjLj` stands for "SetJump / LongJump" and means that exception handling is implemented with this. On iOS this is the default model that is used. We want `dwarf` instead, so we tell this `llc` now and the generated code handles it correctly. So why was it working before? In our older LLVM 3.6 fork we hardcoded it: https://github.com/mono/llvm/blob/mono/mono@f80899cb3eb75f7f5640b4519e83bd96991bffb8/lib/Target/ARM/ARMISelLowering.cpp#L756-L762 The `-exception-model=` option is also not available in LLVM 3.6. Contributes to https://github.com/mono/mono/issues/15058 and https://github.com/mono/mono/issues/9621 Commit migrated from https://github.com/mono/mono/commit/7d5daa2f77246a036f19ddb34ac4715c5ca58f36 --- diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index a6bca65..931e54d 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -1123,8 +1123,12 @@ arch_init (MonoAotCompile *acfg) if (!(acfg->aot_opts.mtriple && strstr (acfg->aot_opts.mtriple, "thumb"))) g_string_append (acfg->llc_args, " -march=arm"); - if (acfg->aot_opts.mtriple && strstr (acfg->aot_opts.mtriple, "ios")) + if (acfg->aot_opts.mtriple && strstr (acfg->aot_opts.mtriple, "ios")) { g_string_append (acfg->llc_args, " -mattr=+v7"); +#ifdef LLVM_API_VERSION > 100 + g_string_append (acfg->llc_args, " -exception-model=dwarf"); +#endif + } #if defined(ARM_FPU_VFP_HARD) g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16 -float-abi=hard");