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

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2016-10-07 01:21:37 +0300
committerJan Vorlicek <janvorli@microsoft.com>2016-10-07 01:21:37 +0300
commit6805241e21540d31973d152da5d2a979a5853978 (patch)
tree85531dd22ccac694ef7159e9a336eae14a294313 /src/Native/Runtime/amd64
parent00bf0f88b007e1f3a8875f97922b411d1045d043 (diff)
This change fixes an issue with invocation of exception filters. We were not saving callee saved registers in the RhpCallFilterFunclet asm helper and the NUTC doesn't save callee saved registers in the filter funclet. So when the FindFirstPassHandler called the filter, the filter have modified ESI, but the FindFirstPassHandler code was expecting to be preserved and so it failed to unwind properly.
It also adds saving callee saved floating point registers to windows amd64 and arm helpers [tfs-changeset: 1631842]
Diffstat (limited to 'src/Native/Runtime/amd64')
-rw-r--r--src/Native/Runtime/amd64/ExceptionHandling.S67
-rw-r--r--src/Native/Runtime/amd64/ExceptionHandling.asm130
2 files changed, 115 insertions, 82 deletions
diff --git a/src/Native/Runtime/amd64/ExceptionHandling.S b/src/Native/Runtime/amd64/ExceptionHandling.S
index 3c0f62595..436efb046 100644
--- a/src/Native/Runtime/amd64/ExceptionHandling.S
+++ b/src/Native/Runtime/amd64/ExceptionHandling.S
@@ -234,6 +234,37 @@ ALTERNATE_ENTRY RhpRethrow2
NESTED_END RhpRethrow, _TEXT
+//
+// Prologue of all funclet calling helpers (RhpCallXXXXFunclet)
+//
+.macro FUNCLET_CALL_PROLOGUE localsCount, alignStack
+
+ push_nonvol_reg r15 // save preserved regs for OS stackwalker
+ push_nonvol_reg r14 // ...
+ push_nonvol_reg r13 // ...
+ push_nonvol_reg r12 // ...
+ push_nonvol_reg rbx // ...
+ push_nonvol_reg rbp // ...
+
+ stack_alloc_size = localsCount * 8 + alignStack * 8
+
+ alloc_stack stack_alloc_size
+
+ END_PROLOGUE
+.endm
+
+//
+// Epilogue of all funclet calling helpers (RhpCallXXXXFunclet)
+//
+.macro FUNCLET_CALL_EPILOGUE
+ add rsp, stack_alloc_size
+ pop rbp
+ pop rbx
+ pop r12
+ pop r13
+ pop r14
+ pop r15
+.endm
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -250,12 +281,7 @@ NESTED_END RhpRethrow, _TEXT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpCallCatchFunclet, _TEXT, NoHandler
- push_nonvol_reg r15 // save preserved regs for OS stackwalker
- push_nonvol_reg r14 // ...
- push_nonvol_reg r13 // ...
- push_nonvol_reg r12 // ...
- push_nonvol_reg rbx // ...
- push_nonvol_reg rbp // ...
+ FUNCLET_CALL_PROLOGUE 6, 1
locThread = 0
locResumeIp = 8
@@ -264,10 +290,6 @@ NESTED_ENTRY RhpCallCatchFunclet, _TEXT, NoHandler
locArg2 = 0x20
locArg3 = 0x28
- alloc_stack 0x38 // locals
-
- END_PROLOGUE
-
mov [rsp + locArg0], rdi // save arguments for later
mov [rsp + locArg1], rsi
mov [rsp + locArg2], rdx
@@ -397,21 +419,12 @@ NESTED_END RhpCallCatchFunclet, _TEXT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpCallFinallyFunclet, _TEXT, NoHandler
- push_nonvol_reg r15 // save preserved regs
- push_nonvol_reg r14 // ...
- push_nonvol_reg r13 // ...
- push_nonvol_reg r12 // ...
- push_nonvol_reg rbx // ...
- push_nonvol_reg rbp // ...
+ FUNCLET_CALL_PROLOGUE 3, 0
locThread = 0
locArg0 = 8
locArg1 = 0x10
- alloc_stack 0x18 // locals
-
- END_PROLOGUE
-
mov [rsp + locArg0], rdi // save arguments for later
mov [rsp + locArg1], rsi
@@ -482,13 +495,7 @@ ALTERNATE_ENTRY RhpCallFinallyFunclet2
mov rax, [rsp + locThread] // rax <- Thread*
lock or dword ptr [rax + OFFSETOF__Thread__m_ThreadStateFlags], ~TSF_DoNotTriggerGc
- add rsp, 0x18
- pop rbp
- pop rbx
- pop r12
- pop r13
- pop r14
- pop r15
+ FUNCLET_CALL_EPILOGUE
ret
@@ -508,9 +515,7 @@ NESTED_END RhpCallFinallyFunclet, _TEXT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpCallFilterFunclet, _TEXT, NoHandler
- push_nonvol_reg rbp // we'll be setting rbp to the funclet's frame pointer
-
- END_PROLOGUE
+ FUNCLET_CALL_PROLOGUE 0, 1
mov rax, [rdx + OFFSETOF__REGDISPLAY__pRbp]
mov rbp, [rax]
@@ -523,7 +528,7 @@ ALTERNATE_ENTRY RhpCallFilterFunclet2
// RAX contains the result of the filter execution
- pop rbp
+ FUNCLET_CALL_EPILOGUE
ret
diff --git a/src/Native/Runtime/amd64/ExceptionHandling.asm b/src/Native/Runtime/amd64/ExceptionHandling.asm
index 022df968c..baf89e9ea 100644
--- a/src/Native/Runtime/amd64/ExceptionHandling.asm
+++ b/src/Native/Runtime/amd64/ExceptionHandling.asm
@@ -282,6 +282,67 @@ ALTERNATE_ENTRY RhpRethrow2
NESTED_END RhpRethrow, _TEXT
+;;
+;; Prologue of all funclet calling helpers (RhpCallXXXXFunclet)
+;;
+FUNCLET_CALL_PROLOGUE macro localsCount, alignStack
+
+ push_nonvol_reg r15 ;; save preserved regs for OS stackwalker
+ push_nonvol_reg r14 ;; ...
+ push_nonvol_reg r13 ;; ...
+ push_nonvol_reg r12 ;; ...
+ push_nonvol_reg rbx ;; ...
+ push_nonvol_reg rsi ;; ...
+ push_nonvol_reg rdi ;; ...
+ push_nonvol_reg rbp ;; ...
+
+ arguments_scratch_area_size = 20h
+ xmm_save_area_size = 10 * 10h ;; xmm6..xmm15 save area
+ stack_alloc_size = arguments_scratch_area_size + localsCount * 8 + alignStack * 8 + xmm_save_area_size
+ rsp_offsetof_arguments = stack_alloc_size + 8*8h + 8h
+ rsp_offsetof_locals = arguments_scratch_area_size + xmm_save_area_size
+
+ alloc_stack stack_alloc_size
+
+ save_xmm128_postrsp xmm6, (arguments_scratch_area_size + 0 * 10h)
+ save_xmm128_postrsp xmm7, (arguments_scratch_area_size + 1 * 10h)
+ save_xmm128_postrsp xmm8, (arguments_scratch_area_size + 2 * 10h)
+ save_xmm128_postrsp xmm9, (arguments_scratch_area_size + 3 * 10h)
+ save_xmm128_postrsp xmm10, (arguments_scratch_area_size + 4 * 10h)
+ save_xmm128_postrsp xmm11, (arguments_scratch_area_size + 5 * 10h)
+ save_xmm128_postrsp xmm12, (arguments_scratch_area_size + 6 * 10h)
+ save_xmm128_postrsp xmm13, (arguments_scratch_area_size + 7 * 10h)
+ save_xmm128_postrsp xmm14, (arguments_scratch_area_size + 8 * 10h)
+ save_xmm128_postrsp xmm15, (arguments_scratch_area_size + 9 * 10h)
+
+ END_PROLOGUE
+endm
+
+;;
+;; Epilogue of all funclet calling helpers (RhpCallXXXXFunclet)
+;;
+FUNCLET_CALL_EPILOGUE macro
+ movdqa xmm6, [rsp + arguments_scratch_area_size + 0 * 10h]
+ movdqa xmm7, [rsp + arguments_scratch_area_size + 1 * 10h]
+ movdqa xmm8, [rsp + arguments_scratch_area_size + 2 * 10h]
+ movdqa xmm9, [rsp + arguments_scratch_area_size + 3 * 10h]
+ movdqa xmm10, [rsp + arguments_scratch_area_size + 4 * 10h]
+ movdqa xmm11, [rsp + arguments_scratch_area_size + 5 * 10h]
+ movdqa xmm12, [rsp + arguments_scratch_area_size + 6 * 10h]
+ movdqa xmm13, [rsp + arguments_scratch_area_size + 7 * 10h]
+ movdqa xmm14, [rsp + arguments_scratch_area_size + 8 * 10h]
+ movdqa xmm15, [rsp + arguments_scratch_area_size + 9 * 10h]
+
+ add rsp, stack_alloc_size
+ pop rbp
+ pop rdi
+ pop rsi
+ pop rbx
+ pop r12
+ pop r13
+ pop r14
+ pop r15
+endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
@@ -298,28 +359,19 @@ NESTED_END RhpRethrow, _TEXT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NESTED_ENTRY RhpCallCatchFunclet, _TEXT
- push_nonvol_reg r15 ;; save preserved regs for OS stackwalker
- push_nonvol_reg r14 ;; ...
- push_nonvol_reg r13 ;; ...
- push_nonvol_reg r12 ;; ...
- push_nonvol_reg rbx ;; ...
- push_nonvol_reg rsi ;; ...
- push_nonvol_reg rdi ;; ...
- push_nonvol_reg rbp ;; ...
-
- alloc_stack 38h ;; outgoing area + locals
-
- END_PROLOGUE
-
- rsp_offsetof_arguments = 38h + 8*8h + 8h
+ FUNCLET_CALL_PROLOGUE 2, 1
+ ;; locals
+ rsp_offsetof_thread = rsp_offsetof_locals
+ rsp_offsetof_resume_ip = rsp_offsetof_locals + 8;
+
mov [rsp + rsp_offsetof_arguments + 0h], rcx ;; save arguments for later
mov [rsp + rsp_offsetof_arguments + 8h], rdx
mov [rsp + rsp_offsetof_arguments + 10h], r8
mov [rsp + rsp_offsetof_arguments + 18h], r9
INLINE_GETTHREAD rax, rbx ;; rax <- Thread*, rbx is trashed
- mov [rsp + 20h], rax ;; save Thread* for later
+ mov [rsp + rsp_offsetof_thread], rax ;; save Thread* for later
;; Clear the DoNotTriggerGc state before calling out to our managed catch funclet.
lock and dword ptr [rax + OFFSETOF__Thread__m_ThreadStateFlags], NOT TSF_DoNotTriggerGc
@@ -389,7 +441,7 @@ ifdef _DEBUG
;; Call into some C++ code to validate the pop of the ExInfo. We only do this in debug because we
;; have to spill all the preserved registers and then refill them after the call.
- mov [rsp + 28h], rax ;; save resume IP for later
+ mov [rsp + rsp_offsetof_resume_ip], rax ;; save resume IP for later
mov rcx, [r8 + OFFSETOF__REGDISPLAY__pRbx]
mov [rcx] , rbx
@@ -408,7 +460,7 @@ ifdef _DEBUG
mov rcx, [r8 + OFFSETOF__REGDISPLAY__pR15]
mov [rcx] , r15
- mov rcx, [rsp + 20h] ;; rcx <- Thread*
+ mov rcx, [rsp + rsp_offsetof_thread] ;; rcx <- Thread*
mov rdx, [rsp + rsp_offsetof_arguments + 18h] ;; rdx <- current ExInfo *
mov r8, [r8 + OFFSETOF__REGDISPLAY__SP] ;; r8 <- resume SP value
call RhpValidateExInfoPop
@@ -431,9 +483,9 @@ ifdef _DEBUG
mov rax, [r8 + OFFSETOF__REGDISPLAY__pR15]
mov r15, [rax]
- mov rax, [rsp + 28h] ;; reload resume IP
+ mov rax, [rsp + rsp_offsetof_resume_ip] ;; reload resume IP
endif
- mov rdx, [rsp + 20h] ;; rdx <- Thread*
+ mov rdx, [rsp + rsp_offsetof_thread] ;; rdx <- Thread*
;; We must unhijack the thread at this point because the section of stack where the hijack is applied
;; may go dead. If it does, then the next time we try to unhijack the thread, it will corrupt the stack.
@@ -469,26 +521,15 @@ NESTED_END RhpCallCatchFunclet, _TEXT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NESTED_ENTRY RhpCallFinallyFunclet, _TEXT
- push_nonvol_reg r15 ;; save preserved regs
- push_nonvol_reg r14 ;; ...
- push_nonvol_reg r13 ;; ...
- push_nonvol_reg r12 ;; ...
- push_nonvol_reg rbx ;; ...
- push_nonvol_reg rsi ;; ...
- push_nonvol_reg rdi ;; ...
- push_nonvol_reg rbp ;; ...
-
- alloc_stack 28h ;; outgoing area + locals
-
- END_PROLOGUE
-
- rsp_offsetof_arguments = 28h + 8*8h + 8h
+ FUNCLET_CALL_PROLOGUE 1, 0
mov [rsp + rsp_offsetof_arguments + 0h], rcx ;; save arguments for later
mov [rsp + rsp_offsetof_arguments + 8h], rdx
+ rsp_offsetof_thread = rsp_offsetof_locals
+
INLINE_GETTHREAD rax, rbx ;; rax <- Thread*, rbx is trashed
- mov [rsp + 20h], rax ;; save Thread* for later
+ mov [rsp + rsp_offsetof_thread], rax ;; save Thread* for later
;;
;; We want to suppress hijacking between invocations of subsequent finallys. We do this because we
@@ -584,18 +625,10 @@ ALTERNATE_ENTRY RhpCallFinallyFunclet2
movdqa [rdx + OFFSETOF__REGDISPLAY__Xmm + 8*10h], xmm14
movdqa [rdx + OFFSETOF__REGDISPLAY__Xmm + 9*10h], xmm15
- mov rax, [rsp + 20h] ;; rax <- Thread*
+ mov rax, [rsp + rsp_offsetof_thread] ;; rax <- Thread*
lock or dword ptr [rax + OFFSETOF__Thread__m_ThreadStateFlags], TSF_DoNotTriggerGc
- add rsp, 28h
- pop rbp
- pop rdi
- pop rsi
- pop rbx
- pop r12
- pop r13
- pop r14
- pop r15
+ FUNCLET_CALL_EPILOGUE
ret
@@ -615,11 +648,7 @@ NESTED_END RhpCallFinallyFunclet, _TEXT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NESTED_ENTRY RhpCallFilterFunclet, _TEXT
- push_nonvol_reg rbp ;; we'll be setting rbp to the funclet's frame pointer
-
- alloc_stack 20h ;; outgoing area
-
- END_PROLOGUE
+ FUNCLET_CALL_PROLOGUE 0, 1
mov rax, [r8 + OFFSETOF__REGDISPLAY__pRbp]
mov rbp, [rax]
@@ -636,8 +665,7 @@ ALTERNATE_ENTRY RhpCallFilterFunclet2
;; RAX contains the result of the filter execution
- add rsp, 20h
- pop rbp
+ FUNCLET_CALL_EPILOGUE
ret