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; }
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(); }
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(); }
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(); }
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(); }
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)); }
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(); }
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)); }
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(); }
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); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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()); }
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); } }
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); }
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()); }
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); }
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); } }
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()); }
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(); }
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()); }
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); }
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()); }
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()); }
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); }
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()); }
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(); } }
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(); }
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()); }
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)); }
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(); }
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(); }
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(); }
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()); }
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); }
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()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // The dependency tracking of this node currently does nothing because the data emission relies // the set of compiled methods which has an incomplete state during dependency tracking. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); objData.AddSymbol(_endSymbol); foreach (var mappingEntry in factory.MetadataManager.GetStackTraceMapping(factory)) { objData.EmitReloc(factory.MethodEntrypoint(mappingEntry.Entity), RelocType.IMAGE_REL_BASED_RELPTR32); objData.EmitInt(mappingEntry.MetadataHandle); } _endSymbol.SetSymbolOffset(objData.CountBytes); return(objData.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { 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()); }
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()); }
public override void EmitDictionaryData(ref ObjectDataBuilder builder, NodeFactory factory, GenericDictionaryNode dictionary, bool fixedLayoutOnly) => throw new NotImplementedException();
protected virtual void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData) { // Non-constructed EETypes have no interface map }
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()); }
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); }