/// <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="machine">Target machine architecture</param> /// <param name="peReader">Input MSIL PE file reader</param> /// <param name="sectionNames">Custom section names to add to the output PE</param> /// <param name="sectionSerializer">Callback for emission of data for the individual sections</param> public R2RPEBuilder( Machine machine, PEReader peReader, IEnumerable <SectionInfo> sectionNames = null, Func <string, SectionLocation, int, BlobBuilder> sectionSerializer = null, Action <PEDirectoriesBuilder> directoriesUpdater = null) : base(PEHeaderCopier.Copy(peReader.PEHeaders, machine), deterministicIdProvider: null) { _peReader = peReader; _sectionSerializer = sectionSerializer; _directoriesUpdater = directoriesUpdater; _customSections = new HashSet <string>(sectionNames.Select((sn) => sn.SectionName)); _sectionRvaDeltas = new List <SectionRVADelta>(); ImmutableArray <Section> .Builder sectionListBuilder = ImmutableArray.CreateBuilder <Section>(); int textSectionIndex = -1; int sdataSectionIndex = -1; int rsrcSectionIndex = -1; int relocSectionIndex = -1; for (int sectionIndex = 0; sectionIndex < peReader.PEHeaders.SectionHeaders.Length; sectionIndex++) { switch (peReader.PEHeaders.SectionHeaders[sectionIndex].Name) { case TextSectionName: textSectionIndex = sectionIndex; break; case SDataSectionName: sdataSectionIndex = sectionIndex; break; case RsrcSectionName: rsrcSectionIndex = sectionIndex; break; case RelocSectionName: relocSectionIndex = sectionIndex; break; } } if (textSectionIndex >= 0 && !sectionNames.Any((sc) => sc.SectionName == TextSectionName)) { SectionHeader sectionHeader = peReader.PEHeaders.SectionHeaders[textSectionIndex]; sectionListBuilder.Add(new Section(sectionHeader.Name, sectionHeader.SectionCharacteristics)); } if (sectionNames != null) { foreach (SectionInfo sectionInfo in sectionNames) { sectionListBuilder.Add(new Section(sectionInfo.SectionName, sectionInfo.Characteristics)); } } if (sdataSectionIndex >= 0 && !sectionNames.Any((sc) => sc.SectionName == SDataSectionName)) { SectionHeader sectionHeader = peReader.PEHeaders.SectionHeaders[sdataSectionIndex]; sectionListBuilder.Add(new Section(sectionHeader.Name, sectionHeader.SectionCharacteristics)); } if (rsrcSectionIndex >= 0 && !sectionNames.Any((sc) => sc.SectionName == RsrcSectionName)) { SectionHeader sectionHeader = peReader.PEHeaders.SectionHeaders[rsrcSectionIndex]; sectionListBuilder.Add(new Section(sectionHeader.Name, sectionHeader.SectionCharacteristics)); } if (relocSectionIndex >= 0) { SectionHeader sectionHeader = peReader.PEHeaders.SectionHeaders[relocSectionIndex]; sectionListBuilder.Add(new Section(sectionHeader.Name, sectionHeader.SectionCharacteristics)); } else { // Always inject the relocation section to the end of section list sectionListBuilder.Add(new Section(RelocSectionName, SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemRead | SectionCharacteristics.MemDiscardable)); } _sections = sectionListBuilder.ToImmutable(); }