diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MrtProcessedExportAddressTableNode.cs | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MrtProcessedExportAddressTableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MrtProcessedExportAddressTableNode.cs index 2981c0381..40c60b8bd 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MrtProcessedExportAddressTableNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MrtProcessedExportAddressTableNode.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Linq; using System.Collections.Generic; using Internal.Text; @@ -24,7 +25,7 @@ namespace ILCompiler.DependencyAnalysis _factory = factory; } - public event Func<uint, IExportableSymbolNode, bool> ReportExportedItem; + public event Func<uint, IExportableSymbolNode, uint> ReportExportedItem; public event Func<uint> GetInitialExportOrdinal; public void AddExportableSymbol(IExportableSymbolNode exportableSymbol) @@ -69,6 +70,13 @@ namespace ILCompiler.DependencyAnalysis builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); + // + // Entries in the export table need to be sorted by ordinals. When compiling using baseline TOC files, we reuse + // the ordinals from the baseline for sorting, otherwise we start assigning new sequential ordinals. Export entries that do + // not exist in the baseline will get new sequential ordinals, but for determinism, they are also pre-sorted using the + // CompilerComparer logic + // + ISortableSymbolNode[] symbolNodes = new ISortableSymbolNode[_exportableSymbols.Count]; _exportableSymbols.CopyTo(symbolNodes); Array.Sort(symbolNodes, new CompilerComparer()); @@ -77,12 +85,17 @@ namespace ILCompiler.DependencyAnalysis builder.EmitInt(symbolNodes.Length); // Count of exported symbols in this table uint index = GetInitialExportOrdinal == null ? 1 : GetInitialExportOrdinal(); + Dictionary<uint, ISortableSymbolNode> symbolsOridnalMap = new Dictionary<uint, ISortableSymbolNode>(); foreach (ISortableSymbolNode symbol in symbolNodes) { - builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); - bool? baselineOrdinalFound = ReportExportedItem?.Invoke(index, (IExportableSymbolNode)symbol); - if (baselineOrdinalFound.HasValue && !baselineOrdinalFound.Value) - index++; + uint indexUsed = ReportExportedItem.Invoke(index, (IExportableSymbolNode)symbol); + symbolsOridnalMap.Add(indexUsed, symbol); + index += (indexUsed == index ? (uint)1 : 0); + } + + foreach (uint ordinal in symbolsOridnalMap.Keys.OrderBy(o => o)) + { + builder.EmitReloc(symbolsOridnalMap[ordinal], RelocType.IMAGE_REL_BASED_REL32); } return builder.ToObjectData(); |