Exemple #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());
        }
Exemple #2
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            int delta = GCStaticRegionConstants.Uninitialized;

            // Set the flag that indicates next pointer following EEType is the preinit data
            bool isPreinitialized = _preinitializationInfo != null && _preinitializationInfo.IsPreinitialized;

            if (isPreinitialized)
            {
                delta |= GCStaticRegionConstants.HasPreInitializedData;
            }

            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

            if (isPreinitialized)
            {
                builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
            }

            builder.AddSymbol(this);

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

            RelocType reloc = factory.Target.Abi == TargetAbi.CoreRT ?
                              RelocType.IMAGE_REL_BASED_RELPTR32 : RelocType.IMAGE_REL_BASED_ADDR32NB;

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

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

            builder.RequireInitialPointerAlignment();

            if (factory.Target.Abi == TargetAbi.CoreRT)
            {
                int delta = GCStaticRegionConstants.Uninitialized;

                // Set the flag that indicates next pointer following EEType is the preinit data
                if (_preInitFieldInfos != null)
                {
                    delta |= GCStaticRegionConstants.HasPreInitializedData;
                }

                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

                if (_preInitFieldInfos != null)
                {
                    builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
                }
            }
            else
            {
                builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt);

                // @TODO - emit the frozen array node reloc
                builder.EmitZeros(_type.GCStaticFieldSize.AsInt);
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
Exemple #5
0
 public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
 {
     // At runtime, an instance of the GCStaticEEType will be created and a GCHandle to it
     // will be written in this location.
     builder.RequireInitialPointerAlignment();
     builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
 }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            builder.AddSymbol(this);

            ISymbolNode nameSymbol       = factory.ConstantUtf8String(_pInvokeModuleData.ModuleName);
            ISymbolNode moduleTypeSymbol = factory.NecessaryTypeSymbol(_pInvokeModuleData.DeclaringModule.GetGlobalModuleType());

            //
            // Emit a ModuleFixupCell struct
            //

            builder.EmitZeroPointer();
            builder.EmitPointerReloc(nameSymbol);
            builder.EmitPointerReloc(moduleTypeSymbol);

            uint dllImportSearchPath = 0;

            if (_pInvokeModuleData.DllImportSearchPath.HasValue)
            {
                dllImportSearchPath = (uint)_pInvokeModuleData.DllImportSearchPath.Value;
                Debug.Assert((dllImportSearchPath & InteropDataConstants.HasDllImportSearchPath) == 0);
                dllImportSearchPath |= InteropDataConstants.HasDllImportSearchPath;
            }
            builder.EmitInt((int)dllImportSearchPath);

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

            builder.RequireInitialPointerAlignment();

            builder.AddSymbol(this);
            builder.AddSymbol(StartSymbol);

            builder.EmitInt(1);
            builder.EmitInt(_importNodes.Count);
            builder.EmitPointerReloc(factory.ExternSymbol(ExportTableToImportSymbol));


            if (!relocsOnly)
            {
                FinalizeOffsets();

                foreach (MrtImportNode node in _importNodes)
                {
                    Debug.Assert(((ISymbolDefinitionNode)node).Offset == builder.CountBytes);
                    builder.AddSymbol(node);
                    builder.EmitNaturalInt(node.Ordinal);
                }
            }

            EndSymbol.SetSymbolOffset(builder.CountBytes);
            builder.AddSymbol(EndSymbol);

            ObjectData objData = builder.ToObjectData();

            return(objData);
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { 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);

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

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

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

            return(objData.ToObjectData());
        }
 public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
 {
     ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
     builder.RequireInitialPointerAlignment();
     builder.EmitZeros(_type.ThreadStaticFieldSize.AsInt);
     builder.AddSymbol(this);
     return builder.ToObjectData();
 }
Exemple #10
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 #11
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

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

            ComputeOptionalEETypeFields(factory, relocsOnly);

            OutputGCDesc(ref objData);
            OutputComponentSize(ref objData);
            OutputFlags(factory, ref objData);
            OutputBaseSize(ref objData);
            OutputRelatedType(factory, ref objData);

            // Number of vtable slots will be only known later. Reseve the bytes for it.
            var vtableSlotCountReservation = objData.ReserveShort();

            // Number of interfaces will only be known later. Reserve the bytes for it.
            var interfaceCountReservation = objData.ReserveShort();

            objData.EmitInt(_type.GetHashCode());
            objData.EmitPointerReloc(factory.TypeManagerIndirection);

            if (EmitVirtualSlotsAndInterfaces)
            {
                // Emit VTable
                Debug.Assert(objData.CountBytes - ((ISymbolDefinitionNode)this).Offset == GetVTableOffset(objData.TargetPointerSize));
                SlotCounter virtualSlotCounter = SlotCounter.BeginCounting(ref /* readonly */ objData);
                OutputVirtualSlots(factory, ref objData, _type, _type, relocsOnly);

                // Update slot count
                int numberOfVtableSlots = virtualSlotCounter.CountSlots(ref /* readonly */ objData);
                objData.EmitShort(vtableSlotCountReservation, checked ((short)numberOfVtableSlots));

                // Emit interface map
                SlotCounter interfaceSlotCounter = SlotCounter.BeginCounting(ref /* readonly */ objData);
                OutputInterfaceMap(factory, ref objData);

                // Update slot count
                int numberOfInterfaceSlots = interfaceSlotCounter.CountSlots(ref /* readonly */ objData);
                objData.EmitShort(interfaceCountReservation, checked ((short)numberOfInterfaceSlots));
            }
            else
            {
                // If we're not emitting any slots, the number of slots is zero.
                objData.EmitShort(vtableSlotCountReservation, 0);
                objData.EmitShort(interfaceCountReservation, 0);
            }

            OutputFinalizerMethod(factory, ref objData);
            OutputOptionalFields(factory, ref objData);
            OutputNullableTypeParameter(factory, ref objData);
            OutputGenericInstantiationDetails(factory, ref objData);

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

            dataBuilder.RequireInitialPointerAlignment();
            dataBuilder.AddSymbol(this);
            EETypeRareFlags rareFlags = 0;

            short flags = (short)EETypeKind.GenericTypeDefEEType;

            if (_type.IsValueType)
            {
                flags |= (short)EETypeFlags.ValueTypeFlag;
            }
            if (_type.IsInterface)
            {
                flags |= (short)EETypeFlags.IsInterfaceFlag;
            }
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                rareFlags = rareFlags | EETypeRareFlags.HasCctorFlag;
            }
            if (_type.IsByRefLike)
            {
                rareFlags |= EETypeRareFlags.IsByRefLikeFlag;
            }

            if (rareFlags != 0)
            {
                _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, (uint)rareFlags);
            }

            if (HasOptionalFields)
            {
                flags |= (short)EETypeFlags.OptionalFieldsFlag;
            }

            if (_type.IsEnum)
            {
                flags |= (short)EETypeBuilderHelpers.ComputeElementTypeFlags(_type);
            }

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            dataBuilder.EmitPointerReloc(factory.TypeManagerIndirection);
            if (HasOptionalFields)
            {
                dataBuilder.EmitPointerReloc(_optionalFieldsNode);
            }

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

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);
            objData.EmitPointerReloc(factory.ReadyToRunHeader);

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

            builder.RequireInitialPointerAlignment();
            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), 1);
            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory, relocsOnly);

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

            builder.EmitPointerReloc(_indirectedNode, _offsetDelta);

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

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

            // Emit an aliased symbol named _tls_index for native P/Invoke code that uses TLS. This is required
            // because we do not link against libcmt.lib.
            ObjectAndOffsetSymbolNode aliasedSymbol = new ObjectAndOffsetSymbolNode(this, objData.CountBytes, "_tls_index", false);

            objData.AddSymbol(aliasedSymbol);

            // This is the TLS index field which is a 4-byte integer. Emit an 8-byte interger which includes a
            // 4-byte padding to make an pointer-sized alignment for the subsequent fields for all targets.
            objData.EmitLong(0);

            // Allocate and initialize the IMAGE_TLS_DIRECTORY PE data structure used by the OS loader to determine
            // TLS allocations. The structure is defined by the OS as following:

            /*
             *  struct _IMAGE_TLS_DIRECTORY32
             *  {
             *      DWORD StartAddressOfRawData;
             *      DWORD EndAddressOfRawData;
             *      DWORD AddressOfIndex;
             *      DWORD AddressOfCallBacks;
             *      DWORD SizeOfZeroFill;
             *      DWORD Characteristics;
             *  }
             *
             *  struct _IMAGE_TLS_DIRECTORY64
             *  {
             *      ULONGLONG StartAddressOfRawData;
             *      ULONGLONG EndAddressOfRawData;
             *      ULONGLONG AddressOfIndex;
             *      ULONGLONG AddressOfCallBacks;
             *      DWORD SizeOfZeroFill;
             *      DWORD Characteristics;
             *  }
             */
            // In order to utilize linker support, the struct variable needs to be named _tls_used
            ObjectAndOffsetSymbolNode structSymbol = new ObjectAndOffsetSymbolNode(this, objData.CountBytes, "_tls_used", false);

            objData.AddSymbol(structSymbol);
            objData.EmitPointerReloc(factory.ThreadStaticsRegion.StartSymbol); // start of tls data
            objData.EmitPointerReloc(factory.ThreadStaticsRegion.EndSymbol);   // end of tls data
            objData.EmitPointerReloc(this);                                    // address of tls_index
            objData.EmitZeroPointer();                                         // pointer to call back array
            objData.EmitInt(0);                                                // size of tls zero fill
            objData.EmitInt(0);                                                // characteristics

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

            builder.RequireInitialPointerAlignment();

            builder.AddSymbol(_standaloneGCStaticDesc);
            _standaloneGCStaticDesc.InitializeOffsetFromBeginningOfArray(0);
            builder.EmitInt(_standaloneGCStaticDesc.NumSeries);
            _standaloneGCStaticDesc.EncodeData(ref builder, factory, relocsOnly);

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

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

            NativeLayoutFieldLdTokenVertexNode ldtokenSigNode = factory.NativeLayout.FieldLdTokenVertex(_targetField);

            objData.EmitPointerReloc(factory.NativeLayout.NativeLayoutSignature(ldtokenSigNode));

            return(objData.ToObjectData());
        }
Exemple #19
0
 public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
 {
     if (factory.Target.Abi == TargetAbi.CoreRT)
     {
         // At runtime, an instance of the GCStaticEEType will be created and a GCHandle to it
         // will be written in this location.
         builder.RequireInitialPointerAlignment();
         builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
     }
     else
     {
         builder.RequireInitialAlignment(_type.ThreadStaticFieldAlignment.AsInt);
         builder.EmitZeros(_type.ThreadStaticFieldSize.AsInt);
     }
 }
Exemple #20
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

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

            if (!relocsOnly)
            {
                _owner.ComputeOptionalEETypeFields(factory, relocsOnly: false);
                objData.EmitBytes(_owner.GetOptionalFieldsData(factory));
            }

            return(objData.ToObjectData());
        }
Exemple #21
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (factory.Target.Abi == TargetAbi.CoreRT || factory.Target.Abi == TargetAbi.CppCodegen)
            {
                ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

                builder.RequireInitialPointerAlignment();

                int delta = GCStaticRegionConstants.Uninitialized;

                // Set the flag that indicates next pointer following EEType is the preinit data
                if (_preInitFieldInfos != null)
                {
                    delta |= GCStaticRegionConstants.HasPreInitializedData;
                }

                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

                if (_preInitFieldInfos != null)
                {
                    builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
                }

                builder.AddSymbol(this);

                return(builder.ToObjectData());
            }
            else
            {
                if (_preInitFieldInfos == null)
                {
                    ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

                    builder.RequireInitialPointerAlignment();

                    builder.EmitZeros(_type.GCStaticFieldSize.AsInt);

                    builder.AddSymbol(this);

                    return(builder.ToObjectData());
                }
                else
                {
                    _preInitFieldInfos.Sort(PreInitFieldInfo.FieldDescCompare);
                    return(GCStaticsPreInitDataNode.GetDataForPreInitDataField(this, _type, _preInitFieldInfos, 0, factory, relocsOnly));
                }
            }
        }
Exemple #22
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

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

            ComputeOptionalEETypeFields(factory, relocsOnly);

            OutputGCDesc(ref objData);
            OutputComponentSize(ref objData);
            OutputFlags(factory, ref objData);
            OutputBaseSize(ref objData);
            OutputRelatedType(factory, ref objData);

            // Avoid consulting VTable slots until they're guaranteed complete during final data emission
            if (EmitVirtualSlotsAndInterfaces && !relocsOnly)
            {
                OutputVirtualSlotAndInterfaceCount(factory, ref objData);
            }
            else
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
            }

            objData.EmitInt(_type.GetHashCode());
            objData.EmitPointerReloc(factory.TypeManagerIndirection);

            if (EmitVirtualSlotsAndInterfaces)
            {
                // Avoid consulting VTable slots until they're guaranteed complete during final data emission
                if (!relocsOnly)
                {
                    OutputVirtualSlots(factory, ref objData, _type, _type);
                }

                OutputInterfaceMap(factory, ref objData);
            }

            OutputFinalizerMethod(factory, ref objData);
            OutputOptionalFields(factory, ref objData);
            OutputNullableTypeParameter(factory, ref objData);
            OutputGenericInstantiationDetails(factory, ref objData);

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

            foreach (var argVariance in _details.Variance)
            {
                if (argVariance != 0)
                {
                    hasVariance = true;
                    break;
                }
            }

            var builder = new ObjectDataBuilder(factory);

            builder.AddSymbol(this);

            builder.RequireInitialPointerAlignment();

            builder.EmitShort((short)checked ((UInt16)_details.Instantiation.Length));

            builder.EmitByte((byte)(hasVariance ? 1 : 0));

            // TODO: general purpose padding
            builder.EmitByte(0);
            if (factory.Target.PointerSize == 8)
            {
                builder.EmitInt(0);
            }

            foreach (var typeArg in _details.Instantiation)
            {
                builder.EmitPointerReloc(factory.NecessaryTypeSymbol(typeArg));
            }

            if (hasVariance)
            {
                foreach (var argVariance in _details.Variance)
                {
                    builder.EmitByte(checked ((byte)argVariance));
                }
            }

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

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

            // Node representing the generic dictionary doesn't have any dependencies for
            // dependency analysis purposes. The dependencies are tracked as dependencies of the
            // concrete method bodies. When we reach the object data emission phase, the dependencies
            // should all already have been marked.
            if (!relocsOnly)
            {
                EmitDataInternal(ref builder, factory);
            }

            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());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            builder.AddSymbol(this);

            //
            // Emit a MethodFixupCell struct
            //

            // Address (to be fixed up at runtime)
            builder.EmitZeroPointer();

            // Entry point name
            string entryPointName = _pInvokeMethodData.EntryPointName;

            if (factory.Target.IsWindows && entryPointName.StartsWith("#", StringComparison.OrdinalIgnoreCase))
            {
                // Windows-specific ordinal import
                // CLR-compatible behavior: Strings that can't be parsed as a signed integer are treated as zero.
                int entrypointOrdinal;
                if (!int.TryParse(entryPointName.Substring(1), out entrypointOrdinal))
                {
                    entrypointOrdinal = 0;
                }

                // CLR-compatible behavior: Ordinal imports are 16-bit on Windows. Discard rest of the bits.
                builder.EmitNaturalInt((ushort)entrypointOrdinal);
            }
            else
            {
                // Import by name
                builder.EmitPointerReloc(factory.ConstantUtf8String(entryPointName));
            }

            // Module fixup cell
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_pInvokeMethodData.ModuleData));

            builder.EmitInt((int)_pInvokeMethodData.CharSetMangling);

            return(builder.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory, relocsOnly);

            dataBuilder.RequireInitialPointerAlignment();
            dataBuilder.AddSymbol(this);

            // +1 for SyncBlock (static size already includes MethodTable)
            Debug.Assert(factory.Target.Abi == TargetAbi.NativeAot || factory.Target.Abi == TargetAbi.CppCodegen);
            int totalSize = (_gcMap.Size + 1) * _target.PointerSize;

            // We only need to check for containsPointers because ThreadStatics are always allocated
            // on the GC heap (no matter what "HasGCStaticBase" says).
            // If that ever changes, we can assume "true" and switch this to an assert.

            bool containsPointers = _gcMap.NumSeries > 0;

            if (containsPointers)
            {
                GCDescEncoder.EncodeStandardGCDesc(ref dataBuilder, _gcMap, totalSize, 0);
            }

            Debug.Assert(dataBuilder.CountBytes == ((ISymbolDefinitionNode)this).Offset);

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            short flags = 0;

            if (containsPointers)
            {
                flags |= (short)EETypeFlags.HasPointersFlag;
            }

            dataBuilder.EmitShort(flags);

            totalSize = Math.Max(totalSize, _target.PointerSize * 3); // minimum GC MethodTable size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            // Related type: System.Object. This allows storing an instance of this type in an array of objects.
            dataBuilder.EmitPointerReloc(factory.NecessaryTypeSymbol(factory.TypeSystemContext.GetWellKnownType(WellKnownType.Object)));

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

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

            if (factory.MetadataManager.SupportsReflection)
            {
                NativeLayoutFieldLdTokenVertexNode ldtokenSigNode = factory.NativeLayout.FieldLdTokenVertex(_targetField);
                objData.EmitPointerReloc(factory.NativeLayout.NativeLayoutSignature(ldtokenSigNode, s_NativeLayoutSignaturePrefix, _targetField));
            }
            else
            {
                objData.EmitZeroPointer();
            }

            return(objData.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // TODO: define _tls_used as comdat select any when multiple object files present.
            UtcNodeFactory    hostedFactory = factory as UtcNodeFactory;
            ObjectDataBuilder objData       = new ObjectDataBuilder(factory, relocsOnly);

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

            // Allocate and initialize the IMAGE_TLS_DIRECTORY PE data structure used by the OS loader to determine
            // TLS allocations. The structure is defined by the OS as following:

            /*
             *  struct _IMAGE_TLS_DIRECTORY32
             *  {
             *      DWORD StartAddressOfRawData;
             *      DWORD EndAddressOfRawData;
             *      DWORD AddressOfIndex;
             *      DWORD AddressOfCallBacks;
             *      DWORD SizeOfZeroFill;
             *      DWORD Characteristics;
             *  }
             *
             *  struct _IMAGE_TLS_DIRECTORY64
             *  {
             *      ULONGLONG StartAddressOfRawData;
             *      ULONGLONG EndAddressOfRawData;
             *      ULONGLONG AddressOfIndex;
             *      ULONGLONG AddressOfCallBacks;
             *      DWORD SizeOfZeroFill;
             *      DWORD Characteristics;
             *  }
             */
            // In order to utilize linker support, the struct variable needs to be named _tls_used
            objData.EmitPointerReloc(hostedFactory.TlsStart);           // start of tls data
            objData.EmitPointerReloc(hostedFactory.TlsEnd);             // end of tls data
            objData.EmitPointerReloc(hostedFactory.ThreadStaticsIndex); // address of tls_index
            objData.EmitZeroPointer();                                  // pointer to call back array
            objData.EmitInt(0);                                         // size of tls zero fill
            objData.EmitInt(0);                                         // characteristics

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

            dataBuilder.RequireInitialPointerAlignment();
            dataBuilder.AddSymbol(this);
            EETypeRareFlags rareFlags = 0;

            ushort flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
            {
                rareFlags = rareFlags | EETypeRareFlags.HasCctorFlag;
            }
            if (_type.IsByRefLike)
            {
                rareFlags |= EETypeRareFlags.IsByRefLikeFlag;
            }

            if (rareFlags != 0)
            {
                _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, (uint)rareFlags);
            }

            if (HasOptionalFields)
            {
                flags |= (ushort)EETypeFlags.OptionalFieldsFlag;
            }

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitUShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            OutputTypeManagerIndirection(factory, ref dataBuilder);
            OutputWritableData(factory, ref dataBuilder);
            OutputOptionalFields(factory, ref dataBuilder);

            return(dataBuilder.ToObjectData());
        }