Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJb Evain <jb@evain.net>2021-06-30 07:57:53 +0300
committerGitHub <noreply@github.com>2021-06-30 07:57:53 +0300
commit96c159d4687ea7493893011f3bd4a6e098dab163 (patch)
treecf9dc331833604d7d650b3b55d46a8662bc5bf7e
parentfbb3c444bba3086f26c03bca8928307dd4ac6883 (diff)
Avoid decompressing/compressing unresolved embedded source information (#771)
-rw-r--r--Mono.Cecil.Cil/Symbols.cs57
-rw-r--r--Mono.Cecil/AssemblyReader.cs50
-rw-r--r--Mono.Cecil/AssemblyWriter.cs7
-rw-r--r--Test/Mono.Cecil.Tests/PortablePdbTests.cs7
4 files changed, 93 insertions, 28 deletions
diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs
index 4cf435d..5e92b67 100644
--- a/Mono.Cecil.Cil/Symbols.cs
+++ b/Mono.Cecil.Cil/Symbols.cs
@@ -619,17 +619,36 @@ namespace Mono.Cecil.Cil {
public sealed class EmbeddedSourceDebugInformation : CustomDebugInformation {
+ internal uint index;
+ internal MetadataReader debug_reader;
+ internal bool resolved;
internal byte [] content;
internal bool compress;
public byte [] Content {
- get { return content; }
- set { content = value; }
+ get {
+ if (!resolved)
+ Resolve ();
+
+ return content;
+ }
+ set {
+ content = value;
+ resolved = true;
+ }
}
public bool Compress {
- get { return compress; }
- set { compress = value; }
+ get {
+ if (!resolved)
+ Resolve ();
+
+ return compress;
+ }
+ set {
+ compress = value;
+ resolved = true;
+ }
}
public override CustomDebugInformationKind Kind {
@@ -638,12 +657,42 @@ namespace Mono.Cecil.Cil {
public static Guid KindIdentifier = new Guid ("{0E8A571B-6926-466E-B4AD-8AB04611F5FE}");
+ internal EmbeddedSourceDebugInformation (uint index, MetadataReader debug_reader)
+ : base (KindIdentifier)
+ {
+ this.index = index;
+ this.debug_reader = debug_reader;
+ }
+
public EmbeddedSourceDebugInformation (byte [] content, bool compress)
: base (KindIdentifier)
{
+ this.resolved = true;
this.content = content;
this.compress = compress;
}
+
+ internal byte [] ReadRawEmbeddedSourceDebugInformation ()
+ {
+ if (debug_reader == null)
+ throw new InvalidOperationException ();
+
+ return debug_reader.ReadRawEmbeddedSourceDebugInformation (index);
+ }
+
+ void Resolve ()
+ {
+ if (resolved)
+ return;
+
+ if (debug_reader == null)
+ throw new InvalidOperationException ();
+
+ var row = debug_reader.ReadEmbeddedSourceDebugInformation (index);
+ content = row.Col1;
+ compress = row.Col2;
+ resolved = true;
+ }
}
public sealed class SourceLinkDebugInformation : CustomDebugInformation {
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index d5b34b7..9fdcf68 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -3223,28 +3223,7 @@ namespace Mono.Cecil {
infos.Add (async_body);
} else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) {
- var signature = ReadSignature (rows [i].Col2);
- var format = signature.ReadInt32 ();
- var length = signature.sig_length - 4;
-
- var info = null as CustomDebugInformation;
-
- if (format == 0) {
- info = new EmbeddedSourceDebugInformation (signature.ReadBytes ((int) length), compress: false);
- } else if (format > 0) {
- var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length));
- var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document
- var decompressed_stream = new MemoryStream (decompressed_document);
-
- using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
- deflate_stream.CopyTo (decompressed_stream);
-
- info = new EmbeddedSourceDebugInformation (decompressed_document, compress: true);
- } else if (format < 0) {
- info = new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2));
- }
-
- infos.Add (info);
+ infos.Add (new EmbeddedSourceDebugInformation (rows [i].Col2, this));
} else if (rows [i].Col1 == SourceLinkDebugInformation.KindIdentifier) {
infos.Add (new SourceLinkDebugInformation (Encoding.UTF8.GetString (ReadBlob (rows [i].Col2))));
} else {
@@ -3256,6 +3235,33 @@ namespace Mono.Cecil {
return infos;
}
+
+ public byte [] ReadRawEmbeddedSourceDebugInformation (uint index)
+ {
+ var signature = ReadSignature (index);
+ return signature.ReadBytes ((int) signature.sig_length);
+ }
+
+ public Row<byte [], bool> ReadEmbeddedSourceDebugInformation (uint index)
+ {
+ var signature = ReadSignature (index);
+ var format = signature.ReadInt32 ();
+ var length = signature.sig_length - 4;
+
+ if (format == 0) {
+ return new Row<byte [], bool> (signature.ReadBytes ((int) length), false);
+ } else if (format > 0) {
+ var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length));
+ var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document
+ var decompressed_stream = new MemoryStream (decompressed_document);
+
+ using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
+ deflate_stream.CopyTo (decompressed_stream);
+
+ return new Row<byte [], bool> (decompressed_document, true);
+ } else
+ throw new NotSupportedException ();
+ }
}
sealed class SignatureReader : ByteBuffer {
diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs
index 200410e..3f17a82 100644
--- a/Mono.Cecil/AssemblyWriter.cs
+++ b/Mono.Cecil/AssemblyWriter.cs
@@ -2422,6 +2422,13 @@ namespace Mono.Cecil {
void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source)
{
var signature = CreateSignatureWriter ();
+
+ if (!embedded_source.resolved) {
+ signature.WriteBytes (embedded_source.ReadRawEmbeddedSourceDebugInformation ());
+ AddCustomDebugInformation (provider, embedded_source, signature);
+ return;
+ }
+
var content = embedded_source.content ?? Empty<byte>.Array;
if (embedded_source.compress) {
signature.WriteInt32 (content.Length);
diff --git a/Test/Mono.Cecil.Tests/PortablePdbTests.cs b/Test/Mono.Cecil.Tests/PortablePdbTests.cs
index b0c1f32..43b8cfe 100644
--- a/Test/Mono.Cecil.Tests/PortablePdbTests.cs
+++ b/Test/Mono.Cecil.Tests/PortablePdbTests.cs
@@ -491,9 +491,12 @@ namespace Mono.Cecil.Tests {
public void EmbeddedSource ()
{
TestModule ("embedcs.exe", module => {
+ }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider));
+
+ TestModule ("embedcs.exe", module => {
var program = GetDocument (module.GetType ("Program"));
var program_src = GetSourceDebugInfo (program);
- Assert.IsTrue (program_src.compress);
+ Assert.IsTrue (program_src.Compress);
var program_src_content = Encoding.UTF8.GetString (program_src.Content);
Assert.AreEqual (Normalize (@"using System;
@@ -533,7 +536,7 @@ class Program
var a = GetDocument (module.GetType ("A"));
var a_src = GetSourceDebugInfo (a);
- Assert.IsFalse (a_src.compress);
+ Assert.IsFalse (a_src.Compress);
var a_src_content = Encoding.UTF8.GetString (a_src.Content);
Assert.AreEqual (Normalize (@"class A
{