-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Use resumable leaf frames in CET hijack and in GC stress. #104198
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1816,37 +1816,20 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) | |
frame.Push(pThread); | ||
} | ||
|
||
DWORD_PTR retValRegs[2] = { 0 }; | ||
// The legacy X86 GC encoder does not encode the state of return registers at | ||
// call sites, so we must add an extra frame to protect returns. | ||
#ifdef TARGET_X86 | ||
DWORD_PTR retValRegs[1] = { 0 }; | ||
UINT numberOfRegs = 0; | ||
|
||
if (afterCallProtect[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that we only need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a lot of cleanup possible since we’ve incremented r2r version. I’d like to do that in a separate follow up change as that could be larger, but mostly mechanical and unlikely to break anything change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We would not need disassemble anything other than x86. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For non-x86 it will be just iterating over interruptible locations (partial or full interruptible - just different iterators) and stick HLT there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although that may still require disassembling - to ensure that hlt is on instruction edges. |
||
{ | ||
#if defined(TARGET_AMD64) | ||
retValRegs[numberOfRegs++] = regs->Rax; | ||
#elif defined(TARGET_X86) | ||
retValRegs[numberOfRegs++] = regs->Eax; | ||
#elif defined(TARGET_ARM) | ||
retValRegs[numberOfRegs++] = regs->R0; | ||
#elif defined(TARGET_ARM64) | ||
retValRegs[numberOfRegs++] = regs->X0; | ||
#elif defined(TARGET_LOONGARCH64) | ||
retValRegs[numberOfRegs++] = regs->A0; | ||
#elif defined(TARGET_RISCV64) | ||
retValRegs[numberOfRegs++] = regs->A0; | ||
#endif // TARGET_ARM64 | ||
} | ||
|
||
if (afterCallProtect[1]) | ||
{ | ||
#if defined(TARGET_AMD64) && defined(TARGET_UNIX) | ||
retValRegs[numberOfRegs++] = regs->Rdx; | ||
#else // !TARGET_AMD64 || !TARGET_UNIX | ||
_ASSERTE(!"Not expected multi reg return with pointers."); | ||
#endif // !TARGET_AMD64 || !TARGET_UNIX | ||
} | ||
|
||
_ASSERTE(sizeof(OBJECTREF) == sizeof(DWORD_PTR)); | ||
GCFrame gcFrame(pThread, (OBJECTREF*)retValRegs, numberOfRegs, TRUE); | ||
#endif | ||
|
||
MethodDesc *pMD = nativeCodeVersion.GetMethodDesc(); | ||
LOG((LF_GCROOTS, LL_EVERYTHING, "GCCOVER: Doing GC at method %s::%s offset 0x%x\n", | ||
|
@@ -1872,36 +1855,15 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) | |
|
||
CONSISTENCY_CHECK(!pThread->HasPendingGCStressInstructionUpdate()); | ||
|
||
#ifdef TARGET_X86 | ||
if (numberOfRegs != 0) | ||
{ | ||
if (afterCallProtect[0]) | ||
{ | ||
#if defined(TARGET_AMD64) | ||
regs->Rax = retValRegs[0]; | ||
#elif defined(TARGET_X86) | ||
regs->Eax = retValRegs[0]; | ||
#elif defined(TARGET_ARM) | ||
regs->R0 = retValRegs[0]; | ||
#elif defined(TARGET_ARM64) | ||
regs->X[0] = retValRegs[0]; | ||
#elif defined(TARGET_LOONGARCH64) | ||
regs->A0 = retValRegs[0]; | ||
#elif defined(TARGET_RISCV64) | ||
regs->A0 = retValRegs[0]; | ||
#else | ||
PORTABILITY_ASSERT("DoGCStress - return register"); | ||
#endif | ||
} | ||
|
||
if (afterCallProtect[1]) | ||
{ | ||
#if defined(TARGET_AMD64) && defined(TARGET_UNIX) | ||
regs->Rdx = retValRegs[numberOfRegs - 1]; | ||
#else // !TARGET_AMD64 || !TARGET_UNIX | ||
_ASSERTE(!"Not expected multi reg return with pointers."); | ||
#endif // !TARGET_AMD64 || !TARGET_UNIX | ||
} | ||
} | ||
#endif | ||
|
||
if (!Thread::UseRedirectForGcStress()) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can simplified since we are only protecting a single value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think with runtime async the need to protect two returns will be back fairly soon, so i did not simplify to strictly one return.