[mtouch] Use a custom symbol writer to ensure only pdb file names are written to assemblies.

We need our 32-bit and 64-bit assemblies to be identical so that we can avoid
duplicating the .dll in fat apps.

One difference used to be that the .dll contained the full path to the
corresponding .pdb ([1]), but we changed cecil to only write the filename
([2]). Unfortunately this change breaks something else, so it has to be
reverted ([3]).

This implements a different solution: we provide a custom symbol writer to
Cecil, which only writes the filename of the pdb in the .dll, not the full
path.

[1]: https://bugzilla.xamarin.com/show_bug.cgi?id=54578
[2]: https://github.com/jbevain/cecil/issues/372
[3]: https://github.com/jbevain/cecil/pull/554

(cherry picked from commit 53874c863996656eaba43a5582731b93eb6f53b7)

# Conflicts:
#	tools/mtouch/mtouch.csproj
This commit is contained in:
Rolf Bjarne Kvinge 2019-01-28 07:21:26 +01:00 коммит произвёл Alexander Köplinger
Родитель 0f49b41513
Коммит 5571877312
5 изменённых файлов: 97 добавлений и 1 удалений

Просмотреть файл

@ -162,7 +162,11 @@ namespace Xamarin.Bundler {
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);

Просмотреть файл

@ -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 ();
}
}

Просмотреть файл

@ -382,6 +382,9 @@
<Compile Include="..\..\external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs">
<Link>external\PListObject.cs</Link>
</Compile>
<Compile Include="..\linker\CustomSymbolWriter.cs">
<Link>Xamarin.Linker\CustomSymbolWriter.cs</Link>
</Compile>
<Compile Include="..\..\src\ObjCRuntime\CpuArchitecture.cs">
<Link>external\CpuArchitecture.cs</Link>
</Compile>

Просмотреть файл

@ -135,6 +135,7 @@ namespace MonoTouch.Tuner {
context.StaticRegistrar = options.Target.StaticRegistrar;
context.Target = options.Target;
context.ExcludedFeatures = new [] { "remoting", "com", "sre" };
context.SymbolWriterProvider = new CustomSymbolWriterProvider ();
options.LinkContext = context;
return context;

Просмотреть файл

@ -389,6 +389,9 @@
<Compile Include="..\linker\MonoTouch.Tuner\RemoveBitcodeIncompatibleCodeStep.cs">
<Link>MonoTouch.Tuner\RemoveBitcodeIncompatibleCodeStep.cs</Link>
</Compile>
<Compile Include="..\linker\CustomSymbolWriter.cs">
<Link>Xamarin.Linker\CustomSymbolWriter.cs</Link>
</Compile>
<Compile Include="..\..\src\ObjCRuntime\CpuArchitecture.cs">
<Link>external\CpuArchitecture.cs</Link>
</Compile>