Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -52,6 +52,8 @@ unsigned SectionKind : 3; public: + virtual ~InputSectionData() = default; + InputSectionData(InputSectionData &&) = default; Kind kind() const { return (Kind)SectionKind; } unsigned Live : 1; // for garbage collection @@ -66,6 +68,9 @@ return llvm::makeArrayRef((const T *)Data.data(), S / sizeof(T)); } + virtual void writeTo(uint8_t *Buf) {} + virtual size_t getSize() const { return Data.size(); } + // If a section is compressed, this has the uncompressed section data. std::unique_ptr UncompressedData; @@ -113,9 +118,6 @@ // this but instead this->Repl. InputSectionBase *Repl; - // Returns the size of this section (even if this is a common or BSS.) - size_t getSize() const; - static InputSectionBase Discarded; ObjectFile *getFile() const { return File; } @@ -243,7 +245,7 @@ // Write this section to a mmap'ed file, assuming Buf is pointing to // beginning of the output section. - void writeTo(uint8_t *Buf); + void writeTo(uint8_t *Buf) override; // Relocation sections that refer to this one. llvm::TinyPtrVector RelocSections; @@ -270,6 +272,9 @@ // Size of chunk with thunks code. uint64_t getThunksSize() const; + // Size of section in bytes. + size_t getSize() const override; + template void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef Rels); Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -79,13 +79,6 @@ this->Offset = Hdr->sh_offset; } -template size_t InputSectionBase::getSize() const { - if (auto *D = dyn_cast>(this)) - if (D->getThunksSize() > 0) - return D->getThunkOff() + D->getThunksSize(); - return Data.size(); -} - // Returns a string for an error message. template static std::string getName(SectionT *Sec) { return (Sec->getFile()->getName() + "(" + Sec->Name + ")").str(); @@ -207,6 +200,11 @@ return S->kind() == Base::Regular; } +template size_t InputSection::getSize() const { + return getThunksSize() > 0 ? getThunkOff() + getThunksSize() + : this->Data.size(); +} + template InputSectionBase *InputSection::getRelocatedSection() { assert(this->Type == SHT_RELA || this->Type == SHT_REL); Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -17,6 +17,8 @@ template class BuildIdSection : public InputSection { public: + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return 16 + HashSize; } virtual void writeBuildId(llvm::MutableArrayRef Buf) = 0; virtual ~BuildIdSection() = default; @@ -24,7 +26,7 @@ protected: BuildIdSection(size_t HashSize); - std::vector Buf; + size_t HashSize; }; template Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -39,14 +39,15 @@ template BuildIdSection::BuildIdSection(size_t HashSize) : InputSection(SHF_ALLOC, SHT_NOTE, 1, ArrayRef(), - ".note.gnu.build-id") { - Buf.resize(16 + HashSize); + ".note.gnu.build-id"), + HashSize(HashSize) {} + +template void BuildIdSection::writeTo(uint8_t *Buf) { const endianness E = ELFT::TargetEndianness; - write32(Buf.data(), 4); // Name size - write32(Buf.data() + 4, HashSize); // Content size - write32(Buf.data() + 8, NT_GNU_BUILD_ID); // Type - memcpy(Buf.data() + 12, "GNU", 4); // Name string - this->Data = ArrayRef(Buf); + write32(Buf, 4); // Name size + write32(Buf + 4, HashSize); // Content size + write32(Buf + 8, NT_GNU_BUILD_ID); // Type + memcpy(Buf + 12, "GNU", 4); // Name string } template