| File: Contracts\PrecodeStubs_3.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Contracts\Microsoft.Diagnostics.DataContractReader.Contracts.csproj (Microsoft.Diagnostics.DataContractReader.Contracts) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; namespace Microsoft.Diagnostics.DataContractReader.Contracts; internal struct PrecodeStubs_3_Impl : IPrecodeStubsContractCommonApi<Data.StubPrecodeData_2> { public static TargetPointer StubPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { // Version 3 of this contract behaves just like version 2 return PrecodeStubs_2_Impl.StubPrecode_GetMethodDesc(instrPointer, target, precodeMachineDescriptor); } public static TargetPointer FixupPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { // Version 3 of this contract behaves just like version 1 return PrecodeStubs_1_Impl.FixupPrecode_GetMethodDesc(instrPointer, target, precodeMachineDescriptor); } public static TargetPointer ThisPtrRetBufPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { // Version 3 of this contract behaves just like version 2 return PrecodeStubs_2_Impl.ThisPtrRetBufPrecode_GetMethodDesc(instrPointer, target, precodeMachineDescriptor); } public static TargetPointer InterpreterPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { TargetPointer dataAddr = instrPointer + precodeMachineDescriptor.StubCodePageSize; Data.InterpreterPrecodeData precodeData = target.ProcessedData.GetOrAdd<Data.InterpreterPrecodeData>(dataAddr); Data.InterpByteCodeStart byteCodeStart = target.ProcessedData.GetOrAdd<Data.InterpByteCodeStart>(precodeData.ByteCodeAddr); Data.InterpMethod interpMethod = target.ProcessedData.GetOrAdd<Data.InterpMethod>(byteCodeStart.Method); return interpMethod.MethodDesc; } public static byte StubPrecodeData_GetType(Data.StubPrecodeData_2 stubPrecodeData) { // Version 3 of this contract behaves just like version 2 return PrecodeStubs_2_Impl.StubPrecodeData_GetType(stubPrecodeData); } private static Data.StubPrecodeData_2 GetStubPrecodeData(TargetPointer stubInstrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { TargetPointer stubPrecodeDataAddress = stubInstrPointer + precodeMachineDescriptor.StubCodePageSize; return target.ProcessedData.GetOrAdd<Data.StubPrecodeData_2>(stubPrecodeDataAddress); } public static KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { if (ReadBytesAndCompare(instrPointer, precodeMachineDescriptor.StubBytes!, precodeMachineDescriptor.StubIgnoredBytes!, target)) { // get the actual type from the StubPrecodeData Data.StubPrecodeData_2 stubPrecodeData = GetStubPrecodeData(instrPointer, target, precodeMachineDescriptor); byte exactPrecodeType = stubPrecodeData.Type; if (exactPrecodeType == 0) return null; if (exactPrecodeType == precodeMachineDescriptor.StubPrecodeType) { return KnownPrecodeType.Stub; } else if (precodeMachineDescriptor.PInvokeImportPrecodeType is byte compareByte1 && compareByte1 == exactPrecodeType) { return KnownPrecodeType.PInvokeImport; } else if (precodeMachineDescriptor.ThisPointerRetBufPrecodeType is byte compareByte2 && compareByte2 == exactPrecodeType) { return KnownPrecodeType.ThisPtrRetBuf; } else if (precodeMachineDescriptor.UMEntryPrecodeType is byte compareByte3 && compareByte3 == exactPrecodeType) { return KnownPrecodeType.UMEntry; } else if (precodeMachineDescriptor.InterpreterPrecodeType is byte compareByte4 && compareByte4 == exactPrecodeType) { return KnownPrecodeType.Interpreter; } else if (precodeMachineDescriptor.DynamicHelperPrecodeType is byte compareByte5 && compareByte5 == exactPrecodeType) { return KnownPrecodeType.DynamicHelper; } } else if (ReadBytesAndCompare(instrPointer, precodeMachineDescriptor.FixupBytes!, precodeMachineDescriptor.FixupIgnoredBytes!, target)) { return KnownPrecodeType.Fixup; } return null; static bool ReadBytesAndCompare(TargetPointer instrAddress, byte[] expectedBytePattern, byte[] bytesToIgnore, Target target) { for (ulong i = 0; i < (ulong)expectedBytePattern.Length; i++) { if (bytesToIgnore[i] == 0) { byte targetBytePattern = target.Read<byte>(new TargetPointer((instrAddress.Value + (ulong)i))); if (expectedBytePattern[i] != targetBytePattern) { return false; } } } return true; } } } internal sealed class PrecodeStubs_3 : PrecodeStubsCommon<PrecodeStubs_3_Impl, Data.StubPrecodeData_2> { public PrecodeStubs_3(Target target) : base(target) { } }