diff options
Diffstat (limited to 'src/inc/regdisp.h')
-rw-r--r-- | src/inc/regdisp.h | 164 |
1 files changed, 87 insertions, 77 deletions
diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h index 09a6a38f62..81143466cd 100644 --- a/src/inc/regdisp.h +++ b/src/inc/regdisp.h @@ -18,10 +18,33 @@ struct REGDISPLAY { // returned by GetContext or provided // at exception time. +#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 // could be otherwise wiped by the unwinding +#else // !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 + +#ifdef DEBUG_REGDISPLAY + Thread *_pThread; +#endif // DEBUG_REGDISPLAY +#endif // !WIN64EXCEPTIONS DWORD * pEdi; DWORD * pEsi; @@ -166,18 +189,6 @@ inline PCODE GetControlPC(REGDISPLAY *display) { 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,20 +215,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_) @@ -307,20 +304,7 @@ 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 @@ -359,6 +343,50 @@ 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); + +#ifdef DEBUG_REGDISPLAY + CheckRegDisplaySP(pRD); +#endif // DEBUG_REGDISPLAY + + 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->Esp = (DWORD)GetSP(pRD->pCurrentContext); + pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); +#else // _TARGET_X86_ + PORTABILITY_ASSERT("SyncRegDisplayToCurrentContext"); +#endif // _TARGET_ARM_ || _TARGET_X86_ +} +#endif // _WIN64 || _TARGET_ARM_ || (_TARGET_X86_ && WIN64EXCEPTIONS) + typedef REGDISPLAY *PREGDISPLAY; @@ -368,6 +396,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; @@ -381,57 +410,38 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC pRD->Esp = 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_) +#elif defined(_TARGET_ARM64_) // _TARGET_AMD64_ for (int i = 0; i < 12; i++) { *(&pRD->ctxPtrsOne.X19 + i) = (&pctx->X19 + i); } -#endif // _TARGET_AMD64_ - - 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) - { - pRD->IsCallerContextValid = FALSE; - pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - } - else - { - *(pRD->pCallerContext) = *(pCallerCtx); - pRD->IsCallerContextValid = TRUE; - 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; - +#elif defined(_TARGET_ARM_) // _TARGET_ARM64_ // Copy over the nonvolatile integer registers (R4-R11) for (int i = 0; i < 8; i++) { *(&pRD->ctxPtrsOne.R4 + i) = (&pctx->R4 + i); } - pRD->ctxPtrsOne.Lr = &pctx->Lr; + pRD->ctxPtrsOne.Lr = &pctx->Lr; +#elif defined(_TARGET_X86_) // _TARGET_ARM_ + for (int i = 0; i < 4; ++i) + { + *(&pRD->ctxPtrsOne.Ebx + i) = (&pctx->Ebx + i); + } +#else // _TARGET_X86_ + PORTABILITY_ASSERT("FillRegDisplay"); +#endif // _TARGET_???_ (ELSE) // Setup the references pRD->pCurrentContextPointers = &pRD->ctxPtrsOne; @@ -456,7 +466,9 @@ 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 _TARGET_ARM_ pRD->pPC = &pRD->pCurrentContext->Pc; +#endif #ifdef DEBUG_REGDISPLAY pRD->_pThread = NULL; @@ -464,9 +476,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. |