diff options
author | Jonghyun Park <parjong@gmail.com> | 2017-05-18 12:34:05 +0900 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2017-05-17 20:34:05 -0700 |
commit | be98fe4989e33273005504425cb4922aa0587b11 (patch) | |
tree | f757ecfc9cf27c576b1444f3d7c858c00fa6c4bb /src/unwinder | |
parent | e33facae6baeb5f14c242ba83112b72d205db911 (diff) | |
download | coreclr-be98fe4989e33273005504425cb4922aa0587b11.tar.gz coreclr-be98fe4989e33273005504425cb4922aa0587b11.tar.bz2 coreclr-be98fe4989e33273005504425cb4922aa0587b11.zip |
[x86/Linux] Port 'DacUnwindStackFrame' (#11666)
* [x86/Linux] Implement 'DacUnwindStackFrame'
* Update ContextPointers using ContextRecord
* An attempt to fix x86/Windows build error
Diffstat (limited to 'src/unwinder')
-rw-r--r-- | src/unwinder/i386/unwinder_i386.cpp | 88 | ||||
-rw-r--r-- | src/unwinder/i386/unwinder_i386.h | 2 |
2 files changed, 59 insertions, 31 deletions
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, |