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 namespace llvm { namespace object { @@ -78,6 +79,28 @@ return Ref; } +template +static bool sectionWithinSegment(const Elf_Shdr_Impl &Sec, + const Elf_Phdr_Impl &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 struct MutableELFSection { Elf_Shdr_Impl Header; std::string Name; @@ -95,10 +118,42 @@ } }; +template class MutableELFSegment { + std::set Sections; + +public: + Elf_Phdr_Impl Header; + ArrayRef Contents; + + MutableELFSegment(uint64_t ToCopy, const MutableELFObject *ObjFile) { + const Elf_Ehdr_Impl &EHeader = + *reinterpret_cast *>(ObjFile->base()); + assert(ToCopy < EHeader.e_phnum && "Copying segment that doesn't exist"); + Header = reinterpret_cast *>( + ObjFile->base() + EHeader.e_phoff)[ToCopy]; + Contents = ArrayRef( + reinterpret_cast(ObjFile->base() + Header.p_offset), + Header.p_filesz); + + ArrayRef> SecHeaders( + reinterpret_cast *>(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 class MutableELFObject : public ELFObjectFile { friend struct MutableELFSection; + friend class MutableELFSegment; MutableRange> Sections; + std::vector> Segments; protected: using MappingType = @@ -132,7 +187,12 @@ MutableELFObject(ELFObjectFile &B) : ELFObjectFile(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 *Header = + reinterpret_cast *>(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));