Exemple #1
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            Debug.Assert(MethodHasAssociatedData(factory, _methodNode));

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(1);
            objData.AddSymbol(this);

            AssociatedDataFlags flags = AssociatedDataFlags.None;

            var flagsReservation = objData.ReserveByte();

            ISpecialUnboxThunkNode unboxThunkNode = _methodNode as ISpecialUnboxThunkNode;

            if (unboxThunkNode != null && unboxThunkNode.IsSpecialUnboxingThunk)
            {
                flags |= AssociatedDataFlags.HasUnboxingStubTarget;
                objData.EmitReloc(unboxThunkNode.GetUnboxingThunkTarget(factory), RelocType.IMAGE_REL_BASED_RELPTR32);
            }

            objData.EmitByte(flagsReservation, (byte)flags);

            return(objData.ToObjectData());
        }
Exemple #2
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            Debug.Assert(_dynamicInvokeMethodContainerType != null);

            // Ensure the native layout blob has been saved
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);

            objData.EmitReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType), RelocType.IMAGE_REL_BASED_RELPTR32);

            List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex);

            sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value));

            for (int i = 0; i < sortedList.Count; i++)
            {
                Debug.Assert(sortedList[i].Value * 4 == objData.CountBytes);
                var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key));

                objData.EmitInt(nameAndSig.SavedVertex.VertexOffset);
                objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32);
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            objData.AddSymbol(_endSymbol);

            // Prevent further adds now we're done writing
#if DEBUG
            if (!relocsOnly)
            {
                _dataEmitted = true;
            }
#endif

            return(objData.ToObjectData());
        }
Exemple #3
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);
            objData.EmitReloc(factory.ThreadStaticsRegion.StartSymbol, RelocType.IMAGE_REL_SECREL);
            return(objData.ToObjectData());
        }
Exemple #4
0
        public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
        {
            int gcFieldCount = 0;
            int startIndex   = 0;
            int numSeries    = 0;

            for (int i = 0; i < _gcMap.Size; i++)
            {
                // Skip non-GC fields
                if (!_gcMap[i])
                {
                    continue;
                }

                gcFieldCount++;

                if (i == 0 || !_gcMap[i - 1])
                {
                    // The cell starts a new series
                    startIndex = i;
                }

                if (i == _gcMap.Size - 1 || !_gcMap[i + 1])
                {
                    // The cell ends the current series
                    builder.EmitInt(gcFieldCount);

                    if (_isThreadStatic)
                    {
                        builder.EmitReloc((factory as UtcNodeFactory).TlsStart, RelocType.IMAGE_REL_SECREL, startIndex * factory.Target.PointerSize);
                    }
                    else
                    {
                        builder.EmitReloc(factory.TypeGCStaticsSymbol(_type), RelocType.IMAGE_REL_BASED_RELPTR32, startIndex * factory.Target.PointerSize);
                    }

                    gcFieldCount = 0;
                    numSeries++;
                }
            }

            Debug.Assert(numSeries == NumSeries);
        }
Exemple #5
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 }));
            }

            // Zero out the dictionary so that we AV if someone tries to insert after we're done.
            _insertedSymbolsDictionary = null;

            var builder = new ObjectDataBuilder(factory, relocsOnly);

            foreach (SymbolAndDelta symbolAndDelta in _insertedSymbols)
            {
                if (factory.Target.Abi == TargetAbi.ProjectN)
                {
                    int delta = symbolAndDelta.Delta;
                    if (symbolAndDelta.Symbol.RepresentsIndirectionCell)
                    {
                        delta = (int)((uint)delta | IndirectionConstants.RVAPointsToIndirection);
                    }
                    builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_ADDR32NB, delta);
                }
                else if (factory.Target.SupportsRelativePointers)
                {
                    // TODO: set low bit if the linkage of the symbol is IAT_PVALUE.
                    builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_RELPTR32, symbolAndDelta.Delta);
                }
                else
                {
                    builder.EmitPointerReloc(symbolAndDelta.Symbol, symbolAndDelta.Delta);
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

            builder.AddSymbol(this);
            builder.AddSymbol(_endSymbol);

            return(builder.ToObjectData());
        }
Exemple #6
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(4);
            objData.AddSymbol(this);

            if (BuildSealedVTableSlots(factory, relocsOnly))
            {
                for (int i = 0; i < _sealedVTableEntries.Count; i++)
                {
                    MethodDesc canonImplMethod = _sealedVTableEntries[i].GetCanonMethodTarget(CanonicalFormKind.Specific);
                    objData.EmitReloc(factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType), RelocType.IMAGE_REL_BASED_RELPTR32);
                }
            }

            return(objData.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());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // The dependency tracking of this node currently does nothing because the data emission relies
            // the set of compiled methods which has an incomplete state during dependency tracking.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);
            objData.AddSymbol(_endSymbol);

            foreach (var mappingEntry in factory.MetadataManager.GetStackTraceMapping(factory))
            {
                objData.EmitReloc(factory.MethodEntrypoint(mappingEntry.Entity), RelocType.IMAGE_REL_BASED_RELPTR32);
                objData.EmitInt(mappingEntry.MetadataHandle);
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            return(objData.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Ensure the native layout blob has been saved
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);

            if (_methodToTemplateIndex == null)
            {
                BuildMethodToIdMap(factory);
            }

            TypeDesc containerType = null;

            foreach (var method in _methodToTemplateIndex.Keys)
            {
                Debug.Assert(containerType == null || containerType == method.OwningType);
                containerType = method.OwningType;
#if !DEBUG
                break;
#endif
            }

            if (factory.Target.SupportsRelativePointers)
            {
                objData.EmitReloc(factory.NecessaryTypeSymbol(containerType), RelocType.IMAGE_REL_BASED_RELPTR32);
            }
            else
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(containerType));
            }

            List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex);
            sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value));

            for (int i = 0; i < sortedList.Count; i++)
            {
                var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key));

                if (factory.Target.SupportsRelativePointers)
                {
                    objData.EmitInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32);
                }
                else
                {
                    objData.EmitNaturalInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(sortedList[i].Key));
                }
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            objData.AddSymbol(_endSymbol);

            return(objData.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 }));
            }

            ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory, relocsOnly);

            // Emit number of dictionaries in table
            objDataBuilder.AddSymbol(this);
            IReadOnlyCollection <GenericDictionaryNode> dictionariesEmitted = factory.MetadataManager.GetCompiledGenericDictionaries();

            objDataBuilder.EmitInt(dictionariesEmitted.Count);
            DebugInfoBlob signatureData = new DebugInfoBlob();

            BlobBuilder          signatureBlobBuilder = new BlobBuilder();
            BlobBuilder          signatureLenBuilder  = new BlobBuilder();
            ManagedBinaryEmitter pseudoAssembly       = factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly;

            foreach (GenericDictionaryNode dictionary in dictionariesEmitted)
            {
                objDataBuilder.EmitReloc(dictionary, RelocType.IMAGE_REL_BASED_ADDR32NB);
                objDataBuilder.EmitUInt(signatureData.Size());

                signatureBlobBuilder.Clear();

                int typeDictLen   = dictionary.TypeInstantiation.IsNull ? 0 : dictionary.TypeInstantiation.Length;
                int methodDictLen = dictionary.MethodInstantiation.IsNull ? 0 : dictionary.MethodInstantiation.Length;
                signatureBlobBuilder.WriteCompressedInteger(typeDictLen + methodDictLen);

                if (typeDictLen != 0)
                {
                    foreach (TypeDesc type in dictionary.TypeInstantiation)
                    {
                        pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder);
                    }
                }

                if (methodDictLen != 0)
                {
                    foreach (TypeDesc type in dictionary.MethodInstantiation)
                    {
                        pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder);
                    }
                }

                int blobSize = signatureBlobBuilder.Count;

                signatureLenBuilder.Clear();
                signatureLenBuilder.WriteCompressedInteger(blobSize);

                // Prepend the signature data with a length
                signatureData.WriteBuffer(signatureLenBuilder);
                // And then attach the actual signature data
                signatureData.WriteBuffer(signatureBlobBuilder);
            }

            // Attach signature information to end after all of the rva/offset pairs
            objDataBuilder.EmitBytes(signatureData.ToArray());

            return(objDataBuilder.ToObjectData());
        }
Exemple #11
0
 public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
 {
     dataBuilder.RequireInitialPointerAlignment();
     dataBuilder.EmitReloc(Target, RelocType.IMAGE_REL_BASED_ADDR32NB);
 }
Exemple #12
0
        private ObjectNode.ObjectData EncodeEHInfo()
        {
            var builder = new ObjectDataBuilder();
            builder.Alignment = 1;

            // TODO: Filter out duplicate clauses

            builder.EmitCompressedUInt((uint)_ehClauses.Length);

            for (int i = 0; i < _ehClauses.Length; i++)
            {
                var clause = _ehClauses[i];
                RhEHClauseKind clauseKind;

                if (((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FAULT) != 0) ||
                    ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FINALLY) != 0))
                {
                    clauseKind = RhEHClauseKind.RH_EH_CLAUSE_FAULT;
                }
                else
                if ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FILTER) != 0)
                {
                    clauseKind = RhEHClauseKind.RH_EH_CLAUSE_FILTER;
                }
                else
                {
                    clauseKind = RhEHClauseKind.RH_EH_CLAUSE_TYPED;
                }

                builder.EmitCompressedUInt((uint)clause.TryOffset);

                // clause.TryLength returned by the JIT is actually end offset...
                // https://github.com/dotnet/coreclr/issues/3585
                int tryLength = (int)clause.TryLength - (int)clause.TryOffset;
                builder.EmitCompressedUInt((uint)((tryLength << 2) | (int)clauseKind));

                switch (clauseKind)
                {
                    case RhEHClauseKind.RH_EH_CLAUSE_TYPED:
                        {
                            builder.EmitCompressedUInt(clause.HandlerOffset);

                            var methodIL = (MethodIL)HandleToObject((IntPtr)_methodScope);
                            var type = (TypeDesc)methodIL.GetObject((int)clause.ClassTokenOrOffset);
                            var typeSymbol = _compilation.NodeFactory.NecessaryTypeSymbol(type);

                            RelocType rel = (_compilation.NodeFactory.Target.IsWindows) ?
                                RelocType.IMAGE_REL_BASED_ABSOLUTE :
                                RelocType.IMAGE_REL_BASED_REL32;

                            builder.EmitReloc(typeSymbol, rel);
                        }
                        break;
                    case RhEHClauseKind.RH_EH_CLAUSE_FAULT:
                        builder.EmitCompressedUInt(clause.HandlerOffset);
                        break;
                    case RhEHClauseKind.RH_EH_CLAUSE_FILTER:
                        builder.EmitCompressedUInt(clause.HandlerOffset);
                        builder.EmitCompressedUInt(clause.ClassTokenOrOffset);
                        break;
                }
            }

            return builder.ToObjectData();
        }
Exemple #13
0
 public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
 {
     builder.EmitReloc(factory.TypeThreadStaticsSymbol(_type), RelocType.IMAGE_REL_SECREL);
 }