Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
b98afa8
Implement GetThreadStoreData in cDAC
elinor-fung May 16, 2024
890f9c6
Add placeholder for getting thread data
elinor-fung May 17, 2024
41ba95c
Apply suggestions from code review
elinor-fung May 23, 2024
29214f0
WIP: Metadata contract
lambdageek May 14, 2024
8beced0
Merge remote-tracking branch 'elinor-fung/cdac-threadstore' into cdac…
lambdageek May 29, 2024
5213286
fix build
lambdageek May 29, 2024
622e01a
WIP: ValidateMethodTable
lambdageek May 29, 2024
e112416
DataCache.GetOrAdd
elinor-fung May 29, 2024
ae1eac9
wip
lambdageek May 30, 2024
79ea0d4
Merge remote-tracking branch 'elinor-fung/cdac-threadstore' into cdac…
lambdageek May 30, 2024
5c696da
checkpoint: ValidateWithPossibleAV
lambdageek May 30, 2024
6eaf80f
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek May 30, 2024
3a7808d
checkpoint EEClass from MethodTable
lambdageek May 31, 2024
66e5476
checkpoint: ValidateMethodTablePointer
lambdageek May 31, 2024
95914b8
cp: delegate from legacy dac
lambdageek May 31, 2024
2b8fda3
add Metadata to runtime contract descriptor
lambdageek Jun 11, 2024
5c7d2ac
checkpoint: more MethodTable fields
lambdageek Jun 12, 2024
7be5c60
checkpoint GetMethodTableData implemented
lambdageek Jun 13, 2024
30b7b26
checkpoint: same answer as legacy dac
lambdageek Jun 13, 2024
187bcbe
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 14, 2024
f0d1fcb
new flags for statics
lambdageek Jun 14, 2024
c53db36
fix GCC build
lambdageek Jun 14, 2024
b70bb1d
WIP: opaque MethodTableHandle
lambdageek Jun 17, 2024
a65fd50
Add contract accessors for MethodTableHandle
lambdageek Jun 18, 2024
6f844bf
fixup
lambdageek Jun 18, 2024
76e0384
simplify FreeObjectMethodTable handling
lambdageek Jun 18, 2024
cdb7543
cleanup
lambdageek Jun 18, 2024
78830ea
fixup
lambdageek Jun 18, 2024
fbbd45b
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 18, 2024
32665b2
[dac] Return canonical MethodTable instead of EEClass
lambdageek Jun 18, 2024
acf8436
Delete unreferenced MethodTable flags
lambdageek Jun 18, 2024
f246c86
add Metadata contract doc; fixups
lambdageek Jun 19, 2024
8409f3e
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 20, 2024
08d069a
rename DacpMethodTableData:klass field
lambdageek Jun 20, 2024
674655f
document GetMethodTableData string baseSize adjustment
lambdageek Jun 20, 2024
2ae4625
Apply suggestions from code review
lambdageek Jun 20, 2024
e18a2be
fix typo
lambdageek Jun 21, 2024
846e779
rename flag to ContainsGCPointers
lambdageek Jun 21, 2024
383af83
[vm] rename ContainsPointers flag to ContainsGCPointers
lambdageek Jun 21, 2024
0f8c7f1
code style suggestions from code review
lambdageek Jun 21, 2024
7a337c1
BUGFIX: read DwFlags2 from the correct offset
lambdageek Jun 21, 2024
a7c8158
hide utility methods
lambdageek Jun 21, 2024
f4a3493
remove EEClass_1 struct
lambdageek Jun 21, 2024
10624c7
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 21, 2024
65cc531
rename data descriptor members to remove prefixes
lambdageek Jun 21, 2024
d526087
cleanup the contract docs
lambdageek Jun 21, 2024
0a4112e
remove hungariant notation prefixes from data descriptors
lambdageek Jun 24, 2024
1071ca4
DAC: always set wNumVirtuals and wNumVtableSlots to 0
lambdageek Jun 25, 2024
6c5235c
Remove NumVirtuals and NumVtableSlots from Metadata.md
lambdageek Jun 27, 2024
95b728a
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 28, 2024
6573e14
"untrusted" -> "non-validated"
lambdageek Jun 28, 2024
8596892
merge fixup
lambdageek Jun 28, 2024
6eabf42
remove #if 0
lambdageek Jun 28, 2024
4d3200d
cleanup
lambdageek Jun 28, 2024
2e66740
pull test target helpers out
lambdageek Jun 28, 2024
8533148
Add one FreeObjectMethodTable unit test
lambdageek Jul 1, 2024
77cf405
clean up the test helpers a bit
lambdageek Jul 2, 2024
f9bce4c
validate that a mock system object is a valid method table
lambdageek Jul 2, 2024
3721992
code review feedback and more tests:
lambdageek Jul 2, 2024
1af7c80
Update src/coreclr/gc/env/gcenv.object.h
lambdageek Jul 2, 2024
993ae1d
Update src/native/managed/cdacreader/src/Contracts/Metadata_1.MethodT…
lambdageek Jul 2, 2024
f04d880
Address code review feedback
lambdageek Jul 2, 2024
76859d1
move non-validated MethodTable handling to a separate class
lambdageek Jul 2, 2024
a12a407
clear up ComponentSize contract spec and impl
lambdageek Jul 2, 2024
9cf4c5a
rename Metadata -> RuntimeTypeSystem
lambdageek Jul 3, 2024
1814848
add validation failure test; change validation to throw InvalidOperat…
lambdageek Jul 3, 2024
89f98a3
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jul 3, 2024
a0989fa
Update src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_…
lambdageek Jul 3, 2024
617bf62
spellcheck
lambdageek Jul 3, 2024
815ff0d
Merge branch 'cdac-wip' of github.com:lambdageek/runtime into cdac-wip
lambdageek Jul 3, 2024
1ab4f08
Add a generic instance test
lambdageek Jul 3, 2024
ee3a362
add array instance test
lambdageek Jul 3, 2024
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
Prev Previous commit
Next Next commit
checkpoint GetMethodTableData implemented
  • Loading branch information
lambdageek committed Jun 13, 2024
commit 7be5c6079c795a028b0458502eedbf1fc5b6ff95
11 changes: 11 additions & 0 deletions src/coreclr/debug/runtimeinfo/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,24 @@ CDAC_TYPE_FIELD(MethodTable, /*uint32*/, DwFlags2, cdac_offsets<MethodTable>::m_
CDAC_TYPE_FIELD(MethodTable, /*nuint*/, EEClassOrCanonMT, cdac_offsets<MethodTable>::m_pEEClassOrCanonMT)
CDAC_TYPE_FIELD(MethodTable, /*pointer*/, Module, cdac_offsets<MethodTable>::m_pModule)
CDAC_TYPE_FIELD(MethodTable, /*pointer*/, AuxiliaryData, cdac_offsets<MethodTable>::m_pAuxiliaryData)
CDAC_TYPE_FIELD(MethodTable, /*pointer*/, ParentMethodTable, cdac_offsets<MethodTable>::m_pParentMethodTable)
CDAC_TYPE_FIELD(MethodTable, /*uint16*/, NumInterfaces, cdac_offsets<MethodTable>::m_wNumInterfaces)
CDAC_TYPE_FIELD(MethodTable, /*uint16*/, NumVirtuals, cdac_offsets<MethodTable>::m_wNumVirtuals)
CDAC_TYPE_END(MethodTable)

CDAC_TYPE_BEGIN(EEClass)
CDAC_TYPE_INDETERMINATE(EEClass)
CDAC_TYPE_FIELD(EEClass, /*pointer*/, MethodTable, cdac_offsets<EEClass>::m_pMethodTable)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumMethods, cdac_offsets<EEClass>::m_NumMethods)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumNonVirtualSlots, cdac_offsets<EEClass>::m_NumNonVirtualSlots)
CDAC_TYPE_FIELD(EEClass, /*uint32*/, DwAttrClass, cdac_offsets<EEClass>::m_dwAttrClass)
CDAC_TYPE_END(EEClass)

CDAC_TYPE_BEGIN(MethodTableAuxiliaryData)
CDAC_TYPE_INDETERMINATE(MethodTableAuxiliaryData)
CDAC_TYPE_FIELD(MethodTableAuxiliaryData, /*uint32*/, DwFlags, offsetof(MethodTableAuxiliaryData, m_dwFlags))
CDAC_TYPE_END(MethodTableAuxiliaryData)

CDAC_TYPES_END()

CDAC_GLOBALS_BEGIN()
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,9 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW!
template<> struct ::cdac_offsets<EEClass>
{
static constexpr size_t m_pMethodTable = offsetof(EEClass, m_pMethodTable);
static constexpr size_t m_NumMethods = offsetof(EEClass, m_NumMethods);
static constexpr size_t m_NumNonVirtualSlots = offsetof(EEClass, m_NumNonVirtualSlots);
static constexpr size_t m_dwAttrClass = offsetof(EEClass, m_dwAttrClass);
};

// --------------------------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -3671,6 +3671,9 @@ template<> struct ::cdac_offsets<MethodTable>
static constexpr size_t m_pEEClassOrCanonMT = offsetof(MethodTable, m_pEEClass);
static constexpr size_t m_pModule = offsetof(MethodTable, m_pModule);
static constexpr size_t m_pAuxiliaryData = offsetof(MethodTable, m_pAuxiliaryData);
static constexpr size_t m_pParentMethodTable = offsetof(MethodTable, m_pParentMethodTable)
static constexpr size_t m_wNumInterfaces = offsetof(MethodTable, m_wNumInterfaces)
static constexpr size_t m_wNumVirtuals = offsetof(MethodTable, m_wNumVirtuals)
};

#ifndef CROSSBITNESS_COMPILE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ internal interface IMethodTableFlags

private Metadata_1.WFLAGS_HIGH FlagsHigh => (Metadata_1.WFLAGS_HIGH)DwFlags;
private Metadata_1.WFLAGS_LOW FlagsLow => (Metadata_1.WFLAGS_LOW)DwFlags;
private int GetTypeDefRid() => (int)(DwFlags2 >> Metadata_1.Constants.MethodTableDwFlags2TypeDefRidShift);
public int GetTypeDefRid() => (int)(DwFlags2 >> Metadata_1.Constants.MethodTableDwFlags2TypeDefRidShift);

public Metadata_1.WFLAGS_LOW GetFlag(Metadata_1.WFLAGS_LOW mask) => throw new NotImplementedException("TODO");
public Metadata_1.WFLAGS_HIGH GetFlag(Metadata_1.WFLAGS_HIGH mask) => FlagsHigh & mask;
Expand All @@ -167,4 +167,8 @@ public bool TestFlagWithMask(Metadata_1.WFLAGS_LOW mask, Metadata_1.WFLAGS_LOW f
}
}
public bool HasInstantiation => !TestFlagWithMask(Metadata_1.WFLAGS_LOW.GenericsMask, Metadata_1.WFLAGS_LOW.GenericsMask_NonGeneric);

public bool ContainsPointers => GetFlag(Metadata_1.WFLAGS_HIGH.ContainsPointers) != 0;

public bool IsDynamicStatics => !TestFlagWithMask(Metadata_1.WFLAGS_LOW.StaticsMask, Metadata_1.WFLAGS_LOW.StaticsMask_Dynamic);
}
92 changes: 83 additions & 9 deletions src/native/managed/cdacreader/src/Contracts/Metadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using MethodTable = Microsoft.Diagnostics.DataContractReader.Contracts.MethodTable_1;
using UntrustedEEClass = Microsoft.Diagnostics.DataContractReader.Contracts.UntrustedEEClass_1;
using EEClass = Microsoft.Diagnostics.DataContractReader.Contracts.EEClass_1;
using System.Diagnostics.SymbolStore;

namespace Microsoft.Diagnostics.DataContractReader.Contracts;

Expand All @@ -26,6 +27,12 @@ static IContract IContract.Create(Target target, int version)
public virtual MethodTable GetMethodTableData(TargetPointer targetPointer) => throw new NotImplementedException();

public virtual TargetPointer GetClass(in MethodTable methodTable) => throw new NotImplementedException();

public virtual ushort GetNumMethods(in MethodTable methodTable) => throw new NotImplementedException();

public virtual ushort GetNumVtableSlots(in MethodTable methodTable) => throw new NotImplementedException();

public virtual ushort GetTypeDefTypeAttributes(in MethodTable methodTable) => throw new NotImplementedException();
}

internal struct Metadata : IMetadata
Expand Down Expand Up @@ -106,6 +113,7 @@ internal MethodTable_1(Data.MethodTable data, bool isFreeObjectMT)
public uint DwFlags => MethodTableData.DwFlags;
public uint DwFlags2 => MethodTableData.DwFlags2;
public uint BaseSize => MethodTableData.BaseSize;
public int GetTypeDefRid() => ((IMethodTableFlags)this).GetTypeDefRid();
public TargetPointer EEClassOrCanonMT => MethodTableData.EEClassOrCanonMT;
public TargetPointer Module => MethodTableData.Module;

Expand All @@ -115,6 +123,12 @@ internal MethodTable_1(Data.MethodTable data, bool isFreeObjectMT)

public int GetComponentSize() => ((IMethodTableFlags)this).HasComponentSize ? ((IMethodTableFlags)this).RawGetComponentSize() : 0;

public TargetPointer ParentMethodTable => MethodTableData.ParentMethodTable;
public ushort NumInterfaces => MethodTableData.NumInterfaces;
public ushort NumVirtuals => MethodTableData.NumVirtuals;

public bool ContainsPointers => ((IMethodTableFlags)this).ContainsPointers;
public bool IsDynamicStatics => ((IMethodTableFlags)this).IsDynamicStatics;
}

internal struct EEClass_1
Expand All @@ -126,6 +140,10 @@ internal EEClass_1(Data.EEClass eeClassData)
}

public TargetPointer MethodTable => EEClassData.MethodTable;
public ushort NumMethods => EEClassData.NumMethods;
public ushort NumNonVirtualSlots => EEClassData.NumNonVirtualSlots;

public ushort TypeDefTypeAttributes => EEClassData.DwAttrClass;
}


Expand Down Expand Up @@ -191,7 +209,7 @@ public MethodTable GetMethodTableData(TargetPointer methodTablePointer)
return new MethodTable(trustedMethodTableData, isFreeObjectMT: false);
}

private bool ValidateMethodTablePointer(ref readonly UntrustedMethodTable umt)
private bool ValidateMethodTablePointer(in UntrustedMethodTable umt)
{
// FIXME: is methodTablePointer properly sign-extended from 32-bit targets?
// FIXME2: do we need this? Data.MethodTable probably would throw if methodTablePointer is invalid
Expand All @@ -201,11 +219,11 @@ private bool ValidateMethodTablePointer(ref readonly UntrustedMethodTable umt)
//}
try
{
if (!ValidateWithPossibleAV(in umt))
if (!ValidateWithPossibleAV(umt))
{
return false;
}
if (!ValidateMethodTable(in umt))
if (!ValidateMethodTable(umt))
{
return false;
}
Expand All @@ -218,7 +236,7 @@ private bool ValidateMethodTablePointer(ref readonly UntrustedMethodTable umt)
return true;
}

private bool ValidateWithPossibleAV(ref readonly UntrustedMethodTable methodTable)
private bool ValidateWithPossibleAV(in UntrustedMethodTable methodTable)
{
// For non-generic classes, we can rely on comparing
// object->methodtable->class->methodtable
Expand All @@ -231,7 +249,7 @@ private bool ValidateWithPossibleAV(ref readonly UntrustedMethodTable methodTabl
// object->methodtable->class->methodtable->class
// to
// object->methodtable->class
TargetPointer eeClassPtr = GetClassWithPossibleAV(in methodTable);
TargetPointer eeClassPtr = GetClassWithPossibleAV(methodTable);
if (eeClassPtr != TargetPointer.Null)
{
UntrustedEEClass eeClass = GetUntrustedEEClassData(eeClassPtr);
Expand All @@ -250,7 +268,7 @@ private bool ValidateWithPossibleAV(ref readonly UntrustedMethodTable methodTabl
return false;
}

private bool ValidateMethodTable(ref readonly UntrustedMethodTable methodTable)
private bool ValidateMethodTable(in UntrustedMethodTable methodTable)
{
if (!((IMethodTableFlags)methodTable).IsInterface && !((IMethodTableFlags)methodTable).IsString)
{
Expand All @@ -266,7 +284,7 @@ internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeCla
{
return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask);
}
private TargetPointer GetClassWithPossibleAV(ref readonly UntrustedMethodTable methodTable)
private TargetPointer GetClassWithPossibleAV(in UntrustedMethodTable methodTable)
{
TargetPointer eeClassOrCanonMT = methodTable.EEClassOrCanonMT;

Expand All @@ -282,12 +300,12 @@ private TargetPointer GetClassWithPossibleAV(ref readonly UntrustedMethodTable m
}
}

private static TargetPointer GetMethodTableWithPossibleAV(ref readonly UntrustedEEClass eeClass)
private static TargetPointer GetMethodTableWithPossibleAV(in UntrustedEEClass eeClass)
{
return eeClass.MethodTable;
}

internal TargetPointer GetClass(ref readonly MethodTable methodTable)
public TargetPointer GetClass(in MethodTable methodTable)
{
switch (GetEEClassOrCanonMTBits(methodTable.EEClassOrCanonMT))
{
Expand All @@ -301,4 +319,60 @@ internal TargetPointer GetClass(ref readonly MethodTable methodTable)
throw new InvalidOperationException();
}
}

// only called on trusted method tables, so we always trust the resulting EEClass
private EEClass GetClassData(in MethodTable methodTable)
{
TargetPointer clsPtr = GetClass(in methodTable);
// Check if we cached it already
if (_target.ProcessedData.TryGet(clsPtr, out Data.EEClass? eeClassData))
{
return new EEClass_1(eeClassData);
}
eeClassData = _target.ProcessedData.GetOrAdd<Data.EEClass>(clsPtr);
return new EEClass_1(eeClassData);
}

public ushort GetNumMethods(in MethodTable methodTable)
{
EEClass cls = GetClassData(in methodTable);
return cls.NumMethods;
}

private ushort GetNumNonVirtualSlots(in MethodTable methodTable)
{
TargetPointer eeClassOrCanonMT = methodTable.EEClassOrCanonMT;
if (GetEEClassOrCanonMTBits(eeClassOrCanonMT) == EEClassOrCanonMTBits.EEClass)
{
return GetClassData(methodTable).NumNonVirtualSlots;
}
else
{
return 0;
}
}

public ushort GetNumVtableSlots(in MethodTable methodTable)
{
return checked((ushort)(methodTable.NumVirtuals + GetNumNonVirtualSlots(methodTable)));
}

public ushort GetTypeDefTypeAttributes(in MethodTable methodTable)
{
return GetClassData(methodTable).TypeDefTypeAttributes;
}


[Flags]
internal enum MethodTableAuxiliaryDataFlags : uint
{
CanCompareBitsOrUseFastGetHashCode = 0x0001, // Is any field type or sub field type overrode Equals or GetHashCode
HasCheckedCanCompareBitsOrUseFastGetHashCode = 0x0002, // Whether we have checked the overridden Equals or GetHashCode
HasApproxParent = 0x0010,
IsNotFullyLoaded = 0x0040,
DependenciesLoaded = 0x0080, // class and all dependencies loaded up to CLASS_LOADED_BUT_NOT_VERIFIED
MayHaveOpenInterfaceInInterfaceMap = 0x0100,
DebugOnly_ParentMethodTablePointerValid = 0x4000,
DebugOnly_HasInjectedInterfaceDuplicates = 0x8000,
}
}
7 changes: 6 additions & 1 deletion src/native/managed/cdacreader/src/Data/EEClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ public EEClass(Target target, TargetPointer address)
Target.TypeInfo type = target.GetTypeInfo(DataType.EEClass);

MethodTable = target.ReadPointer(address + (ulong)type.Fields[nameof(MethodTable)].Offset);
NumMethods = target.Read<ushort>(address + (ulong)type.Fields[nameof(NumMethods)].Offset);
NumNonVirtualSlots = target.Read<ushort>(address + (ulong)type.Fields[nameof(NumNonVirtualSlots)].Offset);
DwAttrClass = target.Read<uint>(address + (ulong)type.Fields[nameof(DwAttrClass)].Offset);
}

public TargetPointer MethodTable { get; init; }

public ushort NumMethods { get; init; }
public ushort NumNonVirtualSlots { get; init; }
public uint DwAttrClass { get; init; }
}
10 changes: 7 additions & 3 deletions src/native/managed/cdacreader/src/Data/MethodTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@ public MethodTable(Target target, TargetPointer address)
{
Target.TypeInfo type = target.GetTypeInfo(DataType.MethodTable);

//Id = target.Read<uint>(address + (ulong)type.Fields[nameof(Id)].Offset);
//LinkNext = target.ReadPointer(address + (ulong)type.Fields[nameof(LinkNext)].Offset);
DwFlags = target.Read<uint>(address + (ulong)type.Fields[nameof(DwFlags)].Offset);
BaseSize = target.Read<uint>(address + (ulong)type.Fields[nameof(BaseSize)].Offset);
DwFlags2 = target.Read<uint>(address + (ulong)type.Fields[nameof(DwFlags2)].Offset);
EEClassOrCanonMT = target.ReadPointer(address + (ulong)type.Fields[nameof(EEClassOrCanonMT)].Offset);
Module = target.ReadPointer(address + (ulong)type.Fields[(nameof(Module))].Offset);
Module = target.ReadPointer(address + (ulong)type.Fields[nameof(Module)].Offset);
ParentMethodTable = target.ReadPointer(address + (ulong)type.Fields[nameof(ParentMethodTable)].Offset);
NumInterfaces = target.Read<ushort>(address + (ulong)type.Fields[nameof(NumInterfaces)].Offset);
NumVirtuals = target.Read<ushort>(address + (ulong)type.Fields[nameof(NumVirtuals)].Offset);
}

public uint DwFlags { get; init; }
public uint BaseSize { get; init; }
public uint DwFlags2 { get; init; }
public TargetPointer EEClassOrCanonMT { get; init; }
public TargetPointer Module { get; init; }
public TargetPointer ParentMethodTable { get; init; }
public ushort NumInterfaces { get; init; }
public ushort NumVirtuals { get; init; }
}
21 changes: 21 additions & 0 deletions src/native/managed/cdacreader/src/Data/MethodTableAuxiliaryData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Microsoft.Diagnostics.DataContractReader.Data;

internal sealed class MethodTableAuxiliaryData : IData<MethodTableAuxiliaryData>
{
static MethodTableAuxiliaryData IData<MethodTableAuxiliaryData>.Create(Target target, TargetPointer address) => new MethodTableAuxiliaryData(target, address);

private MethodTableAuxiliaryData(Target target, TargetPointer address)
{
Target.TypeInfo type = target.GetTypeInfo(DataType.MethodTableAuxiliaryData);

DwFlags = target.Read<uint>(address + (ulong)type.Fields[nameof(DwFlags)].Offset);

}

public uint DwFlags { get; init; }
}
1 change: 1 addition & 0 deletions src/native/managed/cdacreader/src/DataType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ public enum DataType
ThreadStore,
MethodTable,
EEClass,
MethodTableAuxiliaryData,
}
27 changes: 12 additions & 15 deletions src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using Microsoft.Diagnostics.DataContractReader.Data;
Expand Down Expand Up @@ -100,21 +101,17 @@ public unsafe int GetMethodTableData(ulong mt, DacpMethodTableData* data)
if (!methodTable.IsFreeObjectMethodTable)
{
result.module = methodTable.Module;
result.@class = contract.GetClass(in methodTable);
#if false
// TODO
MTData->ParentMethodTable = HOST_CDADDR(pMT->GetParentMethodTable()); ;
MTData->wNumInterfaces = (WORD)pMT->GetNumInterfaces();
MTData->wNumMethods = pMT->GetNumMethods();
MTData->wNumVtableSlots = pMT->GetNumVtableSlots();
MTData->wNumVirtuals = pMT->GetNumVirtuals();
MTData->cl = pMT->GetCl();
MTData->dwAttrClass = pMT->GetAttrClass();
MTData->bContainsPointers = pMT->ContainsPointers();
MTData->bIsShared = FALSE;
MTData->bIsDynamic = pMT->IsDynamicStatics();
#endif
return HResults.E_NOTIMPL;
result.@class = contract.GetClass(methodTable);
result.parentMethodTable = methodTable.ParentMethodTable;
result.wNumInterfaces = methodTable.NumInterfaces;
result.wNumMethods = contract.GetNumMethods(methodTable);
result.wNumVtableSlots = contract.GetNumVtableSlots(methodTable);
result.wNumVirtuals = methodTable.NumVirtuals;
result.cl = (uint)(methodTable.GetTypeDefRid() | ((int)TableIndex.TypeDef << 24));
result.dwAttrClass = contract.GetTypeDefTypeAttributes(methodTable);
result.bContainsPointers = methodTable.ContainsPointers ? 1 : 0;
result.bIsShared = 0;
result.bIsDynamic = methodTable.IsDynamicStatics ? 1 : 0;
}
return HResults.S_OK;
}
Expand Down