diff --git a/tools/common/Application.cs b/tools/common/Application.cs
index d0e3dc207d73..12a607130df4 100644
--- a/tools/common/Application.cs
+++ b/tools/common/Application.cs
@@ -154,7 +154,11 @@ public static void SaveAssembly (AssemblyDefinition assembly, string destination
main.ReadSymbols (provider.GetSymbolReader (main, main.FileName));
}
- var wp = new WriterParameters () { WriteSymbols = symbols };
+ var wp = new WriterParameters () {
+ WriteSymbols = symbols,
+ SymbolWriterProvider = symbols ? new CustomSymbolWriterProvider () : null,
+ };
+
// re-write symbols, if available, so the new tokens will match
assembly.Write (destination, wp);
diff --git a/tools/linker/CustomSymbolWriter.cs b/tools/linker/CustomSymbolWriter.cs
new file mode 100644
index 000000000000..bc26835f1080
--- /dev/null
+++ b/tools/linker/CustomSymbolWriter.cs
@@ -0,0 +1,85 @@
+using System;
+using System.IO;
+using System.Text;
+
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+namespace Xamarin.Linker
+{
+ public sealed class CustomSymbolWriterProvider : ISymbolWriterProvider
+ {
+ readonly DefaultSymbolWriterProvider default_symbol_writer_provider = new DefaultSymbolWriterProvider ();
+
+ public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string filename)
+ => new CustomSymbolWriter (default_symbol_writer_provider.GetSymbolWriter (module, filename));
+
+ public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
+ => new CustomSymbolWriter (default_symbol_writer_provider.GetSymbolWriter (module, symbolStream));
+ }
+
+ // This is symbol writer wraps another symbol writer, and changes one thing:
+ // it writes the filename part of the pdb (as opposed to the full path), in the debug header of the dll.
+ // References:
+ // https://bugzilla.xamarin.com/show_bug.cgi?id=54578 (Assemblies are duplicated in fat apps when built with .pdb, because pdb paths are different)
+ // https://github.com/jbevain/cecil/issues/372 (first attempt at a fix: make cecil write the filename only)
+ // https://github.com/jbevain/cecil/pull/554 (first fix attempt broke something else, so it had to be reverted)
+ public sealed class CustomSymbolWriter : ISymbolWriter
+ {
+ readonly ISymbolWriter _symbolWriter;
+
+ public CustomSymbolWriter (ISymbolWriter symbolWriter)
+ {
+ _symbolWriter = symbolWriter;
+ }
+
+ public ImageDebugHeader GetDebugHeader ()
+ {
+ var header = _symbolWriter.GetDebugHeader ();
+ if (!header.HasEntries)
+ return header;
+
+ for (int i = 0; i < header.Entries.Length; i++) {
+ header.Entries [i] = ProcessEntry (header.Entries [i]);
+ }
+
+ return header;
+ }
+
+ static ImageDebugHeaderEntry ProcessEntry (ImageDebugHeaderEntry entry)
+ {
+ if (entry.Directory.Type != ImageDebugType.CodeView)
+ return entry;
+
+ var reader = new BinaryReader (new MemoryStream (entry.Data));
+ var newDataStream = new MemoryStream ();
+ var writer = new BinaryWriter (newDataStream);
+
+ var sig = reader.ReadUInt32 ();
+ if (sig != 0x53445352)
+ return entry;
+
+ writer.Write (sig); // RSDS
+ writer.Write (reader.ReadBytes (16)); // MVID
+ writer.Write (reader.ReadUInt32 ()); // Age
+
+ var fullPath = Encoding.UTF8.GetString (reader.ReadBytes (entry.Data.Length - 1 - 24)); // length - ending \0 - RSDS+MVID+AGE
+
+ writer.Write (Encoding.UTF8.GetBytes (Path.GetFileName (fullPath)));
+ writer.Write ((byte) 0);
+
+ var newData = newDataStream.ToArray ();
+
+ var directory = entry.Directory;
+ directory.SizeOfData = newData.Length;
+
+ return new ImageDebugHeaderEntry (directory, newData);
+ }
+
+ public ISymbolReaderProvider GetReaderProvider () => _symbolWriter.GetReaderProvider ();
+
+ public void Write (MethodDebugInformation info) => _symbolWriter.Write (info);
+
+ public void Dispose () => _symbolWriter.Dispose ();
+ }
+}
diff --git a/tools/mmp/mmp.csproj b/tools/mmp/mmp.csproj
index 30a89bf1ccbd..f0513395af44 100644
--- a/tools/mmp/mmp.csproj
+++ b/tools/mmp/mmp.csproj
@@ -379,6 +379,9 @@
external\PListObject.cs
+
+ Xamarin.Linker\CustomSymbolWriter.cs
+
diff --git a/tools/mtouch/Tuning.cs b/tools/mtouch/Tuning.cs
index 19be96cd08f2..278f85b3c42d 100644
--- a/tools/mtouch/Tuning.cs
+++ b/tools/mtouch/Tuning.cs
@@ -135,6 +135,7 @@ static MonoTouchLinkContext CreateLinkContext (LinkerOptions options, Pipeline p
context.StaticRegistrar = options.Target.StaticRegistrar;
context.Target = options.Target;
context.ExcludedFeatures = new [] { "remoting", "com", "sre" };
+ context.SymbolWriterProvider = new CustomSymbolWriterProvider ();
options.LinkContext = context;
return context;
diff --git a/tools/mtouch/mtouch.csproj b/tools/mtouch/mtouch.csproj
index 12f8a5f809a6..9d17d6b41680 100644
--- a/tools/mtouch/mtouch.csproj
+++ b/tools/mtouch/mtouch.csproj
@@ -383,6 +383,9 @@
Linker\TypeNameParser.cs
+
+ Xamarin.Linker\CustomSymbolWriter.cs
+