UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
+ ULONG ResumeEsp;
} CONTEXT, *PCONTEXT, *LPCONTEXT;
// To support saving and loading xmm register context we need to know the offset in the ExtendedRegisters
#define CONTEXT_Xmm5 CONTEXT_Xmm4+16
#define CONTEXT_Xmm6 CONTEXT_Xmm5+16
#define CONTEXT_Xmm7 CONTEXT_Xmm6+16
+#define CONTEXT_ResumeEsp CONTEXT_ExtendedRegisters+512
mov [eax + CONTEXT_Ebp], ebp
lea ebx, [esp + 12]
mov [eax + CONTEXT_Esp], ebx
+ mov [eax + CONTEXT_ResumeEsp], ebx
mov ebx, [esp + 8]
mov [eax + CONTEXT_Eip], ebx
LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS):
// Restore Stack
- mov esp, [eax + CONTEXT_Esp]
+ mov esp, [eax + CONTEXT_ResumeEsp]
// Create a minimal frame
push DWORD PTR [eax + CONTEXT_Eip]
mov ebx, [esp + 8] // eax: CONTEXT *
mov ebp, [ebx + CONTEXT_Ebp]
- mov esp, [ebx + CONTEXT_Esp]
+ mov esp, [ebx + CONTEXT_ResumeEsp]
// The ESP is re-initialized as the target frame's value, so the current function's
// CFA is now right at the ESP.
#elif defined(_X86_)
unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Eip);
unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Esp);
+ unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->ResumeEsp);
unw_get_reg(cursor, UNW_X86_EBP, (unw_word_t *) &winContext->Ebp);
unw_get_reg(cursor, UNW_X86_EBX, (unw_word_t *) &winContext->Ebx);
unw_get_reg(cursor, UNW_X86_ESI, (unw_word_t *) &winContext->Esi);
if ((contextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
{
ASSIGN_CONTROL_REGS
-#ifdef _ARM_
+#if defined(_ARM_)
// WinContext assumes that the least bit of Pc is always 1 (denoting thumb)
// although the pc value retrived from native context might not have set the least bit.
// This becomes especially problematic if the context is on the JIT_WRITEBARRIER.
lpContext->Pc |= 0x1;
+#elif defined(_X86_)
+ lpContext->ResumeEsp = MCREG_Esp(native->uc_mcontext);
#endif
}
lpContext->Esi = pState->esi;
lpContext->Ebp = pState->ebp;
lpContext->Esp = pState->esp;
+ lpContext->ResumeEsp = pState->esp;
lpContext->SegSs = pState->ss;
lpContext->EFlags = pState->eflags;
lpContext->Eip = pState->eip;
FillRegDisplay(&rd, ContextRecord);
+ rd.SP = ContextRecord->ResumeEsp;
rd.PCTAddr = (UINT_PTR)&(ContextRecord->Eip);
if (ContextPointers)
ENUM_CALLEE_SAVED_REGISTERS();
#undef CALLEE_SAVED_REGISTER
- ContextRecord->Esp = rd.SP;
+ ContextRecord->Esp = rd.SP - codeInfo.GetCodeManager()->GetStackParameterSize(&codeInfo);
+ ContextRecord->ResumeEsp = rd.SP;
ContextRecord->Eip = rd.ControlPC;
// For x86, the value of Establisher Frame Pointer is Caller SP
{
EnsureCallerContextIsValid(pRD, NULL);
}
- return (size_t) (GetSP(pRD->pCallerContext));
+
+ return GetSP(pRD->pCallerContext);
}
#endif // WIN64EXCEPTIONS && !CROSSGEN_COMPILE
MethodDesc * pFunc = GetFunction();
_ASSERTE(pFunc != NULL);
+
UpdateRegDisplayHelper(pRD, pFunc->CbStackPop());
LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK TransitionFrame::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
#ifdef WIN64EXCEPTIONS
+ DWORD CallerSP = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
+
pRD->IsCallerContextValid = FALSE;
pRD->IsCallerSPValid = FALSE;
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);;
- pRD->pCurrentContext->Esp = GetSP();
+ pRD->pCurrentContext->Esp = CallerSP;
+ pRD->pCurrentContext->ResumeEsp = CallerSP + cbStackPop;
UpdateRegDisplayFromCalleeSavedRegisters(pRD, regs);
ClearRegDisplayArgumentAndScratchRegisters(pRD);
#endif // DACCESS_COMPILE
pRD->pCurrentContext->Eip = pRD->ControlPC = m_MachState.GetRetAddr();
- pRD->pCurrentContext->Esp = pRD->SP = (DWORD) m_MachState.esp();
+ pRD->pCurrentContext->Esp = pRD->pCurrentContext->ResumeEsp = pRD->SP = (DWORD) m_MachState.esp();
#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContext->regname = *((DWORD*) m_MachState.p##regname());
ENUM_CALLEE_SAVED_REGISTERS();
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
- pRD->pCurrentContext->Esp = (DWORD) dac_cast<TADDR>(m_pCallSiteSP) + stackArgSize;
+ pRD->pCurrentContext->Esp = (DWORD) dac_cast<TADDR>(m_pCallSiteSP);
+ pRD->pCurrentContext->ResumeEsp = (DWORD) dac_cast<TADDR>(m_pCallSiteSP) + stackArgSize;
pRD->pCurrentContext->Ebp = (DWORD) m_pCalleeSavedFP;
ClearRegDisplayArgumentAndScratchRegisters(pRD);
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
- pRD->pCurrentContext->Esp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
+ pRD->pCurrentContext->Esp = pRD->pCurrentContext->ResumeEsp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
#define RESTORE_REG(reg) { pRD->pCurrentContext->reg = m_Args->reg; pRD->pCurrentContextPointers->reg = &m_Args->reg; }
#define CALLEE_SAVED_REGISTER(reg) RESTORE_REG(reg)
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
- pRD->pCurrentContext->Esp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
+ pRD->pCurrentContext->Esp = pRD->pCurrentContext->ResumeEsp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
UpdateRegDisplayFromCalleeSavedRegisters(pRD, &m_regs);
ClearRegDisplayArgumentAndScratchRegisters(pRD);