| File: Contracts\StackWalk\Context\Wasm\WasmR2RInfo.cs | Web Access |
| Project: 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 Microsoft.Diagnostics.DataContractReader.Data; using Microsoft.Diagnostics.DataContractReader.ExecutionManagerHelpers; namespace Microsoft.Diagnostics.DataContractReader.Contracts.StackWalkHelpers.Wasm; /// <summary> /// cDAC implementation of <see cref="IWasmR2RInfo"/>, backed by the ExecutionManager's /// <see cref="WasmFunctionTableIndexLookup"/>. /// </summary> internal sealed class WasmR2RInfo : IWasmR2RInfo { private readonly Target _target; private readonly IExecutionManager _executionManager; private readonly WasmFunctionTableIndexLookup _lookup; public WasmR2RInfo(Target target) : this(target, target.Contracts.ExecutionManager) { } internal WasmR2RInfo(Target target, IExecutionManager executionManager) { _target = target; _executionManager = executionManager; _lookup = new WasmFunctionTableIndexLookup(target); } public bool TryGetVirtualIPBase(uint frameIdentity, out ulong baseVirtualIP) { if ((frameIdentity & 1) == 0) { PortableEntryPoint portableEntryPoint = _target.ProcessedData.GetOrAdd<PortableEntryPoint>(new TargetPointer(frameIdentity)); return _lookup.TryGetVirtualIPBase((uint)portableEntryPoint.ActualCode.Value, out baseVirtualIP); } if ((int)frameIdentity < 0) { uint runtimeFunctionIndex = (~frameIdentity) >> 1; return _lookup.TryGetCoreLibVirtualIPBase(runtimeFunctionIndex, out baseVirtualIP); } return _lookup.TryGetVirtualIPBase(frameIdentity >> 1, out baseVirtualIP); } public bool TryGetUnwindData(TargetCodePointer controlPC, out TargetPointer unwindDataAddress) { unwindDataAddress = TargetPointer.Null; if (_executionManager.GetCodeBlockHandle(controlPC) is not CodeBlockHandle codeBlock) return false; TargetPointer runtimeFunctionAddress = _executionManager.GetUnwindInfo(codeBlock); if (runtimeFunctionAddress == TargetPointer.Null) return false; TargetPointer unwindInfoBaseAddress = _executionManager.GetUnwindInfoBaseAddress(codeBlock); RuntimeFunction runtimeFunction = _target.ProcessedData.GetOrAdd<RuntimeFunction>(runtimeFunctionAddress); unwindDataAddress = unwindInfoBaseAddress + runtimeFunction.UnwindData; return true; } }