-
Notifications
You must be signed in to change notification settings - Fork 354
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for MSFZ/PDZ files (#4868)
This adds support for reading MSFZ/PDZ files. MSFZ files are a new container format for PDB files, which allows for efficient compression and decompression of small fragments of a file, without decompressing the entire file. Co-authored-by: Arlie Davis <[email protected]>
- Loading branch information
1 parent
254a730
commit c318910
Showing
8 changed files
with
656 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace Microsoft.FileFormats.PDB | ||
{ | ||
/// <summary> | ||
/// An abstraction for reading both MSF (normal PDB files) and MSFZ files (compressed PDB files). | ||
/// </summary> | ||
internal interface IMSFFile | ||
{ | ||
/// <summary> | ||
/// The number of streams stored in the file. This will always be at least 1. | ||
/// </summary> | ||
uint NumStreams { get; } | ||
|
||
/// <summary> | ||
/// Gets an object which can read the given stream. | ||
/// </summary> | ||
/// <param name="stream">The index of the stream. This must be less than NumStreams.</param> | ||
/// <returns>A Reader which can read the stream.</returns> | ||
Reader GetStream(uint stream); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.FileFormats.PDB | ||
{ | ||
/// <summary> | ||
/// This class can read from PDB files that use the MSF container format. | ||
/// </summary> | ||
internal sealed class MSFFile : IMSFFile | ||
{ | ||
private Reader[] _streams; | ||
|
||
private MSFFile(Reader[] streams) | ||
{ | ||
_streams = streams; | ||
} | ||
|
||
internal static MSFFile OpenInternal(Reader fileReader, PDBFileHeader msfFileHeader) | ||
{ | ||
// Read the Stream Directory and build the list of streams. | ||
|
||
uint pageSize = msfFileHeader.PageSize; | ||
|
||
uint secondLevelPageCount = ToPageCount(pageSize, msfFileHeader.DirectorySize); | ||
ulong pageIndicesOffset = fileReader.SizeOf<PDBFileHeader>(); | ||
PDBPagedAddressSpace secondLevelPageList = CreatePagedAddressSpace(fileReader.DataSource, fileReader.DataSource, msfFileHeader.PageSize, pageIndicesOffset, secondLevelPageCount * sizeof(uint)); | ||
PDBPagedAddressSpace directoryContent = CreatePagedAddressSpace(fileReader.DataSource, secondLevelPageList, msfFileHeader.PageSize, 0, msfFileHeader.DirectorySize); | ||
|
||
Reader directoryReader = new(directoryContent); | ||
ulong position = 0; | ||
uint countStreams = directoryReader.Read<uint>(ref position); | ||
uint[] streamSizes = directoryReader.ReadArray<uint>(ref position, countStreams); | ||
Reader[] streams = new Reader[countStreams]; | ||
for (uint i = 0; i < streamSizes.Length; i++) | ||
{ | ||
uint streamSize = streamSizes[i]; | ||
streams[i] = new Reader(CreatePagedAddressSpace(fileReader.DataSource, directoryContent, pageSize, position, streamSize)); | ||
position += ToPageCount(pageSize, streamSizes[i]) * sizeof(uint); | ||
} | ||
|
||
return new MSFFile(streams); | ||
} | ||
|
||
private static PDBPagedAddressSpace CreatePagedAddressSpace(IAddressSpace fileData, IAddressSpace indicesData, uint pageSize, ulong offset, uint length) | ||
{ | ||
uint[] indices = new Reader(indicesData).ReadArray<uint>(offset, ToPageCount(pageSize, length)); | ||
return new PDBPagedAddressSpace(fileData, indices, pageSize, length); | ||
} | ||
|
||
private static uint ToPageCount(uint pageSize, uint size) | ||
{ | ||
return unchecked((pageSize + size - 1) / pageSize); | ||
} | ||
|
||
public uint NumStreams | ||
{ | ||
get | ||
{ | ||
return (uint)_streams.Length; | ||
} | ||
} | ||
|
||
public Reader GetStream(uint index) | ||
{ | ||
return _streams[index]; | ||
} | ||
} | ||
} |
Oops, something went wrong.