From 199a215b81a9c8f0a270e2ab6b99ea8ebe5d5de3 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 Aug 2025 13:17:58 -0700 Subject: [PATCH 1/4] Adding GetILForModule cDAC API --- .../Contracts/ILoader.cs | 1 + .../Contracts/Loader_1.cs | 12 ++++++ .../Legacy/SOSDacImpl.cs | 38 ++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs index 1c81dadcbe496c..24cacda266339d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs @@ -84,6 +84,7 @@ public interface ILoader : IContract TargetPointer GetAssembly(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetPEAssembly(ModuleHandle handle) => throw new NotImplementedException(); bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddress, out uint size, out uint imageFlags) => throw new NotImplementedException(); + TargetPointer GetILAddr(TargetPointer peAssemblyPtr, int rva) => throw new NotImplementedException(); bool TryGetSymbolStream(ModuleHandle handle, out TargetPointer buffer, out uint size) => throw new NotImplementedException(); bool IsProbeExtensionResultValid(ModuleHandle handle) => throw new NotImplementedException(); ModuleFlags GetFlags(ModuleHandle handle) => throw new NotImplementedException(); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs index 7ceed03f5ac6e1..fc9080b77dabe4 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs @@ -195,6 +195,18 @@ bool ILoader.TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer ba return true; } + TargetPointer ILoader.GetILAddr(TargetPointer peAssemblyPtr, int rva) + { + Data.PEAssembly assembly = _target.ProcessedData.GetOrAdd(peAssemblyPtr); + if (assembly.PEImage == TargetPointer.Null) + throw new InvalidOperationException("PEAssembly does not have a PEImage associated with it."); + Data.PEImage peImage = _target.ProcessedData.GetOrAdd(assembly.PEImage); + if (peImage.LoadedImageLayout == TargetPointer.Null) + throw new InvalidOperationException("PEImage does not have a LoadedImageLayout associated with it."); + Data.PEImageLayout peImageLayout = _target.ProcessedData.GetOrAdd(peImage.LoadedImageLayout); + return peImageLayout.Base + (uint)rva; + } + bool ILoader.TryGetSymbolStream(ModuleHandle handle, out TargetPointer buffer, out uint size) { buffer = TargetPointer.Null; diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index b1cc4cc1ac9d24..ee1a092abd805a 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -663,7 +663,43 @@ int ISOSDacInterface.GetHillClimbingLogEntry(ClrDataAddress addr, void* data) return hr; } int ISOSDacInterface.GetILForModule(ClrDataAddress moduleAddr, int rva, ClrDataAddress* il) - => _legacyImpl is not null ? _legacyImpl.GetILForModule(moduleAddr, rva, il) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + if (moduleAddr == 0 || il == null) + { + hr = HResults.E_INVALIDARG; + } + else if (rva == 0) + *il = 0; + else + { + try + { + Contracts.ILoader loader = _target.Contracts.Loader; + TargetPointer module = moduleAddr.ToTargetPointer(_target); + Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(module); + TargetPointer peAssemblyPtr = loader.GetPEAssembly(moduleHandle); + *il = loader.GetILAddr(peAssemblyPtr, rva).ToClrDataAddress(_target); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + } +#if DEBUG + if (_legacyImpl is not null) + { + ClrDataAddress ilLocal; + int hrLocal = _legacyImpl.GetILForModule(moduleAddr, rva, &ilLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*il == ilLocal, $"cDAC: {*il:x}, DAC: {ilLocal:x}"); + } + } +#endif + return hr; + } int ISOSDacInterface.GetJitHelperFunctionName(ClrDataAddress ip, uint count, byte* name, uint* pNeeded) => _legacyImpl is not null ? _legacyImpl.GetJitHelperFunctionName(ip, count, name, pNeeded) : HResults.E_NOTIMPL; int ISOSDacInterface.GetJitManagerList(uint count, void* managers, uint* pNeeded) From 58b58aa157ab7d33cc6a1ac259966102e3c94bb1 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 8 Aug 2025 11:56:52 -0700 Subject: [PATCH 2/4] docs --- docs/design/datacontracts/Loader.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/design/datacontracts/Loader.md b/docs/design/datacontracts/Loader.md index e8a8461e710e26..6d75659a18a86f 100644 --- a/docs/design/datacontracts/Loader.md +++ b/docs/design/datacontracts/Loader.md @@ -61,6 +61,7 @@ TargetPointer GetModule(ModuleHandle handle); TargetPointer GetAssembly(ModuleHandle handle); TargetPointer GetPEAssembly(ModuleHandle handle); bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddress, out uint size, out uint imageFlags); +TargetPointer ILoader.GetILAddr(TargetPointer peAssemblyPtr, int rva); bool TryGetSymbolStream(ModuleHandle handle, out TargetPointer buffer, out uint size); bool IsProbeExtensionResultValid(ModuleHandle handle); ModuleFlags GetFlags(ModuleHandle handle); @@ -319,6 +320,19 @@ bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddres return true; } +TargetPointer ILoader.GetILAddr(TargetPointer peAssemblyPtr, int rva) +{ + TargetPointer peImage = target.ReadPointer(peAssemblyPtr + /* PEAssembly::PEImage offset */); + if(peImage == TargetPointer.Null) + throw new InvalidOperationException("PEAssembly does not have a PEImage associated with it."); + + TargetPointer peImageLayout = target.ReadPointer(peImage + /* PEImage::LoadedImageLayout offset */); + if(peImageLayout == TargetPointer.Null) + throw new InvalidOperationException("PEImage does not have a LoadedImageLayout associated with it."); + baseAddress = target.ReadPointer(peImageLayout + /* PEImageLayout::Base offset */); + return baseAddress + (uint)rva; +} + bool TryGetSymbolStream(ModuleHandle handle, out TargetPointer buffer, out uint size) { buffer = TargetPointer.Null; From 3edd1221361da73ad5dbb4a2eabec114558cea28 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 8 Aug 2025 18:50:20 -0700 Subject: [PATCH 3/4] !IsMapped() --- docs/design/datacontracts/Loader.md | 78 ++++++++++++++++++- .../vm/datadescriptor/datadescriptor.h | 4 + .../vm/datadescriptor/datadescriptor.inc | 29 +++++++ .../DataType.cs | 5 ++ .../Contracts/Loader_1.cs | 64 ++++++++++++++- .../Data/ImageDosHeader.cs | 17 ++++ .../Data/ImageFileHeader.cs | 19 +++++ .../Data/ImageNTHeaders.cs | 20 +++++ .../Data/ImageOptionalHeader.cs | 17 ++++ .../Data/ImageSectionHeader.cs | 23 ++++++ 10 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDosHeader.cs create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageFileHeader.cs create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageNTHeaders.cs create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageOptionalHeader.cs create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageSectionHeader.cs diff --git a/docs/design/datacontracts/Loader.md b/docs/design/datacontracts/Loader.md index 6d75659a18a86f..d1f5a89dc11e84 100644 --- a/docs/design/datacontracts/Loader.md +++ b/docs/design/datacontracts/Loader.md @@ -132,6 +132,15 @@ TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer); | `ArrayListBlock` | `Size` | Size of data section in block | | `ArrayListBlock` | `ArrayStart` | Start of data section in block | | `SystemDomain` | `GlobalLoaderAllocator` | global LoaderAllocator | +| `ImageDosHeader` | `Lfanew` | Offset to NT headers | +| `ImageNTHeaders` | `OptionalHeader` | Optional header | +| `ImageNTHeaders` | `FileHeader` | File header | +| `ImageOptionalHeader` | `SectionAlignment` | Alignment of sections in memory | +| `ImageFileHeader` | `NumberOfSections` | Number of sections in the PE file | +| `ImageFileHeader` | `SizeOfOptionalHeader` | Size of optional header on disk | +| `ImageSectionHeader` | `VirtualAddress` | Virtual address of the section | +| `ImageSectionHeader` | `VirtualSize` | Virtual size of the section | +| `ImageSectionHeader` | `PointerToRawData` | Offset to section data | ### Global variables used: @@ -157,6 +166,11 @@ private enum ModuleFlags_1 : uint EditAndContinue = 0x00000008, // Edit and Continue is enabled for this module ReflectionEmit = 0x00000040, // Reflection.Emit was used to create this module } + +private enum PEImageFlags : uint +{ + FLAG_MAPPED = 0x01, // the file is mapped/hydrated (vs. the raw disk layout) +}; ``` ### Method Implementations @@ -329,8 +343,68 @@ TargetPointer ILoader.GetILAddr(TargetPointer peAssemblyPtr, int rva) TargetPointer peImageLayout = target.ReadPointer(peImage + /* PEImage::LoadedImageLayout offset */); if(peImageLayout == TargetPointer.Null) throw new InvalidOperationException("PEImage does not have a LoadedImageLayout associated with it."); - baseAddress = target.ReadPointer(peImageLayout + /* PEImageLayout::Base offset */); - return baseAddress + (uint)rva; + + // Get base address and flags from PEImageLayout + TargetPointer baseAddress = target.ReadPointer(peImageLayout + /* PEImageLayout::Base offset */); + uint imageFlags = target.Read(peImageLayout + /* PEImageLayout::Flags offset */); + + bool isMapped = (imageFlags & (uint)PEImageFlags.FLAG_MAPPED) != 0; + + uint offset; + if (isMapped) + { + offset = (uint)rva; + } + else + { + // find NT headers using DOS header + uint dosHeaderLfanew = target.Read(baseAddress + /* ImageDosHeader::Lfanew offset */); + TargetPointer ntHeadersPtr = baseAddress + dosHeaderLfanew; + + TargetPointer optionalHeaderPtr = ntHeadersPtr + /* ImageNTHeaders::OptionalHeader offset */; + uint sectionAlignment = target.Read(optionalHeaderPtr + /* ImageOptionalHeader::SectionAlignment offset */); + + // Get number of sections from file header + TargetPointer fileHeaderPtr = ntHeadersPtr + /* ImageNTHeaders::FileHeader offset */; + uint numberOfSections = target.Read(fileHeaderPtr + /* ImageFileHeader::NumberOfSections offset */); + + // Calculate first section address (after NT headers and optional header) + uint imageFileHeaderSize = target.Read(fileHeaderPtr + /* ImageFileHeader::SizeOfOptionalHeader offset */); + TargetPointer firstSectionPtr = ntHeadersPtr + /* ImageNTHeaders::OptionalHeader offset */ + imageFileHeaderSize; + + // Find the section containing this RVA + TargetPointer sectionPtr = TargetPointer.Null; + uint sectionHeaderSize = /* sizeof(ImageSectionHeader native struct) */; + + for (uint i = 0; i < numberOfSections; i++) + { + TargetPointer currentSectionPtr = firstSectionPtr + (i * sectionHeaderSize); + uint virtualAddress = target.Read(currentSectionPtr + /* ImageSectionHeader::VirtualAddress offset */); + uint virtualSize = target.Read(currentSectionPtr + /* ImageSectionHeader::VirtualSize offset */); + + uint alignedVirtualSize = (virtualSize + sectionAlignment - 1) & ~(sectionAlignment - 1); + if (rva < VirtualAddress + alignedVirtualSize) + { + if (rva < virtualAddress) + sectionPtr = TargetPointer.Null; + else + sectionPtr = currentSectionPtr; + break; + } + } + if (sectionPtr == TargetPointer.Null) + { + offset = (uint)rva; + } + else + { + // Convert RVA to file offset using section information + uint sectionVirtualAddress = target.Read(sectionPtr + /* ImageSectionHeader::VirtualAddress offset */); + uint sectionPointerToRawData = target.Read(sectionPtr + /* ImageSectionHeader::PointerToRawData offset */); + offset = ((rva - sectionVirtualAddress) + sectionPointerToRawData); + } + } + return baseAddress + offset; } bool TryGetSymbolStream(ModuleHandle handle, out TargetPointer buffer, out uint size) diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.h b/src/coreclr/vm/datadescriptor/datadescriptor.h index 84adff2a49b4d3..45aaa53d918267 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.h +++ b/src/coreclr/vm/datadescriptor/datadescriptor.h @@ -1,6 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#ifndef HOST_WINDOWS +#include "../pal/inc/pal_mstypes.h" +#include "../pal/inc/rt/ntimage.h" +#endif // HOST_WINDOWS #include "common.h" #include diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index 167c581cf9e2d3..735eb6a7e83727 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -194,6 +194,35 @@ CDAC_TYPE_FIELD(PEImageLayout, /*uint32*/, Size, cdac_data::Size) CDAC_TYPE_FIELD(PEImageLayout, /*uint32*/, Flags, cdac_data::Flags) CDAC_TYPE_END(PEImageLayout) +CDAC_TYPE_BEGIN(ImageNTHeaders) +CDAC_TYPE_INDETERMINATE(ImageNTHeaders) +CDAC_TYPE_FIELD(ImageNTHeaders, /*uint32*/, OptionalHeader, offsetof(IMAGE_NT_HEADERS, OptionalHeader)) +CDAC_TYPE_FIELD(ImageNTHeaders, /*uint16*/, FileHeader, offsetof(IMAGE_NT_HEADERS, FileHeader)) +CDAC_TYPE_END(ImageNTHeaders) + +CDAC_TYPE_BEGIN(ImageFileHeader) +CDAC_TYPE_INDETERMINATE(ImageFileHeader) +CDAC_TYPE_FIELD(ImageFileHeader, /*uint16*/, NumberOfSections, offsetof(IMAGE_FILE_HEADER, NumberOfSections)) +CDAC_TYPE_FIELD(ImageFileHeader, /*uint16*/, SizeOfOptionalHeader, offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader)) +CDAC_TYPE_END(ImageFileHeader) + +CDAC_TYPE_BEGIN(ImageOptionalHeader) +CDAC_TYPE_INDETERMINATE(ImageOptionalHeader) +CDAC_TYPE_FIELD(ImageOptionalHeader, /*uint32*/, SectionAlignment, offsetof(IMAGE_OPTIONAL_HEADER, SectionAlignment)) +CDAC_TYPE_END(ImageOptionalHeader) + +CDAC_TYPE_BEGIN(ImageSectionHeader) +CDAC_TYPE_SIZE(sizeof(IMAGE_SECTION_HEADER)) +CDAC_TYPE_FIELD(ImageSectionHeader, /*uint32*/, VirtualAddress, offsetof(IMAGE_SECTION_HEADER, VirtualAddress)) +CDAC_TYPE_FIELD(ImageSectionHeader, /*uint32*/, VirtualSize, offsetof(IMAGE_SECTION_HEADER, Misc.VirtualSize)) +CDAC_TYPE_FIELD(ImageSectionHeader, /*uint32*/, PointerToRawData, offsetof(IMAGE_SECTION_HEADER, PointerToRawData)) +CDAC_TYPE_END(ImageSectionHeader) + +CDAC_TYPE_BEGIN(ImageDosHeader) +CDAC_TYPE_INDETERMINATE(ImageDosHeader) +CDAC_TYPE_FIELD(ImageDosHeader, /*uint32*/, Lfanew, offsetof(IMAGE_DOS_HEADER, e_lfanew)) +CDAC_TYPE_END(ImageDosHeader) + CDAC_TYPE_BEGIN(CGrowableSymbolStream) CDAC_TYPE_INDETERMINATE(CGrowableSymbolStream) CDAC_TYPE_FIELD(CGrowableSymbolStream, /*pointer*/, Buffer, cdac_data::Buffer) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs index 98ead3efdd2fdf..a1a46f1f1cdb1c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs @@ -39,6 +39,11 @@ public enum DataType AssemblyBinder, PEImage, PEImageLayout, + ImageFileHeader, + ImageNTHeaders, + ImageOptionalHeader, + ImageSectionHeader, + ImageDosHeader, CGrowableSymbolStream, ProbeExtensionResult, MethodTable, diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs index fc9080b77dabe4..98763c56813fc3 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs @@ -36,6 +36,10 @@ private enum ModuleFlags_1 : uint BeingUnloaded = 0x100000, } + private enum PEImageFlags : uint + { + FLAG_MAPPED = 0x01, // the file is mapped/hydrated (vs. the raw disk layout) + }; private readonly Target _target; internal Loader_1(Target target) @@ -195,6 +199,59 @@ bool ILoader.TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer ba return true; } + private static uint AlignUp(uint value, uint alignment) + { + if (alignment == 0) + throw new ArgumentException("Alignment must be greater than zero.", nameof(alignment)); + return (value + alignment - 1) & ~(alignment - 1); + } + + private static bool IsMapped(Data.PEImageLayout peImageLayout) + { + return (peImageLayout.Flags & (uint)PEImageFlags.FLAG_MAPPED) != 0; + } + + private TargetPointer FindNTHeaders(Data.PEImageLayout imageLayout) + { + Data.ImageDosHeader dosHeader = _target.ProcessedData.GetOrAdd(imageLayout.Base); + return imageLayout.Base + (uint)dosHeader.Lfanew; + } + + private TargetPointer RvaToSection(int rva, Data.PEImageLayout imageLayout) + { + TargetPointer ntHeadersPtr = FindNTHeaders(imageLayout); + Data.ImageNTHeaders ntHeaders = _target.ProcessedData.GetOrAdd(ntHeadersPtr); + Target.TypeInfo type = _target.GetTypeInfo(DataType.ImageNTHeaders); + int offset = type.Fields[nameof(Data.ImageNTHeaders.OptionalHeader)].Offset; + TargetPointer section = ntHeadersPtr + (uint)offset + ntHeaders.FileHeader.SizeOfOptionalHeader; + TargetPointer sectionEnd = section + _target.GetTypeInfo(DataType.ImageSectionHeader).Size!.Value * ntHeaders.FileHeader.NumberOfSections; + uint sectionAlignment = ntHeaders.OptionalHeader.SectionAlignment; + while (section < sectionEnd) + { + Data.ImageSectionHeader sectionHeader = _target.ProcessedData.GetOrAdd(section); + if (rva < sectionHeader.VirtualAddress + AlignUp(sectionHeader.VirtualSize, sectionAlignment)) + { + if (rva < sectionHeader.VirtualAddress) + return TargetPointer.Null; + else + return section; + } + section += _target.GetTypeInfo(DataType.ImageSectionHeader).Size!.Value; + } + return TargetPointer.Null; + } + + private uint RvaToOffset(int rva, Data.PEImageLayout imageLayout) + { + TargetPointer section = RvaToSection(rva, imageLayout); + if (section == TargetPointer.Null) + return (uint)rva; + + Data.ImageSectionHeader sectionHeader = _target.ProcessedData.GetOrAdd(section); + uint offset = (uint)(rva - sectionHeader.VirtualAddress) + sectionHeader.PointerToRawData; + return offset; + } + TargetPointer ILoader.GetILAddr(TargetPointer peAssemblyPtr, int rva) { Data.PEAssembly assembly = _target.ProcessedData.GetOrAdd(peAssemblyPtr); @@ -204,7 +261,12 @@ TargetPointer ILoader.GetILAddr(TargetPointer peAssemblyPtr, int rva) if (peImage.LoadedImageLayout == TargetPointer.Null) throw new InvalidOperationException("PEImage does not have a LoadedImageLayout associated with it."); Data.PEImageLayout peImageLayout = _target.ProcessedData.GetOrAdd(peImage.LoadedImageLayout); - return peImageLayout.Base + (uint)rva; + uint offset; + if (IsMapped(peImageLayout)) + offset = (uint)rva; + else + offset = RvaToOffset(rva, peImageLayout); + return peImageLayout.Base + offset; } bool ILoader.TryGetSymbolStream(ModuleHandle handle, out TargetPointer buffer, out uint size) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDosHeader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDosHeader.cs new file mode 100644 index 00000000000000..f506ffa3685b29 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDosHeader.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ImageDosHeader : IData +{ + static ImageDosHeader IData.Create(Target target, TargetPointer address) + => new ImageDosHeader(target, address); + + public ImageDosHeader(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ImageDosHeader); + Lfanew = target.Read(address + (ulong)type.Fields[nameof(Lfanew)].Offset); + } + public int Lfanew { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageFileHeader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageFileHeader.cs new file mode 100644 index 00000000000000..6c03dbac1166d1 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageFileHeader.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ImageFileHeader : IData +{ + static ImageFileHeader IData.Create(Target target, TargetPointer address) => new ImageFileHeader(target, address); + public ImageFileHeader(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ImageFileHeader); + NumberOfSections = target.Read(address + (ulong)type.Fields[nameof(NumberOfSections)].Offset); + SizeOfOptionalHeader = target.Read(address + (ulong)type.Fields[nameof(SizeOfOptionalHeader)].Offset); + } + public ushort NumberOfSections { get; init; } + public ushort SizeOfOptionalHeader { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageNTHeaders.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageNTHeaders.cs new file mode 100644 index 00000000000000..1985cfd8704601 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageNTHeaders.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ImageNTHeaders : IData +{ + static ImageNTHeaders IData.Create(Target target, TargetPointer address) => new ImageNTHeaders(target, address); + public ImageNTHeaders(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ImageNTHeaders); + OptionalHeader = target.ProcessedData.GetOrAdd(address + (ulong)type.Fields[nameof(OptionalHeader)].Offset); + FileHeader = target.ProcessedData.GetOrAdd(address + (ulong)type.Fields[nameof(FileHeader)].Offset); + } + + public ImageOptionalHeader OptionalHeader { get; init; } + public ImageFileHeader FileHeader { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageOptionalHeader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageOptionalHeader.cs new file mode 100644 index 00000000000000..9a82411dd3e820 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageOptionalHeader.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ImageOptionalHeader : IData +{ + static ImageOptionalHeader IData.Create(Target target, TargetPointer address) => new ImageOptionalHeader(target, address); + public ImageOptionalHeader(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ImageOptionalHeader); + SectionAlignment = target.Read(address + (ulong)type.Fields[nameof(SectionAlignment)].Offset); + } + public uint SectionAlignment { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageSectionHeader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageSectionHeader.cs new file mode 100644 index 00000000000000..af91d83a1e9b7b --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageSectionHeader.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ImageSectionHeader : IData +{ + static ImageSectionHeader IData.Create(Target target, TargetPointer address) => new ImageSectionHeader(target, address); + public ImageSectionHeader(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ImageSectionHeader); + + VirtualSize = target.Read(address + (ulong)type.Fields[nameof(VirtualSize)].Offset); + VirtualAddress = target.Read(address + (ulong)type.Fields[nameof(VirtualAddress)].Offset); + PointerToRawData = target.Read(address + (ulong)type.Fields[nameof(PointerToRawData)].Offset); + } + + public uint VirtualSize { get; init; } + public uint VirtualAddress { get; init; } + public uint PointerToRawData { get; init; } +} From 4ee726dcf930a1cbb2b3c33d950fd9943b3230f4 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 11 Aug 2025 15:34:22 -0700 Subject: [PATCH 4/4] include --- src/coreclr/vm/datadescriptor/datadescriptor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.h b/src/coreclr/vm/datadescriptor/datadescriptor.h index 45aaa53d918267..49a52cdd0e23f3 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.h +++ b/src/coreclr/vm/datadescriptor/datadescriptor.h @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #ifndef HOST_WINDOWS -#include "../pal/inc/pal_mstypes.h" +#include "../pal/inc/pal.h" #include "../pal/inc/rt/ntimage.h" #endif // HOST_WINDOWS #include "common.h"