From bb2a03d85d74804f7eb5c314d3f0eb0622590be4 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Sat, 18 Jul 2026 22:24:53 -0700 Subject: [PATCH 1/3] use cdac for metadata serialization --- docs/design/datacontracts/Debugger.md | 11 +- docs/design/datacontracts/EcmaMetadata.md | 113 ++-- src/coreclr/debug/daccess/CMakeLists.txt | 2 + src/coreclr/debug/daccess/dacdbiimpl.cpp | 464 +++++++++++++++- src/coreclr/debug/daccess/dacdbiimpl.h | 7 +- src/coreclr/debug/di/CMakeLists.txt | 2 - src/coreclr/debug/di/module.cpp | 25 +- src/coreclr/debug/ee/debugger.cpp | 9 - src/coreclr/debug/ee/debugger.h | 16 - src/coreclr/debug/inc/dacdbiinterface.h | 55 +- src/coreclr/dlls/mscordbi/CMakeLists.txt | 1 - src/coreclr/inc/dacdbi.idl | 4 - src/coreclr/inc/metadata.h | 52 -- src/coreclr/inc/shash.h | 2 - src/coreclr/inc/utilcode.h | 1 - src/coreclr/md/CMakeLists.txt | 5 - src/coreclr/md/compiler/CMakeLists.txt | 15 +- src/coreclr/md/compiler/disp.cpp | 89 --- src/coreclr/md/compiler/disp.h | 21 - src/coreclr/md/compiler/regmeta.cpp | 69 +-- src/coreclr/md/compiler/regmeta.h | 6 - src/coreclr/md/compiler/verifylayouts.cpp | 13 - src/coreclr/md/datasource/CMakeLists.txt | 25 - src/coreclr/md/datasource/api.cpp | 30 - .../md/datasource/datatargetreader.cpp | 203 ------- src/coreclr/md/datasource/datatargetreader.h | 57 -- .../datasource/remotemdinternalrwsource.cpp | 240 -------- .../md/datasource/remotemdinternalrwsource.h | 69 --- src/coreclr/md/datasource/stdafx.h | 25 - src/coreclr/md/datasource/targettypes.cpp | 515 ------------------ src/coreclr/md/datasource/targettypes.h | 346 ------------ src/coreclr/md/enc/liteweightstgdbrw.cpp | 36 -- src/coreclr/md/enc/metamodelrw.cpp | 168 ------ src/coreclr/md/inc/VerifyLayouts.inc | 337 ------------ src/coreclr/md/inc/liteweightstgdb.h | 12 +- src/coreclr/md/inc/mdinternalrw.h | 1 - src/coreclr/md/inc/metamodel.h | 3 +- src/coreclr/md/inc/metamodelrw.h | 13 +- src/coreclr/md/inc/recordpool.h | 2 - src/coreclr/md/inc/stgpool.h | 8 - src/coreclr/md/inc/stgpooli.h | 3 - src/coreclr/md/inc/verifylayouts.h | 182 ------- src/coreclr/md/runtime/stgpool.cpp | 5 +- .../vm/datadescriptor/datadescriptor.inc | 2 - .../Contracts/IDebugger.cs | 2 +- .../Contracts/IEcmaMetadata.cs | 1 + .../CorDbHResults.cs | 1 + .../Contracts/Debugger/Debugger_1.cs | 2 +- .../Contracts/EcmaMetadata_1.cs | 334 ++++++------ .../Data/Debugger.cs | 2 - .../ClrDataModule.cs | 3 +- .../Dbi/DacDbiImpl.cs | 135 +++-- .../Dbi/IDacDbiInterface.cs | 12 +- .../StressTestApi/CdacStressApi.cs | 5 +- .../DacDbi/DacDbiDebuggerDumpTests.cs | 53 -- .../cdac/tests/UnitTests/DebuggerTests.cs | 40 +- 56 files changed, 836 insertions(+), 3018 deletions(-) delete mode 100644 src/coreclr/md/compiler/verifylayouts.cpp delete mode 100644 src/coreclr/md/datasource/CMakeLists.txt delete mode 100644 src/coreclr/md/datasource/api.cpp delete mode 100644 src/coreclr/md/datasource/datatargetreader.cpp delete mode 100644 src/coreclr/md/datasource/datatargetreader.h delete mode 100644 src/coreclr/md/datasource/remotemdinternalrwsource.cpp delete mode 100644 src/coreclr/md/datasource/remotemdinternalrwsource.h delete mode 100644 src/coreclr/md/datasource/stdafx.h delete mode 100644 src/coreclr/md/datasource/targettypes.cpp delete mode 100644 src/coreclr/md/datasource/targettypes.h delete mode 100644 src/coreclr/md/inc/VerifyLayouts.inc delete mode 100644 src/coreclr/md/inc/verifylayouts.h diff --git a/docs/design/datacontracts/Debugger.md b/docs/design/datacontracts/Debugger.md index 6923882643d8e8..f88a5f3fcef84f 100644 --- a/docs/design/datacontracts/Debugger.md +++ b/docs/design/datacontracts/Debugger.md @@ -1,11 +1,11 @@ # Contract Debugger -This contract is for reading debugger state from the target process, including initialization status, configuration flags, metadata update state, and JIT attach state. +This contract is for reading debugger state from the target process, including initialization status, metadata update state, and JIT attach state. ## APIs of contract ```csharp -record struct DebuggerData(bool IsLeftSideInitialized, uint DefinesBitField, uint MDStructuresVersion); +record struct DebuggerData(bool IsLeftSideInitialized); ``` ```csharp @@ -48,8 +48,6 @@ The contract additionally depends on these data descriptors | Data Descriptor Name | Field | Meaning | | --- | --- | --- | | `Debugger` | `LeftSideInitialized` | Whether the left-side debugger infrastructure is initialized | -| `Debugger` | `Defines` | Bitfield of compile-time debugger feature defines | -| `Debugger` | `MDStructuresVersion` | Version of metadata data structures | | `Debugger` | `RCThread` | Pointer to `DebuggerRCThread` | | `Debugger` | `RSRequestedSync` | Sync-at-event request flag | | `Debugger` | `SendExceptionsOutsideOfJMC` | Exception delivery policy flag | @@ -84,10 +82,7 @@ bool TryGetDebuggerData(out DebuggerData data) if (debuggerPtr == TargetPointer.Null) return false; bool leftSideInitialized = target.Read(debuggerPtr + /* Debugger::LeftSideInitialized offset */) != 0; - data = new DebuggerData( - IsLeftSideInitialized: leftSideInitialized, - DefinesBitField: target.Read(debuggerPtr + /* Debugger::Defines offset */), - MDStructuresVersion: target.Read(debuggerPtr + /* Debugger::MDStructuresVersion offset */)); + data = new DebuggerData(IsLeftSideInitialized: leftSideInitialized); return true; } diff --git a/docs/design/datacontracts/EcmaMetadata.md b/docs/design/datacontracts/EcmaMetadata.md index 3c62208b3dd524..a99a3debc092a1 100644 --- a/docs/design/datacontracts/EcmaMetadata.md +++ b/docs/design/datacontracts/EcmaMetadata.md @@ -7,6 +7,7 @@ This contract provides methods to get a view of the ECMA-335 metadata for a give ```csharp TargetSpan GetReadOnlyMetadataAddress(ModuleHandle handle); System.Reflection.Metadata.MetadataReader? GetMetadata(ModuleHandle handle); +byte[] GetReadWriteMetadata(ModuleHandle handle); ``` Types from other contracts: @@ -102,58 +103,72 @@ MetadataReader? GetMetadata(ModuleHandle handle) } case AvailableMetadataType.ReadWrite: { - // Get the module's PEAssembly from the Loader contract. - // Read PEAssembly::MDImport as an MDInternalRW. - // Read MDInternalRW::Stgdb as a CLiteWeightStgdbRW. - // Read the embedded CLiteWeightStgdbRW::MiniMd as a CMiniMdRW. - // Read CMiniMdRW::Schema as a CMiniMdSchema. - // - // Validate that CMiniMdRW::TableCount does not exceed the ECMA-335 table count. - // For each table, read its row count from CMiniMdSchema::RecordCounts. - // For each table, test its bit in CMiniMdSchema::Sorted to determine whether it is sorted. - // Decode CMiniMdSchema::Heaps to determine whether the string, GUID, and blob heaps use large indexes. - // Record CMiniMdRW::All4ByteColumns so the reconstructed image can preserve fixed-width variable columns. - // - // To read a storage pool: - // Read the pool head using the StgPool descriptor. - // Record the head segment's SegData and DataSize. - // Follow NextSegment until it is null, reading each remaining node as a StgPoolSeg. - // Record each non-empty segment's SegData and DataSize. - // Allocate one byte array large enough for all recorded segments. - // Read each segment into the array in chain order to produce one contiguous blob. - // - // Read CMiniMdRW::StringHeap as a storage pool. - // Read CMiniMdRW::BlobHeap as a storage pool. - // Read CMiniMdRW::UserStringHeap as a storage pool. - // Read CMiniMdRW::GuidHeap as a storage pool. - // For each table, read CMiniMdRW::Tables[i] as a storage pool containing that table's records. - // Read the metadata version string from CLiteWeightStgdbRW::MetadataAddress. - // Combine the schema, heaps, and table record blobs into a TargetEcmaMetadata value. - // - // Create a builder for a new contiguous ECMA-335 metadata image. - // Write the metadata root header and version string. - // Add stream headers for #Strings, #Blob, #GUID, #US, and the uncompressed tables stream #-. - // If all variable-width columns are 4 bytes, also add the #JTD marker - // stream. The official ECMA-335 metadata format doesn't encode columns this - // way but System.Reflection.Metadata does support this encoding variation - // when it observes the #JTD marker stream. - // See [MetadataReader](https://github.com/dotnet/runtime/blob/1b945942604aa94b4717243b6d301a17b7ae41f1/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs#L166) - // Append the string, blob, GUID, and user-string heap data and fill in their stream offsets. - // - // Begin the #- tables stream. - // Write the tables stream header and the heap-size flags from the reconstructed schema. - // Build the valid-table mask from tables with non-zero row counts. - // Build the sorted-table mask from the schema's per-table sorted flags. - // Write the valid and sorted masks. - // Write the row count for each valid table. - // Append each table's contiguous record blob in table-number order. - // Fill in the final tables stream offset and size. - // - // Create a MetadataReaderProvider over the reconstructed image. - // Return its MetadataReader. + // Reconstruct a contiguous ECMA-335 image from the module's writable + // (MDInternalRW) metadata and return a reader over it. + byte[] data = GetReadWriteMetadata(handle); + return MetadataReaderProvider.FromMetadataImage(ImmutableCollectionsMarshal.AsImmutableArray(data)).GetMetadataReader(); } } } + +// Reconstructs the module's writable (MDInternalRW) metadata as a single contiguous +// ECMA-335 metadata image. The result is cached per module and reused until the +// module's metadata generation counter (Module::MetadataGeneration) changes. +byte[] GetReadWriteMetadata(ModuleHandle handle) +{ + // If a blob was previously built for this handle and the module's metadata + // generation counter is unchanged, return the cached blob. + + // Get the module's PEAssembly from the Loader contract. + // Read PEAssembly::MDImport as an MDInternalRW. + // Read MDInternalRW::Stgdb as a CLiteWeightStgdbRW. + // Read the embedded CLiteWeightStgdbRW::MiniMd as a CMiniMdRW. + // Read CMiniMdRW::Schema as a CMiniMdSchema. + // + // Validate that CMiniMdRW::TableCount does not exceed the ECMA-335 table count. + // For each table, read its row count from CMiniMdSchema::RecordCounts. + // For each table, test its bit in CMiniMdSchema::Sorted to determine whether it is sorted. + // Decode CMiniMdSchema::Heaps to determine whether the string, GUID, and blob heaps use large indexes. + // Record CMiniMdRW::All4ByteColumns so the reconstructed image can preserve fixed-width variable columns. + // + // To read a storage pool: + // Read the pool head using the StgPool descriptor. + // Record the head segment's SegData and DataSize. + // Follow NextSegment until it is null, reading each remaining node as a StgPoolSeg. + // Record each non-empty segment's SegData and DataSize. + // Allocate one byte array large enough for all recorded segments. + // Read each segment into the array in chain order to produce one contiguous blob. + // + // Read CMiniMdRW::StringHeap as a storage pool. + // Read CMiniMdRW::BlobHeap as a storage pool. + // Read CMiniMdRW::UserStringHeap as a storage pool. + // Read CMiniMdRW::GuidHeap as a storage pool. + // For each table, read CMiniMdRW::Tables[i] as a storage pool containing that table's records. + // Read the metadata version string from CLiteWeightStgdbRW::MetadataAddress. + // Combine the schema, heaps, and table record blobs into a TargetEcmaMetadata value. + // + // Create a builder for a new contiguous ECMA-335 metadata image. + // Write the metadata root header and version string. + // Add stream headers for #Strings, #Blob, #GUID, #US, and the uncompressed tables stream #-. + // If all variable-width columns are 4 bytes, also add the #JTD marker + // stream. The official ECMA-335 metadata format doesn't encode columns this + // way but System.Reflection.Metadata does support this encoding variation + // when it observes the #JTD marker stream. + // See [MetadataReader](https://github.com/dotnet/runtime/blob/1b945942604aa94b4717243b6d301a17b7ae41f1/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs#L166) + // Append the string, blob, GUID, and user-string heap data and fill in their stream offsets. + // + // Begin the #- tables stream. + // Write the tables stream header and the heap-size flags from the reconstructed schema. + // Build the valid-table mask from tables with non-zero row counts. + // Build the sorted-table mask from the schema's per-table sorted flags. + // Write the valid and sorted masks. + // Write the row count for each valid table. + // Append each table's contiguous record blob in table-number order. + // Fill in the final tables stream offset and size. + // + // Cache the reconstructed image against the module's current metadata generation + // counter and return it. +} ``` ### Helper Methods diff --git a/src/coreclr/debug/daccess/CMakeLists.txt b/src/coreclr/debug/daccess/CMakeLists.txt index fc6b8ef3c68fa8..0abfaeee3639d8 100644 --- a/src/coreclr/debug/daccess/CMakeLists.txt +++ b/src/coreclr/debug/daccess/CMakeLists.txt @@ -42,6 +42,8 @@ convert_to_absolute_path(DACCESS_SOURCES ${DACCESS_SOURCES}) add_library_clr(daccess ${DACCESS_SOURCES}) set_target_properties(daccess PROPERTIES DAC_COMPONENT TRUE) +# dacdbiimpl.cpp reconstructs read-write (MDInternalRW) metadata using the internal metadata types. +target_compile_definitions(daccess PRIVATE FEATURE_METADATA_INTERNAL_APIS) target_precompile_headers(daccess PRIVATE [["stdafx.h"]]) target_link_libraries(daccess PRIVATE cdac_api) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 5f96d98b6e228d..17381db635f902 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -31,6 +31,12 @@ #include "request_common.h" #include "conditionalweaktable.h" +#include "metamodelro.h" +#include "metamodelrw.h" +#include "liteweightstgdb.h" +#include "mdinternalrw.h" +#include "stgpool.h" + #ifndef USE_DAC_TABLE_RVA extern "C" bool TryGetSymbol(ICorDebugDataTarget* dataTarget, uint64_t baseAddress, const char* symbolName, uint64_t* symbolAddress); #include @@ -3894,7 +3900,437 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetMetadata(VMPTR_Module vmModule return hr; } -// Implementation of IDacDbiInterface::GetSymbolsBuffer +//----------------------------------------------------------------------------- +// Serialization of the target's writable (MDInternalRW) metadata into a +// single contiguous ECMA-335 metadata image. +//----------------------------------------------------------------------------- +namespace +{ + // Heap index size flags (ECMA-335 II.24.2.6) + const BYTE HEAP_STRING_4 = 0x01; + const BYTE HEAP_GUID_4 = 0x02; + const BYTE HEAP_BLOB_4 = 0x04; + + const ULONG64 MaxPoolBytes = 100000000; + const ULONG32 MaxPoolSegments = 1000; + const ULONG32 MaxTableCount = 64; + + FORCEINLINE ULONG32 AlignUp4(ULONG32 value) + { + return (value + 3) & ~(ULONG32)3; + } + + // Owns a copy of a coalesced storage pool. + struct PoolData + { + NewArrayHolder Data; + ULONG32 Size; + + PoolData() : Data(NULL), Size(0) {} + }; + + // Coalesce the data of a StgPool's segment chain. StgPool derives from StgPoolSeg, + // so the head pool and every extension segment are walked through StgPoolSeg. + void ReadStoragePool(TADDR poolAddress, PoolData & result) + { + TADDR segData[MaxPoolSegments]; + ULONG32 segSize[MaxPoolSegments]; + ULONG32 segCount = 0; + ULONG64 totalSize = 0; + + StgPoolSeg * pSeg = dac_cast(poolAddress); + for (ULONG32 iteration = 0; ; iteration++) + { + ULONG32 dataSize = pSeg->GetDataSize(); + if (iteration >= MaxPoolSegments || totalSize > MaxPoolBytes || dataSize > MaxPoolBytes) + { + ThrowHR(CLDB_E_FILE_CORRUPT); + } + if (dataSize > 0) + { + segData[segCount] = (TADDR)pSeg->GetSegData(); + segSize[segCount] = dataSize; + segCount++; + totalSize += dataSize; + } + + TADDR nextSegment = (TADDR)pSeg->GetNextSeg(); + if (nextSegment == (TADDR)NULL) + { + break; + } + pSeg = dac_cast(nextSegment); + } + + result.Size = (ULONG32)totalSize; + result.Data = new BYTE[result.Size == 0 ? 1 : result.Size]; + ULONG32 offset = 0; + for (ULONG32 i = 0; i < segCount; i++) + { + DacReadAll(segData[i], result.Data + offset, segSize[i], true); + offset += segSize[i]; + } + } + + // Minimal growable byte buffer used to assemble the ECMA-335 metadata image. + class MetadataBlobBuilder + { + public: + MetadataBlobBuilder() : m_pData(NULL), m_count(0), m_capacity(0) {} + ~MetadataBlobBuilder() { delete[] m_pData; } + + ULONG32 Count() const { return m_count; } + const BYTE * Data() const { return m_pData; } + + void WriteByte(BYTE value) { EnsureCapacity(m_count + 1); m_pData[m_count++] = value; } + void WriteUInt16(UINT16 value) { WriteRaw(&value, sizeof(value)); } + void WriteUInt32(UINT32 value) { WriteRaw(&value, sizeof(value)); } + void WriteUInt64(UINT64 value) { WriteRaw(&value, sizeof(value)); } + void WriteBytes(const BYTE * pData, ULONG32 size) { if (size != 0) WriteRaw(pData, size); } + + void WriteZeros(ULONG32 count) + { + EnsureCapacity(m_count + count); + memset(m_pData + m_count, 0, count); + m_count += count; + } + + // Reserve a 4-byte slot to be patched later; returns its offset. + ULONG32 Reserve4() + { + ULONG32 offset = m_count; + WriteUInt32(0); + return offset; + } + + void PatchUInt32(ULONG32 offset, UINT32 value) + { + memcpy(m_pData + offset, &value, sizeof(value)); + } + + // Writes a null-terminated ASCII string padded with zeros to a 4-byte boundary, + // occupying AlignUp(length + 1, 4) bytes total. + void WriteAlignedString(const char * value, ULONG32 length) + { + ULONG32 total = AlignUp4(length + 1); + EnsureCapacity(m_count + total); + if (length != 0) + { + memcpy(m_pData + m_count, value, length); + } + memset(m_pData + m_count + length, 0, total - length); + m_count += total; + } + + // Writes a heap's bytes padded with zeros to a 4-byte boundary. + void WriteAlignedHeap(const BYTE * pData, ULONG32 size) + { + WriteBytes(pData, size); + WriteZeros(AlignUp4(size) - size); + } + + private: + void WriteRaw(const void * pData, ULONG32 size) + { + EnsureCapacity(m_count + size); + memcpy(m_pData + m_count, pData, size); + m_count += size; + } + + void EnsureCapacity(ULONG32 needed) + { + if (needed <= m_capacity) + { + return; + } + ULONG32 newCapacity = (m_capacity == 0) ? 256 : m_capacity; + while (newCapacity < needed) + { + newCapacity *= 2; + } + BYTE * pNew = new BYTE[newCapacity]; + if (m_count != 0) + { + memcpy(pNew, m_pData, m_count); + } + delete[] m_pData; + m_pData = pNew; + m_capacity = newCapacity; + } + + BYTE * m_pData; + ULONG32 m_count; + ULONG32 m_capacity; + }; + + // Writes an ECMA-335 stream header (offset placeholder, size, name) and returns + // the offset of the placeholder for the caller to patch with the stream start. + ULONG32 WriteStreamHeader(MetadataBlobBuilder & builder, const char * name, ULONG32 size) + { + ULONG32 offsetField = builder.Reserve4(); + builder.WriteUInt32(size); + builder.WriteAlignedString(name, (ULONG32)strlen(name)); + return offsetField; + } +} + +// Reconstruct and serialize the writable metadata of a module into a freshly allocated +// ECMA-335 image. On success *ppBlob is a new[]-allocated buffer of *pcbBlob bytes that +// the caller owns. +void DacDbiInterfaceImpl::SerializeReadWriteMetadata(Module * pModule, BYTE ** ppBlob, ULONG32 * pcbBlob) +{ + PEAssembly * pPEAssembly = pModule->GetPEAssembly(); + TADDR mdRWAddr = pPEAssembly->GetMDInternalRWAddress(); + if (mdRWAddr == (TADDR)NULL) + { + ThrowHR(E_INVALIDARG); + } + + MDInternalRW * pMDInternalRW = dac_cast(mdRWAddr); + CLiteWeightStgdbRW * pStgdb = dac_cast((TADDR)pMDInternalRW->m_pStgdb); + CMiniMdRW * pMiniMd = dac_cast(PTR_HOST_MEMBER_TADDR(CLiteWeightStgdbRW, pStgdb, m_MiniMd)); + + ULONG32 tableCount = pMiniMd->GetCountTables(); + if (tableCount > MaxTableCount) + { + ThrowHR(CLDB_E_FILE_CORRUPT); + } + + // ECMA-335 II.24.2.6 + ULONG32 rowCounts[MaxTableCount]; + for (ULONG32 i = 0; i < tableCount; i++) + { + rowCounts[i] = pMiniMd->m_Schema.m_cRecs[i]; + } + + ULONG64 sorted = pMiniMd->m_Schema.m_sorted; + BYTE heaps = pMiniMd->m_Schema.m_heaps; + + bool largeStringHeap = (heaps & HEAP_STRING_4) != 0; + bool largeGuidHeap = (heaps & HEAP_GUID_4) != 0; + bool largeBlobHeap = (heaps & HEAP_BLOB_4) != 0; + bool all4ByteColumns = pMiniMd->m_fAll4ByteColumns != FALSE; + + PoolData stringHeap; + PoolData blobHeap; + PoolData userStringHeap; + PoolData guidHeap; + ReadStoragePool(PTR_HOST_MEMBER_TADDR(CMiniMdRW, pMiniMd, m_StringHeap), stringHeap); + ReadStoragePool(PTR_HOST_MEMBER_TADDR(CMiniMdRW, pMiniMd, m_BlobHeap), blobHeap); + ReadStoragePool(PTR_HOST_MEMBER_TADDR(CMiniMdRW, pMiniMd, m_UserStringHeap), userStringHeap); + ReadStoragePool(PTR_HOST_MEMBER_TADDR(CMiniMdRW, pMiniMd, m_GuidHeap), guidHeap); + + // Coalesce the record data for each table. + NewArrayHolder tables = new PoolData[tableCount == 0 ? 1 : tableCount]; + TADDR tablesBase = PTR_HOST_MEMBER_TADDR(CMiniMdRW, pMiniMd, m_Tables); + ULONG32 tableStride = (ULONG32)sizeof(MetaData::TableRW); + for (ULONG32 i = 0; i < tableCount; i++) + { + ReadStoragePool(tablesBase + i * tableStride, tables[i]); + } + + // Read the metadata version string (ECMA-335 II.24.2.1 metadata root): + // Signature(4) | MajorVersion(2) | MinorVersion(2) | Reserved(4) | VersionLength(4) | Version[VersionLength] + const ULONG32 MetadataRootVersionLengthOffset = 12; + const ULONG32 MetadataRootVersionStringOffset = 16; + const ULONG32 MaxMetadataVersionLength = 256; + BYTE versionBuffer[MaxMetadataVersionLength]; + ULONG32 versionLength = 0; + TADDR metadataRootAddress = (TADDR)pStgdb->m_pvMd; + if (metadataRootAddress != (TADDR)NULL) + { + ULONG32 rawVersionLength = *dac_cast(metadataRootAddress + MetadataRootVersionLengthOffset); + if (rawVersionLength != 0) + { + ULONG32 toRead = rawVersionLength < MaxMetadataVersionLength ? rawVersionLength : MaxMetadataVersionLength; + DacReadAll(metadataRootAddress + MetadataRootVersionStringOffset, versionBuffer, toRead, true); + for (versionLength = 0; versionLength < toRead; versionLength++) + { + if (versionBuffer[versionLength] == 0) + { + break; + } + } + } + } + + // From the multiple different storage pools, build a single contiguous ECMA-335 metadata blob. + MetadataBlobBuilder builder; + builder.WriteUInt32(0x424A5342); + + // major version + builder.WriteUInt16(1); + + // minor version + builder.WriteUInt16(1); + + // reserved + builder.WriteUInt32(0); + + builder.WriteUInt32(AlignUp4(versionLength + 1)); + builder.WriteAlignedString((const char *)versionBuffer, versionLength); + + // reserved + builder.WriteUInt16(0); + + // number of streams + UINT16 numStreams = 5; // #Strings, #US, #Blob, #GUID, #~ (metadata) + if (all4ByteColumns) + { + // The #JTD marker stream directs the reader to a "minimal delta" image + // in which all variable-sized columns are 4 bytes long. + numStreams++; + } + builder.WriteUInt16(numStreams); + + // Write stream headers + if (all4ByteColumns) + { + ULONG32 jtdOffset = WriteStreamHeader(builder, "#JTD", 0); + builder.PatchUInt32(jtdOffset, builder.Count()); + } + + ULONG32 stringsOffset = WriteStreamHeader(builder, "#Strings", AlignUp4(stringHeap.Size)); + ULONG32 blobOffset = WriteStreamHeader(builder, "#Blob", AlignUp4(blobHeap.Size)); + ULONG32 guidOffset = WriteStreamHeader(builder, "#GUID", AlignUp4(guidHeap.Size)); + ULONG32 userStringOffset = WriteStreamHeader(builder, "#US", AlignUp4(userStringHeap.Size)); + + // Use the "uncompressed" tables stream name as the runtime may have created the *Ptr tables + // that are only present in the uncompressed tables stream. + ULONG32 tablesOffset = builder.Reserve4(); + ULONG32 tablesSize = builder.Reserve4(); + builder.WriteAlignedString("#-", 2); + + // Write the heap-style streams + builder.PatchUInt32(stringsOffset, builder.Count()); + builder.WriteAlignedHeap(stringHeap.Data, stringHeap.Size); + + builder.PatchUInt32(blobOffset, builder.Count()); + builder.WriteAlignedHeap(blobHeap.Data, blobHeap.Size); + + builder.PatchUInt32(guidOffset, builder.Count()); + builder.WriteAlignedHeap(guidHeap.Data, guidHeap.Size); + + builder.PatchUInt32(userStringOffset, builder.Count()); + builder.WriteAlignedHeap(userStringHeap.Data, userStringHeap.Size); + + // Write tables stream + ULONG32 tableStreamStart = builder.Count(); + builder.PatchUInt32(tablesOffset, tableStreamStart); + + // Write tables stream header + builder.WriteUInt32(0); // reserved + // ECMA-335 II.24.2.6: MajorVersion shall be 2, MinorVersion shall be 0. + builder.WriteByte(2); // major version + builder.WriteByte(0); // minor version + BYTE heapSizes = + (BYTE)((largeStringHeap ? HEAP_STRING_4 : 0) | + (largeGuidHeap ? HEAP_GUID_4 : 0) | + (largeBlobHeap ? HEAP_BLOB_4 : 0)); + builder.WriteByte(heapSizes); + builder.WriteByte(1); // reserved + + ULONG64 validTables = 0; + for (ULONG32 i = 0; i < tableCount; i++) + { + if (rowCounts[i] != 0) + { + validTables |= (ULONG64)1 << i; + } + } + + ULONG64 sortedTables = 0; + for (ULONG32 i = 0; i < tableCount; i++) + { + if ((sorted & ((ULONG64)1 << i)) != 0) + { + sortedTables |= (ULONG64)1 << i; + } + } + + builder.WriteUInt64(validTables); + builder.WriteUInt64(sortedTables); + + for (ULONG32 i = 0; i < tableCount; i++) + { + if (rowCounts[i] != 0) + { + builder.WriteUInt32(rowCounts[i]); + } + } + + // Write the tables + for (ULONG32 i = 0; i < tableCount; i++) + { + builder.WriteBytes(tables[i].Data, tables[i].Size); + } + + // Patch the #- stream size now that the full table stream has been written. + builder.PatchUInt32(tablesSize, builder.Count() - tableStreamStart); + + ULONG32 blobSize = builder.Count(); + BYTE * pBlob = new BYTE[blobSize == 0 ? 1 : blobSize]; + memcpy(pBlob, builder.Data(), blobSize); + *ppBlob = pBlob; + *pcbBlob = blobSize; +} + +// Implementation of IDacDbiInterface::GetReadWriteMetadataSize +HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetReadWriteMetadataSize(VMPTR_Module vmModule, OUT ULONG32 * pSize) +{ + DD_ENTER_MAY_THROW; + + HRESULT hr = S_OK; + EX_TRY + { + if (pSize == NULL) + { + ThrowHR(E_INVALIDARG); + } + + *pSize = 0; + + Module * pModule = vmModule.GetDacPtr(); + BYTE * pRawBlob = NULL; + ULONG32 blobSize = 0; + SerializeReadWriteMetadata(pModule, &pRawBlob, &blobSize); + NewArrayHolder blob(pRawBlob); + *pSize = blobSize; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +// Implementation of IDacDbiInterface::FillReadWriteMetadata +HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::FillReadWriteMetadata(VMPTR_Module vmModule, BYTE * pBuffer, ULONG32 cbBuffer) +{ + DD_ENTER_MAY_THROW; + + HRESULT hr = S_OK; + EX_TRY + { + if (pBuffer == NULL) + { + ThrowHR(E_INVALIDARG); + } + + Module * pModule = vmModule.GetDacPtr(); + BYTE * pRawBlob = NULL; + ULONG32 blobSize = 0; + SerializeReadWriteMetadata(pModule, &pRawBlob, &blobSize); + NewArrayHolder blob(pRawBlob); + + if (cbBuffer < blobSize) + { + ThrowHR(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)); + } + + memcpy(pBuffer, pRawBlob, blobSize); + } + EX_CATCH_HRESULT(hr); + return hr; +} + HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetSymbolsBuffer(VMPTR_Module vmModule, OUT TargetBuffer * pTargetBuffer, OUT SymbolFormat * pSymbolFormat) { DD_ENTER_MAY_THROW; @@ -7099,32 +7535,6 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::AreOptimizationsDisabled(VMPTR_Mo return S_OK; } -HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetDefinesBitField(ULONG32 *pDefines) -{ - DD_ENTER_MAY_THROW; - if (pDefines == NULL) - return E_INVALIDARG; - - if (g_pDebugger == NULL) - return CORDBG_E_NOTREADY; - - *pDefines = g_pDebugger->m_defines; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetMDStructuresVersion(ULONG32* pMDStructuresVersion) -{ - DD_ENTER_MAY_THROW; - if (pMDStructuresVersion == NULL) - return E_INVALIDARG; - - if (g_pDebugger == NULL) - return CORDBG_E_NOTREADY; - - *pMDStructuresVersion = g_pDebugger->m_mdDataStructureVersion; - return S_OK; -} - HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::EnableGCNotificationEvents(BOOL fEnable) { DD_ENTER_MAY_THROW diff --git a/src/coreclr/debug/daccess/dacdbiimpl.h b/src/coreclr/debug/daccess/dacdbiimpl.h index ec0aa77dfc66af..1508f3de8bb57f 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.h +++ b/src/coreclr/debug/daccess/dacdbiimpl.h @@ -140,8 +140,6 @@ class DacDbiInterfaceImpl : HRESULT STDMETHODCALLTYPE GetILCodeVersionNodeData(VMPTR_ILCodeVersionNode vmILCodeVersionNode, DacSharedReJitInfo* pData); #endif // FEATURE_CODE_VERSIONING HRESULT STDMETHODCALLTYPE AreOptimizationsDisabled(VMPTR_Module vmModule, mdMethodDef methodTk, OUT BOOL* pOptimizationsDisabled); - HRESULT STDMETHODCALLTYPE GetDefinesBitField(ULONG32 *pDefines); - HRESULT STDMETHODCALLTYPE GetMDStructuresVersion(ULONG32* pMDStructuresVersion); HRESULT STDMETHODCALLTYPE EnableGCNotificationEvents(BOOL fEnable); HRESULT STDMETHODCALLTYPE GetAssemblyFromModule(VMPTR_Module vmModule, OUT VMPTR_Assembly *pvmAssembly); HRESULT STDMETHODCALLTYPE ParseContinuation(CORDB_ADDRESS continuationAddress, @@ -151,7 +149,12 @@ class DacDbiInterfaceImpl : HRESULT STDMETHODCALLTYPE EnumerateAsyncLocals(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeAddr, UINT32 state, FP_ASYNC_LOCAL_CALLBACK fpCallback, CALLBACK_DATA pUserData); HRESULT STDMETHODCALLTYPE GetGenericArgTokenIndex(VMPTR_MethodDesc vmMethod, OUT UINT32* pIndex); + HRESULT STDMETHODCALLTYPE GetReadWriteMetadataSize(VMPTR_Module vmModule, OUT ULONG32 * pSize); + HRESULT STDMETHODCALLTYPE FillReadWriteMetadata(VMPTR_Module vmModule, BYTE * pBuffer, ULONG32 cbBuffer); + private: + void SerializeReadWriteMetadata(Module * pModule, BYTE ** ppBlob, ULONG32 * pcbBlob); + void TypeHandleToExpandedTypeInfoImpl(AreValueTypesBoxed boxed, TypeHandle typeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo); diff --git a/src/coreclr/debug/di/CMakeLists.txt b/src/coreclr/debug/di/CMakeLists.txt index e9c6b14af9300c..59b8ffc5d04766 100644 --- a/src/coreclr/debug/di/CMakeLists.txt +++ b/src/coreclr/debug/di/CMakeLists.txt @@ -1,7 +1,5 @@ add_definitions( -DDBI_COMPILE - -DFEATURE_METADATA_CUSTOM_DATA_SOURCE - -DFEATURE_METADATA_DEBUGGEE_DATA_SOURCE -DFEATURE_NO_HOST -DFEATURE_METADATA_LOAD_TRUSTED_IMAGES) diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index c261d88df78c6b..2ff707a9593a38 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -495,23 +495,16 @@ void CordbModule::RefreshMetaData() IfFailThrow(GetProcess()->GetDAC()->GetPEFileMDInternalRW(m_vmPEFile, &remoteMDInternalRWAddr)); if (remoteMDInternalRWAddr != (TADDR)NULL) { - // we should only be doing this once to initialize, we don't support reopen with this technique _ASSERTE(m_pIMImport == NULL); - ULONG32 mdStructuresVersion; - HRESULT hr = GetProcess()->GetDAC()->GetMDStructuresVersion(&mdStructuresVersion); - IfFailThrow(hr); - ULONG32 mdStructuresDefines; - hr = GetProcess()->GetDAC()->GetDefinesBitField(&mdStructuresDefines); - IfFailThrow(hr); - IMetaDataDispenserCustom* pDispCustom = NULL; - hr = GetProcess()->GetDispenser()->QueryInterface(IID_IMetaDataDispenserCustom, (void**)&pDispCustom); - IfFailThrow(hr); - IMDCustomDataSource* pDataSource = NULL; - hr = CreateRemoteMDInternalRWSource(remoteMDInternalRWAddr, GetProcess()->GetDataTarget(), mdStructuresDefines, mdStructuresVersion, &pDataSource); - IfFailThrow(hr); - IMetaDataImport* pImport = NULL; - hr = pDispCustom->OpenScopeOnCustomDataSource(pDataSource, 0, IID_IMetaDataImport, (IUnknown**)&m_pIMImport); - IfFailThrow(hr); + ULONG32 cbSize = 0; + IfFailThrow(GetProcess()->GetDAC()->GetReadWriteMetadataSize(m_vmModule, &cbSize)); + CoTaskMemHolder pBuffer{ (BYTE*)CoTaskMemAlloc(cbSize) }; + + IfFailThrow(GetProcess()->GetDAC()->FillReadWriteMetadata(m_vmModule, pBuffer, cbSize)); + IMetaDataDispenserEx * pDisp = GetProcess()->GetDispenser(); + _ASSERTE(pDisp != NULL); + IfFailThrow(pDisp->OpenScopeOnMemory(pBuffer, cbSize, ofTakeOwnership, IID_IMetaDataImport, (IUnknown**)&m_pIMImport)); + pBuffer.Detach(); // ownership transferred to the IMetaDataImport UpdateInternalMetaData(); return; } diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 28b67b722794cc..89625aee5f389e 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -829,7 +829,6 @@ Debugger::Debugger() m_sendExceptionsOutsideOfJMC(TRUE), m_forceNonInterceptable(FALSE), m_pLazyData(NULL), - m_defines(_defines), m_isSuspendedForGarbageCollection(FALSE), m_isBlockedOnGarbageCollectionEvent(FALSE), m_willBlockOnGarbageCollectionEvent(FALSE), @@ -857,14 +856,6 @@ Debugger::Debugger() m_pForceCatchHandlerFoundEventsTable = new ForceCatchHandlerFoundTable(); m_pCustomNotificationTable = new CustomNotificationTable(); - //------------------------------------------------------------------------------ - // Metadata data structure version numbers - // - // 1 - initial state of the layouts ( .NET Framework 4.5.2 ) - // - // as data structure layouts change, add a new version number - // and comment the changes - m_mdDataStructureVersion = 1; m_fOutOfProcessSetContextEnabled = #if defined(OUT_OF_PROCESS_SETTHREADCONTEXT) && !defined(DACCESS_COMPILE) Thread::AreShadowStacksEnabled() || CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_OutOfProcessSetContext) != 0; diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 151ea1385d25e4..d417e670a51b69 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -2886,23 +2886,7 @@ class Debugger : public DebugInterface PTR_DebuggerLazyInit m_pLazyData; - // A list of all defines that affect layout of MD types - typedef enum _Target_Defines - { - DEFINE__DEBUG = 1, - } _Target_Defines; - - // A bitfield that has bits set at build time corresponding - // to which defines are active - static const int _defines = 0 -#ifdef _DEBUG - | DEFINE__DEBUG -#endif - ; - public: - DWORD m_defines; - DWORD m_mdDataStructureVersion; #ifndef DACCESS_COMPILE virtual void SuspendForGarbageCollectionStarted(); virtual void SuspendForGarbageCollectionCompleted(); diff --git a/src/coreclr/debug/inc/dacdbiinterface.h b/src/coreclr/debug/inc/dacdbiinterface.h index e739a2e98395b7..29db96c7d1c418 100644 --- a/src/coreclr/debug/inc/dacdbiinterface.h +++ b/src/coreclr/debug/inc/dacdbiinterface.h @@ -2044,36 +2044,6 @@ IDacDbiInterface : public IUnknown // virtual HRESULT STDMETHODCALLTYPE AreOptimizationsDisabled(VMPTR_Module vmModule, mdMethodDef methodTk, OUT BOOL* pOptimizationsDisabled) = 0; - // Retrieves a bit field indicating which defines were in use when clr was built. This only includes - // defines that are specified in the Debugger::_Target_Defines enumeration, which is a small subset of - // all defines. - // - // - // Arguments: - // pDefines - [out] The set of defines clr.dll was built with. Bit offsets are encoded using the - // enumeration Debugger::_Target_Defines - // - // Returns: - // S_OK if no error - // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible - // - virtual HRESULT STDMETHODCALLTYPE GetDefinesBitField(ULONG32 *pDefines) = 0; - - // Retrieves a version number indicating the shape of the data structures used in the Metadata implementation - // inside clr.dll. This number changes anytime a datatype layout changes so that they can be correctly - // deserialized from out of process - // - // - // Arguments: - // pMDStructuresVersion - [out] The layout version number for metadata data structures. See - // Debugger::Debugger() in Debug\ee\Debugger.cpp for a description of the options. - // - // Returns: - // S_OK if no error - // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible - // - virtual HRESULT STDMETHODCALLTYPE GetMDStructuresVersion(ULONG32* pMDStructuresVersion) = 0; - #ifdef FEATURE_CODE_VERSIONING // Retrieves the active rejit ILCodeVersionNode for a given module/methodDef, if it exists. // Active is defined as after GetReJitParameters returns from the profiler dll and @@ -2208,6 +2178,31 @@ IDacDbiInterface : public IUnknown VMPTR_MethodDesc vmMethod, OUT UINT32* pTokenIndex) = 0; + // Get the size in bytes of the serialized read-write metadata blob for a module. + // + // Arguments: + // vmModule - target module whose in-memory read-write metadata should be serialized. + // pSize - Out parameter receiving the size in bytes of the serialized ECMA-335 metadata blob. + // + // Notes: + // This reconstructs a contiguous ECMA-335 metadata image from the target's writable + // (MDInternalRW) metadata. Use FillReadWriteMetadata to retrieve the bytes into a + // caller-allocated buffer of at least *pSize bytes. + virtual HRESULT STDMETHODCALLTYPE GetReadWriteMetadataSize(VMPTR_Module vmModule, OUT ULONG32 * pSize) = 0; + + // Serialize the read-write metadata for a module into a caller-allocated buffer. + // + // Arguments: + // vmModule - target module whose in-memory read-write metadata should be serialized. + // pBuffer - caller-allocated buffer that receives the serialized ECMA-335 metadata blob. + // cbBuffer - size in bytes of pBuffer; must be at least the size reported by GetReadWriteMetadataSize. + // + // Notes: + // The resulting buffer is a contiguous ECMA-335 metadata image suitable for OpenScopeOnMemory. + // Returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) when cbBuffer is smaller than the + // serialized metadata size. + virtual HRESULT STDMETHODCALLTYPE FillReadWriteMetadata(VMPTR_Module vmModule, BYTE * pBuffer, ULONG32 cbBuffer) = 0; + // The following tag tells the DD-marshalling tool to stop scanning. // END_MARSHAL diff --git a/src/coreclr/dlls/mscordbi/CMakeLists.txt b/src/coreclr/dlls/mscordbi/CMakeLists.txt index 13a0b2ac4aa228..d1d9ec82151c9d 100644 --- a/src/coreclr/dlls/mscordbi/CMakeLists.txt +++ b/src/coreclr/dlls/mscordbi/CMakeLists.txt @@ -73,7 +73,6 @@ set(COREDBI_LIBRARIES mdcompiler-dbi mdruntime-dbi mdruntimerw-dbi - mddatasource_dbi corguids minipal ) diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index 73610b87d4a3d4..1538d1692149cf 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -402,10 +402,6 @@ interface IDacDbiInterface : IUnknown HRESULT AreOptimizationsDisabled([in] VMPTR_Module vmModule, [in] mdMethodDef methodTk, [out] BOOL * pOptimizationsDisabled); - // Defines - HRESULT GetDefinesBitField([out] ULONG32 * pDefines); - HRESULT GetMDStructuresVersion([out] ULONG32 * pMDStructuresVersion); - // Code Versioning (FEATURE_CODE_VERSIONING only) HRESULT GetActiveRejitILCodeVersionNode([in] VMPTR_Module vmModule, [in] mdMethodDef methodTk, [out] VMPTR_ILCodeVersionNode * pVmILCodeVersionNode); HRESULT GetNativeCodeVersionNode([in] VMPTR_MethodDesc vmMethod, [in] CORDB_ADDRESS codeStartAddress, [out] VMPTR_NativeCodeVersionNode * pVmNativeCodeVersionNode); diff --git a/src/coreclr/inc/metadata.h b/src/coreclr/inc/metadata.h index 28703d99f0d292..f614346586eaeb 100644 --- a/src/coreclr/inc/metadata.h +++ b/src/coreclr/inc/metadata.h @@ -1081,58 +1081,6 @@ DECLARE_INTERFACE_(IMDInternalEmit, IUnknown) }; // IMDInternalEmit -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - -struct IMDCustomDataSource; -class CMiniMdSchema; -struct CMiniTableDef; -namespace MetaData -{ - class DataBlob; -} - -// {CC0C8F7A-A00B-493D-80B6-CE0C92491670} -EXTERN_GUID(IID_IMDCustomDataSource, 0xcc0c8f7a, 0xa00b, 0x493d, 0x80, 0xb6, 0xce, 0xc, 0x92, 0x49, 0x16, 0x70); - -#undef INTERFACE -#define INTERFACE IMDCustomDataSource -DECLARE_INTERFACE_(IMDCustomDataSource, IUnknown) -{ - STDMETHOD(GetSchema)(CMiniMdSchema* pSchema) PURE; - STDMETHOD(GetTableDef)(ULONG32 tableIndex, CMiniTableDef* pTableDef) PURE; - STDMETHOD(GetBlobHeap)(MetaData::DataBlob* pBlobHeapData) PURE; - STDMETHOD(GetGuidHeap)(MetaData::DataBlob* pGuidHeapData) PURE; - STDMETHOD(GetStringHeap)(MetaData::DataBlob* pStringHeapData) PURE; - STDMETHOD(GetUserStringHeap)(MetaData::DataBlob* pUserStringHeapData) PURE; - STDMETHOD(GetTableRecords)(ULONG32 tableIndex, MetaData::DataBlob* pTableRecordData) PURE; - STDMETHOD(GetTableSortable)(ULONG32 tableIndex, BOOL* pSortable) PURE; - STDMETHOD(GetStorageSignature)(MetaData::DataBlob* pStorageSignature) PURE; - -}; // IMDCustomDataSource - -// {503F79FB-7AAE-4364-BDA6-8E235D173AEC} -EXTERN_GUID(IID_IMetaDataDispenserCustom, - 0x503f79fb, 0x7aae, 0x4364, 0xbd, 0xa6, 0x8e, 0x23, 0x5d, 0x17, 0x3a, 0xec); - -#undef INTERFACE -#define INTERFACE IMetaDataDispenserCustom -DECLARE_INTERFACE_(IMetaDataDispenserCustom, IUnknown) -{ - STDMETHOD(OpenScopeOnCustomDataSource)( // Return code. - IMDCustomDataSource *pCustomSource, // [in] The scope to open. - DWORD dwOpenFlags, // [in] Open mode flags. - REFIID riid, // [in] The interface desired. - IUnknown **ppIUnk) PURE; // [out] Return interface on success. - -}; // IMetaDataDispenserCustom - -#endif // FEATURE_METADATA_CUSTOM_DATA_SOURCE - -#ifdef FEATURE_METADATA_DEBUGGEE_DATA_SOURCE -struct ICorDebugDataTarget; -HRESULT CreateRemoteMDInternalRWSource(TADDR mdInternalRWRemoteAddress, ICorDebugDataTarget* pDataTarget, DWORD defines, DWORD dataStructureVersion, IMDCustomDataSource** ppDataSource); -#endif - enum MetaDataReorderingOptions { NoReordering=0x0, ReArrangeStringPool=0x1 diff --git a/src/coreclr/inc/shash.h b/src/coreclr/inc/shash.h index 8a9e13d26ec809..8621acff0674c6 100644 --- a/src/coreclr/inc/shash.h +++ b/src/coreclr/inc/shash.h @@ -163,8 +163,6 @@ template class EMPTY_BASES SHash : public TRAITS , private noncopyable { - friend class VerifyLayoutsMD; // verifies class layout doesn't accidentally change - public: // explicitly declare local typedefs for these traits types, otherwise // the compiler may get confused diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index 0b802a91898cbe..3f4262df12dad9 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -2355,7 +2355,6 @@ struct HASHLINK template class CChainedHash { - friend class VerifyLayoutsMD; public: CChainedHash(int iBuckets=32) : m_rgData(0), diff --git a/src/coreclr/md/CMakeLists.txt b/src/coreclr/md/CMakeLists.txt index ef60850b5a1098..d0bf1d4367fc21 100644 --- a/src/coreclr/md/CMakeLists.txt +++ b/src/coreclr/md/CMakeLists.txt @@ -2,12 +2,8 @@ add_compile_definitions(FEATURE_METADATA_EMIT) add_compile_definitions(FEATURE_METADATA_INTERNAL_APIS) add_compile_definitions($<$>,$>>:FEATURE_METADATA_EMIT_IN_DEBUGGER>) add_compile_definitions($<$>,$>>>:FEATURE_METADATA_IN_VM>) -add_compile_definitions($<$>:FEATURE_METADATA_CUSTOM_DATA_SOURCE>) -add_compile_definitions($<$>:FEATURE_METADATA_DEBUGGEE_DATA_SOURCE>) add_compile_definitions($<$>:FEATURE_METADATA_LOAD_TRUSTED_IMAGES>) add_compile_definitions($<$>:FEATURE_METADATA_RELEASE_MEMORY_ON_REOPEN>) -add_compile_definitions($<$>,$>>>:FEATURE_METADATA_VERIFY_LAYOUTS>) - if (CLR_CMAKE_HOST_WIN32) set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$>,$>:Debug>) endif() @@ -16,4 +12,3 @@ add_subdirectory(compiler) add_subdirectory(runtime) add_subdirectory(enc) add_subdirectory(ceefilegen) -add_subdirectory(datasource) diff --git a/src/coreclr/md/compiler/CMakeLists.txt b/src/coreclr/md/compiler/CMakeLists.txt index 56a08ec4ac5be2..b0e97f3029ddc7 100644 --- a/src/coreclr/md/compiler/CMakeLists.txt +++ b/src/coreclr/md/compiler/CMakeLists.txt @@ -39,31 +39,18 @@ set(MDCOMPILER_HEADERS regmeta.h ) -set(MDCOMPILER_WKS_SOURCES - ${MDCOMPILER_SOURCES} - verifylayouts.cpp -) - -set(MDCOMPILER_WKS_HEADERS - ${MDCOMPILER_HEADERS} - ../inc/verifylayouts.h -) - convert_to_absolute_path(MDCOMPILER_SOURCES ${MDCOMPILER_SOURCES}) convert_to_absolute_path(MDCOMPILER_HEADERS ${MDCOMPILER_HEADERS}) -convert_to_absolute_path(MDCOMPILER_WKS_SOURCES ${MDCOMPILER_WKS_SOURCES}) -convert_to_absolute_path(MDCOMPILER_WKS_HEADERS ${MDCOMPILER_WKS_HEADERS}) if (CLR_CMAKE_TARGET_WIN32) list(APPEND MDCOMPILER_SOURCES ${MDCOMPILER_HEADERS}) - list(APPEND MDCOMPILER_WKS_SOURCES ${MDCOMPILER_WKS_HEADERS}) endif() add_library_clr(mdcompiler_dac ${MDCOMPILER_SOURCES}) set_target_properties(mdcompiler_dac PROPERTIES DAC_COMPONENT TRUE) target_precompile_headers(mdcompiler_dac PRIVATE stdafx.h) -add_library_clr(mdcompiler_wks OBJECT ${MDCOMPILER_WKS_SOURCES}) +add_library_clr(mdcompiler_wks OBJECT ${MDCOMPILER_SOURCES}) target_compile_definitions(mdcompiler_wks PRIVATE FEATURE_METADATA_EMIT_ALL) target_precompile_headers(mdcompiler_wks PRIVATE stdafx.h) diff --git a/src/coreclr/md/compiler/disp.cpp b/src/coreclr/md/compiler/disp.cpp index c2a72bfac2fafa..165d4910c727e8 100644 --- a/src/coreclr/md/compiler/disp.cpp +++ b/src/coreclr/md/compiler/disp.cpp @@ -437,91 +437,6 @@ Disp::DefinePortablePdbScope( } // Disp::DefineScope #endif // FEATURE_METADATA_EMIT_PORTABLE_PDB -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - -//***************************************************************************** -// IMetaDataDispenserCustom -//***************************************************************************** - -HRESULT Disp::OpenScopeOnCustomDataSource( // S_OK or error - IMDCustomDataSource *pCustomSource, // [in] The scope to open. - DWORD dwOpenFlags, // [in] Open mode flags. - REFIID riid, // [in] The interface desired. - IUnknown **ppIUnk) // [out] Return interface on success. -{ - HRESULT hr; - LOG((LF_METADATA, LL_INFO10, "Disp::OpenScopeOnCustomDataSource(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", pCustomSource, dwOpenFlags, riid, ppIUnk)); - - IMDCommon *pMDCommon = NULL; - - _ASSERTE(!IsOfReserved(dwOpenFlags)); - if (ppIUnk == NULL) - IfFailGo(E_INVALIDARG); - *ppIUnk = NULL; - IfFailGo(OpenRawScopeOnCustomDataSource(pCustomSource, dwOpenFlags, IID_IMDCommon, (IUnknown**)&pMDCommon)); - IfFailGo(DeliverScope(pMDCommon, riid, dwOpenFlags, ppIUnk)); -ErrExit: - if (pMDCommon) - pMDCommon->Release(); - - return hr; -} - - -//***************************************************************************** -// Open a raw view of existing scope. -//***************************************************************************** -HRESULT Disp::OpenRawScopeOnCustomDataSource( // Return code. - IMDCustomDataSource* pDataSource, // [in] scope data. - DWORD dwOpenFlags, // [in] Open mode flags. - REFIID riid, // [in] The interface desired. - IUnknown **ppIUnk) // [out] Return interface on success. -{ - HRESULT hr; - - RegMeta *pMeta = 0; - - _ASSERTE(!IsOfReserved(dwOpenFlags)); - - // Create a new coclass for this guy. - pMeta = new (nothrow)RegMeta(); - IfNullGo(pMeta); - IfFailGo(pMeta->SetOption(&m_OptionValue)); - - - _ASSERTE(pMeta != NULL); - // Always initialize the RegMeta's stgdb. - // TODO - IfFailGo(pMeta->OpenExistingMD(pDataSource, dwOpenFlags)); - - LOG((LOGMD, "{%08x} Opened new scope on custom data source, pDataSource: %08x\n", pMeta, pDataSource)); - - // Return the requested interface. - IfFailGo(pMeta->QueryInterface(riid, (void **)ppIUnk)); - - // Add the new RegMeta to the cache. - IfFailGo(pMeta->AddToCache()); - -#if defined(_DEBUG) - if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_RegMetaDump)) - { - int DumpMD_impl(RegMeta *pMD); - DumpMD_impl(pMeta); - } -#endif // _DEBUG - -ErrExit: - if (FAILED(hr)) - { - if (pMeta) delete pMeta; - *ppIUnk = 0; - } - - return hr; -} // Disp::OpenRawScopeOnCustomDataSource - -#endif - //***************************************************************************** // IUnknown //***************************************************************************** @@ -554,10 +469,6 @@ HRESULT Disp::QueryInterface(REFIID riid, void **ppUnk) *ppUnk = (IMetaDataDispenserEx2 *) this; else if (riid == IID_IILAsmPortablePdbWriter) *ppUnk = (IILAsmPortablePdbWriter *) this; -#endif -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - else if (riid == IID_IMetaDataDispenserCustom) - *ppUnk = static_cast(this); #endif else return E_NOINTERFACE; diff --git a/src/coreclr/md/compiler/disp.h b/src/coreclr/md/compiler/disp.h index 6c37f8460db053..515a7230afdd41 100644 --- a/src/coreclr/md/compiler/disp.h +++ b/src/coreclr/md/compiler/disp.h @@ -20,9 +20,6 @@ class Disp : #else public IMetaDataDispenserEx2 #endif -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - , IMetaDataDispenserCustom -#endif { public: Disp(); @@ -100,15 +97,6 @@ class Disp : IUnknown** ppIUnk); // [out] Return interface on success. #endif -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - // *** IMetaDataDispenserCustom methods *** - STDMETHODIMP OpenScopeOnCustomDataSource( // S_OK or error - IMDCustomDataSource *pCustomSource, // [in] The scope to open. - DWORD dwOpenFlags, // [in] Open mode flags. - REFIID riid, // [in] The interface desired. - IUnknown **ppIUnk); // [out] Return interface on success. -#endif - // Class factory hook-up. static HRESULT CreateObject(REFIID riid, void **ppUnk); @@ -126,15 +114,6 @@ class Disp : REFIID riid, // [in] The interface desired. IUnknown **ppIUnk); // [out] Return interface on success. -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - HRESULT OpenRawScopeOnCustomDataSource( // Return code. - IMDCustomDataSource* pDataSource, // [in] scope data. - DWORD dwOpenFlags, // [in] Open mode flags. - REFIID riid, // [in] The interface desired. - IUnknown **ppIUnk); // [out] Return interface on success. -#endif - - private: LONG m_cRef; // Ref count OptionValue m_OptionValue; // values can be set by using SetOption diff --git a/src/coreclr/md/compiler/regmeta.cpp b/src/coreclr/md/compiler/regmeta.cpp index b635d43b212435..07823d66df9b29 100644 --- a/src/coreclr/md/compiler/regmeta.cpp +++ b/src/coreclr/md/compiler/regmeta.cpp @@ -369,60 +369,6 @@ HRESULT RegMeta::OpenExistingMD( return hr; } //RegMeta::OpenExistingMD -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE -HRESULT RegMeta::OpenExistingMD( - IMDCustomDataSource* pDataSource, // Name of database. - ULONG dwOpenFlags) // Flags to control open. -{ - HRESULT hr = NOERROR; - - m_OpenFlags = dwOpenFlags; - - if (!IsOfReOpen(dwOpenFlags)) - { - // Allocate our m_pStgdb, if we should. - _ASSERTE(m_pStgdb == NULL); - IfNullGo(m_pStgdb = new (nothrow)CLiteWeightStgdbRW); - } - - IfFailGo(m_pStgdb->OpenForRead( - pDataSource, - m_OpenFlags)); - - if (m_pStgdb->m_MiniMd.m_Schema.m_major == METAMODEL_MAJOR_VER_V1_0 && - m_pStgdb->m_MiniMd.m_Schema.m_minor == METAMODEL_MINOR_VER_V1_0) - m_OptionValue.m_MetadataVersion = MDVersion1; - - else - m_OptionValue.m_MetadataVersion = MDVersion2; - - - - IfFailGo(m_pStgdb->m_MiniMd.SetOption(&m_OptionValue)); - - if (IsThreadSafetyOn()) - { - m_pSemReadWrite = new (nothrow)UTSemReadWrite(); - IfNullGo(m_pSemReadWrite); - IfFailGo(m_pSemReadWrite->Init()); - m_fOwnSem = true; - - INDEBUG(m_pStgdb->m_MiniMd.Debug_SetLock(m_pSemReadWrite);) - } - - if (!IsOfReOpen(dwOpenFlags)) - { - // There must always be a Global Module class and its the first entry in - // the TypeDef table. - m_tdModule = TokenFromRid(1, mdtTypeDef); - } - -ErrExit: - - return hr; -} //RegMeta::OpenExistingMD -#endif // FEATURE_METADATA_CUSTOM_DATA_SOURCE - #ifdef FEATURE_METADATA_INTERNAL_APIS //***************************************************************************** @@ -1442,19 +1388,7 @@ HRESULT RegMeta::GetVersionString( // S_OK or error. _ASSERTE(pVer != NULL); HRESULT hr; LOCKREAD(); -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - if (m_pStgdb->m_pvMd != NULL) - { -#endif - *pVer = reinterpret_cast(reinterpret_cast(m_pStgdb->m_pvMd)->pVersion); -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - } - else - { - //This emptry string matches the fallback behavior we have in other places that query the version string. - *pVer = ""; - } -#endif + *pVer = reinterpret_cast(reinterpret_cast(m_pStgdb->m_pvMd)->pVersion); hr = S_OK; ErrExit: return hr; @@ -1528,4 +1462,3 @@ HRESULT RegMeta::GetIMDInternalImport( return hr; } #endif //FEATURE_METADATA_INTERNAL_APIS - diff --git a/src/coreclr/md/compiler/regmeta.h b/src/coreclr/md/compiler/regmeta.h index 4f19d5d1ea912c..9623f2f2954188 100644 --- a/src/coreclr/md/compiler/regmeta.h +++ b/src/coreclr/md/compiler/regmeta.h @@ -1587,12 +1587,6 @@ class RegMeta : ULONG cbData, // How big is the data. ULONG dwFlags); // Flags to control open. -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - HRESULT OpenExistingMD( - IMDCustomDataSource* pDataSource, // Name of database. - ULONG dwFlags); // Flags to control open. -#endif - FORCEINLINE CLiteWeightStgdbRW* GetMiniStgdb() { return m_pStgdb; } FORCEINLINE CMiniMdRW* GetMiniMd() { return &m_pStgdb->m_MiniMd; } diff --git a/src/coreclr/md/compiler/verifylayouts.cpp b/src/coreclr/md/compiler/verifylayouts.cpp deleted file mode 100644 index 24f9498e3d9df1..00000000000000 --- a/src/coreclr/md/compiler/verifylayouts.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// VerifyLayouts.cpp -// - -// -// Make sure that layouts of MD data structures doesn't change accidentally -// -//***************************************************************************** - -#include "stdafx.h" -#include "verifylayouts.h" diff --git a/src/coreclr/md/datasource/CMakeLists.txt b/src/coreclr/md/datasource/CMakeLists.txt deleted file mode 100644 index 75bdec0bc1bcf2..00000000000000 --- a/src/coreclr/md/datasource/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(MDDATASOURCE_SOURCES - api.cpp - datatargetreader.cpp - remotemdinternalrwsource.cpp - targettypes.cpp -) - -set(MDDATASOURCE_HEADERS - ../../inc/cor.h - ../../inc/corpriv.h - datatargetreader.h - remotemdinternalrwsource.h - targettypes.h -) - -convert_to_absolute_path(MDDATASOURCE_SOURCES ${MDDATASOURCE_SOURCES}) -convert_to_absolute_path(MDDATASOURCE_HEADERS ${MDDATASOURCE_HEADERS}) - -if (CLR_CMAKE_TARGET_WIN32) - list(APPEND MDDATASOURCE_SOURCES ${MDDATASOURCE_HEADERS}) -endif (CLR_CMAKE_TARGET_WIN32) - -add_library_clr(mddatasource_dbi STATIC ${MDDATASOURCE_SOURCES}) -set_target_properties(mddatasource_dbi PROPERTIES DBI_COMPONENT TRUE) -target_precompile_headers(mddatasource_dbi PRIVATE stdafx.h) diff --git a/src/coreclr/md/datasource/api.cpp b/src/coreclr/md/datasource/api.cpp deleted file mode 100644 index 9d062d5f6b0810..00000000000000 --- a/src/coreclr/md/datasource/api.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// api.cpp -// - -// -//***************************************************************************** - -#include "stdafx.h" -#include "remotemdinternalrwsource.h" - -HRESULT CreateRemoteMDInternalRWSource(TADDR mdInternalRWRemoteAddress, ICorDebugDataTarget* pDataTarget, DWORD defines, DWORD dataStructureVersion, IMDCustomDataSource** ppDataSource) -{ - HRESULT hr = S_OK; - RemoteMDInternalRWSource* pSource = new (nothrow) RemoteMDInternalRWSource(); - if (pSource == NULL) - return E_OUTOFMEMORY; - - hr = pSource->InitFromTarget(mdInternalRWRemoteAddress, pDataTarget, defines, dataStructureVersion); - if (SUCCEEDED(hr)) - { - hr = pSource->QueryInterface(IID_IMDCustomDataSource, (void**)ppDataSource); - } - if (FAILED(hr)) - { - delete pSource; - } - return hr; -} diff --git a/src/coreclr/md/datasource/datatargetreader.cpp b/src/coreclr/md/datasource/datatargetreader.cpp deleted file mode 100644 index 0a14829b780e94..00000000000000 --- a/src/coreclr/md/datasource/datatargetreader.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -#include "stdafx.h" -#include "datatargetreader.h" - - -DataTargetReader::DataTargetReader(CORDB_ADDRESS remoteAddressCursor, ICorDebugDataTarget* pDataTarget, DWORD targetDefines, DWORD mdStructuresVersion) -: m_remotePointerSize(0), -m_currentStructureAlign(1), -m_targetDefines(targetDefines), -m_mdStructuresVersion(mdStructuresVersion) -{ - m_remoteAddressCursor = remoteAddressCursor; - m_pDataTarget = pDataTarget; - m_pDataTarget->AddRef(); -} -DataTargetReader::DataTargetReader(const DataTargetReader & otherReader) -{ - m_pDataTarget = otherReader.m_pDataTarget; - m_pDataTarget->AddRef(); - m_remotePointerSize = otherReader.m_remotePointerSize; - m_remoteAddressCursor = otherReader.m_remoteAddressCursor; - m_targetDefines = otherReader.m_targetDefines; - m_mdStructuresVersion = otherReader.m_mdStructuresVersion; -} -DataTargetReader & DataTargetReader::operator=(const DataTargetReader & otherReader) -{ - if (this != &otherReader) - { - m_pDataTarget = otherReader.m_pDataTarget; - m_pDataTarget->AddRef(); - m_remotePointerSize = otherReader.m_remotePointerSize; - m_remoteAddressCursor = otherReader.m_remoteAddressCursor; - m_targetDefines = otherReader.m_targetDefines; - m_mdStructuresVersion = otherReader.m_mdStructuresVersion; - } - return *this; -} -DataTargetReader::~DataTargetReader() -{ - m_pDataTarget->Release(); - m_pDataTarget = NULL; -} - -HRESULT DataTargetReader::ReadPointer(CORDB_ADDRESS* pPointerValue) -{ - HRESULT hr = S_OK; - if (m_remotePointerSize == 0) - { - IfFailRet(GetRemotePointerSize(&m_remotePointerSize)); - } - _ASSERTE(m_remotePointerSize == 4 || m_remotePointerSize == 8); - *pPointerValue = 0; - if (m_remotePointerSize == 4) - return Read32((ULONG32*)pPointerValue); - else - return Read64((ULONG64*)pPointerValue); -} -HRESULT DataTargetReader::SkipPointer() -{ - HRESULT hr = S_OK; - if (m_remotePointerSize == 0) - { - IfFailRet(GetRemotePointerSize(&m_remotePointerSize)); - } - _ASSERTE(m_remotePointerSize == 4 || m_remotePointerSize == 8); - Align(m_remotePointerSize); - return SkipBytes(m_remotePointerSize); -} -HRESULT DataTargetReader::Read8(BYTE* pByteValue) -{ - return ReadBytes(pByteValue, 1); -} -HRESULT DataTargetReader::Skip8() -{ - return SkipBytes(1); -} -HRESULT DataTargetReader::Read32(ULONG32* pUlong32Value) -{ - Align(4); - return ReadBytes((BYTE*)pUlong32Value, sizeof(ULONG32)); -} -HRESULT DataTargetReader::Skip32() -{ - Align(4); - return SkipBytes(sizeof(ULONG32)); -} -HRESULT DataTargetReader::Read64(ULONG64* pUlong64Value) -{ - Align(8); - return ReadBytes((BYTE*)pUlong64Value, sizeof(ULONG64)); -} -HRESULT DataTargetReader::Skip64() -{ - Align(8); - return SkipBytes(sizeof(ULONG64)); -} - -HRESULT DataTargetReader::ReadBytes(BYTE* pBuffer, DWORD cbBuffer) -{ - HRESULT hr = S_OK; - ULONG32 cbTotalRead = 0; - CORDB_ADDRESS m_tempRemoteAddressCursor = m_remoteAddressCursor; - while (cbTotalRead < cbBuffer) - { - ULONG32 cbRead = 0; - if(FAILED(m_pDataTarget->ReadVirtual(m_remoteAddressCursor + cbTotalRead, - pBuffer + cbTotalRead, - cbBuffer - cbTotalRead, - &cbRead))) - return CORDBG_E_READVIRTUAL_FAILURE; - if (cbRead == 0) - return CORDBG_E_READVIRTUAL_FAILURE; - cbTotalRead += cbRead; - } - - // on success only, move the cursor - m_remoteAddressCursor += cbTotalRead; - return S_OK; -} -HRESULT DataTargetReader::SkipBytes(DWORD cbRead) -{ - m_remoteAddressCursor += cbRead; - return S_OK; -} - -#ifndef MAX -#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#endif - -HRESULT DataTargetReader::Read(TargetObject* pTargetObject) -{ - ULONG32 previousAlign = m_currentStructureAlign; - m_currentStructureAlign = 1; - HRESULT hr = pTargetObject->ReadFrom(*this); - if (SUCCEEDED(hr)) - { - // increase the structure size to a multiple of the maximum alignment of any of its members - Align(m_currentStructureAlign); - } - m_currentStructureAlign = MAX(previousAlign, m_currentStructureAlign); - return hr; -} - -HRESULT DataTargetReader::ReadPointer(TargetObject* pTargetObject) -{ - HRESULT hr = S_OK; - CORDB_ADDRESS pointerValue; - IfFailRet(ReadPointer(&pointerValue)); - - DataTargetReader reader = CreateReaderAt(pointerValue); - return pTargetObject->ReadFrom(reader); -} - -void DataTargetReader::Align(DWORD alignmentBytes) -{ - m_remoteAddressCursor = AlignUp(m_remoteAddressCursor, alignmentBytes); - m_currentStructureAlign = MAX(m_currentStructureAlign, alignmentBytes); -} - -void DataTargetReader::AlignBase() -{ - // Align structs based on the largest field size - // This is the default for MSVC compilers - // This is forced on other platforms by the DAC_ALIGNAS macro - Align(m_currentStructureAlign); -} - -HRESULT DataTargetReader::GetRemotePointerSize(ULONG32* pPointerSize) -{ - HRESULT hr = S_OK; - CorDebugPlatform platform; - IfFailRet(m_pDataTarget->GetPlatform(&platform)); - if ((platform == CORDB_PLATFORM_WINDOWS_X86) || (platform == CORDB_PLATFORM_POSIX_X86) || (platform == CORDB_PLATFORM_MAC_X86)) - *pPointerSize = 4; - else if ((platform == CORDB_PLATFORM_WINDOWS_AMD64) || (platform == CORDB_PLATFORM_POSIX_AMD64) || (platform == CORDB_PLATFORM_MAC_AMD64)) - *pPointerSize = 8; - else if ((platform == CORDB_PLATFORM_WINDOWS_ARM) || (platform == CORDB_PLATFORM_POSIX_ARM)) - *pPointerSize = 4; - else if ((platform == CORDB_PLATFORM_WINDOWS_ARM64) || (platform == CORDB_PLATFORM_POSIX_ARM64)) - *pPointerSize = 8; - else - return CORDBG_E_UNSUPPORTED; - return S_OK; -} - -DWORD DataTargetReader::GetMDStructuresVersion() -{ - return m_mdStructuresVersion; -} - -BOOL DataTargetReader::IsDefined(DWORD define) -{ - return (m_targetDefines & define) == define; -} - -DataTargetReader DataTargetReader::CreateReaderAt(CORDB_ADDRESS remoteAddressCursor) -{ - DataTargetReader newReader(remoteAddressCursor, m_pDataTarget, m_targetDefines, m_mdStructuresVersion); - return newReader; -} diff --git a/src/coreclr/md/datasource/datatargetreader.h b/src/coreclr/md/datasource/datatargetreader.h deleted file mode 100644 index e1d0ee5d8ad592..00000000000000 --- a/src/coreclr/md/datasource/datatargetreader.h +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#ifndef _MD_DATA_TARGET_READER_ -#define _MD_DATA_TARGET_READER_ - -#include "cor.h" -#include "cordebug.h" - -class DataTargetReader; - -class TargetObject -{ -public: - virtual HRESULT ReadFrom(DataTargetReader & reader) = 0; -}; - -class DataTargetReader -{ -public: - DataTargetReader(CORDB_ADDRESS remoteAddressCursor, ICorDebugDataTarget* pDataTarget, DWORD targetDefines, DWORD mdStructuresVersion); - DataTargetReader(const DataTargetReader & otherReader); - DataTargetReader & operator=(const DataTargetReader & rhs); - ~DataTargetReader(); - - HRESULT Read(TargetObject* pTargetObjectValue); - HRESULT ReadPointer(TargetObject* pTargetObjectValue); - HRESULT ReadPointer(CORDB_ADDRESS* pPointerValue); - HRESULT SkipPointer(); - HRESULT Read8(BYTE* pByteValue); - HRESULT Skip8(); - HRESULT Read32(ULONG32* pUlong32Value); - HRESULT Skip32(); - HRESULT Read64(ULONG64* pUlong64Value); - HRESULT Skip64(); - HRESULT ReadBytes(BYTE* pBuffer, DWORD cbBuffer); - HRESULT SkipBytes(DWORD cbBuffer); - void Align(DWORD alignmentBytes); - void AlignBase(); - - DataTargetReader CreateReaderAt(CORDB_ADDRESS remoteAddressCursor); - - DWORD GetMDStructuresVersion(); - BOOL IsDefined(DWORD define); - - -private: - HRESULT GetRemotePointerSize(ULONG32* pPointerSize); - ICorDebugDataTarget* m_pDataTarget; - ULONG32 m_remotePointerSize; - CORDB_ADDRESS m_remoteAddressCursor; - ULONG32 m_currentStructureAlign; - DWORD m_targetDefines; - DWORD m_mdStructuresVersion; -}; - -#endif // _MD_DATA_TARGET_READER_ diff --git a/src/coreclr/md/datasource/remotemdinternalrwsource.cpp b/src/coreclr/md/datasource/remotemdinternalrwsource.cpp deleted file mode 100644 index 7effa8a67ff1be..00000000000000 --- a/src/coreclr/md/datasource/remotemdinternalrwsource.cpp +++ /dev/null @@ -1,240 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// RemoteMDInternalRWSource.cpp -// - -// -//***************************************************************************** - -#include "stdafx.h" -#include "remotemdinternalrwsource.h" - -RemoteMDInternalRWSource::RemoteMDInternalRWSource() : -m_cRef(0) -{ - memset(&m_TableDefs, 0, sizeof(CMiniTableDef)*TBL_COUNT); - memset(&m_bSortable, 0, sizeof(BOOL)*TBL_COUNT); -} - -RemoteMDInternalRWSource::~RemoteMDInternalRWSource() -{ - for (int i = 0; i < TBL_COUNT; i++) - { - delete[] m_TableDefs[i].m_pColDefs; - } -} - -ULONG RemoteMDInternalRWSource::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -ULONG RemoteMDInternalRWSource::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - return cRef; -} - -HRESULT RemoteMDInternalRWSource::QueryInterface(REFIID riid, void ** ppUnk) -{ - *ppUnk = 0; - if (riid == IID_IUnknown) - { - *ppUnk = static_cast(this); - } - else if (riid == IID_IMDCustomDataSource) - { - *ppUnk = static_cast(this); - } - else - { - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -HRESULT _MarshalDataFromTargetStgPool(DataTargetReader & reader, const Target_StgPool & pool, MetaData::DataBlob* pBlob) -{ - HRESULT hr = S_OK; - ULONG32 dataSize = 0; - ULONG32 segmentCount = 0; - Target_StgPoolSeg curSeg = (Target_StgPoolSeg)pool; - - // The storage pool grows exponentially, and should reach 2GB in at most 64 segments. Allowing for 1000 - // adds a sizable risk mitigation factor in case my analysis was inaccurate or the algorithm changes in the future - // without corresponding changes here. - CORDB_ADDRESS segmentData[1000]; - ULONG32 segmentSize[1000]; - for (; segmentCount < 1000; segmentCount++) - { - // sanity check that each segment and the sum of all segments is less than 100M bytes - if (curSeg.m_cbSegNext > 100000000) - return CLDB_E_FILE_CORRUPT; - dataSize += curSeg.m_cbSegNext; - if (dataSize > 100000000) - return CLDB_E_FILE_CORRUPT; - segmentData[segmentCount] = curSeg.m_pSegData; - segmentSize[segmentCount] = curSeg.m_cbSegNext; - if (curSeg.m_pNextSeg == 0) - break; - - DataTargetReader segReader = reader.CreateReaderAt(curSeg.m_pNextSeg); - IfFailRet(segReader.Read(&curSeg)); - } - - //we exited the loop with a break, count should be one more than the last index - segmentCount++; - - // sanity check, no more than 1000 segments allowed - if (segmentCount > 1000) - return CLDB_E_FILE_CORRUPT; - - // things looked reasonable enough, marshal over the data - NewArrayHolder pData = new (nothrow) BYTE[dataSize]; - if (pData == NULL) - return E_OUTOFMEMORY; - BYTE* pCursor = pData; - for (ULONG32 i = 0; i < segmentCount; i++) - { - DataTargetReader segDataReader = reader.CreateReaderAt(segmentData[i]); - hr = segDataReader.ReadBytes(pCursor, segmentSize[i]); - if (FAILED(hr)) - { - return hr; - } - else - { - pCursor += segmentSize[i]; - } - } - pBlob->Init(pData, dataSize); - pData.SuppressRelease(); // our caller owns the buffer now - return S_OK; - -} - -HRESULT RemoteMDInternalRWSource::InitFromTarget(TADDR remoteMDInternalRWAddr, ICorDebugDataTarget* pDataTarget, DWORD defines, DWORD dataStructureVersion) -{ - HRESULT hr = S_OK; - DataTargetReader reader(remoteMDInternalRWAddr, pDataTarget, defines, dataStructureVersion); - IfFailRet(reader.Read(&m_targetData)); - - Target_CMiniMdSchema targetSchema = m_targetData.m_pStgdb.m_MiniMd.m_Schema; - m_Schema.m_ulReserved = targetSchema.m_ulReserved; - m_Schema.m_major = targetSchema.m_major; - m_Schema.m_minor = targetSchema.m_minor; - m_Schema.m_heaps = targetSchema.m_heaps; - m_Schema.m_rid = targetSchema.m_rid; - m_Schema.m_maskvalid = targetSchema.m_maskvalid; - m_Schema.m_sorted = targetSchema.m_sorted; - memcpy(m_Schema.m_cRecs, targetSchema.m_cRecs, sizeof(ULONG32)*TBL_COUNT); - m_Schema.m_ulExtra = targetSchema.m_ulExtra; - - for (int i = 0; i < TBL_COUNT; i++) - { - Target_CMiniTableDef* pTargetTableDef = &(m_targetData.m_pStgdb.m_MiniMd.m_TableDefs[i]); - m_TableDefs[i].m_cCols = pTargetTableDef->m_cCols; - m_TableDefs[i].m_iKey = pTargetTableDef->m_iKey; - m_TableDefs[i].m_cbRec = pTargetTableDef->m_cbRec; - m_TableDefs[i].m_pColDefs = new (nothrow) CMiniColDef[m_TableDefs[i].m_cCols]; - if (m_TableDefs[i].m_pColDefs == NULL) - return E_OUTOFMEMORY; - for (int j = 0; j < m_TableDefs[i].m_cCols; j++) - { - m_TableDefs[i].m_pColDefs[j].m_Type = pTargetTableDef->m_pColDefs[j].m_Type; - m_TableDefs[i].m_pColDefs[j].m_oColumn = pTargetTableDef->m_pColDefs[j].m_oColumn; - m_TableDefs[i].m_pColDefs[j].m_cbColumn = pTargetTableDef->m_pColDefs[j].m_cbColumn; - } - } - - IfFailRet(_MarshalDataFromTargetStgPool(reader, (Target_StgPool)m_targetData.m_pStgdb.m_MiniMd.m_StringHeap, &m_StringHeap)); - m_StringHeapStorage = m_StringHeap.GetDataPointer(); - IfFailRet(_MarshalDataFromTargetStgPool(reader, (Target_StgPool)m_targetData.m_pStgdb.m_MiniMd.m_BlobHeap, &m_BlobHeap)); - m_BlobHeapStorage = m_BlobHeap.GetDataPointer(); - IfFailRet(_MarshalDataFromTargetStgPool(reader, (Target_StgPool)m_targetData.m_pStgdb.m_MiniMd.m_UserStringHeap, &m_UserStringHeap)); - m_UserStringHeapStorage = m_UserStringHeap.GetDataPointer(); - IfFailRet(_MarshalDataFromTargetStgPool(reader, (Target_StgPool)m_targetData.m_pStgdb.m_MiniMd.m_GuidHeap, &m_GuidHeap)); - m_GuidHeapStorage = m_GuidHeap.GetDataPointer(); - - for (int i = 0; i < TBL_COUNT; i++) - { - IfFailRet(_MarshalDataFromTargetStgPool(reader, (Target_StgPool)m_targetData.m_pStgdb.m_MiniMd.m_Tables[i], &m_TableRecords[i])); - m_TableRecordsStorage[i] = m_TableRecords[i].GetDataPointer(); - m_bSortable[i] = m_targetData.m_pStgdb.m_MiniMd.m_bSortable[i]; - } - - if (m_targetData.m_pStgdb.m_pvMd != 0) - { - STORAGESIGNATURE sig = { 0 }; - DataTargetReader storageSigReader = reader.CreateReaderAt(m_targetData.m_pStgdb.m_pvMd); - storageSigReader.ReadBytes((BYTE*)&sig, sizeof(sig)); - if (sig.GetVersionStringLength() > 1000) - return CLDB_E_FILE_CORRUPT; - ULONG32 totalSigSize = offsetof(STORAGESIGNATURE, pVersion) + sig.GetVersionStringLength(); - m_SigStorage = new (nothrow)BYTE[totalSigSize]; - if (m_SigStorage == NULL) - return E_OUTOFMEMORY; - memcpy_s(m_SigStorage, totalSigSize, &sig, sizeof(sig)); - storageSigReader.ReadBytes(m_SigStorage + sizeof(sig), totalSigSize - sizeof(sig)); - m_Sig.Init(m_SigStorage, totalSigSize); - } - - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetSchema(CMiniMdSchema* pSchema) -{ - *pSchema = m_Schema; - return S_OK; -} -STDMETHODIMP RemoteMDInternalRWSource::GetTableDef(ULONG32 tableIndex, CMiniTableDef* pTableDef) -{ - *pTableDef = m_TableDefs[tableIndex]; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetBlobHeap(MetaData::DataBlob* pBlobHeapData) -{ - *pBlobHeapData = m_BlobHeap; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetGuidHeap(MetaData::DataBlob* pGuidHeapData) -{ - *pGuidHeapData = m_GuidHeap; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetStringHeap(MetaData::DataBlob* pStringHeapData) -{ - *pStringHeapData = m_StringHeap; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetUserStringHeap(MetaData::DataBlob* pUserStringHeapData) -{ - *pUserStringHeapData = m_UserStringHeap; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetTableRecords(ULONG32 tableIndex, MetaData::DataBlob* pTableRecordData) -{ - *pTableRecordData = m_TableRecords[tableIndex]; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetTableSortable(ULONG32 tableIndex, BOOL* pSortable) -{ - *pSortable = TRUE; - return S_OK; -} - -STDMETHODIMP RemoteMDInternalRWSource::GetStorageSignature(MetaData::DataBlob* pStorageSignature) -{ - *pStorageSignature = m_Sig; - return S_OK; -} diff --git a/src/coreclr/md/datasource/remotemdinternalrwsource.h b/src/coreclr/md/datasource/remotemdinternalrwsource.h deleted file mode 100644 index f2e98fc1ce9ef8..00000000000000 --- a/src/coreclr/md/datasource/remotemdinternalrwsource.h +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// RemoteMDInternalRWSource.h -// - -// -//***************************************************************************** - -#ifndef _REMOTE_MDINTERNALRW_SOURCE_ -#define _REMOTE_MDINTERNALRW_SOURCE_ - -#include "targettypes.h" - -class RemoteMDInternalRWSource : IMDCustomDataSource -{ -public: - RemoteMDInternalRWSource(); - virtual ~RemoteMDInternalRWSource(); - - //***************************************************************************** - // IUnknown methods - //***************************************************************************** - STDMETHODIMP QueryInterface(REFIID riid, void** ppv); - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - - //***************************************************************************** - // IMDCustomDataSource methods - //***************************************************************************** - STDMETHODIMP GetSchema(CMiniMdSchema* pSchema); - STDMETHODIMP GetTableDef(ULONG32 tableIndex, CMiniTableDef* pTableDef); - STDMETHODIMP GetBlobHeap(MetaData::DataBlob* pBlobHeapData); - STDMETHODIMP GetGuidHeap(MetaData::DataBlob* pGuidHeapData); - STDMETHODIMP GetStringHeap(MetaData::DataBlob* pStringHeapData); - STDMETHODIMP GetUserStringHeap(MetaData::DataBlob* pUserStringHeapData); - STDMETHODIMP GetTableRecords(ULONG32 tableIndex, MetaData::DataBlob* pTableRecordData); - STDMETHODIMP GetTableSortable(ULONG32 tableIndex, BOOL* pSortable); - STDMETHODIMP GetStorageSignature(MetaData::DataBlob* pStorageSignature); - - //***************************************************************************** - // public non-COM methods - //***************************************************************************** - HRESULT InitFromTarget(TADDR remoteMDInternalRWAddress, ICorDebugDataTarget* pDataTarget, DWORD defines, DWORD dataStructureVersion); - -private: - Target_MDInternalRW m_targetData; - CMiniMdSchema m_Schema; - CMiniTableDef m_TableDefs[TBL_COUNT]; - MetaData::DataBlob m_StringHeap; - MetaData::DataBlob m_UserStringHeap; - MetaData::DataBlob m_BlobHeap; - MetaData::DataBlob m_GuidHeap; - MetaData::DataBlob m_TableRecords[TBL_COUNT]; - BOOL m_bSortable[TBL_COUNT]; - MetaData::DataBlob m_Sig; - - NewArrayHolder m_StringHeapStorage; - NewArrayHolder m_UserStringHeapStorage; - NewArrayHolder m_BlobHeapStorage; - NewArrayHolder m_GuidHeapStorage; - NewArrayHolder m_TableRecordsStorage[TBL_COUNT]; - NewArrayHolder m_SigStorage; - - volatile LONG m_cRef; -}; - - -#endif diff --git a/src/coreclr/md/datasource/stdafx.h b/src/coreclr/md/datasource/stdafx.h deleted file mode 100644 index 1495c5f463646d..00000000000000 --- a/src/coreclr/md/datasource/stdafx.h +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// stdafx.h -// - -// -// Precompiled headers. -// -//***************************************************************************** -#ifndef __STDAFX_H_ -#define __STDAFX_H_ - -#include -#include -#include - -#include -#include - -#include -#include - - -#endif // __STDAFX_H_ diff --git a/src/coreclr/md/datasource/targettypes.cpp b/src/coreclr/md/datasource/targettypes.cpp deleted file mode 100644 index 3ef0e9712353ac..00000000000000 --- a/src/coreclr/md/datasource/targettypes.cpp +++ /dev/null @@ -1,515 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// TargetTypes.cpp -// - -// -//***************************************************************************** - -#include "stdafx.h" -#include "targettypes.h" - - -Target_CMiniMdSchemaBase::Target_CMiniMdSchemaBase() : -m_ulReserved(0), -m_major(0), -m_minor(0), -m_heaps(0), -m_rid(0), -m_maskvalid(0), -m_sorted(0) -{} - -HRESULT Target_CMiniMdSchemaBase::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - reader.Align(8); // this type needs 8 byte alignment from m_maskvalid - IfFailRet(reader.Read32(&m_ulReserved)); - IfFailRet(reader.Read8(&m_major)); - IfFailRet(reader.Read8(&m_minor)); - IfFailRet(reader.Read8(&m_heaps)); - IfFailRet(reader.Read8(&m_rid)); - IfFailRet(reader.Read64(&m_maskvalid)); - IfFailRet(reader.Read64(&m_sorted)); - return S_OK; -} - -Target_CMiniMdSchema::Target_CMiniMdSchema() : -m_ulExtra(0) -{ - memset(&m_cRecs, 0, TBL_COUNT*sizeof(ULONG32)); -} - -HRESULT Target_CMiniMdSchema::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_CMiniMdSchemaBase::ReadFrom(reader)); - reader.AlignBase(); - for (int i = 0; i < TBL_COUNT; i++) - IfFailRet(reader.Read32(&(m_cRecs[i]))); - IfFailRet(reader.Read32(&m_ulExtra)); - return S_OK; -} - -Target_CMiniColDef::Target_CMiniColDef() : -m_Type(0), -m_oColumn(0), -m_cbColumn(0) -{ -} - -HRESULT Target_CMiniColDef::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.Read8(&m_Type)); - IfFailRet(reader.Read8(&m_oColumn)); - IfFailRet(reader.Read8(&m_cbColumn)); - return S_OK; -} - -Target_CMiniTableDef::Target_CMiniTableDef() : -m_pColDefs(NULL), -m_cCols(0), -m_iKey(0), -m_cbRec(0) -{} - -HRESULT Target_CMiniTableDef::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - CORDB_ADDRESS pColDefs = 0; - IfFailRet(reader.ReadPointer(&pColDefs)); - IfFailRet(reader.Read8(&m_cCols)); - IfFailRet(reader.Read8(&m_iKey)); - IfFailRet(reader.Read8(&m_cbRec)); - - // sanity check before allocating - if (m_cCols > 100) - return CLDB_E_FILE_CORRUPT; - m_pColDefs = new (nothrow) Target_CMiniColDef[m_cCols]; - if (m_pColDefs == NULL) - return E_OUTOFMEMORY; - DataTargetReader colsReader = reader.CreateReaderAt(pColDefs); - for (int i = 0; i < m_cCols; i++) - { - IfFailRet(colsReader.Read(&m_pColDefs[i])); - } - - return S_OK; -} - -Target_CMiniMdBase::Target_CMiniMdBase() : -m_TblCount(0), -m_fVerifiedByTrustedSource(FALSE), -m_iStringsMask(0), -m_iGuidsMask(0), -m_iBlobsMask(0) -{} - -HRESULT Target_CMiniMdBase::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.SkipPointer()); // vtable - IfFailRet(reader.Read(&m_Schema)); - IfFailRet(reader.Read32(&m_TblCount)); - IfFailRet(reader.Read32((ULONG32*)&m_fVerifiedByTrustedSource)); - for (int i = 0; i < TBL_COUNT; i++) - IfFailRet(reader.Read(&(m_TableDefs[i]))); - IfFailRet(reader.Read32(&m_iStringsMask)); - IfFailRet(reader.Read32(&m_iGuidsMask)); - IfFailRet(reader.Read32(&m_iBlobsMask)); - return S_OK; -} - -Target_MapSHash::Target_MapSHash() : -m_table(0), -m_tableSize(0), -m_tableCount(0), -m_tableOccupied(0), -m_tableMax(0) -{} - -HRESULT Target_MapSHash::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.ReadPointer(&m_table)); - IfFailRet(reader.Read32(&m_tableSize)); - IfFailRet(reader.Read32(&m_tableCount)); - IfFailRet(reader.Read32(&m_tableOccupied)); - IfFailRet(reader.Read32(&m_tableMax)); - return S_OK; -} - - - -Target_StgPoolSeg::Target_StgPoolSeg() : -m_pSegData(0), -m_pNextSeg(0), -m_cbSegSize(0), -m_cbSegNext(0) -{} - -HRESULT Target_StgPoolSeg::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.ReadPointer(&m_pSegData)); - IfFailRet(reader.ReadPointer(&m_pNextSeg)); - IfFailRet(reader.Read32(&m_cbSegSize)); - IfFailRet(reader.Read32(&m_cbSegNext)); - return S_OK; -} - - -Target_CChainedHash::Target_CChainedHash() : -m_rgData(0), -m_iBuckets(0), -m_iSize(0), -m_iCount(0), -m_iMaxChain(0), -m_iFree(0) -{} - -HRESULT Target_CChainedHash::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.SkipPointer()); // __vfptr - IfFailRet(reader.ReadPointer(&m_rgData)); - IfFailRet(reader.Read32(&m_iBuckets)); - IfFailRet(reader.Read32(&m_iSize)); - IfFailRet(reader.Read32(&m_iCount)); - IfFailRet(reader.Read32(&m_iMaxChain)); - IfFailRet(reader.Read32(&m_iFree)); - return S_OK; -} - -Target_CStringPoolHash::Target_CStringPoolHash() : -m_Pool(0) -{} - -HRESULT Target_CStringPoolHash::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_CChainedHash::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.ReadPointer(&m_Pool)); - return S_OK; -} - -Target_CBlobPoolHash::Target_CBlobPoolHash() : -m_Pool(0) -{} - -HRESULT Target_CBlobPoolHash::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_CChainedHash::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.ReadPointer(&m_Pool)); - return S_OK; -} - - -Target_CGuidPoolHash::Target_CGuidPoolHash() : -m_Pool(0) -{ } - -HRESULT Target_CGuidPoolHash::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_CChainedHash::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.ReadPointer(&m_Pool)); - return S_OK; -} - -HRESULT Target_StgPoolReadOnly::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.SkipPointer()); // __vfptr - IfFailRet(Target_StgPoolSeg::ReadFrom(reader)); - reader.AlignBase(); - return S_OK; -} - -Target_StgPool::Target_StgPool() : -m_ulGrowInc(0), -m_pCurSeg(0), -m_cbCurSegOffset(0), -m_bFree(FALSE), -m_bReadOnly(FALSE), -m_nVariableAlignmentMask(0), -m_cbStartOffsetOfEdit(0), -m_fValidOffsetOfEdit(FALSE) -{} - -HRESULT Target_StgPool::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_StgPoolReadOnly::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.Read32(&m_ulGrowInc)); - IfFailRet(reader.ReadPointer(&m_pCurSeg)); - IfFailRet(reader.Read32(&m_cbCurSegOffset)); - ULONG32 bitField; - IfFailRet(reader.Read32(&bitField)); - m_bFree = (bitField & 0x1) != 0; - m_bReadOnly = (bitField & 0x2) != 0; - IfFailRet(reader.Read32(&m_nVariableAlignmentMask)); - IfFailRet(reader.Read32(&m_cbStartOffsetOfEdit)); - IfFailRet(reader.Read8((BYTE*)&m_fValidOffsetOfEdit)); - return S_OK; -} - -HRESULT Target_StgBlobPool::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_StgPool::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.Read(&m_Hash)); - return S_OK; -} - -Target_StgStringPool::Target_StgStringPool() : -m_bHash(FALSE) -{ -} - -HRESULT Target_StgStringPool::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_StgPool::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.Read(&m_Hash)); - IfFailRet(reader.Read8((BYTE*)&m_bHash)); - return S_OK; -} - -Target_StgGuidPool::Target_StgGuidPool() : -m_bHash(FALSE) -{} - -HRESULT Target_StgGuidPool::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_StgPool::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.Read(&m_Hash)); - IfFailRet(reader.Read8((BYTE*)&m_bHash)); - return S_OK; -} - -Target_RecordPool::Target_RecordPool() : -m_cbRec(0) -{} - -HRESULT Target_RecordPool::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_StgPool::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.Read32(&m_cbRec)); - return S_OK; -} - -Target_OptionValue::Target_OptionValue() : -m_DupCheck(0), -m_RefToDefCheck(0), -m_NotifyRemap(0), -m_UpdateMode(0), -m_ErrorIfEmitOutOfOrder(0), -m_ThreadSafetyOptions(0), -m_ImportOption(0), -m_LinkerOption(0), -m_GenerateTCEAdapters(0), -m_RuntimeVersion(0), -m_MetadataVersion(0), -m_MergeOptions(0), -m_InitialSize(0), -m_LocalRefPreservation(0) -{} - -HRESULT Target_OptionValue::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.Read32(&m_DupCheck)); - IfFailRet(reader.Read32(&m_RefToDefCheck)); - IfFailRet(reader.Read32(&m_NotifyRemap)); - IfFailRet(reader.Read32(&m_UpdateMode)); - IfFailRet(reader.Read32(&m_ErrorIfEmitOutOfOrder)); - IfFailRet(reader.Read32(&m_ThreadSafetyOptions)); - IfFailRet(reader.Read32(&m_ImportOption)); - IfFailRet(reader.Read32(&m_LinkerOption)); - IfFailRet(reader.Read32(&m_GenerateTCEAdapters)); - IfFailRet(reader.ReadPointer(&m_RuntimeVersion)); - IfFailRet(reader.Read32(&m_MetadataVersion)); - IfFailRet(reader.Read32(&m_MergeOptions)); - IfFailRet(reader.Read32(&m_InitialSize)); - IfFailRet(reader.Read32(&m_LocalRefPreservation)); - return S_OK; -} - -Target_CMiniMdRW::Target_CMiniMdRW() : -m_pMemberRefHash(0), -m_pMemberDefHash(0), -m_pNamedItemHash(0), -m_maxRid(0), -m_limRid(0), -m_maxIx(0), -m_limIx(0), -m_eGrow(0), -m_pHandler(0), -m_cbSaveSize(0), -m_fIsReadOnly(FALSE), -m_bPreSaveDone(FALSE), -m_bSaveCompressed(FALSE), -m_bPostGSSMod(FALSE), -m_pMethodMap(0), -m_pFieldMap(0), -m_pPropertyMap(0), -m_pEventMap(0), -m_pParamMap(0), -m_pFilterTable(0), -m_pHostFilter(0), -m_pTokenRemapManager(0), -dbg_m_pLock(0), -m_fMinimalDelta(FALSE), -m_rENCRecs(0) -{ - memset(&m_pLookUpHashes, 0, TBL_COUNT*sizeof(CORDB_ADDRESS)); - memset(&m_pVS, 0, TBL_COUNT*sizeof(CORDB_ADDRESS)); - memset(&m_bSortable, 0, TBL_COUNT*sizeof(BYTE)); -} - -HRESULT Target_CMiniMdRW::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_CMiniMdTemplate_CMiniMdRW::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.ReadPointer(&m_pMemberRefHash)); - IfFailRet(reader.ReadPointer(&m_pMemberDefHash)); - for (int i = 0; i < TBL_COUNT; i++) - IfFailRet(reader.ReadPointer(&m_pLookUpHashes[i])); - IfFailRet(reader.ReadPointer(&m_pNamedItemHash)); - IfFailRet(reader.Read32(&m_maxRid)); - IfFailRet(reader.Read32(&m_limRid)); - IfFailRet(reader.Read32(&m_maxIx)); - IfFailRet(reader.Read32(&m_limIx)); - IfFailRet(reader.Read32(&m_eGrow)); - for (int i = 0; i < TBL_COUNT; i++) - IfFailRet(reader.Read(&m_Tables[i])); - for (int i = 0; i < TBL_COUNT; i++) - IfFailRet(reader.ReadPointer(&m_pVS[i])); - IfFailRet(reader.Read(&m_StringHeap)); - IfFailRet(reader.Read(&m_BlobHeap)); - IfFailRet(reader.Read(&m_UserStringHeap)); - IfFailRet(reader.Read(&m_GuidHeap)); - IfFailRet(reader.ReadPointer(&m_pHandler)); - IfFailRet(reader.Read32(&m_cbSaveSize)); - ULONG32 bitField; - IfFailRet(reader.Read32(&bitField)); - m_fIsReadOnly = (bitField & 0x1) != 0; - m_bPreSaveDone = (bitField & 0x2) != 0; - m_bSaveCompressed = (bitField & 0x4) != 0; - m_bPostGSSMod = (bitField & 0x8) != 0; - IfFailRet(reader.ReadPointer(&m_pMethodMap)); - IfFailRet(reader.ReadPointer(&m_pFieldMap)); - IfFailRet(reader.ReadPointer(&m_pPropertyMap)); - IfFailRet(reader.ReadPointer(&m_pEventMap)); - IfFailRet(reader.ReadPointer(&m_pParamMap)); - IfFailRet(reader.ReadPointer(&m_pFilterTable)); - IfFailRet(reader.ReadPointer(&m_pHostFilter)); - IfFailRet(reader.ReadPointer(&m_pTokenRemapManager)); - IfFailRet(reader.Read(&m_OptionValue)); - IfFailRet(reader.Read(&m_StartupSchema)); - for (int i = 0; i < TBL_COUNT; i++) - IfFailRet(reader.Read8((BYTE*)&m_bSortable[i])); - if (reader.IsDefined(1)) // replace this with DEFINE__DEBUG - { - IfFailRet(reader.ReadPointer(&dbg_m_pLock)); - } - IfFailRet(reader.Read8((BYTE*)&m_fMinimalDelta)); - IfFailRet(reader.Read8((BYTE*)&m_fAll4ByteColumns)); - IfFailRet(reader.ReadPointer(&m_rENCRecs)); - return S_OK; -} - - - -Target_CLiteWeightStgdb_CMiniMdRW::Target_CLiteWeightStgdb_CMiniMdRW() : -m_pvMd(0), -m_cbMd(0) -{ -} - -HRESULT Target_CLiteWeightStgdb_CMiniMdRW::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.Read(&m_MiniMd)); - IfFailRet(reader.ReadPointer(&m_pvMd)); - IfFailRet(reader.Read32(&m_cbMd)); - return S_OK; -} - -Target_CLiteWeightStgdbRW::Target_CLiteWeightStgdbRW() : -m_cbSaveSize(0), -m_bSaveCompressed(FALSE), -m_pImage(0), -m_dwImageSize(0), -m_dwPEKind(0), -m_dwMachine(0), -m_pStreamList(0), -m_pNextStgdb(0), -m_eFileType(0), -m_wszFileName(0) -{} - -HRESULT Target_CLiteWeightStgdbRW::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(Target_CLiteWeightStgdb_CMiniMdRW::ReadFrom(reader)); - reader.AlignBase(); - IfFailRet(reader.Read32(&m_cbSaveSize)); - IfFailRet(reader.Read8((BYTE*)&m_bSaveCompressed)); - IfFailRet(reader.ReadPointer(&m_pImage)); - IfFailRet(reader.Read32(&m_dwImageSize)); - IfFailRet(reader.Read32(&m_dwPEKind)); - IfFailRet(reader.Read32(&m_dwMachine)); - IfFailRet(reader.ReadPointer(&m_pStreamList)); - IfFailRet(reader.ReadPointer(&m_pNextStgdb)); - IfFailRet(reader.Read32(&m_eFileType)); - IfFailRet(reader.ReadPointer(&m_wszFileName)); - IfFailRet(reader.ReadPointer(&m_pStgIO)); - return S_OK; -} - - - -Target_MDInternalRW::Target_MDInternalRW() : -m_tdModule(0), -m_cRefs(0), -m_fOwnStgdb(FALSE), -m_pUnk(0), -m_pUserUnk(0), -m_pIMetaDataHelper(0), -m_pSemReadWrite(0), -m_fOwnSem(FALSE) -{ -} - -HRESULT Target_MDInternalRW::ReadFrom(DataTargetReader & reader) -{ - HRESULT hr = S_OK; - IfFailRet(reader.SkipPointer()); // IMDInternalImportENC vtable - IfFailRet(reader.SkipPointer()); // IMDCommon vtable - IfFailRet(reader.ReadPointer(&m_pStgdb)); - IfFailRet(reader.Read32(&m_tdModule)); - IfFailRet(reader.Read32(&m_cRefs)); - IfFailRet(reader.Read8((BYTE*)&m_fOwnStgdb)); - IfFailRet(reader.ReadPointer(&m_pUnk)); - IfFailRet(reader.ReadPointer(&m_pUserUnk)); - IfFailRet(reader.ReadPointer(&m_pIMetaDataHelper)); - IfFailRet(reader.ReadPointer(&m_pSemReadWrite)); - IfFailRet(reader.Read8((BYTE*)&m_fOwnSem)); - return S_OK; -} diff --git a/src/coreclr/md/datasource/targettypes.h b/src/coreclr/md/datasource/targettypes.h deleted file mode 100644 index adfcdb87d635c5..00000000000000 --- a/src/coreclr/md/datasource/targettypes.h +++ /dev/null @@ -1,346 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// TargetTypes.h -// - -// -//***************************************************************************** - -#ifndef _MD_TARGET_TYPES_ -#define _MD_TARGET_TYPES_ - -#include "datatargetreader.h" - -class Target_CMiniMdSchemaBase : public TargetObject -{ -public: - Target_CMiniMdSchemaBase(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - ULONG32 m_ulReserved; - BYTE m_major; - BYTE m_minor; - BYTE m_heaps; - BYTE m_rid; - ULONG64 m_maskvalid; - ULONG64 m_sorted; -}; - -class Target_CMiniMdSchema : public Target_CMiniMdSchemaBase -{ -public: - Target_CMiniMdSchema(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - ULONG32 m_cRecs[TBL_COUNT]; - ULONG32 m_ulExtra; -}; - -class Target_CMiniColDef : public TargetObject -{ -public: - Target_CMiniColDef(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - BYTE m_Type; - BYTE m_oColumn; - BYTE m_cbColumn; -}; - -class Target_CMiniTableDef : public TargetObject -{ -public: - Target_CMiniTableDef(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - NewArrayHolder m_pColDefs; - BYTE m_cCols; - BYTE m_iKey; - BYTE m_cbRec; - -private: - // don't copy this type - avoids needing to deep copy m_pColDefs - Target_CMiniTableDef(const Target_CMiniTableDef & rhs) { _ASSERTE(!"Don't copy"); } - Target_CMiniTableDef & operator=(const Target_CMiniTableDef &) - { - _ASSERTE(!"Don't copy"); - return *this; - } -}; - -class Target_CMiniMdBase : public TargetObject -{ -public: - Target_CMiniMdBase(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - Target_CMiniMdSchema m_Schema; - ULONG32 m_TblCount; - BOOL m_fVerifiedByTrustedSource; - Target_CMiniTableDef m_TableDefs[TBL_COUNT]; - - ULONG32 m_iStringsMask; - ULONG32 m_iGuidsMask; - ULONG32 m_iBlobsMask; -}; - -class Target_CMiniMdTemplate_CMiniMdRW : public Target_CMiniMdBase -{ -}; - -class Target_MapSHash : public TargetObject -{ -public: - Target_MapSHash(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_table; - ULONG32 m_tableSize; - ULONG32 m_tableCount; - ULONG32 m_tableOccupied; - ULONG32 m_tableMax; -}; - -class Target_CChainedHash : public TargetObject -{ -public: - Target_CChainedHash(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_rgData; - ULONG32 m_iBuckets; - ULONG32 m_iSize; - ULONG32 m_iCount; - ULONG32 m_iMaxChain; - ULONG32 m_iFree; -}; - -class Target_CStringPoolHash : public Target_CChainedHash -{ -public: - Target_CStringPoolHash(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_Pool; -}; - -class Target_StgPoolSeg : public TargetObject -{ -public: - Target_StgPoolSeg(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_pSegData; - CORDB_ADDRESS m_pNextSeg; - ULONG32 m_cbSegSize; - ULONG32 m_cbSegNext; -}; - -class Target_StgPoolReadOnly : public Target_StgPoolSeg -{ -public: - virtual HRESULT ReadFrom(DataTargetReader & reader); -}; - -class Target_StgPool : public Target_StgPoolReadOnly -{ -public: - Target_StgPool(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - ULONG32 m_ulGrowInc; - CORDB_ADDRESS m_pCurSeg; - ULONG32 m_cbCurSegOffset; - BOOL m_bFree; - BOOL m_bReadOnly; - ULONG32 m_nVariableAlignmentMask; - ULONG32 m_cbStartOffsetOfEdit; - BOOL m_fValidOffsetOfEdit; -}; - -class Target_StgStringPool : public Target_StgPool -{ -public: - Target_StgStringPool(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - Target_CStringPoolHash m_Hash; - BOOL m_bHash; -}; - -class Target_StringHeapRW : public Target_StgStringPool -{ -}; - -class Target_CBlobPoolHash : public Target_CChainedHash -{ -public: - Target_CBlobPoolHash(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_Pool; -}; - -class Target_StgBlobPool : public Target_StgPool -{ -public: - virtual HRESULT ReadFrom(DataTargetReader & reader); - - Target_CBlobPoolHash m_Hash; -}; - -class Target_BlobHeapRW : public Target_StgBlobPool -{ -}; - -class Target_CGuidPoolHash : public Target_CChainedHash -{ -public: - Target_CGuidPoolHash(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_Pool; -}; - -class Target_StgGuidPool : public Target_StgPool -{ -public: - Target_StgGuidPool(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - Target_CGuidPoolHash m_Hash; - BOOL m_bHash; -}; - -class Target_GuidHeapRW : public Target_StgGuidPool -{ -}; - -class Target_RecordPool : public Target_StgPool -{ -public: - Target_RecordPool(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - ULONG32 m_cbRec; -}; - -class Target_TableRW : public Target_RecordPool -{ -}; - -class Target_OptionValue : public TargetObject -{ -public: - Target_OptionValue(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - ULONG32 m_DupCheck; - ULONG32 m_RefToDefCheck; - ULONG32 m_NotifyRemap; - ULONG32 m_UpdateMode; - ULONG32 m_ErrorIfEmitOutOfOrder; - ULONG32 m_ThreadSafetyOptions; - ULONG32 m_ImportOption; - ULONG32 m_LinkerOption; - ULONG32 m_GenerateTCEAdapters; - CORDB_ADDRESS m_RuntimeVersion; - ULONG32 m_MetadataVersion; - ULONG32 m_MergeOptions; - ULONG32 m_InitialSize; - ULONG32 m_LocalRefPreservation; -}; - -class Target_CMiniMdRW : public Target_CMiniMdTemplate_CMiniMdRW -{ -public: - Target_CMiniMdRW(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - CORDB_ADDRESS m_pMemberRefHash; - CORDB_ADDRESS m_pMemberDefHash; - CORDB_ADDRESS m_pLookUpHashes[TBL_COUNT]; - CORDB_ADDRESS m_pNamedItemHash; - ULONG32 m_maxRid; - ULONG32 m_limRid; - ULONG32 m_maxIx; - ULONG32 m_limIx; - ULONG32 m_eGrow; - Target_TableRW m_Tables[TBL_COUNT]; - CORDB_ADDRESS m_pVS[TBL_COUNT]; - Target_StringHeapRW m_StringHeap; - Target_BlobHeapRW m_BlobHeap; - Target_BlobHeapRW m_UserStringHeap; - Target_GuidHeapRW m_GuidHeap; - CORDB_ADDRESS m_pHandler; - ULONG32 m_cbSaveSize; - BOOL m_fIsReadOnly; - BOOL m_bPreSaveDone; - BOOL m_bSaveCompressed; - BOOL m_bPostGSSMod; - CORDB_ADDRESS m_pMethodMap; - CORDB_ADDRESS m_pFieldMap; - CORDB_ADDRESS m_pPropertyMap; - CORDB_ADDRESS m_pEventMap; - CORDB_ADDRESS m_pParamMap; - CORDB_ADDRESS m_pFilterTable; - CORDB_ADDRESS m_pHostFilter; - CORDB_ADDRESS m_pTokenRemapManager; - Target_OptionValue m_OptionValue; - Target_CMiniMdSchema m_StartupSchema; - BYTE m_bSortable[TBL_COUNT]; - CORDB_ADDRESS dbg_m_pLock; - BOOL m_fMinimalDelta; - BOOL m_fAll4ByteColumns; - CORDB_ADDRESS m_rENCRecs; -}; - -class Target_CLiteWeightStgdb_CMiniMdRW : public TargetObject -{ -public: - Target_CLiteWeightStgdb_CMiniMdRW(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - Target_CMiniMdRW m_MiniMd; - CORDB_ADDRESS m_pvMd; - ULONG32 m_cbMd; -}; - -class Target_CLiteWeightStgdbRW : public Target_CLiteWeightStgdb_CMiniMdRW -{ -public: - Target_CLiteWeightStgdbRW(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - ULONG32 m_cbSaveSize; - BOOL m_bSaveCompressed; - CORDB_ADDRESS m_pImage; - ULONG32 m_dwImageSize; - ULONG32 m_dwPEKind; - ULONG32 m_dwMachine; - CORDB_ADDRESS m_pStreamList; - CORDB_ADDRESS m_pNextStgdb; - ULONG32 m_eFileType; - CORDB_ADDRESS m_wszFileName; - CORDB_ADDRESS m_pStgIO; -}; - -class Target_MDInternalRW : public TargetObject -{ -public: - Target_MDInternalRW(); - virtual HRESULT ReadFrom(DataTargetReader & reader); - - Target_CLiteWeightStgdbRW m_pStgdb; - ULONG32 m_tdModule; - ULONG32 m_cRefs; - BOOL m_fOwnStgdb; - CORDB_ADDRESS m_pUnk; - CORDB_ADDRESS m_pUserUnk; - CORDB_ADDRESS m_pIMetaDataHelper; - CORDB_ADDRESS m_pSemReadWrite; - BOOL m_fOwnSem; -}; - -#endif diff --git a/src/coreclr/md/enc/liteweightstgdbrw.cpp b/src/coreclr/md/enc/liteweightstgdbrw.cpp index 5a867df0e1f98c..4094e84aed5d17 100644 --- a/src/coreclr/md/enc/liteweightstgdbrw.cpp +++ b/src/coreclr/md/enc/liteweightstgdbrw.cpp @@ -417,32 +417,6 @@ HRESULT CLiteWeightStgdbRW::OpenForRead( return hr; } -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE -// Open a metadata section for read/write -__checkReturn -HRESULT CLiteWeightStgdbRW::OpenForRead( - IMDCustomDataSource *pDataSource, // data to open on top of - DWORD dwFlags) // Flags for the open. -{ - LPCWSTR pNoFile = W(""); // Constant for empty file name. - StgIO *pStgIO = NULL; // For file i/o. - HRESULT hr; - - m_pImage = NULL; - m_dwImageSize = 0; - m_eFileType = FILETYPE_UNKNOWN; - - IfFailGo(m_MiniMd.InitOnCustomDataSource(pDataSource)); - IfFailGo(m_MiniMd.PostInit(0)); - - // Save off everything. - IfFailGo(SetFileName(pNoFile)); - -ErrExit: - return hr; -} -#endif - // Read/Write versions. //***************************************************************************** // Init the Stgdb and its subcomponents. @@ -1015,11 +989,6 @@ HRESULT CLiteWeightStgdbRW::GetRawData( const void **ppvMd, // [OUT] put pointer to MD section here (aka, 'BSJB'). ULONG *pcbMd) // [OUT] put size of the stream here. { -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - if (m_pStgIO == NULL) - return COR_E_NOTSUPPORTED; -#endif - *ppvMd = (const void*) m_pStgIO->m_pData; *pcbMd = m_pStgIO->m_cbData; return S_OK; @@ -1044,11 +1013,6 @@ CLiteWeightStgdbRW::GetRawStreamInfo( void *pData; ULONG cbData; -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - if (m_pStgIO == NULL) - IfFailGo(COR_E_NOTSUPPORTED); -#endif - pData = m_pStgIO->m_pData; cbData = m_pStgIO->m_cbData; diff --git a/src/coreclr/md/enc/metamodelrw.cpp b/src/coreclr/md/enc/metamodelrw.cpp index 7bb292e6f515ad..be814089a2cd14 100644 --- a/src/coreclr/md/enc/metamodelrw.cpp +++ b/src/coreclr/md/enc/metamodelrw.cpp @@ -1658,173 +1658,6 @@ CMiniMdRW::InitOnRO( return hr; } // CMiniMdRW::InitOnRO -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - -// This checks that column sizes are reasonable for their types -// The sizes could still be too small to hold all values in the range, or larger -// than they needed, but there must exist some scenario where this size is the -// one we would use. -// As long as this validation passes + we verify that the records actually -// have space for columns of this size then the worst thing that malicious -// data could do is be slightly inneficient, or be unable to address all their data -HRESULT _ValidateColumnSize(BYTE trustedColumnType, BYTE untrustedColumnSize) -{ - // Is the field a RID into a table? - if (trustedColumnType <= iCodedTokenMax) - { - if (untrustedColumnSize != sizeof(USHORT) && untrustedColumnSize != sizeof(ULONG)) - return CLDB_E_FILE_CORRUPT; - } - else - { // Fixed type. - switch (trustedColumnType) - { - case iBYTE: - if (untrustedColumnSize != 1) - return CLDB_E_FILE_CORRUPT; - break; - case iSHORT: - case iUSHORT: - if (untrustedColumnSize != 2) - return CLDB_E_FILE_CORRUPT; - break; - case iLONG: - case iULONG: - if (untrustedColumnSize != 4) - return CLDB_E_FILE_CORRUPT; - break; - case iSTRING: - case iGUID: - case iBLOB: - if (untrustedColumnSize != 2 && untrustedColumnSize != 4) - return CLDB_E_FILE_CORRUPT; - break; - default: - _ASSERTE(!"Unexpected schema type"); - return CLDB_E_FILE_CORRUPT; - } - } - return S_OK; -} - -__checkReturn -HRESULT CMiniMdRW::InitOnCustomDataSource(IMDCustomDataSource* pDataSource) -{ - HRESULT hr = S_OK; - ULONG i; // Loop control. - ULONG key; - BOOL fIsReadOnly = TRUE; - MetaData::DataBlob stringPoolData; - MetaData::DataBlob userStringPoolData; - MetaData::DataBlob guidHeapData; - MetaData::DataBlob blobHeapData; - MetaData::DataBlob tableRecordData; - CMiniTableDef tableDef; - BOOL sortable = FALSE; - - - // the data source owns all the memory backing the storage pools, so we need to ensure it stays alive - // after this method returns. When the CMiniMdRW is destroyed the reference will be released. - pDataSource->AddRef(); - m_pCustomDataSource = pDataSource; - - // Copy over the schema. - IfFailGo(pDataSource->GetSchema(&m_Schema)); - - // Is this the "native" version of the metadata for this runtime? - if ((m_Schema.m_major != METAMODEL_MAJOR_VER) || (m_Schema.m_minor != METAMODEL_MINOR_VER)) - { - // We don't support this version of the metadata - Debug_ReportError("Unsupported version of MetaData."); - return PostError(CLDB_E_FILE_OLDVER, m_Schema.m_major, m_Schema.m_minor); - } - - // How big are the various pool inidices? - m_iStringsMask = (m_Schema.m_heaps & CMiniMdSchema::HEAP_STRING_4) ? 0xffffffff : 0xffff; - m_iGuidsMask = (m_Schema.m_heaps & CMiniMdSchema::HEAP_GUID_4) ? 0xffffffff : 0xffff; - m_iBlobsMask = (m_Schema.m_heaps & CMiniMdSchema::HEAP_BLOB_4) ? 0xffffffff : 0xffff; - - // Copy over TableDefs, column definitions and allocate VS structs for tables with key columns. - for (ULONG ixTbl = 0; ixTbl < m_TblCount; ++ixTbl) - { - IfFailGo(pDataSource->GetTableDef(ixTbl, &tableDef)); - const CMiniTableDef* pTemplate = GetTableDefTemplate(ixTbl); - - // validate that the table def looks safe - // we only allow some very limited differences between the standard template and the data source - key = (pTemplate->m_iKey < pTemplate->m_cCols) ? pTemplate->m_iKey : 0xFF; - if (key != tableDef.m_iKey) { IfFailGo(CLDB_E_FILE_CORRUPT); } - if (pTemplate->m_cCols != tableDef.m_cCols) { IfFailGo(CLDB_E_FILE_CORRUPT); } - ULONG cbRec = 0; - for (ULONG i = 0; i < pTemplate->m_cCols; i++) - { - if (tableDef.m_pColDefs == NULL) { IfFailGo(CLDB_E_FILE_CORRUPT); } - if (pTemplate->m_pColDefs[i].m_Type != tableDef.m_pColDefs[i].m_Type) { IfFailGo(CLDB_E_FILE_CORRUPT); } - IfFailGo(_ValidateColumnSize(pTemplate->m_pColDefs[i].m_Type, tableDef.m_pColDefs[i].m_cbColumn)); - // sometimes, but not always, it seems like columns get alignment padding - // we'll allow it if we see it - if (cbRec > tableDef.m_pColDefs[i].m_oColumn) { IfFailGo(CLDB_E_FILE_CORRUPT); } - if (tableDef.m_pColDefs[i].m_oColumn > AlignUp(cbRec, tableDef.m_pColDefs[i].m_cbColumn)) { IfFailGo(CLDB_E_FILE_CORRUPT); } - cbRec = tableDef.m_pColDefs[i].m_oColumn + tableDef.m_pColDefs[i].m_cbColumn; - } - if (tableDef.m_cbRec != cbRec) { IfFailGo(CLDB_E_FILE_CORRUPT); } - - // tabledef passed validation, copy it in - m_TableDefs[ixTbl].m_iKey = tableDef.m_iKey; - m_TableDefs[ixTbl].m_cCols = tableDef.m_cCols; - m_TableDefs[ixTbl].m_cbRec = tableDef.m_cbRec; - IfFailGo(SetNewColumnDefinition(&(m_TableDefs[ixTbl]), tableDef.m_pColDefs, ixTbl)); - if (m_TableDefs[ixTbl].m_iKey < m_TableDefs[ixTbl].m_cCols) - { - m_pVS[ixTbl] = new (nothrow)VirtualSort; - IfNullGo(m_pVS[ixTbl]); - - m_pVS[ixTbl]->Init(ixTbl, m_TableDefs[ixTbl].m_iKey, this); - } - } - - // Initialize string heap - IfFailGo(pDataSource->GetStringHeap(&stringPoolData)); - m_StringHeap.Initialize(stringPoolData, !fIsReadOnly); - - // Initialize user string heap - IfFailGo(pDataSource->GetUserStringHeap(&userStringPoolData)); - m_UserStringHeap.Initialize(userStringPoolData, !fIsReadOnly); - - // Initialize guid heap - IfFailGo(pDataSource->GetGuidHeap(&guidHeapData)); - m_GuidHeap.Initialize(guidHeapData, !fIsReadOnly); - - // Initialize blob heap - IfFailGo(pDataSource->GetBlobHeap(&blobHeapData)); - m_BlobHeap.Initialize(blobHeapData, !fIsReadOnly); - - // Init the record pools - for (i = 0; i < m_TblCount; ++i) - { - IfFailGo(pDataSource->GetTableRecords(i, &tableRecordData)); - // sanity check record counts and table sizes, this also ensures that cbRec*m_cRecs[x] doesn't overflow - if (m_Schema.m_cRecs[i] > 1000000) { IfFailGo(CLDB_E_FILE_CORRUPT); } - if (tableRecordData.GetSize() < m_TableDefs[i].m_cbRec * m_Schema.m_cRecs[i]) { IfFailGo(CLDB_E_FILE_CORRUPT); } - m_Tables[i].Initialize(m_TableDefs[i].m_cbRec, tableRecordData, !fIsReadOnly); - - IfFailGo(pDataSource->GetTableSortable(i, &sortable)); - m_bSortable[i] = !!sortable ? 1 : 0; - } - - // Set the limits so we will know when to grow the database. - ComputeGrowLimits(TRUE /* small */); - - // Track records that this MD started with. - m_StartupSchema = m_Schema; - - m_fIsReadOnly = fIsReadOnly; - -ErrExit: - return hr; -} -#endif - //***************************************************************************** // Convert a read-only to read-write. Copies data. //***************************************************************************** @@ -7704,4 +7537,3 @@ FilterTable::~FilterTable() delete m_daUserStringMarker; Clear(); } // FilterTable::~FilterTable - diff --git a/src/coreclr/md/inc/VerifyLayouts.inc b/src/coreclr/md/inc/VerifyLayouts.inc deleted file mode 100644 index 97f841d10c8bf3..00000000000000 --- a/src/coreclr/md/inc/VerifyLayouts.inc +++ /dev/null @@ -1,337 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -// This file provides an explicit check of field layouts using some macro magic -// in VerifyLayouts.h. The goal is that if any field changes offset or type changes -// size then a build time assert should trigger. DO NOT change these definitions without -// reading the comments in VerifyLayouts.h and understanding what other code you need -// to change at the same time. -// -// -// AN EXAMPLE: -// You want to validate the fields in type CDerived -// -// class CFoo -// { -// void* m_ptrField; -// } -// -// struct BigStruct -// { -// DWORD m_one; -// DWORD m_two; -// DWORD m_three; -// } -// -// CDerived : CFoo -// { -// DWORD m_cRef; -// SomeOtherType* m_otherType; -// #ifdef _SOME_DEFINE -// BigStruct m_struct; -// #endif //_SOME_DEFINE -// } -// -// -// and the layout validation is written as: -// -// BEGIN_TYPE(CDerived, sizeof(CFoo)) // a) The first field starts at sizeof(CFoo) to account for base class data -// // b) Beware of vtable pointers, they take up space before the data fields too -// // c) Beware of using sizeof(some_other_type) unless you also explicitly verify -// // the layout of that type here. Changing the base type would change the derived types -// // layout and won't be caught unless the base type is explicitly verified. -// // d) sizeof() is fine - they never change over time and we know how -// // to deal with platform pointer size differences -// FIELD(CDerived, m_cRef, 4) -// FIELD(CDerived, m_otherType, sizeof(void*)) -// #ifdef _SOME_DEFINE_ -// ALIGN_FIELD(CDerived, m_struct, sizeof(BigStruct), 4) // We need to use the ALIGN_FIELD macro because the alignment isn't the same as -// // the field size. The alignment of a structure is typically the max alignment -// // of any member. The alignment of a primitive type is typically the size of the type. -// #endif _SOME_DEFINE_ -// END_TYPE(CDerived, sizeof(void*) -// -// -// BEGIN_TYPE(CFoo, 0) // We must verify this type because we used it to define the starting offset of CDerived -// FIELD(CFoo, m_ptrField, sizeof(void*)) -// END_TYPE(CFoo, sizeof(void*)) -// -// -// BEGIN_TYPE(BigStruct, 0) // We must verify this type because we used sizeof(BigStruct) to define the size of -// // CDerived::m_struct field -// FIELD(BigStruct, m_one, 4) -// FIELD(BigStruct, m_two, 4) -// FIELD(BigStruct, m_thee, 4) -// END_TYPE(BigStruct, 4) -// -// -// -// -// OTHER CONSIDERATIONS: -// -// 1) if the type layout is conditional on a define, just include the same define here in the layout verification -// Make sure that the define is registered in the list of defines and the debugger reading code knows how to dynamically -// adjust for it (See VerifyLayouts.h comment item (b) and (c)) -// -// 2) If your type names use characters that aren't valid identifiers (such as the '<', '>' and ',' chars in templates) -// then you need to provide an escaped name. Use the USING_ALIAS macros to do that: -// USING_ALIAS(escapedTypeName, typeName) -// -// If CFoo above had instead been CFoo we would write: -// USING_ALIAS(CFoo__ULONG__, CFoo) -// BEGIN_TYPE(CFoo__ULONG__, 0) -// FIELD(CFoo__ULONG__, m_ptrField, sizeof(void*)) -// END_TYPE(CFoo__ULONG__, sizeof(void*)) -// -// The escapedTypeName is relatively arbitrary, but convention is to replace the illegal characters with double underscore -// The name does show up in build error messages, so it should close to the real name for people to understand -// -// 3) If you have a bitfield in your type, the offsetof macro can't be used which will break the static asserts. -// There is a special BITFIELD macro that can work around it: -// BITFIELD(typeName, fieldName, expectedFieldOffset, fieldSize, fieldAlign) -// -// The macro is just like FIELD execpt you must provide the offset yourself. Since you can't use offsetof on the field directly -// the convention is to use the offset of the previous field and then add the size and alignment requirements. For example if your -// type had this: -// CMiniMdRW -// { -// ULONG m_cbSaveSize; -// int m_fIsReadOnly : 1; -// int m_bPreSaveDone : 1; -// int m_bSaveCompressed : 1; -// int m_bPostGSSMod : 1; -// } -// -// You could write -// FIELD(CMiniMdRW, m_cbSaveSize, 4) -// BITFIELD(CMiniMdRW, m_fIsReadOnly, offsetof(CMiniMdRW, m_cbSaveSize)+4, 4) -// -// Don't include al the fields in the bitfield, just pick one as the canonical field name -// -// -// -// HOW DO I DEBUG THIS STUFF WHEN THE BUILD DOESN'T WORK? -// -// One way that has been effective for me is to write a few static_assert entries manually in VerifyLayouts.h -// You can use those to verify your assumptions such as: -// static_assert(sizeof(Foo) == 24) -// static_assert(offset(Foo, m_lastField) == 20) -// static_assert(offset_of_field_affter_Foo_m_lastField == 24) -// Then rebuild and find out where the compiler disagress with you. -// -// Another option is to run the source through the preprocessor -// -// -// - - - - - - -BEGIN_TYPE(MDInternalRW, 2*sizeof(void*)) -FIELD(MDInternalRW, m_pStgdb, sizeof(void*)) -FIELD(MDInternalRW, m_tdModule, 4) -FIELD(MDInternalRW, m_cRefs, 4) -FIELD(MDInternalRW, m_fOwnStgdb, 4) -FIELD(MDInternalRW, m_pUnk, sizeof(void*)) -FIELD(MDInternalRW, m_pUserUnk, sizeof(void*)) -FIELD(MDInternalRW, m_pIMetaDataHelper, sizeof(void*)) -FIELD(MDInternalRW, m_pSemReadWrite, sizeof(void*)) -FIELD(MDInternalRW, m_fOwnSem, 4) -END_TYPE(MDInternalRW, sizeof(void*)) - -BEGIN_TYPE(CLiteWeightStgdbRW, sizeof(CLiteWeightStgdb)) -FIELD(CLiteWeightStgdbRW, m_cbSaveSize, 4) -FIELD(CLiteWeightStgdbRW, m_bSaveCompressed, 4) -FIELD(CLiteWeightStgdbRW, m_pImage, sizeof(void*)) -FIELD(CLiteWeightStgdbRW, m_dwImageSize, 4) -FIELD(CLiteWeightStgdbRW, m_dwPEKind, 4) -FIELD(CLiteWeightStgdbRW, m_dwMachine, 4) -FIELD(CLiteWeightStgdbRW, m_pStreamList, sizeof(void*)) -FIELD(CLiteWeightStgdbRW, m_pNextStgdb, sizeof(void*)) -FIELD(CLiteWeightStgdbRW, m_eFileType, 4) -FIELD(CLiteWeightStgdbRW, m_wszFileName, sizeof(void*)) -FIELD(CLiteWeightStgdbRW, m_pStgIO, sizeof(void*)) -#ifdef FEATURE_METADATA_EMIT_PORTABLE_PDB -FIELD(CLiteWeightStgdbRW, m_pPdbHeap, sizeof(void*)) -#endif -END_TYPE(CLiteWeightStgdbRW, 8) - -USING_ALIAS(CLiteWeightStgdb__CMiniMdRW__, CLiteWeightStgdb) -BEGIN_TYPE(CLiteWeightStgdb__CMiniMdRW__, 0) -ALIGN_FIELD(CLiteWeightStgdb__CMiniMdRW__, m_MiniMd, sizeof(CMiniMdRW), sizeof(void*)) -FIELD(CLiteWeightStgdb__CMiniMdRW__, m_pvMd, sizeof(void*)) -FIELD(CLiteWeightStgdb__CMiniMdRW__, m_cbMd, 4) -END_TYPE(CLiteWeightStgdb__CMiniMdRW__, sizeof(void*)) - -BEGIN_TYPE(CMiniMdRW, sizeof(CMiniMdTemplate)) -FIELD(CMiniMdRW, m_pMemberRefHash, sizeof(void*)) -FIELD(CMiniMdRW, m_pMemberDefHash, sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_pLookUpHashes, sizeof(void*)*TBL_COUNT, sizeof(void*)) -FIELD(CMiniMdRW, m_pNamedItemHash, sizeof(void*)) -FIELD(CMiniMdRW, m_maxRid, 4) -FIELD(CMiniMdRW, m_limRid, 4) -FIELD(CMiniMdRW, m_maxIx, 4) -FIELD(CMiniMdRW, m_limIx, 4) -FIELD(CMiniMdRW, m_eGrow, 4) -ALIGN_FIELD(CMiniMdRW, m_Tables, sizeof(RecordPool)*TBL_COUNT, sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_pVS, sizeof(void*)*TBL_COUNT, sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_StringHeap, sizeof(StgStringPool), sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_BlobHeap, sizeof(StgBlobPool), sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_UserStringHeap, sizeof(StgBlobPool), sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_GuidHeap, sizeof(StgGuidPool), sizeof(void*)) -FIELD(CMiniMdRW, m_pHandler, sizeof(void*)) -FIELD(CMiniMdRW, m_cbSaveSize, 4) -BITFIELD(CMiniMdRW, m_fIsReadOnly, offsetof(CMiniMdRW, m_cbSaveSize)+4, 4) -FIELD(CMiniMdRW, m_pMethodMap, sizeof(void*)) -FIELD(CMiniMdRW, m_pFieldMap, sizeof(void*)) -FIELD(CMiniMdRW, m_pPropertyMap, sizeof(void*)) -FIELD(CMiniMdRW, m_pEventMap, sizeof(void*)) -FIELD(CMiniMdRW, m_pParamMap, sizeof(void*)) -FIELD(CMiniMdRW, m_pFilterTable, sizeof(void*)) -FIELD(CMiniMdRW, m_pHostFilter, sizeof(void*)) -FIELD(CMiniMdRW, m_pTokenRemapManager, sizeof(void*)) -ALIGN_FIELD(CMiniMdRW, m_OptionValue, sizeof(OptionValue), 4) -ALIGN_FIELD(CMiniMdRW, m_StartupSchema, sizeof(CMiniMdSchema), 8) -ALIGN_FIELD(CMiniMdRW, m_bSortable, sizeof(BYTE)*TBL_COUNT, sizeof(BYTE)) -#ifdef _DEBUG -FIELD(CMiniMdRW, dbg_m_pLock, sizeof(void*)) -#endif -FIELD(CMiniMdRW, m_fMinimalDelta, 4) -FIELD(CMiniMdRW, m_fAll4ByteColumns, 4) -FIELD(CMiniMdRW, m_rENCRecs, sizeof(void*)) -END_TYPE(CMiniMdRW, 8) - -BEGIN_TYPE(OptionValue, 0) -FIELD(OptionValue, m_DupCheck, 4) -FIELD(OptionValue, m_RefToDefCheck, 4) -FIELD(OptionValue, m_NotifyRemap, 4) -FIELD(OptionValue, m_UpdateMode, 4) -FIELD(OptionValue, m_ErrorIfEmitOutOfOrder, 4) -FIELD(OptionValue, m_ThreadSafetyOptions, 4) -FIELD(OptionValue, m_ImportOption, 4) -FIELD(OptionValue, m_LinkerOption, 4) -FIELD(OptionValue, m_GenerateTCEAdapters, 4) -FIELD(OptionValue, m_RuntimeVersion, sizeof(void*)) -FIELD(OptionValue, m_MetadataVersion, 4) -FIELD(OptionValue, m_MergeOptions, 4) -FIELD(OptionValue, m_InitialSize, 4) -FIELD(OptionValue, m_LocalRefPreservation, 4) -END_TYPE(OptionValue, sizeof(void*)) - - -BEGIN_TYPE(StgBlobPool, sizeof(StgPool)) -ALIGN_FIELD(StgBlobPool, m_Hash, sizeof(CBlobPoolHash), sizeof(void*)) -END_TYPE(StgBlobPool, sizeof(void*)) - -BEGIN_TYPE(StgStringPool, sizeof(StgPool)) -ALIGN_FIELD(StgStringPool, m_Hash, sizeof(CStringPoolHash), sizeof(void*)) -FIELD(StgStringPool, m_bHash, sizeof(BOOL)) -END_TYPE(StgStringPool, sizeof(void*)) - -BEGIN_TYPE(StgGuidPool, sizeof(StgPool)) -ALIGN_FIELD(StgGuidPool, m_Hash, sizeof(CGuidPoolHash), sizeof(void*)) -FIELD(StgGuidPool, m_bHash, sizeof(BOOL)) -END_TYPE(StgGuidPool, sizeof(void*)) - -BEGIN_TYPE(RecordPool, sizeof(StgPool)) -FIELD(RecordPool, m_cbRec, 4) -END_TYPE(RecordPool, sizeof(void*)) - -BEGIN_TYPE(StgPool, sizeof(StgPoolReadOnly)) -FIELD(StgPool, m_ulGrowInc, 4) -FIELD(StgPool, m_pCurSeg, sizeof(void*)) -FIELD(StgPool, m_cbCurSegOffset, 4) -BITFIELD(StgPool, m_bFree, offsetof(StgPool, m_cbCurSegOffset)+4, 4) // can't take offsetof on a bitfield so we have to provide the offset another way -FIELD(StgPool, m_nVariableAlignmentMask, 4) -FIELD(StgPool, m_cbStartOffsetOfEdit, 4) -FIELD(StgPool, m_fValidOffsetOfEdit, 4) -END_TYPE(StgPool, sizeof(void*)) - - -BEGIN_TYPE(CStringPoolHash, sizeof(CChainedHash)) -FIELD(CStringPoolHash, m_Pool, sizeof(void*)) -END_TYPE(CStringPoolHash, sizeof(void*)) - - -BEGIN_TYPE(CBlobPoolHash, sizeof(CChainedHash)) -FIELD(CBlobPoolHash, m_Pool, sizeof(void*)) -END_TYPE(CStringPoolHash, sizeof(void*)) - - -BEGIN_TYPE(CGuidPoolHash, sizeof(CChainedHash)) -FIELD(CGuidPoolHash, m_Pool, sizeof(void*)) -END_TYPE(CGuidPoolHash, sizeof(void*)) - -BEGIN_TYPE(StgPoolReadOnly, sizeof(StgPoolSeg) + sizeof(void*)) //vtable pointer -END_TYPE(StgPoolReadOnly, sizeof(void*)) - -USING_ALIAS(MapSHash__ULONG__ULONG, MapSHash) // Create a using alias to avoid commas in the type name -BEGIN_TYPE(MapSHash__ULONG__ULONG, 0) -FIELD(MapSHash__ULONG__ULONG, m_table, sizeof(void*)) -FIELD(MapSHash__ULONG__ULONG, m_tableSize, 4) -FIELD(MapSHash__ULONG__ULONG, m_tableCount, 4) -FIELD(MapSHash__ULONG__ULONG, m_tableOccupied, 4) -FIELD(MapSHash__ULONG__ULONG, m_tableMax, 4) -END_TYPE(MapSHash__ULONG__ULONG, sizeof(void*)) - - -BEGIN_TYPE(StgPoolSeg, 0) -FIELD(StgPoolSeg, m_pSegData, sizeof(void*)) -FIELD(StgPoolSeg, m_pNextSeg, sizeof(void*)) -FIELD(StgPoolSeg, m_cbSegSize, 4) -FIELD(StgPoolSeg, m_cbSegNext, 4) -END_TYPE(StgPoolSeg, sizeof(void*)) - -USING_ALIAS(CCHainedHash_STRINGHASH, CChainedHash) -BEGIN_TYPE(CCHainedHash_STRINGHASH, sizeof(void*)) // vtable pointer -FIELD(CCHainedHash_STRINGHASH, m_rgData, sizeof(void*)) -FIELD(CCHainedHash_STRINGHASH, m_iBuckets, 4) -FIELD(CCHainedHash_STRINGHASH, m_iSize, 4) -FIELD(CCHainedHash_STRINGHASH, m_iCount, 4) -FIELD(CCHainedHash_STRINGHASH, m_iMaxChain, 4) -FIELD(CCHainedHash_STRINGHASH, m_iFree, 4) -END_TYPE(CCHainedHash_STRINGHASH, sizeof(void*)) - - -BEGIN_TYPE(CMiniColDef, 0) -FIELD(CMiniColDef, m_Type, 1) -FIELD(CMiniColDef, m_oColumn, 1) -FIELD(CMiniColDef, m_cbColumn, 1) -END_TYPE(CMiniColDef, 1) - - -BEGIN_TYPE(CMiniTableDef, 0) -FIELD(CMiniTableDef, m_pColDefs, sizeof(void*)) -FIELD(CMiniTableDef, m_cCols, 1) -FIELD(CMiniTableDef, m_iKey, 1) -FIELD(CMiniTableDef, m_cbRec, 1) -END_TYPE(CMiniTableDef, sizeof(void*)) - -BEGIN_TYPE(CMiniMdBase, 8) //vtable ptr and first field 8-byte alignment -ALIGN_FIELD(CMiniMdBase, m_Schema, sizeof(CMiniMdSchema), 8) -FIELD(CMiniMdBase, m_TblCount, 4) -FIELD(CMiniMdBase, m_fVerifiedByTrustedSource, 4) -ALIGN_FIELD(CMiniMdBase, m_TableDefs, sizeof(CMiniTableDef)*TBL_COUNT, sizeof(void*)) -FIELD(CMiniMdBase, m_iStringsMask, 4) -FIELD(CMiniMdBase, m_iGuidsMask, 4) -FIELD(CMiniMdBase, m_iBlobsMask, 4) -END_TYPE(CMiniMdBase, 8) - - -BEGIN_TYPE(CMiniMdSchemaBase, 0) -FIELD(CMiniMdSchemaBase, m_ulReserved, 4) -FIELD(CMiniMdSchemaBase, m_major, 1) -FIELD(CMiniMdSchemaBase, m_minor, 1) -FIELD(CMiniMdSchemaBase, m_heaps, 1) -FIELD(CMiniMdSchemaBase, m_rid, 1) -FIELD(CMiniMdSchemaBase, m_maskvalid, 8) -FIELD(CMiniMdSchemaBase, m_sorted, 8) -END_TYPE(CMiniMdSchemaBase, 8) - -BEGIN_TYPE(CMiniMdSchema, sizeof(CMiniMdSchemaBase)) -ALIGN_FIELD(CMiniMdSchema, m_cRecs, 4*TBL_COUNT, 4) -FIELD(CMiniMdSchema, m_ulExtra, 4) -END_TYPE(CMiniMdSchema, 8) diff --git a/src/coreclr/md/inc/liteweightstgdb.h b/src/coreclr/md/inc/liteweightstgdb.h index 440fabbc28261c..2209c769e067d3 100644 --- a/src/coreclr/md/inc/liteweightstgdb.h +++ b/src/coreclr/md/inc/liteweightstgdb.h @@ -33,10 +33,11 @@ class TiggerStorage; // base class for the heap, and the class for heap extensions (additional // memory that must be allocated to grow the heap). //***************************************************************************** +class DacDbiInterfaceImpl; template class CLiteWeightStgdb { - friend class VerifyLayoutsMD; + friend class ::DacDbiInterfaceImpl; public: CLiteWeightStgdb() : m_pvMd(NULL), m_cbMd(0) {} @@ -82,7 +83,6 @@ class CLiteWeightStgdbRW : public CLiteWeightStgdb { friend struct ::cdac_data; friend class RegMeta; - friend class VerifyLayoutsMD; friend HRESULT TranslateSigHelper( IMDInternalImport* pImport, IMDInternalImport* pAssemImport, @@ -141,14 +141,6 @@ class CLiteWeightStgdbRW : public CLiteWeightStgdb ULONG cbData, // How big is the data. DWORD dwFlags); // Flags for the open. -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - // Open a metadata section for read/write - __checkReturn - HRESULT OpenForRead( - IMDCustomDataSource *pDataSource, // data to open on top of - DWORD dwFlags); // Flags for the open. -#endif - __checkReturn HRESULT FindImageMetaData( PVOID pImage, // Pointer to head of a file diff --git a/src/coreclr/md/inc/mdinternalrw.h b/src/coreclr/md/inc/mdinternalrw.h index 6385372d6da85a..c45c4df97e66db 100644 --- a/src/coreclr/md/inc/mdinternalrw.h +++ b/src/coreclr/md/inc/mdinternalrw.h @@ -19,7 +19,6 @@ class UTSemReadWrite; class MDInternalRW : public IMDInternalImportENC, public IMDCommon { - friend class VerifyLayoutsMD; public: diff --git a/src/coreclr/md/inc/metamodel.h b/src/coreclr/md/inc/metamodel.h index 322c295ca291be..ee5027f1116e9e 100644 --- a/src/coreclr/md/inc/metamodel.h +++ b/src/coreclr/md/inc/metamodel.h @@ -400,11 +400,12 @@ class CMiniMdSchema : public CMiniMdSchemaBase // To make that happen would be a substantial refactoring job as RegMeta // always embeds CMiniMdRW even when it was opened for ReadOnly. //***************************************************************************** +class DacDbiInterfaceImpl; class CMiniMdBase : public IMetaModelCommonRO { - friend class VerifyLayoutsMD; // verifies class layout doesn't accidentally change friend struct ::cdac_data; + friend class ::DacDbiInterfaceImpl; public: CMiniMdBase(); diff --git a/src/coreclr/md/inc/metamodelrw.h b/src/coreclr/md/inc/metamodelrw.h index 47661f5ebe2986..5bd3adc0bcb142 100644 --- a/src/coreclr/md/inc/metamodelrw.h +++ b/src/coreclr/md/inc/metamodelrw.h @@ -28,9 +28,6 @@ #include struct HENUMInternal; -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE -struct IMDCustomDataSource; -#endif // ENUM for marking bit enum @@ -205,12 +202,14 @@ class MDInternalRW; class UTSemReadWrite; template class CLiteWeightStgdb; +class DacDbiInterfaceImpl; //***************************************************************************** // Read/Write MiniMd. //***************************************************************************** class CMiniMdRW : public CMiniMdTemplate { public: + friend class ::DacDbiInterfaceImpl; friend class CLiteWeightStgdb; friend class CLiteWeightStgdbRW; friend class CMiniMdTemplate; @@ -220,7 +219,6 @@ class CMiniMdRW : public CMiniMdTemplate friend class RegMeta; friend class FilterTable; friend class ImportHelper; - friend class VerifyLayoutsMD; friend struct ::cdac_data; CMiniMdRW(); @@ -236,10 +234,6 @@ class CMiniMdRW : public CMiniMdTemplate HRESULT InitPoolOnMem(int iPool, void *pbData, ULONG cbData, int bReadOnly); __checkReturn HRESULT InitOnRO(CMiniMd *pMd, int bReadOnly); -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - __checkReturn - HRESULT InitOnCustomDataSource(IMDCustomDataSource* pDataSource); -#endif __checkReturn HRESULT ConvertToRW(); @@ -1234,9 +1228,6 @@ class CMiniMdRW : public CMiniMdTemplate CMiniMdSchema m_StartupSchema; // Schema at start time. Keep count of records. BYTE m_bSortable[TBL_COUNT]; // Is a given table sortable? (Can it be reorganized?) -#ifdef FEATURE_METADATA_CUSTOM_DATA_SOURCE - ReleaseHolder m_pCustomDataSource; -#endif #ifdef _DEBUG diff --git a/src/coreclr/md/inc/recordpool.h b/src/coreclr/md/inc/recordpool.h index 34331488943d32..8b8f31fdd341cd 100644 --- a/src/coreclr/md/inc/recordpool.h +++ b/src/coreclr/md/inc/recordpool.h @@ -22,8 +22,6 @@ //***************************************************************************** class RecordPool : public StgPool { - friend class VerifyLayoutsMD; - using StgPool::InitNew; using StgPool::InitOnMem; diff --git a/src/coreclr/md/inc/stgpool.h b/src/coreclr/md/inc/stgpool.h index 0593326b2a4414..b0a82ee8592d34 100644 --- a/src/coreclr/md/inc/stgpool.h +++ b/src/coreclr/md/inc/stgpool.h @@ -82,7 +82,6 @@ class RIDBinarySearch : public CBinarySearch //***************************************************************************** class StgPoolSeg { - friend class VerifyLayoutsMD; friend struct ::cdac_data; public: StgPoolSeg() : @@ -145,8 +144,6 @@ friend class CBlobPoolHash; friend class MetaData::StringHeapRO; friend class MetaData::StringHeapRW; friend class MetaData::BlobHeapRO; -friend class VerifyLayoutsMD; - public: StgPoolReadOnly() { LIMITED_METHOD_CONTRACT; }; @@ -421,7 +418,6 @@ friend class StgStringPool; friend class StgBlobPool; friend class RecordPool; friend class CBlobPoolHash; -friend class VerifyLayoutsMD; friend struct ::cdac_data; public: @@ -762,7 +758,6 @@ friend struct ::cdac_data; //***************************************************************************** class StgStringPool : public StgPool { - friend class VerifyLayoutsMD; public: StgStringPool() : StgPool(DFT_STRING_HEAP_SIZE), @@ -923,7 +918,6 @@ class StgStringPool : public StgPool //***************************************************************************** class StgGuidPool : public StgPool { - friend class VerifyLayoutsMD; public: StgGuidPool() : StgPool(DFT_GUID_HEAP_SIZE), @@ -1075,8 +1069,6 @@ class StgGuidPool : public StgPool //***************************************************************************** class StgBlobPool : public StgPool { - friend class VerifyLayoutsMD; - using StgPool::InitNew; using StgPool::InitOnMem; diff --git a/src/coreclr/md/inc/stgpooli.h b/src/coreclr/md/inc/stgpooli.h index 1301b789c4421e..b1b09aae396a73 100644 --- a/src/coreclr/md/inc/stgpooli.h +++ b/src/coreclr/md/inc/stgpooli.h @@ -29,7 +29,6 @@ struct STRINGHASH : HASHLINK class CStringPoolHash : public CChainedHash { - friend class VerifyLayoutsMD; public: CStringPoolHash(StgPoolReadOnly *pool) : m_Pool(pool) { @@ -69,7 +68,6 @@ typedef STRINGHASH BLOBHASH; class CBlobPoolHash : public CChainedHash { - friend class VerifyLayoutsMD; public: CBlobPoolHash(StgPoolReadOnly *pool) : m_Pool(pool) { @@ -116,7 +114,6 @@ struct GUIDHASH : HASHLINK class CGuidPoolHash : public CChainedHash { - friend class VerifyLayoutsMD; public: CGuidPoolHash(StgPoolReadOnly *pool) : m_Pool(pool) { diff --git a/src/coreclr/md/inc/verifylayouts.h b/src/coreclr/md/inc/verifylayouts.h deleted file mode 100644 index 7a8256fe13729b..00000000000000 --- a/src/coreclr/md/inc/verifylayouts.h +++ /dev/null @@ -1,182 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// VerifyLayouts.h -// - -// -// Make sure that layouts of MD data structures doesn't change accidentally -// -//***************************************************************************** - -// The code in MD\DataSource\TargetTypes.* takes a direct dependency on -// the layouts of types in MD. This is used by the debugger to read metadata -// from a separate process by deserializing the memory for these datastructures. -// -// You are probably reading this comment because you changed a layout and -// one of the static_asserts failed during build. This is what you should -// do to fix it: -// -// a) Go to clr\src\Debug\EE\Debugger.cpp and increment the global version counter -// m_mdDataStructureVersion set in Debugger::Debugger() -// Please comment the change there with a new entry in the version table -// -// b) If a define is conditionally changing the layout: -// i) add, if needed, an entry to the list of define bits in -// clr\src\Debug\EE\debugger.h Debugger::_Target_Defines -// ii) add code like this that sets the bit in the Debugger::_defines static -// variable -// #ifdef MY_DEFINE -// | DEFINE_MY_DEFINE -// #endif -// -// c) Update the code in MD\DataSource\TargetTypes.h/cpp to deserialize your -// new layout correctly. The code needs to work for any version of the layouts -// with or without defines set. Your reader code can access the current version -// and defines by calling: -// reader.GetMDStructuresVersion() -// reader.IsDefined(Define_XYZ) -// -// d) If your changes affect what a debugger should be reading in order to fetch -// metadata then you probably need to change other parts of the debugger -// implementation as well. In general the debugger cares about the schema, -// TableDefs, storage signature, table records, and storage pools. -// -// e) AFTER you have fixed up the debugger stuff above, now its time to update -// layout definitions so the static asserts will quiet down. Check out -// the comments in VerifyLayouts.inc for how to do that. -// -// Thanks for helping us keep the debugger working :) -// - - - - -//------------------------------------------------------------------------------- -// Type layout verification -// -// -// These macros includes VerifyLayouts.inc a few times with different definitions to build up -// the source. The final result should look something like this: -// (don't assume specific type names/fields/offsets/sizes are accurate in this example) -// -// -// class VerifyLayoutsMD -// { -// -// static const int expected_offset_of_first_field_in_CMiniMdRW = 208; -// static const int actual_offset_of_first_field_in_CMiniMdRW = -// 208; -// static const int offset_of_field_after_CMiniMdRW_m_Schema = -// 312; -// static const int offset_of_field_after_CMiniMdRW_m_Tables = -// 316; -// ... many more lines like this covering all fields in all marked up types ... -// -// -// static const int alignment_of_first_field_in_CMiniMdRW = -// 4; -// static const int alignment_of_field_after_CMiniMdRW_m_Schema = -// 8; -// static const int alignment_of_field_after_CMiniMdRW_m_Tables = -// 8; -// ... many more lines like this cover all fields in all marked up types ... -// -// -// static_assert(expected_offset_of_first_field_in_CMiniMdRW == actual_offset_of_first_field_in_CMiniMdRW); -// static_assert(offset_of_field_after_CMiniMdRW_m_Schema == -// ALIGN_UP(offsetof(CMiniMdRW, m_Schema) + 104, alignment_of_field_after_CMiniMdRW_m_Schema)); -// static_assert(offset_of_field_after_CMiniMdRW_m_Tables == -// ALIGN_UP(offsetof(CMiniMdRW, m_Tables) + 4, alignment_of_field_after_CMiniMdRW_m_Tables)); -// ... many more lines like this cover all fields in all marked up types ... -// -// }; -// -// -// -// - -#ifdef FEATURE_METADATA_VERIFY_LAYOUTS - -#include // offsetof -#include "metamodel.h" -#include "mdinternalrw.h" - -// other types provide friend access to this type so that the -// offsetof macro can access their private fields -class VerifyLayoutsMD -{ - // we have a bunch of arrays with this fixed size, make sure it doesn't change - static_assert(TBL_COUNT == 45); - -#define USING_ALIAS(typeName, ...) using typeName = __VA_ARGS__; - -#define FIELD(typeName, fieldName, fieldSize) ALIGN_FIELD(typeName, fieldName, fieldSize, fieldSize) - -#define BEGIN_TYPE(typeName, initialFieldOffset) \ - static const int expected_offset_of_first_field_in_##typeName = initialFieldOffset; \ - static const int actual_offset_of_first_field_in_##typeName = - -#define ALIGN_FIELD(typeName, fieldName, fieldSize, fieldAlign) \ - offsetof(typeName, fieldName); \ - static const int offset_of_field_after_##typeName##_##fieldName = - -#define BITFIELD(typeName, fieldName, fieldOffset, fieldSize) \ - fieldOffset; \ - static const int offset_of_field_after_##typeName##_##fieldName = - -#define END_TYPE(typeName, typeAlignentSize) \ - sizeof(typeName); - -#include "VerifyLayouts.inc" - -// Only declare using once -#undef USING_ALIAS -#define USING_ALIAS(a, ...) - -#undef BEGIN_TYPE -#undef ALIGN_FIELD -#undef END_TYPE -#undef BITFIELD - - -#define BEGIN_TYPE(typeName, initialFieldOffset) \ - static const int alignment_of_first_field_in_##typeName = -#define ALIGN_FIELD(typeName, fieldName, fieldSize, fieldAlign) \ - fieldAlign; \ - static const int alignment_of_field_after_##typeName##_##fieldName = -#define BITFIELD(typeName, fieldName, fieldOffset, fieldSize) \ - fieldSize; \ - static const int alignment_of_field_after_##typeName##_##fieldName = -#define END_TYPE(typeName, typeAlignmentSize) \ - typeAlignmentSize; - -#include "VerifyLayouts.inc" - -#undef BEGIN_TYPE -#undef ALIGN_FIELD -#undef END_TYPE -#undef BITFIELD - - -#define BEGIN_TYPE(typeName, initialFieldOffset) \ - static_assert(expected_offset_of_first_field_in_##typeName == actual_offset_of_first_field_in_##typeName); - - -#define ALIGN_UP(value, alignment) (((value) + (alignment) - 1)&~((alignment) - 1)) -#define ALIGN_FIELD(typeName, fieldName, fieldSize, fieldAlign) \ - static_assert(offset_of_field_after_##typeName##_##fieldName == \ - ALIGN_UP(offsetof(typeName, fieldName) + fieldSize, alignment_of_field_after_##typeName##_##fieldName)); -#define BITFIELD(typeName, fieldName, fieldOffset, fieldSize) \ - static_assert(offset_of_field_after_##typeName##_##fieldName == \ - ALIGN_UP(fieldOffset + fieldSize, alignment_of_field_after_##typeName##_##fieldName)); - -#define END_TYPE(typeName, typeAlignmentSize) -#include "VerifyLayouts.inc" - -}; - - - - -#endif //FEATURE_METADATA_VERIFY_LAYOUTS diff --git a/src/coreclr/md/runtime/stgpool.cpp b/src/coreclr/md/runtime/stgpool.cpp index 1122c4c9f208c6..7810599241bab0 100644 --- a/src/coreclr/md/runtime/stgpool.cpp +++ b/src/coreclr/md/runtime/stgpool.cpp @@ -292,10 +292,10 @@ bool StgPool::Grow( // true if successful. if ((m_pCurSeg->m_cbSegNext + m_cbCurSegOffset) / m_ulGrowInc >= 3) m_ulGrowInc *= 2; - // NOTE: MD\DataSource\RemoteMDInternalRWSource has taken a dependency that there + // NOTE: DacDbiInterfaceImpl::ReadStoragePool has taken a dependency that there // won't be more than 1000 segments. Given the current exponential growth algorithm // we'll never get anywhere close to that, but if the algorithm changes to allow for - // many segments, please update that source as well. + // many segments, please update that implementation as well. // If first time, handle specially. if (m_pSegData == m_zeros) @@ -1793,4 +1793,3 @@ StgBlobPool::RehashBlobs() return (S_OK); } // StgBlobPool::RehashBlobs - diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index f6ed92ee2d4319..fd723be4e8cb84 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -492,8 +492,6 @@ CDAC_TYPE_END(SystemDomain) CDAC_TYPE_BEGIN(Debugger) CDAC_TYPE_INDETERMINATE(Debugger) CDAC_TYPE_FIELD(Debugger, T_INT32, LeftSideInitialized, offsetof(Debugger, m_fLeftSideInitialized)) -CDAC_TYPE_FIELD(Debugger, T_UINT32, Defines, offsetof(Debugger, m_defines)) -CDAC_TYPE_FIELD(Debugger, T_UINT32, MDStructuresVersion, offsetof(Debugger, m_mdDataStructureVersion)) CDAC_TYPE_FIELD(Debugger, T_POINTER, RCThread, cdac_data::RCThread) CDAC_TYPE_FIELD(Debugger, T_INT32, RSRequestedSync, cdac_data::RSRequestedSync) CDAC_TYPE_FIELD(Debugger, T_INT32, SendExceptionsOutsideOfJMC, cdac_data::SendExceptionsOutsideOfJMC) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugger.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugger.cs index 253c7faff878b2..2803be014c423c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugger.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugger.cs @@ -5,7 +5,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; -public record struct DebuggerData(bool IsLeftSideInitialized, uint DefinesBitField, uint MDStructuresVersion); +public record struct DebuggerData(bool IsLeftSideInitialized); public enum HijackKind { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs index b69fd414f933ff..633c9b9e2354c6 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs @@ -11,6 +11,7 @@ public interface IEcmaMetadata : IContract static string IContract.Name { get; } = nameof(EcmaMetadata); TargetSpan GetReadOnlyMetadataAddress(ModuleHandle handle) => throw new NotImplementedException(); MetadataReader? GetMetadata(ModuleHandle module) => throw new NotImplementedException(); + byte[] GetReadWriteMetadata(ModuleHandle handle) => throw new NotImplementedException(); } public readonly struct EcmaMetadata : IEcmaMetadata diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs index bea06f7516d7ba..aaa24d678cbbc2 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs @@ -9,6 +9,7 @@ public static class CorDbgHResults public const int CORDBG_E_BAD_THREAD_STATE = unchecked((int)0x8013132d); public const int CORDBG_E_READVIRTUAL_FAILURE = unchecked((int)0x80131c49); public const int ERROR_BUFFER_OVERFLOW = unchecked((int)0x8007006F); // HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW) + public const int ERROR_INSUFFICIENT_BUFFER = unchecked((int)0x8007007A); // HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) public const int CORDBG_E_CLASS_NOT_LOADED = unchecked((int)0x80131303); public const int CORDBG_E_FUNCTION_NOT_IL = unchecked((int)0x8013130a); public const int CORDBG_E_TARGET_INCONSISTENT = unchecked((int)0x80131c36); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Debugger/Debugger_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Debugger/Debugger_1.cs index 2d9751adaca52b..c3b41f9bbd4b23 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Debugger/Debugger_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Debugger/Debugger_1.cs @@ -45,7 +45,7 @@ bool IDebugger.TryGetDebuggerData(out DebuggerData data) return false; Data.Debugger debugger = _target.ProcessedData.GetOrAdd(debuggerAddress); - data = new DebuggerData(debugger.LeftSideInitialized != 0, debugger.Defines, debugger.MDStructuresVersion); + data = new DebuggerData(debugger.LeftSideInitialized != 0); return true; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs index 567e018ac045e5..8407a476fc2109 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Numerics; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -19,6 +18,7 @@ internal sealed class EcmaMetadata_1(Target target) : IEcmaMetadata private const byte HEAP_GUID_4 = 0x02; private const byte HEAP_BLOB_4 = 0x04; private readonly Dictionary _metadata = []; + private readonly Dictionary _readWriteMetadataBlob = []; private readonly Dictionary _readOnlyMetadataAddress = []; public void Flush(FlushScope scope) @@ -26,6 +26,7 @@ public void Flush(FlushScope scope) if (scope == FlushScope.All) { _metadata.Clear(); + _readWriteMetadataBlob.Clear(); _readOnlyMetadataAddress.Clear(); } } @@ -97,167 +98,186 @@ public TargetSpan GetReadOnlyMetadataAddress(ModuleHandle handle) } case AvailableMetadataType.ReadWrite: { - var targetEcmaMetadata = GetReadWriteMetadata(handle); - - // From the multiple different target spans, we need to build a single - // contiguous ECMA-335 metadata blob. - BlobBuilder builder = new BlobBuilder(); - builder.WriteUInt32(0x424A5342); - - // major version - builder.WriteUInt16(1); - - // minor version - builder.WriteUInt16(1); - - // reserved - builder.WriteUInt32(0); - - string version = targetEcmaMetadata.Schema.MetadataVersion; - builder.WriteInt32(AlignUp(version.Length + 1, 4)); - Write4ByteAlignedString(builder, version); - - // reserved - builder.WriteUInt16(0); - - // number of streams - ushort numStreams = 5; // #Strings, #US, #Blob, #GUID, #~ (metadata) - if (targetEcmaMetadata.Schema.VariableSizedColumnsAreAll4BytesLong) - { - // We direct MetadataReader to use 4-byte encoding for all variable-sized columns - // by providing the marker stream for a "minimal delta" image. - numStreams++; - } - builder.WriteUInt16(numStreams); - - // Write Stream headers - if (targetEcmaMetadata.Schema.VariableSizedColumnsAreAll4BytesLong) - { - // Write the #JTD stream to indicate that all variable-sized columns are 4 bytes long. - WriteStreamHeader(builder, "#JTD", 0).WriteInt32(builder.Count); - } - - BlobWriter stringsOffset = WriteStreamHeader(builder, "#Strings", (int)AlignUp((ulong)targetEcmaMetadata.StringHeap.Length, 4ul)); - BlobWriter blobOffset = WriteStreamHeader(builder, "#Blob", (int)AlignUp((ulong)targetEcmaMetadata.BlobHeap.Length, 4ul)); - BlobWriter guidOffset = WriteStreamHeader(builder, "#GUID", (int)AlignUp((ulong)targetEcmaMetadata.GuidHeap.Length, 4ul)); - BlobWriter userStringOffset = WriteStreamHeader(builder, "#US", (int)AlignUp((ulong)targetEcmaMetadata.UserStringHeap.Length, 4ul)); - - // We'll use the "uncompressed" tables stream name as the runtime may have created the *Ptr tables - // that are only present in the uncompressed tables stream. - BlobWriter tablesOffset = new(builder.ReserveBytes(4)); - BlobWriter tablesSize = new(builder.ReserveBytes(4)); - Write4ByteAlignedString(builder, "#-"); - - // Write the heap-style Streams - - stringsOffset.WriteInt32(builder.Count); - WriteAlignedHeap(builder, targetEcmaMetadata.StringHeap); - - blobOffset.WriteInt32(builder.Count); - WriteAlignedHeap(builder, targetEcmaMetadata.BlobHeap); - - guidOffset.WriteInt32(builder.Count); - WriteAlignedHeap(builder, targetEcmaMetadata.GuidHeap); - - userStringOffset.WriteInt32(builder.Count); - WriteAlignedHeap(builder, targetEcmaMetadata.UserStringHeap); - - // Write tables stream - int tableStreamStart = builder.Count; - tablesOffset.WriteInt32(tableStreamStart); - - // Write tables stream header - builder.WriteInt32(0); // reserved - // ECMA-335 II.24.2.6: MajorVersion shall be 2, MinorVersion shall be 0. - builder.WriteByte(2); // major version - builder.WriteByte(0); // minor version - uint heapSizes = - (targetEcmaMetadata.Schema.LargeStringHeap ? (uint)HEAP_STRING_4 : 0) | - (targetEcmaMetadata.Schema.LargeGuidHeap ? (uint)HEAP_GUID_4 : 0) | - (targetEcmaMetadata.Schema.LargeBlobHeap ? (uint)HEAP_BLOB_4 : 0); - - builder.WriteByte((byte)heapSizes); - builder.WriteByte(1); // reserved - - ulong validTables = 0; - for (int i = 0; i < targetEcmaMetadata.Schema.RowCount.Length; i++) - { - if (targetEcmaMetadata.Schema.RowCount[i] != 0) - { - validTables |= 1ul << i; - } - } - - ulong sortedTables = 0; - for (int i = 0; i < targetEcmaMetadata.Schema.IsSorted.Length; i++) - { - if (targetEcmaMetadata.Schema.IsSorted[i]) - { - sortedTables |= 1ul << i; - } - } - - builder.WriteUInt64(validTables); - builder.WriteUInt64(sortedTables); - - foreach (int rowCount in targetEcmaMetadata.Schema.RowCount) - { - if (rowCount > 0) - { - builder.WriteInt32(rowCount); - } - } - - // Write the tables - foreach (byte[] table in targetEcmaMetadata.Tables) - { - builder.WriteBytes(table); - } - - // Patch the #- stream size now that the full table stream has been written. - tablesSize.WriteInt32(builder.Count - tableStreamStart); - - MemoryStream metadataStream = new MemoryStream(); - builder.WriteContentTo(metadataStream); - metadataStream.Position = 0; - return MetadataReaderProvider.FromMetadataStream(metadataStream); - - static BlobWriter WriteStreamHeader(BlobBuilder builder, string name, int size) - { - BlobWriter offset = new(builder.ReserveBytes(4)); - builder.WriteInt32(size); - Write4ByteAlignedString(builder, name); - return offset; - } - - static void WriteAlignedHeap(BlobBuilder builder, byte[] heap) - { - builder.WriteBytes(heap); - for (int i = heap.Length; i < (int)AlignUp((ulong)heap.Length, 4ul); i++) - { - builder.WriteByte(0); - } - } - - static void Write4ByteAlignedString(BlobBuilder builder, string value) - { - int bufferStart = builder.Count; - builder.WriteUTF8(value); - builder.WriteByte(0); - int stringEnd = builder.Count; - // The name field occupies the null-terminated string padded to a 4-byte boundary, - // i.e. AlignUp(length + 1, 4) bytes (the +1 accounts for the null terminator). - for (int i = stringEnd; i < bufferStart + AlignUp(value.Length + 1, 4); i++) - { - builder.WriteByte(0); - } - } + byte[] data = GetReadWriteMetadata(handle); + return MetadataReaderProvider.FromMetadataImage(ImmutableCollectionsMarshal.AsImmutableArray(data)); } default: throw new NotImplementedException(); } } + public byte[] GetReadWriteMetadata(ModuleHandle handle) + { + if (GetAvailableMetadataType(handle) != AvailableMetadataType.ReadWrite) + { + throw new ArgumentException("Module does not have read/write metadata.", nameof(handle)); + } + uint generation = GetMetadataGeneration(handle); + + if (_readWriteMetadataBlob.TryGetValue(handle, out (uint Generation, byte[] Blob) cached) && cached.Generation == generation) + { + return cached.Blob; + } + + byte[] blob = BuildReadWriteMetadataBlob(GetTargetEcmaMetadata(handle)); + _readWriteMetadataBlob[handle] = (generation, blob); + return blob; + } + + private static byte[] BuildReadWriteMetadataBlob(TargetEcmaMetadata targetEcmaMetadata) + { + // From the multiple different target spans, we need to build a single + // contiguous ECMA-335 metadata blob. + BlobBuilder builder = new BlobBuilder(); + builder.WriteUInt32(0x424A5342); + + // major version + builder.WriteUInt16(1); + + // minor version + builder.WriteUInt16(1); + + // reserved + builder.WriteUInt32(0); + + string version = targetEcmaMetadata.Schema.MetadataVersion; + builder.WriteInt32(AlignUp(version.Length + 1, 4)); + Write4ByteAlignedString(builder, version); + + // reserved + builder.WriteUInt16(0); + + // number of streams + ushort numStreams = 5; // #Strings, #US, #Blob, #GUID, #~ (metadata) + if (targetEcmaMetadata.Schema.VariableSizedColumnsAreAll4BytesLong) + { + // We direct MetadataReader to use 4-byte encoding for all variable-sized columns + // by providing the marker stream for a "minimal delta" image. + numStreams++; + } + builder.WriteUInt16(numStreams); + + // Write Stream headers + if (targetEcmaMetadata.Schema.VariableSizedColumnsAreAll4BytesLong) + { + // Write the #JTD stream to indicate that all variable-sized columns are 4 bytes long. + WriteStreamHeader(builder, "#JTD", 0).WriteInt32(builder.Count); + } + + BlobWriter stringsOffset = WriteStreamHeader(builder, "#Strings", (int)AlignUp((ulong)targetEcmaMetadata.StringHeap.Length, 4ul)); + BlobWriter blobOffset = WriteStreamHeader(builder, "#Blob", (int)AlignUp((ulong)targetEcmaMetadata.BlobHeap.Length, 4ul)); + BlobWriter guidOffset = WriteStreamHeader(builder, "#GUID", (int)AlignUp((ulong)targetEcmaMetadata.GuidHeap.Length, 4ul)); + BlobWriter userStringOffset = WriteStreamHeader(builder, "#US", (int)AlignUp((ulong)targetEcmaMetadata.UserStringHeap.Length, 4ul)); + + // We'll use the "uncompressed" tables stream name as the runtime may have created the *Ptr tables + // that are only present in the uncompressed tables stream. + BlobWriter tablesOffset = new(builder.ReserveBytes(4)); + BlobWriter tablesSize = new(builder.ReserveBytes(4)); + Write4ByteAlignedString(builder, "#-"); + + // Write the heap-style Streams + + stringsOffset.WriteInt32(builder.Count); + WriteAlignedHeap(builder, targetEcmaMetadata.StringHeap); + + blobOffset.WriteInt32(builder.Count); + WriteAlignedHeap(builder, targetEcmaMetadata.BlobHeap); + + guidOffset.WriteInt32(builder.Count); + WriteAlignedHeap(builder, targetEcmaMetadata.GuidHeap); + + userStringOffset.WriteInt32(builder.Count); + WriteAlignedHeap(builder, targetEcmaMetadata.UserStringHeap); + + // Write tables stream + int tableStreamStart = builder.Count; + tablesOffset.WriteInt32(tableStreamStart); + + // Write tables stream header + builder.WriteInt32(0); // reserved + // ECMA-335 II.24.2.6: MajorVersion shall be 2, MinorVersion shall be 0. + builder.WriteByte(2); // major version + builder.WriteByte(0); // minor version + uint heapSizes = + (targetEcmaMetadata.Schema.LargeStringHeap ? (uint)HEAP_STRING_4 : 0) | + (targetEcmaMetadata.Schema.LargeGuidHeap ? (uint)HEAP_GUID_4 : 0) | + (targetEcmaMetadata.Schema.LargeBlobHeap ? (uint)HEAP_BLOB_4 : 0); + + builder.WriteByte((byte)heapSizes); + builder.WriteByte(1); // reserved + + ulong validTables = 0; + for (int i = 0; i < targetEcmaMetadata.Schema.RowCount.Length; i++) + { + if (targetEcmaMetadata.Schema.RowCount[i] != 0) + { + validTables |= 1ul << i; + } + } + + ulong sortedTables = 0; + for (int i = 0; i < targetEcmaMetadata.Schema.IsSorted.Length; i++) + { + if (targetEcmaMetadata.Schema.IsSorted[i]) + { + sortedTables |= 1ul << i; + } + } + + builder.WriteUInt64(validTables); + builder.WriteUInt64(sortedTables); + + foreach (int rowCount in targetEcmaMetadata.Schema.RowCount) + { + if (rowCount > 0) + { + builder.WriteInt32(rowCount); + } + } + + // Write the tables + foreach (byte[] table in targetEcmaMetadata.Tables) + { + builder.WriteBytes(table); + } + + // Patch the #- stream size now that the full table stream has been written. + tablesSize.WriteInt32(builder.Count - tableStreamStart); + + return builder.ToArray(); + + static BlobWriter WriteStreamHeader(BlobBuilder builder, string name, int size) + { + BlobWriter offset = new(builder.ReserveBytes(4)); + builder.WriteInt32(size); + Write4ByteAlignedString(builder, name); + return offset; + } + + static void WriteAlignedHeap(BlobBuilder builder, byte[] heap) + { + builder.WriteBytes(heap); + for (int i = heap.Length; i < (int)AlignUp((ulong)heap.Length, 4ul); i++) + { + builder.WriteByte(0); + } + } + + static void Write4ByteAlignedString(BlobBuilder builder, string value) + { + int bufferStart = builder.Count; + builder.WriteUTF8(value); + builder.WriteByte(0); + int stringEnd = builder.Count; + // The name field occupies the null-terminated string padded to a 4-byte boundary, + // i.e. AlignUp(length + 1, 4) bytes (the +1 accounts for the null terminator). + for (int i = stringEnd; i < bufferStart + AlignUp(value.Length + 1, 4); i++) + { + builder.WriteByte(0); + } + } + } + private struct EcmaMetadataSchema { public EcmaMetadataSchema(string metadataVersion, bool largeStringHeap, bool largeBlobHeap, bool largeGuidHeap, int[] rowCount, bool[] isSorted, bool variableSizedColumnsAre4BytesLong) @@ -363,7 +383,7 @@ private TargetSpan GetReadWriteSavedMetadataAddress(ModuleHandle handle) return new TargetSpan(dynamicMetadata.Data, dynamicMetadata.Size); } - private TargetEcmaMetadata GetReadWriteMetadata(ModuleHandle handle) + private TargetEcmaMetadata GetTargetEcmaMetadata(ModuleHandle handle) { TargetPointer peAssemblyPtr = target.Contracts.Loader.GetPEAssembly(handle); Data.PEAssembly peAssembly = target.ProcessedData.GetOrAdd(peAssemblyPtr); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Debugger.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Debugger.cs index 86bb807c1bfd26..7fbb7adfe586d0 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Debugger.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Debugger.cs @@ -7,8 +7,6 @@ namespace Microsoft.Diagnostics.DataContractReader.Data; internal sealed partial class Debugger : IData { [Field] public int LeftSideInitialized { get; } - [Field] public uint Defines { get; } - [Field] public uint MDStructuresVersion { get; } [Field] public TargetPointer RCThread { get; } [Field(Writable = true)] public int RSRequestedSync { get; private set; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs index 6e194d4b19155c..16a79283021574 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs @@ -453,7 +453,6 @@ int IXCLRDataModule.EndEnumDataByName(ulong handle) int IXCLRDataModule.GetName(uint bufLen, uint* nameLen, char* name) { int hr = HResults.S_OK; - int E_INSUFFICIENT_BUFFER = unchecked((int)0x8007007A); try { if (nameLen != null) @@ -468,7 +467,7 @@ int IXCLRDataModule.GetName(uint bufLen, uint* nameLen, char* name) *nameLen = nameLenLocal; // throw on insufficient buffer if (nameLenLocal > bufLen) - throw Marshal.GetExceptionForHR(E_INSUFFICIENT_BUFFER)!; + throw Marshal.GetExceptionForHR(CorDbgHResults.ERROR_INSUFFICIENT_BUFFER)!; } catch (System.Exception ex) { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs index 7469d332124916..59577825a495d3 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs @@ -350,6 +350,83 @@ public int GetModulePath(ulong vmModule, nint pStrFilename, Interop.BOOL* pResul public int GetMetadata(ulong vmModule, DacDbiTargetBuffer* pTargetBuffer) => LegacyFallbackHelper.CanFallback() && _legacy is not null ? _legacy.GetMetadata(vmModule, pTargetBuffer) : HResults.E_NOTIMPL; + public int GetReadWriteMetadataSize(ulong vmModule, uint* pSize) + { + int hr = HResults.S_OK; + try + { + if (pSize == null) + throw new ArgumentException(nameof(pSize)); + if (vmModule == 0) + throw new ArgumentException("Module pointer must be non-zero.", nameof(vmModule)); + *pSize = 0; + Contracts.ILoader loader = _target.Contracts.Loader; + Contracts.ModuleHandle handle = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); + + byte[] blob = _target.Contracts.EcmaMetadata.GetReadWriteMetadata(handle); + *pSize = (uint)blob.Length; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacy is not null) + { + uint sizeLocal; + int hrLocal = _legacy.GetReadWriteMetadataSize(vmModule, &sizeLocal); + Debug.ValidateHResult(hr, hrLocal); + if (hr == HResults.S_OK) + { + Debug.Assert(*pSize == sizeLocal, $"cDAC size: {*pSize}, DAC size: {sizeLocal}"); + } + } +#endif + return hr; + } + + public int FillReadWriteMetadata(ulong vmModule, byte* pBuffer, uint cbBuffer) + { + int hr = HResults.S_OK; + try + { + if (pBuffer == null) + throw new ArgumentNullException(nameof(pBuffer)); + if (vmModule == 0) + throw new ArgumentException("Module pointer must be non-zero.", nameof(vmModule)); + + Contracts.ILoader loader = _target.Contracts.Loader; + Contracts.ModuleHandle handle = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); + + byte[] blob = _target.Contracts.EcmaMetadata.GetReadWriteMetadata(handle); + if (cbBuffer < (uint)blob.Length) + throw Marshal.GetExceptionForHR(CorDbgHResults.ERROR_INSUFFICIENT_BUFFER)!; + + blob.AsSpan().CopyTo(new Span(pBuffer, (int)cbBuffer)); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacy is not null) + { + byte[] bufferLocal = new byte[cbBuffer]; + int hrLocal; + fixed (byte* pLocal = bufferLocal) + { + hrLocal = _legacy.FillReadWriteMetadata(vmModule, pLocal, cbBuffer); + } + Debug.ValidateHResult(hr, hrLocal); + if (hr == HResults.S_OK) + { + Debug.Assert(new Span(pBuffer, (int)cbBuffer).SequenceEqual(bufferLocal), "cDAC and DAC read-write metadata buffers differ."); + } + } +#endif + return hr; + } + public int GetSymbolsBuffer(ulong vmModule, DacDbiTargetBuffer* pTargetBuffer, SymbolFormat* pSymbolFormat) { int hr = HResults.S_OK; @@ -5084,64 +5161,6 @@ public int AreOptimizationsDisabled(ulong vmModule, uint methodTk, Interop.BOOL* return hr; } - public int GetDefinesBitField(uint* pDefines) - { - *pDefines = 0; - int hr = HResults.S_OK; - try - { - if (!_target.Contracts.Debugger.TryGetDebuggerData(out Contracts.DebuggerData data)) - throw Marshal.GetExceptionForHR(CorDbgHResults.CORDBG_E_NOTREADY)!; - *pDefines = data.DefinesBitField; - } - catch (System.Exception ex) - { - hr = ex.HResult; - } - -#if DEBUG - if (_legacy is not null) - { - uint resultLocal; - int hrLocal = _legacy.GetDefinesBitField(&resultLocal); - Debug.ValidateHResult(hr, hrLocal); - if (hr == HResults.S_OK) - Debug.Assert(*pDefines == resultLocal); - } -#endif - - return hr; - } - - public int GetMDStructuresVersion(uint* pMDStructuresVersion) - { - *pMDStructuresVersion = 0; - int hr = HResults.S_OK; - try - { - if (!_target.Contracts.Debugger.TryGetDebuggerData(out Contracts.DebuggerData data)) - throw Marshal.GetExceptionForHR(CorDbgHResults.CORDBG_E_NOTREADY)!; - *pMDStructuresVersion = data.MDStructuresVersion; - } - catch (System.Exception ex) - { - hr = ex.HResult; - } - -#if DEBUG - if (_legacy is not null) - { - uint resultLocal; - int hrLocal = _legacy.GetMDStructuresVersion(&resultLocal); - Debug.ValidateHResult(hr, hrLocal); - if (hr == HResults.S_OK) - Debug.Assert(*pMDStructuresVersion == resultLocal); - } -#endif - - return hr; - } - public int GetActiveRejitILCodeVersionNode(ulong vmModule, uint methodTk, ulong* pVmILCodeVersionNode) { int hr = HResults.S_OK; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs index cc96dd9fc20abd..9779d5d52aa95c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs @@ -848,12 +848,6 @@ int EnumerateTypeHandleParams(ulong vmTypeHandle, [PreserveSig] int AreOptimizationsDisabled(ulong vmModule, uint methodTk, Interop.BOOL* pOptimizationsDisabled); - [PreserveSig] - int GetDefinesBitField(uint* pDefines); - - [PreserveSig] - int GetMDStructuresVersion(uint* pMDStructuresVersion); - [PreserveSig] int GetActiveRejitILCodeVersionNode(ulong vmModule, uint methodTk, ulong* pVmILCodeVersionNode); @@ -896,4 +890,10 @@ int EnumerateAsyncLocals(ulong vmMethod, ulong codeAddr, uint state, [PreserveSig] int GetGenericArgTokenIndex(ulong vmMethod, uint* pIndex); + + [PreserveSig] + int GetReadWriteMetadataSize(ulong vmModule, uint* pSize); + + [PreserveSig] + int FillReadWriteMetadata(ulong vmModule, byte* pBuffer, uint cbBuffer); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/StressTestApi/CdacStressApi.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/StressTestApi/CdacStressApi.cs index 6a1a440ff07e93..dbe94c4a9f5e8b 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/StressTestApi/CdacStressApi.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/StressTestApi/CdacStressApi.cs @@ -18,9 +18,6 @@ internal static unsafe class CdacStressApi public const uint RequestFlushTargetState = 0xf2000000; public const uint RequestComputeArgGCRefMap = 0xf2000001; - // HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER). - private const int HResultErrorInsufficientBuffer = unchecked((int)0x8007007A); - public static bool IsStressRequest(uint reqCode) => reqCode == RequestFlushTargetState || reqCode == RequestComputeArgGCRefMap; @@ -101,7 +98,7 @@ private static int HandleComputeArgGCRefMap(Target target, uint inSize, byte* in { req.cbFilled = 0; Unsafe.WriteUnaligned(inBuffer, req); - return HResultErrorInsufficientBuffer; + return CorDbgHResults.ERROR_INSUFFICIENT_BUFFER; } byte* dest = (byte*)(nuint)req.BlobBuffer; diff --git a/src/native/managed/cdac/tests/DumpTests/DacDbi/DacDbiDebuggerDumpTests.cs b/src/native/managed/cdac/tests/DumpTests/DacDbi/DacDbiDebuggerDumpTests.cs index 380fc93d04ec20..ce5adeb61cf411 100644 --- a/src/native/managed/cdac/tests/DumpTests/DacDbi/DacDbiDebuggerDumpTests.cs +++ b/src/native/managed/cdac/tests/DumpTests/DacDbi/DacDbiDebuggerDumpTests.cs @@ -44,30 +44,6 @@ public unsafe void GetAttachStateFlags_Succeeds(TestConfiguration config) Assert.Equal(System.HResults.S_OK, hr); } - [ConditionalTheory] - [MemberData(nameof(TestConfigurations))] - public unsafe void GetDefinesBitField_Succeeds(TestConfiguration config) - { - InitializeDumpTest(config); - DacDbiImpl dbi = CreateDacDbi(); - - uint defines; - int hr = dbi.GetDefinesBitField(&defines); - Assert.Equal(System.HResults.S_OK, hr); - } - - [ConditionalTheory] - [MemberData(nameof(TestConfigurations))] - public unsafe void GetMDStructuresVersion_Succeeds(TestConfiguration config) - { - InitializeDumpTest(config); - DacDbiImpl dbi = CreateDacDbi(); - - uint version; - int hr = dbi.GetMDStructuresVersion(&version); - Assert.Equal(System.HResults.S_OK, hr); - } - [ConditionalTheory] [MemberData(nameof(TestConfigurations))] public unsafe void MetadataUpdatesApplied_Succeeds(TestConfiguration config) @@ -96,33 +72,4 @@ public unsafe void IsLeftSideInitialized_CrossValidateWithContract(TestConfigura Assert.Equal(contractResult && data.IsLeftSideInitialized, dbiResult != Interop.BOOL.FALSE); } - [ConditionalTheory] - [MemberData(nameof(TestConfigurations))] - public unsafe void GetDefinesBitField_CrossValidateWithContract(TestConfiguration config) - { - InitializeDumpTest(config); - DacDbiImpl dbi = CreateDacDbi(); - - uint dbiResult; - int hr = dbi.GetDefinesBitField(&dbiResult); - Assert.Equal(System.HResults.S_OK, hr); - - Assert.True(Target.Contracts.Debugger.TryGetDebuggerData(out Contracts.DebuggerData data)); - Assert.Equal(data.DefinesBitField, dbiResult); - } - - [ConditionalTheory] - [MemberData(nameof(TestConfigurations))] - public unsafe void GetMDStructuresVersion_CrossValidateWithContract(TestConfiguration config) - { - InitializeDumpTest(config); - DacDbiImpl dbi = CreateDacDbi(); - - uint dbiResult; - int hr = dbi.GetMDStructuresVersion(&dbiResult); - Assert.Equal(System.HResults.S_OK, hr); - - Assert.True(Target.Contracts.Debugger.TryGetDebuggerData(out Contracts.DebuggerData data)); - Assert.Equal(data.MDStructuresVersion, dbiResult); - } } diff --git a/src/native/managed/cdac/tests/UnitTests/DebuggerTests.cs b/src/native/managed/cdac/tests/UnitTests/DebuggerTests.cs index a0a9aea33e6c72..69bbe906ae21e1 100644 --- a/src/native/managed/cdac/tests/UnitTests/DebuggerTests.cs +++ b/src/native/managed/cdac/tests/UnitTests/DebuggerTests.cs @@ -33,8 +33,6 @@ private static TargetTestHelpers.LayoutResult GetDebuggerLayout(TargetTestHelper return helpers.LayoutFields( [ new(nameof(Data.Debugger.LeftSideInitialized), DataType.int32), - new(nameof(Data.Debugger.Defines), DataType.uint32), - new(nameof(Data.Debugger.MDStructuresVersion), DataType.uint32), new(nameof(Data.Debugger.RCThread), DataType.pointer), new(nameof(Data.Debugger.RSRequestedSync), DataType.int32), new(nameof(Data.Debugger.SendExceptionsOutsideOfJMC), DataType.int32), @@ -54,8 +52,6 @@ private static TargetTestHelpers.LayoutResult GetDebuggerRCThreadLayout(TargetTe private static TestPlaceholderTarget BuildTarget( MockTarget.Architecture arch, int leftSideInitialized, - uint defines, - uint mdStructuresVersion, int? attachStateFlags = null, uint? debuggerControlFlags = null, byte? metadataUpdatesApplied = null, @@ -85,8 +81,6 @@ private static TestPlaceholderTarget BuildTarget( // Allocate and populate the Debugger struct MockMemorySpace.HeapFragment debuggerFrag = allocator.Allocate(debuggerLayout.Stride, "Debugger"); helpers.Write(debuggerFrag.Data.AsSpan(debuggerLayout.Fields[nameof(Data.Debugger.LeftSideInitialized)].Offset, sizeof(int)), leftSideInitialized); - helpers.Write(debuggerFrag.Data.AsSpan(debuggerLayout.Fields[nameof(Data.Debugger.Defines)].Offset, sizeof(uint)), defines); - helpers.Write(debuggerFrag.Data.AsSpan(debuggerLayout.Fields[nameof(Data.Debugger.MDStructuresVersion)].Offset, sizeof(uint)), mdStructuresVersion); helpers.WritePointer(debuggerFrag.Data.AsSpan(debuggerLayout.Fields[nameof(Data.Debugger.RCThread)].Offset, helpers.PointerSize), debuggerRcThreadAddress); helpers.Write(debuggerFrag.Data.AsSpan(debuggerLayout.Fields[nameof(Data.Debugger.RSRequestedSync)].Offset, sizeof(int)), 0); helpers.Write(debuggerFrag.Data.AsSpan(debuggerLayout.Fields[nameof(Data.Debugger.SendExceptionsOutsideOfJMC)].Offset, sizeof(int)), 0); @@ -150,26 +144,22 @@ private static uint GetDebuggerControlFlags(Target target) [ClassData(typeof(MockTarget.StdArch))] public void TryGetDebuggerData_ReturnsTrue_WhenInitialized(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0xDEADBEEF, mdStructuresVersion: 42); + Target target = BuildTarget(arch, leftSideInitialized: 1); IDebugger debugger = target.Contracts.Debugger; Assert.True(debugger.TryGetDebuggerData(out DebuggerData data)); Assert.True(data.IsLeftSideInitialized); - Assert.Equal(0xDEADBEEFu, data.DefinesBitField); - Assert.Equal(42u, data.MDStructuresVersion); } [Theory] [ClassData(typeof(MockTarget.StdArch))] public void TryGetDebuggerData_ReturnsTrue_WhenNotInitialized(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 0, defines: 0xCAFE, mdStructuresVersion: 7); + Target target = BuildTarget(arch, leftSideInitialized: 0); IDebugger debugger = target.Contracts.Debugger; Assert.True(debugger.TryGetDebuggerData(out DebuggerData data)); Assert.False(data.IsLeftSideInitialized); - Assert.Equal(0xCAFEu, data.DefinesBitField); - Assert.Equal(7u, data.MDStructuresVersion); } [Theory] @@ -186,7 +176,7 @@ public void TryGetDebuggerData_ReturnsFalse_WhenDebuggerNull(MockTarget.Architec [ClassData(typeof(MockTarget.StdArch))] public void GetAttachStateFlags_ReturnsValue(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, attachStateFlags: 0x42); + Target target = BuildTarget(arch, leftSideInitialized: 1, attachStateFlags: 0x42); IDebugger debugger = target.Contracts.Debugger; Assert.Equal(0x42, debugger.GetAttachStateFlags()); @@ -196,7 +186,7 @@ public void GetAttachStateFlags_ReturnsValue(MockTarget.Architecture arch) [ClassData(typeof(MockTarget.StdArch))] public void GetAttachStateFlags_ReturnsZero_WhenValueIsZero(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, attachStateFlags: 0); + Target target = BuildTarget(arch, leftSideInitialized: 1, attachStateFlags: 0); IDebugger debugger = target.Contracts.Debugger; Assert.Equal(0, debugger.GetAttachStateFlags()); @@ -206,7 +196,7 @@ public void GetAttachStateFlags_ReturnsZero_WhenValueIsZero(MockTarget.Architect [ClassData(typeof(MockTarget.StdArch))] public void MarkDebuggerAttachPending_SetsPendingAttachFlag(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, attachStateFlags: 0, debuggerControlFlags: 0x42); + Target target = BuildTarget(arch, leftSideInitialized: 1, attachStateFlags: 0, debuggerControlFlags: 0x42); IDebugger debugger = target.Contracts.Debugger; debugger.MarkDebuggerAttachPending(); @@ -218,7 +208,7 @@ public void MarkDebuggerAttachPending_SetsPendingAttachFlag(MockTarget.Architect [ClassData(typeof(MockTarget.StdArch))] public void MarkDebuggerAttached_SetsAttachedFlag_WhenTrue(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, attachStateFlags: 0, debuggerControlFlags: DebuggerControlFlagPendingAttach); + Target target = BuildTarget(arch, leftSideInitialized: 1, attachStateFlags: 0, debuggerControlFlags: DebuggerControlFlagPendingAttach); IDebugger debugger = target.Contracts.Debugger; debugger.MarkDebuggerAttached(true); @@ -231,7 +221,7 @@ public void MarkDebuggerAttached_SetsAttachedFlag_WhenTrue(MockTarget.Architectu public void MarkDebuggerAttached_ClearsAttachedAndPending_WhenFalse(MockTarget.Architecture arch) { const uint originalFlags = 0x0042u | DebuggerControlFlagPendingAttach | DebuggerControlFlagAttached; - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, attachStateFlags: 0, debuggerControlFlags: originalFlags); + Target target = BuildTarget(arch, leftSideInitialized: 1, attachStateFlags: 0, debuggerControlFlags: originalFlags); IDebugger debugger = target.Contracts.Debugger; debugger.MarkDebuggerAttached(false); @@ -243,7 +233,7 @@ public void MarkDebuggerAttached_ClearsAttachedAndPending_WhenFalse(MockTarget.A [ClassData(typeof(MockTarget.StdArch))] public void MetadataUpdatesApplied_ReturnsTrue_WhenSet(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, metadataUpdatesApplied: 1); + Target target = BuildTarget(arch, leftSideInitialized: 1, metadataUpdatesApplied: 1); IDebugger debugger = target.Contracts.Debugger; Assert.True(debugger.MetadataUpdatesApplied()); @@ -253,7 +243,7 @@ public void MetadataUpdatesApplied_ReturnsTrue_WhenSet(MockTarget.Architecture a [ClassData(typeof(MockTarget.StdArch))] public void MetadataUpdatesApplied_ReturnsFalse_WhenNotSet(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, metadataUpdatesApplied: 0); + Target target = BuildTarget(arch, leftSideInitialized: 1, metadataUpdatesApplied: 0); IDebugger debugger = target.Contracts.Debugger; Assert.False(debugger.MetadataUpdatesApplied()); @@ -263,7 +253,7 @@ public void MetadataUpdatesApplied_ReturnsFalse_WhenNotSet(MockTarget.Architectu [ClassData(typeof(MockTarget.StdArch))] public void MetadataUpdatesApplied_ReturnsFalse_WhenGlobalMissing(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0); + Target target = BuildTarget(arch, leftSideInitialized: 1); IDebugger debugger = target.Contracts.Debugger; Assert.False(debugger.MetadataUpdatesApplied()); @@ -295,7 +285,7 @@ public void SetSendExceptionsOutsideOfJMC_DoesNothing_WhenDebuggerNull(MockTarge public void GetDebuggerControlBlockAddress_ReturnsAddress(MockTarget.Architecture arch) { const ulong expectedAddress = 0x1234_5678; - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0, debuggerControlBlockAddress: expectedAddress); + Target target = BuildTarget(arch, leftSideInitialized: 1, debuggerControlBlockAddress: expectedAddress); IDebugger debugger = target.Contracts.Debugger; TargetPointer result = debugger.GetDebuggerControlBlockAddress(); @@ -319,7 +309,7 @@ public void GetDebuggerControlBlockAddress_ReturnsNull_WhenDebuggerNull(MockTarg [ClassData(typeof(MockTarget.StdArch))] public void GetDebuggerControlBlockAddress_ReturnsNull_WhenRCThreadNull(MockTarget.Architecture arch) { - Target target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0); + Target target = BuildTarget(arch, leftSideInitialized: 1); IDebugger debugger = target.Contracts.Debugger; TargetPointer result = debugger.GetDebuggerControlBlockAddress(); @@ -362,7 +352,7 @@ private static TargetPointer GetDebuggerAddress(TestPlaceholderTarget target) [ClassData(typeof(MockTarget.StdArch))] public void RequestSyncAtEvent_WritesSyncFlag(MockTarget.Architecture arch) { - TestPlaceholderTarget target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0); + TestPlaceholderTarget target = BuildTarget(arch, leftSideInitialized: 1); IDebugger debugger = target.Contracts.Debugger; TargetPointer debuggerAddress = GetDebuggerAddress(target); @@ -379,7 +369,7 @@ public void RequestSyncAtEvent_WritesSyncFlag(MockTarget.Architecture arch) [MemberData(nameof(StdArchWithBool))] public void SetSendExceptionsOutsideOfJMC_WritesFlag(MockTarget.Architecture arch, bool value) { - TestPlaceholderTarget target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0); + TestPlaceholderTarget target = BuildTarget(arch, leftSideInitialized: 1); IDebugger debugger = target.Contracts.Debugger; TargetPointer debuggerAddress = GetDebuggerAddress(target); @@ -394,7 +384,7 @@ public void SetSendExceptionsOutsideOfJMC_WritesFlag(MockTarget.Architecture arc [MemberData(nameof(StdArchWithBool))] public void EnableGCNotificationEvents_WritesFlag(MockTarget.Architecture arch, bool value) { - TestPlaceholderTarget target = BuildTarget(arch, leftSideInitialized: 1, defines: 0, mdStructuresVersion: 0); + TestPlaceholderTarget target = BuildTarget(arch, leftSideInitialized: 1); IDebugger debugger = target.Contracts.Debugger; TargetPointer debuggerAddress = GetDebuggerAddress(target); From cc878ae8c7c9eeeaa4704da04e246ab688c063f2 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Sat, 18 Jul 2026 23:39:04 -0700 Subject: [PATCH 2/3] fix --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 6 ++++-- src/coreclr/inc/dacdbi.idl | 3 +++ .../Dbi/DacDbiImpl.cs | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 17381db635f902..810353930510a5 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -3942,7 +3942,9 @@ namespace for (ULONG32 iteration = 0; ; iteration++) { ULONG32 dataSize = pSeg->GetDataSize(); - if (iteration >= MaxPoolSegments || totalSize > MaxPoolBytes || dataSize > MaxPoolBytes) + if (iteration >= MaxPoolSegments || + totalSize > MaxPoolBytes || + dataSize > MaxPoolBytes - totalSize) { ThrowHR(CLDB_E_FILE_CORRUPT); } @@ -4285,7 +4287,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetReadWriteMetadataSize(VMPTR_Mo { if (pSize == NULL) { - ThrowHR(E_INVALIDARG); + ThrowHR(E_POINTER); } *pSize = 0; diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index 1538d1692149cf..0048933f756a16 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -436,4 +436,7 @@ interface IDacDbiInterface : IUnknown // Generic Arg Token HRESULT GetGenericArgTokenIndex([in] VMPTR_MethodDesc vmMethod, [out] UINT32 * pTokenIndex); + + HRESULT GetReadWriteMetadataSize([in] VMPTR_Module vmModule, [out] ULONG32 * pSize); + HRESULT FillReadWriteMetadata([in] VMPTR_Module vmModule, [out] BYTE * pBuffer, [in] ULONG32 cbBuffer); }; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs index 59577825a495d3..4a58567e111cf9 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs @@ -356,9 +356,10 @@ public int GetReadWriteMetadataSize(ulong vmModule, uint* pSize) try { if (pSize == null) - throw new ArgumentException(nameof(pSize)); + throw new ArgumentNullException(nameof(pSize)); if (vmModule == 0) throw new ArgumentException("Module pointer must be non-zero.", nameof(vmModule)); + *pSize = 0; Contracts.ILoader loader = _target.Contracts.Loader; Contracts.ModuleHandle handle = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); From f3624222029196385397fe46f922def3daea9ced Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 21 Jul 2026 12:47:46 -0700 Subject: [PATCH 3/3] bugfix --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 810353930510a5..5e9c4a9642ef71 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -3929,8 +3929,6 @@ namespace PoolData() : Data(NULL), Size(0) {} }; - // Coalesce the data of a StgPool's segment chain. StgPool derives from StgPoolSeg, - // so the head pool and every extension segment are walked through StgPoolSeg. void ReadStoragePool(TADDR poolAddress, PoolData & result) { TADDR segData[MaxPoolSegments]; @@ -3938,7 +3936,8 @@ namespace ULONG32 segCount = 0; ULONG64 totalSize = 0; - StgPoolSeg * pSeg = dac_cast(poolAddress); + StgPool * pPool = dac_cast(poolAddress); + StgPoolSeg * pSeg = pPool; for (ULONG32 iteration = 0; ; iteration++) { ULONG32 dataSize = pSeg->GetDataSize();