Skip to content

Commit 73da9d2

Browse files
authored
Merge branch 'main' into feature/MDCS-to-UCOA-pattern
2 parents ebabb51 + 286dc15 commit 73da9d2

58 files changed

Lines changed: 1597 additions & 75 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/design/datacontracts/RuntimeTypeSystem.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ partial interface IRuntimeTypeSystem : IContract
5151

5252
// True if the MethodTable is the sentinel value associated with unallocated space in the managed heap
5353
public virtual bool IsFreeObjectMethodTable(TypeHandle typeHandle);
54+
// True if the MethodTable is the System.Object MethodTable (g_pObjectClass)
55+
public virtual bool IsObject(TypeHandle typeHandle);
5456
public virtual bool IsString(TypeHandle typeHandle);
5557
// True if the type is a GC-collectable object reference.
5658
public virtual bool IsObjRef(TypeHandle typeHandle);
@@ -448,7 +450,8 @@ The contract depends on the following globals
448450
| Global name | Meaning |
449451
| --- | --- |
450452
| `ContinuationMethodTable` | A pointer to the address of the base `Continuation` `MethodTable`, or null if no continuations have been created
451-
| `FreeObjectMethodTablePointer` | A pointer to the address of a `MethodTable` used by the GC to indicate reclaimed memory
453+
| `FreeObjectMethodTable` | A pointer to the address of a `MethodTable` used by the GC to indicate reclaimed memory
454+
| `ObjectMethodTable` | A pointer to the address of the `System.Object` `MethodTable` (`g_pObjectClass`)
452455
| `StaticsPointerMask` | For masking out a bit of DynamicStaticsInfo pointer fields
453456
| `ArrayBaseSize` | The base size of an array object; used to compute multidimensional array rank from `MethodTable::BaseSize`
454457

@@ -521,6 +524,7 @@ Contracts used:
521524
private readonly Dictionary<TargetPointer, MethodTable_1> _methodTables;
522525

523526
internal TargetPointer FreeObjectMethodTablePointer {get; }
527+
internal TargetPointer ObjectMethodTablePointer {get; }
524528
internal TargetPointer ContinuationMethodTablePointer {get; }
525529

526530
public TypeHandle GetTypeHandle(TargetPointer typeHandlePointer)
@@ -581,6 +585,8 @@ Contracts used:
581585

582586
public bool IsFreeObjectMethodTable(TypeHandle TypeHandle) => FreeObjectMethodTablePointer == TypeHandle.Address;
583587

588+
public bool IsObject(TypeHandle TypeHandle) => ObjectMethodTablePointer != TargetPointer.Null && ObjectMethodTablePointer == TypeHandle.Address;
589+
584590
public bool IsString(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsString;
585591

586592
public bool IsObjRef(TypeHandle typeHandle) => // Returns true if GetSignatureCorElementType returns Class, Array, or SzArray.

src/coreclr/debug/daccess/dacdbiimpl.cpp

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,28 +2513,13 @@ void DacDbiInterfaceImpl::TypeHandleToBasicTypeInfo(TypeHandle
25132513
} // DacDbiInterfaceImpl::TypeHandleToBasicTypeInfo
25142514

25152515

2516-
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetObjectExpandedTypeInfoFromID(AreValueTypesBoxed boxed, COR_TYPEID id, OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo)
2517-
{
2518-
DD_ENTER_MAY_THROW;
2519-
2520-
HRESULT hr = S_OK;
2521-
EX_TRY
2522-
{
2523-
2524-
TypeHandleToExpandedTypeInfoImpl(boxed, TypeHandle::FromPtr(TO_TADDR(id.token1)), pTypeInfo);
2525-
}
2526-
EX_CATCH_HRESULT(hr);
2527-
return hr;
2528-
}
2529-
25302516
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetObjectExpandedTypeInfo(AreValueTypesBoxed boxed, CORDB_ADDRESS addr, OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo)
25312517
{
25322518
DD_ENTER_MAY_THROW;
25332519

25342520
HRESULT hr = S_OK;
25352521
EX_TRY
25362522
{
2537-
25382523
PTR_Object obj(TO_TADDR(addr));
25392524
TypeHandleToExpandedTypeInfoImpl(boxed, obj->GetGCSafeTypeHandle(), pTypeInfo);
25402525
}
@@ -2543,16 +2528,14 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetObjectExpandedTypeInfo(AreValu
25432528
}
25442529

25452530
// DacDbi API: use a type handle to get the information needed to create the corresponding RS CordbType instance
2546-
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_TypeHandle vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo)
2531+
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, CORDB_ADDRESS vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo)
25472532
{
25482533
DD_ENTER_MAY_THROW;
25492534

25502535
HRESULT hr = S_OK;
25512536
EX_TRY
25522537
{
2553-
2554-
2555-
TypeHandle typeHandle = TypeHandle::FromPtr(vmTypeHandle.GetDacPtr());
2538+
TypeHandle typeHandle = TypeHandle::FromPtr((TADDR)vmTypeHandle);
25562539
TypeHandleToExpandedTypeInfoImpl(boxed, typeHandle, pTypeInfo);
25572540
}
25582541
EX_CATCH_HRESULT(hr);
@@ -2564,6 +2547,7 @@ void DacDbiInterfaceImpl::TypeHandleToExpandedTypeInfoImpl(AreValueTypesBoxed
25642547
TypeHandle typeHandle,
25652548
DebuggerIPCE_ExpandedTypeData * pTypeInfo)
25662549
{
2550+
*pTypeInfo = {};
25672551
pTypeInfo->elementType = GetElementType(typeHandle);
25682552

25692553
switch (pTypeInfo->elementType)
@@ -2776,20 +2760,16 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetMethodDescParams(VMPTR_MethodD
27762760
EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER
27772761
{
27782762
// Fill in the struct using the TypeHandle of the current type parameter if we can.
2779-
VMPTR_TypeHandle vmTypeHandle = VMPTR_TypeHandle::NullPtr();
2780-
vmTypeHandle.SetDacTargetPtr(thCurrent.AsTAddr());
27812763
IfFailThrow(TypeHandleToExpandedTypeInfo(NoValueTypeBoxing,
2782-
vmTypeHandle,
2764+
(CORDB_ADDRESS)thCurrent.AsTAddr(),
27832765
&((*pGenericTypeParams)[i])));
27842766
}
27852767
EX_CATCH_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER
27862768
{
27872769
// On failure for a particular type, default it back to System.__Canon.
2788-
VMPTR_TypeHandle vmTHCanon = VMPTR_TypeHandle::NullPtr();
27892770
TypeHandle thCanon = TypeHandle(g_pCanonMethodTableClass);
2790-
vmTHCanon.SetDacTargetPtr(thCanon.AsTAddr());
27912771
IfFailThrow(TypeHandleToExpandedTypeInfo(NoValueTypeBoxing,
2792-
vmTHCanon,
2772+
(CORDB_ADDRESS)thCanon.AsTAddr(),
27932773
&((*pGenericTypeParams)[i])));
27942774
}
27952775
EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER
@@ -3214,11 +3194,8 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetTypeHandleParams(VMPTR_TypeHan
32143194
// collect type information for each type parameter
32153195
for (unsigned int i = 0; i < pParams->Count(); ++i)
32163196
{
3217-
VMPTR_TypeHandle thInst = VMPTR_TypeHandle::NullPtr();
3218-
thInst.SetDacTargetPtr(typeHandle.GetInstantiation()[i].AsTAddr());
3219-
32203197
IfFailThrow(TypeHandleToExpandedTypeInfo(NoValueTypeBoxing,
3221-
thInst,
3198+
(CORDB_ADDRESS)typeHandle.GetInstantiation()[i].AsTAddr(),
32223199
&((*pParams)[i])));
32233200
}
32243201

@@ -5947,15 +5924,11 @@ void DacDbiInterfaceImpl::InitObjectData(PTR_Object objPtr,
59475924
DebuggerIPCE_ObjectData * pObjectData)
59485925
{
59495926
_ASSERTE(pObjectData != NULL);
5950-
// @todo - this is still dangerous because the object may still be invalid.
5951-
VMPTR_TypeHandle vmTypeHandle = VMPTR_TypeHandle::NullPtr();
5952-
vmTypeHandle.SetDacTargetPtr(objPtr->GetGCSafeTypeHandle().AsTAddr());
5953-
59545927
// Save basic object info.
59555928
pObjectData->objSize = objPtr->GetSize();
59565929
pObjectData->objOffsetToVars = dac_cast<TADDR>((objPtr)->GetData()) - dac_cast<TADDR>(objPtr);
59575930

5958-
IfFailThrow(TypeHandleToExpandedTypeInfo(AllBoxed, vmTypeHandle, &(pObjectData->objTypeData)));
5931+
IfFailThrow(TypeHandleToExpandedTypeInfo(AllBoxed, (CORDB_ADDRESS)objPtr->GetGCSafeTypeHandle().AsTAddr(), &(pObjectData->objTypeData)));
59595932

59605933
// If this is a string object, set the type to ELEMENT_TYPE_STRING.
59615934
if (objPtr->GetGCSafeMethodTable() == g_pStringClass)

src/coreclr/debug/daccess/dacdbiimpl.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,10 @@ class DacDbiInterfaceImpl :
243243
HRESULT STDMETHODCALLTYPE GetObjectExpandedTypeInfo(AreValueTypesBoxed boxed, CORDB_ADDRESS addr, OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo);
244244

245245

246-
HRESULT STDMETHODCALLTYPE GetObjectExpandedTypeInfoFromID(AreValueTypesBoxed boxed, COR_TYPEID id, OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo);
247-
248-
249246
// @dbgtodo Microsoft inspection: change DebuggerIPCE_ExpandedTypeData to DacDbiStructures type hierarchy
250247
// once ICorDebugType and ICorDebugClass are DACized
251248
// use a type handle to get the information needed to create the corresponding RS CordbType instance
252-
HRESULT STDMETHODCALLTYPE TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_TypeHandle vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo);
249+
HRESULT STDMETHODCALLTYPE TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, CORDB_ADDRESS vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo);
253250

254251
// Get type handle for a TypeDef token, if one exists. For generics this returns the open type.
255252
HRESULT STDMETHODCALLTYPE GetTypeHandle(VMPTR_Module vmModule, mdTypeDef metadataToken, OUT VMPTR_TypeHandle * pRetVal);

src/coreclr/debug/di/process.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2398,7 +2398,7 @@ HRESULT CordbProcess::GetTypeForTypeID(COR_TYPEID id, ICorDebugType **ppType)
23982398
EX_TRY
23992399
{
24002400
DebuggerIPCE_ExpandedTypeData data;
2401-
IfFailThrow(GetDAC()->GetObjectExpandedTypeInfoFromID(AllBoxed, id, &data));
2401+
IfFailThrow(GetDAC()->TypeHandleToExpandedTypeInfo(AllBoxed, id.token1, &data));
24022402

24032403
CordbType *type = 0;
24042404
hr = CordbType::TypeDataToType(GetAppDomain(), &data, &type);

src/coreclr/debug/di/rstype.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1163,8 +1163,11 @@ HRESULT CordbType::TypeDataToType(CordbAppDomain *pAppDomain, DebuggerIPCE_Basic
11631163

11641164
{
11651165
RSLockHolder lockHolder(pProcess->GetProcessLock());
1166+
CORDB_ADDRESS vmTypeHandleRaw = 0;
1167+
static_assert(sizeof(data->vmTypeHandle) <= sizeof(vmTypeHandleRaw), "VMPTR_TypeHandle is larger than CORDB_ADDRESS");
1168+
memcpy(&vmTypeHandleRaw, &data->vmTypeHandle, sizeof(data->vmTypeHandle));
11661169
IfFailThrow(pProcess->GetDAC()->TypeHandleToExpandedTypeInfo(NoValueTypeBoxing, // could be generics which are never boxed
1167-
data->vmTypeHandle,
1170+
vmTypeHandleRaw,
11681171
&typeInfo));
11691172
}
11701173

src/coreclr/debug/inc/dacdbiinterface.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,14 +1549,11 @@ IDacDbiInterface : public IUnknown
15491549
// vmTypeHandle - type handle for the type
15501550
// output: pTypeInfo - holds information needed to build the corresponding CordbType
15511551
//
1552-
virtual HRESULT STDMETHODCALLTYPE TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_TypeHandle vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
1552+
virtual HRESULT STDMETHODCALLTYPE TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, CORDB_ADDRESS vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
15531553

15541554
virtual HRESULT STDMETHODCALLTYPE GetObjectExpandedTypeInfo(AreValueTypesBoxed boxed, CORDB_ADDRESS addr, OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
15551555

15561556

1557-
virtual HRESULT STDMETHODCALLTYPE GetObjectExpandedTypeInfoFromID(AreValueTypesBoxed boxed, COR_TYPEID id, OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
1558-
1559-
15601557
// Get type handle for a TypeDef token, if one exists. For generics this returns the open type.
15611558
// Note there is no guarantee the returned handle will be fully restored (in pre-jit scenarios),
15621559
// only that it exists. Later functions that use this type handle should fail if they require

src/coreclr/debug/inc/dacdbistructures.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,12 @@ class MSLAYOUT EnCHangingFieldInfo
648648
// NoValueTypeBoxing:
649649
// TypeHandleToExpandedTypeInfo is also used to report type parameters,
650650
// and in this case none of the types are considered boxed (
651-
enum AreValueTypesBoxed { NoValueTypeBoxing, OnlyPrimitivesUnboxed, AllBoxed };
651+
enum AreValueTypesBoxed
652+
{
653+
NoValueTypeBoxing = 0,
654+
OnlyPrimitivesUnboxed = 1,
655+
AllBoxed = 2
656+
};
652657

653658
// TypeRefData is used for resolving a type reference (see code:CordbModule::ResolveTypeRef and
654659
// code:DacDbiInterfaceImpl::ResolveTypeReference) to store relevant information about the type

src/coreclr/inc/cfi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ enum CFI_OPCODE
99
{
1010
CFI_ADJUST_CFA_OFFSET, // Offset is adjusted relative to the current one.
1111
CFI_DEF_CFA_REGISTER, // New register is used to compute CFA
12-
CFI_REL_OFFSET // Register is saved at offset from the current CFA
12+
CFI_REL_OFFSET, // Register is saved at offset from the current CFA
13+
CFI_NEGATE_RA_STATE, // Sign the return address in lr with paciasp
1314
};
1415

1516
struct CFI_CODE

src/coreclr/inc/dacdbi.idl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,8 @@ interface IDacDbiInterface : IUnknown
310310
[in] VMPTR_TypeHandle vmThApprox,
311311
[out] DacDbiArrayList_FieldData * pFieldList,
312312
[out] SIZE_T * pObjectSize);
313-
HRESULT TypeHandleToExpandedTypeInfo([in] AreValueTypesBoxed boxed, [in] VMPTR_TypeHandle vmTypeHandle, [out] struct DebuggerIPCE_ExpandedTypeData * pTypeInfo);
313+
HRESULT TypeHandleToExpandedTypeInfo([in] AreValueTypesBoxed boxed, [in] CORDB_ADDRESS vmTypeHandle, [out] struct DebuggerIPCE_ExpandedTypeData * pTypeInfo);
314314
HRESULT GetObjectExpandedTypeInfo([in] AreValueTypesBoxed boxed, [in] CORDB_ADDRESS addr, [out] struct DebuggerIPCE_ExpandedTypeData * pTypeInfo);
315-
HRESULT GetObjectExpandedTypeInfoFromID([in] AreValueTypesBoxed boxed, [in] COR_TYPEID id, [out] struct DebuggerIPCE_ExpandedTypeData * pTypeInfo);
316315
HRESULT GetTypeHandle([in] VMPTR_Module vmModule, [in] mdTypeDef metadataToken, [out] VMPTR_TypeHandle * pRetVal);
317316
HRESULT GetApproxTypeHandle([in] TypeInfoList * pTypeData, [out] VMPTR_TypeHandle * pRetVal);
318317
HRESULT GetExactTypeHandle([in] struct DebuggerIPCE_ExpandedTypeData * pTypeData, [in] ArgInfoList * pArgInfo, [out] VMPTR_TypeHandle * pVmTypeHandle);

src/coreclr/jit/codegenarm64.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ void CodeGen::genPopCalleeSavedRegistersAndFreeLclFrame(bool jmpEpilog)
251251
}
252252
}
253253

254+
if (JitConfig.JitPacEnabled() != 0)
255+
{
256+
GetEmitter()->emitPacInEpilog();
257+
}
258+
254259
// For OSR, we must also adjust the SP to remove the Tier0 frame.
255260
//
256261
if (m_compiler->opts.IsOSR())
@@ -487,9 +492,10 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1,
487492

488493
if ((spOffset == 0) && (spDelta >= -512))
489494
{
490-
// We can use pre-indexed addressing.
495+
// We can use pre-indexed addressing when the stack adjustment fits in the instruction.
491496
// stp REG, REG + 1, [SP, #spDelta]!
492497
// 64-bit STP offset range: -512 to 504, multiple of 8.
498+
assert(reg1 != REG_LR);
493499
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, reg1, reg2, REG_SPBASE, spDelta, INS_OPTS_PRE_INDEX);
494500
m_compiler->unwindSaveRegPairPreindexed(reg1, reg2, spDelta);
495501

@@ -511,6 +517,8 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1,
511517
// 64-bit STP offset range: -512 to 504, multiple of 8.
512518
assert(spOffset <= 504);
513519
assert((spOffset % 8) == 0);
520+
assert(reg1 != REG_LR);
521+
514522
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, reg1, reg2, REG_SPBASE, spOffset);
515523

516524
if (TargetOS::IsUnix && m_compiler->generateCFIUnwindCodes())
@@ -622,6 +630,7 @@ void CodeGen::genRestoreRegPair(regNumber reg1,
622630
assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned
623631
assert(genIsValidFloatReg(reg1) == genIsValidFloatReg(reg2)); // registers must be both general-purpose, or both
624632
// FP/SIMD
633+
assert(reg1 != REG_LR);
625634

626635
if (spDelta != 0)
627636
{
@@ -1384,6 +1393,11 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
13841393

13851394
m_compiler->unwindBegProlog();
13861395

1396+
if (JitConfig.JitPacEnabled() != 0)
1397+
{
1398+
GetEmitter()->emitPacInProlog();
1399+
}
1400+
13871401
regMaskTP maskSaveRegsFloat = genFuncletInfo.fiSaveRegs & RBM_ALLFLOAT;
13881402
regMaskTP maskSaveRegsInt = genFuncletInfo.fiSaveRegs & ~maskSaveRegsFloat;
13891403

@@ -1669,6 +1683,11 @@ void CodeGen::genFuncletEpilog(BasicBlock* /* block */)
16691683
}
16701684
}
16711685

1686+
if (JitConfig.JitPacEnabled() != 0)
1687+
{
1688+
GetEmitter()->emitPacInEpilog();
1689+
}
1690+
16721691
inst_RV(INS_ret, REG_LR, TYP_I_IMPL);
16731692
m_compiler->unwindReturn(REG_LR);
16741693

@@ -5675,6 +5694,20 @@ void CodeGen::genOSRHandleTier0CalleeSavedRegistersAndFrame()
56755694
genRestoreRegPair(REG_FP, REG_LR, REG_FP, 0, 0, false, REG_IP1, nullptr,
56765695
/* reportUnwindData */ false);
56775696

5697+
if (JitConfig.JitPacEnabled() != 0)
5698+
{
5699+
// Tier0 signed LR with the Tier0 caller SP before allocating its frame.
5700+
// Recreate that SP from the current Tier0 body SP so we can authenticate
5701+
// LR before the OSR prolog later re-signs it with the OSR SP.
5702+
// TODO-PAC: Avoid authenticating and re-signing so the signing SP will point to the start of the frame. It may
5703+
// require adding a phantom pac_sign_lr unwind code.
5704+
genInstrWithConstant(INS_add, EA_PTRSIZE, REG_IP0, REG_SPBASE, patchpointInfo->TotalFrameSize(), REG_IP0,
5705+
/* inUnwindRegion */ false);
5706+
GetEmitter()->emitIns_Mov(INS_mov, EA_PTRSIZE, REG_IP1, REG_LR, /* canSkip */ false);
5707+
GetEmitter()->emitIns(TargetOS::IsWindows ? INS_autib1716 : INS_autia1716);
5708+
GetEmitter()->emitIns_Mov(INS_mov, EA_PTRSIZE, REG_LR, REG_IP1, /* canSkip */ false);
5709+
}
5710+
56785711
// Emit phantom unwind data for the tier0 frame.
56795712
m_compiler->unwindAllocStack(patchpointInfo->TotalFrameSize());
56805713
// Emit nops to make the prolog 1:1 in unwind codes to instructions. This

0 commit comments

Comments
 (0)