private void PopulateDependenciesInternal(IDictionary <string, FileNode> allFiles, bool preferNativeImage, ILog log, Stack <FileNode> stack) { if (stack == null) { stack = new Stack <FileNode>(); } stack.Push(this); if (dependencies != null) { // re-entrant call indicates a cycle, bail log.LogMessage($"Cycle detected: {String.Join(" -> ", stack)}"); stack.Pop(); return; } dependencies = new HashSet <FileNode>(); try { using (var peReader = new PEReader(new FileStream(SourceFile, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))) { if (peReader.HasMetadata) { var reader = peReader.GetMetadataReader(); var includeDependencies = true; // map of facade handles to enable quickly getting to FileNode without repeatedly looking up by name var facadeHandles = new Dictionary <AssemblyReferenceHandle, FileNode>(); if (IsFullFacade(reader)) { // don't include dependencies in full facades. We'll instead follow their typeforwards and promote the dependencies to the parent. includeDependencies = false; // follow typeforwards in any full facade. followTypeForwards = true; } foreach (var handle in reader.AssemblyReferences) { var reference = reader.GetAssemblyReference(handle); var referenceName = reader.GetString(reference.Name); FileNode referencedFile = TryGetFileForReference(referenceName, allFiles, preferNativeImage); if (referencedFile != null) { if (includeDependencies) { dependencies.Add(referencedFile); } // populate dependencies of child referencedFile.PopulateDependenciesInternal(allFiles, preferNativeImage, log, stack); // if we're following type-forwards out of any dependency make sure to look at typerefs from this assembly. // and populate the type-forwards in the dependency if (referencedFile.followTypeForwards || followTypeForwards) { facadeHandles.Add(handle, referencedFile); } } else { // static dependency that wasn't satisfied, this can happen if folks use // lightup code to guard the static dependency. // this can also happen when referencing a package that isn't implemented // on this platform but don't fail the build here log.LogMessage(LogImportance.Low, $"Could not locate assembly dependency {referenceName} of {SourceFile}."); } } if (followTypeForwards) { // if following typeforwards out of this assembly, capture all type forwards foreach (var exportedTypeHandle in reader.ExportedTypes) { var exportedType = reader.GetExportedType(exportedTypeHandle); if (exportedType.IsForwarder) { var assemblyReferenceHandle = (AssemblyReferenceHandle)exportedType.Implementation; FileNode assemblyReferenceNode; if (facadeHandles.TryGetValue(assemblyReferenceHandle, out assemblyReferenceNode)) { var typeName = exportedType.Namespace.IsNil ? reader.GetString(exportedType.Name) : reader.GetString(exportedType.Namespace) + reader.GetString(exportedType.Name); typeForwards.Add(typeName, assemblyReferenceNode); } } } } else if (facadeHandles.Count > 0) { // if examining type forwards in some dependency, enumerate type-refs // for any that point at a facade assembly. foreach (var typeReferenceHandle in reader.TypeReferences) { var typeReference = reader.GetTypeReference(typeReferenceHandle); var resolutionScope = typeReference.ResolutionScope; if (resolutionScope.Kind == HandleKind.AssemblyReference) { var assemblyReferenceHandle = (AssemblyReferenceHandle)resolutionScope; FileNode assemblyReferenceNode; if (facadeHandles.TryGetValue(assemblyReferenceHandle, out assemblyReferenceNode)) { var typeName = typeReference.Namespace.IsNil ? reader.GetString(typeReference.Name) : reader.GetString(typeReference.Namespace) + reader.GetString(typeReference.Name); FileNode typeForwardedToNode = null; var forwardAssemblies = new Stack <FileNode>(); // while assembly forwarded to is also a facade, add a dependency on the target while (assemblyReferenceNode.followTypeForwards) { if (!assemblyReferenceNode.typeForwards.TryGetValue(typeName, out typeForwardedToNode)) { break; } dependencies.Add(typeForwardedToNode); forwardAssemblies.Push(assemblyReferenceNode); // look at the target in case it is also a facade assemblyReferenceNode = typeForwardedToNode; if (forwardAssemblies.Contains(assemblyReferenceNode)) { // type-forward cycle, bail log.LogMessage($"Cycle detected involving type-forwards: {String.Join(" -> ", forwardAssemblies)}"); break; } } } } } } // examine native module dependencies for (int i = 1, count = reader.GetTableRowCount(TableIndex.ModuleRef); i <= count; i++) { var moduleRef = reader.GetModuleReference(MetadataTokens.ModuleReferenceHandle(i)); var moduleName = reader.GetString(moduleRef.Name); var moduleRefCandidates = new[] { moduleName, moduleName + ".dll", moduleName + ".so", moduleName + ".dylib" }; FileNode referencedNativeFile = null; foreach (var moduleRefCandidate in moduleRefCandidates) { if (allFiles.TryGetValue(moduleRefCandidate, out referencedNativeFile)) { break; } } if (referencedNativeFile != null) { dependencies.Add(referencedNativeFile); } else { // DLLImport that wasn't satisfied } } } } } catch (BadImageFormatException) { // not a PE } // allow for components to specify their dependencies themselves, by placing a file next to their source file. var additionalDependenciesFile = SourceFile + AdditionalDependenciesFileSuffix; if (File.Exists(additionalDependenciesFile)) { foreach (var additionalDependency in File.ReadAllLines(additionalDependenciesFile)) { if (additionalDependency.Length == 0 || additionalDependency[0] == '#') { continue; } FileNode additionalDependencyFile; if (allFiles.TryGetValue(additionalDependency, out additionalDependencyFile)) { dependencies.Add(additionalDependencyFile); } else { log.LogMessage(LogImportance.Low, $"Could not locate explicit dependency {additionalDependency} of {SourceFile} specified in {additionalDependenciesFile}."); } } } stack.Pop(); }
public static int ToResolutionScope(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToResolutionScopeTag(handle.Kind));
public static int ToTypeOrMethodDef(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToTypeOrMethodDefTag(handle.Kind));
public static int ToHasSemantics(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasSemanticsTag(handle.Kind));
public static int ToMemberForwarded(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToMemberForwardedTag(handle.Kind));
public static void VerifyPdb(this CompilationDifference diff, IEnumerable <MethodDefinitionHandle> methodHandles, XElement expectedPdb) { VerifyPdb(diff, methodHandles.Select(h => MetadataTokens.GetToken(h)), expectedPdb); }
public static int ToHasDeclSecurity(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasDeclSecurityTag(handle.Kind));
protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva) { int offset = blob.Offset; if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) { var sp = sequencePoints[nextSequencePointIndex]; if (sp.Offset <= offset) { output.Write("// sequence point: "); if (sp.Offset != offset) { output.Write("!! at " + DisassemblerHelpers.OffsetToString(sp.Offset) + " !!"); } if (sp.IsHidden) { output.WriteLine("hidden"); } else { output.WriteLine($"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.DocumentUrl}"); } nextSequencePointIndex++; } } ILOpCode opCode = ILParser.DecodeOpCode(ref blob); if (opCode.IsDefined()) { WriteRVA(blob, offset + methodRva, opCode); output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true); output.Write(": "); WriteOpCode(opCode); switch (opCode.GetOperandType()) { case OperandType.BrTarget: case OperandType.ShortBrTarget: output.Write(' '); int targetOffset = ILParser.DecodeBranchTarget(ref blob, opCode); output.WriteLocalReference($"IL_{targetOffset:x4}", targetOffset); break; case OperandType.Field: case OperandType.Method: case OperandType.Sig: case OperandType.Type: output.Write(' '); int metadataToken = blob.ReadInt32(); EntityHandle?handle = MetadataTokenHelpers.TryAsEntityHandle(metadataToken); try { handle?.WriteTo(module, output, genericContext); } catch (BadImageFormatException) { handle = null; } WriteMetadataToken(handle, metadataToken, spaceBefore: true); break; case OperandType.Tok: output.Write(' '); metadataToken = blob.ReadInt32(); handle = MetadataTokenHelpers.TryAsEntityHandle(metadataToken); switch (handle?.Kind) { case HandleKind.MemberReference: switch (metadata.GetMemberReference((MemberReferenceHandle)handle).GetKind()) { case MemberReferenceKind.Method: output.Write("method "); break; case MemberReferenceKind.Field: output.Write("field "); break; } break; case HandleKind.FieldDefinition: output.Write("field "); break; case HandleKind.MethodDefinition: output.Write("method "); break; } try { handle?.WriteTo(module, output, genericContext); } catch (BadImageFormatException) { handle = null; } WriteMetadataToken(handle, metadataToken, spaceBefore: true); break; case OperandType.ShortI: output.Write(' '); DisassemblerHelpers.WriteOperand(output, blob.ReadSByte()); break; case OperandType.I: output.Write(' '); DisassemblerHelpers.WriteOperand(output, blob.ReadInt32()); break; case OperandType.I8: output.Write(' '); DisassemblerHelpers.WriteOperand(output, blob.ReadInt64()); break; case OperandType.ShortR: output.Write(' '); DisassemblerHelpers.WriteOperand(output, blob.ReadSingle()); break; case OperandType.R: output.Write(' '); DisassemblerHelpers.WriteOperand(output, blob.ReadDouble()); break; case OperandType.String: metadataToken = blob.ReadInt32(); output.Write(' '); UserStringHandle?userString; string text; try { userString = MetadataTokens.UserStringHandle(metadataToken); text = metadata.GetUserString(userString.Value); } catch (BadImageFormatException) { userString = null; text = null; } if (userString != null) { DisassemblerHelpers.WriteOperand(output, text); } WriteMetadataToken(userString, metadataToken, spaceBefore: true); break; case OperandType.Switch: var tmp = blob; int[] targets = ILParser.DecodeSwitchTargets(ref blob); if (ShowRawRVAOffsetAndBytes) { output.WriteLine(" ("); } else { output.Write(" ("); } tmp.ReadInt32(); for (int i = 0; i < targets.Length; i++) { if (i > 0) { if (ShowRawRVAOffsetAndBytes) { output.WriteLine(","); } else { output.Write(", "); } } if (ShowRawRVAOffsetAndBytes) { output.Write("/* "); output.Write($"{tmp.ReadByte():X2}{tmp.ReadByte():X2}{tmp.ReadByte():X2}{tmp.ReadByte():X2}"); output.Write(" */ "); } if (ShowRawRVAOffsetAndBytes) { output.Write(" "); } output.WriteLocalReference($"IL_{targets[i]:x4}", targets[i]); } output.Write(")"); break; case OperandType.Variable: output.Write(' '); int index = blob.ReadUInt16(); if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc) { DisassemblerHelpers.WriteVariableReference(output, metadata, methodHandle, index); } else { DisassemblerHelpers.WriteParameterReference(output, metadata, methodHandle, index); } break; case OperandType.ShortVariable: output.Write(' '); index = blob.ReadByte(); if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s) { DisassemblerHelpers.WriteVariableReference(output, metadata, methodHandle, index); } else { DisassemblerHelpers.WriteParameterReference(output, metadata, methodHandle, index); } break; } } else { ushort opCodeValue = (ushort)opCode; if (opCodeValue > 0xFF) { if (ShowRawRVAOffsetAndBytes) { output.Write("/* "); output.Write($"0x{offset + methodRva:X8} {(ushort)opCode >> 8:X2}"); output.Write(" */ "); } output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true); output.Write(": "); // split 16-bit value into two emitbyte directives output.WriteLine($".emitbyte 0x{(byte)(opCodeValue >> 8):x}"); if (ShowRawRVAOffsetAndBytes) { output.Write("/* "); output.Write($"0x{offset + methodRva + 1:X8} {(ushort)opCode & 0xFF:X2}"); output.Write(" */ "); } // add label output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset + 1), offset + 1, isDefinition: true); output.Write(": "); output.Write($".emitbyte 0x{(byte)(opCodeValue & 0xFF):x}"); } else { if (ShowRawRVAOffsetAndBytes) { output.Write("/* "); output.Write($"0x{offset + methodRva:X8} {(ushort)opCode & 0xFF:X2}"); output.Write(" */ "); } output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true); output.Write(": "); output.Write($".emitbyte 0x{(byte)opCodeValue:x}"); } } output.WriteLine(); }
private void WriteMetadataToken(EntityHandle handle, bool spaceBefore) { WriteMetadataToken(handle, MetadataTokens.GetToken(handle), spaceBefore); }
/// <summary> /// Read the EH clause from a given file offset in the PE image. /// </summary> /// <param name="reader">R2R image reader<param> /// <param name="offset">Offset of the EH clause in the image</param> public EHClause(ReadyToRunReader reader, int offset) { Flags = (CorExceptionFlag)BitConverter.ToUInt32(reader.Image, offset + 0 * sizeof(uint)); TryOffset = BitConverter.ToUInt32(reader.Image, offset + 1 * sizeof(uint)); TryEnd = BitConverter.ToUInt32(reader.Image, offset + 2 * sizeof(uint)); HandlerOffset = BitConverter.ToUInt32(reader.Image, offset + 3 * sizeof(uint)); HandlerEnd = BitConverter.ToUInt32(reader.Image, offset + 4 * sizeof(uint)); ClassTokenOrFilterOffset = BitConverter.ToUInt32(reader.Image, offset + 5 * sizeof(uint)); if ((Flags & CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_KIND_MASK) == CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_NONE) { ClassName = MetadataNameFormatter.FormatHandle(reader.MetadataReader, MetadataTokens.Handle((int)ClassTokenOrFilterOffset)); } }
internal override void DumpSectionContents(ReadyToRunSection section) { switch (section.Type) { case ReadyToRunSectionType.AvailableTypes: if (!_options.Naked) { uint availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); NativeParser availableTypesParser = new NativeParser(_r2r.Image, availableTypesSectionOffset); NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); _writer.WriteLine(availableTypes.ToString()); } int assemblyIndex1 = _r2r.GetAssemblyIndex(section); if (assemblyIndex1 != -1) { _writer.WriteLine(); foreach (string name in _r2r.ReadyToRunAssemblies[assemblyIndex1].AvailableTypes) { _writer.WriteLine(name); } } break; case ReadyToRunSectionType.MethodDefEntryPoints: if (!_options.Naked) { NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); _writer.Write(methodEntryPoints.ToString()); } int assemblyIndex2 = _r2r.GetAssemblyIndex(section); if (assemblyIndex2 != -1) { _writer.WriteLine(); foreach (ReadyToRunMethod method in _r2r.ReadyToRunAssemblies[assemblyIndex2].Methods) { _writer.WriteLine($@"{MetadataTokens.GetToken(method.MethodHandle):X8}: {method.SignatureString}"); } } break; case ReadyToRunSectionType.InstanceMethodEntryPoints: if (!_options.Naked) { uint instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); NativeParser instanceParser = new NativeParser(_r2r.Image, instanceSectionOffset); NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size)); _writer.Write(instMethodEntryPoints.ToString()); _writer.WriteLine(); } foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods) { _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}"); } break; case ReadyToRunSectionType.RuntimeFunctions: int rtfOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int rtfEndOffset = rtfOffset + section.Size; int rtfIndex = 0; _writer.WriteLine(" Index | StartRVA | EndRVA | UnwindRVA"); _writer.WriteLine("-----------------------------------------"); while (rtfOffset < rtfEndOffset) { int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); int endRva = -1; if (_r2r.Machine == Machine.Amd64) { endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); } int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); string endRvaText = (endRva != -1 ? endRva.ToString("x8") : " "); _writer.WriteLine($"{rtfIndex,7} | {startRva:X8} | {endRvaText} | {unwindRva:X8}"); rtfIndex++; } break; case ReadyToRunSectionType.CompilerIdentifier: _writer.WriteLine(_r2r.CompilerIdentifier); break; case ReadyToRunSectionType.ImportSections: if (_options.Naked) { DumpNakedImportSections(); } else { foreach (ReadyToRunImportSection importSection in _r2r.ImportSections) { importSection.WriteTo(_writer); if (_options.Raw && importSection.Entries.Count != 0) { if (importSection.SectionRVA != 0) { _writer.WriteLine("Section Bytes:"); DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize); } if (importSection.SignatureRVA != 0) { _writer.WriteLine("Signature Bytes:"); DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int)); } if (importSection.AuxiliaryDataRVA != 0 && importSection.AuxiliaryDataSize != 0) { _writer.WriteLine("AuxiliaryData Bytes:"); DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize); } } foreach (ReadyToRunImportSection.ImportSectionEntry entry in importSection.Entries) { entry.WriteTo(_writer, _options); _writer.WriteLine(); } _writer.WriteLine(); } } break; case ReadyToRunSectionType.ManifestMetadata: int assemblyRefCount = 0; if (!_r2r.Composite) { MetadataReader globalReader = _r2r.GetGlobalMetadata().MetadataReader; assemblyRefCount = globalReader.GetTableRowCount(TableIndex.AssemblyRef) + 1; _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):"); for (int assemblyRefIndex = 1; assemblyRefIndex < assemblyRefCount; assemblyRefIndex++) { AssemblyReference assemblyRef = globalReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex)); string assemblyRefName = globalReader.GetString(assemblyRef.Name); _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}"); } } _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count} entries):"); int manifestAsmIndex = 0; foreach (string manifestReferenceAssembly in _r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key)) { _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 1:X2}]: {manifestReferenceAssembly}"); manifestAsmIndex++; } break; case ReadyToRunSectionType.AttributePresence: int attributesStartOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int attributesEndOffset = attributesStartOffset + section.Size; NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset); _writer.WriteLine("Attribute presence filter"); _writer.WriteLine(attributes.ToString()); break; case ReadyToRunSectionType.InliningInfo: int iiOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int iiEndOffset = iiOffset + section.Size; InliningInfoSection inliningInfoSection = new InliningInfoSection(_r2r, iiOffset, iiEndOffset); _writer.WriteLine(inliningInfoSection.ToString()); break; case ReadyToRunSectionType.InliningInfo2: int ii2Offset = _r2r.GetOffset(section.RelativeVirtualAddress); int ii2EndOffset = ii2Offset + section.Size; InliningInfoSection2 inliningInfoSection2 = new InliningInfoSection2(_r2r, ii2Offset, ii2EndOffset); _writer.WriteLine(inliningInfoSection2.ToString()); break; case ReadyToRunSectionType.OwnerCompositeExecutable: int oceOffset = _r2r.GetOffset(section.RelativeVirtualAddress); if (_r2r.Image[oceOffset + section.Size - 1] != 0) { R2RDump.WriteWarning("String is not zero-terminated"); } string ownerCompositeExecutable = Encoding.UTF8.GetString(_r2r.Image, oceOffset, section.Size - 1); // exclude the zero terminator _writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable.ToEscapedString()); break; case ReadyToRunSectionType.ManifestAssemblyMvids: int mvidCount = section.Size / ReadyToRunReader.GuidByteSize; for (int mvidIndex = 0; mvidIndex < mvidCount; mvidIndex++) { _writer.WriteLine("MVID[{0}] = {1:b}", mvidIndex, _r2r.GetAssemblyMvid(mvidIndex)); } break; default: _writer.WriteLine("Unsupported section type {0}", section.Type); break; } }
public unsafe ClassLayout(byte *ptr, int typeDefSize) { PackingSize = (ushort)Helpers.GetValue(ptr, 2); ClassSize = (uint)Helpers.GetValue(ptr + 2, 4); Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + 6, typeDefSize)); }
internal static PENamedTypeSymbol GetType(this CSharpCompilation compilation, Guid moduleVersionId, int typeToken) { return(GetType(compilation.GetModule(moduleVersionId), (TypeDefinitionHandle)MetadataTokens.Handle(typeToken))); }
internal static bool WritePeToStream( EmitContext context, CommonMessageProvider messageProvider, Func <Stream> getPeStream, Func <Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, string pdbPathOpt, bool metadataOnly, bool isDeterministic, bool emitTestCoverageData, RSAParameters?privateKeyOpt, CancellationToken cancellationToken) { // If PDB writer is given, we have to have PDB path. Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null); var mdWriter = FullMetadataWriter.Create(context, messageProvider, metadataOnly, isDeterministic, emitTestCoverageData, getPortablePdbStreamOpt != null, cancellationToken); var properties = context.Module.SerializationProperties; nativePdbWriterOpt?.SetMetadataEmitter(mdWriter); // Since we are producing a full assembly, we should not have a module version ID // imposed ahead-of time. Instead we will compute a deterministic module version ID // based on the contents of the generated stream. Debug.Assert(properties.PersistentIdentifier == default(Guid)); var ilBuilder = new BlobBuilder(32 * 1024); var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceBuilder = new BlobBuilder(1024); Blob mvidFixup, mvidStringFixup; mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out mvidFixup, out mvidStringFixup); MethodDefinitionHandle entryPointHandle; MethodDefinitionHandle debugEntryPointHandle; mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle); if (!debugEntryPointHandle.IsNil) { nativePdbWriterOpt?.SetEntryPoint(MetadataTokens.GetToken(debugEntryPointHandle)); } if (nativePdbWriterOpt != null) { if (context.Module.SourceLinkStreamOpt != null) { nativePdbWriterOpt.EmbedSourceLink(context.Module.SourceLinkStreamOpt); } if (mdWriter.Module.OutputKind == OutputKind.WindowsRuntimeMetadata) { // Dev12: If compiling to winmdobj, we need to add to PDB source spans of // all types and members for better error reporting by WinMDExp. nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap()); } else { #if DEBUG // validate that all definitions are writable // if same scenario would happen in an winmdobj project nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap()); #endif } nativePdbWriterOpt.WriteRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); } Stream peStream = getPeStream(); if (peStream == null) { return(false); } BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default; // the writer shall not be used after this point for writing: nativePdbWriterOpt = null; ushort portablePdbVersion = 0; var metadataRootBuilder = mdWriter.GetRootBuilder(); var peHeaderBuilder = new PEHeaderBuilder( machine: properties.Machine, sectionAlignment: properties.SectionAlignment, fileAlignment: properties.FileAlignment, imageBase: properties.BaseAddress, majorLinkerVersion: properties.LinkerMajorVersion, minorLinkerVersion: properties.LinkerMinorVersion, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: properties.MajorSubsystemVersion, minorSubsystemVersion: properties.MinorSubsystemVersion, subsystem: properties.Subsystem, dllCharacteristics: properties.DllCharacteristics, imageCharacteristics: properties.ImageCharacteristics, sizeOfStackReserve: properties.SizeOfStackReserve, sizeOfStackCommit: properties.SizeOfStackCommit, sizeOfHeapReserve: properties.SizeOfHeapReserve, sizeOfHeapCommit: properties.SizeOfHeapCommit); var peIdProvider = isDeterministic ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content))) : null; // We need to calculate the PDB checksum, so we may as well use the calculated hash for PDB ID regardless of whether deterministic build is requested. var portablePdbContentHash = default(ImmutableArray <byte>); BlobBuilder portablePdbToEmbed = null; if (mdWriter.EmitPortableDebugMetadata) { mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); // The algorithm must be specified for deterministic builds (checked earlier). Debug.Assert(!isDeterministic || context.Module.PdbChecksumAlgorithm.Name != null); var portablePdbIdProvider = (context.Module.PdbChecksumAlgorithm.Name != null) ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(portablePdbContentHash = CryptographicHashProvider.ComputeHash(context.Module.PdbChecksumAlgorithm, content))) : null; var portablePdbBlob = new BlobBuilder(); var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, debugEntryPointHandle, portablePdbIdProvider); pdbContentId = portablePdbBuilder.Serialize(portablePdbBlob); portablePdbVersion = portablePdbBuilder.FormatVersion; if (getPortablePdbStreamOpt == null) { // embed to debug directory: portablePdbToEmbed = portablePdbBlob; } else { // write to Portable PDB stream: Stream portablePdbStream = getPortablePdbStreamOpt(); if (portablePdbStream != null) { try { portablePdbBlob.WriteContentTo(portablePdbStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new SymUnmanagedWriterException(e.Message, e); } } } } DebugDirectoryBuilder debugDirectoryBuilder; if (pdbPathOpt != null || isDeterministic || portablePdbToEmbed != null) { debugDirectoryBuilder = new DebugDirectoryBuilder(); if (pdbPathOpt != null) { string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt); debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion); if (!portablePdbContentHash.IsDefault) { // Emit PDB Checksum entry for Portable and Embedded PDBs. The checksum is not as useful when the PDB is embedded, // however it allows the client to efficiently validate a standalone Portable PDB that // has been extracted from Embedded PDB and placed next to the PE file. debugDirectoryBuilder.AddPdbChecksumEntry(context.Module.PdbChecksumAlgorithm.Name, portablePdbContentHash); } } if (isDeterministic) { debugDirectoryBuilder.AddReproducibleEntry(); } if (portablePdbToEmbed != null) { debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion); } } else { debugDirectoryBuilder = null; } var strongNameProvider = context.Module.CommonCompilation.Options.StrongNameProvider; var corFlags = properties.CorFlags; var peBuilder = new ExtendedPEBuilder( peHeaderBuilder, metadataRootBuilder, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), debugDirectoryBuilder, CalculateStrongNameSignatureSize(context.Module, privateKeyOpt), entryPointHandle, corFlags, peIdProvider, metadataOnly && !context.IncludePrivateMembers); var peBlob = new BlobBuilder(); var peContentId = peBuilder.Serialize(peBlob, out Blob mvidSectionFixup); PatchModuleVersionIds(mvidFixup, mvidSectionFixup, mvidStringFixup, peContentId.Guid); if (privateKeyOpt != null && corFlags.HasFlag(CorFlags.StrongNameSigned)) { strongNameProvider.SignBuilder(peBuilder, peBlob, privateKeyOpt.Value); } try { peBlob.WriteContentTo(peStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new PeWritingException(e); } return(true); }
public static byte[] GetCustomDebugInfoBytes(ISymUnmanagedReader3 reader, MethodDefinitionHandle handle, int methodVersion) { return(reader.GetCustomDebugInfoBytes(MetadataTokens.GetToken(handle), methodVersion)); }
public virtual void Disassemble(PEFile module, MethodDefinitionHandle handle) { this.module = module ?? throw new ArgumentNullException(nameof(module)); metadata = module.Metadata; genericContext = new MetadataGenericContext(handle, module); signatureDecoder = new DisassemblerSignatureTypeProvider(module, output); var methodDefinition = metadata.GetMethodDefinition(handle); // start writing IL code output.WriteLine("// Method begins at RVA 0x{0:x4}", methodDefinition.RelativeVirtualAddress); if (methodDefinition.RelativeVirtualAddress == 0) { output.WriteLine("// Header size: {0}", 0); output.WriteLine("// Code size: {0} (0x{0:x})", 0); output.WriteLine(".maxstack {0}", 0); output.WriteLine(); return; } MethodBodyBlock body; BlobReader bodyBlockReader; try { body = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); bodyBlockReader = module.Reader.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader(); } catch (BadImageFormatException ex) { output.WriteLine("// {0}", ex.Message); return; } var blob = body.GetILReader(); int headerSize = ILParser.GetHeaderSize(bodyBlockReader); output.WriteLine("// Header size: {0}", headerSize); output.WriteLine("// Code size: {0} (0x{0:x})", blob.Length); output.WriteLine(".maxstack {0}", body.MaxStack); var entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress); if (handle == entrypointHandle) { output.WriteLine(".entrypoint"); } DisassembleLocalsBlock(handle, body); output.WriteLine(); sequencePoints = DebugInfo?.GetSequencePoints(handle) ?? EmptyList <DebugInfo.SequencePoint> .Instance; nextSequencePointIndex = 0; if (DetectControlStructure && blob.Length > 0) { blob.Reset(); HashSet <int> branchTargets = GetBranchTargets(blob); blob.Reset(); WriteStructureBody(new ILStructure(module, handle, genericContext, body), branchTargets, ref blob, methodDefinition.RelativeVirtualAddress + headerSize); } else { while (blob.RemainingBytes > 0) { cancellationToken.ThrowIfCancellationRequested(); WriteInstruction(output, metadata, handle, ref blob, methodDefinition.RelativeVirtualAddress); } WriteExceptionHandlers(module, handle, body); } sequencePoints = null; }
/// <summary> /// Find a method given its metadata token. This method is used for debugging support. /// </summary> /// <param name="mdMethodToken">Method metadata token.</param> /// <returns></returns> public ImportedMethod GetMethod(int mdToken) { MethodDefinitionHandle methodHandle = (MethodDefinitionHandle)MetadataTokens.EntityHandle(mdToken); return(ResolveMethod(methodHandle)); }
public void VerifyUpdatedMethods(params string[] expectedMethodTokens) { AssertEx.Equal( expectedMethodTokens, UpdatedMethods.Select(methodHandle => $"0x{MetadataTokens.GetToken(methodHandle):X8}")); }
public static int ToCustomAttributeType(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToCustomAttributeTypeTag(handle.Kind));
internal void VerifyIL( string qualifiedMethodName, string expectedIL, Func <Cci.ILocalDefinition, ILVisualizer.LocalInfo> mapLocal = null, MethodDefinitionHandle methodToken = default, [CallerFilePath] string callerPath = null, [CallerLineNumber] int callerLine = 0) { var ilBuilder = TestData.GetMethodData(qualifiedMethodName).ILBuilder; Dictionary <int, string> sequencePointMarkers = null; if (!methodToken.IsNil) { string actualPdb = PdbToXmlConverter.DeltaPdbToXml(new ImmutableMemoryStream(PdbDelta), new[] { MetadataTokens.GetToken(methodToken) }); sequencePointMarkers = ILValidation.GetSequencePointMarkers(actualPdb); Assert.True(sequencePointMarkers.Count > 0, $"No sequence points found in:{Environment.NewLine}{actualPdb}"); } string actualIL = ILBuilderVisualizer.ILBuilderToString(ilBuilder, mapLocal ?? ToLocalInfo, sequencePointMarkers); AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL, escapeQuotes: true, expectedValueSourcePath: callerPath, expectedValueSourceLine: callerLine); }
public static int ToHasFieldMarshal(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasFieldMarshalTag(handle.Kind));
/// <summary> /// Helper method to return all async methods stepping information. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="asyncInfo">array with all async methods stepping information</param> /// <param name="asyncInfoCount">entry's count in asyncInfo</param> internal static void GetAsyncMethodsSteppingInfo(IntPtr symbolReaderHandle, out IntPtr asyncInfo, out int asyncInfoCount) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); asyncInfo = IntPtr.Zero; asyncInfoCount = 0; var list = new List <AsyncAwaitInfoBlock>(); GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; // Guid is taken from Roslyn source code: // https://github.com/dotnet/roslyn/blob/afd10305a37c0ffb2cfb2c2d8446154c68cfa87a/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs#L13 Guid asyncMethodSteppingInformationBlob = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8"); foreach (MethodDebugInformationHandle methodDebugInformationHandle in reader.MethodDebugInformation) { var entityHandle = MetadataTokens.EntityHandle(MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle())); foreach (var cdiHandle in reader.GetCustomDebugInformation(entityHandle)) { var cdi = reader.GetCustomDebugInformation(cdiHandle); if (reader.GetGuid(cdi.Kind) == asyncMethodSteppingInformationBlob) { // Format of this blob is taken from Roslyn source code: // https://github.com/dotnet/roslyn/blob/afd10305a37c0ffb2cfb2c2d8446154c68cfa87a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs#L575 var blobReader = reader.GetBlobReader(cdi.Value); var catchHandlerOffset = blobReader.ReadUInt32(); while (blobReader.Offset < blobReader.Length) { list.Add(new AsyncAwaitInfoBlock() { catch_handler_offset = catchHandlerOffset, yield_offset = blobReader.ReadUInt32(), resume_offset = blobReader.ReadUInt32(), // explicit conversion from int into uint here, see: // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.metadata.blobreader.readcompressedinteger token = (uint)blobReader.ReadCompressedInteger() }); } } } } if (list.Count == 0) { return; } var structSize = Marshal.SizeOf <AsyncAwaitInfoBlock>(); IntPtr allInfo = Marshal.AllocCoTaskMem(list.Count * structSize); var currentPtr = allInfo; foreach (var p in list) { Marshal.StructureToPtr(p, currentPtr, false); currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize); } asyncInfo = allInfo; asyncInfoCount = list.Count; }
public static int ToImplementation(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToImplementationTag(handle.Kind));
/// <summary> /// Returns source line number and source file name for given IL offset and method token. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="methodToken">method token</param> /// <param name="ilOffset">IL offset</param> /// <param name="sequencePoint">sequence point return</param> /// <returns> true if information is available</returns> private static bool GetSequencePointByILOffset(IntPtr symbolReaderHandle, int methodToken, long ilOffset, out DbgSequencePoint sequencePoint) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); sequencePoint.document = IntPtr.Zero; sequencePoint.startLine = 0; sequencePoint.startColumn = 0; sequencePoint.endLine = 0; sequencePoint.endColumn = 0; sequencePoint.offset = 0; try { GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current; bool found = false; foreach (SequencePoint point in sequencePoints) { if (found && point.Offset > ilOffset) { break; } if (!point.IsHidden) { nearestPoint = point; found = true; } } if (!found || nearestPoint.StartLine == 0) { return(false); } var fileName = reader.GetString(reader.GetDocument(nearestPoint.Document).Name); sequencePoint.document = Marshal.StringToBSTR(fileName); sequencePoint.startLine = nearestPoint.StartLine; sequencePoint.startColumn = nearestPoint.StartColumn; sequencePoint.endLine = nearestPoint.EndLine; sequencePoint.endColumn = nearestPoint.EndColumn; sequencePoint.offset = nearestPoint.Offset; fileName = null; return(true); } catch { } return(false); }
public static int ToMemberRefParent(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToMemberRefParentTag(handle.Kind));
internal static bool GetSequencePoints(IntPtr symbolReaderHandle, int methodToken, out IntPtr points, out int pointsCount) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); var list = new List <DbgSequencePoint>(); pointsCount = 0; points = IntPtr.Zero; GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint p in sequencePoints) { string fileName = reader.GetString(reader.GetDocument(p.Document).Name); list.Add(new DbgSequencePoint() { document = Marshal.StringToBSTR(fileName), startLine = p.StartLine, endLine = p.EndLine, startColumn = p.StartColumn, endColumn = p.EndColumn, offset = p.Offset }); } if (list.Count == 0) { return(true); } var structSize = Marshal.SizeOf <DbgSequencePoint>(); IntPtr allPoints = Marshal.AllocCoTaskMem(list.Count * structSize); var currentPtr = allPoints; foreach (var p in list) { Marshal.StructureToPtr(p, currentPtr, false); currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize); } points = allPoints; pointsCount = list.Count; return(true); } catch { foreach (var p in list) { Marshal.FreeBSTR(p.document); } } return(false); }
public static int ToTypeDefOrRefOrSpec(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToTypeDefOrRefOrSpecTag(handle.Kind));
internal static bool GetStepRangesFromIP(IntPtr symbolReaderHandle, int ip, int methodToken, out uint ilStartOffset, out uint ilEndOffset) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); ilStartOffset = 0; ilEndOffset = 0; Debug.Assert(symbolReaderHandle != IntPtr.Zero); GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); var list = new List <SequencePoint>(); foreach (SequencePoint p in sequencePoints) { list.Add(p); } var pointsArray = list.ToArray(); for (int i = 1; i < pointsArray.Length; i++) { SequencePoint p = pointsArray[i]; if (p.Offset > ip && p.StartLine != 0 && p.StartLine != SequencePoint.HiddenLine) { ilStartOffset = (uint)pointsArray[0].Offset; for (int j = i - 1; j > 0; j--) { if (pointsArray[j].Offset <= ip) { ilStartOffset = (uint)pointsArray[j].Offset; break; } } ilEndOffset = (uint)p.Offset; return(true); } } // let's handle correctly last step range from last sequence point till // end of the method. if (pointsArray.Length > 0) { ilStartOffset = (uint)pointsArray[0].Offset; for (int j = pointsArray.Length - 1; j > 0; j--) { if (pointsArray[j].Offset <= ip) { ilStartOffset = (uint)pointsArray[j].Offset; break; } } ilEndOffset = ilStartOffset; // Should set this to IL code size in calling code return(true); } } catch { } return(false); }
public static int ToHasCustomDebugInformation(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasCustomDebugInformationTag(handle.Kind));
internal override void DumpSectionContents(R2RSection section, XmlNode parentNode = null) { switch (section.Type) { case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES: if (!_options.Naked) { uint availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); NativeParser availableTypesParser = new NativeParser(_r2r.Image, availableTypesSectionOffset); NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); _writer.WriteLine(availableTypes.ToString()); } foreach (string name in _r2r.AvailableTypes) { _writer.WriteLine(name); } break; case R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS: if (!_options.Naked) { NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); _writer.Write(methodEntryPoints.ToString()); } break; case R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS: if (!_options.Naked) { uint instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); NativeParser instanceParser = new NativeParser(_r2r.Image, instanceSectionOffset); NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size)); _writer.Write(instMethodEntryPoints.ToString()); _writer.WriteLine(); } foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods) { _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}"); } break; case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS: int rtfOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int rtfEndOffset = rtfOffset + section.Size; int rtfIndex = 0; while (rtfOffset < rtfEndOffset) { int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); int endRva = -1; if (_r2r.Machine == Machine.Amd64) { endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); } int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); _writer.WriteLine($"Index: {rtfIndex}"); _writer.WriteLine($"\tStartRva: 0x{startRva:X8}"); if (endRva != -1) { _writer.WriteLine($"\tEndRva: 0x{endRva:X8}"); } _writer.WriteLine($"\tUnwindRva: 0x{unwindRva:X8}"); rtfIndex++; } break; case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER: _writer.WriteLine(_r2r.CompilerIdentifier); break; case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS: if (_options.Naked) { DumpNakedImportSections(); } else { foreach (R2RImportSection importSection in _r2r.ImportSections) { importSection.WriteTo(_writer); if (_options.Raw && importSection.Entries.Count != 0) { if (importSection.SectionRVA != 0) { _writer.WriteLine("Section Bytes:"); DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize); } if (importSection.SignatureRVA != 0) { _writer.WriteLine("Signature Bytes:"); DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int)); } if (importSection.AuxiliaryDataRVA != 0 && importSection.AuxiliaryDataSize != 0) { _writer.WriteLine("AuxiliaryData Bytes:"); DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize); } } foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries) { entry.WriteTo(_writer, _options); _writer.WriteLine(); } _writer.WriteLine(); } } break; case R2RSection.SectionType.READYTORUN_SECTION_MANIFEST_METADATA: int assemblyRefCount = _r2r.MetadataReader.GetTableRowCount(TableIndex.AssemblyRef); _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):"); for (int assemblyRefIndex = 1; assemblyRefIndex <= assemblyRefCount; assemblyRefIndex++) { AssemblyReference assemblyRef = _r2r.MetadataReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex)); string assemblyRefName = _r2r.MetadataReader.GetString(assemblyRef.Name); _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}"); } _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count} entries):"); for (int manifestAsmIndex = 0; manifestAsmIndex < _r2r.ManifestReferenceAssemblies.Count; manifestAsmIndex++) { _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 2:X2}]: {_r2r.ManifestReferenceAssemblies[manifestAsmIndex]}"); } break; case R2RSection.SectionType.READYTORUN_SECTION_ATTRIBUTEPRESENCE: int attributesStartOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int attributesEndOffset = attributesStartOffset + section.Size; NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset); _writer.WriteLine("Attribute presence filter"); _writer.WriteLine(attributes.ToString()); break; } }