diff options
author | Chris Ahna <chrisahn@microsoft.com> | 2016-01-26 03:58:38 +0300 |
---|---|---|
committer | Chris Ahna <chrisahn@microsoft.com> | 2016-01-26 03:58:38 +0300 |
commit | fa0df48cfda30c090081a3ecf0913976c733995c (patch) | |
tree | eae1c80b477acb15278198863e8c6a904eef6c30 /src/Native/Runtime/i386 | |
parent | 20196c2b9fa74cdfbebc1d7b95365e4ebb155273 (diff) |
MRT StackFrameIterator improvements
These changes are targeted at completing/hardening the runtime's
support for the new UniversalTransition and CallDescr thunks and also
clarifying the invariants that hold throughout stack walker operation.
[tfs-changeset: 1568546]
Diffstat (limited to 'src/Native/Runtime/i386')
-rw-r--r-- | src/Native/Runtime/i386/AsmMacros.inc | 12 | ||||
-rw-r--r-- | src/Native/Runtime/i386/AsmOffsetsCpu.h | 6 | ||||
-rw-r--r-- | src/Native/Runtime/i386/UniversalTransition.asm | 54 |
3 files changed, 26 insertions, 46 deletions
diff --git a/src/Native/Runtime/i386/AsmMacros.inc b/src/Native/Runtime/i386/AsmMacros.inc index 8a249d2c1..ffda6561e 100644 --- a/src/Native/Runtime/i386/AsmMacros.inc +++ b/src/Native/Runtime/i386/AsmMacros.inc @@ -85,31 +85,21 @@ endm ;; ;; EAX is trashed by this macro. ;; -;; If <NoModeSwitch> is set, threadReg is ignored. As a result, <NoModeSwitch> can only be used by helpers -;; which guarantee that they will never transition into pre-emptive mode and will never examine the m_pThread -;; field of the frame. -;; -PUSH_COOP_PINVOKE_FRAME macro threadReg, NoModeSwitch +PUSH_COOP_PINVOKE_FRAME macro threadReg lea eax, [ebp + 8] ; get the ESP of the caller push eax ; save ESP push edi push esi push ebx push PTFF_SAVE_ALL_PRESERVED + PTFF_SAVE_RSP -ifb <NoModeSwitch> push threadReg ; Thread * (unused by stackwalker) -else - push 0 -endif mov eax, [ebp + 0] ; Find previous EBP value push eax ; save EBP mov eax, [ebp + 4] ; Find the return address push eax ; save m_RIP lea eax, [esp + 0] ; EAX == address of frame -ifb <NoModeSwitch> mov [threadReg + OFFSETOF__Thread__m_pHackPInvokeTunnel], eax ; Link frame to thread -endif endm ;; diff --git a/src/Native/Runtime/i386/AsmOffsetsCpu.h b/src/Native/Runtime/i386/AsmOffsetsCpu.h index c214c06fb..be2d04abc 100644 --- a/src/Native/Runtime/i386/AsmOffsetsCpu.h +++ b/src/Native/Runtime/i386/AsmOffsetsCpu.h @@ -9,7 +9,7 @@ // // NOTE: the offsets MUST be in hex notation WITHOUT the 0x prefix -PLAT_ASM_SIZEOF(b4, ExInfo) +PLAT_ASM_SIZEOF(b8, ExInfo) PLAT_ASM_OFFSET(0, ExInfo, m_pPrevExInfo) PLAT_ASM_OFFSET(4, ExInfo, m_pExContext) PLAT_ASM_OFFSET(8, ExInfo, m_exception) @@ -17,7 +17,7 @@ PLAT_ASM_OFFSET(0c, ExInfo, m_kind) PLAT_ASM_OFFSET(0d, ExInfo, m_passNumber) PLAT_ASM_OFFSET(10, ExInfo, m_idxCurClause) PLAT_ASM_OFFSET(14, ExInfo, m_frameIter) -PLAT_ASM_OFFSET(b0, ExInfo, m_notifyDebuggerSP) +PLAT_ASM_OFFSET(b4, ExInfo, m_notifyDebuggerSP) PLAT_ASM_OFFSET(0, PInvokeTransitionFrame, m_RIP) PLAT_ASM_OFFSET(4, PInvokeTransitionFrame, m_FramePointer) @@ -25,7 +25,7 @@ PLAT_ASM_OFFSET(8, PInvokeTransitionFrame, m_pThread) PLAT_ASM_OFFSET(0c, PInvokeTransitionFrame, m_dwFlags) PLAT_ASM_OFFSET(10, PInvokeTransitionFrame, m_PreservedRegs) -PLAT_ASM_SIZEOF(9c, StackFrameIterator) +PLAT_ASM_SIZEOF(a0, StackFrameIterator) PLAT_ASM_OFFSET(08, StackFrameIterator, m_FramePointer) PLAT_ASM_OFFSET(0c, StackFrameIterator, m_ControlPC) PLAT_ASM_OFFSET(10, StackFrameIterator, m_RegDisplay) diff --git a/src/Native/Runtime/i386/UniversalTransition.asm b/src/Native/Runtime/i386/UniversalTransition.asm index 7abd1fc63..1f7a13634 100644 --- a/src/Native/Runtime/i386/UniversalTransition.asm +++ b/src/Native/Runtime/i386/UniversalTransition.asm @@ -34,24 +34,26 @@ ifdef FEATURE_DYNAMIC_CODE ;; ; -; Stack frame layout (from lower addresses to higher addresses): +; Frame layout is: ; -; [callee return] -; [pinvoke frame, 20h] -; [in edx (argument register from the caller)] -; [in ecx (argument register from the caller)] -; [ConservativelyReportedScratchSpace 8h] -; -- On input (i.e., when control jumps to RhpUniversalTransition), the low 4 bytes of -; this area contain the address of the callee and the high 4 bytes of this area contain -; the extra argument to pass to the callee. -; [ptr to pinvoke frame 4h] -; [saved ebp register] -; [caller return addr] -; [stack-passed arguments from the caller] +; {StackPassedArgs} ChildSP+018 CallerSP+000 +; {CallerRetaddr} ChildSP+014 CallerSP-004 +; {CallerEBP} ChildSP+010 CallerSP-008 +; {ReturnBlock (0x8 bytes)} ChildSP+008 CallerSP-010 +; -- On input (i.e., when control jumps to RhpUniversalTransition), the low 4 bytes of +; the ReturnBlock area holds the address of the callee and the high 4 bytes holds the +; extra argument to pass to the callee. +; {IntArgRegs (edx,ecx) (0x8 bytes)} ChildSP+000 CallerSP-018 +; {CalleeRetaddr} ChildSP-004 CallerSP-01c ; -; Note: The callee receives a pointer to the pushed edx value, and the callee has -; knowledge of the exact layout of all pieces of the frame that lie at or above the pushed -; edx value. +; NOTE: If the frame layout ever changes, the C++ UniversalTransitionStackFrame structure +; must be updated as well. +; +; NOTE: The callee receives a pointer to the base of the pushed IntArgRegs, and the callee +; has knowledge of the exact layout of the entire frame. +; +; NOTE: The stack walker guarantees that conservative GC reporting will be applied to +; everything between the base of the IntArgRegs and the top of the StackPassedArgs. ; FASTCALL_FUNC RhpUniversalTransition_FAKE_ENTRY, 0 @@ -60,34 +62,22 @@ FASTCALL_FUNC RhpUniversalTransition_FAKE_ENTRY, 0 mov ebp, esp push eax push eax - push eax ALTERNATE_ENTRY RhpUniversalTransition@0 push ecx push edx - ; Build the frame that the stack walker will use to unwind through this function. The - ; <NoModeSwitch> flag indicates that this function never uses Enable/DisablePreemptiveGC, - ; implying that frame address does not need to be recorded in the current thread object. - PUSH_COOP_PINVOKE_FRAME notUsed, <NoModeSwitch> - - ;; Stash the pinvoke frame's address immediately on top of the old ebp value. This - ;; position is important; the stack frame iterator knows about this setup. -.erre MANAGED_CALLOUT_THUNK_TRANSITION_FRAME_POINTER_OFFSET eq -4 - mov [ebp-4], esp - ; ; Call out to the target, while storing and reporting arguments to the GC. ; - mov eax, [ebp-0Ch] ; Get the address of the callee - mov edx, [ebp-8] ; Get the extra argument to pass to the callee - lea ecx, [ebp-14h] ; Get pointer to edx value pushed above + mov eax, [ebp-8] ; Get the address of the callee + mov edx, [ebp-4] ; Get the extra argument to pass to the callee + lea ecx, [ebp-10h] ; Get pointer to edx value pushed above call eax LABELED_RETURN_ADDRESS ReturnFromUniversalTransition - POP_COOP_PINVOKE_FRAME pop edx pop ecx - add esp, 12 + add esp, 8 pop ebp jmp eax |