[llvm-objcopy] Add objcopy:🧝:Object::allocSections to simplify loops on SHF_ALLOC sections
Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D67142 llvm-svn: 370860
This commit is contained in:
parent
9bae231558
commit
fe2da4e5ed
@ -2101,23 +2101,19 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error BinaryWriter::write() {
|
Error BinaryWriter::write() {
|
||||||
for (const SectionBase &Sec : Obj.sections())
|
for (const SectionBase &Sec : Obj.allocSections())
|
||||||
if (Sec.Flags & SHF_ALLOC)
|
Sec.accept(*SecWriter);
|
||||||
Sec.accept(*SecWriter);
|
|
||||||
return Buf.commit();
|
return Buf.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error BinaryWriter::finalize() {
|
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
|
// 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
|
// 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
|
// 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.
|
// that will affect layout of allocated sections so we only add those.
|
||||||
std::vector<Segment *> OrderedSegments;
|
std::vector<Segment *> OrderedSegments;
|
||||||
for (const SectionBase &Sec : Obj.sections())
|
for (const SectionBase &Sec : Obj.allocSections())
|
||||||
if ((Sec.Flags & SHF_ALLOC) != 0 && Sec.ParentSegment != nullptr)
|
if (Sec.ParentSegment != nullptr)
|
||||||
OrderedSegments.push_back(Sec.ParentSegment);
|
OrderedSegments.push_back(Sec.ParentSegment);
|
||||||
|
|
||||||
// For binary output, we're going to use physical addresses instead of
|
// For binary output, we're going to use physical addresses instead of
|
||||||
@ -2161,24 +2157,16 @@ Error BinaryWriter::finalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: generalize layoutSections to take a range. Pass a special range
|
layoutSections(Obj.allocSections(), Offset);
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Now that every section has been laid out we just need to compute the total
|
// 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
|
// 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
|
// layoutSections, because we want to truncate the last segment to the end of
|
||||||
// its last section, to match GNU objcopy's behaviour.
|
// its last section, to match GNU objcopy's behaviour.
|
||||||
TotalSize = 0;
|
TotalSize = 0;
|
||||||
for (SectionBase *Sec : AllocatedSections)
|
for (const SectionBase &Sec : Obj.allocSections())
|
||||||
if (Sec->Type != SHT_NOBITS)
|
if (Sec.Type != SHT_NOBITS)
|
||||||
TotalSize = std::max(TotalSize, Sec->Offset + Sec->Size);
|
TotalSize = std::max(TotalSize, Sec.Offset + Sec.Size);
|
||||||
|
|
||||||
if (Error E = Buf.allocate(TotalSize))
|
if (Error E = Buf.allocate(TotalSize))
|
||||||
return E;
|
return E;
|
||||||
|
@ -57,8 +57,8 @@ public:
|
|||||||
: Sections(Secs) {}
|
: Sections(Secs) {}
|
||||||
SectionTableRef(const SectionTableRef &) = default;
|
SectionTableRef(const SectionTableRef &) = default;
|
||||||
|
|
||||||
iterator begin() { return iterator(Sections.data()); }
|
iterator begin() const { return iterator(Sections.data()); }
|
||||||
iterator end() { return iterator(Sections.data() + Sections.size()); }
|
iterator end() const { return iterator(Sections.data() + Sections.size()); }
|
||||||
size_t size() const { return Sections.size(); }
|
size_t size() const { return Sections.size(); }
|
||||||
|
|
||||||
SectionBase *getSection(uint32_t Index, Twine ErrMsg);
|
SectionBase *getSection(uint32_t Index, Twine ErrMsg);
|
||||||
@ -994,6 +994,10 @@ private:
|
|||||||
std::vector<SegPtr> Segments;
|
std::vector<SegPtr> Segments;
|
||||||
std::vector<SecPtr> RemovedSections;
|
std::vector<SecPtr> RemovedSections;
|
||||||
|
|
||||||
|
static bool sectionIsAlloc(const SectionBase &Sec) {
|
||||||
|
return Sec.Flags & ELF::SHF_ALLOC;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <class T>
|
template <class T>
|
||||||
using Range = iterator_range<
|
using Range = iterator_range<
|
||||||
@ -1032,6 +1036,13 @@ public:
|
|||||||
ConstRange<SectionBase> sections() const {
|
ConstRange<SectionBase> sections() const {
|
||||||
return make_pointee_range(Sections);
|
return make_pointee_range(Sections);
|
||||||
}
|
}
|
||||||
|
iterator_range<
|
||||||
|
filter_iterator<pointee_iterator<std::vector<SecPtr>::const_iterator>,
|
||||||
|
decltype(§ionIsAlloc)>>
|
||||||
|
allocSections() const {
|
||||||
|
return make_filter_range(make_pointee_range(Sections), sectionIsAlloc);
|
||||||
|
}
|
||||||
|
|
||||||
SectionBase *findSection(StringRef Name) {
|
SectionBase *findSection(StringRef Name) {
|
||||||
auto SecIt =
|
auto SecIt =
|
||||||
find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
|
find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user