public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.Alignment = factory.Target.PointerSize;

            if (_sorter != null)
                _nestedNodesList.Sort(_sorter);

            builder.DefinedSymbols.Add(_startSymbol);
            foreach (EmbeddedObjectNode node in _nestedNodesList)
            {
                if (!relocsOnly)
                    node.Offset = builder.CountBytes;

                node.EncodeData(ref builder, factory, relocsOnly);
                if (node is ISymbolNode)
                {
                    builder.DefinedSymbols.Add((ISymbolNode)node);
                }
            }
            _endSymbol.SetSymbolOffset(builder.CountBytes);
            builder.DefinedSymbols.Add(_endSymbol);

            ObjectData objData = builder.ToObjectData();
            return objData;
        }
Пример #2
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory);

            // These need to be aligned the same as methods because they show up in same contexts
            builder.RequireAlignment(factory.Target.MinimumFunctionAlignment);

            builder.DefinedSymbols.Add(this);

            MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific);

            // Pointer to the canonical body of the method
            builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod));

            // Find out what's the context to use
            ISymbolNode contextParameter;
            if (canonMethod.RequiresInstMethodDescArg())
            {
                contextParameter = factory.MethodGenericDictionary(Method);
            }
            else
            {
                Debug.Assert(canonMethod.RequiresInstMethodTableArg());

                // Ask for a constructed type symbol because we need the vtable to get to the dictionary
                contextParameter = factory.ConstructedTypeSymbol(Method.OwningType);
            }

            // The next entry is a pointer to the pointer to the context to be used for the canonical method
            // TODO: in multi-module, this points to the import cell, and is no longer this weird pointer
            builder.EmitPointerReloc(factory.Indirection(contextParameter));
            
            return builder.ToObjectData();
        }
Пример #3
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.Alignment = factory.Target.PointerSize;
            builder.DefinedSymbols.Add(this);

            _items.Sort((x, y) => Comparer<int>.Default.Compare((int)x.Id, (int)y.Id));

            // ReadyToRunHeader.Magic
            builder.EmitInt((int)(ReadyToRunHeaderConstants.Signature));

            // ReadyToRunHeader.MajorVersion
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMajorVersion));
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMinorVersion));

            // ReadyToRunHeader.Flags
            builder.EmitInt(0);

            // ReadyToRunHeader.NumberOfSections
            var sectionCountReservation = builder.ReserveShort();

            // ReadyToRunHeader.EntrySize
            builder.EmitByte((byte)(8 + 2 * factory.Target.PointerSize));

            // ReadyToRunHeader.EntryType
            builder.EmitByte(1);

            int count = 0;
            foreach (var item in _items)
            {
                // Skip empty entries
                if (item.Node.ShouldSkipEmittingObjectNode(factory))
                    continue;

                builder.EmitInt((int)item.Id);

                ModuleInfoFlags flags = 0;
                if (item.EndSymbol != null)
                {
                    flags |= ModuleInfoFlags.HasEndPointer;
                }
                builder.EmitInt((int)flags);

                builder.EmitPointerReloc(item.StartSymbol);

                if (item.EndSymbol != null)
                {
                    builder.EmitPointerReloc(item.EndSymbol);
                }
                else
                {
                    builder.EmitZeroPointer();
                }

                count++;
            }
            builder.EmitShort(sectionCountReservation, checked((short)count));

            return builder.ToObjectData();
        }
Пример #4
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 ISymbolNode[] { this });

            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
                    continue;

                var node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
                
                if (node.Marked)
                {
                    // TODO: this format got very inefficient due to not being able to use RVAs
                    //       replace with a hash table

                    builder.EmitPointerReloc(node);
                    builder.EmitInt(mappingEntry.MetadataHandle);

                    if (factory.Target.PointerSize == 8)
                        builder.EmitInt(0); // Pad
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);
            
            builder.DefinedSymbols.Add(this);
            builder.DefinedSymbols.Add(_endSymbol);

            return builder.ToObjectData();
        }
Пример #5
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

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

            // Entry point name
            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(_moduleName));

            return builder.ToObjectData();
        }
Пример #6
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            dataBuilder.EmitZeroPointer(); // Sync block

            DefType systemStringType = factory.TypeSystemContext.GetWellKnownType(WellKnownType.String);

            //
            // The GC requires a direct reference to frozen objects' EETypes. If System.String will be compiled into a separate
            // binary, it must be cloned into this one.
            //
            if (factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(systemStringType))
            {
                dataBuilder.EmitPointerReloc(factory.ConstructedClonedTypeSymbol(systemStringType));
            }
            else
            {
                dataBuilder.EmitPointerReloc(factory.ConstructedTypeSymbol(systemStringType));
            }

            dataBuilder.EmitInt(_data.Length);

            foreach (char c in _data)
            {
                dataBuilder.EmitShort((short)c);
            }

            // Null-terminate for friendliness with interop
            dataBuilder.EmitShort(0);

        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the 
            // synchronization mechanism of the two values in the runtime.
            objData.Alignment = _targetMethod.Context.Target.PointerSize * 2;
            objData.DefinedSymbols.Add(this);
            
            objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch"));
            
            // The second cell field uses the two lower-order bits to communicate the contents.
            // We add 1 to signal IDC_CachePointerIsInterfacePointer. See src\Native\Runtime\inc\rhbinder.h.
            objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), 1);
            
            // End the run of dispatch cells
            objData.EmitZeroPointer();

            // Avoid consulting VTable slots until they're guaranteed complete during final data emission
            if (!relocsOnly)
            {
                int interfaceMethodSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod);
                if (factory.Target.PointerSize == 8)
                {
                    objData.EmitLong(interfaceMethodSlot);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            return objData.ToObjectData();
        }
 protected override void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     //
     // Cloned types use the related type field to point via an IAT slot at their true implementation
     //
     objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type));
 }
Пример #9
0
        void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            var entryCountReservation = builder.ReserveInt();
            int entryCount = 0;
            
            for (int interfaceIndex = 0; interfaceIndex < _type.RuntimeInterfaces.Length; interfaceIndex++)
            {
                var interfaceType = _type.RuntimeInterfaces[interfaceIndex];
                Debug.Assert(interfaceType.IsInterface);

                IReadOnlyList<MethodDesc> virtualSlots = factory.VTable(interfaceType).Slots;
                
                for (int interfaceMethodSlot = 0; interfaceMethodSlot < virtualSlots.Count; interfaceMethodSlot++)
                {
                    MethodDesc declMethod = virtualSlots[interfaceMethodSlot];
                    var implMethod = _type.GetClosestDefType().ResolveInterfaceMethodToVirtualMethodOnType(declMethod);

                    // Interface methods first implemented by a base type in the hierarchy will return null for the implMethod (runtime interface
                    // dispatch will walk the inheritance chain).
                    if (implMethod != null)
                    {
                        builder.EmitShort(checked((short)interfaceIndex));
                        builder.EmitShort(checked((short)interfaceMethodSlot));
                        builder.EmitShort(checked((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod)));
                        entryCount++;
                    }
                }
            }

            builder.EmitInt(entryCountReservation, entryCount);
        }
 public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
 {
     ObjectDataBuilder objData = new ObjectDataBuilder(factory);
     objData.DefinedSymbols.Add(this);
     objData.RequirePointerAlignment();
     objData.EmitZeroPointer();
     return objData.ToObjectData();
 }
Пример #11
0
        public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
        {
            builder.RequirePointerAlignment();

            // At runtime, an instance of the GCStaticEEType will be created and a GCHandle to it
            // will be written in this location.
            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
        }
Пример #12
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.RequirePointerAlignment();
            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), 1);
            builder.DefinedSymbols.Add(this);

            return builder.ToObjectData();
        }
Пример #13
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            dataBuilder.RequirePointerAlignment();

            StringDataNode stringDataNode = factory.StringData(_data);
            if (!relocsOnly)
                stringDataNode.SetId(base.Offset);

            dataBuilder.EmitPointerReloc(stringDataNode);
        }
Пример #14
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory);
            builder.RequirePointerAlignment();
            builder.DefinedSymbols.Add(this);

            builder.EmitPointerReloc(_indirectedNode);

            return builder.ToObjectData();
        }
Пример #15
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            Encoding encoding = UTF8Encoding.UTF8;

            ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory);
            AsmStringWriter stringWriter = new AsmStringWriter((byte b) => objDataBuilder.EmitByte(b));
            stringWriter.WriteString(_data);
            objDataBuilder.DefinedSymbols.Add(this);

            return objDataBuilder.ToObjectData();
        }
Пример #16
0
        protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            DictionaryLayoutNode layout = GetDictionaryLayout(factory);

            Instantiation typeInst = this.TypeInstantiation;
            Instantiation methodInst = this.MethodInstantiation;

            foreach (var entry in layout.Entries)
            {
                ISymbolNode targetNode = entry.GetTarget(factory, typeInst, methodInst);
                builder.EmitPointerReloc(targetNode);
            }
        }
 public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
 {
     ObjectDataBuilder objData = new ObjectDataBuilder(factory);
     objData.Alignment = factory.Target.PointerSize;
     objData.DefinedSymbols.Add(this);
     
     foreach (var map in _dispatchMaps)
     {
         objData.EmitPointerReloc(map);
     }
     
     return objData.ToObjectData();
 }
Пример #18
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.RequirePointerAlignment();
            objData.DefinedSymbols.Add(this);

            if (!relocsOnly)
            {
                objData.EmitBytes(_owner.GetOptionalFieldsData());
            }
            
            return objData.ToObjectData();
        }
Пример #19
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

            builder.EmitZeroPointer();
            builder.EmitPointerReloc(factory.ConstantUtf8String(_entryPointName));
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName));

            return builder.ToObjectData();
        }
Пример #20
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 ISymbolNode[] { this });

            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
                    continue;

                // We are looking for any EEType - constructed or not, it has to be in the mapping
                // table so that we can map it to metadata.
                EETypeNode node = null;
                
                if (!mappingEntry.Entity.IsGenericDefinition)
                {
                    node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }
                
                if (node == null || !node.Marked)
                {
                    // This might have been a typeof() expression.
                    node = factory.NecessaryTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }

                if (node.Marked)
                {
                    // TODO: this format got very inefficient due to not being able to use RVAs
                    //       replace with a hash table

                    builder.EmitPointerReloc(node);
                    builder.EmitInt(mappingEntry.MetadataHandle);

                    if (factory.Target.PointerSize == 8)
                        builder.EmitInt(0); // Pad
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);
            
            builder.DefinedSymbols.Add(this);
            builder.DefinedSymbols.Add(_endSymbol);

            return builder.ToObjectData();
        }
Пример #21
0
        public sealed override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);
            builder.RequirePointerAlignment();

            // 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();
        }
Пример #22
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            ISymbolNode nameSymbol = factory.Target.IsWindows ?
                factory.ConstantUtf16String(_moduleName) :
                factory.ConstantUtf8String(_moduleName);

            //
            // Emit a ModuleFixupCell struct
            //

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

            return builder.ToObjectData();
        }
Пример #23
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a ModuleFixupCell struct
            //

            builder.EmitZeroPointer();

            Encoding encoding = factory.Target.IsWindows ? Encoding.Unicode : Encoding.UTF8;

            int moduleNameBytesCount = encoding.GetByteCount(_moduleName);
            byte[] moduleNameBytes = new byte[moduleNameBytesCount + 2];
            encoding.GetBytes(_moduleName, 0, _moduleName.Length, moduleNameBytes, 0);
            builder.EmitPointerReloc(factory.ReadOnlyDataBlob("__modulename_" + _moduleName, moduleNameBytes, 2));

            return builder.ToObjectData();
        }
Пример #24
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

            builder.EmitZeroPointer();

            int entryPointBytesCount = Encoding.UTF8.GetByteCount(_entryPointName);
            byte[] entryPointNameBytes = new byte[entryPointBytesCount + 1];
            Encoding.UTF8.GetBytes(_entryPointName, 0, _entryPointName.Length, entryPointNameBytes, 0);

            builder.EmitPointerReloc(factory.ReadOnlyDataBlob("__pinvokename_" + _entryPointName, entryPointNameBytes, 1));
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName));

            return builder.ToObjectData();
        }
Пример #25
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            // If the type has a class constructor, its non-GC statics section is prefixed
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireInitialAlignment(alignmentRequired);

                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                MethodDesc cctorMethod      = _type.GetStaticConstructor();
                MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                if (cctorMethod != canonCctorMethod)
                {
                    builder.EmitPointerReloc(factory.FatFunctionPointer(cctorMethod), FatFunctionPointerConstants.Offset);
                }
                else
                {
                    builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                }
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireInitialAlignment(_type.NonGCStaticFieldAlignment.AsInt);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize.AsInt);
            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
Пример #26
0
        private void OutputComponentSize(ref ObjectDataBuilder objData)
        {
            if (_type.IsArray)
            {
                int elementSize = ((ArrayType)_type).ElementType.GetElementSize();
                if (elementSize >= 64 * 1024)
                {
                    // TODO: Array of type 'X' cannot be created because base value type is too large.
                    throw new TypeLoadException();
                }

                objData.EmitShort((short)elementSize);
            }
            else if (_type.IsString)
            {
                objData.EmitShort(2);
            }
            else
            {
                objData.EmitShort(0);
            }
        }
Пример #27
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type;

            while (currentTypeSlice != null)
            {
                List <MethodDesc> virtualSlots;
                factory.VirtualSlots.TryGetValue(currentTypeSlice, out virtualSlots);
                if (virtualSlots != null)
                {
                    virtualSlotCount += virtualSlots.Count;
                }

                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));

            // Todo: Number of slots of EEInterfaceInfo when we add interface support
            objData.EmitShort(0);
        }
Пример #28
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.DefinedSymbols.Add(this);

            //
            // Emit a ModuleFixupCell struct
            //

            builder.EmitZeroPointer();

            Encoding encoding = factory.Target.IsWindows ? Encoding.Unicode : Encoding.UTF8;

            int moduleNameBytesCount = encoding.GetByteCount(_moduleName);

            byte[] moduleNameBytes = new byte[moduleNameBytesCount + 2];
            encoding.GetBytes(_moduleName, 0, _moduleName.Length, moduleNameBytes, 0);
            builder.EmitPointerReloc(factory.ReadOnlyDataBlob("__modulename_" + _moduleName, moduleNameBytes, 2));

            return(builder.ToObjectData());
        }
Пример #29
0
        protected override void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory, bool fixedLayoutOnly)
        {
            // Method generic dictionaries get prefixed by the hash code of the owning method
            // to allow quick lookups of additional details by the type loader.

            builder.EmitInt(_owningMethod.GetHashCode());
            if (builder.TargetPointerSize == 8)
            {
                builder.EmitInt(0);
            }

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

            // Lazy method dictionaries are generated by the compiler, but they have no entries within them. (They are used solely to identify the exact method)
            // The dictionary layout may be filled in by various needs for generic lookups, but those are handled in a lazy fashion.
            if (factory.LazyGenericsPolicy.UsesLazyGenerics(OwningMethod))
            {
                return;
            }

            base.EmitDataInternal(ref builder, factory, fixedLayoutOnly);
        }
Пример #30
0
        protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
        {
            int numSeries = 0;

            foreach (GCStaticDescNode descNode in NodesList)
            {
                numSeries += descNode.NumSeries;
            }

            builder.EmitInt(numSeries);

            foreach (GCStaticDescNode node in NodesList)
            {
                if (!relocsOnly)
                {
                    node.InitializeOffsetFromBeginningOfArray(builder.CountBytes);
                }

                node.EncodeData(ref builder, factory, relocsOnly);
                builder.AddSymbol(node);
            }
        }
Пример #31
0
        public static ObjectData GetDataForPreInitDataField(
            ISymbolDefinitionNode node,
            MetadataType _type, List <PreInitFieldInfo> sortedPreInitFields,
            int startOffset,
            NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt);

            int staticOffset    = startOffset;
            int staticOffsetEnd = _type.GCStaticFieldSize.AsInt;
            int idx             = 0;

            while (staticOffset < staticOffsetEnd)
            {
                int writeTo = staticOffsetEnd;
                if (idx < sortedPreInitFields.Count)
                {
                    writeTo = sortedPreInitFields[idx].Field.Offset.AsInt;
                }

                // Emit the zero before the next preinitField
                builder.EmitZeros(writeTo - staticOffset);
                staticOffset = writeTo;

                // Emit a pointer reloc to the frozen data
                if (idx < sortedPreInitFields.Count)
                {
                    builder.EmitPointerReloc(factory.SerializedFrozenArray(sortedPreInitFields[idx]));
                    idx++;
                    staticOffset += factory.Target.PointerSize;
                }
            }

            builder.AddSymbol(node);

            return(builder.ToObjectData());
        }
Пример #32
0
        protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
        {
            foreach (EmbeddedObjectNode node in NodesList)
            {
                AlignNextObject(ref builder, factory);

                if (!relocsOnly)
                {
                    node.InitializeOffsetFromBeginningOfArray(builder.CountBytes);
                }

                node.EncodeData(ref builder, factory, relocsOnly);
                if (node is ISymbolDefinitionNode)
                {
                    builder.AddSymbol((ISymbolDefinitionNode)node);
                }
            }

            // Terminate with a null pointer as expected by the GC
            AlignNextObject(ref builder, factory);
            builder.EmitZeroPointer();
        }
Пример #33
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

            objData.Alignment = 16;
            objData.DefinedSymbols.Add(this);

            // Todo: Generic Type Definition EETypes
            //       Early-out just to prevent crashing at compile time...
            if (_type.HasInstantiation && _type.IsTypeDefinition)
            {
                objData.EmitZeroPointer();
                return(objData.ToObjectData());
            }

            ComputeOptionalEETypeFields(factory);
            if (null == _optionalFieldsNode)
            {
                _optionalFieldsNode = factory.EETypeOptionalFields(_optionalFieldsBuilder);
            }

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

            objData.EmitInt(_type.GetHashCode());

            if (_constructed)
            {
                OutputVirtualSlots(factory, ref objData, _type, _type);
                OutputFinalizerMethod(factory, ref objData);
                OutputOptionalFields(factory, ref objData);
                OutputNullableTypeParameter(factory, ref objData);
            }

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

            // 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.CoreRT)
                {
                    // 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
                {
                    Debug.Assert(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);
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

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

            return(builder.ToObjectData());
        }
Пример #35
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            if (_sorter != null)
            {
                _nestedNodesList.Sort(_sorter);
            }

            builder.AddSymbol(_startSymbol);

            GetElementDataForNodes(ref builder, factory, relocsOnly);

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

            ObjectData objData = builder.ToObjectData();

            return(objData);
        }
Пример #36
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

            builder.EmitZeroPointer();

            int entryPointBytesCount = Encoding.UTF8.GetByteCount(_entryPointName);

            byte[] entryPointNameBytes = new byte[entryPointBytesCount + 1];
            Encoding.UTF8.GetBytes(_entryPointName, 0, _entryPointName.Length, entryPointNameBytes, 0);

            builder.EmitPointerReloc(factory.ReadOnlyDataBlob("__pinvokename_" + _entryPointName, entryPointNameBytes, 1));
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName));

            return(builder.ToObjectData());
        }
Пример #37
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

            objData.Alignment = objData.TargetPointerSize;
            objData.DefinedSymbols.Add(this);

            ComputeOptionalEETypeFields(factory);

            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 (!relocsOnly)
            {
                OutputVirtualSlotAndInterfaceCount(factory, ref objData);
            }

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

            // 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());
        }
Пример #38
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            TypeDesc relatedType = null;

            if (_type.IsArray || _type.IsPointer || _type.IsByRef)
            {
                relatedType = ((ParameterizedType)_type).ParameterType;
            }
            else
            {
                relatedType = _type.BaseType;
            }

            // If the related type (base type / array element type / pointee type) is not part of this compilation group, and
            // the output binaries will be multi-file (not multiple object files linked together), indicate to the runtime
            // that it should indirect through the import address table
            if (relatedType != null && factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(relatedType))
            {
                flags |= (UInt16)EETypeFlags.RelatedTypeViaIATFlag;
            }

            // Todo: Generic Type Definition EETypes

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

            objData.EmitShort((short)flags);
        }
Пример #39
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

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

            // Entry point name
            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(_moduleName));

            return(builder.ToObjectData());
        }
Пример #40
0
        private void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            ISymbolNode relatedTypeNode = null;

            if (_type.IsArray || _type.IsPointer)
            {
                var parameterType = ((ParameterizedType)_type).ParameterType;
                relatedTypeNode = factory.NecessaryTypeSymbol(parameterType);
            }
            else if (_type.IsGenericDefinition)
            {
                // Related type is not set for generic definitions
            }
            else
            {
                TypeDesc baseType = _type.BaseType;
                if (baseType != null)
                {
                    if (_constructed)
                    {
                        relatedTypeNode = factory.ConstructedTypeSymbol(baseType);
                    }
                    else
                    {
                        relatedTypeNode = factory.NecessaryTypeSymbol(baseType);
                    }
                }
            }

            if (relatedTypeNode != null)
            {
                objData.EmitPointerReloc(relatedTypeNode);
            }
            else
            {
                objData.EmitZeroPointer();
            }
        }
Пример #41
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            short flags = (short)EETypeKind.GenericTypeDefEEType;
            if (_type.IsValueType)
                flags |= (short)EETypeFlags.ValueTypeFlag;
            if (_type.IsInterface)
                flags |= (short)EETypeFlags.IsInterfaceFlag;

            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.ModuleManagerIndirection);
            
            return dataBuilder.ToObjectData();
        }
Пример #42
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            Debug.Assert((EETypeNode.GetVTableOffset(factory.Target.PointerSize) % factory.Target.PointerSize) == 0, "vtable offset must be aligned");
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.AddSymbol(this);

            if (!relocsOnly)
            {
                int tableOffset;
                if (_targetMethod.OwningType.IsInterface)
                {
                    tableOffset = 0;
                }
                else
                {
                    tableOffset = EETypeNode.GetVTableOffset(factory.Target.PointerSize) / factory.Target.PointerSize;
                }

                objData.EmitInt(tableOffset + VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod, _targetMethod.OwningType));
            }
            return(objData.ToObjectData());
        }
Пример #43
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (!_constructed)
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
                return;
            }

            Debug.Assert(!_type.IsGenericDefinition);

            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type.GetClosestMetadataType();

            while (currentTypeSlice != null)
            {
                virtualSlotCount += factory.VTable(currentTypeSlice).Slots.Count;
                currentTypeSlice  = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));
            objData.EmitShort(checked ((short)_type.RuntimeInterfaces.Length));
        }
Пример #44
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            if (factory.TypeSystemContext.IsGenericArrayInterfaceType(_type))
            {
                // Runtime casting logic relies on all interface types implemented on arrays
                // to have the variant flag set (even if all the arguments are non-variant).
                // This supports e.g. casting uint[] to ICollection<int>
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            ISymbolNode relatedTypeNode = GetRelatedTypeNode(factory);

            // If the related type (base type / array element type / pointee type) is not part of this compilation group, and
            // the output binaries will be multi-file (not multiple object files linked together), indicate to the runtime
            // that it should indirect through the import address table
            if (relatedTypeNode != null && relatedTypeNode.RepresentsIndirectionCell)
            {
                flags |= (UInt16)EETypeFlags.RelatedTypeViaIATFlag;
            }

            // Todo: Generic Type Definition EETypes

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

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

            dataBuilder.Alignment = dataBuilder.TargetPointerSize;
            dataBuilder.DefinedSymbols.Add(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 (rareFlags != 0)
                _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, (uint)rareFlags);

            if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
                flags |= (short)EETypeFlags.OptionalFieldsFlag;

            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.ModuleManagerIndirection);
            if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
            {
                dataBuilder.EmitPointerReloc(factory.EETypeOptionalFields(_optionalFieldsBuilder));
            }

            return dataBuilder.ToObjectData();
        }
Пример #46
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            // +2 for SyncBlock and EETypePtr field
            int totalSize = (_gcMap.Size + 2) * _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 == 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 eetype 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();
        }
Пример #47
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            // +2 for SyncBlock and EETypePtr field
            int totalSize = (_gcMap.Size + 2) * _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 == ((ISymbolNode)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 eetype size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            // This is just so that EEType::Validate doesn't blow up at runtime
            dataBuilder.EmitPointerReloc(this); // Related type: itself

            return dataBuilder.ToObjectData();
        }
Пример #48
0
        public sealed override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

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

            DictionaryLayoutNode layout = GetDictionaryLayout(factory);

            // Node representing the generic dictionary layout might be one of two kinds:
            // With fixed slots, or where slots are added as we're expanding the graph.
            // If it's the latter, we can't touch the collection of slots before the graph expansion
            // is complete (relocsOnly == false). It's someone else's responsibility
            // to make sure the dependencies are properly generated.
            // If this is a dictionary layout with fixed slots, it's the responsibility of
            // each dictionary to ensure the targets are marked.
            if (layout.HasFixedSlots || !relocsOnly)
            {
                // TODO: pass the layout we already have to EmitDataInternal
                EmitDataInternal(ref builder, factory, relocsOnly);
            }

            return(builder.ToObjectData());
        }
Пример #49
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            // Sync Block
            dataBuilder.EmitZeroPointer();

            // EEType
            dataBuilder.EmitPointerReloc(GetEETypeNode(factory));

            // numComponents
            dataBuilder.EmitInt(_preInitFieldInfo.Length);

            int pointerSize = _preInitFieldInfo.Field.Context.Target.PointerSize;

            Debug.Assert(pointerSize == 8 || pointerSize == 4);

            if (pointerSize == 8)
            {
                // padding numComponents in 64-bit
                dataBuilder.EmitInt(0);
            }

            // byte contents
            _preInitFieldInfo.WriteData(ref dataBuilder, factory);
        }
Пример #50
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            bool hasVariance = _details.Variance != null;

            var builder = new ObjectDataBuilder(factory, relocsOnly);

            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.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(typeArg));
            }

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

            return(builder.ToObjectData());
        }
Пример #51
0
        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());
        }
Пример #52
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            // If the type has a class constructor, its non-GC statics section is prefixed  
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireAlignment(alignmentRequired);
                
                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                MethodDesc cctorMethod = _type.GetStaticConstructor();
                MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                if (cctorMethod != canonCctorMethod)
                    builder.EmitPointerReloc(factory.FatFunctionPointer(cctorMethod), FatFunctionPointerConstants.Offset);
                else
                    builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireAlignment(_type.NonGCStaticFieldAlignment);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize);
            builder.DefinedSymbols.Add(this);

            return builder.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());
        }
Пример #54
0
        private void OutputGenericInstantiationDetails(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (_type.HasInstantiation && !_type.IsTypeDefinition)
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type.GetTypeDefinition()));

                GenericCompositionDetails details;
                if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
                {
                    // Generic array enumerators use special variance rules recognized by the runtime
                    details = new GenericCompositionDetails(_type.Instantiation, new[] { GenericVariance.ArrayCovariant });
                }
                else
                    details = new GenericCompositionDetails(_type);

                objData.EmitPointerReloc(factory.GenericComposition(details));
            }
        }
        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());
        }
Пример #56
0
 public override void EmitDictionaryData(ref ObjectDataBuilder builder, NodeFactory factory, GenericDictionaryNode dictionary, bool fixedLayoutOnly) => throw new NotImplementedException();
Пример #57
0
 protected virtual void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     // Non-constructed EETypes have no interface map
 }
Пример #58
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.Alignment = factory.Target.PointerSize;
            builder.DefinedSymbols.Add(this);

            // Don't bother sorting if we're not emitting the contents
            if (!relocsOnly)
            {
                _items.Sort((x, y) => Comparer <int> .Default.Compare((int)x.Id, (int)y.Id));
            }

            // ReadyToRunHeader.Magic
            builder.EmitInt((int)(ReadyToRunHeaderConstants.Signature));

            // ReadyToRunHeader.MajorVersion
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMajorVersion));
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMinorVersion));

            // ReadyToRunHeader.Flags
            builder.EmitInt(0);

            // ReadyToRunHeader.NumberOfSections
            var sectionCountReservation = builder.ReserveShort();

            // ReadyToRunHeader.EntrySize
            builder.EmitByte((byte)(8 + 2 * factory.Target.PointerSize));

            // ReadyToRunHeader.EntryType
            builder.EmitByte(1);

            int count = 0;

            foreach (var item in _items)
            {
                // Skip empty entries
                if (item.Node.ShouldSkipEmittingObjectNode(factory))
                {
                    continue;
                }

                builder.EmitInt((int)item.Id);

                ModuleInfoFlags flags = 0;
                if (item.EndSymbol != null)
                {
                    flags |= ModuleInfoFlags.HasEndPointer;
                }
                builder.EmitInt((int)flags);

                builder.EmitPointerReloc(item.StartSymbol);

                if (item.EndSymbol != null)
                {
                    builder.EmitPointerReloc(item.EndSymbol);
                }
                else
                {
                    builder.EmitZeroPointer();
                }

                count++;
            }
            builder.EmitShort(sectionCountReservation, checked ((short)count));

            return(builder.ToObjectData());
        }
Пример #59
0
 public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
 {
     dataBuilder.RequireInitialPointerAlignment();
     dataBuilder.EmitReloc(Target, RelocType.IMAGE_REL_BASED_ADDR32NB);
 }
 public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
 {
     dataBuilder.RequireInitialPointerAlignment();
     dataBuilder.EmitPointerReloc(Target);
 }