Skip to content

Commit ff010bb

Browse files
committed
Add GC tracking for APX EGPRs for LINUX AMD64
1 parent ecdfb14 commit ff010bb

File tree

13 files changed

+252
-39
lines changed

13 files changed

+252
-39
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class AsmOffsets
1616
// Debug build offsets
1717
#if TARGET_AMD64
1818
#if TARGET_UNIX
19-
public const int SIZEOF__REGDISPLAY = 0x1b90;
19+
public const int SIZEOF__REGDISPLAY = 0x1c10;
2020
public const int OFFSETOF__REGDISPLAY__SP = 0x1b78;
2121
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x1b80;
2222
#else // TARGET_UNIX
@@ -82,7 +82,7 @@ class AsmOffsets
8282
// Release build offsets
8383
#if TARGET_AMD64
8484
#if TARGET_UNIX
85-
public const int SIZEOF__REGDISPLAY = 0x1b80;
85+
public const int SIZEOF__REGDISPLAY = 0x1c00;
8686
public const int OFFSETOF__REGDISPLAY__SP = 0x1b70;
8787
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x1b78;
8888
#else // TARGET_UNIX

src/coreclr/debug/ee/debugger.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16850,6 +16850,26 @@ void FuncEvalFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloa
1685016850
pRD->pCurrentContextPointers->R14 = &(pDE->m_context.R14);
1685116851
pRD->pCurrentContextPointers->R15 = &(pDE->m_context.R15);
1685216852

16853+
#if defined(TARGET_UNIX)
16854+
// This would mean we need to update winnt.h in windows sdk.
16855+
pRD->volatileCurrContextPointers.R16 = &(pDE->m_context.R16);
16856+
pRD->volatileCurrContextPointers.R17 = &(pDE->m_context.R17);
16857+
pRD->volatileCurrContextPointers.R18 = &(pDE->m_context.R18);
16858+
pRD->volatileCurrContextPointers.R19 = &(pDE->m_context.R19);
16859+
pRD->volatileCurrContextPointers.R20 = &(pDE->m_context.R20);
16860+
pRD->volatileCurrContextPointers.R21 = &(pDE->m_context.R21);
16861+
pRD->volatileCurrContextPointers.R22 = &(pDE->m_context.R22);
16862+
pRD->volatileCurrContextPointers.R23 = &(pDE->m_context.R23);
16863+
pRD->volatileCurrContextPointers.R24 = &(pDE->m_context.R24);
16864+
pRD->volatileCurrContextPointers.R25 = &(pDE->m_context.R25);
16865+
pRD->volatileCurrContextPointers.R26 = &(pDE->m_context.R26);
16866+
pRD->volatileCurrContextPointers.R27 = &(pDE->m_context.R27);
16867+
pRD->volatileCurrContextPointers.R28 = &(pDE->m_context.R28);
16868+
pRD->volatileCurrContextPointers.R29 = &(pDE->m_context.R29);
16869+
pRD->volatileCurrContextPointers.R30 = &(pDE->m_context.R30);
16870+
pRD->volatileCurrContextPointers.R31 = &(pDE->m_context.R31);
16871+
#endif // TARGET_UNIX
16872+
1685316873
// SyncRegDisplayToCurrentContext() sets the pRD->SP and pRD->ControlPC on AMD64.
1685416874
SyncRegDisplayToCurrentContext(pRD);
1685516875

src/coreclr/gcinfo/gcinfodumper.cpp

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,28 @@ BOOL GcInfoDumper::ReportPointerRecord (
131131
REG(r13, R13),
132132
REG(r14, R14),
133133
REG(r15, R15),
134+
#if defined(TARGET_UNIX)
135+
#undef REG
136+
#define REG(reg, field) { offsetof(Amd64VolatileContextPointer, field) }
137+
REG(r16, R16),
138+
REG(r17, R17),
139+
REG(r18, R18),
140+
REG(r19, R19),
141+
REG(r20, R20),
142+
REG(r21, R21),
143+
REG(r22, R22),
144+
REG(r23, R23),
145+
REG(r24, R24),
146+
REG(r25, R25),
147+
REG(r26, R26),
148+
REG(r27, R27),
149+
REG(r28, R28),
150+
REG(r29, R29),
151+
REG(r30, R30),
152+
REG(r31, R31),
153+
REG(r16, R16),
154+
REG(r16, R16),
155+
#endif // TARGET_UNIX
134156
#elif defined(TARGET_ARM)
135157
#undef REG
136158
#define REG(reg, field) { offsetof(ArmVolatileContextPointer, field) }
@@ -294,7 +316,7 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
294316

295317
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
296318
BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers);
297-
#else
319+
#else // TARGET_ARM || TARGET_ARM64 || TARGET_RISCV64 || TARGET_LOONGARCH64
298320
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
299321
#endif
300322

@@ -390,7 +412,12 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
390412
{
391413
continue;
392414
}
393-
#endif
415+
#elif defined(TARGET_AMD64) && defined(TARGET_UNIX)
416+
if (ctx != 0 && iEncodedReg > 15)
417+
{
418+
break;
419+
}
420+
#endif // TARGET_AMD64 || TARGET_UNIX
394421
{
395422
_ASSERTE(iReg < nCONTEXTRegisters);
396423
#ifdef TARGET_ARM
@@ -414,6 +441,19 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this
414441
{
415442
pReg = (SIZE_T*)((BYTE*)pRD->pCurrentContext + rgRegisters[iReg].cbContextOffset);
416443
}
444+
#elif defined(TARGET_AMD64) && defined(TARGET_UNIX)
445+
if (ctx == 0 && iReg == 16)
446+
{
447+
pContext = (BYTE*)&(pRD->volatileCurrContextPointers);
448+
}
449+
if (ctx == 0 && iReg >= 16)
450+
{
451+
pReg = *(SIZE_T**)(pContext + rgRegisters[iReg].cbContextOffset);
452+
}
453+
else
454+
{
455+
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
456+
}
417457
#else
418458
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
419459
#endif
@@ -664,6 +704,13 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges (
664704
*(ppCurrentRax + iReg) = &regdisp.pCurrentContext->Rax + iReg;
665705
*(ppCallerRax + iReg) = &regdisp.pCallerContext ->Rax + iReg;
666706
}
707+
#if defined(TARGET_UNIX)
708+
ULONG64 **ppVolatileReg = &regdisp.volatileCurrContextPointers.R16;
709+
for (iReg = 0; iReg < 16; iReg++)
710+
{
711+
*(ppVolatileReg+iReg) = &regdisp.pCurrentContext->R16 + iReg;
712+
}
713+
#endif // TARGET_UNIX
667714
#elif defined(TARGET_ARM)
668715
FILL_REGS(pCurrentContext->R0, 16);
669716
FILL_REGS(pCallerContext->R0, 16);

src/coreclr/inc/gcinfotypes.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,16 +595,16 @@ struct AMD64GcInfoEncoding {
595595
static const int SIZE_OF_STACK_AREA_ENCBASE = 3;
596596
static const int SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE = 4;
597597
static const int REVERSE_PINVOKE_FRAME_ENCBASE = 6;
598-
static const int NUM_REGISTERS_ENCBASE = 2;
598+
static const int NUM_REGISTERS_ENCBASE = 3;
599599
static const int NUM_STACK_SLOTS_ENCBASE = 2;
600600
static const int NUM_UNTRACKED_SLOTS_ENCBASE = 1;
601601
static const int NORM_PROLOG_SIZE_ENCBASE = 5;
602602
static const int NORM_EPILOG_SIZE_ENCBASE = 3;
603603
static const int NORM_CODE_OFFSET_DELTA_ENCBASE = 3;
604604
static const int INTERRUPTIBLE_RANGE_DELTA1_ENCBASE = 6;
605605
static const int INTERRUPTIBLE_RANGE_DELTA2_ENCBASE = 6;
606-
static const int REGISTER_ENCBASE = 3;
607-
static const int REGISTER_DELTA_ENCBASE = 2;
606+
static const int REGISTER_ENCBASE = 5;
607+
static const int REGISTER_DELTA_ENCBASE = 5;
608608
static const int STACK_SLOT_ENCBASE = 6;
609609
static const int STACK_SLOT_DELTA_ENCBASE = 4;
610610
static const int NUM_SAFE_POINTS_ENCBASE = 2;

src/coreclr/inc/regdisp.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,33 @@ typedef struct _Arm64VolatileContextPointer
197197
} Arm64VolatileContextPointer;
198198
#endif //TARGET_ARM64
199199

200+
#if defined(TARGET_AMD64)
201+
typedef struct _Amd64VolatileContextPointer
202+
{
203+
union {
204+
struct {
205+
PDWORD64 R16;
206+
PDWORD64 R17;
207+
PDWORD64 R18;
208+
PDWORD64 R19;
209+
PDWORD64 R20;
210+
PDWORD64 R21;
211+
PDWORD64 R22;
212+
PDWORD64 R23;
213+
PDWORD64 R24;
214+
PDWORD64 R25;
215+
PDWORD64 R26;
216+
PDWORD64 R27;
217+
PDWORD64 R28;
218+
PDWORD64 R29;
219+
PDWORD64 R30;
220+
PDWORD64 R31;
221+
};
222+
PDWORD64 R[16];
223+
};
224+
} Amd64VolatileContextPointer;
225+
#endif //TARGET_AMD64
226+
200227
#if defined(TARGET_LOONGARCH64)
201228
typedef struct _LoongArch64VolatileContextPointer
202229
{
@@ -253,6 +280,10 @@ struct REGDISPLAY : public REGDISPLAY_BASE {
253280
LoongArch64VolatileContextPointer volatileCurrContextPointers;
254281
#endif
255282

283+
#if defined(TARGET_AMD64) && defined(TARGET_UNIX)
284+
Amd64VolatileContextPointer volatileCurrContextPointers;
285+
#endif
286+
256287
#ifdef TARGET_RISCV64
257288
RiscV64VolatileContextPointer volatileCurrContextPointers;
258289
#endif
@@ -563,7 +594,11 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
563594
// Fill volatile context pointers. They can be used by GC in the case of the leaf frame
564595
for (int i=0; i < 18; i++)
565596
pRD->volatileCurrContextPointers.X[i] = &pctx->X[i];
566-
#elif defined(TARGET_LOONGARCH64) // TARGET_ARM64
597+
#elif defined(TARGET_AMD64) && defined(TARGET_UNIX) // TARGET_ARM64
598+
// Fill volatile context pointers. They can be used by GC in the case of the leaf frame
599+
for (int i=0; i < 16; i++)
600+
pRD->volatileCurrContextPointers.R[i] = &pctx->R[i];
601+
#elif defined(TARGET_LOONGARCH64) // TARGET_ADM64 && TARGET_UNIX
567602
pRD->volatileCurrContextPointers.A0 = &pctx->A0;
568603
pRD->volatileCurrContextPointers.A1 = &pctx->A1;
569604
pRD->volatileCurrContextPointers.A2 = &pctx->A2;
@@ -664,7 +699,7 @@ inline size_t * getRegAddr (unsigned regNum, PTR_CONTEXT regs)
664699

665700
return (PTR_size_t)(PTR_BYTE(regs) + OFFSET_OF_REGISTERS[regNum]);
666701
#elif defined(TARGET_AMD64)
667-
_ASSERTE(regNum < 16);
702+
_ASSERTE(regNum < 32);
668703
return (size_t *)&regs->Rax + regNum;
669704
#elif defined(TARGET_ARM)
670705
_ASSERTE(regNum < 16);

src/coreclr/nativeaot/Runtime/amd64/AsmOffsetsCpu.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,28 @@ PLAT_ASM_OFFSET(90, REGDISPLAY, Xmm)
7373

7474
#else // !UNIX_AMD64_ABI
7575

76-
PLAT_ASM_SIZEOF(190, ExInfo)
76+
PLAT_ASM_SIZEOF(210, ExInfo)
7777
PLAT_ASM_OFFSET(0, ExInfo, m_pPrevExInfo)
7878
PLAT_ASM_OFFSET(8, ExInfo, m_pExContext)
7979
PLAT_ASM_OFFSET(10, ExInfo, m_exception)
8080
PLAT_ASM_OFFSET(18, ExInfo, m_kind)
8181
PLAT_ASM_OFFSET(19, ExInfo, m_passNumber)
8282
PLAT_ASM_OFFSET(1c, ExInfo, m_idxCurClause)
8383
PLAT_ASM_OFFSET(20, ExInfo, m_frameIter)
84-
PLAT_ASM_OFFSET(188, ExInfo, m_notifyDebuggerSP)
84+
PLAT_ASM_OFFSET(208, ExInfo, m_notifyDebuggerSP)
8585

8686
PLAT_ASM_OFFSET(0, PInvokeTransitionFrame, m_RIP)
8787
PLAT_ASM_OFFSET(8, PInvokeTransitionFrame, m_FramePointer)
8888
PLAT_ASM_OFFSET(10, PInvokeTransitionFrame, m_pThread)
8989
PLAT_ASM_OFFSET(18, PInvokeTransitionFrame, m_Flags)
9090
PLAT_ASM_OFFSET(20, PInvokeTransitionFrame, m_PreservedRegs)
9191

92-
PLAT_ASM_SIZEOF(168, StackFrameIterator)
92+
PLAT_ASM_SIZEOF(1e8, StackFrameIterator)
9393
PLAT_ASM_OFFSET(10, StackFrameIterator, m_FramePointer)
9494
PLAT_ASM_OFFSET(18, StackFrameIterator, m_ControlPC)
9595
PLAT_ASM_OFFSET(20, StackFrameIterator, m_RegDisplay)
96-
PLAT_ASM_OFFSET(158, StackFrameIterator, m_OriginalControlPC)
97-
PLAT_ASM_OFFSET(160, StackFrameIterator, m_pPreviousTransitionFrame)
96+
PLAT_ASM_OFFSET(1d8, StackFrameIterator, m_OriginalControlPC)
97+
PLAT_ASM_OFFSET(1e0, StackFrameIterator, m_pPreviousTransitionFrame)
9898

9999
PLAT_ASM_SIZEOF(50, PAL_LIMITED_CONTEXT)
100100
PLAT_ASM_OFFSET(0, PAL_LIMITED_CONTEXT, IP)
@@ -110,8 +110,8 @@ PLAT_ASM_OFFSET(38, PAL_LIMITED_CONTEXT, R13)
110110
PLAT_ASM_OFFSET(40, PAL_LIMITED_CONTEXT, R14)
111111
PLAT_ASM_OFFSET(48, PAL_LIMITED_CONTEXT, R15)
112112

113-
PLAT_ASM_SIZEOF(88, REGDISPLAY)
114-
PLAT_ASM_OFFSET(78, REGDISPLAY, SP)
113+
PLAT_ASM_SIZEOF(108, REGDISPLAY)
114+
PLAT_ASM_OFFSET(f8, REGDISPLAY, SP)
115115

116116
PLAT_ASM_OFFSET(18, REGDISPLAY, pRbx)
117117
PLAT_ASM_OFFSET(20, REGDISPLAY, pRbp)

src/coreclr/nativeaot/Runtime/regdisplay.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ struct REGDISPLAY
2727
PTR_uintptr_t pR13;
2828
PTR_uintptr_t pR14;
2929
PTR_uintptr_t pR15;
30+
#if defined(TARGET_UNIX)
31+
PTR_uintptr_t pR16;
32+
PTR_uintptr_t pR17;
33+
PTR_uintptr_t pR18;
34+
PTR_uintptr_t pR19;
35+
PTR_uintptr_t pR20;
36+
PTR_uintptr_t pR21;
37+
PTR_uintptr_t pR22;
38+
PTR_uintptr_t pR23;
39+
PTR_uintptr_t pR24;
40+
PTR_uintptr_t pR25;
41+
PTR_uintptr_t pR26;
42+
PTR_uintptr_t pR27;
43+
PTR_uintptr_t pR28;
44+
PTR_uintptr_t pR29;
45+
PTR_uintptr_t pR30;
46+
PTR_uintptr_t pR31;
47+
#endif //TARGET_UNIX
3048
#endif // TARGET_AMD64
3149

3250
uintptr_t SP;

src/coreclr/pal/inc/pal.h

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,24 +1464,29 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
14641464
M512 Zmm31;
14651465
};
14661466

1467-
struct
1467+
// XSTATE_APX
1468+
union
14681469
{
1469-
DWORD64 R16;
1470-
DWORD64 R17;
1471-
DWORD64 R18;
1472-
DWORD64 R19;
1473-
DWORD64 R20;
1474-
DWORD64 R21;
1475-
DWORD64 R22;
1476-
DWORD64 R23;
1477-
DWORD64 R24;
1478-
DWORD64 R25;
1479-
DWORD64 R26;
1480-
DWORD64 R27;
1481-
DWORD64 R28;
1482-
DWORD64 R29;
1483-
DWORD64 R30;
1484-
DWORD64 R31;
1470+
struct
1471+
{
1472+
DWORD64 R16;
1473+
DWORD64 R17;
1474+
DWORD64 R18;
1475+
DWORD64 R19;
1476+
DWORD64 R20;
1477+
DWORD64 R21;
1478+
DWORD64 R22;
1479+
DWORD64 R23;
1480+
DWORD64 R24;
1481+
DWORD64 R25;
1482+
DWORD64 R26;
1483+
DWORD64 R27;
1484+
DWORD64 R28;
1485+
DWORD64 R29;
1486+
DWORD64 R30;
1487+
DWORD64 R31;
1488+
};
1489+
DWORD64 R[16];
14851490
};
14861491

14871492
} CONTEXT, *PCONTEXT, *LPCONTEXT;

src/coreclr/unwinder/amd64/unwinder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ BOOL DacUnwindStackFrame(CONTEXT * pContext, KNONVOLATILE_CONTEXT_POINTERS* pCon
242242

243243
if (res && pContextPointers)
244244
{
245-
for (int i = 0; i < 16; i++)
245+
for (int i = 0; i < 32; i++)
246246
{
247247
*(&pContextPointers->Rax + i) = &pContext->Rax + i;
248248
}

src/coreclr/vm/amd64/asmconstants.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,13 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__Xmm15
419419
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__VectorRegister
420420
== offsetof(CONTEXT, VectorRegister[0]));
421421

422+
// TBD APX: is this needed for unix?
423+
// #if defined(UNIX_AMD64_ABI) && !defined(HOST_WINDOWS)
424+
// #define OFFSETOF__CONTEXT__R16 (8*6 + 4*2 + 2*6 + 4 + 8*6 + 8*16 + 8 + 2*16 + 8*16 + 16*16 + 96 + 128*26 + 8*8 + 8*8*7 + 8*16*16 + 8*8*8 + 8*32*16 + 8*64*16)
425+
// ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__R16
426+
// == offsetof(CONTEXT, R16));
427+
// #endif // UNIX_AMD64_ABI && !HOST_WINDOWS
428+
422429
#define SIZEOF__FaultingExceptionFrame (0x20 + SIZEOF__CONTEXT + 16)
423430
ASMCONSTANTS_C_ASSERT(SIZEOF__FaultingExceptionFrame
424431
== sizeof(FaultingExceptionFrame));

0 commit comments

Comments
 (0)