void UpdateRegDisplayFromCalleeSavedRegisters(REGDISPLAY * pRD, CalleeSavedRegisters * pRegs) { LIMITED_METHOD_CONTRACT; T_CONTEXT * pContext = pRD->pCurrentContext; #define CALLEE_SAVED_REGISTER(regname) pContext->regname = pRegs->regname; ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER KNONVOLATILE_CONTEXT_POINTERS * pContextPointers = pRD->pCurrentContextPointers; #define CALLEE_SAVED_REGISTER(regname) pContextPointers->regname = (PULONG64)&pRegs->regname; ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER }
void TailCallFrame::InitFromContext(T_CONTEXT * pContext) { WRAPPER_NO_CONTRACT; #define CALLEE_SAVED_REGISTER(regname) m_calleeSavedRegisters.regname = pContext->regname; ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER m_pGCLayout = 0; m_ReturnAddress = pContext->Rip; }
/*++ Routine Description: This function virtually unwinds the specified function by executing its prologue code backward or its epilogue code forward. If a context pointers record is specified, then the address where each nonvolatile registers is restored from is recorded in the appropriate element of the context pointers record. Arguments: HandlerType - Supplies the handler type expected for the virtual unwind. This may be either an exception or an unwind handler. A flag may optionally be supplied to avoid epilogue detection if it is known the specified control PC is not located inside a function epilogue. ImageBase - Supplies the base address of the image that contains the function being unwound. ControlPc - Supplies the address where control left the specified function. FunctionEntry - Supplies the address of the function table entry for the specified function. ContextRecord - Supplies the address of a context record. HandlerData - Supplies a pointer to a variable that receives a pointer the the language handler data. EstablisherFrame - Supplies a pointer to a variable that receives the the establisher frame pointer value. ContextPointers - Supplies an optional pointer to a context pointers record. HandlerRoutine - Supplies an optional pointer to a variable that receives the handler routine address. If control did not leave the specified function in either the prologue or an epilogue and a handler of the proper type is associated with the function, then the address of the language specific exception handler is returned. Otherwise, NULL is returned. --*/ HRESULT OOPStackUnwinderX86::VirtualUnwind( __in DWORD HandlerType, __in DWORD ImageBase, __in DWORD ControlPc, __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry, __inout PCONTEXT ContextRecord, __out PVOID *HandlerData, __out PDWORD EstablisherFrame, __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, __deref_opt_out_opt PEXCEPTION_ROUTINE *HandlerRoutine ) { if (HandlerRoutine != NULL) { *HandlerRoutine = NULL; } REGDISPLAY rd; FillRegDisplay(&rd, ContextRecord); rd.SP = ContextRecord->ResumeEsp; rd.PCTAddr = (UINT_PTR)&(ContextRecord->Eip); if (ContextPointers) { rd.pCurrentContextPointers = ContextPointers; } CodeManState codeManState; codeManState.dwIsSet = 0; EECodeInfo codeInfo; codeInfo.Init((PCODE) ControlPc); if (!UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL)) { 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->ResumeEsp = rd.SP; ContextRecord->Eip = rd.ControlPC; // For x86, the value of Establisher Frame Pointer is Caller SP // // (Please refers to CLR ABI for details) *EstablisherFrame = ContextRecord->Esp; return S_OK; }