コード例 #1
0
 private void SerializeMethodBodyTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _methodBodyTable)
     {
         writer.WriteReference((uint)_debugHeapsOpt.ResolveBlobIndex(row.SequencePoints), metadataSizes.BlobIndexSize);
     }
 }
コード例 #2
0
 private void SerializeLocalConstantTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _localConstantTable)
     {
         writer.WriteReference((uint)_debugHeapsOpt.ResolveStringIndex(row.Name), metadataSizes.StringIndexSize);
         writer.WriteReference((uint)_debugHeapsOpt.ResolveBlobIndex(row.Signature), metadataSizes.BlobIndexSize);
     }
 }
コード例 #3
0
 private void SerializeImportScopeTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _importScopeTable)
     {
         writer.WriteReference(row.Parent, metadataSizes.ImportScopeIndexSize);
         writer.WriteReference((uint)_debugHeapsOpt.ResolveBlobIndex(row.Imports), metadataSizes.BlobIndexSize);
     }
 }
コード例 #4
0
 private void SerializeStateMachineMethodTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _stateMachineMethodTable)
     {
         writer.WriteReference(row.MoveNextMethod, metadataSizes.MethodDefIndexSize);
         writer.WriteReference(row.KickoffMethod, metadataSizes.MethodDefIndexSize);
     }
 }
コード例 #5
0
 private void SerializeLocalVariableTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _localVariableTable)
     {
         writer.WriteUInt16(row.Attributes);
         writer.WriteUInt16(row.Index);
         writer.WriteReference((uint)_debugHeapsOpt.ResolveStringIndex(row.Name), metadataSizes.StringIndexSize);
     }
 }
コード例 #6
0
 private void SerializeDocumentTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _documentTable)
     {
         writer.WriteReference((uint)_debugHeapsOpt.ResolveBlobIndex(row.Name), metadataSizes.BlobIndexSize);
         writer.WriteReference(row.HashAlgorithm, metadataSizes.GuidIndexSize);
         writer.WriteReference((uint)_debugHeapsOpt.ResolveBlobIndex(row.Hash), metadataSizes.BlobIndexSize);
         writer.WriteReference(row.Language, metadataSizes.GuidIndexSize);
     }
 }
コード例 #7
0
        private void SerializeCustomDebugInformationTable(BlobBuilder writer, MetadataSizes metadataSizes)
        {
            // sort by Parent, Kind
            _customDebugInformationTable.Sort(CustomDebugInformationRowComparer.Instance);

            foreach (var row in _customDebugInformationTable)
            {
                writer.WriteReference(row.Parent, metadataSizes.HasCustomDebugInformationSize);
                writer.WriteReference(row.Kind, metadataSizes.GuidIndexSize);
                writer.WriteReference((uint)_debugHeapsOpt.ResolveBlobIndex(row.Value), metadataSizes.BlobIndexSize);
            }
        }
コード例 #8
0
 private void SerializeLocalScopeTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _localScopeTable)
     {
         writer.WriteReference(row.Method, metadataSizes.MethodDefIndexSize);
         writer.WriteReference(row.ImportScope, metadataSizes.ImportScopeIndexSize);
         writer.WriteReference(row.VariableList, metadataSizes.LocalVariableIndexSize);
         writer.WriteReference(row.ConstantList, metadataSizes.LocalConstantIndexSize);
         writer.WriteUInt32(row.StartOffset);
         writer.WriteUInt32(row.Length);
     }
 }
コード例 #9
0
ファイル: PeWriter.cs プロジェクト: elemk0vv/roslyn-1
 private uint ComputeOffsetToDebugTable(MetadataSizes metadataSizes)
 {
     uint result = this.ComputeOffsetToMetadata(metadataSizes.ILStreamSize);
     result += (uint)metadataSizes.MetadataSize;
     result += (uint)metadataSizes.ResourceDataSize;
     result += this.ComputeStrongNameSignatureSize(); // size of strong name hash
     return result;
 }
コード例 #10
0
ファイル: PeWriter.cs プロジェクト: elemk0vv/roslyn-1
 private uint ComputeOffsetToImportTable(MetadataSizes metadataSizes)
 {
     uint result = this.ComputeOffsetToDebugTable(metadataSizes);
     result += this.ComputeSizeOfDebugTable(result);
     result += 0; // TODO: size of unmanaged export stubs (when and if these are ever supported).
     return result;
 }
コード例 #11
0
ファイル: PeWriter.cs プロジェクト: AnthonyDGreen/roslyn
        private readonly static byte[] s_zeroStamp = new byte[4]; // four bytes of zero

        /// <summary>
        /// Write the entire "Debug Directory (Image Only)" along with data that it points to.
        /// </summary>
        private void WriteDebugTable(Stream peStream, SectionHeader textSection, ContentId nativePdbContentId, ContentId portablePdbContentId, MetadataSizes metadataSizes)
        {
            int tableSize = ImageDebugDirectoryBaseSize;
            Debug.Assert(tableSize != 0);
            Debug.Assert(nativePdbContentId.IsDefault || portablePdbContentId.IsDefault);
            Debug.Assert(!EmitPdb || (nativePdbContentId.IsDefault ^ portablePdbContentId.IsDefault));

            var writer = PooledBlobBuilder.GetInstance();

            int dataSize = ComputeSizeOfDebugDirectoryData();
            if (this.EmitPdb)
            {
                const int IMAGE_DEBUG_TYPE_CODEVIEW = 2; // from PE spec
                uint dataOffset = (uint)(ComputeOffsetToDebugTable(metadataSizes) + tableSize);
                WriteDebugTableEntry(writer,
                    stamp: nativePdbContentId.Stamp ?? portablePdbContentId.Stamp,
                    version: portablePdbContentId.IsDefault ? (uint)0 : ('P' << 24 | 'M' << 16 | 0x01 << 8 | 0x00),
                    debugType: IMAGE_DEBUG_TYPE_CODEVIEW,
                    sizeOfData: (uint)dataSize,
                    addressOfRawData: (uint)textSection.RelativeVirtualAddress + dataOffset, // RVA of the data
                    pointerToRawData: (uint)textSection.PointerToRawData + dataOffset); // position of the data in the PE stream
            }

            if (_deterministic)
            {
                const int IMAGE_DEBUG_TYPE_NO_TIMESTAMP = 16; // from PE spec
                WriteDebugTableEntry(writer,
                    stamp: s_zeroStamp,
                    version: 0,
                    debugType: IMAGE_DEBUG_TYPE_NO_TIMESTAMP,
                    sizeOfData: 0,
                    addressOfRawData: 0,
                    pointerToRawData: 0);
            }

            // We should now have written all and precisely the data we said we'd write for the table entries.
            Debug.Assert(writer.Count == tableSize);

            // ====================
            // The following is additional data beyond the debug directory at the offset `dataOffset`
            // pointed to by the ImageDebugTypeCodeView entry.

            if (EmitPdb)
            {
                writer.WriteByte((byte)'R');
                writer.WriteByte((byte)'S');
                writer.WriteByte((byte)'D');
                writer.WriteByte((byte)'S');

                // PDB id:
                writer.WriteBytes(nativePdbContentId.Guid ?? portablePdbContentId.Guid);

                // age
                writer.WriteUInt32(PdbWriter.Age);

                // UTF-8 encoded zero-terminated path to PDB
                int pathStart = writer.Position;
                writer.WriteUTF8(_pdbPathOpt, allowUnpairedSurrogates: true);
                writer.WriteByte(0);

                // padding:
                writer.WriteBytes(0, Math.Max(0, _minPdbPath - (writer.Position - pathStart)));
            }

            // We should now have written all and precisely the data we said we'd write for the table and its data.
            Debug.Assert(writer.Count == tableSize + dataSize);

            writer.WriteContentTo(peStream);
            writer.Free();
        }
コード例 #12
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private int CalculateMappedFieldDataStreamRva(MetadataSizes metadataSizes)
        {
            FillInTextSectionHeader(metadataSizes);

            Debug.Assert(metadataSizes.MappedFieldDataSize % MetadataWriter.MappedFieldDataAlignment == 0);
            return (int)(_textSection.RelativeVirtualAddress + _textSection.VirtualSize - metadataSizes.MappedFieldDataSize);
        }
コード例 #13
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private int ComputeOffsetToDebugTable(MetadataSizes metadataSizes)
        {
            Debug.Assert(metadataSizes.MetadataSize % 4 == 0);
            Debug.Assert(metadataSizes.ResourceDataSize % 4 == 0);

            return
                ComputeOffsetToMetadata(metadataSizes.ILStreamSize) +
                metadataSizes.MetadataSize +
                metadataSizes.ResourceDataSize +
                metadataSizes.StrongNameSignatureSize;
        }
コード例 #14
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private int CalculateOffsetToMappedFieldDataStream(MetadataSizes metadataSizes)
        {
            int result = ComputeOffsetToImportTable(metadataSizes);

            if (_properties.RequiresStartupStub)
            {
                result += SizeOfImportTable + SizeOfNameTable;
                result = BitArithmeticUtilities.Align(result, _is32bit ? 4 : 8); //optional padding to make startup stub's target address align on word or double word boundary
                result += SizeOfRuntimeStartupStub;
            }

            return result;
        }
コード例 #15
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteDebugTable(Stream peStream, SectionHeader textSection, ContentId nativePdbContentId, ContentId portablePdbContentId, MetadataSizes metadataSizes)
        {
            Debug.Assert(nativePdbContentId.IsDefault ^ portablePdbContentId.IsDefault);

            var writer = PooledBlobBuilder.GetInstance();

            // characteristics:
            writer.WriteUInt32(0);

            // PDB stamp & version
            if (portablePdbContentId.IsDefault)
            {
                writer.WriteBytes(nativePdbContentId.Stamp);
                writer.WriteUInt32(0);
            }
            else
            {
                writer.WriteBytes(portablePdbContentId.Stamp);
                writer.WriteUInt32('P' << 24 | 'M' << 16 | 0x00 << 8 | 0x01);
            }
            
            // type: 
            const int ImageDebugTypeCodeView = 2;
            writer.WriteUInt32(ImageDebugTypeCodeView);

            // size of data:
            writer.WriteUInt32((uint)ComputeSizeOfDebugDirectoryData());

            uint dataOffset = (uint)ComputeOffsetToDebugTable(metadataSizes) + ImageDebugDirectoryBaseSize;

            // PointerToRawData (RVA of the data):
            writer.WriteUInt32((uint)textSection.RelativeVirtualAddress + dataOffset);

            // AddressOfRawData (position of the data in the PE stream):
            writer.WriteUInt32((uint)textSection.PointerToRawData + dataOffset);

            writer.WriteByte((byte)'R');
            writer.WriteByte((byte)'S');
            writer.WriteByte((byte)'D');
            writer.WriteByte((byte)'S');

            // PDB id:
            writer.WriteBytes(nativePdbContentId.Guid ?? portablePdbContentId.Guid);

            // age
            writer.WriteUInt32(PdbWriter.Age);

            // UTF-8 encoded zero-terminated path to PDB
            writer.WriteUTF8(_pdbPathOpt, allowUnpairedSurrogates: true);
            writer.WriteByte(0);

            writer.WriteContentTo(peStream);
            writer.Free();
        }
コード例 #16
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private void FillInTextSectionHeader(MetadataSizes metadataSizes)
        {
            if (_textSection == null)
            {
                uint sizeOfPeHeaders = (uint)ComputeSizeOfPeHeaders();
                uint sizeOfTextSection = (uint)ComputeSizeOfTextSection(metadataSizes);

                _textSection = new SectionHeader
                {
                    Characteristics = 0x60000020, // section is read + execute + code 
                    Name = ".text",
                    NumberOfLinenumbers = 0,
                    NumberOfRelocations = 0,
                    PointerToLinenumbers = 0,
                    PointerToRawData = BitArithmeticUtilities.Align(sizeOfPeHeaders, _module.FileAlignment),
                    PointerToRelocations = 0,
                    RelativeVirtualAddress = BitArithmeticUtilities.Align(sizeOfPeHeaders, 0x2000),
                    SizeOfRawData = BitArithmeticUtilities.Align(sizeOfTextSection, _module.FileAlignment),
                    VirtualSize = sizeOfTextSection
                };
            }
        }
コード例 #17
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private void FillInNtHeader(MetadataSizes metadataSizes, int mappedFieldDataStreamRva)
        {
            bool use32bitAddresses = !_module.Requires64bits;
            NtHeader ntHeader = _ntHeader;
            ntHeader.AddressOfEntryPoint = _emitRuntimeStartupStub ? (uint)mappedFieldDataStreamRva - (use32bitAddresses ? 6u : 10u) : 0;
            ntHeader.BaseOfCode = _textSection.RelativeVirtualAddress;
            ntHeader.BaseOfData = _rdataSection.RelativeVirtualAddress;
            ntHeader.PointerToSymbolTable = 0;
            ntHeader.SizeOfCode = _textSection.SizeOfRawData;
            ntHeader.SizeOfInitializedData = _rdataSection.SizeOfRawData + _coverSection.SizeOfRawData + _sdataSection.SizeOfRawData + _tlsSection.SizeOfRawData + _resourceSection.SizeOfRawData + _relocSection.SizeOfRawData;
            ntHeader.SizeOfHeaders = BitArithmeticUtilities.Align(this.ComputeSizeOfPeHeaders(), _module.FileAlignment);
            ntHeader.SizeOfImage = BitArithmeticUtilities.Align(_relocSection.RelativeVirtualAddress + _relocSection.VirtualSize, 0x2000);
            ntHeader.SizeOfUninitializedData = 0;

            // In the PE File Header this is a "Time/Date Stamp" whose description is "Time and date
            // the file was created in seconds since January 1st 1970 00:00:00 or 0"
            // However, when we want to make it deterministic we fill it in (later) with bits from the hash of the full PE file.
            ntHeader.TimeDateStamp = _deterministic ? 0 : (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

            ntHeader.ImportAddressTable.RelativeVirtualAddress = (_emitRuntimeStartupStub) ? _textSection.RelativeVirtualAddress : 0;
            ntHeader.ImportAddressTable.Size = (uint)_sizeOfImportAddressTable;

            ntHeader.CliHeaderTable.RelativeVirtualAddress = _textSection.RelativeVirtualAddress + ntHeader.ImportAddressTable.Size;
            ntHeader.CliHeaderTable.Size = 72;

            ntHeader.ImportTable.RelativeVirtualAddress = _textSection.RelativeVirtualAddress + (uint)ComputeOffsetToImportTable(metadataSizes);

            if (!_emitRuntimeStartupStub)
            {
                ntHeader.ImportTable.Size = 0;
                ntHeader.ImportTable.RelativeVirtualAddress = 0;
            }
            else
            {
                ntHeader.ImportTable.Size = use32bitAddresses ? 66u : 70u;
                ntHeader.ImportTable.Size += 13;  //size of nametable
            }

            ntHeader.BaseRelocationTable.RelativeVirtualAddress = (_emitRuntimeStartupStub) ? _relocSection.RelativeVirtualAddress : 0;
            ntHeader.BaseRelocationTable.Size = _relocSection.VirtualSize;
            ntHeader.BoundImportTable.RelativeVirtualAddress = 0;
            ntHeader.BoundImportTable.Size = 0;
            ntHeader.CertificateTable.RelativeVirtualAddress = 0;
            ntHeader.CertificateTable.Size = 0;
            ntHeader.CopyrightTable.RelativeVirtualAddress = 0;
            ntHeader.CopyrightTable.Size = 0;
            ntHeader.DebugTable.RelativeVirtualAddress = EmitPdb ? _textSection.RelativeVirtualAddress + (uint)ComputeOffsetToDebugTable(metadataSizes) : 0u;
            ntHeader.DebugTable.Size = EmitPdb ? ImageDebugDirectoryBaseSize : 0u; // Only the size of the fixed part of the debug table goes here.
            ntHeader.DelayImportTable.RelativeVirtualAddress = 0;
            ntHeader.DelayImportTable.Size = 0;
            ntHeader.ExceptionTable.RelativeVirtualAddress = 0;
            ntHeader.ExceptionTable.Size = 0;
            ntHeader.ExportTable.RelativeVirtualAddress = 0;
            ntHeader.ExportTable.Size = 0;
            ntHeader.GlobalPointerTable.RelativeVirtualAddress = 0;
            ntHeader.GlobalPointerTable.Size = 0;
            ntHeader.LoadConfigTable.RelativeVirtualAddress = 0;
            ntHeader.LoadConfigTable.Size = 0;
            ntHeader.Reserved.RelativeVirtualAddress = 0;
            ntHeader.Reserved.Size = 0;
            ntHeader.ResourceTable.RelativeVirtualAddress = _resourceSection.SizeOfRawData == 0 ? 0u : _resourceSection.RelativeVirtualAddress;
            ntHeader.ResourceTable.Size = _resourceSection.VirtualSize;
            ntHeader.ThreadLocalStorageTable.RelativeVirtualAddress = _tlsSection.SizeOfRawData == 0 ? 0u : _tlsSection.RelativeVirtualAddress;
            ntHeader.ThreadLocalStorageTable.Size = _tlsSection.SizeOfRawData;
        }
コード例 #18
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private CorHeader CreateCorHeader(MetadataSizes metadataSizes, int entryPointToken)
        {
            CorHeader corHeader = new CorHeader();
            corHeader.CodeManagerTable.RelativeVirtualAddress = 0;
            corHeader.CodeManagerTable.Size = 0;
            corHeader.EntryPointToken = (uint)entryPointToken;
            corHeader.ExportAddressTableJumps.RelativeVirtualAddress = 0;
            corHeader.ExportAddressTableJumps.Size = 0;
            corHeader.Flags = this.GetCorHeaderFlags();
            corHeader.MajorRuntimeVersion = 2;
            corHeader.MetadataDirectory.RelativeVirtualAddress = _textSection.RelativeVirtualAddress + (uint)ComputeOffsetToMetadata(metadataSizes.ILStreamSize);
            corHeader.MetadataDirectory.Size = (uint)metadataSizes.MetadataSize;
            corHeader.MinorRuntimeVersion = 5;
            corHeader.Resources.RelativeVirtualAddress = corHeader.MetadataDirectory.RelativeVirtualAddress + corHeader.MetadataDirectory.Size;
            corHeader.Resources.Size = (uint)metadataSizes.ResourceDataSize;
            corHeader.StrongNameSignature.RelativeVirtualAddress = corHeader.Resources.RelativeVirtualAddress + corHeader.Resources.Size;
            corHeader.StrongNameSignature.Size = (uint)ComputeStrongNameSignatureSize();
            corHeader.VTableFixups.RelativeVirtualAddress = 0;
            corHeader.VTableFixups.Size = 0;

            return corHeader;
        }
コード例 #19
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private int ComputeSizeOfTextSection(MetadataSizes metadataSizes)
        {
            int textSectionLength = this.ComputeOffsetToImportTable(metadataSizes);

            if (_emitRuntimeStartupStub)
            {
                textSectionLength += !_module.Requires64bits ? 66 : 70; //size of import table
                textSectionLength += 14; //size of name table
                textSectionLength = BitArithmeticUtilities.Align(textSectionLength, !_module.Requires64bits ? 4 : 8); //optional padding to make startup stub's target address align on word or double word boundary
                textSectionLength += !_module.Requires64bits ? 8 : 16; //fixed size of runtime startup stub
            }

            Debug.Assert(metadataSizes.MappedFieldDataSize % MetadataWriter.MappedFieldDataAlignment == 0);
            textSectionLength += metadataSizes.MappedFieldDataSize;
            return textSectionLength;
        }
コード例 #20
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
 private int ComputeOffsetToImportTable(MetadataSizes metadataSizes)
 {
     // TODO: add size of unmanaged export stubs (when and if these are ever supported).
     return
         ComputeOffsetToDebugTable(metadataSizes) +
         ComputeSizeOfDebugDirectory();
 }
コード例 #21
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
 private int ComputeOffsetToDebugTable(MetadataSizes metadataSizes)
 {
     return
         ComputeOffsetToMetadata(metadataSizes.ILStreamSize) +
         metadataSizes.MetadataSize +
         metadataSizes.ResourceDataSize +
         ComputeStrongNameSignatureSize(); // size of strong name hash
 }
コード例 #22
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteTextSection(
            Stream peStream,
            SectionHeader textSection,
            int importTableRva,
            int importAddressTableRva,
            int entryPointToken,
            BlobBuilder metadataWriter,
            BlobBuilder ilWriter,
            BlobBuilder mappedFieldDataWriter,
            BlobBuilder managedResourceWriter,
            MetadataSizes metadataSizes,
            ContentId nativePdbContentId,
            ContentId portablePdbContentId,
            out long metadataPosition)
        {
            // TODO: zero out all bytes:
            peStream.Position = textSection.PointerToRawData;

            if (_properties.RequiresStartupStub)
            {
                WriteImportAddressTable(peStream, importTableRva);
            }

            var corHeader = CreateCorHeader(metadataSizes, textSection.RelativeVirtualAddress, entryPointToken);
            WriteCorHeader(peStream, corHeader);

            // IL:
            ilWriter.Align(4);
            ilWriter.WriteContentTo(peStream);

            // metadata:
            metadataPosition = peStream.Position;
            Debug.Assert(metadataWriter.Count % 4 == 0);
            metadataWriter.WriteContentTo(peStream);

            // managed resources:
            Debug.Assert(managedResourceWriter.Count % 4 == 0);
            managedResourceWriter.WriteContentTo(peStream);

            // strong name signature:
            WriteSpaceForHash(peStream, metadataSizes.StrongNameSignatureSize);

            if (EmitPdb)
            {
                WriteDebugTable(peStream, textSection, nativePdbContentId, portablePdbContentId, metadataSizes);
            }

            if (_properties.RequiresStartupStub)
            {
                WriteImportTable(peStream, importTableRva, importAddressTableRva);
                WriteNameTable(peStream);
                WriteRuntimeStartupStub(peStream, importAddressTableRva);
            }

            // mapped field data:            
            mappedFieldDataWriter.WriteContentTo(peStream);

            // TODO: zero out all bytes:
            int alignedPosition = textSection.PointerToRawData + textSection.SizeOfRawData;
            if (peStream.Position != alignedPosition)
            {
                peStream.Position = alignedPosition - 1;
                peStream.WriteByte(0);
            }
        }
コード例 #23
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
 private int ComputeSizeOfTextSection(MetadataSizes metadataSizes)
 {
     Debug.Assert(metadataSizes.MappedFieldDataSize % MetadataWriter.MappedFieldDataAlignment == 0);
     return CalculateOffsetToMappedFieldDataStream(metadataSizes) + metadataSizes.MappedFieldDataSize;
 }
コード例 #24
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private List<SectionHeader> CreateSectionHeaders(MetadataSizes metadataSizes, int sectionCount)
        {
            var sectionHeaders = new List<SectionHeader>();
            SectionHeader lastSection;
            int sizeOfPeHeaders = ComputeSizeOfPeHeaders(sectionCount);
            int sizeOfTextSection = ComputeSizeOfTextSection(metadataSizes);

            sectionHeaders.Add(lastSection = 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(lastSection.RelativeVirtualAddress + lastSection.VirtualSize, _properties.SectionAlignment);
            int sizeOfWin32Resources = this.ComputeSizeOfWin32Resources(resourcesRva);

            if (sizeOfWin32Resources > 0)
            {
                sectionHeaders.Add(lastSection = new SectionHeader(
                    characteristics: SectionCharacteristics.MemRead |
                                     SectionCharacteristics.ContainsInitializedData,
                    name: ResourceSectionName,
                    numberOfLinenumbers: 0,
                    numberOfRelocations: 0,
                    pointerToLinenumbers: 0,
                    pointerToRawData: lastSection.PointerToRawData + lastSection.SizeOfRawData,
                    pointerToRelocations: 0,
                    relativeVirtualAddress: resourcesRva,
                    sizeOfRawData: BitArithmeticUtilities.Align(sizeOfWin32Resources, _properties.FileAlignment),
                    virtualSize: sizeOfWin32Resources
                ));
            }

            if (_properties.RequiresStartupStub)
            {
                var size = (_properties.Requires64bits && !_properties.RequiresAmdInstructionSet) ? 14 : 12; // TODO: constants

                sectionHeaders.Add(lastSection = new SectionHeader(
                    characteristics: SectionCharacteristics.MemRead |
                                     SectionCharacteristics.MemDiscardable |
                                     SectionCharacteristics.ContainsInitializedData,
                    name: RelocationSectionName,
                    numberOfLinenumbers: 0,
                    numberOfRelocations: 0,
                    pointerToLinenumbers: 0,
                    pointerToRawData: lastSection.PointerToRawData + lastSection.SizeOfRawData,
                    pointerToRelocations: 0,
                    relativeVirtualAddress: BitArithmeticUtilities.Align(lastSection.RelativeVirtualAddress + lastSection.VirtualSize, _properties.SectionAlignment),
                    sizeOfRawData: BitArithmeticUtilities.Align(size, _properties.FileAlignment),
                    virtualSize: size));
            }

            Debug.Assert(sectionHeaders.Count == sectionCount);
            return sectionHeaders;
        }
コード例 #25
0
ファイル: PeWriter.cs プロジェクト: dalestone/roslyn
        private void FillInTextSectionHeader(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
                );
            }
        }
コード例 #26
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
 private int CalculateMappedFieldDataStreamRva(int textSectionRva, MetadataSizes metadataSizes)
 {
     return textSectionRva + CalculateOffsetToMappedFieldDataStream(metadataSizes);
 }
コード例 #27
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private void WriteTextSection(
            Stream peStream,
            CorHeader corHeader,
            BlobWriter metadataWriter,
            BlobWriter ilStream,
            BlobWriter mappedFieldDataWriter,
            BlobWriter managedResourceWriter,
            MetadataSizes metadataSizes,
            ContentId pdbContentId,
            out long metadataPosition)
        {
            peStream.Position = _textSection.PointerToRawData;
            if (_emitRuntimeStartupStub)
            {
                this.WriteImportAddressTable(peStream);
            }

            WriteCorHeader(peStream, corHeader);
            WriteIL(peStream, ilStream);

            metadataPosition = peStream.Position;
            WriteMetadata(peStream, metadataWriter);

            WriteManagedResources(peStream, managedResourceWriter);
            WriteSpaceForHash(peStream, (int)corHeader.StrongNameSignature.Size);
            WriteDebugTable(peStream, pdbContentId, metadataSizes);

            if (_emitRuntimeStartupStub)
            {
                WriteImportTable(peStream);
                WriteNameTable(peStream);
                WriteRuntimeStartupStub(peStream);
            }

            WriteMappedFieldData(peStream, mappedFieldDataWriter);
        }
コード例 #28
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
 private int ComputeOffsetToImportTable(MetadataSizes metadataSizes)
 {
     return
         ComputeOffsetToDebugTable(metadataSizes) +
         ComputeSizeOfDebugDirectory();
 }
コード例 #29
0
ファイル: PeWriter.cs プロジェクト: fernando-rodriguez/roslyn
        private void WriteDebugTable(Stream peStream, ContentId nativePdbContentId, MetadataSizes metadataSizes)
        {
            if (!EmitPdb)
            {
                return;
            }

            var writer = new BlobWriter();

            // characteristics:
            writer.WriteUint(0);

            // PDB stamp
            writer.WriteBytes(nativePdbContentId.Stamp);

            // version
            writer.WriteUint(0);

            // type: 
            const int ImageDebugTypeCodeView = 2;
            writer.WriteUint(ImageDebugTypeCodeView);

            // size of data:
            writer.WriteUint((uint)ComputeSizeOfDebugDirectoryData());

            uint dataOffset = (uint)ComputeOffsetToDebugTable(metadataSizes) + ImageDebugDirectoryBaseSize;

            // PointerToRawData (RVA of the data):
            writer.WriteUint(_textSection.RelativeVirtualAddress + dataOffset);

            // AddressOfRawData (position of the data in the PE stream):
            writer.WriteUint(_textSection.PointerToRawData + dataOffset);

            writer.WriteByte((byte)'R');
            writer.WriteByte((byte)'S');
            writer.WriteByte((byte)'D');
            writer.WriteByte((byte)'S');

            // PDB id:
            writer.WriteBytes(nativePdbContentId.Guid);

            // age
            writer.WriteUint(PdbWriter.Age);

            // UTF-8 encoded zero-terminated path to PDB
            writer.WriteUTF8(_pdbPathOpt);
            writer.WriteByte(0);

            writer.WriteTo(peStream);
            writer.Free();
        }
コード例 #30
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private CorHeader CreateCorHeader(MetadataSizes metadataSizes, int textSectionRva, int entryPointToken)
        {
            int metadataRva = textSectionRva + ComputeOffsetToMetadata(metadataSizes.ILStreamSize);
            int resourcesRva = metadataRva + metadataSizes.MetadataSize;
            int signatureRva = resourcesRva + metadataSizes.ResourceDataSize;

            return new CorHeader(
                entryPointTokenOrRelativeVirtualAddress: entryPointToken,
                flags: _properties.GetCorHeaderFlags(),
                metadataDirectory: new DirectoryEntry(metadataRva, metadataSizes.MetadataSize),
                resourcesDirectory: new DirectoryEntry(resourcesRva, metadataSizes.ResourceDataSize),
                strongNameSignatureDirectory: new DirectoryEntry(signatureRva, metadataSizes.StrongNameSignatureSize));
        }
コード例 #31
0
ファイル: PeWriter.cs プロジェクト: dalestone/roslyn
        private void FillInNtHeader(MetadataSizes metadataSizes, int mappedFieldDataStreamRva)
        {
            // In the PE File Header this is a "Time/Date Stamp" whose description is "Time and date
            // the file was created in seconds since January 1st 1970 00:00:00 or 0"
            // However, when we want to make it deterministic we fill it in (later) with bits from the hash of the full PE file.
            int timeStamp = _deterministic ? 0 : (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

            int textSectionRva = _textSection.RelativeVirtualAddress;
            
            _coffHeader = new CoffHeader(
                machine: (_properties.Machine == 0) ? Machine.I386 : _properties.Machine,
                numberOfSections: GetSectionCount(),
                timeDateStamp: timeStamp,
                pointerToSymbolTable: 0,
                numberOfSymbols: 0,
                sizeOfOptionalHeader: (short)(_is32bit ? 224 : 240), // TODO: constants
                characteristics: _properties.ImageCharacteristics);

            var ntHeader = _ntHeader = new NtHeader();
            ntHeader.Magic = _is32bit ? PEMagic.PE32 : PEMagic.PE32Plus;
            ntHeader.MajorLinkerVersion = _properties.LinkerMajorVersion;
            ntHeader.MinorLinkerVersion = _properties.LinkerMinorVersion;
            ntHeader.AddressOfEntryPoint = _properties.RequiresStartupStub ? mappedFieldDataStreamRva - (_is32bit ? 6 : 10) : 0; // TODO: constants
            ntHeader.BaseOfCode = textSectionRva;
            ntHeader.BaseOfData = _rdataSection.RelativeVirtualAddress;
            ntHeader.ImageBase = _properties.BaseAddress;
            ntHeader.FileAlignment = _properties.FileAlignment;
            ntHeader.MajorSubsystemVersion = _properties.MajorSubsystemVersion;
            ntHeader.MinorSubsystemVersion = _properties.MinorSubsystemVersion;

            ntHeader.Subsystem = _properties.Subsystem;
            ntHeader.DllCharacteristics = _properties.DllCharacteristics;

            ntHeader.SizeOfStackReserve = _properties.SizeOfStackReserve;
            ntHeader.SizeOfStackCommit = _properties.SizeOfStackCommit;
            ntHeader.SizeOfHeapReserve = _properties.SizeOfHeapReserve; 
            ntHeader.SizeOfHeapCommit = _properties.SizeOfHeapCommit;

            ntHeader.SizeOfCode = _textSection.SizeOfRawData;
            ntHeader.SizeOfInitializedData = _rdataSection.SizeOfRawData + _coverSection.SizeOfRawData + _sdataSection.SizeOfRawData + _tlsSection.SizeOfRawData + _resourceSection.SizeOfRawData + _relocSection.SizeOfRawData;
            ntHeader.SizeOfHeaders = BitArithmeticUtilities.Align(ComputeSizeOfPeHeaders(), _properties.FileAlignment);
            ntHeader.SizeOfImage = BitArithmeticUtilities.Align(_relocSection.RelativeVirtualAddress + _relocSection.VirtualSize, 0x2000);
            ntHeader.SizeOfUninitializedData = 0;

            ntHeader.ImportAddressTable = new DirectoryEntry(
                (_properties.RequiresStartupStub) ? textSectionRva : 0,
                _sizeOfImportAddressTable);

            ntHeader.CliHeaderTable = new DirectoryEntry(
                textSectionRva + _sizeOfImportAddressTable,
                size: 72); // TODO: constants

            if (_properties.RequiresStartupStub)
            {
                ntHeader.ImportTable = new DirectoryEntry(
                    textSectionRva + ComputeOffsetToImportTable(metadataSizes),
                    (_is32bit ? 66 : 70) + 13); // TODO: constants
            }

            ntHeader.BaseRelocationTable = new DirectoryEntry(
                (_properties.RequiresStartupStub) ? _relocSection.RelativeVirtualAddress : 0,
                _relocSection.VirtualSize);

            if (EmitPdb)
            {
                // Only the size of the fixed part of the debug table goes here.
                ntHeader.DebugTable = new DirectoryEntry(
                    _textSection.RelativeVirtualAddress + ComputeOffsetToDebugTable(metadataSizes),
                    ImageDebugDirectoryBaseSize);
            }

            if (_resourceSection.SizeOfRawData > 0)
            {
                ntHeader.ResourceTable = new DirectoryEntry(
                    _resourceSection.RelativeVirtualAddress,
                    _resourceSection.VirtualSize);
            }

            if (_tlsSection.SizeOfRawData > 0)
            {
                ntHeader.ThreadLocalStorageTable = new DirectoryEntry(
                   _tlsSection.RelativeVirtualAddress,
                   _tlsSection.SizeOfRawData);
            }
        }