Skip to content

Commit

Permalink
[llvm-objcopy] Add objcopy::elf::Object::allocSections to simplify lo…
Browse files Browse the repository at this point in the history
…ops on SHF_ALLOC sections

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D67142

llvm-svn: 370860
  • Loading branch information
MaskRay committed Sep 4, 2019
1 parent 9bae231 commit fe2da4e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
28 changes: 8 additions & 20 deletions llvm/tools/llvm-objcopy/ELF/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2101,23 +2101,19 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
}

Error BinaryWriter::write() {
for (const SectionBase &Sec : Obj.sections())
if (Sec.Flags & SHF_ALLOC)
Sec.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<Segment *> OrderedSegments;
for (const SectionBase &Sec : Obj.sections())
if ((Sec.Flags & SHF_ALLOC) != 0 && Sec.ParentSegment != nullptr)
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
Expand Down Expand Up @@ -2161,24 +2157,16 @@ Error BinaryWriter::finalize() {
}
}

// 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<SectionBase *> AllocatedSections;
for (SectionBase &Sec : Obj.sections())
if (Sec.Flags & SHF_ALLOC)
AllocatedSections.push_back(&Sec);
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 *Sec : AllocatedSections)
if (Sec->Type != SHT_NOBITS)
TotalSize = std::max(TotalSize, Sec->Offset + Sec->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;
Expand Down
15 changes: 13 additions & 2 deletions llvm/tools/llvm-objcopy/ELF/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class SectionTableRef {
: 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);
Expand Down Expand Up @@ -994,6 +994,10 @@ class Object {
std::vector<SegPtr> Segments;
std::vector<SecPtr> RemovedSections;

static bool sectionIsAlloc(const SectionBase &Sec) {
return Sec.Flags & ELF::SHF_ALLOC;
};

public:
template <class T>
using Range = iterator_range<
Expand Down Expand Up @@ -1032,6 +1036,13 @@ class Object {
ConstRange<SectionBase> sections() const {
return make_pointee_range(Sections);
}
iterator_range<
filter_iterator<pointee_iterator<std::vector<SecPtr>::const_iterator>,
decltype(&sectionIsAlloc)>>
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; });
Expand Down

0 comments on commit fe2da4e

Please sign in to comment.