Exemple #1
0
        /// <summary>
        /// Constructor initializes the various control structures and combines the section list.
        /// </summary>
        /// <param name="target">Target environment specifier</param>
        /// <param name="peReader">Input MSIL PE file reader</param>
        /// <param name="sectionStartNodeLookup">Callback to locate section start node for a given section name</param>
        /// <param name="getRuntimeFunctionsTable">Callback to retrieve the runtime functions table</param>
        public R2RPEBuilder(
            TargetDetails target,
            PEReader peReader,
            Func <string, ISymbolNode> sectionStartNodeLookup,
            Func <RuntimeFunctionsTableNode> getRuntimeFunctionsTable)
            : base(PEHeaderCopier.Copy(peReader.PEHeaders, target), deterministicIdProvider: null)
        {
            _target   = target;
            _peReader = peReader;
            _getRuntimeFunctionsTable = getRuntimeFunctionsTable;
            _sectionRvaDeltas         = new List <SectionRVADelta>();

            _sectionBuilder = new SectionBuilder(target);
            _sectionBuilder.SetSectionStartNodeLookup(sectionStartNodeLookup);

            _textSectionIndex  = _sectionBuilder.AddSection(R2RPEBuilder.TextSectionName, SectionCharacteristics.ContainsCode | SectionCharacteristics.MemExecute | SectionCharacteristics.MemRead, 512);
            _rdataSectionIndex = _sectionBuilder.AddSection(".rdata", SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemRead, 512);
            _dataSectionIndex  = _sectionBuilder.AddSection(".data", SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemWrite | SectionCharacteristics.MemRead, 512);

            _customSections = new HashSet <string>();
            foreach (SectionInfo section in _sectionBuilder.GetSections())
            {
                _customSections.Add(section.SectionName);
            }

            foreach (SectionHeader sectionHeader in peReader.PEHeaders.SectionHeaders)
            {
                if (_sectionBuilder.FindSection(sectionHeader.Name) == null)
                {
                    _sectionBuilder.AddSection(sectionHeader.Name, sectionHeader.SectionCharacteristics, peReader.PEHeaders.PEHeader.SectionAlignment);
                }
            }

            if (_sectionBuilder.FindSection(R2RPEBuilder.RelocSectionName) == null)
            {
                // Always inject the relocation section to the end of section list
                _sectionBuilder.AddSection(
                    R2RPEBuilder.RelocSectionName,
                    SectionCharacteristics.ContainsInitializedData |
                    SectionCharacteristics.MemRead |
                    SectionCharacteristics.MemDiscardable,
                    peReader.PEHeaders.PEHeader.SectionAlignment);
            }

            ImmutableArray <Section> .Builder sectionListBuilder = ImmutableArray.CreateBuilder <Section>();
            foreach (SectionInfo sectionInfo in _sectionBuilder.GetSections())
            {
                ILCompiler.PEWriter.Section builderSection = _sectionBuilder.FindSection(sectionInfo.SectionName);
                Debug.Assert(builderSection != null);
                sectionListBuilder.Add(new Section(builderSection.Name, builderSection.Characteristics));
            }

            _sections        = sectionListBuilder.ToImmutableArray();
            _sectionRVAs     = new int[_sections.Length];
            _sectionRawSizes = new int[_sections.Length];
        }
        /// <summary>
        /// Constructor initializes the various control structures and combines the section list.
        /// </summary>
        /// <param name="target">Target environment specifier</param>
        /// <param name="peHeaderBuilder">PE file header builder</param>
        /// <param name="getRuntimeFunctionsTable">Callback to retrieve the runtime functions table</param>
        public R2RPEBuilder(
            TargetDetails target,
            PEHeaderBuilder peHeaderBuilder,
            ISymbolNode r2rHeaderExportSymbol,
            string outputFileSimpleName,
            Func <RuntimeFunctionsTableNode> getRuntimeFunctionsTable,
            int customPESectionAlignment,
            Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider)
            : base(peHeaderBuilder, deterministicIdProvider: deterministicIdProvider)
        {
            _target = target;
            _getRuntimeFunctionsTable = getRuntimeFunctionsTable;
            _sectionRvaDeltas         = new List <SectionRVADelta>();

            _sectionBuilder = new SectionBuilder(target);

            _textSectionIndex = _sectionBuilder.AddSection(TextSectionName, SectionCharacteristics.ContainsCode | SectionCharacteristics.MemExecute | SectionCharacteristics.MemRead, 512);
            _dataSectionIndex = _sectionBuilder.AddSection(DataSectionName, SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemWrite | SectionCharacteristics.MemRead, 512);

            _customPESectionAlignment = customPESectionAlignment;

            if (r2rHeaderExportSymbol != null)
            {
                _sectionBuilder.AddSection(R2RPEBuilder.ExportDataSectionName, SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemRead, 512);
                _sectionBuilder.AddExportSymbol("RTR_HEADER", 1, r2rHeaderExportSymbol);
                _sectionBuilder.SetDllNameForExportDirectoryTable(outputFileSimpleName);
            }

            if (_sectionBuilder.FindSection(R2RPEBuilder.RelocSectionName) == null)
            {
                // Always inject the relocation section to the end of section list
                _sectionBuilder.AddSection(
                    R2RPEBuilder.RelocSectionName,
                    SectionCharacteristics.ContainsInitializedData |
                    SectionCharacteristics.MemRead |
                    SectionCharacteristics.MemDiscardable,
                    PEHeaderConstants.SectionAlignment);
            }

            ImmutableArray <Section> .Builder sectionListBuilder = ImmutableArray.CreateBuilder <Section>();
            foreach (SectionInfo sectionInfo in _sectionBuilder.GetSections())
            {
                ILCompiler.PEWriter.Section builderSection = _sectionBuilder.FindSection(sectionInfo.SectionName);
                Debug.Assert(builderSection != null);
                sectionListBuilder.Add(new Section(builderSection.Name, builderSection.Characteristics));
            }

            _sections                = sectionListBuilder.ToImmutableArray();
            _sectionRVAs             = new int[_sections.Length];
            _sectionPointerToRawData = new int[_sections.Length];
            _sectionRawSizes         = new int[_sections.Length];
        }
Exemple #3
0
        /// <summary>
        /// Emit built sections using the R2R PE writer.
        /// </summary>
        /// <param name="builder">Section builder to emit</param>
        /// <param name="machine">Target machine architecture</param>
        /// <param name="inputReader">Input MSIL reader</param>
        /// <param name="outputStream">Output stream for the final R2R PE file</param>
        public static void EmitR2R(
            this SectionBuilder builder,
            Machine machine,
            PEReader inputReader,
            Action <PEDirectoriesBuilder> directoriesUpdater,
            Stream outputStream)
        {
            R2RPEBuilder r2rBuilder = new R2RPEBuilder(
                machine: machine,
                peReader: inputReader,
                sectionNames: builder.GetSections(),
                sectionSerializer: builder.SerializeSection,
                directoriesUpdater: (PEDirectoriesBuilder directoriesBuilder) =>
            {
                builder.UpdateDirectories(directoriesBuilder);
                if (directoriesUpdater != null)
                {
                    directoriesUpdater(directoriesBuilder);
                }
            });

            BlobBuilder outputPeFile = new BlobBuilder();

            r2rBuilder.Serialize(outputPeFile);

            CorHeaderBuilder corHeader = r2rBuilder.CorHeader;

            if (corHeader != null)
            {
                corHeader.Flags = (r2rBuilder.CorHeader.Flags & ~CorFlags.ILOnly) | CorFlags.ILLibrary;

                corHeader.MetadataDirectory                = r2rBuilder.RelocateDirectoryEntry(corHeader.MetadataDirectory);
                corHeader.ResourcesDirectory               = r2rBuilder.RelocateDirectoryEntry(corHeader.ResourcesDirectory);
                corHeader.StrongNameSignatureDirectory     = r2rBuilder.RelocateDirectoryEntry(corHeader.StrongNameSignatureDirectory);
                corHeader.CodeManagerTableDirectory        = r2rBuilder.RelocateDirectoryEntry(corHeader.CodeManagerTableDirectory);
                corHeader.VtableFixupsDirectory            = r2rBuilder.RelocateDirectoryEntry(corHeader.VtableFixupsDirectory);
                corHeader.ExportAddressTableJumpsDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.ExportAddressTableJumpsDirectory);
                corHeader.ManagedNativeHeaderDirectory     = r2rBuilder.RelocateDirectoryEntry(corHeader.ManagedNativeHeaderDirectory);

                builder.UpdateCorHeader(corHeader);
            }

            builder.RelocateOutputFile(
                outputPeFile,
                inputReader.PEHeaders.PEHeader.ImageBase,
                corHeader,
                r2rBuilder.CorHeaderFileOffset,
                outputStream);

            r2rBuilder.RelocateMetadataBlob(outputStream);
        }