summaryrefslogtreecommitdiff
path: root/src/inc/regdisp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/regdisp.h')
-rw-r--r--src/inc/regdisp.h409
1 files changed, 194 insertions, 215 deletions
diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h
index 09a6a38f62..d08c44c904 100644
--- a/src/inc/regdisp.h
+++ b/src/inc/regdisp.h
@@ -8,19 +8,71 @@
#ifdef DEBUG_REGDISPLAY
class Thread;
+struct REGDISPLAY;
+void CheckRegDisplaySP (REGDISPLAY *pRD);
+#endif // DEBUG_REGDISPLAY
+
+struct REGDISPLAY_BASE {
+ PT_CONTEXT pContext; // This is the context of the active call frame;
+ // either returned by GetContext or provided at
+ // exception time.
+ //
+ // This will be used to resume execution, so
+ // do NOT trash it! But DO update any static
+ // registers here.
+
+#ifdef WIN64EXCEPTIONS
+ PT_CONTEXT pCurrentContext; // [trashed] points to current Context of stackwalk
+ PT_CONTEXT pCallerContext; // [trashed] points to the Context of the caller during stackwalk -- used for GC crawls
+
+ // [trashed] points to current context pointers of stackwalk
+ T_KNONVOLATILE_CONTEXT_POINTERS *pCurrentContextPointers;
+ // [trashed] points to the context pointers of the caller during stackwalk -- used for GC crawls
+ T_KNONVOLATILE_CONTEXT_POINTERS *pCallerContextPointers;
+
+ BOOL IsCallerContextValid; // TRUE if pCallerContext really contains the caller's context
+ BOOL IsCallerSPValid; // Don't add usage of this field. This is only temporary.
+
+ T_CONTEXT ctxOne; // used by stackwalk
+ T_CONTEXT ctxTwo; // used by stackwalk
+
+ T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsOne; // used by stackwalk
+ T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsTwo; // used by stackwalk
+#endif // WIN64EXCEPTIONS
+
+#ifdef DEBUG_REGDISPLAY
+ Thread *_pThread;
#endif // DEBUG_REGDISPLAY
+ TADDR SP;
+ TADDR ControlPC;
+};
+
+inline PCODE GetControlPC(REGDISPLAY_BASE *pRD) {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return (PCODE)(pRD->ControlPC);
+}
+
+inline TADDR GetRegdisplaySP(REGDISPLAY_BASE *pRD) {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return pRD->SP;
+}
+
+inline void SetRegdisplaySP(REGDISPLAY_BASE *pRD, LPVOID sp) {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ pRD->SP = (TADDR)sp;
+}
#if defined(_TARGET_X86_)
-struct REGDISPLAY {
- PCONTEXT pContext; // points to current Context; either
- // returned by GetContext or provided
- // at exception time.
+struct REGDISPLAY : public REGDISPLAY_BASE {
+#ifndef WIN64EXCEPTIONS
// TODO: Unify with pCurrentContext / pCallerContext used on 64-bit
PCONTEXT pContextForUnwind; // scratch context for unwinding
- // used to preserve context saved in the frame that
+ // used to preserve context saved in the frame that
// could be otherwise wiped by the unwinding
DWORD * pEdi;
@@ -31,52 +83,68 @@ struct REGDISPLAY {
DWORD * pEax;
DWORD * pEbp;
- DWORD Esp; // (Esp) Stack Pointer
- PCODE ControlPC;
- TADDR PCTAddr;
+#endif // !WIN64EXCEPTIONS
-};
+#ifndef WIN64EXCEPTIONS
-inline TADDR GetRegdisplaySP(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
+#define REG_METHODS(reg) \
+ inline PDWORD Get##reg##Location(void) { return p##reg; } \
+ inline void Set##reg##Location(PDWORD p##reg) { this->p##reg = p##reg; }
- return (TADDR)display->Esp;
-}
+#else // !WIN64EXCEPTIONS
-inline void SetRegdisplaySP(REGDISPLAY *display, LPVOID sp ) {
- LIMITED_METHOD_DAC_CONTRACT;
+#define REG_METHODS(reg) \
+ inline PDWORD Get##reg##Location(void) { return pCurrentContextPointers->reg; } \
+ inline void Set##reg##Location(PDWORD p##reg) { pCurrentContextPointers->reg = p##reg; }
- (display->Esp) = (DWORD)(size_t)sp;
-}
+#endif // WIN64EXCEPTIONS
+
+ REG_METHODS(Eax)
+ REG_METHODS(Ecx)
+ REG_METHODS(Edx)
+
+ REG_METHODS(Ebx)
+ REG_METHODS(Esi)
+ REG_METHODS(Edi)
+ REG_METHODS(Ebp)
+
+#undef REG_METHODS
+
+ TADDR PCTAddr;
+};
inline TADDR GetRegdisplayFP(REGDISPLAY *display) {
LIMITED_METHOD_DAC_CONTRACT;
- return (TADDR)*(display->pEbp);
+ return (TADDR)*display->GetEbpLocation();
}
inline LPVOID GetRegdisplayFPAddress(REGDISPLAY *display) {
LIMITED_METHOD_CONTRACT;
- return (LPVOID)display->pEbp;
+ return (LPVOID)display->GetEbpLocation();
}
-inline PCODE GetControlPC(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
-
- return display->ControlPC;
-}
// This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame
inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) {
LIMITED_METHOD_CONTRACT;
+#ifdef WIN64EXCEPTIONS
+ return stackPointer < ((LPVOID)(display->SP));
+#else
return (TADDR)stackPointer < display->PCTAddr;
+#endif
}
inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) {
LIMITED_METHOD_DAC_CONTRACT;
+#ifdef WIN64EXCEPTIONS
+ _ASSERTE(GetRegdisplaySP(display) == GetSP(display->pCurrentContext));
+ return GetRegdisplaySP(display);
+#else
return display->PCTAddr;
+#endif
}
#elif defined(_WIN64)
@@ -110,42 +178,18 @@ typedef struct _Arm64VolatileContextPointer
};
} Arm64VolatileContextPointer;
#endif //_TARGET_ARM64_
-struct REGDISPLAY {
- PT_CONTEXT pContext; // This is the context of the active call frame. This
- // will be used to resume execution, so do not use trash it!
- // But DO update any static registers here.
-
- PT_CONTEXT pCurrentContext; // [trashed] points to current Context of stackwalk
- PT_CONTEXT pCallerContext; // [trashed] points to the Context of the caller during stackwalk -- used for GC crawls
-
- size_t ControlPC;
-
- size_t SP;
-
- T_KNONVOLATILE_CONTEXT_POINTERS *pCurrentContextPointers; // [trashed] points to current context pointers of stackwalk
- T_KNONVOLATILE_CONTEXT_POINTERS *pCallerContextPointers; // [trashed] points to the context pointers of the caller during stackwalk -- used for GC crawls
+struct REGDISPLAY : public REGDISPLAY_BASE {
#ifdef _TARGET_ARM64_
Arm64VolatileContextPointer volatileCurrContextPointers;
#endif
- BOOL IsCallerContextValid; // TRUE if pCallerContext really contains the caller's context
- BOOL IsCallerSPValid; // Don't add usage of this field. This is only temporary.
-
- T_CONTEXT ctxOne; // used by stackwalk
- T_CONTEXT ctxTwo; // used by stackwalk
-
- T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsOne; // used by stackwalk
- T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsTwo; // used by stackwalk
-
-#ifdef DEBUG_REGDISPLAY
- Thread *_pThread;
-#endif // DEBUG_REGDISPLAY
+ REGDISPLAY()
+ {
+ // Initialize
+ memset(this, 0, sizeof(REGDISPLAY));
+ }
};
-inline TADDR GetRegdisplaySP(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
- return (TADDR)display->SP;
-}
inline TADDR GetRegdisplayFP(REGDISPLAY *display) {
LIMITED_METHOD_CONTRACT;
@@ -157,28 +201,6 @@ inline TADDR GetRegdisplayFPAddress(REGDISPLAY *display) {
return NULL;
}
-inline PCODE GetControlPC(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
- return (PCODE)(display->ControlPC);
-}
-
-#ifdef DEBUG_REGDISPLAY
-void CheckRegDisplaySP (REGDISPLAY *pRD);
-#endif // DEBUG_REGDISPLAY
-
-inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
-{
- LIMITED_METHOD_CONTRACT;
-
- pRD->SP = (INT_PTR)GetSP(pRD->pCurrentContext);
-
-#ifdef DEBUG_REGDISPLAY
- CheckRegDisplaySP(pRD);
-#endif // DEBUG_REGDISPLAY
-
- pRD->ControlPC = INT_PTR(GetIP(pRD->pCurrentContext));
-}
-
// This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame
inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer)
{
@@ -204,21 +226,6 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display)
#endif // _TARGET_AMD64_
}
-// This needs to be implemented for platforms that have funclets.
-inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
-{
- LIMITED_METHOD_CONTRACT;
-
-#if defined(_TARGET_AMD64_)
- return (LPVOID)display->pCurrentContext->Rax;
-#elif defined(_TARGET_ARM64_)
- return (LPVOID)display->pCurrentContext->X0;
-#else
- PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)");
- return NULL;
-#endif
-}
-
#elif defined(_TARGET_ARM_)
// ResumableFrame is pushed on the stack before
@@ -239,31 +246,11 @@ typedef struct _ArmVolatileContextPointer
PDWORD R12;
} ArmVolatileContextPointer;
-struct REGDISPLAY {
- PT_CONTEXT pContext; // points to current Context; either
- // returned by GetContext or provided
- // at exception time.
-
- PT_CONTEXT pCurrentContext; // [trashed] points to current Context of stackwalk
- PT_CONTEXT pCallerContext; // [trashed] points to the Context of the caller during stackwalk -- used for GC crawls
-
- T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsOne; // used by stackwalk
- T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsTwo; // used by stackwalk
-
- PT_KNONVOLATILE_CONTEXT_POINTERS pCurrentContextPointers;
- PT_KNONVOLATILE_CONTEXT_POINTERS pCallerContextPointers;
+struct REGDISPLAY : public REGDISPLAY_BASE {
ArmVolatileContextPointer volatileCurrContextPointers;
- BOOL IsCallerContextValid; // TRUE if pCallerContext really contains the caller's context
- BOOL IsCallerSPValid; // Don't add usage of this field. This is only temporary.
-
- DWORD SP;
- DWORD ControlPC;
DWORD * pPC; // processor neutral name
- T_CONTEXT ctxOne; // used by stackwalk
- T_CONTEXT ctxTwo; // used in ExceptionTracker::InitializeCrawlFrame
-
REGDISPLAY()
{
// Initialize regdisplay
@@ -272,28 +259,8 @@ struct REGDISPLAY {
// Setup the pointer to ControlPC field
pPC = &ControlPC;
}
-
-#ifdef DEBUG_REGDISPLAY
- Thread *_pThread;
-#endif // DEBUG_REGDISPLAY
-
};
-#ifdef DEBUG_REGDISPLAY
-void CheckRegDisplaySP (REGDISPLAY *pRD);
-#endif // DEBUG_REGDISPLAY
-
-inline TADDR GetRegdisplaySP(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
- return (TADDR)(size_t)display->SP;
-}
-
-inline PCODE GetControlPC(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
- return (PCODE)(display->ControlPC);
-}
-
-
// This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame
inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) {
LIMITED_METHOD_CONTRACT;
@@ -307,42 +274,15 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) {
return GetSP(display->pCallerContext);
}
-inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
-{
- LIMITED_METHOD_CONTRACT;
- pRD->SP = (DWORD)GetSP(pRD->pCurrentContext);
- pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext);
-}
-
-// This needs to be implemented for platforms that have funclets.
-inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
-{
- LIMITED_METHOD_CONTRACT;
-
- return (LPVOID)display->pCurrentContext->R0;
-}
-
#else // none of the above processors
PORTABILITY_WARNING("RegDisplay functions are not implemented on this platform.")
-struct REGDISPLAY {
- PCONTEXT pContext; // points to current Context
- size_t SP;
+struct REGDISPLAY : public REGDISPLAY_BASE {
size_t * FramePtr;
SLOT * pPC;
};
-inline PCODE GetControlPC(REGDISPLAY *display) {
- LIMITED_METHOD_CONTRACT;
- return (PCODE) NULL;
-}
-
-inline LPVOID GetRegdisplaySP(REGDISPLAY *display) {
- LIMITED_METHOD_DAC_CONTRACT;
- return (LPVOID)display->SP;
-}
-
inline TADDR GetRegdisplayFP(REGDISPLAY *display) {
LIMITED_METHOD_CONTRACT;
return (TADDR)*(display->FramePtr);
@@ -359,6 +299,49 @@ inline LPVOID GetRegdisplayStackMark(REGDISPLAY *display) {
#endif
+#if defined(_WIN64) || defined(_TARGET_ARM_) || (defined(_TARGET_X86_) && defined(WIN64EXCEPTIONS))
+// This needs to be implemented for platforms that have funclets.
+inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
+{
+ LIMITED_METHOD_CONTRACT;
+
+#if defined(_TARGET_AMD64_)
+ return (LPVOID)display->pCurrentContext->Rax;
+#elif defined(_TARGET_ARM64_)
+ return (LPVOID)display->pCurrentContext->X0;
+#elif defined(_TARGET_ARM_)
+ return (LPVOID)display->pCurrentContext->R0;
+#elif defined(_TARGET_X86_)
+ return (LPVOID)display->pCurrentContext->Eax;
+#else
+ PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)");
+ return NULL;
+#endif
+}
+
+inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
+{
+ LIMITED_METHOD_CONTRACT;
+
+#if defined(_WIN64)
+ pRD->SP = (INT_PTR)GetSP(pRD->pCurrentContext);
+ pRD->ControlPC = INT_PTR(GetIP(pRD->pCurrentContext));
+#elif defined(_TARGET_ARM_) // _WIN64
+ pRD->SP = (DWORD)GetSP(pRD->pCurrentContext);
+ pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext);
+#elif defined(_TARGET_X86_) // _TARGET_ARM_
+ pRD->SP = (DWORD)GetSP(pRD->pCurrentContext);
+ pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext);
+#else // _TARGET_X86_
+ PORTABILITY_ASSERT("SyncRegDisplayToCurrentContext");
+#endif // _TARGET_ARM_ || _TARGET_X86_
+
+#ifdef DEBUG_REGDISPLAY
+ CheckRegDisplaySP(pRD);
+#endif // DEBUG_REGDISPLAY
+}
+#endif // _WIN64 || _TARGET_ARM_ || (_TARGET_X86_ && WIN64EXCEPTIONS)
+
typedef REGDISPLAY *PREGDISPLAY;
@@ -368,6 +351,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
SUPPORTS_DAC;
+#ifndef WIN64EXCEPTIONS
#ifdef _TARGET_X86_
pRD->pContext = pctx;
pRD->pContextForUnwind = NULL;
@@ -378,23 +362,17 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
pRD->pEax = &(pctx->Eax);
pRD->pEcx = &(pctx->Ecx);
pRD->pEdx = &(pctx->Edx);
- pRD->Esp = pctx->Esp;
+ pRD->SP = pctx->Esp;
pRD->ControlPC = (PCODE)(pctx->Eip);
pRD->PCTAddr = (UINT_PTR)&(pctx->Eip);
-#elif defined(_WIN64)
+#else // _TARGET_X86_
+ PORTABILITY_ASSERT("FillRegDisplay");
+#endif // _TARGET_???_ (ELSE)
+
+#else // !WIN64EXCEPTIONS
pRD->pContext = pctx;
-#ifdef _TARGET_AMD64_
- for (int i = 0; i < 16; i++)
- {
- *(&pRD->ctxPtrsOne.Rax + i) = (&pctx->Rax + i);
- }
-#elif defined(_TARGET_ARM64_)
- for (int i = 0; i < 12; i++)
- {
- *(&pRD->ctxPtrsOne.X19 + i) = (&pctx->X19 + i);
- }
-#endif // _TARGET_AMD64_
+ // Setup the references
pRD->pCurrentContextPointers = &pRD->ctxPtrsOne;
pRD->pCallerContextPointers = &pRD->ctxPtrsTwo;
@@ -417,46 +395,33 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
pRD->IsCallerSPValid = TRUE; // Don't add usage of this field. This is only temporary.
}
-#ifdef DEBUG_REGDISPLAY
- pRD->_pThread = NULL;
-#endif // DEBUG_REGDISPLAY
-
- SyncRegDisplayToCurrentContext(pRD);
-#elif defined(_TARGET_ARM_)
- pRD->pContext = pctx;
-
- // Copy over the nonvolatile integer registers (R4-R11)
- for (int i = 0; i < 8; i++)
+#ifdef _TARGET_AMD64_
+ for (int i = 0; i < 16; i++)
{
- *(&pRD->ctxPtrsOne.R4 + i) = (&pctx->R4 + i);
+ *(&pRD->ctxPtrsOne.Rax + i) = (&pctx->Rax + i);
}
-
- pRD->ctxPtrsOne.Lr = &pctx->Lr;
-
- // Setup the references
- pRD->pCurrentContextPointers = &pRD->ctxPtrsOne;
- pRD->pCallerContextPointers = &pRD->ctxPtrsTwo;
-
- pRD->pCurrentContext = &(pRD->ctxOne);
- pRD->pCallerContext = &(pRD->ctxTwo);
-
- // copy the active context to initialize our stackwalk
- *(pRD->pCurrentContext) = *(pctx);
-
- // copy the caller context as well if it's specified
- if (pCallerCtx == NULL)
+#elif defined(_TARGET_ARM64_) // _TARGET_AMD64_
+ for (int i = 0; i < 12; i++)
{
- pRD->IsCallerContextValid = FALSE;
- pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
+ *(&pRD->ctxPtrsOne.X19 + i) = (&pctx->X19 + i);
}
- else
+#elif defined(_TARGET_ARM_) // _TARGET_ARM64_
+ // Copy over the nonvolatile integer registers (R4-R11)
+ for (int i = 0; i < 8; i++)
{
- *(pRD->pCallerContext) = *(pCallerCtx);
- pRD->IsCallerContextValid = TRUE;
- pRD->IsCallerSPValid = TRUE; // Don't add usage of this field. This is only temporary.
+ *(&pRD->ctxPtrsOne.R4 + i) = (&pctx->R4 + i);
}
+ pRD->ctxPtrsOne.Lr = &pctx->Lr;
pRD->pPC = &pRD->pCurrentContext->Pc;
+#elif defined(_TARGET_X86_) // _TARGET_ARM_
+ for (int i = 0; i < 7; i++)
+ {
+ *(&pRD->ctxPtrsOne.Esi + i) = (&pctx->Esi + i);
+ }
+#else // _TARGET_X86_
+ PORTABILITY_ASSERT("FillRegDisplay");
+#endif // _TARGET_???_ (ELSE)
#ifdef DEBUG_REGDISPLAY
pRD->_pThread = NULL;
@@ -464,9 +429,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
// This will setup the PC and SP
SyncRegDisplayToCurrentContext(pRD);
-#else
- PORTABILITY_ASSERT("@NYI Platform - InitRegDisplay (Threads.cpp)");
-#endif
+#endif // !WIN64EXCEPTIONS
}
// Initialize a new REGDISPLAY/CONTEXT pair from an existing valid REGDISPLAY.
@@ -479,7 +442,9 @@ inline void CopyRegDisplay(const PREGDISPLAY pInRD, PREGDISPLAY pOutRD, T_CONTEX
T_CONTEXT* pOutCallerCtx = NULL;
-#ifdef _TARGET_X86_
+#ifndef WIN64EXCEPTIONS
+
+#if defined(_TARGET_X86_)
if (pInRD->pEdi != NULL) {pOutCtx->Edi = *pInRD->pEdi;} else {pInRD->pEdi = NULL;}
if (pInRD->pEsi != NULL) {pOutCtx->Esi = *pInRD->pEsi;} else {pInRD->pEsi = NULL;}
if (pInRD->pEbx != NULL) {pOutCtx->Ebx = *pInRD->pEbx;} else {pInRD->pEbx = NULL;}
@@ -487,15 +452,21 @@ inline void CopyRegDisplay(const PREGDISPLAY pInRD, PREGDISPLAY pOutRD, T_CONTEX
if (pInRD->pEax != NULL) {pOutCtx->Eax = *pInRD->pEax;} else {pInRD->pEax = NULL;}
if (pInRD->pEcx != NULL) {pOutCtx->Ecx = *pInRD->pEcx;} else {pInRD->pEcx = NULL;}
if (pInRD->pEdx != NULL) {pOutCtx->Edx = *pInRD->pEdx;} else {pInRD->pEdx = NULL;}
- pOutCtx->Esp = pInRD->Esp;
+ pOutCtx->Esp = pInRD->SP;
pOutCtx->Eip = pInRD->ControlPC;
-#else
+#else // _TARGET_X86_
+ PORTABILITY_ASSERT("CopyRegDisplay");
+#endif // _TARGET_???_
+
+#else // WIN64EXCEPTIONS
+
*pOutCtx = *(pInRD->pCurrentContext);
if (pInRD->IsCallerContextValid)
{
pOutCallerCtx = pInRD->pCallerContext;
}
-#endif
+
+#endif // WIN64EXCEPTIONS
if (pOutRD)
FillRegDisplay(pOutRD, pOutCtx, pOutCallerCtx);
@@ -562,6 +533,8 @@ inline void UpdateContextFromRegDisp(PREGDISPLAY pRegDisp, PT_CONTEXT pContext)
{
_ASSERTE((pRegDisp != NULL) && (pContext != NULL));
+#ifndef WIN64EXCEPTIONS
+
#if defined(_TARGET_X86_)
pContext->ContextFlags = (CONTEXT_INTEGER | CONTEXT_CONTROL);
pContext->Edi = *pRegDisp->pEdi;
@@ -571,11 +544,17 @@ inline void UpdateContextFromRegDisp(PREGDISPLAY pRegDisp, PT_CONTEXT pContext)
pContext->Eax = *pRegDisp->pEax;
pContext->Ecx = *pRegDisp->pEcx;
pContext->Edx = *pRegDisp->pEdx;
- pContext->Esp = pRegDisp->Esp;
+ pContext->Esp = pRegDisp->SP;
pContext->Eip = pRegDisp->ControlPC;
-#else
+#else // _TARGET_X86_
+ PORTABILITY_ASSERT("UpdateContextFromRegDisp");
+#endif // _TARGET_???_
+
+#else // WIN64EXCEPTIONS
+
*pContext = *pRegDisp->pCurrentContext;
-#endif
+
+#endif // WIN64EXCEPTIONS
}