[PATCH] D65367: [Object] Create MutableELFObject Class for Doing Mutations on ELFObjectFiles [Part 2]
Alex Brachet via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 26 23:01:06 PDT 2019
abrachet created this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Added support for segments
https://reviews.llvm.org/D65367
Files:
llvm/include/llvm/Object/MutableELFObject.h
Index: llvm/include/llvm/Object/MutableELFObject.h
===================================================================
--- llvm/include/llvm/Object/MutableELFObject.h
+++ llvm/include/llvm/Object/MutableELFObject.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Object/ELFObjectFile.h"
+#include <set>
namespace llvm {
namespace object {
@@ -78,6 +79,28 @@
return Ref;
}
+template <typename ELFT>
+static bool sectionWithinSegment(const Elf_Shdr_Impl<ELFT> &Sec,
+ const Elf_Phdr_Impl<ELFT> &Seg) {
+ uint64_t SecSize = Sec.sh_size ? Sec.sh_size : 1;
+
+ if (Sec.sh_type == ELF::SHT_NOBITS) {
+ if (!(Sec.sh_flags & ELF::SHF_ALLOC))
+ return false;
+
+ bool SectionIsTLS = Sec.sh_flags & ELF::SHF_TLS;
+ bool SegmentIsTLS = Seg.p_type == ELF::PT_TLS;
+ if (SectionIsTLS != SegmentIsTLS)
+ return false;
+
+ return Seg.p_vaddr <= Sec.sh_addr &&
+ Seg.p_vaddr + Seg.p_memsz >= Sec.sh_addr + SecSize;
+ }
+
+ return Seg.p_offset <= Sec.sh_offset &&
+ Seg.p_offset + Seg.p_filesz >= Sec.sh_offset + SecSize;
+}
+
template <typename ELFT> struct MutableELFSection {
Elf_Shdr_Impl<ELFT> Header;
std::string Name;
@@ -95,10 +118,42 @@
}
};
+template <typename ELFT> class MutableELFSegment {
+ std::set<uint64_t> Sections;
+
+public:
+ Elf_Phdr_Impl<ELFT> Header;
+ ArrayRef<uint8_t> Contents;
+
+ MutableELFSegment(uint64_t ToCopy, const MutableELFObject<ELFT> *ObjFile) {
+ const Elf_Ehdr_Impl<ELFT> &EHeader =
+ *reinterpret_cast<const Elf_Ehdr_Impl<ELFT> *>(ObjFile->base());
+ assert(ToCopy < EHeader.e_phnum && "Copying segment that doesn't exist");
+ Header = reinterpret_cast<const Elf_Phdr_Impl<ELFT> *>(
+ ObjFile->base() + EHeader.e_phoff)[ToCopy];
+ Contents = ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(ObjFile->base() + Header.p_offset),
+ Header.p_filesz);
+
+ ArrayRef<Elf_Shdr_Impl<ELFT>> SecHeaders(
+ reinterpret_cast<const Elf_Shdr_Impl<ELFT> *>(ObjFile->base() +
+ EHeader.e_shoff),
+ EHeader.e_shnum);
+ uint64_t Index = 0;
+ for (const auto &Sec : SecHeaders) {
+ if (sectionWithinSegment(Sec, Header))
+ Sections.insert(Index);
+ ++Index;
+ }
+ }
+};
+
template <typename ELFT> class MutableELFObject : public ELFObjectFile<ELFT> {
friend struct MutableELFSection<ELFT>;
+ friend class MutableELFSegment<ELFT>;
MutableRange<MutableELFSection<ELFT>> Sections;
+ std::vector<MutableELFSegment<ELFT>> Segments;
protected:
using MappingType =
@@ -132,7 +187,12 @@
MutableELFObject(ELFObjectFile<ELFT> &B)
: ELFObjectFile<ELFT>(std::move(B)),
Sections(B.section_begin(), B.section_end(),
- [&](SectionRef Ref) { return Ref.getRawDataRefImpl().p; }) {}
+ [&](SectionRef Ref) { return Ref.getRawDataRefImpl().p; }) {
+ const Elf_Ehdr_Impl<ELFT> *Header =
+ reinterpret_cast<const Elf_Ehdr_Impl<ELFT> *>(this->base());
+ for (int I = 0; I < Header->e_phnum; ++I)
+ Segments.emplace_back(I, this);
+ }
section_iterator section_begin() const override {
return section_iterator(SectionRef(toDataRef(0), this));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65367.212046.patch
Type: text/x-patch
Size: 3290 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190727/e58340e9/attachment.bin>
More information about the llvm-commits
mailing list