Skip to content

Commit

Permalink
[arm] set exception handling model to dwarf for iOS
Browse files Browse the repository at this point in the history
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, #24]
	str	r0, [sp, #4]
	ldr	r0, [sp, #28]
	ldr	r0, [sp, #12]
	ldr	r0, [r0]
	cmp	r0, #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, #4]
	ldr	r0, [r6]
	cmp	r0, #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/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/f80899cb3eb75f7f5640b4519e83bd96991bffb8/lib/Target/ARM/ARMISelLowering.cpp#L756-L762

The `-exception-model=` option is also not available in LLVM 3.6.

Contributes to mono#15058 and mono#9621
  • Loading branch information
lewurm authored and marek-safar committed Jun 24, 2019
1 parent d0294cf commit d707d74
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit d707d74

Please sign in to comment.