Skip to content
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

Save stack arguments size in InlinedCallFrame.m_Datum on x86 to handle callee's popping of arguments #33249

Merged
merged 2 commits into from
Mar 10, 2020
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
17 changes: 13 additions & 4 deletions src/coreclr/src/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3172,7 +3172,7 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call)
#else // !TARGET_X86
// In case of helper dispatched tail calls, "thisptr" will be the third arg.
// The first two args are: real call target and addr of args copy routine.
const unsigned argNum = 2;
const unsigned argNum = 2;
#endif // !TARGET_X86

fgArgTabEntry* thisArgTabEntry = comp->gtArgEntryByArgNum(call, argNum);
Expand Down Expand Up @@ -3439,7 +3439,7 @@ void Lowering::InsertPInvokeMethodProlog()
#if defined(TARGET_X86) || defined(TARGET_ARM)
GenTreeCall::Use* argList = comp->gtNewCallArgs(frameAddr);
#else
GenTreeCall::Use* argList = comp->gtNewCallArgs(frameAddr, PhysReg(REG_SECRET_STUB_PARAM));
GenTreeCall::Use* argList = comp->gtNewCallArgs(frameAddr, PhysReg(REG_SECRET_STUB_PARAM));
#endif

GenTree* call = comp->gtNewHelperCallNode(CORINFO_HELP_INIT_PINVOKE_FRAME, TYP_I_IMPL, argList);
Expand Down Expand Up @@ -3620,9 +3620,18 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
GenTree* frameAddr =
new (comp, GT_LCL_VAR_ADDR) GenTreeLclVar(GT_LCL_VAR_ADDR, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar);

#if defined(TARGET_X86) && !defined(UNIX_X86_ABI)
// On x86 targets, PInvoke calls need the size of the stack args in InlinedCallFrame.m_Datum.
// This is because the callee pops stack arguments, and we need to keep track of this during stack
// walking
const unsigned numStkArgBytes = call->fgArgInfo->GetNextSlotNum() * TARGET_POINTER_SIZE;
GenTree* stackBytes = comp->gtNewIconNode(numStkArgBytes, TYP_INT);
GenTreeCall::Use* args = comp->gtNewCallArgs(frameAddr, stackBytes);
#else
GenTreeCall::Use* args = comp->gtNewCallArgs(frameAddr);
#endif
// Insert call to CORINFO_HELP_JIT_PINVOKE_BEGIN
GenTree* helperCall =
comp->gtNewHelperCallNode(CORINFO_HELP_JIT_PINVOKE_BEGIN, TYP_VOID, comp->gtNewCallArgs(frameAddr));
GenTree* helperCall = comp->gtNewHelperCallNode(CORINFO_HELP_JIT_PINVOKE_BEGIN, TYP_VOID, args);

comp->fgMorphTree(helperCall);
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, helperCall));
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/src/vm/i386/PInvokeStubs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ extern @JIT_PInvokeEndRarePath@0:proc

;
; in:
; InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
; before actual InlinedCallFrame data)
;
; InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
; before actual InlinedCallFrame data)
; StackArgumentsSize (edx) = Number of argument bytes pushed on the stack, which will be popped by the callee
;
_JIT_PInvokeBegin@4 PROC public

Expand All @@ -46,7 +46,7 @@ _JIT_PInvokeBegin@4 PROC public
lea eax,[??_7InlinedCallFrame@@6B@]
mov dword ptr [ecx], eax

mov dword ptr [ecx + InlinedCallFrame__m_Datum], 0
mov dword ptr [ecx + InlinedCallFrame__m_Datum], edx


mov eax, esp
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/src/vm/i386/cgenx86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,10 @@ void InlinedCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
return;
}

DWORD stackArgSize = (DWORD) dac_cast<TADDR>(m_Datum);
DWORD stackArgSize = 0;

#if !defined(UNIX_X86_ABI)
stackArgSize = (DWORD) dac_cast<TADDR>(m_Datum);

if (stackArgSize & ~0xFFFF)
{
Expand All @@ -624,6 +627,7 @@ void InlinedCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)

stackArgSize = pMD->GetStackArgumentSize();
}
#endif

/* The return address is just above the "ESP" */
pRD->PCTAddr = PTR_HOST_MEMBER_TADDR(InlinedCallFrame, this,
Expand Down