Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for reading and writing document checksums in native pdbs #616

Merged
merged 1 commit into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions symbols/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Licensed under the MIT/X11 license.
//

using System;
using System.Runtime.InteropServices;

namespace Mono.Cecil.Pdb {
Expand All @@ -14,5 +15,7 @@ namespace Mono.Cecil.Pdb {
[InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
interface ISymUnmanagedDocumentWriter {
void SetSource (uint sourceSize, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 0)] byte [] source);
void SetCheckSum (Guid algorithmId, uint checkSumSize, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] checkSum);
}
}
8 changes: 5 additions & 3 deletions symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,11 @@ Document GetDocument (PdbSource source)
return document;

document = new Document (name) {
Language = source.language.ToLanguage (),
LanguageVendor = source.vendor.ToVendor (),
Type = source.doctype.ToType (),
LanguageGuid = source.language,
LanguageVendorGuid = source.vendor,
TypeGuid = source.doctype,
HashAlgorithmGuid = source.checksumAlgorithm,
Hash = source.checksum,
};
documents.Add (name, document);
return document;
Expand Down
3 changes: 3 additions & 0 deletions symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ SymDocumentWriter GetDocument (Document document)
document.LanguageVendorGuid,
document.TypeGuid);

if (!document.Hash.IsNullOrEmpty ())
doc_writer.SetCheckSum (document.HashAlgorithmGuid, document.Hash);

documents [document.Url] = doc_writer;
return doc_writer;
}
Expand Down
20 changes: 15 additions & 5 deletions symbols/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,26 @@ namespace Mono.Cecil.Pdb
{
internal class SymDocumentWriter
{
readonly ISymUnmanagedDocumentWriter m_unmanagedDocumentWriter;
readonly ISymUnmanagedDocumentWriter writer;

public SymDocumentWriter (ISymUnmanagedDocumentWriter unmanagedDocumentWriter)
public ISymUnmanagedDocumentWriter Writer
{
m_unmanagedDocumentWriter = unmanagedDocumentWriter;
get { return writer; }
}

public ISymUnmanagedDocumentWriter GetUnmanaged ()
public SymDocumentWriter (ISymUnmanagedDocumentWriter writer)
{
return m_unmanagedDocumentWriter;
this.writer = writer;
}

public void SetSource (byte [] source)
{
writer.SetSource ((uint) source.Length, source);
}

public void SetCheckSum (Guid hashAlgo, byte [] checkSum)
{
writer.SetCheckSum (hashAlgo, (uint) checkSum.Length, checkSum);
}
}
}
48 changes: 24 additions & 24 deletions symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ static extern int CoCreateInstance (
static Guid s_symUnmangedWriterIID = new Guid("0b97726e-9e6d-4f05-9a26-424022093caa");
static Guid s_CorSymWriter_SxS_ClassID = new Guid ("108296c1-281e-11d3-bd22-0000f80849bd");

readonly ISymUnmanagedWriter2 m_writer;
readonly ISymUnmanagedWriter2 writer;
readonly Collection<ISymUnmanagedDocumentWriter> documents;

public SymWriter ()
{
object objWriter;
CoCreateInstance (ref s_CorSymWriter_SxS_ClassID, null, 1, ref s_symUnmangedWriterIID, out objWriter);

m_writer = (ISymUnmanagedWriter2) objWriter;
writer = (ISymUnmanagedWriter2) objWriter;
documents = new Collection<ISymUnmanagedDocumentWriter> ();
}

Expand All @@ -45,10 +45,10 @@ public byte[] GetDebugInfo (out ImageDebugDirectory idd)
int size;

// get size of debug info
m_writer.GetDebugInfo (out idd, 0, out size, null);
writer.GetDebugInfo (out idd, 0, out size, null);

byte[] debug_info = new byte[size];
m_writer.GetDebugInfo (out idd, size, out size, debug_info);
writer.GetDebugInfo (out idd, size, out size, debug_info);

return debug_info;
}
Expand All @@ -63,93 +63,93 @@ public void DefineLocalVariable2 (
int startOffset,
int endOffset)
{
m_writer.DefineLocalVariable2 (name, (int)attributes, sigToken, 1 /* ILOffset*/, addr1, addr2, addr3, startOffset, endOffset);
writer.DefineLocalVariable2 (name, (int)attributes, sigToken, 1 /* ILOffset*/, addr1, addr2, addr3, startOffset, endOffset);
}

public void DefineConstant2 (string name, object value, int sigToken)
{
if (value == null) {
m_writer.DefineConstant2 (name, 0, sigToken);
writer.DefineConstant2 (name, 0, sigToken);
return;
}

m_writer.DefineConstant2 (name, value, sigToken);
writer.DefineConstant2 (name, value, sigToken);
}

public void Close ()
{
m_writer.Close ();
Marshal.ReleaseComObject (m_writer);
writer.Close ();
Marshal.ReleaseComObject (writer);

foreach (var document in documents)
Marshal.ReleaseComObject (document);
}

public void CloseMethod ()
{
m_writer.CloseMethod ();
writer.CloseMethod ();
}

public void CloseNamespace ()
{
m_writer.CloseNamespace ();
writer.CloseNamespace ();
}

public void CloseScope (int endOffset)
{
m_writer.CloseScope (endOffset);
writer.CloseScope (endOffset);
}

public SymDocumentWriter DefineDocument (string url, Guid language, Guid languageVendor, Guid documentType)
{
ISymUnmanagedDocumentWriter unmanagedDocumentWriter;
m_writer.DefineDocument (url, ref language, ref languageVendor, ref documentType, out unmanagedDocumentWriter);
ISymUnmanagedDocumentWriter doc_writer;
writer.DefineDocument (url, ref language, ref languageVendor, ref documentType, out doc_writer);

documents.Add (unmanagedDocumentWriter);
return new SymDocumentWriter (unmanagedDocumentWriter);
documents.Add (doc_writer);
return new SymDocumentWriter (doc_writer);
}

public void DefineSequencePoints (SymDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns)
{
m_writer.DefineSequencePoints (document.GetUnmanaged(), offsets.Length, offsets, lines, columns, endLines, endColumns);
writer.DefineSequencePoints (document.Writer, offsets.Length, offsets, lines, columns, endLines, endColumns);
}

public void Initialize (object emitter, string filename, bool fFullBuild)
{
m_writer.Initialize (emitter, filename, null, fFullBuild);
writer.Initialize (emitter, filename, null, fFullBuild);
}

public void SetUserEntryPoint (int methodToken)
{
m_writer.SetUserEntryPoint (methodToken);
writer.SetUserEntryPoint (methodToken);
}

public void OpenMethod (int methodToken)
{
m_writer.OpenMethod (methodToken);
writer.OpenMethod (methodToken);
}

public void OpenNamespace (string name)
{
m_writer.OpenNamespace (name);
writer.OpenNamespace (name);
}

public int OpenScope (int startOffset)
{
int result;
m_writer.OpenScope (startOffset, out result);
writer.OpenScope (startOffset, out result);
return result;
}

public void UsingNamespace (string fullName)
{
m_writer.UsingNamespace (fullName);
writer.UsingNamespace (fullName);
}

public void DefineCustomMetadata (string name, byte [] metadata)
{
var handle = GCHandle.Alloc (metadata, GCHandleType.Pinned);
m_writer.SetSymAttribute (0, name, (uint) metadata.Length, handle.AddrOfPinnedObject ());
writer.SetSymAttribute (0, name, (uint) metadata.Length, handle.AddrOfPinnedObject ());
handle.Free ();
}
}
Expand Down
6 changes: 4 additions & 2 deletions symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public void Document ()

Assert.AreEqual (@"c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs", document.Url);
Assert.AreEqual (DocumentType.Text, document.Type);
Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm);
Assert.AreEqual (DocumentHashAlgorithm.MD5, document.HashAlgorithm);
Assert.AreEqual (new byte [] { 228, 176, 152, 54, 82, 238, 238, 68, 237, 156, 5, 142, 118, 160, 118, 245 }, document.Hash);
Assert.AreEqual (DocumentLanguage.CSharp, document.Language);
Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor);
}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
Expand All @@ -119,7 +120,8 @@ public void BasicDocument ()

Assert.AreEqual (@"c:\tmp\VBConsApp\Program.vb", document.Url);
Assert.AreEqual (DocumentType.Text, document.Type);
Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm);
Assert.AreEqual (DocumentHashAlgorithm.MD5, document.HashAlgorithm);
Assert.AreEqual (new byte [] { 184, 188, 100, 23, 27, 123, 187, 201, 175, 206, 110, 198, 242, 139, 154, 119 }, document.Hash);
Assert.AreEqual (DocumentLanguage.Basic, document.Language);
Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor);
}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
Expand Down