summaryrefslogtreecommitdiff
path: root/packaging/0026-Port-DacUnwindStackFrame-11666.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0026-Port-DacUnwindStackFrame-11666.patch')
-rw-r--r--packaging/0026-Port-DacUnwindStackFrame-11666.patch227
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
+