diff options
Diffstat (limited to 'packaging/0026-Port-DacUnwindStackFrame-11666.patch')
-rw-r--r-- | packaging/0026-Port-DacUnwindStackFrame-11666.patch | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/packaging/0026-Port-DacUnwindStackFrame-11666.patch b/packaging/0026-Port-DacUnwindStackFrame-11666.patch new file mode 100644 index 0000000000..f2747f9d26 --- /dev/null +++ b/packaging/0026-Port-DacUnwindStackFrame-11666.patch @@ -0,0 +1,227 @@ +From 29d32d571bfb8ed844de4a2549baa8ae65aa3155 Mon Sep 17 00:00:00 2001 +From: Jonghyun Park <parjong@gmail.com> +Date: Thu, 18 May 2017 12:34:05 +0900 +Subject: [PATCH 26/29] Port 'DacUnwindStackFrame' (#11666) + +* [x86/Linux] Implement 'DacUnwindStackFrame' + +* Update ContextPointers using ContextRecord + +* An attempt to fix x86/Windows build error +--- + src/inc/regdisp.h | 56 +++++++++++++---------- + src/unwinder/i386/unwinder_i386.cpp | 88 ++++++++++++++++++++++++------------- + src/unwinder/i386/unwinder_i386.h | 2 + + 3 files changed, 91 insertions(+), 55 deletions(-) + +diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h +index a361dca..eb84fdf 100644 +--- a/src/inc/regdisp.h ++++ b/src/inc/regdisp.h +@@ -323,6 +323,35 @@ inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) + + typedef REGDISPLAY *PREGDISPLAY; + ++#ifdef WIN64EXCEPTIONS ++inline void FillContextPointers(PT_KNONVOLATILE_CONTEXT_POINTERS pCtxPtrs, PT_CONTEXT pCtx) ++{ ++#ifdef _TARGET_AMD64_ ++ for (int i = 0; i < 16; i++) ++ { ++ *(&pCtxPtrs->Rax + i) = (&pCtx->Rax + i); ++ } ++#elif defined(_TARGET_ARM64_) // _TARGET_AMD64_ ++ for (int i = 0; i < 12; i++) ++ { ++ *(&pCtxPtrs->X19 + i) = (&pCtx->X19 + i); ++ } ++#elif defined(_TARGET_ARM_) // _TARGET_ARM64_ ++ // Copy over the nonvolatile integer registers (R4-R11) ++ for (int i = 0; i < 8; i++) ++ { ++ *(&pCtxPtrs->R4 + i) = (&pCtx->R4 + i); ++ } ++#elif defined(_TARGET_X86_) // _TARGET_ARM_ ++ for (int i = 0; i < 7; i++) ++ { ++ *(&pCtxPtrs->Edi + i) = (&pCtx->Edi + i); ++ } ++#else // _TARGET_X86_ ++ PORTABILITY_ASSERT("FillContextPointers"); ++#endif // _TARGET_???_ (ELSE) ++} ++#endif // WIN64EXCEPTIONS + + inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pCallerCtx = NULL) + { +@@ -374,33 +403,12 @@ 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_AMD64_ +- for (int i = 0; i < 16; i++) +- { +- *(&pRD->ctxPtrsOne.Rax + i) = (&pctx->Rax + i); +- } +-#elif defined(_TARGET_ARM64_) // _TARGET_AMD64_ +- for (int i = 0; i < 12; i++) +- { +- *(&pRD->ctxPtrsOne.X19 + i) = (&pctx->X19 + i); +- } +-#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); +- } ++ FillContextPointers(&pRD->ctxPtrsOne, pctx); + ++#if defined(_TARGET_ARM_) + 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.Edi + i) = (&pctx->Edi + i); +- } +-#else // _TARGET_X86_ +- PORTABILITY_ASSERT("FillRegDisplay"); +-#endif // _TARGET_???_ (ELSE) ++#endif // _TARGET_ARM_ + + #ifdef DEBUG_REGDISPLAY + pRD->_pThread = NULL; +diff --git a/src/unwinder/i386/unwinder_i386.cpp b/src/unwinder/i386/unwinder_i386.cpp +index f221020..42c19cb 100644 +--- a/src/unwinder/i386/unwinder_i386.cpp ++++ b/src/unwinder/i386/unwinder_i386.cpp +@@ -8,6 +8,49 @@ + #include "unwinder_i386.h" + + #ifdef WIN64EXCEPTIONS ++BOOL OOPStackUnwinderX86::Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers) ++{ ++ REGDISPLAY rd; ++ ++ FillRegDisplay(&rd, pContextRecord); ++ ++ rd.SP = pContextRecord->Esp; ++ rd.PCTAddr = (UINT_PTR)&(pContextRecord->Eip); ++ ++ if (pContextPointers) ++ { ++ rd.pCurrentContextPointers = pContextPointers; ++ } ++ ++ CodeManState codeManState; ++ codeManState.dwIsSet = 0; ++ ++ DWORD ControlPc = pContextRecord->Eip; ++ ++ EECodeInfo codeInfo; ++ codeInfo.Init((PCODE) ControlPc); ++ ++ if (!UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL)) ++ { ++ return FALSE; ++ } ++ ++ pContextRecord->ContextFlags |= CONTEXT_UNWOUND_TO_CALL; ++ ++#define ARGUMENT_AND_SCRATCH_REGISTER(reg) if (rd.pCurrentContextPointers->reg) pContextRecord->reg = *rd.pCurrentContextPointers->reg; ++ ENUM_ARGUMENT_AND_SCRATCH_REGISTERS(); ++#undef ARGUMENT_AND_SCRATCH_REGISTER ++ ++#define CALLEE_SAVED_REGISTER(reg) if (rd.pCurrentContextPointers->reg) pContextRecord->reg = *rd.pCurrentContextPointers->reg; ++ ENUM_CALLEE_SAVED_REGISTERS(); ++#undef CALLEE_SAVED_REGISTER ++ ++ pContextRecord->Esp = rd.SP - codeInfo.GetCodeManager()->GetStackParameterSize(&codeInfo); ++ pContextRecord->Eip = rd.ControlPC; ++ ++ return TRUE; ++} ++ + /*++ + + Routine Description: +@@ -72,42 +115,13 @@ OOPStackUnwinderX86::VirtualUnwind( + *HandlerRoutine = NULL; + } + +- REGDISPLAY rd; +- +- FillRegDisplay(&rd, ContextRecord); +- +- rd.SP = ContextRecord->Esp; +- rd.PCTAddr = (UINT_PTR)&(ContextRecord->Eip); +- +- if (ContextPointers) +- { +- rd.pCurrentContextPointers = ContextPointers; +- } +- +- CodeManState codeManState; +- codeManState.dwIsSet = 0; ++ _ASSERTE(ContextRecord->Eip == ControlPc); + +- EECodeInfo codeInfo; +- codeInfo.Init((PCODE) ControlPc); +- +- if (!UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL)) ++ if (!OOPStackUnwinderX86::Unwind(ContextRecord, ContextPointers)) + { + return HRESULT_FROM_WIN32(ERROR_READ_FAULT); + } + +- ContextRecord->ContextFlags |= CONTEXT_UNWOUND_TO_CALL; +- +-#define ARGUMENT_AND_SCRATCH_REGISTER(reg) if (rd.pCurrentContextPointers->reg) ContextRecord->reg = *rd.pCurrentContextPointers->reg; +- ENUM_ARGUMENT_AND_SCRATCH_REGISTERS(); +-#undef ARGUMENT_AND_SCRATCH_REGISTER +- +-#define CALLEE_SAVED_REGISTER(reg) if (rd.pCurrentContextPointers->reg) ContextRecord->reg = *rd.pCurrentContextPointers->reg; +- ENUM_CALLEE_SAVED_REGISTERS(); +-#undef CALLEE_SAVED_REGISTER +- +- ContextRecord->Esp = rd.SP - codeInfo.GetCodeManager()->GetStackParameterSize(&codeInfo); +- ContextRecord->Eip = rd.ControlPC; +- + // For x86, the value of Establisher Frame Pointer is Caller SP + // + // (Please refers to CLR ABI for details) +@@ -115,6 +129,18 @@ OOPStackUnwinderX86::VirtualUnwind( + return S_OK; + } + ++BOOL DacUnwindStackFrame(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers) ++{ ++ BOOL res = OOPStackUnwinderX86::Unwind(pContextRecord, NULL); ++ ++ if (res && pContextPointers) ++ { ++ FillContextPointers(pContextPointers, pContextRecord); ++ } ++ ++ return res; ++} ++ + //--------------------------------------------------------------------------------------- + // + // This function behaves like the RtlVirtualUnwind in Windows. +diff --git a/src/unwinder/i386/unwinder_i386.h b/src/unwinder/i386/unwinder_i386.h +index bed30bf..f29248f 100644 +--- a/src/unwinder/i386/unwinder_i386.h ++++ b/src/unwinder/i386/unwinder_i386.h +@@ -18,6 +18,8 @@ + class OOPStackUnwinderX86 : public OOPStackUnwinder + { + public: ++ static BOOL Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers); ++ + static HRESULT VirtualUnwind(__in DWORD HandlerType, + __in DWORD ImageBase, + __in DWORD ControlPc, +-- +2.7.4 + |