Skip to content

Commit

Permalink
Introduce ISymbolWriter.Write
Browse files Browse the repository at this point in the history
This mostly cleans up the code to make it easier to understand. `ISymbolWriter.GetDebugHeader` no longer actually writes the symbols, there's a new `Write` method for just that.

The assembly writer calls `Write` first and then the image writer calls `GetDebugHeader` when it's needed.

This is partially taken from jbevain#617.
  • Loading branch information
vitek-karas committed Jan 14, 2022
1 parent d02d7b3 commit ddc26b2
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 24 deletions.
16 changes: 14 additions & 2 deletions Mono.Cecil.Cil/PortablePdb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,10 @@ public void Write (MethodDebugInformation info)
pdb_metadata.AddMethodDebugInformation (info);
}

public ImageDebugHeader GetDebugHeader ()
public void Write ()
{
if (IsEmbedded)
return new ImageDebugHeader ();
return;

WritePdbFile ();

Expand All @@ -317,6 +317,12 @@ public ImageDebugHeader GetDebugHeader ()
var buffer = new byte [8192];
CryptoService.CopyStreamChunk (writer.BaseStream, final_stream.value, buffer, (int)writer.BaseStream.Length);
}
}

public ImageDebugHeader GetDebugHeader ()
{
if (IsEmbedded)
return new ImageDebugHeader ();

ImageDebugHeaderEntry codeViewEntry;
{
Expand Down Expand Up @@ -548,8 +554,14 @@ public ImageDebugHeader GetDebugHeader ()
return new ImageDebugHeader (debugHeaderEntries);
}

public void Write ()
{
writer.Write ();
}

public void Dispose ()
{
writer.Dispose ();
}
}

Expand Down
1 change: 1 addition & 0 deletions Mono.Cecil.Cil/Symbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,7 @@ public interface ISymbolWriter : IDisposable {
ISymbolReaderProvider GetReaderProvider ();
ImageDebugHeader GetDebugHeader ();
void Write (MethodDebugInformation info);
void Write ();
}

public interface ISymbolWriterProvider {
Expand Down
26 changes: 17 additions & 9 deletions Mono.Cecil.PE/ImageWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ sealed class ImageWriter : BinaryStreamWriter {

internal long debug_header_entries_position;

ImageWriter (ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Disposable<Stream> stream, bool metadataOnly = false, ImageDebugHeader debugHeader = null)
ImageWriter (ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Disposable<Stream> stream, bool metadataOnly = false)
: base (stream.value)
{
this.module = module;
Expand All @@ -63,18 +63,26 @@ sealed class ImageWriter : BinaryStreamWriter {

this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64;
this.has_reloc = module.Architecture == TargetArchitecture.I386;
this.GetDebugHeader ();
this.GetWin32Resources ();
this.BuildTextMap ();
this.sections = (ushort)(has_reloc ? 2 : 1); // text + reloc?
}

void GetDebugHeader ()
{
var symbol_writer = metadata.symbol_writer;
if (symbol_writer != null)
debug_header = symbol_writer.GetDebugHeader ();

debug_header = debugHeader;
if (module.HasDebugHeader) {
var header = module.GetDebugHeader ();
var deterministic = header.GetDeterministicEntry ();
if (deterministic != null)
debug_header = debug_header.AddDeterministicEntry ();
}
if (deterministic == null)
return;

this.BuildTextMap ();
this.sections = (ushort)(has_reloc ? 2 : 1); // text + reloc?
debug_header = debug_header.AddDeterministicEntry ();
}
}

void GetWin32Resources ()
Expand All @@ -90,9 +98,9 @@ void GetWin32Resources ()
}
}

public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream, ImageDebugHeader debugHeader)
public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
{
var writer = new ImageWriter (module, module.runtime_version, metadata, stream, metadataOnly: false, debugHeader: debugHeader);
var writer = new ImageWriter (module, module.runtime_version, metadata, stream, metadataOnly: false);
writer.BuildSections ();
return writer;
}
Expand Down
5 changes: 2 additions & 3 deletions Mono.Cecil/AssemblyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,10 @@ static void Write (ModuleDefinition module, Disposable<Stream> stream, WriterPar
metadata.SetSymbolWriter (symbol_writer);
BuildMetadata (module, metadata);

ImageDebugHeader debugHeader = null;
if (symbol_writer != null)
debugHeader = symbol_writer.GetDebugHeader ();
symbol_writer.Write ();

var writer = ImageWriter.CreateWriter (module, metadata, stream, debugHeader);
var writer = ImageWriter.CreateWriter (module, metadata, stream);
stream.value.SetLength (0);
writer.WriteImage ();

Expand Down
5 changes: 5 additions & 0 deletions Test/Mono.Cecil.Tests/PortablePdbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,11 @@ public void Write (MethodDebugInformation info)
symbol_writer.Write (info);
}

public void Write ()
{
symbol_writer.Write ();
}

public void Dispose ()
{
symbol_writer.Dispose ();
Expand Down
6 changes: 6 additions & 0 deletions symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ public ImageDebugHeader GetDebugHeader ()
return new ImageDebugHeader ();
}

public void Write ()
{
// Can't write it here since we need the final module MVID - which is only computed
// after the entire image of the assembly is written (since it's computed from the hash of that)
}

public void Dispose ()
{
writer.WriteSymbolFile (module.Mvid);
Expand Down
26 changes: 16 additions & 10 deletions symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public class NativePdbWriter : ISymbolWriter {
readonly Dictionary<string, SymDocumentWriter> documents;
readonly Dictionary<ImportDebugInformation, MetadataToken> import_info_to_parent;

ImageDebugDirectory debug_directory;
byte [] debug_info;

internal NativePdbWriter (ModuleDefinition module, SymWriter writer)
{
this.module = module;
Expand All @@ -44,16 +47,7 @@ public ISymbolReaderProvider GetReaderProvider ()

public ImageDebugHeader GetDebugHeader ()
{
var entry_point = module.EntryPoint;
if (entry_point != null)
writer.SetUserEntryPoint (entry_point.MetadataToken.ToInt32 ());

ImageDebugDirectory directory;
var data = writer.GetDebugInfo (out directory);
directory.TimeDateStamp = (int) module.timestamp;

writer.Close ();
return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data));
return new ImageDebugHeader (new ImageDebugHeaderEntry (debug_directory, debug_info));
}

public void Write (MethodDebugInformation info)
Expand Down Expand Up @@ -259,6 +253,18 @@ SymDocumentWriter GetDocument (Document document)
return doc_writer;
}

public void Write ()
{
var entry_point = module.EntryPoint;
if (entry_point != null)
writer.SetUserEntryPoint (entry_point.MetadataToken.ToInt32 ());

debug_info = writer.GetDebugInfo (out debug_directory);
debug_directory.TimeDateStamp = (int)module.timestamp;

writer.Close ();
}

public void Dispose ()
{
}
Expand Down

0 comments on commit ddc26b2

Please sign in to comment.