Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlateralusX <lateralusx.github@gmail.com>2016-07-07 18:24:49 +0300
committerlateralusX <lateralusx.github@gmail.com>2016-07-07 18:24:49 +0300
commit87afbc44229e22db3b9784766967d23de8d83283 (patch)
tree19493bb7134e2804d3838082a4f11cc3436e9a0d
parent7fa8d071253bba57ec253623b36a6c08f2c444d2 (diff)
Fix crash in mono mini exceptions.exe regression test on win x64.
Exceptions.exe regression test started to fail on win x64 release builds. Turns out that the Visual Studio C compiler picked a different optimization for release builds (due to a change of library type that uses a different default optimization level) using RSI register in native code calling into JIT:ed code. If the JIT:ed code used reflection and exceptions, that triggers InternalInvoke and lmf_filter, the code only stored System V x64 non-volatile registers in the unwind information. On Windows, RSI is also a non-volatile register (RDI as well) that needs to be preserved and since the code didn’t include those in the unwind information, the correct RSI value was not restored during the unwind. Once the control was handled back to the native code it dereferenced RSI (that was set to 0) and crashed. The fix is to make sure we store all non-volatile registers on x64 Windows when we save an lmf so the unwind code can restore them when unwinding through the lmf.
-rw-r--r--mono/mini/mini-amd64.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c
index 054aa4017ae..932f198a779 100644
--- a/mono/mini/mini-amd64.c
+++ b/mono/mini/mini-amd64.c
@@ -1550,9 +1550,11 @@ mono_arch_allocate_vars (MonoCompile *cfg)
}
cfg->arch.saved_iregs = cfg->used_int_regs;
- if (cfg->method->save_lmf)
- /* Save all callee-saved registers normally, and restore them when unwinding through an LMF */
- cfg->arch.saved_iregs |= (1 << AMD64_RBX) | (1 << AMD64_R12) | (1 << AMD64_R13) | (1 << AMD64_R14) | (1 << AMD64_R15);
+ if (cfg->method->save_lmf) {
+ /* Save all callee-saved registers normally (except RBP, if not already used), and restore them when unwinding through an LMF */
+ guint32 iregs_to_save = AMD64_CALLEE_SAVED_REGS & ~(1<<AMD64_RBP);
+ cfg->arch.saved_iregs |= iregs_to_save;
+ }
if (cfg->arch.omit_fp)
cfg->arch.reg_save_area_offset = offset;