diff options
author | Konstantin Baladurin <k.baladurin@samsung.com> | 2019-09-26 20:06:57 +0300 |
---|---|---|
committer | Михаил Аксенов/Device Solutions Lab /SRR/Engineer/삼성전자 <m.aksenov@samsung.com> | 2019-10-04 19:42:39 +0300 |
commit | a52f00caa51bfadc03134f6de3491238bc1e7d61 (patch) | |
tree | 2a8cc2579f62ff956c349c385fe03d8d19564d7c | |
parent | 47e34c60ffb197064f2def6845b91fe0001b2846 (diff) | |
download | coreclr-a52f00caa51bfadc03134f6de3491238bc1e7d61.tar.gz coreclr-a52f00caa51bfadc03134f6de3491238bc1e7d61.tar.bz2 coreclr-a52f00caa51bfadc03134f6de3491238bc1e7d61.zip |
[Linux/x86] Use ebp from current context during unwinding (#26789)
pCurrentContextPointers in REGDISPLAY can contain NULLs so we need to use
ebp value from pCurrentContext. This patch contains following changes:
- GetRegdisplayFP returns ebp from pCurrentContext
- GetRegdisplayFP is used instead of *GetEbpLocation()
- Set##reg##Location also updates register value in pCurrentContext
-rw-r--r-- | src/debug/ee/i386/x86walker.cpp | 2 | ||||
-rw-r--r-- | src/inc/regdisp.h | 11 | ||||
-rw-r--r-- | src/vm/eetwain.cpp | 21 | ||||
-rw-r--r-- | src/vm/proftoeeinterfaceimpl.cpp | 2 |
4 files changed, 21 insertions, 15 deletions
diff --git a/src/debug/ee/i386/x86walker.cpp b/src/debug/ee/i386/x86walker.cpp index 8b62797484..078bc7ca75 100644 --- a/src/debug/ee/i386/x86walker.cpp +++ b/src/debug/ee/i386/x86walker.cpp @@ -307,7 +307,7 @@ DWORD NativeWalker::GetRegisterValue(int registerNumber) return m_registers->SP; break; case 5: - return *m_registers->GetEbpLocation(); + return GetRegdisplayFP(m_registers); break; case 6: return *m_registers->GetEsiLocation(); diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h index 7875edf653..4a7e57e63d 100644 --- a/src/inc/regdisp.h +++ b/src/inc/regdisp.h @@ -95,7 +95,11 @@ struct REGDISPLAY : public REGDISPLAY_BASE { #define REG_METHODS(reg) \ inline PDWORD Get##reg##Location(void) { return pCurrentContextPointers->reg; } \ - inline void Set##reg##Location(PDWORD p##reg) { pCurrentContextPointers->reg = p##reg; } + inline void Set##reg##Location(PDWORD p##reg) \ + { \ + pCurrentContextPointers->reg = p##reg; \ + pCurrentContext->reg = *p##reg; \ + } #endif // WIN64EXCEPTIONS @@ -115,8 +119,11 @@ struct REGDISPLAY : public REGDISPLAY_BASE { inline TADDR GetRegdisplayFP(REGDISPLAY *display) { LIMITED_METHOD_DAC_CONTRACT; - +#ifdef WIN64EXCEPTIONS + return (TADDR)display->pCurrentContext->Ebp; +#else return (TADDR)*display->GetEbpLocation(); +#endif } inline LPVOID GetRegdisplayFPAddress(REGDISPLAY *display) { diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index c0eb7aa8d0..c3e49cfe8a 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -3203,7 +3203,7 @@ void EECodeManager::QuickUnwindStackFrame(PREGDISPLAY pRD, StackwalkCacheEntry * if (pCacheEntry->fUseEbpAsFrameReg) { _ASSERTE(pCacheEntry->fUseEbp); - TADDR curEBP = (TADDR)*pRD->GetEbpLocation(); + TADDR curEBP = GetRegdisplayFP(pRD); // EBP frame, update ESP through EBP, since ESPOffset may vary pRD->SetEbpLocation(PTR_DWORD(curEBP)); @@ -3479,7 +3479,7 @@ void UnwindEbpDoubleAlignFrameEpilog( unsigned calleeSavedRegsSize = info->savedRegsCountExclFP * sizeof(void*); if (!InstructionAlreadyExecuted(offset, info->epilogOffs)) - ESP = *pContext->GetEbpLocation() - calleeSavedRegsSize; + ESP = GetRegdisplayFP(pContext) - calleeSavedRegsSize; offset = SKIP_LEA_ESP_EBP(-int(calleeSavedRegsSize), epilogBase, offset); } @@ -3508,7 +3508,7 @@ void UnwindEbpDoubleAlignFrameEpilog( if (needMovEspEbp) { if (!InstructionAlreadyExecuted(offset, info->epilogOffs)) - ESP = *pContext->GetEbpLocation(); + ESP = GetRegdisplayFP(pContext); offset = SKIP_MOV_REG_REG(epilogBase, offset); } @@ -3802,7 +3802,7 @@ void UnwindEbpDoubleAlignFrameProlog( can be determined using EBP. Since we are still in the prolog, we need to know our exact location to determine the callee-saved registers */ - const unsigned curEBP = *pContext->GetEbpLocation(); + const unsigned curEBP = GetRegdisplayFP(pContext); if (flags & UpdateAllRegs) { @@ -3873,8 +3873,8 @@ bool UnwindEbpDoubleAlignFrame( _ASSERTE(info->ebpFrame || info->doubleAlign); - const unsigned curESP = pContext->SP; - const unsigned curEBP = *pContext->GetEbpLocation(); + const unsigned curESP = pContext->SP; + const unsigned curEBP = GetRegdisplayFP(pContext); /* First check if we are in a filter (which is obviously after the prolog) */ @@ -4015,7 +4015,6 @@ bool UnwindEbpDoubleAlignFrame( /* The caller's saved EBP is pointed to by our EBP */ pContext->SetEbpLocation(PTR_DWORD((TADDR)curEBP)); - return true; } @@ -4310,8 +4309,8 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); unsigned curOffs = pCodeInfo->GetRelOffset(); - unsigned EBP = *pContext->GetEbpLocation(); - unsigned ESP = pContext->SP; + unsigned EBP = GetRegdisplayFP(pContext); + unsigned ESP = pContext->SP; unsigned ptrOffs; @@ -5243,7 +5242,7 @@ OBJECTREF* EECodeManager::GetAddrOfSecurityObjectFromCachedInfo(PREGDISPLAY pRD, // We pretend that filters are ESP-based methods in UnwindEbpDoubleAlignFrame(). // Hence we cannot enforce this assert. // _ASSERTE(stackwalkCacheUnwindInfo->fUseEbpAsFrameReg); - return (OBJECTREF *) (size_t) (*pRD->GetEbpLocation() - (securityObjectOffset * sizeof(void*))); + return (OBJECTREF *) (size_t) (GetRegdisplayFP(pRD) - (securityObjectOffset * sizeof(void*))); } #endif // _TARGET_X86_ @@ -5280,7 +5279,7 @@ OBJECTREF* EECodeManager::GetAddrOfSecurityObject(CrawlFrame *pCF) if(stateBuf->hdrInfoBody.prologOffs == hdrInfo::NOT_IN_PROLOG && stateBuf->hdrInfoBody.epilogOffs == hdrInfo::NOT_IN_EPILOG) { - return (OBJECTREF *)(size_t)(*pRD->GetEbpLocation() - GetSecurityObjectOffset(&stateBuf->hdrInfoBody)); + return (OBJECTREF *)(size_t)(GetRegdisplayFP(pRD) - GetSecurityObjectOffset(&stateBuf->hdrInfoBody)); } } #else // !USE_GC_INFO_DECODER diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp index cff17213a7..03362f9299 100644 --- a/src/vm/proftoeeinterfaceimpl.cpp +++ b/src/vm/proftoeeinterfaceimpl.cpp @@ -7747,7 +7747,7 @@ Loop: CodeManState codeManState; codeManState.dwIsSet = 0; REGDISPLAY rd; - ZeroMemory(&rd, sizeof(rd)); + FillRegDisplay(&rd, &ctxCur); rd.SetEbpLocation(&ctxCur.Ebp); rd.SP = ctxCur.Esp; |