Пример #1
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();
            builder.AddSymbol(this);

            ISortableSymbolNode[] symbolNodes = new ISortableSymbolNode[_exportableSymbols.Count];
            _exportableSymbols.CopyTo(symbolNodes);
            Array.Sort(symbolNodes, new CompilerComparer());

            builder.EmitInt(1);                  // Export table version 1
            builder.EmitInt(symbolNodes.Length); // Count of exported symbols in this table

            int index = 1;

            foreach (ISortableSymbolNode symbol in symbolNodes)
            {
                builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
                ReportExportedItem?.Invoke(index, (IExportableSymbolNode)symbol);
                index++;
            }

            return(builder.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var builder = new ObjectDataBuilder(factory, relocsOnly);

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

            builder.EmitInt(1);                  // Export table version 1
            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)
            {
                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());
        }