From: sivadeilra Date: Wed, 21 Aug 2024 18:32:01 +0000 (-0700) Subject: Provide info about PDB container type (MSF vs. MSFZ) (#4877) X-Git-Tag: accepted/tizen/unified/20241231.014852~39^2^2~69 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=23af0ac5dc808dd0fc8459250406d233deaaa143;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git Provide info about PDB container type (MSF vs. MSFZ) (#4877) This is a follow-on to my previous PR, #4868 . This allows users of the `PDBFile` class to query for the "kind" of the container that a given PDB file uses. Normal (uncompressed) PDBs use a container format called "MSF". Compressed PDBs use a container format called "MSFZ". This adds two properties to `PDBFile`. The `ContainerKind` property returns an enum which allows the caller to distinguish between MSF, and MSFZ. This also allows for new container formats (as yet unspecified) in the future. However, the `ContainerKind` enum intentionally does not distinguish between the version of the container. For that, the `ContainerKindSpecString` returns a string which contains a textual identifier ("msf" vs. "msfz") and for MSFZ, a version number. For now, the only version number defined is 0. --------- Co-authored-by: Arlie Davis --- diff --git a/src/Microsoft.FileFormats/PDB/IMSFFile.cs b/src/Microsoft.FileFormats/PDB/IMSFFile.cs index 2c6d4f445..b61502cb1 100644 --- a/src/Microsoft.FileFormats/PDB/IMSFFile.cs +++ b/src/Microsoft.FileFormats/PDB/IMSFFile.cs @@ -19,5 +19,19 @@ namespace Microsoft.FileFormats.PDB /// The index of the stream. This must be less than NumStreams. /// A Reader which can read the stream. Reader GetStream(uint stream); + + /// + /// Returns the container kind for this implementation. + /// + PDBContainerKind ContainerKind { get; } + + /// + /// Returns a string which identifies the container kind, using a backward-compatible naming scheme. + /// + /// + /// The existing PDB format is identified as "pdb", while PDZ (MSFZ) is identified as "msfz0". + /// This allows new versions of MSFZ to be identified and deployed without updating clients of this API. + /// + public string ContainerKindSpecString { get; } } } diff --git a/src/Microsoft.FileFormats/PDB/MSFFile.cs b/src/Microsoft.FileFormats/PDB/MSFFile.cs index 877380e5c..2118932fe 100644 --- a/src/Microsoft.FileFormats/PDB/MSFFile.cs +++ b/src/Microsoft.FileFormats/PDB/MSFFile.cs @@ -67,5 +67,15 @@ namespace Microsoft.FileFormats.PDB { return _streams[index]; } + + public PDBContainerKind ContainerKind + { + get { return PDBContainerKind.MSF; } + } + + public string ContainerKindSpecString + { + get { return "msf"; } + } } } diff --git a/src/Microsoft.FileFormats/PDB/MSFZFile.cs b/src/Microsoft.FileFormats/PDB/MSFZFile.cs index 870899230..8f08437a0 100644 --- a/src/Microsoft.FileFormats/PDB/MSFZFile.cs +++ b/src/Microsoft.FileFormats/PDB/MSFZFile.cs @@ -36,13 +36,19 @@ namespace Microsoft.FileFormats.PDB /// private readonly uint[] _streamDirStarts; - private MSFZFile(Reader reader, uint numStreams, uint[] streamDir, uint[] streamDirStarts) + /// + /// The value of the "version" field from the MSFZ header. + /// + private readonly ulong _msfzVersion; + + private MSFZFile(Reader reader, uint numStreams, uint[] streamDir, uint[] streamDirStarts, ulong msfzVersion) { Debug.Assert(numStreams == streamDirStarts.Length); this._numStreams = numStreams; this._reader = reader; this._streamDir = streamDir; this._streamDirStarts = streamDirStarts; + this._msfzVersion = msfzVersion; } public uint NumStreams @@ -120,6 +126,9 @@ namespace Microsoft.FileFormats.PDB uint streamDirSizeCompressed = fileHeader.StreamDirSizeCompressed; uint streamDirSizeUncompressed = fileHeader.StreamDirSizeUncompressed; + // Validate the MSFZ file header version. We keep track of the version in a variable, + // even though the only version that is actually supported is V0. This is to minimize + // code changes in future versions of this code that would parse V1, V2, etc. if (headerVersion != MSFZFileHeader.VersionV0) { // Wrong version @@ -154,7 +163,7 @@ namespace Microsoft.FileFormats.PDB // We do not read the Chunk Table because this implementation does not support // compression. Since the Chunk Table describes compressed chunks, we will never use it. - return new MSFZFile(reader, numStreams, streamDirEncoded, streamStarts); + return new MSFZFile(reader, numStreams, streamDirEncoded, streamStarts, headerVersion); } /// @@ -277,6 +286,15 @@ namespace Microsoft.FileFormats.PDB return totalBytesTransferred; } + public PDBContainerKind ContainerKind + { + get { return PDBContainerKind.MSFZ; } + } + + public string ContainerKindSpecString + { + get { return $"msfz{_msfzVersion}"; } + } public void Dispose() { diff --git a/src/Microsoft.FileFormats/PDB/PDBFile.cs b/src/Microsoft.FileFormats/PDB/PDBFile.cs index cafccb108..a0318664a 100644 --- a/src/Microsoft.FileFormats/PDB/PDBFile.cs +++ b/src/Microsoft.FileFormats/PDB/PDBFile.cs @@ -146,6 +146,34 @@ namespace Microsoft.FileFormats.PDB } return streamReaders; } + + /// + /// Returns the container kind used for this PDB file. + /// + public PDBContainerKind ContainerKind + { + get + { + CheckValid(); + return _msfFile.ContainerKind; + } + } + + /// + /// Returns a string which identifies the container kind, using a backward-compatible naming scheme. + /// + /// + /// The existing PDB format is identified as "pdb", while PDZ (MSFZ) is identified as "msfz0". + /// This allows new versions of MSFZ to be identified and deployed without updating clients of this API. + /// + public string ContainerKindSpecString + { + get + { + CheckValid(); + return _msfFile.ContainerKindSpecString; + } + } } /// @@ -252,4 +280,20 @@ namespace Microsoft.FileFormats.PDB public DbiStreamHeader Header { get { _header.Value.IsHeaderValid.CheckThrowing(); return _header.Value; } } } + + /// + /// Specifies the kinds of PDB container formats. + /// + public enum PDBContainerKind + { + /// + /// An uncompressed PDB. + /// + MSF, + + /// + /// A compressed PDB, also known as a PDBZ or "PDB using MSFZ container". + /// + MSFZ, + } } diff --git a/src/tests/Microsoft.FileFormats.UnitTests/PDB/Tests.cs b/src/tests/Microsoft.FileFormats.UnitTests/PDB/Tests.cs index 5a467d2b7..e61dc237d 100644 --- a/src/tests/Microsoft.FileFormats.UnitTests/PDB/Tests.cs +++ b/src/tests/Microsoft.FileFormats.UnitTests/PDB/Tests.cs @@ -22,6 +22,9 @@ namespace Microsoft.FileFormats.PDB.Tests Assert.Equal((uint)1, pdb.Age); Assert.Equal(Guid.Parse("99891B3E-D7AE-4C3B-ABFF-8A2B4A9B0C43"), pdb.Signature); + Assert.Equal(PDBContainerKind.MSF, pdb.ContainerKind); + Assert.Equal("msf", pdb.ContainerKindSpecString); + // Also read the PDBI stream directly, using the downlevel API. #pragma warning disable CS0618 // Type or member is obsolete var stream1 = pdb.Streams[1]; @@ -42,6 +45,9 @@ namespace Microsoft.FileFormats.PDB.Tests Assert.Equal((uint)1, pdb.Age); Assert.Equal(Guid.Parse("99891B3E-D7AE-4C3B-ABFF-8A2B4A9B0C43"), pdb.Signature); + Assert.Equal(PDBContainerKind.MSFZ, pdb.ContainerKind); + Assert.Equal("msfz0", pdb.ContainerKindSpecString); + // Also read the PDBI stream directly, using the downlevel API. #pragma warning disable CS0618 // Type or member is obsolete var stream1 = pdb.Streams[1];