提交 47cca4eb 编写于 作者: T Tomas Matousek

Text section header cleanup

上级 16975929
......@@ -1255,6 +1255,7 @@ internal List<Win32Resource> MakeWin32ResourceList(Stream win32Resources, Diagno
return new Cci.ModulePropertiesForSerialization(
persistentIdentifier: moduleVersionId,
fileAlignment: fileAlignment,
sectionAlignment: Cci.ModulePropertiesForSerialization.DefaultSectionAlignment,
targetRuntimeVersion: targetRuntimeVersion,
machine: machine,
prefer32Bit: platform == Platform.AnyCpu32BitPreferred,
......
......@@ -11,9 +11,17 @@ namespace Microsoft.Cci
internal sealed class ModulePropertiesForSerialization
{
/// <summary>
/// The alignment of sections in the module's image file.
/// The alignment factor (in bytes) that is used to align the raw data of sections in the image file.
/// The value should be a power of 2 between 512 and 64K, inclusive. The default is 512.
/// </summary>
public readonly ushort FileAlignment;
public readonly int FileAlignment;
/// <summary>
/// The alignment (in bytes) of sections when they are loaded into memory.
/// It must be greater than or equal to <see cref="FileAlignment"/>.
/// The default is the page size for the architecture.
/// </summary>
public readonly int SectionAlignment;
/// <summary>
/// Identifies the version of the CLR that is required to load this module or assembly.
......@@ -122,12 +130,15 @@ internal sealed class ModulePropertiesForSerialization
public const ulong DefaultSizeOfStackCommit32Bit = 0x1000;
public const ulong DefaultSizeOfStackCommit64Bit = 0x4000;
public const ushort DefaultFileAlignment32Bit = 0x00000200;
public const ushort DefaultFileAlignment64Bit = 0x00000200; //both 32 and 64 bit binaries used this value in the native stack.
public const ushort DefaultFileAlignment32Bit = 0x200;
public const ushort DefaultFileAlignment64Bit = 0x200; //both 32 and 64 bit binaries used this value in the native stack.
public const ushort DefaultSectionAlignment = 0x2000;
internal ModulePropertiesForSerialization(
Guid persistentIdentifier,
ushort fileAlignment,
int fileAlignment,
int sectionAlignment,
string targetRuntimeVersion,
Machine machine,
bool prefer32Bit,
......@@ -149,6 +160,7 @@ internal sealed class ModulePropertiesForSerialization
{
this.PersistentIdentifier = persistentIdentifier;
this.FileAlignment = fileAlignment;
this.SectionAlignment = sectionAlignment;
this.TargetRuntimeVersion = targetRuntimeVersion;
this.Machine = machine;
this.Prefers32Bit = prefer32Bit;
......
......@@ -105,11 +105,13 @@ private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream,
// based on the contents of the generated stream.
Debug.Assert(_properties.PersistentIdentifier == default(Guid));
int sizeOfPeHeaders = ComputeSizeOfPeHeaders();
int textSectionRva = BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.SectionAlignment);
int moduleVersionIdOffsetInMetadataStream;
var calculateMethodBodyStreamRva = new Func<MetadataSizes, int>(mdSizes =>
{
FillInTextSectionHeader(mdSizes);
return _textSection.RelativeVirtualAddress + _sizeOfImportAddressTable + 72;
return textSectionRva + _sizeOfImportAddressTable + CorHeaderSize;
});
int entryPointToken;
......@@ -161,11 +163,11 @@ private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream,
nativePdbContentId = default(ContentId);
}
FillInSectionHeaders();
FillInSectionHeaders(metadataSizes);
// fill in header fields.
FillInNtHeader(metadataSizes, CalculateMappedFieldDataStreamRva(metadataSizes));
var corHeader = CreateCorHeader(metadataSizes, entryPointToken);
var corHeader = CreateCorHeader(metadataSizes, textSectionRva, entryPointToken);
// write to PE stream.
Stream peStream = getPeStream();
......@@ -202,12 +204,26 @@ private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream,
return true;
}
private int CalculateMappedFieldDataStreamRva(MetadataSizes metadataSizes)
private int CalculateOffsetToMappedFieldDataStream(MetadataSizes metadataSizes)
{
FillInTextSectionHeader(metadataSizes);
int result = ComputeOffsetToImportTable(metadataSizes);
Debug.Assert(metadataSizes.MappedFieldDataSize % MetadataWriter.MappedFieldDataAlignment == 0);
return (int)(_textSection.RelativeVirtualAddress + _textSection.VirtualSize - metadataSizes.MappedFieldDataSize);
if (_properties.RequiresStartupStub)
{
result += _is32bit ? 66 : 70; //size of import table
result += 14; //size of name table
result = BitArithmeticUtilities.Align(result, _is32bit ? 4 : 8); //optional padding to make startup stub's target address align on word or double word boundary
result += _is32bit ? 8 : 16; //fixed size of runtime startup stub
}
return result;
}
private int CalculateMappedFieldDataStreamRva(MetadataSizes metadataSizes)
{
int sizeOfPeHeaders = ComputeSizeOfPeHeaders();
int textSectionRva = BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.SectionAlignment);
return textSectionRva + CalculateOffsetToMappedFieldDataStream(metadataSizes);
}
/// <summary>
......@@ -266,18 +282,33 @@ private int ComputeOffsetToDebugTable(MetadataSizes metadataSizes)
private int ComputeOffsetToImportTable(MetadataSizes metadataSizes)
{
// TODO: add size of unmanaged export stubs (when and if these are ever supported).
return
ComputeOffsetToDebugTable(metadataSizes) +
ComputeSizeOfDebugDirectory();
}
private const int CorHeaderSize =
sizeof(int) + // header size
sizeof(short) + // major runtime version
sizeof(short) + // minor runtime version
sizeof(long) + // metadata directory
sizeof(int) + // COR flags
sizeof(int) + // entry point
sizeof(long) + // resources directory
sizeof(long) + // strong name signature directory
sizeof(long) + // code manager table directory
sizeof(long) + // vtable fixups directory
sizeof(long) + // export address table jumps directory
sizeof(long); // managed-native header directory
private int ComputeOffsetToILStream()
{
return _sizeOfImportAddressTable + CorHeaderSize;
}
private int ComputeOffsetToMetadata(int ilStreamLength)
{
return
_sizeOfImportAddressTable +
72 + // size of CLR header
BitArithmeticUtilities.Align(ilStreamLength, 4);
return ComputeOffsetToILStream() + BitArithmeticUtilities.Align(ilStreamLength, 4);
}
private const int ImageDebugDirectoryBaseSize =
......@@ -326,19 +357,8 @@ private int ComputeSizeOfPeHeaders()
private int ComputeSizeOfTextSection(MetadataSizes metadataSizes)
{
int textSectionLength = this.ComputeOffsetToImportTable(metadataSizes);
if (_properties.RequiresStartupStub)
{
textSectionLength += _is32bit ? 66 : 70; //size of import table
textSectionLength += 14; //size of name table
textSectionLength = BitArithmeticUtilities.Align(textSectionLength, _is32bit ? 4 : 8); //optional padding to make startup stub's target address align on word or double word boundary
textSectionLength += _is32bit ? 8 : 16; //fixed size of runtime startup stub
}
Debug.Assert(metadataSizes.MappedFieldDataSize % MetadataWriter.MappedFieldDataAlignment == 0);
textSectionLength += metadataSizes.MappedFieldDataSize;
return textSectionLength;
return CalculateOffsetToMappedFieldDataStream(metadataSizes) + metadataSizes.MappedFieldDataSize;
}
private int ComputeSizeOfWin32Resources(int resourcesRva)
......@@ -353,9 +373,9 @@ private int ComputeSizeOfWin32Resources(int resourcesRva)
return result;
}
private CorHeader CreateCorHeader(MetadataSizes metadataSizes, int entryPointToken)
private CorHeader CreateCorHeader(MetadataSizes metadataSizes, int textSectionRva, int entryPointToken)
{
int metadataRva = _textSection.RelativeVirtualAddress + ComputeOffsetToMetadata(metadataSizes.ILStreamSize);
int metadataRva = textSectionRva + ComputeOffsetToMetadata(metadataSizes.ILStreamSize);
int resourcesRva = metadataRva + metadataSizes.MetadataSize;
int signatureRva = resourcesRva + metadataSizes.ResourceDataSize;
......@@ -413,7 +433,7 @@ private void FillInNtHeader(MetadataSizes metadataSizes, int mappedFieldDataStre
ntHeader.SizeOfHeaders = BitArithmeticUtilities.Align(ComputeSizeOfPeHeaders(), _properties.FileAlignment);
// TODO: last section:
ntHeader.SizeOfImage = BitArithmeticUtilities.Align(_relocSection.RelativeVirtualAddress + _relocSection.VirtualSize, 0x2000);
ntHeader.SizeOfImage = BitArithmeticUtilities.Align(_relocSection.RelativeVirtualAddress + _relocSection.VirtualSize, _properties.SectionAlignment);
ntHeader.SizeOfUninitializedData = 0;
ntHeader.ImportAddressTable = new DirectoryEntry(
......@@ -422,7 +442,7 @@ private void FillInNtHeader(MetadataSizes metadataSizes, int mappedFieldDataStre
ntHeader.CliHeaderTable = new DirectoryEntry(
textSectionRva + _sizeOfImportAddressTable,
size: 72); // TODO: constants
size: CorHeaderSize);
if (_properties.RequiresStartupStub)
{
......@@ -451,33 +471,27 @@ private void FillInNtHeader(MetadataSizes metadataSizes, int mappedFieldDataStre
}
}
private void FillInTextSectionHeader(MetadataSizes metadataSizes)
private void FillInSectionHeaders(MetadataSizes metadataSizes)
{
if (_textSection == null)
{
int sizeOfPeHeaders = ComputeSizeOfPeHeaders();
int sizeOfTextSection = ComputeSizeOfTextSection(metadataSizes);
_textSection = new SectionHeader(
characteristics: SectionCharacteristics.MemRead |
SectionCharacteristics.MemExecute |
SectionCharacteristics.ContainsCode,
name: ".text",
numberOfLinenumbers: 0,
numberOfRelocations: 0,
pointerToLinenumbers: 0,
pointerToRawData: BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.FileAlignment),
pointerToRelocations: 0,
relativeVirtualAddress: BitArithmeticUtilities.Align(sizeOfPeHeaders, 0x2000),
sizeOfRawData: BitArithmeticUtilities.Align(sizeOfTextSection, _properties.FileAlignment),
virtualSize: sizeOfTextSection
);
}
}
int sizeOfPeHeaders = ComputeSizeOfPeHeaders();
int sizeOfTextSection = ComputeSizeOfTextSection(metadataSizes);
private void FillInSectionHeaders()
{
int resourcesRva = BitArithmeticUtilities.Align(_textSection.RelativeVirtualAddress + _textSection.VirtualSize, 0x2000);
_textSection = new SectionHeader(
characteristics: SectionCharacteristics.MemRead |
SectionCharacteristics.MemExecute |
SectionCharacteristics.ContainsCode,
name: ".text",
numberOfLinenumbers: 0,
numberOfRelocations: 0,
pointerToLinenumbers: 0,
pointerToRawData: BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.FileAlignment),
pointerToRelocations: 0,
relativeVirtualAddress: BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.SectionAlignment),
sizeOfRawData: BitArithmeticUtilities.Align(sizeOfTextSection, _properties.FileAlignment),
virtualSize: sizeOfTextSection
);
int resourcesRva = BitArithmeticUtilities.Align(_textSection.RelativeVirtualAddress + _textSection.VirtualSize, _properties.SectionAlignment);
int sizeOfWin32Resources = this.ComputeSizeOfWin32Resources(resourcesRva);
_resourceSection = new SectionHeader(
......@@ -504,7 +518,7 @@ private void FillInSectionHeaders()
pointerToLinenumbers: 0,
pointerToRawData: _resourceSection.PointerToRawData + _resourceSection.SizeOfRawData,
pointerToRelocations: 0,
relativeVirtualAddress: BitArithmeticUtilities.Align(_resourceSection.RelativeVirtualAddress + _resourceSection.VirtualSize, 0x2000),
relativeVirtualAddress: BitArithmeticUtilities.Align(_resourceSection.RelativeVirtualAddress + _resourceSection.VirtualSize, _properties.SectionAlignment),
sizeOfRawData: _properties.RequiresStartupStub ? _properties.FileAlignment : 0,
virtualSize: _properties.RequiresStartupStub ? (_properties.Requires64bits && !_properties.RequiresAmdInstructionSet ? 14 : 12) : 0
);
......@@ -1201,25 +1215,27 @@ private static void WriteNameTable(Stream peStream)
private static void WriteCorHeader(Stream peStream, CorHeader corHeader)
{
var writer = new BlobWriter(72);
writer.WriteUint(72); // Number of bytes in this header 4
writer.WriteUshort(corHeader.MajorRuntimeVersion); // 6
writer.WriteUshort(corHeader.MinorRuntimeVersion); // 8
writer.WriteUint((uint)corHeader.MetadataDirectory.RelativeVirtualAddress); // 12
writer.WriteUint((uint)corHeader.MetadataDirectory.Size); // 16
writer.WriteUint((uint)corHeader.Flags); // 20
writer.WriteUint((uint)corHeader.EntryPointTokenOrRelativeVirtualAddress); // 24
var writer = new BlobWriter(CorHeaderSize);
writer.WriteUint(CorHeaderSize);
writer.WriteUshort(corHeader.MajorRuntimeVersion);
writer.WriteUshort(corHeader.MinorRuntimeVersion);
writer.WriteUint((uint)corHeader.MetadataDirectory.RelativeVirtualAddress);
writer.WriteUint((uint)corHeader.MetadataDirectory.Size);
writer.WriteUint((uint)corHeader.Flags);
writer.WriteUint((uint)corHeader.EntryPointTokenOrRelativeVirtualAddress);
writer.WriteUint((uint)(corHeader.ResourcesDirectory.Size == 0 ? 0 : corHeader.ResourcesDirectory.RelativeVirtualAddress)); // 28
writer.WriteUint((uint)corHeader.ResourcesDirectory.Size); // 32
writer.WriteUint((uint)corHeader.ResourcesDirectory.Size);
writer.WriteUint((uint)(corHeader.StrongNameSignatureDirectory.Size == 0 ? 0 : corHeader.StrongNameSignatureDirectory.RelativeVirtualAddress)); // 36
writer.WriteUint((uint)corHeader.StrongNameSignatureDirectory.Size); // 40
writer.WriteUint((uint)corHeader.CodeManagerTableDirectory.RelativeVirtualAddress); // 44
writer.WriteUint((uint)corHeader.CodeManagerTableDirectory.Size); // 48
writer.WriteUint((uint)corHeader.VtableFixupsDirectory.RelativeVirtualAddress); // 52
writer.WriteUint((uint)corHeader.VtableFixupsDirectory.Size); // 56
writer.WriteUint((uint)corHeader.ExportAddressTableJumpsDirectory.RelativeVirtualAddress); // 60
writer.WriteUint((uint)corHeader.ExportAddressTableJumpsDirectory.Size); // 64
writer.WriteUlong(0); // 72
writer.WriteUint((uint)corHeader.StrongNameSignatureDirectory.Size);
writer.WriteUint((uint)corHeader.CodeManagerTableDirectory.RelativeVirtualAddress);
writer.WriteUint((uint)corHeader.CodeManagerTableDirectory.Size);
writer.WriteUint((uint)corHeader.VtableFixupsDirectory.RelativeVirtualAddress);
writer.WriteUint((uint)corHeader.VtableFixupsDirectory.Size);
writer.WriteUint((uint)corHeader.ExportAddressTableJumpsDirectory.RelativeVirtualAddress);
writer.WriteUint((uint)corHeader.ExportAddressTableJumpsDirectory.Size);
writer.WriteUlong(0);
Debug.Assert(writer.Length == CorHeaderSize);
writer.WriteTo(peStream);
}
......
......@@ -504,6 +504,7 @@ internal static Cci.ModulePropertiesForSerialization GetDefaultModulePropertiesF
return new Cci.ModulePropertiesForSerialization(
persistentIdentifier: default(Guid),
fileAlignment: Cci.ModulePropertiesForSerialization.DefaultFileAlignment32Bit,
sectionAlignment: Cci.ModulePropertiesForSerialization.DefaultSectionAlignment,
targetRuntimeVersion: "v4.0.30319",
machine: 0,
prefer32Bit: false,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册