Dump the Portable PDB debug tables with --dump-table

The metadata-table dumper only knew the Cor tables, so the debug metadata a
Portable PDB carries had no command-line view at all; the GUI has shown those
eight tables for years. Moving the dumper into ILSpyX puts it next to the PDB
providers it now needs and makes it available to any host, not just ilspycmd.

Two things a user would otherwise trip over: a standalone .pdb is accepted as
an input file, and asking an assembly for a debug table resolves the embedded
or adjacent PDB instead of reporting an empty table. Reading a debug table
without either would silently print nothing at all.

The GUI's StateMachineMethod reader moves to a shared extension. Its own copy
read the MethodDef column with ReadInt16 and switched to the wide form at
ushort.MaxValue rather than 1 << 16, so a large enough method table would have
produced negative RIDs.

Assisted-by: Claude:claude-opus-5:Claude Code
This commit is contained in:
Siegfried Pammer
2026-10-02 07:44:55 +02:00
parent 1332609cb5
commit 58be31306e
7 changed files with 287 additions and 20 deletions
+17 -2
View File
@@ -63,6 +63,21 @@ namespace ICSharpCode.ILSpyCmd
/// The file is a package and <paramref name="entryName"/> is null or unknown.
/// </exception>
public static PEFile Load(string fileName, string entryName, bool applyWinRTProjections = true)
{
var file = LoadMetadata(fileName, entryName, applyWinRTProjections);
if (file is PEFile module)
{
return module;
}
file.Dispose();
throw new BadImageFormatException($"'{fileName}' contains metadata, but no PE image.");
}
/// <summary>
/// Like <see cref="Load"/>, but also accepts a file that carries metadata without a PE
/// image around it: a standalone Portable PDB, or a raw metadata blob.
/// </summary>
public static MetadataFile LoadMetadata(string fileName, string entryName, bool applyWinRTProjections = true)
{
var context = new FileLoadContext(applyWinRTProjections, null);
var result = LoadFile(fileName, context);
@@ -70,9 +85,9 @@ namespace ICSharpCode.ILSpyCmd
{
return LoadPackageEntry(package, entryName, context);
}
if (result?.MetadataFile is PEFile module)
if (result?.MetadataFile is { } file)
{
return module;
return file;
}
// Not a file any loader recognized: let PEFile report what is wrong with it, which is
// the error the tool has always produced for such input.