Index: tools/llvm-objcopy/ELF/Object.h =================================================================== --- tools/llvm-objcopy/ELF/Object.h +++ tools/llvm-objcopy/ELF/Object.h @@ -57,8 +57,8 @@ : Sections(Secs) {} SectionTableRef(const SectionTableRef &) = default; - iterator begin() { return iterator(Sections.data()); } - iterator end() { return iterator(Sections.data() + Sections.size()); } + iterator begin() const { return iterator(Sections.data()); } + iterator end() const { return iterator(Sections.data() + Sections.size()); } size_t size() const { return Sections.size(); } SectionBase *getSection(uint32_t Index, Twine ErrMsg); @@ -994,6 +994,10 @@ std::vector Segments; std::vector RemovedSections; + static bool sectionIsAlloc(const SectionBase &Sec) { + return Sec.Flags & ELF::SHF_ALLOC; + }; + public: template using Range = iterator_range< @@ -1032,6 +1036,13 @@ ConstRange sections() const { return make_pointee_range(Sections); } + iterator_range< + filter_iterator::const_iterator>, + decltype(§ionIsAlloc)>> + allocSections() const { + return make_filter_range(make_pointee_range(Sections), sectionIsAlloc); + } + SectionBase *findSection(StringRef Name) { auto SecIt = find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; }); Index: tools/llvm-objcopy/ELF/Object.cpp =================================================================== --- tools/llvm-objcopy/ELF/Object.cpp +++ tools/llvm-objcopy/ELF/Object.cpp @@ -2107,24 +2107,20 @@ } Error BinaryWriter::write() { - for (auto &Section : Obj.sections()) - if (Section.Flags & SHF_ALLOC) - Section.accept(*SecWriter); + for (const SectionBase &Sec : Obj.allocSections()) + Sec.accept(*SecWriter); return Buf.commit(); } Error BinaryWriter::finalize() { - // TODO: Create a filter range to construct OrderedSegments from so that this - // code can be deduped with assignOffsets above. This should also solve the - // todo below for LayoutSections. // We need a temporary list of segments that has a special order to it // so that we know that anytime ->ParentSegment is set that segment has // already had it's offset properly set. We only want to consider the segments // that will affect layout of allocated sections so we only add those. std::vector OrderedSegments; - for (SectionBase &Section : Obj.sections()) - if ((Section.Flags & SHF_ALLOC) != 0 && Section.ParentSegment != nullptr) - OrderedSegments.push_back(Section.ParentSegment); + for (const SectionBase &Sec : Obj.allocSections()) + if (Sec.ParentSegment != nullptr) + OrderedSegments.push_back(Sec.ParentSegment); // For binary output, we're going to use physical addresses instead of // virtual addresses, since a binary output is used for cases like ROM @@ -2167,24 +2163,16 @@ } } - // TODO: generalize layoutSections to take a range. Pass a special range - // constructed from an iterator that skips values for which a predicate does - // not hold. Then pass such a range to layoutSections instead of constructing - // AllocatedSections here. - std::vector AllocatedSections; - for (SectionBase &Section : Obj.sections()) - if (Section.Flags & SHF_ALLOC) - AllocatedSections.push_back(&Section); - layoutSections(make_pointee_range(AllocatedSections), Offset); + layoutSections(Obj.allocSections(), Offset); // Now that every section has been laid out we just need to compute the total // file size. This might not be the same as the offset returned by // layoutSections, because we want to truncate the last segment to the end of // its last section, to match GNU objcopy's behaviour. TotalSize = 0; - for (SectionBase *Section : AllocatedSections) - if (Section->Type != SHT_NOBITS) - TotalSize = std::max(TotalSize, Section->Offset + Section->Size); + for (const SectionBase &Sec : Obj.allocSections()) + if (Sec.Type != SHT_NOBITS) + TotalSize = std::max(TotalSize, Sec.Offset + Sec.Size); if (Error E = Buf.allocate(TotalSize)) return E;