Skip to content

Commit

Permalink
Fix portable PDB stamp in CodeView header (jbevain#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitek-karas committed Nov 29, 2021
1 parent ff616bf commit e04f141
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 13 deletions.
10 changes: 5 additions & 5 deletions Mono.Cecil.Cil/PortablePdb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ public sealed class PortablePdbWriter : ISymbolWriter {

internal byte [] pdb_checksum;
internal Guid pdb_id_guid;
internal uint pdb_id_age;
internal uint pdb_id_stamp;

bool IsEmbedded { get { return writer == null; } }

Expand Down Expand Up @@ -324,7 +324,7 @@ public ImageDebugHeader GetDebugHeader ()
MajorVersion = 256,
MinorVersion = 20557,
Type = ImageDebugType.CodeView,
TimeDateStamp = (int)module.timestamp,
TimeDateStamp = (int)pdb_id_stamp,
};

var buffer = new ByteBuffer ();
Expand All @@ -333,7 +333,7 @@ public ImageDebugHeader GetDebugHeader ()
// Module ID
buffer.WriteBytes (pdb_id_guid.ToByteArray ());
// PDB Age
buffer.WriteUInt32 (pdb_id_age);
buffer.WriteUInt32 (1);
// PDB Path
var fileName = writer.BaseStream.GetFileName ();
if (string.IsNullOrEmpty (fileName)) {
Expand Down Expand Up @@ -462,15 +462,15 @@ void ComputeChecksumAndPdbId ()

var hashBytes = new ByteBuffer (pdb_checksum);
pdb_id_guid = new Guid (hashBytes.ReadBytes (16));
pdb_id_age = hashBytes.ReadUInt32 ();
pdb_id_stamp = hashBytes.ReadUInt32 ();
}

void WritePdbId ()
{
// PDB ID is the first 20 bytes of the PdbHeap
writer.MoveToRVA (TextSegment.PdbHeap);
writer.WriteBytes (pdb_id_guid.ToByteArray ());
writer.WriteUInt32 (pdb_id_age);
writer.WriteUInt32 (pdb_id_stamp);
}
}

Expand Down
38 changes: 30 additions & 8 deletions Test/Mono.Cecil.Tests/PortablePdbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -885,11 +885,13 @@ public void ReadPortablePdbChecksum ()
using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) {
GetPdbChecksumData (module.GetDebugHeader (), out string algorithmName, out byte [] checksum);
Assert.AreEqual ("SHA256", algorithmName);
GetCodeViewPdbId (module, out byte[] pdbId);

string pdbPath = GetDebugHeaderPdbPath (module);
CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out byte [] pdbId);
string pdbPath = Mixin.GetPdbFileName (module.FileName);
CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out byte [] expectedPdbId);

CollectionAssert.AreEqual (expectedChecksum, checksum);
CollectionAssert.AreEqual (expectedPdbId, pdbId);
}
}

Expand All @@ -902,11 +904,13 @@ public void ReadEmbeddedPortablePdbChecksum ()
var debugHeader = module.GetDebugHeader ();
GetPdbChecksumData (debugHeader, out string algorithmName, out byte [] checksum);
Assert.AreEqual ("SHA256", algorithmName);
GetCodeViewPdbId (module, out byte [] pdbId);

GetEmbeddedPdb (debugHeader, out byte [] embeddedPdb);
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] pdbId);
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] expectedPdbId);

CollectionAssert.AreEqual (expectedChecksum, checksum);
CollectionAssert.AreEqual (expectedPdbId, pdbId);
}
}

Expand All @@ -923,11 +927,13 @@ public void WritePortablePdbChecksum ()
using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) {
GetPdbChecksumData (module.GetDebugHeader (), out string algorithmName, out byte [] checksum);
Assert.AreEqual ("SHA256", algorithmName);
GetCodeViewPdbId (module, out byte [] pdbId);

string pdbPath = GetDebugHeaderPdbPath (module);
CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out byte [] pdbId);
string pdbPath = Mixin.GetPdbFileName (module.FileName);
CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out byte [] expectedPdbId);

CollectionAssert.AreEqual (expectedChecksum, checksum);
CollectionAssert.AreEqual (expectedPdbId, pdbId);
}
}

Expand Down Expand Up @@ -961,7 +967,7 @@ public void DoubleWritePortablePdbDeterministicPdbId ()

byte [] pdbIdOne;
using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) {
string pdbPath = GetDebugHeaderPdbPath (module);
string pdbPath = Mixin.GetPdbFileName (module.FileName);
CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out pdbIdOne);
}

Expand All @@ -971,7 +977,7 @@ public void DoubleWritePortablePdbDeterministicPdbId ()

byte [] pdbIdTwo;
using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) {
string pdbPath = GetDebugHeaderPdbPath (module);
string pdbPath = Mixin.GetPdbFileName (module.FileName);
CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out pdbIdTwo);
}

Expand All @@ -992,11 +998,13 @@ public void WriteEmbeddedPortablePdbChecksum ()
var debugHeader = module.GetDebugHeader ();
GetPdbChecksumData (debugHeader, out string algorithmName, out byte [] checksum);
Assert.AreEqual ("SHA256", algorithmName);
GetCodeViewPdbId (module, out byte [] pdbId);

GetEmbeddedPdb (debugHeader, out byte [] embeddedPdb);
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] pdbId);
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] expectedPdbId);

CollectionAssert.AreEqual (expectedChecksum, checksum);
CollectionAssert.AreEqual (expectedPdbId, pdbId);
}
}

Expand Down Expand Up @@ -1102,5 +1110,19 @@ private void CalculatePdbChecksumAndId (Stream pdbStream, out byte [] pdbChecksu
var sha256 = SHA256.Create ();
pdbChecksum = sha256.ComputeHash (bytes);
}

static void GetCodeViewPdbId (ModuleDefinition module, out byte[] pdbId)
{
var header = module.GetDebugHeader ();
var cv = Mixin.GetCodeViewEntry (header);
Assert.IsNotNull (cv);

CollectionAssert.AreEqual (new byte [] { 0x52, 0x53, 0x44, 0x53 }, cv.Data.Take (4));

ByteBuffer buffer = new ByteBuffer (20);
buffer.WriteBytes (cv.Data.Skip (4).Take (16).ToArray ());
buffer.WriteInt32 (cv.Directory.TimeDateStamp);
pdbId = buffer.buffer;
}
}
}

0 comments on commit e04f141

Please sign in to comment.