From 037212e7625d7ebfccad4d7846e26fe25cc32318 Mon Sep 17 00:00:00 2001 From: Max Charlamb Date: Mon, 3 Aug 2026 15:36:32 -0400 Subject: [PATCH] Hide module lookup map layout details Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f2aa5dc4-0c99-43f0-af14-734143849c4a --- docs/design/datacontracts/CodeVersions.md | 7 +- docs/design/datacontracts/Loader.md | 93 +++++++++++-------- .../design/datacontracts/ManagedTypeSource.md | 7 +- .../Contracts/Extensions/ILoaderExtensions.cs | 7 +- .../Contracts/ILoader.cs | 25 ++--- .../Contracts/CodeVersions_1.cs | 7 +- .../ExecutionManager/ExecutionManagerCore.cs | 5 +- .../Contracts/Loader_1.cs | 61 ++++++++---- .../Contracts/ManagedTypeSource_1.cs | 7 +- .../Contracts/RuntimeTypeSystem_1.cs | 7 +- .../Signature/SignatureTypeProvider.cs | 14 ++- .../ClrDataMethodDefinition.cs | 7 +- .../ClrDataTypeInstance.cs | 7 +- .../Dbi/DacDbiImpl.cs | 58 +++++++----- .../Dbi/TypeDataWalk.cs | 5 +- .../SOSDacImpl.cs | 40 ++++---- .../IXCLRDataMethodDefinitionDumpTests.cs | 6 +- .../cdac/tests/UnitTests/CodeVersionsTests.cs | 15 +-- .../cdac/tests/UnitTests/DacDbiImplTests.cs | 82 ++++++++-------- .../cdac/tests/UnitTests/TypeHandleTests.cs | 25 +++-- 20 files changed, 278 insertions(+), 207 deletions(-) diff --git a/docs/design/datacontracts/CodeVersions.md b/docs/design/datacontracts/CodeVersions.md index 76d64e8445603a..d87d818f2473f6 100644 --- a/docs/design/datacontracts/CodeVersions.md +++ b/docs/design/datacontracts/CodeVersions.md @@ -238,8 +238,11 @@ IEnumerable ICodeVersions.GetILCodeVersions(TargetPointer m GetModuleAndMethodDesc(methodDesc, out TargetPointer module, out uint methodDefToken); ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandleFromModulePtr(module); - TargetPointer ilCodeVersionTable = _target.Contracts.Loader.GetLookupTables(moduleHandle).MethodDefToILCodeVersioningState; - TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement(ilCodeVersionTable, methodDefToken, out var _); + TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToILCodeVersioningState, + methodDefToken, + out var _); // always add the synthetic version yield return new ILCodeVersionHandle(module, methodDefToken, TargetPointer.Null); diff --git a/docs/design/datacontracts/Loader.md b/docs/design/datacontracts/Loader.md index 7a91306fa93c02..cfb3cf1f288807 100644 --- a/docs/design/datacontracts/Loader.md +++ b/docs/design/datacontracts/Loader.md @@ -44,15 +44,16 @@ public enum AssemblyIterationFlags IncludeCollected = 0x00000080, // Include all collectible assemblies that have been collected } -record struct ModuleLookupTables( - TargetPointer FieldDefToDesc, - TargetPointer ManifestModuleReferences, - TargetPointer MemberRefToDesc, - TargetPointer MethodDefToDesc, - TargetPointer TypeDefToMethodTable, - TargetPointer TypeRefToMethodTable, - TargetPointer MethodDefToILCodeVersioningState, - uint TableDataOffset); +enum ModuleLookupMapKind +{ + FieldDefToDesc, + ManifestModuleReferences, + MemberRefToDesc, + MethodDefToDesc, + TypeDefToMethodTable, + TypeRefToMethodTable, + MethodDefToILCodeVersioningState, +} readonly record struct LoaderHeapBlock(TargetPointer Address, TargetNUInt Size); @@ -99,10 +100,10 @@ bool GetFileHeadersInfo(ModuleHandle handle, out uint timeStamp, out uint imageS TargetPointer GetLoaderAllocator(ModuleHandle handle); TargetPointer GetILBase(ModuleHandle handle); TargetPointer GetAssemblyLoadContext(ModuleHandle handle); -ModuleLookupTables GetLookupTables(ModuleHandle handle); -TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags); +TargetPointer GetModuleLookupMapBase(ModuleHandle module, ModuleLookupMapKind kind); +TargetPointer GetModuleLookupMapElement(ModuleHandle module, ModuleLookupMapKind kind, uint token, out TargetNUInt flags); TargetPointer LookupMemberRefAsMethod(ModuleHandle handle, uint token); -IEnumerable<(TargetPointer, uint)> EnumerateModuleLookupMap(TargetPointer table); +IEnumerable<(TargetPointer Value, uint Token)> EnumerateModuleLookupMap(ModuleHandle module, ModuleLookupMapKind kind); bool IsCollectible(ModuleHandle handle); bool IsDynamic(ModuleHandle handle); bool IsModuleMapped(ModuleHandle handle); @@ -711,29 +712,38 @@ TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle) return objectHandle.Object; } -ModuleLookupTables GetLookupTables(ModuleHandle handle) +TargetPointer GetModuleLookupMap(ModuleHandle module, ModuleLookupMapKind kind) { - uint tableDataOffset = (uint)/* ModuleLookupMap::TableData offset */; - return new ModuleLookupTables( - FieldDefToDescMap: target.ReadPointer(handle.Address + /* Module::FieldDefToDescMap */), - ManifestModuleReferencesMap: target.ReadPointer(handle.Address + /* Module::ManifestModuleReferencesMap */), - MemberRefToDescMap: target.ReadPointer(handle.Address + /* Module::MemberRefToDescMap */), - MethodDefToDescMap: target.ReadPointer(handle.Address + /* Module::MethodDefToDescMap */), - TypeDefToMethodTableMap: target.ReadPointer(handle.Address + /* Module::TypeDefToMethodTableMap */), - TypeRefToMethodTableMap: target.ReadPointer(handle.Address + /* Module::TypeRefToMethodTableMap */), - // Module::MethodDefToILCodeVersioningState is only present when the target was built - // with code versioning (FEATURE_CODE_VERSIONING). When absent (e.g. on WASM) it is - // treated as a null (empty) table. - MethodDefToILCodeVersioningState: HasField(Module::MethodDefToILCodeVersioningState) - ? target.ReadPointer(handle.Address + /* Module::MethodDefToILCodeVersioningState */) - : TargetPointer.Null, - TableDataOffset: tableDataOffset); + return kind switch + { + FieldDefToDesc => target.ReadPointer(module.Address + /* Module::FieldDefToDescMap offset */), + ManifestModuleReferences => target.ReadPointer(module.Address + /* Module::ManifestModuleReferencesMap offset */), + MemberRefToDesc => target.ReadPointer(module.Address + /* Module::MemberRefToDescMap offset */), + MethodDefToDesc => target.ReadPointer(module.Address + /* Module::MethodDefToDescMap offset */), + TypeDefToMethodTable => target.ReadPointer(module.Address + /* Module::TypeDefToMethodTableMap offset */), + TypeRefToMethodTable => target.ReadPointer(module.Address + /* Module::TypeRefToMethodTableMap offset */), + MethodDefToILCodeVersioningState => target.ReadPointer(module.Address + /* Module::MethodDefToILCodeVersioningStateMap offset */), + }; } -TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags); +TargetPointer GetModuleLookupMapBase(ModuleHandle module, ModuleLookupMapKind kind) +{ + TargetPointer table = GetModuleLookupMap(module, kind); + return table == TargetPointer.Null + ? TargetPointer.Null + : target.ReadPointer(table + /* ModuleLookupMap::TableData offset */); +} + +uint CreateModuleLookupMapToken(ModuleLookupMapKind kind, uint rid) +{ + // Combine rid with the metadata table prefix implied by kind. +} + +TargetPointer GetModuleLookupMapElement(ModuleHandle module, ModuleLookupMapKind kind, uint token, out TargetNUInt flags) { uint rid = /* get row id from token*/ (token); flags = new TargetNUInt(0); + TargetPointer table = GetModuleLookupMap(module, kind); if (table == TargetPointer.Null) return TargetPointer.Null; uint index = rid; @@ -742,34 +752,35 @@ TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out Tar TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */); do { - if (index < target.Read(table + /*ModuleLookupMap::Count*/)) + uint count = target.Read(table + /*ModuleLookupMap::Count*/); + if (index < count) { - TargetPointer entryAddress = target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize); + TargetPointer entryAddress = target.ReadPointer(table + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize); TargetPointer rawValue = target.ReadPointer(entryAddress); flags = rawValue & supportedFlagsMask; return rawValue & ~(supportedFlagsMask.Value); } else { - table = target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/); - index -= target.Read(lookupMap + /*ModuleLookupMap::Count*/); + index -= count; + table = target.ReadPointer(table + /*ModuleLookupMap::Next*/); } } while (table != TargetPointer.Null); return TargetPointer.Null; } -// Returns the MethodDesc pointer for the given mdMemberRef token, or TargetPointer.Null -// if the entry is a FieldDesc (flagged with IS_FIELD_MEMBER_REF) or not present. -TargetPointer LookupMemberRefAsMethod(ModuleHandle handle, uint memberRefToken) +TargetPointer LookupMemberRefAsMethod(ModuleHandle module, uint token) { - ModuleLookupTables tables = GetLookupTables(handle); - TargetPointer result = GetModuleLookupMapElement(tables.MemberRefToDesc, memberRefToken, out TargetNUInt flags); + TargetPointer result = GetModuleLookupMapElement(module, MemberRefToDesc, token, out TargetNUInt flags); return (flags.Value & IS_FIELD_MEMBER_REF) == 0 ? result : TargetPointer.Null; } -IEnumerable<(TargetPointer, uint)> EnumerateModuleLookupMap(TargetPointer table) +IEnumerable<(TargetPointer Value, uint Token)> EnumerateModuleLookupMap(ModuleHandle module, ModuleLookupMapKind kind) { - Data.ModuleLookupMap lookupMap = new Data.ModuleLookupMap(table); + TargetPointer table = GetModuleLookupMap(module, kind); + if (table == TargetPointer.Null) + yield break; + // have to read lookupMap an extra time upfront because only the first map // has valid supportedFlagsMask TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */); @@ -783,7 +794,7 @@ IEnumerable<(TargetPointer, uint)> EnumerateModuleLookupMap(TargetPointer table) TargetPointer rawValue = target.ReadPointer(entryAddress); ulong maskedValue = rawValue & ~(supportedFlagsMask.Value); if (maskedValue != 0) - yield return (new TargetPointer(maskedValue), index); + yield return (new TargetPointer(maskedValue), CreateModuleLookupMapToken(kind, index)); index++; } else diff --git a/docs/design/datacontracts/ManagedTypeSource.md b/docs/design/datacontracts/ManagedTypeSource.md index 1ce166a9f7cefc..0b2856999d3343 100644 --- a/docs/design/datacontracts/ManagedTypeSource.md +++ b/docs/design/datacontracts/ManagedTypeSource.md @@ -96,8 +96,11 @@ bool TryResolveType( // Resolve the TypeDef token via the module's TypeDef -> MethodTable map. int token = MetadataTokens.GetToken(typeDefHandle); - TargetPointer typeDefToMT = loader.GetLookupTables(moduleHandle).TypeDefToMethodTable; - TargetPointer mt = loader.GetModuleLookupMapElement(typeDefToMT, (uint)token, out _); + TargetPointer mt = loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.TypeDefToMethodTable, + (uint)token, + out _); if (mt == TargetPointer.Null) return false; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ILoaderExtensions.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ILoaderExtensions.cs index 99f9602cd4458a..7fd68615f18f93 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ILoaderExtensions.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ILoaderExtensions.cs @@ -23,8 +23,11 @@ public static bool TryResolveAssemblyRefToModule( uint token = (uint)MetadataTokens.GetToken(assemblyRef); - ModuleLookupTables tables = loader.GetLookupTables(referencingModule); - TargetPointer modulePtr = loader.GetModuleLookupMapElement(tables.ManifestModuleReferences, token, out _); + TargetPointer modulePtr = loader.GetModuleLookupMapElement( + referencingModule, + ModuleLookupMapKind.ManifestModuleReferences, + token, + out _); if (modulePtr == TargetPointer.Null) return false; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs index 6f0a3276817fef..282cfb12ee7beb 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs @@ -72,15 +72,16 @@ public enum AssemblyIterationFlags IncludeCollected = 0x00000080, // Include all collectible assemblies that have been collected } -public record struct ModuleLookupTables( - TargetPointer FieldDefToDesc, - TargetPointer ManifestModuleReferences, - TargetPointer MemberRefToDesc, - TargetPointer MethodDefToDesc, - TargetPointer TypeDefToMethodTable, - TargetPointer TypeRefToMethodTable, - TargetPointer MethodDefToILCodeVersioningState, - uint TableDataOffset); +public enum ModuleLookupMapKind +{ + FieldDefToDesc, + ManifestModuleReferences, + MemberRefToDesc, + MethodDefToDesc, + TypeDefToMethodTable, + TypeRefToMethodTable, + MethodDefToILCodeVersioningState, +} public readonly record struct LoaderHeapBlock(TargetPointer Address, TargetNUInt Size); @@ -114,10 +115,10 @@ public interface ILoader : IContract TargetPointer GetLoaderAllocator(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetILBase(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetAssemblyLoadContext(ModuleHandle handle) => throw new NotImplementedException(); - ModuleLookupTables GetLookupTables(ModuleHandle handle) => throw new NotImplementedException(); - TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags) => throw new NotImplementedException(); + TargetPointer GetModuleLookupMapBase(ModuleHandle module, ModuleLookupMapKind kind) => throw new NotImplementedException(); + TargetPointer GetModuleLookupMapElement(ModuleHandle module, ModuleLookupMapKind kind, uint token, out TargetNUInt flags) => throw new NotImplementedException(); TargetPointer LookupMemberRefAsMethod(ModuleHandle handle, uint token) => throw new NotImplementedException(); - IEnumerable<(TargetPointer, uint)> EnumerateModuleLookupMap(TargetPointer table) => throw new NotImplementedException(); + IEnumerable<(TargetPointer Value, uint Token)> EnumerateModuleLookupMap(ModuleHandle module, ModuleLookupMapKind kind) => throw new NotImplementedException(); bool IsCollectible(ModuleHandle handle) => throw new NotImplementedException(); bool IsDynamic(ModuleHandle handle) => throw new NotImplementedException(); bool IsModuleMapped(ModuleHandle handle) => throw new NotImplementedException(); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs index 91aee65a6550cf..811d6747a13f20 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs @@ -348,8 +348,11 @@ private TargetPointer GetILVersionStateAddress(TargetPointer module, uint method return TargetPointer.Null; ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandleFromModulePtr(module); - TargetPointer ilCodeVersionTable = _target.Contracts.Loader.GetLookupTables(moduleHandle).MethodDefToILCodeVersioningState; - TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement(ilCodeVersionTable, methodDefToken, out var _); + TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToILCodeVersioningState, + methodDefToken, + out var _); return ilVersionStateAddress; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs index 8c8f933f948e62..b679dbce6a1e6e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs @@ -560,12 +560,11 @@ private bool IsObjectType(TargetPointer moduleAddr, uint classToken) { ILoader loader = _target.Contracts.Loader; ModuleHandle module = loader.GetModuleHandleFromModulePtr(moduleAddr); - ModuleLookupTables tables = loader.GetLookupTables(module); TargetPointer resolvedMethodTable = (EcmaMetadataUtils.TokenType)(classToken & EcmaMetadataUtils.TokenTypeMask) switch { - EcmaMetadataUtils.TokenType.mdtTypeDef => loader.GetModuleLookupMapElement(tables.TypeDefToMethodTable, classToken, out _), - EcmaMetadataUtils.TokenType.mdtTypeRef => loader.GetModuleLookupMapElement(tables.TypeRefToMethodTable, classToken, out _), + EcmaMetadataUtils.TokenType.mdtTypeDef => loader.GetModuleLookupMapElement(module, ModuleLookupMapKind.TypeDefToMethodTable, classToken, out _), + EcmaMetadataUtils.TokenType.mdtTypeRef => loader.GetModuleLookupMapElement(module, ModuleLookupMapKind.TypeRefToMethodTable, classToken, out _), _ => TargetPointer.Null, }; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs index 4d79c09db52545..c4bff95296e78b 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs @@ -539,24 +539,44 @@ TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle) return binder.AssemblyLoadContext.Object; } - ModuleLookupTables ILoader.GetLookupTables(ModuleHandle handle) + private TargetPointer GetModuleLookupMap(ModuleHandle handle, ModuleLookupMapKind kind) { Data.Module module = _target.ProcessedData.GetOrAdd(handle.Address); - uint tableDataOffset = (uint)Data.ModuleLookupMap.GetTableDataOffset(_target); - return new ModuleLookupTables( - module.FieldDefToDescMap, - module.ManifestModuleReferencesMap, - module.MemberRefToDescMap, - module.MethodDefToDescMap, - module.TypeDefToMethodTableMap, - module.TypeRefToMethodTableMap, - // Absent on builds without code versioning (e.g. WASM); treat as an empty table. - module.MethodDefToILCodeVersioningStateMap ?? TargetPointer.Null, - tableDataOffset); + return kind switch + { + ModuleLookupMapKind.FieldDefToDesc => module.FieldDefToDescMap, + ModuleLookupMapKind.ManifestModuleReferences => module.ManifestModuleReferencesMap, + ModuleLookupMapKind.MemberRefToDesc => module.MemberRefToDescMap, + ModuleLookupMapKind.MethodDefToDesc => module.MethodDefToDescMap, + ModuleLookupMapKind.TypeDefToMethodTable => module.TypeDefToMethodTableMap, + ModuleLookupMapKind.TypeRefToMethodTable => module.TypeRefToMethodTableMap, + ModuleLookupMapKind.MethodDefToILCodeVersioningState => module.MethodDefToILCodeVersioningStateMap ?? TargetPointer.Null, + _ => throw new ArgumentOutOfRangeException(nameof(kind)), + }; + } + + TargetPointer ILoader.GetModuleLookupMapBase(ModuleHandle module, ModuleLookupMapKind kind) + { + TargetPointer table = GetModuleLookupMap(module, kind); + return table == TargetPointer.Null + ? TargetPointer.Null + : _target.ProcessedData.GetOrAdd(table).TableData; } private static (bool Done, uint NextIndex) IterateLookupMap(uint index) => (false, index + 1); private static (bool Done, uint NextIndex) SearchLookupMap(uint index) => (true, index); + private static uint CreateModuleLookupMapToken(ModuleLookupMapKind kind, uint rid) + => (uint)(kind switch + { + ModuleLookupMapKind.FieldDefToDesc => EcmaMetadataUtils.TokenType.mdtFieldDef, + ModuleLookupMapKind.ManifestModuleReferences => EcmaMetadataUtils.TokenType.mdtAssemblyRef, + ModuleLookupMapKind.MemberRefToDesc => EcmaMetadataUtils.TokenType.mdtMemberRef, + ModuleLookupMapKind.MethodDefToDesc or ModuleLookupMapKind.MethodDefToILCodeVersioningState => EcmaMetadataUtils.TokenType.mdtMethodDef, + ModuleLookupMapKind.TypeDefToMethodTable => EcmaMetadataUtils.TokenType.mdtTypeDef, + ModuleLookupMapKind.TypeRefToMethodTable => EcmaMetadataUtils.TokenType.mdtTypeRef, + _ => throw new ArgumentOutOfRangeException(nameof(kind)), + }) | (rid & EcmaMetadataUtils.RIDMask); + private delegate (bool Done, uint NextIndex) Delegate(uint index); private IEnumerable<(TargetPointer, uint)> IterateModuleLookupMap(TargetPointer table, uint index, Delegate iterator) { @@ -581,7 +601,7 @@ ModuleLookupTables ILoader.GetLookupTables(ModuleHandle handle) } while (table != TargetPointer.Null); } - TargetPointer ILoader.GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags) + private TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags) { uint rid = EcmaMetadataUtils.GetRowId(token); if (table == TargetPointer.Null || rid == 0) @@ -597,20 +617,21 @@ TargetPointer ILoader.GetModuleLookupMapElement(TargetPointer table, uint token, return rval & ~supportedFlagsMask; } + TargetPointer ILoader.GetModuleLookupMapElement(ModuleHandle module, ModuleLookupMapKind kind, uint token, out TargetNUInt flags) + => GetModuleLookupMapElement(GetModuleLookupMap(module, kind), token, out flags); + TargetPointer ILoader.LookupMemberRefAsMethod(ModuleHandle handle, uint token) { - ModuleLookupTables lookupTables = ((ILoader)this).GetLookupTables(handle); - TargetPointer result = ((ILoader)this).GetModuleLookupMapElement(lookupTables.MemberRefToDesc, token, out TargetNUInt flags); + TargetPointer result = ((ILoader)this).GetModuleLookupMapElement(handle, ModuleLookupMapKind.MemberRefToDesc, token, out TargetNUInt flags); return (flags.Value & IS_FIELD_MEMBER_REF) == 0 ? result : TargetPointer.Null; } - IEnumerable<(TargetPointer, uint)> ILoader.EnumerateModuleLookupMap(TargetPointer table) + private IEnumerable<(TargetPointer, uint)> EnumerateModuleLookupMap(TargetPointer table) { if (table == TargetPointer.Null) yield break; Data.ModuleLookupMap lookupMap = _target.ProcessedData.GetOrAdd(table); ulong supportedFlagsMask = lookupMap.SupportedFlagsMask.Value; - TargetNUInt flags = new TargetNUInt(0); uint index = 1; // zero is invalid foreach ((TargetPointer targetPointer, uint idx) in IterateModuleLookupMap(table, index, IterateLookupMap)) { @@ -620,6 +641,12 @@ TargetPointer ILoader.LookupMemberRefAsMethod(ModuleHandle handle, uint token) } } + IEnumerable<(TargetPointer Value, uint Token)> ILoader.EnumerateModuleLookupMap(ModuleHandle module, ModuleLookupMapKind kind) + { + foreach ((TargetPointer value, uint rid) in EnumerateModuleLookupMap(GetModuleLookupMap(module, kind))) + yield return (value, CreateModuleLookupMapToken(kind, rid)); + } + bool ILoader.IsCollectible(ModuleHandle handle) { Data.Module module = _target.ProcessedData.GetOrAdd(handle.Address); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ManagedTypeSource_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ManagedTypeSource_1.cs index 8ba10c81445a7d..6e0515e5b171b8 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ManagedTypeSource_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ManagedTypeSource_1.cs @@ -271,8 +271,11 @@ private bool TryResolveType(string managedFqName, [NotNullWhen(true)] out ITypeH // Look up the cDAC ITypeHandle via the module's TypeDef → MethodTable map. int token = MetadataTokens.GetToken((EntityHandle)typeDefHandle); - TargetPointer typeDefToMethodTable = loader.GetLookupTables(moduleHandle).TypeDefToMethodTable; - TargetPointer typeHandlePtr = loader.GetModuleLookupMapElement(typeDefToMethodTable, (uint)token, out _); + TargetPointer typeHandlePtr = loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.TypeDefToMethodTable, + (uint)token, + out _); if (typeHandlePtr == TargetPointer.Null) return false; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs index a265780c5c93c2..fbe6e2265d3707 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs @@ -2473,14 +2473,17 @@ TargetPointer IRuntimeTypeSystem.GetFieldDescByName(ITypeHandle typeHandle, stri if (md is null) return TargetPointer.Null; - TargetPointer fieldDefToDescMap = loader.GetLookupTables(moduleHandle).FieldDefToDesc; foreach (FieldDefinitionHandle fieldDefHandle in md.GetTypeDefinition(typeDefHandle).GetFields()) { FieldDefinition fieldDef = md.GetFieldDefinition(fieldDefHandle); if (md.GetString(fieldDef.Name) == fieldName) { uint fieldDefToken = (uint)MetadataTokens.GetToken(fieldDefHandle); - TargetPointer fieldDescPtr = loader.GetModuleLookupMapElement(fieldDefToDescMap, fieldDefToken, out _); + TargetPointer fieldDescPtr = loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.FieldDefToDesc, + fieldDefToken, + out _); return fieldDescPtr; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureTypeProvider.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureTypeProvider.cs index 1f10f401710ca3..807c40bffdb835 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureTypeProvider.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureTypeProvider.cs @@ -75,16 +75,22 @@ public SignatureTypeProvider(Target target, Contracts.ModuleHandle moduleHandle) public ITypeHandle? GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) { int token = MetadataTokens.GetToken((EntityHandle)handle); - TargetPointer typeDefToMethodTable = _loader.GetLookupTables(_moduleHandle).TypeDefToMethodTable; - TargetPointer typeHandlePtr = _loader.GetModuleLookupMapElement(typeDefToMethodTable, (uint)token, out _); + TargetPointer typeHandlePtr = _loader.GetModuleLookupMapElement( + _moduleHandle, + ModuleLookupMapKind.TypeDefToMethodTable, + (uint)token, + out _); return typeHandlePtr == TargetPointer.Null ? null : _runtimeTypeSystem.GetTypeHandle(typeHandlePtr); } public ITypeHandle? GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) { int token = MetadataTokens.GetToken((EntityHandle)handle); - TargetPointer typeRefToMethodTable = _loader.GetLookupTables(_moduleHandle).TypeRefToMethodTable; - TargetPointer typeHandlePtr = _loader.GetModuleLookupMapElement(typeRefToMethodTable, (uint)token, out _); + TargetPointer typeHandlePtr = _loader.GetModuleLookupMapElement( + _moduleHandle, + ModuleLookupMapKind.TypeRefToMethodTable, + (uint)token, + out _); return typeHandlePtr == TargetPointer.Null ? null : _runtimeTypeSystem.GetTypeHandle(typeHandlePtr); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataMethodDefinition.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataMethodDefinition.cs index 6b7fe626dd424a..7846e4c5aa3fe4 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataMethodDefinition.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataMethodDefinition.cs @@ -48,8 +48,11 @@ private TargetPointer TryResolveMethodDesc() { ILoader loader = _target.Contracts.Loader; Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(_module); - ModuleLookupTables tables = loader.GetLookupTables(moduleHandle); - TargetPointer methodDescAddr = loader.GetModuleLookupMapElement(tables.MethodDefToDesc, _token, out _); + TargetPointer methodDescAddr = loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToDesc, + _token, + out _); return methodDescAddr; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataTypeInstance.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataTypeInstance.cs index f8aeecde9b47b3..0f5cb81f34d624 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataTypeInstance.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataTypeInstance.cs @@ -154,8 +154,11 @@ int IXCLRDataTypeInstance.GetDefinition(DacComNullableByRefMethodTable map - Contracts.ModuleLookupTables tables = loader.GetLookupTables(referencingModule); - TargetPointer methodTable = loader.GetModuleLookupMapElement(tables.TypeRefToMethodTable, typeToken, out _); + TargetPointer methodTable = loader.GetModuleLookupMapElement( + referencingModule, + ModuleLookupMapKind.TypeRefToMethodTable, + typeToken, + out _); if (methodTable != TargetPointer.Null) { Contracts.IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; @@ -1531,8 +1534,11 @@ public int ResolveAssembly(ulong vmScope, uint tkAssemblyRef, ulong* pRetVal) { Contracts.ILoader loader = _target.Contracts.Loader; Contracts.ModuleHandle scopeModule = loader.GetModuleHandleFromAssemblyPtr(new TargetPointer(vmScope)); - Contracts.ModuleLookupTables lookupTables = loader.GetLookupTables(scopeModule); - TargetPointer referencedModule = loader.GetModuleLookupMapElement(lookupTables.ManifestModuleReferences, tkAssemblyRef, out _); + TargetPointer referencedModule = loader.GetModuleLookupMapElement( + scopeModule, + ModuleLookupMapKind.ManifestModuleReferences, + tkAssemblyRef, + out _); if (referencedModule != TargetPointer.Null) { Contracts.ModuleHandle referencedModuleHandle = loader.GetModuleHandleFromModulePtr(referencedModule); @@ -2745,8 +2751,11 @@ public int GetILCodeAndSig(ulong vmAssembly, uint functionToken, DacDbiTargetBuf if ((methodDef.ImplAttributes & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL) throw Marshal.GetExceptionForHR(CorDbgHResults.CORDBG_E_FUNCTION_NOT_IL)!; - ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); - TargetPointer methodDescPtr = loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, functionToken, out _); + TargetPointer methodDescPtr = loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToDesc, + functionToken, + out _); if (methodDescPtr != TargetPointer.Null) { IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; @@ -2957,8 +2966,7 @@ private static TargetPointer FindLoadedMethodRefOrDef(ILoader loader, Contracts. uint tokenType = token & EcmaMetadataUtils.TokenTypeMask; if (tokenType == (uint)EcmaMetadataUtils.TokenType.mdtMethodDef) { - ModuleLookupTables lookupTables = loader.GetLookupTables(module); - return loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, token, out _); + return loader.GetModuleLookupMapElement(module, ModuleLookupMapKind.MethodDefToDesc, token, out _); } else if (tokenType == (uint)EcmaMetadataUtils.TokenType.mdtMemberRef) @@ -3422,14 +3430,13 @@ public int GetTypeHandle(ulong vmModule, uint metadataToken, ulong* pRetVal) Contracts.ILoader loader = _target.Contracts.Loader; TargetPointer module = new TargetPointer(vmModule); Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(module); - Contracts.ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); switch ((EcmaMetadataUtils.TokenType)(metadataToken & EcmaMetadataUtils.TokenTypeMask)) { case EcmaMetadataUtils.TokenType.mdtTypeDef: - *pRetVal = loader.GetModuleLookupMapElement(lookupTables.TypeDefToMethodTable, metadataToken, out var _).Value; + *pRetVal = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeDefToMethodTable, metadataToken, out var _).Value; break; case EcmaMetadataUtils.TokenType.mdtTypeRef: - *pRetVal = loader.GetModuleLookupMapElement(lookupTables.TypeRefToMethodTable, metadataToken, out var _).Value; + *pRetVal = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeRefToMethodTable, metadataToken, out var _).Value; break; default: throw Marshal.GetExceptionForHR(CorDbgHResults.CORDBG_E_CLASS_NOT_LOADED)!; @@ -3865,8 +3872,11 @@ public int GetEnCHangingFieldInfo(EnCHangingFieldInfo* pEnCFieldInfo, FieldData* _ = LookupTypeDefOrRefInAssembly(vmAssembly, metadataToken); Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromAssemblyPtr(new TargetPointer(vmAssembly)); - Contracts.ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); - TargetPointer fieldDescPointer = loader.GetModuleLookupMapElement(lookupTables.FieldDefToDesc, fldToken, out _); + TargetPointer fieldDescPointer = loader.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.FieldDefToDesc, + fldToken, + out _); if (fieldDescPointer == TargetPointer.Null || mrts.DoesEnCFieldDescNeedFixup(fieldDescPointer)) throw Marshal.GetExceptionForHR(CorDbgHResults.CORDBG_E_ENC_HANGING_FIELD)!; @@ -3958,15 +3968,14 @@ internal ITypeHandle LookupTypeDefOrRefInAssembly(ulong vmAssembly, uint metadat ILoader loader = _target.Contracts.Loader; IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromAssemblyPtr(new TargetPointer(vmAssembly)); - ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); TargetPointer mt; switch ((EcmaMetadataUtils.TokenType)(metadataToken & EcmaMetadataUtils.TokenTypeMask)) { case EcmaMetadataUtils.TokenType.mdtTypeDef: - mt = loader.GetModuleLookupMapElement(lookupTables.TypeDefToMethodTable, metadataToken, out _); + mt = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeDefToMethodTable, metadataToken, out _); break; case EcmaMetadataUtils.TokenType.mdtTypeRef: - mt = loader.GetModuleLookupMapElement(lookupTables.TypeRefToMethodTable, metadataToken, out _); + mt = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeRefToMethodTable, metadataToken, out _); break; default: return null; @@ -5692,8 +5701,11 @@ public int AreOptimizationsDisabled(ulong vmModule, uint methodTk, Interop.BOOL* { ILoader loader = _target.Contracts.Loader; Contracts.ModuleHandle module = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); - ModuleLookupTables lookupTables = loader.GetLookupTables(module); - TargetPointer methodDesc = loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, methodTk, out _); + TargetPointer methodDesc = loader.GetModuleLookupMapElement( + module, + ModuleLookupMapKind.MethodDefToDesc, + methodTk, + out _); if (methodDesc != TargetPointer.Null) { @@ -5740,12 +5752,15 @@ public int GetActiveRejitILCodeVersionNode(ulong vmModule, uint methodTk, ulong* ILoader loader = _target.Contracts.Loader; Contracts.ModuleHandle module = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); - ModuleLookupTables lookupTables = loader.GetLookupTables(module); TargetPointer methodDesc = TargetPointer.Null; if ((EcmaMetadataUtils.TokenType)(methodTk & EcmaMetadataUtils.TokenTypeMask) != EcmaMetadataUtils.TokenType.mdtMethodDef) throw new ArgumentException("methodTk must be a MethodDef token.", nameof(methodTk)); - methodDesc = loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, methodTk, out _); + methodDesc = loader.GetModuleLookupMapElement( + module, + ModuleLookupMapKind.MethodDefToDesc, + methodTk, + out _); if (methodDesc != TargetPointer.Null) { @@ -5792,11 +5807,10 @@ public int GetEnCILCodeAndSig(ulong vmModule, uint methodTk, nuint enCVersion, D ILoader loader = _target.Contracts.Loader; Contracts.ModuleHandle module = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); - ModuleLookupTables lookupTables = loader.GetLookupTables(module); if ((EcmaMetadataUtils.TokenType)(methodTk & EcmaMetadataUtils.TokenTypeMask) != EcmaMetadataUtils.TokenType.mdtMethodDef) throw new ArgumentException("methodTk must be a MethodDef token.", nameof(methodTk)); - TargetPointer methodDesc = loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, methodTk, out _); + TargetPointer methodDesc = loader.GetModuleLookupMapElement(module, ModuleLookupMapKind.MethodDefToDesc, methodTk, out _); if (methodDesc != TargetPointer.Null) { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/TypeDataWalk.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/TypeDataWalk.cs index a33386c22647c9..918cacc8389380 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/TypeDataWalk.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/TypeDataWalk.cs @@ -211,15 +211,14 @@ private ITypeHandle ObjRefOrPrimitiveTypeArg(DebuggerIPCE_TypeArgData* pInfo, Co ILoader loader = _target.Contracts.Loader; IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromAssemblyPtr(new TargetPointer(vmAssembly)); - ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); TargetPointer mt; switch ((EcmaMetadataUtils.TokenType)(metadataToken & EcmaMetadataUtils.TokenTypeMask)) { case EcmaMetadataUtils.TokenType.mdtTypeDef: - mt = loader.GetModuleLookupMapElement(lookupTables.TypeDefToMethodTable, metadataToken, out _); + mt = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeDefToMethodTable, metadataToken, out _); break; case EcmaMetadataUtils.TokenType.mdtTypeRef: - mt = loader.GetModuleLookupMapElement(lookupTables.TypeRefToMethodTable, metadataToken, out _); + mt = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeRefToMethodTable, metadataToken, out _); break; default: return null; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs index 18255e48911da2..c0574ee6e72952 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs @@ -2557,20 +2557,19 @@ int ISOSDacInterface.GetMethodDescFromToken(ClrDataAddress moduleAddr, uint toke Contracts.ILoader loader = _target.Contracts.Loader; TargetPointer module = moduleAddr.ToTargetPointer(_target); Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(module); - Contracts.ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); switch ((EcmaMetadataUtils.TokenType)(token & EcmaMetadataUtils.TokenTypeMask)) { case EcmaMetadataUtils.TokenType.mdtFieldDef: - *methodDesc = loader.GetModuleLookupMapElement(lookupTables.FieldDefToDesc, token, out var _).ToClrDataAddress(_target); + *methodDesc = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.FieldDefToDesc, token, out var _).ToClrDataAddress(_target); break; case EcmaMetadataUtils.TokenType.mdtMethodDef: - *methodDesc = loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, token, out var _).ToClrDataAddress(_target); + *methodDesc = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.MethodDefToDesc, token, out var _).ToClrDataAddress(_target); break; case EcmaMetadataUtils.TokenType.mdtTypeDef: - *methodDesc = loader.GetModuleLookupMapElement(lookupTables.TypeDefToMethodTable, token, out var _).ToClrDataAddress(_target); + *methodDesc = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeDefToMethodTable, token, out var _).ToClrDataAddress(_target); break; case EcmaMetadataUtils.TokenType.mdtTypeRef: - *methodDesc = loader.GetModuleLookupMapElement(lookupTables.TypeRefToMethodTable, token, out var _).ToClrDataAddress(_target); + *methodDesc = loader.GetModuleLookupMapElement(moduleHandle, ModuleLookupMapKind.TypeRefToMethodTable, token, out var _).ToClrDataAddress(_target); break; default: throw new ArgumentException(); @@ -3150,18 +3149,12 @@ int ISOSDacInterface.GetModuleData(ClrDataAddress moduleAddr, DacpModuleData* da data->LoaderAllocator = contract.GetLoaderAllocator(handle).ToClrDataAddress(_target); - Contracts.ModuleLookupTables tables = contract.GetLookupTables(handle); - data->FieldDefToDescMap = ReadMapBase(_target, tables.FieldDefToDesc, tables.TableDataOffset); - data->ManifestModuleReferencesMap = ReadMapBase(_target, tables.ManifestModuleReferences, tables.TableDataOffset); - data->MemberRefToDescMap = ReadMapBase(_target, tables.MemberRefToDesc, tables.TableDataOffset); - data->MethodDefToDescMap = ReadMapBase(_target, tables.MethodDefToDesc, tables.TableDataOffset); - data->TypeDefToMethodTableMap = ReadMapBase(_target, tables.TypeDefToMethodTable, tables.TableDataOffset); - data->TypeRefToMethodTableMap = ReadMapBase(_target, tables.TypeRefToMethodTable, tables.TableDataOffset); - - static ClrDataAddress ReadMapBase(Target target, TargetPointer table, uint offset) - => table == TargetPointer.Null - ? default - : target.ReadPointer(table + offset).ToClrDataAddress(target); + data->FieldDefToDescMap = contract.GetModuleLookupMapBase(handle, ModuleLookupMapKind.FieldDefToDesc).ToClrDataAddress(_target); + data->ManifestModuleReferencesMap = contract.GetModuleLookupMapBase(handle, ModuleLookupMapKind.ManifestModuleReferences).ToClrDataAddress(_target); + data->MemberRefToDescMap = contract.GetModuleLookupMapBase(handle, ModuleLookupMapKind.MemberRefToDesc).ToClrDataAddress(_target); + data->MethodDefToDescMap = contract.GetModuleLookupMapBase(handle, ModuleLookupMapKind.MethodDefToDesc).ToClrDataAddress(_target); + data->TypeDefToMethodTableMap = contract.GetModuleLookupMapBase(handle, ModuleLookupMapKind.TypeDefToMethodTable).ToClrDataAddress(_target); + data->TypeRefToMethodTableMap = contract.GetModuleLookupMapBase(handle, ModuleLookupMapKind.TypeRefToMethodTable).ToClrDataAddress(_target); // Always 0 - .NET no longer has these concepts data->dwModuleID = 0; @@ -4827,22 +4820,21 @@ int ISOSDacInterface.TraverseModuleMap(ModuleMapType mmt, ClrDataAddress moduleA Contracts.ILoader loader = _target.Contracts.Loader; TargetPointer moduleAddrPtr = moduleAddr.ToTargetPointer(_target); Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(moduleAddrPtr); - Contracts.ModuleLookupTables lookupTables = loader.GetLookupTables(moduleHandle); switch (mmt) { case ModuleMapType.TYPEDEFTOMETHODTABLE: - elements = loader.EnumerateModuleLookupMap(lookupTables.TypeDefToMethodTable); + elements = loader.EnumerateModuleLookupMap(moduleHandle, ModuleLookupMapKind.TypeDefToMethodTable); break; case ModuleMapType.TYPEREFTOMETHODTABLE: - elements = loader.EnumerateModuleLookupMap(lookupTables.TypeRefToMethodTable); + elements = loader.EnumerateModuleLookupMap(moduleHandle, ModuleLookupMapKind.TypeRefToMethodTable); break; default: throw new ArgumentException(); } - foreach ((TargetPointer element, uint index) in elements) + foreach ((TargetPointer element, uint metadataToken) in elements) { // Call the callback with each element - pCallback(index, element.ToClrDataAddress(_target).Value, token); + pCallback(EcmaMetadataUtils.GetRowId(metadataToken), element.ToClrDataAddress(_target).Value, token); } } catch (System.Exception ex) @@ -4852,7 +4844,7 @@ int ISOSDacInterface.TraverseModuleMap(ModuleMapType mmt, ClrDataAddress moduleA #if DEBUG if (_legacyImpl is not null) { - Dictionary expectedElements = elements.ToDictionary(tuple => tuple.Address.ToClrDataAddress(_target).Value, tuple => tuple.Index); + Dictionary expectedElements = elements.ToDictionary(tuple => tuple.Address.ToClrDataAddress(_target).Value, tuple => EcmaMetadataUtils.GetRowId(tuple.Index)); expectedElements.Add(default, 0); void* tokenDebug = GCHandle.ToIntPtr(GCHandle.Alloc(expectedElements)).ToPointer(); delegate* unmanaged callbackDebugPtr = &TraverseModuleMapCallback; @@ -5646,7 +5638,7 @@ int ISOSDacInterface7.GetMethodsWithProfilerModifiedIL(ClrDataAddress mod, ClrDa TargetPointer modulePtr = mod.ToTargetPointer(_target); Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(modulePtr); // iterate through typedef to method table map - foreach ((TargetPointer ptr, _) in loader.EnumerateModuleLookupMap(loader.GetLookupTables(moduleHandle).TypeDefToMethodTable)) + foreach ((TargetPointer ptr, _) in loader.EnumerateModuleLookupMap(moduleHandle, ModuleLookupMapKind.TypeDefToMethodTable)) { if (*pcMethodDescs >= cMethodDescs) break; diff --git a/src/native/managed/cdac/tests/DumpTests/IXCLRDataMethodDefinitionDumpTests.cs b/src/native/managed/cdac/tests/DumpTests/IXCLRDataMethodDefinitionDumpTests.cs index 236bb3ecde4b04..874f79a2f6ce4a 100644 --- a/src/native/managed/cdac/tests/DumpTests/IXCLRDataMethodDefinitionDumpTests.cs +++ b/src/native/managed/cdac/tests/DumpTests/IXCLRDataMethodDefinitionDumpTests.cs @@ -247,12 +247,14 @@ private IXCLRDataMethodDefinition GetGenericMethodDefinition() TypeDefinitionHandle tdh = MetadataTokens.TypeDefinitionHandle(rowId); TypeDefinition td = reader.GetTypeDefinition(tdh); - ModuleLookupTables tables = loader.GetLookupTables(coreLibModule); foreach (MethodDefinitionHandle mdh in td.GetMethods()) { uint token = (uint)MetadataTokens.GetToken(mdh); TargetPointer mdAddr = loader.GetModuleLookupMapElement( - tables.MethodDefToDesc, token, out _); + coreLibModule, + ModuleLookupMapKind.MethodDefToDesc, + token, + out _); if (mdAddr == TargetPointer.Null) continue; diff --git a/src/native/managed/cdac/tests/UnitTests/CodeVersionsTests.cs b/src/native/managed/cdac/tests/UnitTests/CodeVersionsTests.cs index 0d9ded6023a5c9..f11b12370f8e53 100644 --- a/src/native/managed/cdac/tests/UnitTests/CodeVersionsTests.cs +++ b/src/native/managed/cdac/tests/UnitTests/CodeVersionsTests.cs @@ -86,19 +86,20 @@ public static void AddCodeBlock(this Mock mock, MockCodeBlock public static void AddModule(this Mock mock, CodeVersionsMockModule module) { Contracts.ModuleHandle handle = new Contracts.ModuleHandle(module.Address); + TargetNUInt flags = new TargetNUInt(0); mock.Setup(l => l.GetModuleHandleFromModulePtr(module.Address)).Returns(handle); - mock.Setup(l => l.GetLookupTables(handle)).Returns(new ModuleLookupTables() { - MethodDefToILCodeVersioningState = module.MethodDefToILCodeVersioningStateAddress, - }); - mock.Setup(l => l.GetModuleLookupMapElement(module.MethodDefToILCodeVersioningStateAddress, It.IsAny(), out It.Ref.IsAny)) - .Returns((table, token, flags) => + mock.Setup(l => l.GetModuleLookupMapElement( + handle, + ModuleLookupMapKind.MethodDefToILCodeVersioningState, + It.IsAny(), + out flags)) + .Returns((_, kind, token, _) => { - flags = new TargetNUInt(0); if (module.MethodDefToILCodeVersioningStateTable.TryGetValue(EcmaMetadataUtils.GetRowId(token), out TargetPointer value)) { return value; } - throw new InvalidOperationException($"No token found for 0x{token:x} in table {table}"); + throw new InvalidOperationException($"No token found for 0x{token:x} in lookup map {kind}"); }); } diff --git a/src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs b/src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs index 38a185a17f372f..6e7e7a2b50c95d 100644 --- a/src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs +++ b/src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs @@ -629,13 +629,12 @@ public void ResolveTypeReference_TypeDef_PassesThrough(MockTarget.Architecture a [ClassData(typeof(MockTarget.StdArch))] public void ResolveTypeReference_TypeRef_NotCached_ReturnsClassNotLoaded(MockTarget.Architecture arch) { - const ulong refAsmPtr = 0x100, refManifest = 0x9001; + const ulong refAsmPtr = 0x100; ModuleHandle refHandle = Mod(0x1000); Mock loader = new(MockBehavior.Strict); loader.Setup(l => l.GetModuleHandleFromAssemblyPtr(Ptr(refAsmPtr))).Returns(refHandle); - loader.Setup(l => l.GetLookupTables(refHandle)).Returns(Tables(refManifest)); - SetupTypeRefCacheMiss(loader); + SetupTypeRefCacheMiss(loader, refHandle); Mock ecma = new(MockBehavior.Strict); ecma.Setup(e => e.GetMetadata(refHandle)).Returns((MetadataReader?)null); @@ -682,29 +681,22 @@ private static TypeDefinitionHandle AddTypeDef(MetadataBuilder mb, string @names MetadataTokens.FieldDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1)); - private static ModuleLookupTables Tables(ulong manifestModuleReferences) - => new ModuleLookupTables( - FieldDefToDesc: TargetPointer.Null, - ManifestModuleReferences: Ptr(manifestModuleReferences), - MemberRefToDesc: TargetPointer.Null, - MethodDefToDesc: TargetPointer.Null, - TypeDefToMethodTable: TargetPointer.Null, - TypeRefToMethodTable: TargetPointer.Null, - MethodDefToILCodeVersioningState: TargetPointer.Null, - TableDataOffset: 0); - - private static void SetupLookupMap(Mock loader, ulong table, uint token, ulong result) + private static void SetupLookupMap(Mock loader, ModuleHandle module, ModuleLookupMapKind kind, uint token, ulong result) { TargetNUInt flags = default; - loader.Setup(l => l.GetModuleLookupMapElement(Ptr(table), token, out flags)).Returns(Ptr(result)); + loader.Setup(l => l.GetModuleLookupMapElement(module, kind, token, out flags)).Returns(Ptr(result)); } - private static void SetupTypeRefCacheMiss(Mock loader) + private static void SetupTypeRefCacheMiss(Mock loader, ModuleHandle module) { - // The referencing module's TypeRef->MethodTable cache is empty (TypeRefToMethodTable == Null), - // so every Tier 1 lookup on the Null table misses. + // The referencing module's TypeRef->MethodTable cache misses. TargetNUInt flags = default; - loader.Setup(l => l.GetModuleLookupMapElement(TargetPointer.Null, It.IsAny(), out flags)).Returns(TargetPointer.Null); + loader.Setup(l => l.GetModuleLookupMapElement( + module, + ModuleLookupMapKind.TypeRefToMethodTable, + It.IsAny(), + out flags)) + .Returns(TargetPointer.Null); } private static DacDbiImpl CreateDacDbiWithMockContracts(MockTarget.Architecture arch, Mock loader, Mock ecma) @@ -731,14 +723,13 @@ public void ResolveTypeReference_TypeRef_AssemblyRefScope_ResolvesToTypeDef(Mock // Target module: TypeDef "NS.Foo" (row 2 -> token 0x02000002). var (targetReader, targetProvider) = BuildMetadata(mb => AddTypeDef(mb, "NS", "Foo")); - const ulong refAsmPtr = 0x100, targetAsmPtr = 0x200, refManifest = 0x9001, targetModPtr = 0x4000; + const ulong refAsmPtr = 0x100, targetAsmPtr = 0x200, targetModPtr = 0x4000; ModuleHandle refHandle = Mod(0x1000), targetHandle = Mod(0x2000); Mock loader = new(MockBehavior.Strict); loader.Setup(l => l.GetModuleHandleFromAssemblyPtr(Ptr(refAsmPtr))).Returns(refHandle); - loader.Setup(l => l.GetLookupTables(refHandle)).Returns(Tables(refManifest)); - SetupTypeRefCacheMiss(loader); - SetupLookupMap(loader, refManifest, MdtAssemblyRef | 1, targetModPtr); + SetupTypeRefCacheMiss(loader, refHandle); + SetupLookupMap(loader, refHandle, ModuleLookupMapKind.ManifestModuleReferences, MdtAssemblyRef | 1, targetModPtr); loader.Setup(l => l.GetModuleHandleFromModulePtr(Ptr(targetModPtr))).Returns(targetHandle); loader.Setup(l => l.GetAssembly(targetHandle)).Returns(Ptr(targetAsmPtr)); @@ -782,16 +773,14 @@ public void ResolveTypeReference_TypeRef_TypeForwarder_FollowsExportedType(MockT var (readerB, providerB) = BuildMetadata(mb => AddTypeDef(mb, "NS", "Bar")); const ulong refAsmPtr = 0x100, asmBPtr = 0x300; - const ulong refManifest = 0x9001, manifestA = 0x9002, modAPtr = 0x4000, modBPtr = 0x5000; + const ulong modAPtr = 0x4000, modBPtr = 0x5000; ModuleHandle refHandle = Mod(0x1000), handleA = Mod(0x2000), handleB = Mod(0x3000); Mock loader = new(MockBehavior.Strict); loader.Setup(l => l.GetModuleHandleFromAssemblyPtr(Ptr(refAsmPtr))).Returns(refHandle); - loader.Setup(l => l.GetLookupTables(refHandle)).Returns(Tables(refManifest)); - loader.Setup(l => l.GetLookupTables(handleA)).Returns(Tables(manifestA)); - SetupTypeRefCacheMiss(loader); - SetupLookupMap(loader, refManifest, MdtAssemblyRef | 1, modAPtr); - SetupLookupMap(loader, manifestA, MdtAssemblyRef | 1, modBPtr); + SetupTypeRefCacheMiss(loader, refHandle); + SetupLookupMap(loader, refHandle, ModuleLookupMapKind.ManifestModuleReferences, MdtAssemblyRef | 1, modAPtr); + SetupLookupMap(loader, handleA, ModuleLookupMapKind.ManifestModuleReferences, MdtAssemblyRef | 1, modBPtr); loader.Setup(l => l.GetModuleHandleFromModulePtr(Ptr(modAPtr))).Returns(handleA); loader.Setup(l => l.GetModuleHandleFromModulePtr(Ptr(modBPtr))).Returns(handleB); loader.Setup(l => l.GetAssembly(handleB)).Returns(Ptr(asmBPtr)); @@ -840,15 +829,14 @@ public void ResolveTypeReference_TypeRef_NestedType_ResolvesNestedTypeDef(MockTa mb.AddNestedType(inner, outer); }); - const ulong refAsmPtr = 0x100, targetAsmPtr = 0x200, refManifest = 0x9001, targetModPtr = 0x4000; + const ulong refAsmPtr = 0x100, targetAsmPtr = 0x200, targetModPtr = 0x4000; ModuleHandle refHandle = Mod(0x1000), targetHandle = Mod(0x2000); uint innerToken = (uint)MetadataTokens.GetToken(innerRefHandle); Mock loader = new(MockBehavior.Strict); loader.Setup(l => l.GetModuleHandleFromAssemblyPtr(Ptr(refAsmPtr))).Returns(refHandle); - loader.Setup(l => l.GetLookupTables(refHandle)).Returns(Tables(refManifest)); - SetupTypeRefCacheMiss(loader); - SetupLookupMap(loader, refManifest, MdtAssemblyRef | 1, targetModPtr); + SetupTypeRefCacheMiss(loader, refHandle); + SetupLookupMap(loader, refHandle, ModuleLookupMapKind.ManifestModuleReferences, MdtAssemblyRef | 1, targetModPtr); loader.Setup(l => l.GetModuleHandleFromModulePtr(Ptr(targetModPtr))).Returns(targetHandle); loader.Setup(l => l.GetAssembly(targetHandle)).Returns(Ptr(targetAsmPtr)); @@ -1011,10 +999,13 @@ public void GetNativeCodeInfo_FillsDataForAsyncVariant(MockTarget.Architecture a var loader = new Mock(); ModuleHandle moduleHandle = new(module); - ModuleLookupTables lookupTables = new() { MethodDefToDesc = new TargetPointer(0x2100) }; loader.Setup(l => l.GetModuleHandleFromAssemblyPtr(new TargetPointer(Assembly))).Returns(moduleHandle); - loader.Setup(l => l.GetLookupTables(moduleHandle)).Returns(lookupTables); - loader.Setup(l => l.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, MethodToken, out It.Ref.IsAny)).Returns(methodDesc); + loader.Setup(l => l.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToDesc, + MethodToken, + out It.Ref.IsAny)) + .Returns(methodDesc); MethodDescHandle methodDescHandle = new(methodDesc); MethodDescHandle asyncVariantHandle = new(asyncVariant); @@ -1068,12 +1059,15 @@ public void GetNativeCodeInfo_NoNativeCode_ReturnsMethodDesc(MockTarget.Architec TargetPointer module = new(0x2000); TargetPointer methodDesc = new(0x3000); ModuleHandle moduleHandle = new(module); - ModuleLookupTables lookupTables = new() { MethodDefToDesc = new TargetPointer(0x2100) }; var loader = new Mock(); loader.Setup(l => l.GetModuleHandleFromAssemblyPtr(new TargetPointer(Assembly))).Returns(moduleHandle); - loader.Setup(l => l.GetLookupTables(moduleHandle)).Returns(lookupTables); - loader.Setup(l => l.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, MethodToken, out It.Ref.IsAny)).Returns(methodDesc); + loader.Setup(l => l.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToDesc, + MethodToken, + out It.Ref.IsAny)) + .Returns(methodDesc); MethodDescHandle methodDescHandle = new(methodDesc); var rts = new Mock(); @@ -1247,10 +1241,12 @@ private static Mock SetupMockLoader(TargetPointer modulePtr, uint metho { var mockLoader = new Mock(); var moduleHandle = new Contracts.ModuleHandle(modulePtr); - var lookupTables = new ModuleLookupTables { MethodDefToDesc = new TargetPointer(0x4000) }; mockLoader.Setup(l => l.GetModuleHandleFromModulePtr(modulePtr)).Returns(moduleHandle); - mockLoader.Setup(l => l.GetLookupTables(moduleHandle)).Returns(lookupTables); - mockLoader.Setup(l => l.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, methodTk, out It.Ref.IsAny)) + mockLoader.Setup(l => l.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.MethodDefToDesc, + methodTk, + out It.Ref.IsAny)) .Returns(methodDesc); return mockLoader; } diff --git a/src/native/managed/cdac/tests/UnitTests/TypeHandleTests.cs b/src/native/managed/cdac/tests/UnitTests/TypeHandleTests.cs index 3ed4037d007bbb..dc86c9262e58c3 100644 --- a/src/native/managed/cdac/tests/UnitTests/TypeHandleTests.cs +++ b/src/native/managed/cdac/tests/UnitTests/TypeHandleTests.cs @@ -274,7 +274,6 @@ public void ClrDataTypeDefinition_GetTokenAndScopeReturnsConstructorValues(MockT public void ClrDataTypeInstance_GetDefinition(MockTarget.Architecture architecture) { const uint TypeDefToken = 0x02000001; - TargetPointer lookupMap = new(0x2000); TargetPointer definitionTypeAddress = new(0x3000); TargetTypeHandle typeHandle = new(0x4000); TargetTypeHandle definitionType = new(definitionTypeAddress); @@ -287,20 +286,15 @@ public void ClrDataTypeInstance_GetDefinition(MockTarget.Architecture architectu runtimeTypeSystem.TypeDefTokens[definitionType] = TypeDefToken; runtimeTypeSystem.TypeHandles[definitionTypeAddress] = definitionType; - ModuleLookupTables lookupTables = new( - FieldDefToDesc: TargetPointer.Null, - ManifestModuleReferences: TargetPointer.Null, - MemberRefToDesc: TargetPointer.Null, - MethodDefToDesc: TargetPointer.Null, - TypeDefToMethodTable: lookupMap, - TypeRefToMethodTable: TargetPointer.Null, - MethodDefToILCodeVersioningState: TargetPointer.Null, - TableDataOffset: 0); Mock loader = new(); loader.Setup(l => l.GetModuleHandleFromModulePtr(new TargetPointer(ModuleAddress))).Returns(moduleHandle); - loader.Setup(l => l.GetLookupTables(moduleHandle)).Returns(lookupTables); TargetNUInt lookupFlags = default; - loader.Setup(l => l.GetModuleLookupMapElement(lookupMap, TypeDefToken, out lookupFlags)).Returns(definitionTypeAddress); + loader.Setup(l => l.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.TypeDefToMethodTable, + TypeDefToken, + out lookupFlags)) + .Returns(definitionTypeAddress); TestPlaceholderTarget target = new TestPlaceholderTarget.Builder(architecture) .AddMockContract(runtimeTypeSystem) @@ -315,7 +309,12 @@ public void ClrDataTypeInstance_GetDefinition(MockTarget.Architecture architectu DacComNullableByRef nullTypeDefinition = new(isNullRef: true); Assert.Equal(HResults.E_POINTER, typeInstance.GetDefinition(nullTypeDefinition)); - loader.Setup(l => l.GetModuleLookupMapElement(lookupMap, TypeDefToken, out lookupFlags)).Returns(TargetPointer.Null); + loader.Setup(l => l.GetModuleLookupMapElement( + moduleHandle, + ModuleLookupMapKind.TypeDefToMethodTable, + TypeDefToken, + out lookupFlags)) + .Returns(TargetPointer.Null); DacComNullableByRef unloadedTypeDefinition = new(isNullRef: false); Assert.Equal(HResults.S_OK, typeInstance.GetDefinition(unloadedTypeDefinition)); Assert.IsType(unloadedTypeDefinition.Interface);