summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin 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
commita52f00caa51bfadc03134f6de3491238bc1e7d61 (patch)
tree2a8cc2579f62ff956c349c385fe03d8d19564d7c
parent47e34c60ffb197064f2def6845b91fe0001b2846 (diff)
downloadcoreclr-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.cpp2
-rw-r--r--src/inc/regdisp.h11
-rw-r--r--src/vm/eetwain.cpp21
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp2
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;