| File: Compiler\ObjectWriter\ObjectWriter.Aot.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.Compiler\ILCompiler.Compiler.csproj (ILCompiler.Compiler) |
// 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.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.TypesDebugInfo; using ObjectData = ILCompiler.DependencyAnalysis.ObjectNode.ObjectData; using static ILCompiler.DependencyAnalysis.RelocType; namespace ILCompiler.ObjectWriter { public abstract partial class ObjectWriter { // Debugging private UserDefinedTypeDescriptor _userDefinedTypeDescriptor; private protected abstract void EmitUnwindInfo( SectionWriter sectionWriter, INodeWithCodeInfo nodeWithCodeInfo, Utf8String currentSymbolName); private protected uint GetVarTypeIndex(bool isStateMachineMoveNextMethod, DebugVarInfoMetadata debugVar) { uint typeIndex; try { if (isStateMachineMoveNextMethod && debugVar.DebugVarInfo.VarNumber == 0) { typeIndex = _userDefinedTypeDescriptor.GetStateMachineThisVariableTypeIndex(debugVar.Type); // FIXME // varName = "locals"; } else { typeIndex = _userDefinedTypeDescriptor.GetVariableTypeIndex(debugVar.Type); } } catch (TypeSystemException) { typeIndex = 0; // T_NOTYPE // FIXME // Debug.Fail(); } return typeIndex; } private protected abstract ITypesDebugInfoWriter CreateDebugInfoBuilder(); private protected abstract void EmitDebugFunctionInfo( uint methodTypeIndex, Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode, bool hasSequencePoints); private protected virtual void EmitDebugThunkInfo( Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode) { } private protected abstract void EmitDebugSections(IDictionary<Utf8String, SymbolDefinition> definedSymbols); partial void EmitDebugInfo(IReadOnlyCollection<DependencyNode> nodes, Logger logger) { if (logger.IsVerbose) logger.LogMessage($"Emitting debug information"); _userDefinedTypeDescriptor = new UserDefinedTypeDescriptor(CreateDebugInfoBuilder(), _nodeFactory); foreach (DependencyNode depNode in nodes) { ObjectNode node = depNode as ObjectNode; if (node is null || node.ShouldSkipEmittingObjectNode(_nodeFactory)) { continue; } ISymbolNode symbolNode = node as ISymbolNode; ISymbolNode deduplicatedSymbolNode = _nodeFactory.ObjectInterner.GetDeduplicatedSymbol(_nodeFactory, symbolNode); if (deduplicatedSymbolNode != symbolNode) { continue; } // Ensure any allocated MethodTables have debug info if (node is ConstructedEETypeNode methodTable) { _userDefinedTypeDescriptor.GetTypeIndex(methodTable.Type, needsCompleteType: true); } if (node is INodeWithDebugInfo debugNode and ISymbolDefinitionNode symbolDefinitionNode) { Utf8String methodName = GetMangledName(symbolDefinitionNode); if (_definedSymbols.TryGetValue(methodName, out var methodSymbol)) { if (node is IMethodNode methodNode) { bool hasSequencePoints = debugNode.GetNativeSequencePoints().Any(); uint methodTypeIndex = hasSequencePoints ? _userDefinedTypeDescriptor.GetMethodFunctionIdTypeIndex(methodNode.Method) : 0; EmitDebugFunctionInfo(methodTypeIndex, methodName, methodSymbol, debugNode, hasSequencePoints); } else { EmitDebugThunkInfo(methodName, methodSymbol, debugNode); } } } } // Ensure all fields associated with generated static bases have debug info foreach (MetadataType typeWithStaticBase in _nodeFactory.MetadataManager.GetTypesWithStaticBases()) { _userDefinedTypeDescriptor.GetTypeIndex(typeWithStaticBase, needsCompleteType: true); } EmitDebugSections(_definedSymbols); } private protected abstract void CreateEhSections(); partial void PrepareForUnwindInfo() => CreateEhSections(); partial void EmitUnwindInfoForNode(ObjectNode node, Utf8String currentSymbolName, SectionWriter sectionWriter) { if (node is INodeWithCodeInfo nodeWithCodeInfo) { EmitUnwindInfo(sectionWriter, nodeWithCodeInfo, currentSymbolName); } } partial void HandleControlFlowForRelocation(ISymbolNode relocTarget, Utf8String relocSymbolName) { if (relocTarget is IMethodNode or AssemblyStubNode or AddressTakenExternFunctionSymbolNode) { // For now consider all method symbols address taken. // We could restrict this in the future to those that are referenced from // reflection tables, EH tables, were actually address taken in code, or are referenced from vtables. EmitReferencedMethod(relocSymbolName); } } } }