From 2d98fead250894f0c3304450999dc1a1db0ebccb Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 22 Nov 2016 01:31:32 +0000 Subject: [PATCH] Convert BuildId a derived class of SyntheticSection. Some synthetic sections are not derived calsses of SyntehticSection. They are derived directly from InputSection. For consistencly, we should use SyntheticSection. llvm-svn: 287606 --- lld/ELF/SyntheticSections.cpp | 64 ++++++++++++++++++++----------------------- lld/ELF/SyntheticSections.h | 44 ++++++++++++++--------------- 2 files changed, 50 insertions(+), 58 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 75821d5..8378aef6 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -244,28 +244,7 @@ template InputSection *elf::createInterpSection() { return Ret; } -template -BuildIdSection::BuildIdSection() - : InputSection(SHF_ALLOC, SHT_NOTE, 1, ArrayRef(), - ".note.gnu.build-id"), - HashSize(getHashSize()) { - this->Live = true; - - Buf.resize(HeaderSize + HashSize); - 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); -} - -// Returns the location of the build-id hash value in the output. -template size_t BuildIdSection::getOutputOffset() { - return this->OutSec->Offset + this->OutSecOff + HeaderSize; -} - -template size_t BuildIdSection::getHashSize() { +static size_t getHashSize() { switch (Config->BuildId) { case BuildIdKind::Fast: return 8; @@ -281,6 +260,22 @@ template size_t BuildIdSection::getHashSize() { } } +template +BuildIdSection::BuildIdSection() + : SyntheticSection(SHF_ALLOC, SHT_NOTE, 1, ".note.gnu.build-id"), + HashSize(getHashSize()) { + this->Live = true; +} + +template void BuildIdSection::writeTo(uint8_t *Buf) { + const endianness E = ELFT::TargetEndianness; + 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 + HashBuf = Buf + 16; +} + // Split one uint8 array into small pieces of uint8 arrays. static std::vector> split(ArrayRef Arr, size_t ChunkSize) { @@ -300,34 +295,36 @@ static std::vector> split(ArrayRef Arr, // of the hash values. template void BuildIdSection::computeHash( - llvm::MutableArrayRef Data, - std::function Arr, uint8_t *Dest)> HashFn) { + llvm::ArrayRef Data, + std::function Arr)> HashFn) { std::vector> Chunks = split(Data, 1024 * 1024); - std::vector HashList(Chunks.size() * HashSize); + std::vector Hashes(Chunks.size() * HashSize); auto Fn = [&](ArrayRef &Chunk) { size_t Idx = &Chunk - Chunks.data(); - HashFn(Chunk, HashList.data() + Idx * HashSize); + HashFn(Hashes.data() + Idx * HashSize, Chunk); }; + // Compute hash values. if (Config->Threads) parallel_for_each(Chunks.begin(), Chunks.end(), Fn); else std::for_each(Chunks.begin(), Chunks.end(), Fn); - HashFn(HashList, Data.data() + getOutputOffset()); + // Write to the final output buffer. + HashFn(HashBuf, Hashes); } template -void BuildIdSection::writeBuildId(MutableArrayRef Buf) { +void BuildIdSection::writeBuildId(ArrayRef Buf) { switch (Config->BuildId) { case BuildIdKind::Fast: - computeHash(Buf, [](ArrayRef Arr, uint8_t *Dest) { + computeHash(Buf, [](uint8_t *Dest, ArrayRef Arr) { write64le(Dest, xxHash64(toStringRef(Arr))); }); break; case BuildIdKind::Md5: - computeHash(Buf, [](ArrayRef Arr, uint8_t *Dest) { + computeHash(Buf, [](uint8_t *Dest, ArrayRef Arr) { MD5 Hash; Hash.update(Arr); MD5::MD5Result Res; @@ -336,19 +333,18 @@ void BuildIdSection::writeBuildId(MutableArrayRef Buf) { }); break; case BuildIdKind::Sha1: - computeHash(Buf, [](ArrayRef Arr, uint8_t *Dest) { + computeHash(Buf, [](uint8_t *Dest, ArrayRef Arr) { SHA1 Hash; Hash.update(Arr); memcpy(Dest, Hash.final().data(), 20); }); break; case BuildIdKind::Uuid: - if (getRandomBytes(Buf.data() + getOutputOffset(), HashSize)) + if (getRandomBytes(HashBuf, HashSize)) error("entropy source failure"); break; case BuildIdKind::Hexstring: - memcpy(Buf.data() + getOutputOffset(), Config->BuildIdVector.data(), - Config->BuildIdVector.size()); + memcpy(HashBuf, Config->BuildIdVector.data(), Config->BuildIdVector.size()); break; default: llvm_unreachable("unknown BuildIdKind"); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 60f8811..76b3da6 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -71,6 +71,7 @@ public: this->Live = true; } + virtual ~SyntheticSection() = default; virtual void writeTo(uint8_t *Buf) = 0; virtual size_t getSize() const { return this->Data.size(); } virtual void finalize() {} @@ -81,30 +82,6 @@ public: static bool classof(const InputSectionData *D) { return D->kind() == InputSectionData::Synthetic; } - -protected: - ~SyntheticSection() = default; -}; - -// .note.gnu.build-id section. -template class BuildIdSection : public InputSection { -public: - BuildIdSection(); - void writeBuildId(llvm::MutableArrayRef Buf); - -private: - // First 16 bytes are a header. - static const unsigned HeaderSize = 16; - - size_t getHashSize(); - size_t getOutputOffset(); - - void - computeHash(llvm::MutableArrayRef Buf, - std::function Arr, uint8_t *Hash)> Hash); - - std::vector Buf; - size_t HashSize; }; template class GotSection final : public SyntheticSection { @@ -135,6 +112,25 @@ private: uintX_t Size = 0; }; +// .note.gnu.build-id section. +template class BuildIdSection : public SyntheticSection { + // First 16 bytes are a header. + static const unsigned HeaderSize = 16; + +public: + BuildIdSection(); + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return HeaderSize + HashSize; } + void writeBuildId(llvm::ArrayRef Buf); + +private: + void computeHash(llvm::ArrayRef Buf, + std::function)> Hash); + + size_t HashSize; + uint8_t *HashBuf; +}; + template class MipsGotSection final : public SyntheticSection { typedef typename ELFT::uint uintX_t; -- 2.7.4