summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/inc/regdisp.h56
-rw-r--r--src/unwinder/i386/unwinder_i386.cpp88
-rw-r--r--src/unwinder/i386/unwinder_i386.h2
3 files changed, 91 insertions, 55 deletions
diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h
index a361dca719..eb84fdfa14 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 f221020752..42c19cb54d 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 bed30bf894..f29248f0ef 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,