Browse Source

Merge pull request #2679 from fowl2/debugDirectory

pull/2693/head
Siegfried Pammer 3 years ago committed by GitHub
parent
commit
6ff0dd41b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      ILSpy/Metadata/DebugDirectory/CodeViewTreeNode.cs
  2. 62
      ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs
  3. 83
      ILSpy/Metadata/DebugDirectory/PdbChecksumTreeNode.cs
  4. 45
      ILSpy/Metadata/DebugDirectoryTreeNode.cs
  5. 4
      ILSpy/Metadata/DebugMetadataTreeNode.cs
  6. 2
      ILSpy/TreeNodes/AssemblyTreeNode.cs

75
ILSpy/Metadata/DebugDirectory/CodeViewTreeNode.cs

@ -0,0 +1,75 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
sealed class CodeViewTreeNode : ILSpyTreeNode
{
readonly CodeViewDebugDirectoryData entry;
public CodeViewTreeNode(CodeViewDebugDirectoryData entry)
{
this.entry = entry;
}
override public object Text => nameof(DebugDirectoryEntryType.CodeView);
public override object ToolTip => "Associated PDB file description.";
public override object Icon => Images.Literal;
public override bool View(TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var dataGrid = Helpers.PrepareDataGrid(tabPage, this);
dataGrid.ItemsSource = new[] { entry };
tabPage.Content = dataGrid;
return true;
}
sealed class PdbChecksumDebugDirectoryDataEntry
{
readonly CodeViewDebugDirectoryData entry;
public PdbChecksumDebugDirectoryDataEntry(CodeViewDebugDirectoryData entry)
{
this.entry = entry;
}
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, Text.ToString());
language.WriteCommentLine(output, $"GUID: {entry.Guid}");
language.WriteCommentLine(output, $"Age: {entry.Age}");
language.WriteCommentLine(output, $"Path: {entry.Path}");
}
}
}

62
ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs

@ -0,0 +1,62 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
sealed class DebugDirectoryEntryTreeNode : ILSpyTreeNode
{
readonly PEFile module;
readonly PEReader reader;
readonly DebugDirectoryEntry entry;
public DebugDirectoryEntryTreeNode(PEFile module, DebugDirectoryEntry entry)
{
this.module = module;
this.reader = module.Reader;
this.entry = entry;
}
override public object Text => $"{entry.Type}";
public override object Icon => Images.Literal;
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, Text.ToString());
if (entry.DataSize > 0)
{
language.WriteCommentLine(output, $"Raw Data ({entry.DataSize}):");
int dataOffset = module.Reader.IsLoadedImage ? entry.DataRelativeVirtualAddress : entry.DataPointer;
var data = module.Reader.GetEntireImage().GetContent(dataOffset, entry.DataSize);
language.WriteCommentLine(output, data.ToHexString(data.Length));
}
else
{
language.WriteCommentLine(output, $"(no data)");
}
}
}
}

83
ILSpy/Metadata/DebugDirectory/PdbChecksumTreeNode.cs

@ -0,0 +1,83 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
sealed class PdbChecksumTreeNode : ILSpyTreeNode
{
readonly PdbChecksumDebugDirectoryData entry;
public PdbChecksumTreeNode(PdbChecksumDebugDirectoryData entry)
{
this.entry = entry;
}
override public object Text => nameof(DebugDirectoryEntryType.PdbChecksum);
public override object ToolTip
=> "The entry stores a crypto hash of the content of the symbol file the PE/COFF\n"
+ "file was built with. The hash can be used to validate that a given PDB file was\n"
+ "built with the PE/COFF file and not altered in any way. More than one entry can\n"
+ "be present if multiple PDBs were produced during the build of the PE/COFF file\n"
+ "(for example, private and public symbols).";
public override object Icon => Images.Literal;
public override bool View(TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var dataGrid = Helpers.PrepareDataGrid(tabPage, this);
dataGrid.ItemsSource = new[] { new PdbChecksumDebugDirectoryDataEntry(entry) };
tabPage.Content = dataGrid;
return true;
}
sealed class PdbChecksumDebugDirectoryDataEntry
{
readonly PdbChecksumDebugDirectoryData entry;
public PdbChecksumDebugDirectoryDataEntry(PdbChecksumDebugDirectoryData entry)
{
this.entry = entry;
}
public string AlgorithmName => entry.AlgorithmName;
public string Checksum => entry.Checksum.ToHexString(entry.Checksum.Length);
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, Text.ToString());
language.WriteCommentLine(output, $"AlgorithmName: {entry.AlgorithmName}");
language.WriteCommentLine(output, $"Checksum: {entry.Checksum.ToHexString(entry.Checksum.Length)}");
}
}
}

45
ILSpy/Metadata/DebugDirectoryTreeNode.cs

@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
@ -36,6 +38,7 @@ namespace ICSharpCode.ILSpy.Metadata
public DebugDirectoryTreeNode(PEFile module) public DebugDirectoryTreeNode(PEFile module)
{ {
this.module = module; this.module = module;
this.LazyLoading = true;
} }
public override object Text => "Debug Directory"; public override object Text => "Debug Directory";
@ -51,7 +54,10 @@ namespace ICSharpCode.ILSpy.Metadata
var entries = new List<DebugDirectoryEntryView>(); var entries = new List<DebugDirectoryEntryView>();
foreach (var entry in module.Reader.ReadDebugDirectory()) foreach (var entry in module.Reader.ReadDebugDirectory())
{ {
entries.Add(new DebugDirectoryEntryView(entry)); int dataOffset = module.Reader.IsLoadedImage ? entry.DataRelativeVirtualAddress : entry.DataPointer;
var data = module.Reader.GetEntireImage().GetContent(dataOffset, entry.DataSize);
entries.Add(new DebugDirectoryEntryView(entry, data.ToHexString(data.Length)));
} }
dataGrid.ItemsSource = entries.ToArray(); dataGrid.ItemsSource = entries.ToArray();
@ -60,6 +66,37 @@ namespace ICSharpCode.ILSpy.Metadata
return true; return true;
} }
protected override void LoadChildren()
{
foreach (var entry in module.Reader.ReadDebugDirectory())
{
switch (entry.Type)
{
case DebugDirectoryEntryType.CodeView:
var codeViewData = module.Reader.ReadCodeViewDebugDirectoryData(entry);
this.Children.Add(new CodeViewTreeNode(codeViewData));
break;
case DebugDirectoryEntryType.EmbeddedPortablePdb:
var embeddedPortablePdbReader = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry).GetMetadataReader();
this.Children.Add(new DebugMetadataTreeNode(module, isEmbedded: true, provider: embeddedPortablePdbReader));
break;
case DebugDirectoryEntryType.PdbChecksum:
var pdbChecksumData = module.Reader.ReadPdbChecksumDebugDirectoryData(entry);
this.Children.Add(new PdbChecksumTreeNode(pdbChecksumData));
break;
case DebugDirectoryEntryType.Unknown:
case DebugDirectoryEntryType.Coff:
case DebugDirectoryEntryType.Reproducible:
default:
this.Children.Add(new DebugDirectoryEntryTreeNode(module, entry));
break;
}
}
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{ {
language.WriteCommentLine(output, "Data Directories"); language.WriteCommentLine(output, "Data Directories");
@ -67,7 +104,6 @@ namespace ICSharpCode.ILSpy.Metadata
class DebugDirectoryEntryView class DebugDirectoryEntryView
{ {
public int Characteristics { get; set; }
public uint Timestamp { get; set; } public uint Timestamp { get; set; }
public ushort MajorVersion { get; set; } public ushort MajorVersion { get; set; }
public ushort MinorVersion { get; set; } public ushort MinorVersion { get; set; }
@ -75,10 +111,11 @@ namespace ICSharpCode.ILSpy.Metadata
public int SizeOfRawData { get; set; } public int SizeOfRawData { get; set; }
public int AddressOfRawData { get; set; } public int AddressOfRawData { get; set; }
public int PointerToRawData { get; set; } public int PointerToRawData { get; set; }
public string RawData { get; set; }
public DebugDirectoryEntryView(DebugDirectoryEntry entry) public DebugDirectoryEntryView(DebugDirectoryEntry entry, string data)
{ {
this.Characteristics = 0; this.RawData = data;
this.Timestamp = entry.Stamp; this.Timestamp = entry.Stamp;
this.MajorVersion = entry.MajorVersion; this.MajorVersion = entry.MajorVersion;
this.MinorVersion = entry.MinorVersion; this.MinorVersion = entry.MinorVersion;

4
ILSpy/Metadata/DebugMetadataTreeNode.cs

@ -32,14 +32,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
private PEFile module; private PEFile module;
private MetadataReader provider; private MetadataReader provider;
private AssemblyTreeNode assemblyTreeNode;
private bool isEmbedded; private bool isEmbedded;
public DebugMetadataTreeNode(PEFile module, bool isEmbedded, MetadataReader provider, AssemblyTreeNode assemblyTreeNode) public DebugMetadataTreeNode(PEFile module, bool isEmbedded, MetadataReader provider)
{ {
this.module = module; this.module = module;
this.provider = provider; this.provider = provider;
this.assemblyTreeNode = assemblyTreeNode;
this.isEmbedded = isEmbedded; this.isEmbedded = isEmbedded;
this.Text = "Debug Metadata (" + (isEmbedded ? "Embedded" : "From portable PDB") + ")"; this.Text = "Debug Metadata (" + (isEmbedded ? "Embedded" : "From portable PDB") + ")";
this.LazyLoading = true; this.LazyLoading = true;

2
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -210,7 +210,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (debugInfo is PortableDebugInfoProvider ppdb if (debugInfo is PortableDebugInfoProvider ppdb
&& ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader) && ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader)
{ {
this.Children.Add(new Metadata.DebugMetadataTreeNode(module, ppdb.IsEmbedded, reader, this)); this.Children.Add(new Metadata.DebugMetadataTreeNode(module, ppdb.IsEmbedded, reader));
} }
this.Children.Add(new ReferenceFolderTreeNode(module, this)); this.Children.Add(new ReferenceFolderTreeNode(module, this));
if (module.Resources.Any()) if (module.Resources.Any())

Loading…
Cancel
Save