예제 #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
 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
 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
        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
        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
        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
        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
        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
        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
 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
 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
        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
        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
        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
        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);
            }
        }