-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Fix ARM/ARM64 hijacking in tail calls #16039
Changes from all commits
ca5371b
91642b7
176abd4
9fe28cc
77f5aba
8b91fcb
91b5c6d
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 |
---|---|---|
|
@@ -27,7 +27,8 @@ | |
hasPSPSymStackSlot, | ||
hasGenericsInstContextStackSlot, | ||
hasStackBaseregister, | ||
wantsReportOnlyLeaf, | ||
wantsReportOnlyLeaf (AMD64 use only), | ||
hasTailCalls (ARM/ARM64 only) | ||
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. comma is missed. |
||
hasSizeOfEditAndContinuePreservedArea | ||
hasReversePInvokeFrame, | ||
- ReturnKind (Fat: 4 bits) | ||
|
@@ -436,10 +437,14 @@ class GcInfoEncoder | |
// Number of slots preserved during EnC remap | ||
void SetSizeOfEditAndContinuePreservedArea( UINT32 size ); | ||
|
||
#ifdef _TARGET_AMD64_ | ||
// Used to only report a frame once for the leaf function/funclet | ||
// instead of once for each live function/funclet on the stack. | ||
// Called only by RyuJIT (not JIT64) | ||
void SetWantsReportOnlyLeaf(); | ||
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) | ||
void SetHasTailCalls(); | ||
#endif // _TARGET_AMD64_ | ||
|
||
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA | ||
void SetSizeOfStackOutgoingAndScratchArea( UINT32 size ); | ||
|
@@ -491,7 +496,11 @@ class GcInfoEncoder | |
GcInfoArrayList<LifetimeTransition, 64> m_LifetimeTransitions; | ||
|
||
bool m_IsVarArg; | ||
#if defined(_TARGET_AMD64_) | ||
bool m_WantsReportOnlyLeaf; | ||
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) | ||
bool m_HasTailCalls; | ||
#endif // _TARGET_AMD64_ | ||
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. wrong comment for and 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. It seems that the coding convention doc actually doesn't cover the #elif pattern and in coreclr runtime, we use the pattern I've used (the comment on #endif matching the #if and not the #elif comment) |
||
INT32 m_SecurityObjectStackSlot; | ||
INT32 m_GSCookieStackSlot; | ||
UINT32 m_GSCookieValidRangeStart; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,7 @@ set_property(TARGET legacynonjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPOR | |
|
||
set(RYUJIT_LINK_LIBRARIES | ||
utilcodestaticnohost | ||
gcinfo | ||
gcinfo_arm | ||
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. @BruceForstall this is a bug in the legacynonjit CMakeLists.txt. I've hit it when making my changes that are ARM / ARM64 specific and was getting missing symbols due to the fact that x86 version of the gcinfo was being linked in. |
||
) | ||
|
||
if(CLR_CMAKE_PLATFORM_UNIX) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,7 +125,11 @@ GcInfoDecoder::GcInfoDecoder( | |
m_GenericSecretParamIsMD = (headerFlags & GC_INFO_HAS_GENERICS_INST_CONTEXT_MASK) == GC_INFO_HAS_GENERICS_INST_CONTEXT_MD; | ||
m_GenericSecretParamIsMT = (headerFlags & GC_INFO_HAS_GENERICS_INST_CONTEXT_MASK) == GC_INFO_HAS_GENERICS_INST_CONTEXT_MT; | ||
int hasStackBaseRegister = headerFlags & GC_INFO_HAS_STACK_BASE_REGISTER; | ||
#ifdef _TARGET_AMD64_ | ||
m_WantsReportOnlyLeaf = ((headerFlags & GC_INFO_WANTS_REPORT_ONLY_LEAF) != 0); | ||
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) | ||
m_HasTailCalls = ((headerFlags & GC_INFO_HAS_TAILCALLS) != 0); | ||
#endif // _TARGET_AMD64_ | ||
int hasSizeOfEditAndContinuePreservedArea = headerFlags & GC_INFO_HAS_EDIT_AND_CONTINUE_PRESERVED_SLOTS; | ||
|
||
int hasReversePInvokeFrame = false; | ||
|
@@ -527,9 +531,22 @@ bool GcInfoDecoder::GetIsVarArg() | |
return m_IsVarArg; | ||
} | ||
|
||
#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) | ||
bool GcInfoDecoder::HasTailCalls() | ||
{ | ||
_ASSERTE( m_Flags & DECODE_HAS_TAILCALLS ); | ||
return m_HasTailCalls; | ||
} | ||
#endif // _TARGET_ARM_ || _TARGET_ARM64_ | ||
|
||
bool GcInfoDecoder::WantsReportOnlyLeaf() | ||
{ | ||
// Only AMD64 with JIT64 can return false here. | ||
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. Don't you just want to put the whole function under 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. I have intentionally kept it on the GCInfoDecoder and just always return true for non-amd64 platforms. The places in the code that call this method would need to have ifdefs around parts of conditions otherwise and it seemed less readable. |
||
#ifdef _TARGET_AMD64_ | ||
return m_WantsReportOnlyLeaf; | ||
#else | ||
return true; | ||
#endif | ||
} | ||
|
||
UINT32 GcInfoDecoder::GetCodeLength() | ||
|
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.
You should put the
bool WantsReportOnlyLeaf();
above this also under#ifdef