private static int GetClassConstructorContextStorageSize(TargetDetails target, MetadataType type) { int alignmentRequired = Math.Max(type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(target)); return(AlignmentHelper.AlignUp(GetClassConstructorContextSize(type.Context.Target), alignmentRequired)); }
public void Pad(int size, int alignment, int expected) { int result = AlignmentHelper.Pad(size, alignment); Assert.AreEqual(result, expected); }
private static async Task <Document> FixWhitespaceAsync(Document document, Diagnostic diagnostic, double dAlignmentStandardDeviation, CancellationToken cancellationToken) { var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); int nCharToAdd = await AlignmentHelper.AdditionalSpacesToAddForConditionAsync(root, diagnostic, dAlignmentStandardDeviation, AlignmentHelper.IsSimpleAssignment, SyntaxKind.EqualsToken, cancellationToken).ConfigureAwait(false); var newText = text.Replace(new TextSpan(diagnostic.Location.SourceSpan.Start, 0), AlignmentHelper.WhiteSpaceString(nCharToAdd)); return(document.WithText(newText)); }
protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics) { if (diagnostics.IsEmpty) { return(null); } var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, fixAllContext.CancellationToken); var text = await document.GetTextAsync().ConfigureAwait(false); SyntaxNode root = await document.GetSyntaxRootAsync().ConfigureAwait(false); for (int nDiagnostic = diagnostics.Length; nDiagnostic-- > 0;) { var diagnostic = diagnostics[nDiagnostic]; int nCharToAdd = await AlignmentHelper.AdditionalSpacesToAddForConditionAsync(root, diagnostic, settings.AlignmentRules.AlignmentStandardDeviation, AlignmentHelper.IsSimpleAssignment, SyntaxKind.EqualsToken, fixAllContext.CancellationToken).ConfigureAwait(false); text = text.Replace(new TextSpan(diagnostic.Location.SourceSpan.Start, 0), AlignmentHelper.WhiteSpaceString(nCharToAdd)); } var tree = await document.GetSyntaxTreeAsync().ConfigureAwait(false); return(await tree.WithChangedText(text).GetRootAsync().ConfigureAwait(false)); }
/// <summary> /// Output the section with a given name. For sections existent in the source MSIL PE file /// (.text, optionally .rsrc and .reloc), we first copy the content of the input MSIL PE file /// and then call the section serialization callback to emit the extra content after the input /// section content. /// </summary> /// <param name="name">Section name</param> /// <param name="location">RVA and file location where the section will be put</param> /// <returns>Blob builder representing the section data</returns> protected override BlobBuilder SerializeSection(string name, SectionLocation location) { BlobBuilder sectionDataBuilder = null; bool haveCustomSection = _customSections.Contains(name); int sectionStartRva = location.RelativeVirtualAddress; int outputSectionIndex = _sections.Length - 1; while (outputSectionIndex >= 0 && _sections[outputSectionIndex].Name != name) { outputSectionIndex--; } if (!_target.IsWindows) { if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); } const int RVAAlign = 1 << RVABitsToMatchFilePos; sectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, RVAAlign); int rvaAdjust = (location.PointerToRawData - sectionStartRva) & (RVAAlign - 1); sectionStartRva += rvaAdjust; location = new SectionLocation(sectionStartRva, location.PointerToRawData); } if (outputSectionIndex >= 0) { _sectionRVAs[outputSectionIndex] = sectionStartRva; } int inputSectionIndex = _peReader.PEHeaders.SectionHeaders.Count() - 1; while (inputSectionIndex >= 0 && _peReader.PEHeaders.SectionHeaders[inputSectionIndex].Name != name) { inputSectionIndex--; } if (inputSectionIndex >= 0) { SectionHeader sectionHeader = _peReader.PEHeaders.SectionHeaders[inputSectionIndex]; int sectionOffset = (_peReader.IsLoadedImage ? sectionHeader.VirtualAddress : sectionHeader.PointerToRawData); int rvaDelta = location.RelativeVirtualAddress - sectionHeader.VirtualAddress; _sectionRvaDeltas.Add(new SectionRVADelta( startRVA: sectionHeader.VirtualAddress, endRVA: sectionHeader.VirtualAddress + Math.Max(sectionHeader.VirtualSize, sectionHeader.SizeOfRawData), deltaRVA: rvaDelta)); unsafe { int bytesToRead = Math.Min(sectionHeader.SizeOfRawData, sectionHeader.VirtualSize); BlobReader inputSectionReader = _peReader.GetEntireImage().GetReader(sectionOffset, bytesToRead); if (name == ".rsrc") { // There seems to be a bug in BlobBuilder - when we LinkSuffix to an empty blob builder, // the blob data goes out of sync and WriteContentTo outputs garbage. sectionDataBuilder = PEResourceHelper.Relocate(inputSectionReader, rvaDelta); } else { sectionDataBuilder = new BlobBuilder(); sectionDataBuilder.WriteBytes(inputSectionReader.CurrentPointer, inputSectionReader.RemainingBytes); } int metadataRvaDelta = _peReader.PEHeaders.CorHeader.MetadataDirectory.RelativeVirtualAddress - sectionHeader.VirtualAddress; if (metadataRvaDelta >= 0 && metadataRvaDelta < bytesToRead) { _metadataFileOffset = location.PointerToRawData + metadataRvaDelta; } int corHeaderRvaDelta = _peReader.PEHeaders.PEHeader.CorHeaderTableDirectory.RelativeVirtualAddress - sectionHeader.VirtualAddress; if (corHeaderRvaDelta >= 0 && corHeaderRvaDelta < bytesToRead) { // Assume COR header resides in this section, deserialize it and store its location _corHeaderFileOffset = location.PointerToRawData + corHeaderRvaDelta; inputSectionReader.Offset = corHeaderRvaDelta; _corHeaderBuilder = new CorHeaderBuilder(ref inputSectionReader); } int alignedSize = sectionHeader.VirtualSize; // When custom section data is present, align the section size to 4K to prevent // pre-generated MSIL relocations from tampering with native relocations. if (_customSections.Contains(name)) { alignedSize = (alignedSize + 0xFFF) & ~0xFFF; } if (alignedSize > bytesToRead) { // If the number of bytes read from the source PE file is less than the virtual size, // zero pad to the end of virtual size before emitting extra section data sectionDataBuilder.WriteBytes(0, alignedSize - bytesToRead); } location = new SectionLocation( location.RelativeVirtualAddress + sectionDataBuilder.Count, location.PointerToRawData + sectionDataBuilder.Count); } } BlobBuilder extraData = _sectionBuilder.SerializeSection(name, location, sectionStartRva); if (extraData != null) { if (sectionDataBuilder == null) { // See above - there's a bug due to which LinkSuffix to an empty BlobBuilder screws up the blob content. sectionDataBuilder = extraData; } else { sectionDataBuilder.LinkSuffix(extraData); } } // Make sure the section has at least 1 byte, otherwise the PE emitter goes mad, // messes up the section map and corrups the output executable. if (sectionDataBuilder == null) { sectionDataBuilder = new BlobBuilder(); } if (sectionDataBuilder.Count == 0) { sectionDataBuilder.WriteByte(0); } if (outputSectionIndex >= 0) { _sectionRawSizes[outputSectionIndex] = sectionDataBuilder.Count; } return(sectionDataBuilder); }
/// <summary> /// Output the section with a given name. For sections existent in the source MSIL PE file /// (.text, optionally .rsrc and .reloc), we first copy the content of the input MSIL PE file /// and then call the section serialization callback to emit the extra content after the input /// section content. /// </summary> /// <param name="name">Section name</param> /// <param name="location">RVA and file location where the section will be put</param> /// <returns>Blob builder representing the section data</returns> protected override BlobBuilder SerializeSection(string name, SectionLocation location) { BlobBuilder sectionDataBuilder = null; int sectionStartRva = location.RelativeVirtualAddress; int outputSectionIndex = _sections.Length - 1; while (outputSectionIndex >= 0 && _sections[outputSectionIndex].Name != name) { outputSectionIndex--; } if (!_target.IsWindows) { if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); } const int RVAAlign = 1 << RVABitsToMatchFilePos; sectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, RVAAlign); int rvaAdjust = (location.PointerToRawData - sectionStartRva) & (RVAAlign - 1); sectionStartRva += rvaAdjust; location = new SectionLocation(sectionStartRva, location.PointerToRawData); } if (outputSectionIndex >= 0) { _sectionRVAs[outputSectionIndex] = sectionStartRva; } BlobBuilder extraData = _sectionBuilder.SerializeSection(name, location); if (extraData != null) { if (sectionDataBuilder == null) { // See above - there's a bug due to which LinkSuffix to an empty BlobBuilder screws up the blob content. sectionDataBuilder = extraData; } else { sectionDataBuilder.LinkSuffix(extraData); } } // Make sure the section has at least 1 byte, otherwise the PE emitter goes mad, // messes up the section map and corrups the output executable. if (sectionDataBuilder == null) { sectionDataBuilder = new BlobBuilder(); } if (sectionDataBuilder.Count == 0) { sectionDataBuilder.WriteByte(0); } if (outputSectionIndex >= 0) { _sectionRawSizes[outputSectionIndex] = sectionDataBuilder.Count; } return(sectionDataBuilder); }
private static unsafe int GetPaddedSize() { return(AlignmentHelper.Pad(sizeof(T), ElementAlignment)); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { ObjectDataBuilder objData = new ObjectDataBuilder(factory); objData.Alignment = 16; objData.DefinedSymbols.Add(this); if (_type.IsArray) { objData.EmitShort((short)((ArrayType)_type).ElementType.GetElementSize()); // m_ComponentSize objData.EmitShort(0x4); // m_flags: IsArray(0x4) } else if (_type.IsString) { objData.EmitShort(2); // m_ComponentSize objData.EmitShort(0); // m_flags: 0 } else { objData.EmitShort(0); // m_ComponentSize objData.EmitShort(0); // m_flags: 0 } int pointerSize = _type.Context.Target.PointerSize; int minimumObjectSize = pointerSize * 3; int objectSize; if (_type is MetadataType) { objectSize = pointerSize + ((MetadataType)_type).InstanceByteCount; // +pointerSize for SyncBlock } else if (_type is ArrayType) { objectSize = 3 * pointerSize; // SyncBlock + EETypePtr + Length int rank = ((ArrayType)_type).Rank; if (rank > 1) { objectSize += 2 * _type.Context.GetWellKnownType(WellKnownType.Int32).GetElementSize() * rank; } } else { throw new NotImplementedException(); } objectSize = AlignmentHelper.AlignUp(objectSize, pointerSize); objectSize = Math.Max(minimumObjectSize, objectSize); if (_type.IsString) { // If this is a string, throw away objectSize we computed so far. Strings are special. // SyncBlock + EETypePtr + length + firstChar objectSize = 2 * pointerSize + _type.Context.GetWellKnownType(WellKnownType.Int32).GetElementSize() + _type.Context.GetWellKnownType(WellKnownType.Char).GetElementSize(); } objData.EmitInt(objectSize); if (Type.BaseType != null) { if (_constructed) { objData.EmitPointerReloc(factory.ConstructedTypeSymbol(Type.BaseType)); } else { objData.EmitPointerReloc(factory.NecessaryTypeSymbol(Type.BaseType)); } } else { objData.EmitZeroPointer(); } if (_constructed) { OutputVirtualSlots(ref objData, _type, _type, factory); } return(objData.ToObjectData()); }
protected virtual void OutputBaseSize(ref ObjectDataBuilder objData) { int pointerSize = _type.Context.Target.PointerSize; int objectSize; if (_type.IsDefType) { LayoutInt instanceByteCount = ((DefType)_type).InstanceByteCount; if (instanceByteCount.IsIndeterminate) { // Some value must be put in, but the specific value doesn't matter as it // isn't used for specific instantiations, and the universal canon eetype // is never associated with an allocated object. objectSize = pointerSize; } else { objectSize = pointerSize + ((DefType)_type).InstanceByteCount.AsInt; // +pointerSize for SyncBlock } if (_type.IsValueType) { objectSize += pointerSize; // + EETypePtr field inherited from System.Object } } else if (_type.IsArray) { objectSize = 3 * pointerSize; // SyncBlock + EETypePtr + Length if (_type.IsMdArray) { objectSize += 2 * sizeof(int) * ((ArrayType)_type).Rank; } } else if (_type.IsPointer) { // These never get boxed and don't have a base size. Use a sentinel value recognized by the runtime. objData.EmitInt(ParameterizedTypeShapeConstants.Pointer); return; } else if (_type.IsByRef) { // These never get boxed and don't have a base size. Use a sentinel value recognized by the runtime. objData.EmitInt(ParameterizedTypeShapeConstants.ByRef); return; } else { throw new NotImplementedException(); } objectSize = AlignmentHelper.AlignUp(objectSize, pointerSize); objectSize = Math.Max(MinimumObjectSize, objectSize); if (_type.IsString) { // If this is a string, throw away objectSize we computed so far. Strings are special. // SyncBlock + EETypePtr + length + firstChar objectSize = 2 * pointerSize + sizeof(int) + StringComponentSize.Value; } objData.EmitInt(objectSize); }
private void AlignNextObject(ref ObjectDataBuilder builder, NodeFactory factory) { builder.EmitZeros(AlignmentHelper.AlignUp(builder.CountBytes, factory.Target.PointerSize) - builder.CountBytes); }
/// <summary> /// Creates a new <see cref="Buffer{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="GraphicsDevice"/> associated with the current instance.</param> /// <param name="length">The number of items to store in the current buffer.</param> /// <param name="elementSizeInBytes">The size in bytes of each buffer item (including padding, if any).</param> /// <param name="resourceType">The resource type for the current buffer.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected Buffer(GraphicsDevice device, int length, uint elementSizeInBytes, ResourceType resourceType, AllocationMode allocationMode) { device.ThrowIfDisposed(); if (resourceType == ResourceType.Constant) { Guard.IsBetweenOrEqualTo(length, 1, D3D12.D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); } else { // The maximum length is set such that the aligned buffer size can't exceed uint.MaxValue Guard.IsBetweenOrEqualTo(length, 1, (uint.MaxValue / elementSizeInBytes) & ~255); } if (TypeInfo <T> .IsDoubleOrContainsDoubles && device.D3D12Device->CheckFeatureSupport <D3D12_FEATURE_DATA_D3D12_OPTIONS>(D3D12_FEATURE_D3D12_OPTIONS).DoublePrecisionFloatShaderOps == 0) { UnsupportedDoubleOperationException.Throw <T>(); } nint usableSizeInBytes = checked ((nint)(length * elementSizeInBytes)); nint effectiveSizeInBytes = resourceType == ResourceType.Constant ? AlignmentHelper.Pad(usableSizeInBytes, D3D12.D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT) : usableSizeInBytes; SizeInBytes = usableSizeInBytes; GraphicsDevice = device; Length = length; #if NET6_0_OR_GREATER this.allocation = device.Allocator->CreateResource(device.Pool, resourceType, allocationMode, (ulong)effectiveSizeInBytes); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); #else this.d3D12Resource = device.D3D12Device->CreateCommittedResource(resourceType, (ulong)effectiveSizeInBytes, device.IsCacheCoherentUMA); #endif device.RegisterAllocatedResource(); device.RentShaderResourceViewDescriptorHandles(out this.d3D12ResourceDescriptorHandles); device.RentShaderResourceViewDescriptorHandles(out this.d3D12ResourceDescriptorHandlesForTypedUnorderedAccessView); switch (resourceType) { case ResourceType.Constant: device.D3D12Device->CreateConstantBufferView(this.d3D12Resource.Get(), effectiveSizeInBytes, this.d3D12ResourceDescriptorHandles.D3D12CpuDescriptorHandle); break; case ResourceType.ReadOnly: device.D3D12Device->CreateShaderResourceView(this.d3D12Resource.Get(), (uint)length, elementSizeInBytes, this.d3D12ResourceDescriptorHandles.D3D12CpuDescriptorHandle); break; case ResourceType.ReadWrite: device.D3D12Device->CreateUnorderedAccessView(this.d3D12Resource.Get(), (uint)length, elementSizeInBytes, this.d3D12ResourceDescriptorHandles.D3D12CpuDescriptorHandle); device.D3D12Device->CreateUnorderedAccessViewForClear( this.d3D12Resource.Get(), DXGI_FORMAT_R32_UINT, (uint)(usableSizeInBytes / sizeof(uint)), this.d3D12ResourceDescriptorHandlesForTypedUnorderedAccessView.D3D12CpuDescriptorHandle, this.d3D12ResourceDescriptorHandlesForTypedUnorderedAccessView.D3D12CpuDescriptorHandleNonShaderVisible); break; } this.d3D12Resource.Get()->SetName(this); }