Skip to content

Fix incorrect codemanager implementation on x86 #115391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/coreclr/vm/codeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -2945,6 +2945,9 @@ class EECodeInfo
*infoPtr = &m_hdrInfoBody;
return m_hdrInfoTable;
}

PTR_CBYTE DecodeGCHdrInfo(hdrInfo * infoPtr, DWORD relOffset);

private:
PTR_CBYTE DecodeGCHdrInfoHelper(hdrInfo ** infoPtr);
#endif // TARGET_X86
Expand Down
65 changes: 37 additions & 28 deletions src/coreclr/vm/eetwain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,26 @@ void EECodeManager::FixContext( ContextType ctxType,
_ASSERTE((ctxType == FINALLY_CONTEXT) == (thrownObject == NULL));

/* Extract the necessary information from the info block header */
hdrInfo *hdrInfoBody;
pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody);
hdrInfo hdrInfoBody = { 0 };
pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody, dwRelOffset);

#ifdef _DEBUG
if (trFixContext) {
minipal_log_print_info("FixContext [%s][%s] for %s.%s: ",
hdrInfoBody->ebpFrame?"ebp":" ",
hdrInfoBody->interruptible?"int":" ",
hdrInfoBody.ebpFrame?"ebp":" ",
hdrInfoBody.interruptible?"int":" ",
"UnknownClass","UnknownMethod");
minipal_log_flush_info();
}
#endif

/* make sure that we have an ebp stack frame */

_ASSERTE(hdrInfoBody->ebpFrame);
_ASSERTE(hdrInfoBody->handlers); // <TODO>@TODO : This will always be set. Remove it</TODO>
_ASSERTE(hdrInfoBody.ebpFrame);
_ASSERTE(hdrInfoBody.handlers); // <TODO>@TODO : This will always be set. Remove it</TODO>

TADDR baseSP;
GetHandlerFrameInfo(hdrInfoBody, ctx->Ebp,
GetHandlerFrameInfo(&hdrInfoBody, ctx->Ebp,
ctxType == FILTER_CONTEXT ? ctx->Esp : IGNORE_VAL,
ctxType == FILTER_CONTEXT ? (DWORD) IGNORE_VAL : nestingLevel,
&baseSP,
Expand All @@ -102,7 +102,7 @@ void EECodeManager::FixContext( ContextType ctxType,
// EE will write Esp to **pShadowSP before jumping to handler

PTR_TADDR pBaseSPslots =
GetFirstBaseSPslotPtr(ctx->Ebp, hdrInfoBody);
GetFirstBaseSPslotPtr(ctx->Ebp, &hdrInfoBody);
*ppShadowSP = (size_t *)&pBaseSPslots[-(int) nestingLevel ];
pBaseSPslots[-(int)(nestingLevel+1)] = 0; // Zero out the next slot

Expand Down Expand Up @@ -851,18 +851,18 @@ bool EECodeManager::IsGcSafe( EECodeInfo *pCodeInfo,
SUPPORTS_DAC;
} CONTRACTL_END;

hdrInfo *info;
hdrInfo info = { 0 };

/* Extract the necessary information from the info block header */

pCodeInfo->DecodeGCHdrInfo(&info);
pCodeInfo->DecodeGCHdrInfo(&info, dwRelOffset);

/* workaround: prevent interruption within prolog/epilog */

if (info->prologOffs != hdrInfo::NOT_IN_PROLOG || info->epilogOffs != hdrInfo::NOT_IN_EPILOG)
if (info.prologOffs != hdrInfo::NOT_IN_PROLOG || info.epilogOffs != hdrInfo::NOT_IN_EPILOG)
return false;

return (info->interruptible);
return (info.interruptible);
}

#endif // !USE_GC_INFO_DECODER
Expand Down Expand Up @@ -2254,34 +2254,43 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext,

/* Extract the necessary information from the info block header */

hdrInfo *hdrInfoBody;
PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody);
PTR_CBYTE table = nullptr;
hdrInfo hdrInfoBody = { 0 };
hdrInfo *pCodeInfoBody = &hdrInfoBody;
if (pCodeInfo->GetRelOffset() == dwRelOffset)
{
table = pCodeInfo->DecodeGCHdrInfo(&pCodeInfoBody);
}
else
{
table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody, dwRelOffset);
}

#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
if (trFixContext)
{
minipal_log_print_info("GetAmbientSP [%s][%s] for %s.%s: ",
hdrInfoBody->ebpFrame?"ebp":" ",
hdrInfoBody->interruptible?"int":" ",
pCodeInfoBody->ebpFrame?"ebp":" ",
pCodeInfoBody->interruptible?"int":" ",
"UnknownClass","UnknownMethod");
minipal_log_flush_info();
}
#endif // _DEBUG && !DACCESS_COMPILE

if ((hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG) ||
(hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG))
if ((pCodeInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG) ||
(pCodeInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG))
{
return NULL;
}

/* make sure that we have an ebp stack frame */

if (hdrInfoBody->handlers)
if (pCodeInfoBody->handlers)
{
_ASSERTE(hdrInfoBody->ebpFrame);
_ASSERTE(pCodeInfoBody->ebpFrame);

TADDR baseSP;
GetHandlerFrameInfo(hdrInfoBody,
GetHandlerFrameInfo(pCodeInfoBody,
GetRegdisplayFP(pContext),
(DWORD) IGNORE_VAL,
nestingLevel,
Expand All @@ -2294,24 +2303,24 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext,

_ASSERTE(nestingLevel == 0);

if (hdrInfoBody->ebpFrame)
if (pCodeInfoBody->ebpFrame)
{
return GetOutermostBaseFP(GetRegdisplayFP(pContext), hdrInfoBody);
return GetOutermostBaseFP(GetRegdisplayFP(pContext), pCodeInfoBody);
}

TADDR baseSP = GetRegdisplaySP(pContext);
if (hdrInfoBody->interruptible)
if (pCodeInfoBody->interruptible)
{
baseSP += scanArgRegTableI(skipToArgReg(*hdrInfoBody, table),
baseSP += scanArgRegTableI(skipToArgReg(*pCodeInfoBody, table),
dwRelOffset,
dwRelOffset,
hdrInfoBody);
pCodeInfoBody);
}
else
{
baseSP += scanArgRegTable(skipToArgReg(*hdrInfoBody, table),
baseSP += scanArgRegTable(skipToArgReg(*pCodeInfoBody, table),
dwRelOffset,
hdrInfoBody);
pCodeInfoBody);
}

return baseSP;
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15301,6 +15301,15 @@ PTR_CBYTE EECodeInfo::DecodeGCHdrInfoHelper(hdrInfo ** infoPtr)
return m_hdrInfoTable;
}

PTR_CBYTE EECodeInfo::DecodeGCHdrInfo(hdrInfo * infoPtr, DWORD relOffset)
{
_ASSERTE(infoPtr != NULL);
GCInfoToken gcInfoToken = GetGCInfoToken();
DWORD hdrInfoSize = (DWORD)::DecodeGCHdrInfo(gcInfoToken, relOffset, infoPtr);
_ASSERTE(hdrInfoSize != 0);
return (PTR_CBYTE)gcInfoToken.Info + hdrInfoSize;
}

#endif // TARGET_X86

#if defined(TARGET_AMD64)
Expand Down