// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; namespace dnlib.DotNet.Writer { readonly struct SectionSizeInfo { /// /// Length of section /// public readonly uint length; /// /// Section characteristics /// public readonly uint characteristics; /// /// Constructor /// /// Length of section /// Section characteristics public SectionSizeInfo(uint length, uint characteristics) { this.length = length; this.characteristics = characteristics; } } /// /// Calculates the optional header section sizes /// readonly struct SectionSizes { public readonly uint SizeOfHeaders; public readonly uint SizeOfImage; public readonly uint BaseOfData, BaseOfCode; public readonly uint SizeOfCode, SizeOfInitdData, SizeOfUninitdData; public static uint GetSizeOfHeaders(uint fileAlignment, uint headerLen) => Utils.AlignUp(headerLen, fileAlignment); public SectionSizes(uint fileAlignment, uint sectionAlignment, uint headerLen, Func> getSectionSizeInfos) { SizeOfHeaders = GetSizeOfHeaders(fileAlignment, headerLen); SizeOfImage = Utils.AlignUp(SizeOfHeaders, sectionAlignment); BaseOfData = 0; BaseOfCode = 0; SizeOfCode = 0; SizeOfInitdData = 0; SizeOfUninitdData = 0; foreach (var section in getSectionSizeInfos()) { uint sectAlignedVs = Utils.AlignUp(section.length, sectionAlignment); uint fileAlignedVs = Utils.AlignUp(section.length, fileAlignment); bool isCode = (section.characteristics & 0x20) != 0; bool isInitdData = (section.characteristics & 0x40) != 0; bool isUnInitdData = (section.characteristics & 0x80) != 0; if (BaseOfCode == 0 && isCode) BaseOfCode = SizeOfImage; if (BaseOfData == 0 && (isInitdData || isUnInitdData)) BaseOfData = SizeOfImage; if (isCode) SizeOfCode += fileAlignedVs; if (isInitdData) SizeOfInitdData += fileAlignedVs; if (isUnInitdData) SizeOfUninitdData += fileAlignedVs; SizeOfImage += sectAlignedVs; } } } }