Browse Source

Ignore document checksum and blob length in PdbGenerationTestRunner

pull/1440/head
Siegfried Pammer 6 years ago
parent
commit
b4c376d195
  1. 2
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 45
      ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs
  3. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/.gitignore
  4. 23
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml
  5. 32
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

2
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -356,7 +356,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -356,7 +356,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
foreach (KeyValuePair<string, string> file in sourceFiles) {
var sourceText = SourceText.From(file.Value, Encoding.UTF8);
var sourceText = SourceText.From(file.Value, new UTF8Encoding(false), SourceHashAlgorithm.Sha256);
syntaxTrees.Add(SyntaxFactory.ParseSyntaxTree(sourceText, parseOptions, file.Key));
embeddedTexts.Add(EmbeddedText.FromSource(file.Key, sourceText));
}

45
ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs

@ -4,6 +4,7 @@ using System.IO; @@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml.Linq;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
@ -22,7 +23,8 @@ namespace ICSharpCode.Decompiler.Tests @@ -22,7 +23,8 @@ namespace ICSharpCode.Decompiler.Tests
{
static readonly string TestCasePath = Tester.TestCasePath + "/PdbGen";
[Test, Ignore("Needs adjustments in generator")]
[Test]
[Ignore("Needs adjustments in generator")]
public void HelloWorld()
{
TestGeneratePdb();
@ -44,11 +46,46 @@ namespace ICSharpCode.Decompiler.Tests @@ -44,11 +46,46 @@ namespace ICSharpCode.Decompiler.Tests
var resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
var decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());
using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, testName + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream);
pdbStream.SetLength(0);
PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true);
pdbStream.Position = 0;
string resultFile = PdbToXmlConverter.ToXml(pdbStream, moduleDefinition.Reader.GetEntireImage().GetContent().ToArray(), options);
Assert.AreEqual(xmlContent, resultFile);
using (Stream peStream = File.OpenRead(peFileName))
using (Stream expectedPdbStream = File.OpenRead(pdbFileName)) {
using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(pdbFileName, ".xml"), false, Encoding.UTF8)) {
PdbToXmlConverter.ToXml(writer, expectedPdbStream, peStream, options);
}
peStream.Position = 0;
using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(xmlFile, ".generated.xml"), false, Encoding.UTF8)) {
PdbToXmlConverter.ToXml(writer, pdbStream, peStream, options);
}
}
}
ProcessXmlFile(Path.ChangeExtension(pdbFileName, ".xml"));
ProcessXmlFile(Path.ChangeExtension(xmlFile, ".generated.xml"));
Assert.AreEqual(File.ReadAllText(xmlFile), File.ReadAllText(Path.ChangeExtension(xmlFile, ".generated.xml")));
}
private void ProcessXmlFile(string v)
{
var document = XDocument.Load(v);
foreach (var file in document.Descendants("file")) {
file.Attribute("checksum").Remove();
file.Attribute("embeddedSourceLength").Remove();
file.ReplaceNodes(new XCData(file.Value.Replace("\uFEFF", "")));
}
document.Save(v, SaveOptions.None);
}
}
class StringWriterWithEncoding : StringWriter
{
readonly Encoding encoding;
public StringWriterWithEncoding(Encoding encoding)
{
this.encoding = encoding ?? throw new ArgumentNullException("encoding");
}
public override Encoding Encoding => encoding;
}
}

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/.gitignore vendored

@ -1,2 +1,4 @@ @@ -1,2 +1,4 @@
/*.dll
/*.pdb
/*.expected.xml
/*.generated.xml

23
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml

@ -1,33 +1,38 @@ @@ -1,33 +1,38 @@
<?xml version="1.0" encoding="utf-16"?>
<?xml version="1.0" encoding="utf-8"?>
<symbols>
<files>
<file id="1" name="HelloWorld.cs" language="C#" checksumAlgorithm="SHA1" checksum="80-99-0D-B3-EA-B0-A3-72-39-A0-C5-FB-17-13-1B-CC-BF-3D-4C-AA" embeddedSourceLength="200"><![CDATA[using System;
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\HelloWorld.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen
{
public class HelloWorld
{
public static void Hello()
public static void Main(string[] args)
{
Console.ReadKey();
Console.WriteLine("Hello World!");
Console.ReadKey();
}
}
}
]]></file>
</files>
<methods>
<method containingType="ICSharpCode.Decompiler.Tests.TestCases.PdbGen.HelloWorld" name="Hello" token="0x6000001">
<method containingType="ICSharpCode.Decompiler.Tests.TestCases.PdbGen.HelloWorld" name="Main" parameterNames="args" token="0x6000001">
<sequencePoints>
<entry offset="0x0" startLine="8" startColumn="3" endLine="8" endColumn="4" document="1" />
<entry offset="0x1" startLine="9" startColumn="4" endLine="9" endColumn="38" document="1" />
<entry offset="0xc" startLine="10" startColumn="3" endLine="10" endColumn="4" document="1" />
<entry offset="0x1" startLine="9" startColumn="4" endLine="9" endColumn="22" document="1" />
<entry offset="0x7" startLine="10" startColumn="4" endLine="10" endColumn="38" document="1" />
<entry offset="0x12" startLine="11" startColumn="4" endLine="11" endColumn="22" document="1" />
<entry offset="0x18" startLine="12" startColumn="3" endLine="12" endColumn="4" document="1" />
</sequencePoints>
<scope startOffset="0x0" endOffset="0xd" />
<scope startOffset="0x0" endOffset="0x19" />
</method>
</methods>
<method-spans>
<method declaringType="ICSharpCode.Decompiler.Tests.TestCases.PdbGen.HelloWorld" methodName="Hello" token="0x6000001">
<document startLine="8" endLine="10" />
<method declaringType="ICSharpCode.Decompiler.Tests.TestCases.PdbGen.HelloWorld" methodName="Main" parameterNames="args" token="0x6000001">
<document startLine="8" endLine="12" />
</method>
</method-spans>
</symbols>

32
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -47,19 +48,19 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -47,19 +48,19 @@ namespace ICSharpCode.Decompiler.DebugInfo
public static readonly Guid HashAlgorithmSHA1 = new Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460");
public static readonly Guid HashAlgorithmSHA256 = new Guid("8829d00f-11b8-4213-878b-770e8597ac16");
static readonly FileVersionInfo decompilerVersion = FileVersionInfo.GetVersionInfo(typeof(CSharpDecompiler).Assembly.Location);
static readonly SHA256 hasher = SHA256.Create();
public static bool HasCodeViewDebugDirectoryEntry(PEFile file)
{
return file.Reader.ReadDebugDirectory().Any(entry => entry.Type == DebugDirectoryEntryType.CodeView);
}
public static void WritePdb(PEFile file, CSharpDecompiler decompiler, DecompilerSettings settings, Stream targetStream)
public static void WritePdb(PEFile file, CSharpDecompiler decompiler, DecompilerSettings settings, Stream targetStream, bool noLogo = false)
{
MetadataBuilder metadata = new MetadataBuilder();
MetadataReader reader = file.Metadata;
var entrypointHandle = MetadataTokens.MethodDefinitionHandle(file.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);
var hasher = SHA256.Create();
var sequencePointBlobs = new Dictionary<MethodDefinitionHandle, (DocumentHandle Document, BlobHandle SequencePoints)>();
var emptyList = new List<SequencePoint>();
var globalImportScope = metadata.AddImportScope(default, default);
@ -67,13 +68,18 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -67,13 +68,18 @@ namespace ICSharpCode.Decompiler.DebugInfo
foreach (var handle in reader.GetTopLevelTypeDefinitions()) {
var type = reader.GetTypeDefinition(handle);
// Generate syntax tree, source and checksum
var name = metadata.GetOrAddDocumentName(type.GetFullTypeName(reader).ReflectionName.Replace('.', Path.DirectorySeparatorChar) + ".cs");
// Generate syntax tree
var syntaxTree = decompiler.DecompileTypes(new[] { handle });
if (!syntaxTree.HasChildren)
continue;
// Generate source and checksum
var name = metadata.GetOrAddDocumentName(type.GetFullTypeName(reader).ReflectionName.Replace('.', Path.DirectorySeparatorChar) + ".cs");
if (!noLogo)
syntaxTree.InsertChildAfter(null, new Comment(" PDB and source generated by ICSharpCode.Decompiler " + decompilerVersion.FileVersion), Roles.Comment);
var sourceText = SyntaxTreeToString(syntaxTree, settings);
var sourceCheckSum = hasher.ComputeHash(Encoding.UTF8.GetBytes(sourceText));
var sourceBlob = WriteSourceToBlob(metadata, sourceText);
var sourceBlob = WriteSourceToBlob(metadata, sourceText, out var sourceCheckSum);
// Create Document(Handle)
var document = metadata.AddDocument(name,
@ -143,11 +149,19 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -143,11 +149,19 @@ namespace ICSharpCode.Decompiler.DebugInfo
}
}
static BlobHandle WriteSourceToBlob(MetadataBuilder metadata, string sourceText)
static BlobHandle WriteSourceToBlob(MetadataBuilder metadata, string sourceText, out byte[] sourceCheckSum)
{
var builder = new BlobBuilder();
builder.WriteInt32(0); // uncompressed
builder.WriteUTF8(sourceText);
using (var memory = new MemoryStream()) {
var deflate = new DeflateStream(memory, CompressionLevel.Optimal, leaveOpen: true);
byte[] bytes = Encoding.UTF8.GetBytes(sourceText);
deflate.Write(bytes, 0, bytes.Length);
deflate.Close();
byte[] buffer = memory.ToArray();
builder.WriteInt32(bytes.Length); // compressed
builder.WriteBytes(buffer);
sourceCheckSum = hasher.ComputeHash(bytes);
}
return metadata.GetOrAddBlob(builder);
}

Loading…
Cancel
Save