Skip to content

Commit 15d48ef

Browse files
committed
Update Cecil submodule to latest
Read embedded pdbs Copy debug information for scopes and imports Taken from Alexx999#3 Make the output assembly MVID deterministic Fix test locking dlls Add .ToArray() to flush the Linq expression so that it is not evaluated more than once. Better error if the pdb doesn't exist Use cecil from https://github.com/KirillOsenkov/cecil/tree/ilrepack
1 parent 96a60b6 commit 15d48ef

File tree

14 files changed

+206
-49
lines changed

14 files changed

+206
-49
lines changed

.gitmodules

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "cecil"]
22
path = cecil
3-
url = https://github.com/gluck/cecil.git
3+
url = https://github.com/KirillOsenkov/cecil
4+
branch = ilrepack

Directory.Build.props

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<Project>
22

3+
<PropertyGroup>
4+
<LangVersion>latest</LangVersion>
5+
</PropertyGroup>
6+
37
<ItemGroup>
48
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
59
</ItemGroup>

ILRepack.IntegrationTests/NuGet/RepackNuGetTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public void VerifiesMergedPdbUnchangedSourceIndexationForTfsIndexation()
136136
{
137137
// This test requires Mono.Cecil.Pdb.dll. Indicate a dependency such that
138138
// the reference is not accidentally removed.
139-
_ = typeof(Mono.Cecil.Pdb.PdbReader);
139+
_ = typeof(Mono.Cecil.Pdb.PdbReaderProvider);
140140

141141
var platform = Platform.From(
142142
Package.From("TfsIndexer", "1.2.4"),

ILRepack.IntegrationTests/NuGet/TestHelpers.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,20 @@ public static void DoRepackForCmd(IEnumerable<string> args)
3838

3939
private static void ReloadAndCheckReferences(RepackOptions repackOptions)
4040
{
41-
var outputFile = AssemblyDefinition.ReadAssembly(repackOptions.OutputFile, new ReaderParameters(ReadingMode.Immediate));
42-
var mergedFiles = repackOptions.ResolveFiles().Select(f => AssemblyDefinition.ReadAssembly(f, new ReaderParameters(ReadingMode.Deferred)));
41+
using var ar = new DefaultAssemblyResolver();
42+
using var outputFile = AssemblyDefinition.ReadAssembly(repackOptions.OutputFile, new ReaderParameters(ReadingMode.Immediate));
43+
var mergedFiles = repackOptions
44+
.ResolveFiles()
45+
.Select(f => AssemblyDefinition.ReadAssembly(f, new ReaderParameters(ReadingMode.Deferred)))
46+
.ToArray();
4347
foreach (var a in outputFile.MainModule.AssemblyReferences.Where(x => mergedFiles.Any(y => repackOptions.KeepOtherVersionReferences ? x.FullName == y.FullName : x.Name == y.Name.Name)))
4448
{
4549
Assert.Fail($"Merged assembly retains a reference to one (or more) of the merged files: {a.FullName}");
4650
}
51+
foreach (var a in mergedFiles)
52+
{
53+
a.Dispose();
54+
}
4755
}
4856

4957
public static void SaveAs(Stream input, string directory, string fileName)

ILRepack/IKVMLineIndexer.cs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ internal class IKVMLineIndexer
1717
{
1818
private readonly IRepackContext repack;
1919
private bool enabled;
20-
private LineNumberWriter lineNumberWriter;
2120
private string fileName;
2221
private TypeReference sourceFileAttributeTypeReference;
2322
private TypeReference lineNumberTableAttributeTypeReference;
@@ -41,29 +40,29 @@ public IKVMLineIndexer(IRepackContext ilRepack, bool doLineIndexing)
4140

4241
public void Reset()
4342
{
44-
lineNumberWriter = null;
4543
fileName = null;
4644
}
4745

4846
public void PreMethodBodyRepack(MethodBody body, MethodDefinition parent)
4947
{
50-
if (!enabled)
48+
if (!enabled || !parent.DebugInformation.HasSequencePoints)
5149
return;
5250

5351
Reset();
5452
if (!parent.CustomAttributes.Any(x => x.Constructor.DeclaringType.Name == "LineNumberTableAttribute"))
5553
{
56-
lineNumberWriter = new LineNumberWriter(body.Instructions.Count / 4);
54+
var lineNumberWriter = new LineNumberWriter(body.Instructions.Count / 4);
55+
foreach (var sp in parent.DebugInformation.SequencePoints)
56+
{
57+
AddSeqPoint(sp, lineNumberWriter);
58+
}
59+
PostMethodBodyRepack(parent, lineNumberWriter);
5760
}
5861
}
5962

60-
public void ProcessMethodBodyInstruction(Instruction instr)
63+
private void AddSeqPoint(SequencePoint currentSeqPoint, LineNumberWriter lineNumberWriter)
6164
{
62-
if (!enabled)
63-
return;
64-
65-
var currentSeqPoint = instr.SequencePoint;
66-
if (lineNumberWriter != null && currentSeqPoint != null)
65+
if (currentSeqPoint != null)
6766
{
6867
if (fileName == null && currentSeqPoint.Document != null)
6968
{
@@ -84,25 +83,22 @@ public void ProcessMethodBodyInstruction(Instruction instr)
8483
{
8584
if (lineNumberWriter.LineNo > 0)
8685
{
87-
lineNumberWriter.AddMapping(instr.Offset, -1);
86+
lineNumberWriter.AddMapping(currentSeqPoint.Offset, -1);
8887
}
8988
}
9089
else
9190
{
9291
if (lineNumberWriter.LineNo != currentSeqPoint.StartLine)
9392
{
94-
lineNumberWriter.AddMapping(instr.Offset, currentSeqPoint.StartLine);
93+
lineNumberWriter.AddMapping(currentSeqPoint.Offset, currentSeqPoint.StartLine);
9594
}
9695
}
9796
}
9897
}
9998

100-
public void PostMethodBodyRepack(MethodDefinition parent)
99+
private void PostMethodBodyRepack(MethodDefinition parent, LineNumberWriter lineNumberWriter)
101100
{
102-
if (!enabled)
103-
return;
104-
105-
if (lineNumberWriter != null && lineNumberWriter.Count > 0)
101+
if (lineNumberWriter.Count > 0)
106102
{
107103
CustomAttribute ca;
108104
if (lineNumberWriter.Count == 1)
@@ -155,7 +151,7 @@ public void PostRepackReferences()
155151
IMetadataScope ikvmRuntimeReference = repack.TargetAssemblyMainModule.AssemblyReferences.FirstOrDefault(r => r.Name == "IKVM.Runtime");
156152
if (ikvmRuntimeReference == null)
157153
{
158-
ikvmRuntimeReference = repack.MergeScope(repack.GlobalAssemblyResolver.Resolve("IKVM.Runtime").Name);
154+
ikvmRuntimeReference = repack.MergeScope(repack.GlobalAssemblyResolver.Resolve(new AssemblyNameReference("IKVM.Runtime", null)).Name);
159155
}
160156
if (ikvmRuntimeReference == null)
161157
{

ILRepack/ILRepack.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using System.Text.RegularExpressions;
2222
using ILRepacking.Steps;
2323
using Mono.Cecil;
24+
using Mono.Cecil.Cil;
2425
using Mono.Cecil.PE;
2526
using Mono.Unix.Native;
2627
using ILRepacking.Mixins;
@@ -112,9 +113,10 @@ private AssemblyDefinitionContainer ReadInputAssembly(string assembly, bool isPr
112113
{
113114
ReaderParameters rp = new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = GlobalAssemblyResolver };
114115
// read PDB/MDB?
115-
if (Options.DebugInfo && (File.Exists(Path.ChangeExtension(assembly, "pdb")) || File.Exists(assembly + ".mdb")))
116+
if (Options.DebugInfo)
116117
{
117118
rp.ReadSymbols = true;
119+
rp.SymbolReaderProvider = new DefaultSymbolReaderProvider(throwIfNoSymbol: false);
118120
}
119121
AssemblyDefinition mergeAsm;
120122
try
@@ -144,6 +146,7 @@ private AssemblyDefinitionContainer ReadInputAssembly(string assembly, bool isPr
144146

145147
if (!Options.AllowZeroPeKind && (mergeAsm.MainModule.Attributes & ModuleAttributes.ILOnly) == 0)
146148
throw new ArgumentException("Failed to load assembly with Zero PeKind: " + assembly);
149+
GlobalAssemblyResolver.RegisterAssembly(mergeAsm);
147150

148151
return new AssemblyDefinitionContainer
149152
{
@@ -264,7 +267,6 @@ public void Repack()
264267

265268
// Read input assemblies only after all properties are set.
266269
ReadInputAssemblies();
267-
GlobalAssemblyResolver.RegisterAssemblies(MergedAssemblies);
268270

269271
_platformFixer = new PlatformFixer(this, PrimaryAssemblyMainModule.Runtime);
270272
_mappingHandler = new MappingHandler();
@@ -309,7 +311,7 @@ public void Repack()
309311
}
310312
// set the main module attributes
311313
TargetAssemblyMainModule.Attributes = PrimaryAssemblyMainModule.Attributes;
312-
TargetAssemblyMainModule.Win32ResourceDirectory = MergeWin32Resources(PrimaryAssemblyMainModule.Win32ResourceDirectory);
314+
TargetAssemblyMainModule.Win32ResourceDirectory = MergeWin32Resources();
313315

314316
if (Options.Version != null)
315317
TargetAssemblyDefinition.Name.Version = Options.Version;
@@ -337,10 +339,17 @@ public void Repack()
337339
step.Perform();
338340
}
339341

342+
var anySymbolReader = MergedAssemblies
343+
.Select(m => m.MainModule.SymbolReader)
344+
.Where(r => r != null)
345+
.FirstOrDefault();
346+
var symbolWriterProvider = anySymbolReader?.GetWriterProvider();
340347
var parameters = new WriterParameters
341348
{
342349
StrongNameKeyPair = signingStep.KeyPair,
343-
WriteSymbols = Options.DebugInfo
350+
WriteSymbols = Options.DebugInfo && symbolWriterProvider != null,
351+
SymbolWriterProvider = symbolWriterProvider,
352+
DeterministicMvid = true
344353
};
345354
// create output directory if it does not exist
346355
var outputDir = Path.GetDirectoryName(Options.OutputFile);
@@ -350,11 +359,19 @@ public void Repack()
350359
Directory.CreateDirectory(outputDir);
351360
}
352361

362+
Logger.Info("Writing output assembly to disk");
353363
TargetAssemblyDefinition.Write(Options.OutputFile, parameters);
354364

355365
sourceServerDataStep.Write();
356366

357-
Logger.Info("Writing output assembly to disk");
367+
foreach (var assembly in MergedAssemblies)
368+
{
369+
assembly.Dispose();
370+
}
371+
372+
TargetAssemblyDefinition.Dispose();
373+
GlobalAssemblyResolver.Dispose();
374+
358375
// If this is an executable and we are on linux/osx we should copy file permissions from
359376
// the primary assembly
360377
if (isUnixEnvironment && (kind == ModuleKind.Console || kind == ModuleKind.Windows))
@@ -405,13 +422,17 @@ private void ResolveSearchDirectories()
405422
}
406423
}
407424

408-
private ResourceDirectory MergeWin32Resources(ResourceDirectory primary)
425+
private ResourceDirectory MergeWin32Resources()
409426
{
410-
if (primary == null)
411-
return null;
427+
var primary = PrimaryAssemblyMainModule.ReadWin32ResourceDirectory() ?? new ResourceDirectory();
428+
412429
foreach (var ass in OtherAssemblies)
413430
{
414-
MergeDirectory(new List<ResourceEntry>(), primary, ass, ass.MainModule.Win32ResourceDirectory);
431+
var directory = ass.MainModule.ReadWin32ResourceDirectory();
432+
if (directory != null)
433+
{
434+
MergeDirectory(new List<ResourceEntry>(), primary, ass, directory);
435+
}
415436
}
416437
return primary;
417438
}

ILRepack/Mixins/Mixins.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using Mono.Collections.Generic;
3+
4+
namespace ILRepacking.Mixins
5+
{
6+
static class CollectionMixins
7+
{
8+
public static void AddRange<T>(this Collection<T> destination, IEnumerable<T> source)
9+
{
10+
foreach (var item in source)
11+
{
12+
destination.Add(item);
13+
}
14+
}
15+
}
16+
}

ILRepack/PlatformFixer.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private void FixPlatformVersion(ParameterDefinition pd)
192192
private void FixPlatformVersion(GenericParameter gp)
193193
{
194194
if (gp.HasConstraints)
195-
foreach (TypeReference tr in gp.Constraints)
195+
foreach (var tr in gp.Constraints)
196196
FixPlatformVersion(tr);
197197
if (gp.HasCustomAttributes)
198198
foreach (CustomAttribute ca in gp.CustomAttributes)
@@ -202,6 +202,11 @@ private void FixPlatformVersion(GenericParameter gp)
202202
FixPlatformVersion(gp1);
203203
}
204204

205+
private void FixPlatformVersion(GenericParameterConstraint gp)
206+
{
207+
FixPlatformVersion(gp.ConstraintType);
208+
}
209+
205210
private void FixPlatformVersion(CustomAttribute ca)
206211
{
207212
FixPlatformVersion(ca.Constructor);

ILRepack/ReferenceFixator.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,27 @@ internal void FixMethodVisibility(TypeDefinition type)
111111
FixOverridenMethodDef(meth);
112112
}
113113

114+
private void FixReferences(Collection<GenericParameterConstraint> constraints)
115+
{
116+
foreach (var constraint in constraints)
117+
{
118+
constraint.ConstraintType = Fix(constraint.ConstraintType);
119+
FixReferences(constraint.CustomAttributes);
120+
}
121+
}
122+
114123
internal void FixReferences(TypeDefinition type)
115124
{
116125
FixReferences(type.GenericParameters);
117126

118127
type.BaseType = Fix(type.BaseType);
119128

120129
// interfaces before methods, because methods will have to go through them
121-
FixReferences(type.Interfaces);
130+
foreach (InterfaceImplementation nested in type.Interfaces)
131+
{
132+
nested.InterfaceType = Fix(nested.InterfaceType);
133+
FixReferences(nested.CustomAttributes);
134+
}
122135

123136
// nested types first
124137
foreach (TypeDefinition nested in type.NestedTypes)
@@ -332,7 +345,7 @@ private bool IsAnnotation(TypeDefinition typeAttribute)
332345
{
333346
if (typeAttribute == null)
334347
return false;
335-
if (typeAttribute.Interfaces.Any(@interface => @interface.FullName == "java.lang.annotation.Annotation"))
348+
if (typeAttribute.Interfaces.Any(@interface => @interface.InterfaceType.FullName == "java.lang.annotation.Annotation"))
336349
return true;
337350
return typeAttribute.BaseType != null && IsAnnotation(typeAttribute.BaseType.Resolve());
338351
}

ILRepack/RepackAssemblyResolver.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
using Mono.Cecil;
2-
using System.Collections.Generic;
32

43
namespace ILRepacking
54
{
65
public class RepackAssemblyResolver : DefaultAssemblyResolver
76
{
8-
public void RegisterAssemblies(IList<AssemblyDefinition> mergedAssemblies)
7+
public new void RegisterAssembly(AssemblyDefinition assembly)
98
{
10-
foreach (var assemblyDefinition in mergedAssemblies)
11-
{
12-
RegisterAssembly(assemblyDefinition);
13-
}
9+
base.RegisterAssembly(assembly);
1410
}
1511
}
1612
}

0 commit comments

Comments
 (0)