public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory); dataBuilder.Alignment = 16; dataBuilder.DefinedSymbols.Add(this); bool hasPointers = NumSeries > 0; if (hasPointers) { for (int i = ((_runLengths.Length / 2) * 2) - 1; i >= 0; i--) { if (_targetPointerSize == 4) { dataBuilder.EmitInt(_runLengths[i]); } else { dataBuilder.EmitLong(_runLengths[i]); } } if (_targetPointerSize == 4) { dataBuilder.EmitInt(NumSeries); } else { dataBuilder.EmitLong(NumSeries); } } int totalSize = 0; foreach (int run in _runLengths) { totalSize += run * _targetPointerSize; } dataBuilder.EmitShort(0); // ComponentSize is always 0 if (hasPointers) { dataBuilder.EmitShort(0x20); // TypeFlags.HasPointers } else { dataBuilder.EmitShort(0x00); } totalSize = Math.Max(totalSize, _targetPointerSize * 3); // minimum GC eetype size is 3 pointers dataBuilder.EmitInt(totalSize); return(dataBuilder.ToObjectData()); }
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(); int interfaceMethodSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod); if (factory.Target.PointerSize == 8) { objData.EmitLong(interfaceMethodSlot); } else { throw new NotImplementedException(); } return(objData.ToObjectData()); }
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(); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder objData = new ObjectDataBuilder(factory); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); // Emit an aliased symbol named _tls_index for native P/Invoke code that uses TLS. This is required // because we do not link against libcmt.lib. ObjectAndOffsetSymbolNode aliasedSymbol = new ObjectAndOffsetSymbolNode(this, objData.CountBytes, "_tls_index", false); objData.AddSymbol(aliasedSymbol); // This is the TLS index field which is a 4-byte integer. Emit an 8-byte interger which includes a // 4-byte padding to make an pointer-sized alignment for the subsequent fields for all targets. objData.EmitLong(0); // Allocate and initialize the IMAGE_TLS_DIRECTORY PE data structure used by the OS loader to determine // TLS allocations. The structure is defined by the OS as following: /* * struct _IMAGE_TLS_DIRECTORY32 * { * DWORD StartAddressOfRawData; * DWORD EndAddressOfRawData; * DWORD AddressOfIndex; * DWORD AddressOfCallBacks; * DWORD SizeOfZeroFill; * DWORD Characteristics; * } * * struct _IMAGE_TLS_DIRECTORY64 * { * ULONGLONG StartAddressOfRawData; * ULONGLONG EndAddressOfRawData; * ULONGLONG AddressOfIndex; * ULONGLONG AddressOfCallBacks; * DWORD SizeOfZeroFill; * DWORD Characteristics; * } */ // In order to utilize linker support, the struct variable needs to be named _tls_used ObjectAndOffsetSymbolNode structSymbol = new ObjectAndOffsetSymbolNode(this, objData.CountBytes, "_tls_used", false); objData.AddSymbol(structSymbol); objData.EmitPointerReloc(factory.ThreadStaticsRegion.StartSymbol); // start of tls data objData.EmitPointerReloc(factory.ThreadStaticsRegion.EndSymbol); // end of tls data objData.EmitPointerReloc(this); // address of tls_index objData.EmitZeroPointer(); // pointer to call back array objData.EmitInt(0); // size of tls zero fill objData.EmitInt(0); // characteristics return(objData.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory); dataBuilder.Alignment = 16; dataBuilder.DefinedSymbols.Add(this); bool hasPointers = NumSeries > 0; if (hasPointers) { for (int i = ((_runLengths.Length / 2) * 2) - 1; i >= 0; i--) { if (_targetPointerSize == 4) { dataBuilder.EmitInt(_runLengths[i]); } else { dataBuilder.EmitLong(_runLengths[i]); } } if (_targetPointerSize == 4) { dataBuilder.EmitInt(NumSeries); } else { dataBuilder.EmitLong(NumSeries); } } int totalSize = 0; foreach (int run in _runLengths) { totalSize += run * _targetPointerSize; } dataBuilder.EmitShort(0); // ComponentSize is always 0 if (hasPointers) dataBuilder.EmitShort(0x20); // TypeFlags.HasPointers else dataBuilder.EmitShort(0x00); totalSize = Math.Max(totalSize, _targetPointerSize * 3); // minimum GC eetype size is 3 pointers dataBuilder.EmitInt(totalSize); return dataBuilder.ToObjectData(); }