Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,20 @@ private TargetPointer GetILExtentStart(out uint codeSize)
{
ILoader loader = _target.Contracts.Loader;
Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(_module);
TargetPointer ilHeader = loader.GetILHeader(moduleHandle, _token);
TargetPointer ilHeader = TargetPointer.Null;
TargetPointer methodDesc = TryResolveMethodDesc();
if (methodDesc != TargetPointer.Null && _target.Contracts.TryGetContract(out ICodeVersions codeVersions))
{
ILCodeVersionHandle activeVersion = codeVersions.GetActiveILCodeVersion(methodDesc);
if (activeVersion.IsValid && codeVersions.GetSource(activeVersion) == CodeVersionSource.EnC)
{
ilHeader = codeVersions.GetIL(activeVersion);
}
}

if (ilHeader == TargetPointer.Null)
ilHeader = loader.GetILHeader(moduleHandle, _token);

if (ilHeader == TargetPointer.Null)
{
codeSize = 0;
Expand Down
67 changes: 67 additions & 0 deletions src/native/managed/cdac/tests/UnitTests/IXCLRDataProcessTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ public void MethodDefinitionsByAddress(MockTarget.Architecture arch)
loader.Setup(l => l.GetILAddr(new TargetPointer(PeAssemblyAddress), 0x20)).Returns(new TargetPointer(SecondHeaderAddress));
loader.Setup(l => l.GetILHeader(module, FirstToken)).Returns(new TargetPointer(FirstHeaderAddress));
loader.Setup(l => l.GetILHeader(module, SecondToken)).Returns(new TargetPointer(SecondHeaderAddress));
loader.Setup(l => l.GetModuleLookupMapElement(
module,
ModuleLookupMapKind.MethodDefToDesc,
It.IsAny<uint>(),
out It.Ref<TargetNUInt>.IsAny)).Returns(TargetPointer.Null);

Mock<IEcmaMetadata> ecmaMetadata = new(MockBehavior.Strict);
ecmaMetadata.Setup(e => e.GetMetadata(module)).Returns(reader);
Expand Down Expand Up @@ -360,6 +365,11 @@ public void MethodDefinitionWithoutIL(MockTarget.Architecture arch)
Mock<ILoader> loader = new(MockBehavior.Strict);
loader.Setup(l => l.GetModuleHandleFromModulePtr(new TargetPointer(ModuleAddress))).Returns(module);
loader.Setup(l => l.GetILHeader(module, Token)).Returns(TargetPointer.Null);
loader.Setup(l => l.GetModuleLookupMapElement(
module,
ModuleLookupMapKind.MethodDefToDesc,
Token,
out It.Ref<TargetNUInt>.IsAny)).Returns(TargetPointer.Null);
TestPlaceholderTarget.Builder builder = new(arch);
builder.AddMockContract(loader.Object);
IXCLRDataMethodDefinition method = new ClrDataMethodDefinition(
Expand All @@ -376,6 +386,63 @@ public void MethodDefinitionWithoutIL(MockTarget.Architecture arch)
Assert.Equal(CorDbgHResults.E_UNEXPECTED, method.GetRepresentativeEntryAddress(&address));
}

[Theory]
[ClassData(typeof(MockTarget.StdArch))]
public void MethodDefinitionUsesActiveEnCIL(MockTarget.Architecture arch)
{
const ulong ModuleAddress = 0x2000;
const ulong DefaultHeaderAddress = 0x3000;
const ulong EnCHeaderAddress = 0x4000;
const ulong MethodDescAddress = 0x5000;
const uint Token = 0x06000001;
const byte TinyFormat = 0x2;
const int DefaultCodeSize = 1;
const int EnCCodeSize = 3;

ModuleHandle module = new(new TargetPointer(ModuleAddress));
Mock<ILoader> loader = new(MockBehavior.Strict);
loader.Setup(l => l.GetModuleHandleFromModulePtr(new TargetPointer(ModuleAddress))).Returns(module);
loader.Setup(l => l.GetModuleLookupMapElement(
module,
ModuleLookupMapKind.MethodDefToDesc,
Token,
out It.Ref<TargetNUInt>.IsAny)).Returns(new TargetPointer(MethodDescAddress));
loader.Setup(l => l.GetILHeader(module, Token)).Returns(new TargetPointer(DefaultHeaderAddress));

ILCodeVersionHandle activeVersion = ILCodeVersionHandle.CreateExplicit(new TargetPointer(0x7000));
Mock<ICodeVersions> codeVersions = new(MockBehavior.Strict);
codeVersions.Setup(c => c.GetActiveILCodeVersion(new TargetPointer(MethodDescAddress))).Returns(activeVersion);
codeVersions.Setup(c => c.GetSource(activeVersion)).Returns(CodeVersionSource.EnC);
codeVersions.Setup(c => c.GetIL(activeVersion)).Returns(new TargetPointer(EnCHeaderAddress));

TestPlaceholderTarget.Builder builder = new(arch);
builder.AddMockContract(loader.Object);
builder.AddMockContract(codeVersions.Object);
builder.MemoryBuilder.AddHeapFragment(new MockMemorySpace.HeapFragment
{
Address = DefaultHeaderAddress,
Data = [(byte)((DefaultCodeSize << 2) | TinyFormat), 0],
Name = nameof(DefaultHeaderAddress),
});
builder.MemoryBuilder.AddHeapFragment(new MockMemorySpace.HeapFragment
{
Address = EnCHeaderAddress,
Data = [(byte)((EnCCodeSize << 2) | TinyFormat), 0, 0, 0],
Name = nameof(EnCHeaderAddress),
});

IXCLRDataMethodDefinition method = new ClrDataMethodDefinition(
builder.Build(),
new TargetPointer(ModuleAddress),
Token,
legacyImpl: null);

AssertMethodDefinitionExtent(
method,
EnCHeaderAddress + sizeof(byte),
EnCHeaderAddress + sizeof(byte) + EnCCodeSize - 1);
}

private static void AssertMethodDefinitionExtent(
IXCLRDataMethodDefinition method,
ClrDataAddress expectedStart,
Expand Down
Loading