return Ret;
}
-template <class ELFT>
-BuildIdSection<ELFT>::BuildIdSection()
- : InputSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ArrayRef<uint8_t>(),
- ".note.gnu.build-id"),
- HashSize(getHashSize()) {
- this->Live = true;
-
- Buf.resize(HeaderSize + HashSize);
- const endianness E = ELFT::TargetEndianness;
- write32<E>(Buf.data(), 4); // Name size
- write32<E>(Buf.data() + 4, HashSize); // Content size
- write32<E>(Buf.data() + 8, NT_GNU_BUILD_ID); // Type
- memcpy(Buf.data() + 12, "GNU", 4); // Name string
- this->Data = ArrayRef<uint8_t>(Buf);
-}
-
-// Returns the location of the build-id hash value in the output.
-template <class ELFT> size_t BuildIdSection<ELFT>::getOutputOffset() {
- return this->OutSec->Offset + this->OutSecOff + HeaderSize;
-}
-
-template <class ELFT> size_t BuildIdSection<ELFT>::getHashSize() {
+static size_t getHashSize() {
switch (Config->BuildId) {
case BuildIdKind::Fast:
return 8;
}
}
+template <class ELFT>
+BuildIdSection<ELFT>::BuildIdSection()
+ : SyntheticSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ".note.gnu.build-id"),
+ HashSize(getHashSize()) {
+ this->Live = true;
+}
+
+template <class ELFT> void BuildIdSection<ELFT>::writeTo(uint8_t *Buf) {
+ const endianness E = ELFT::TargetEndianness;
+ write32<E>(Buf, 4); // Name size
+ write32<E>(Buf + 4, HashSize); // Content size
+ write32<E>(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<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
size_t ChunkSize) {
// of the hash values.
template <class ELFT>
void BuildIdSection<ELFT>::computeHash(
- llvm::MutableArrayRef<uint8_t> Data,
- std::function<void(ArrayRef<uint8_t> Arr, uint8_t *Dest)> HashFn) {
+ llvm::ArrayRef<uint8_t> Data,
+ std::function<void(uint8_t *Dest, ArrayRef<uint8_t> Arr)> HashFn) {
std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
- std::vector<uint8_t> HashList(Chunks.size() * HashSize);
+ std::vector<uint8_t> Hashes(Chunks.size() * HashSize);
auto Fn = [&](ArrayRef<uint8_t> &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 <class ELFT>
-void BuildIdSection<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
+void BuildIdSection<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
switch (Config->BuildId) {
case BuildIdKind::Fast:
- computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) {
+ computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
write64le(Dest, xxHash64(toStringRef(Arr)));
});
break;
case BuildIdKind::Md5:
- computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) {
+ computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
MD5 Hash;
Hash.update(Arr);
MD5::MD5Result Res;
});
break;
case BuildIdKind::Sha1:
- computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) {
+ computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> 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");
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() {}
static bool classof(const InputSectionData *D) {
return D->kind() == InputSectionData::Synthetic;
}
-
-protected:
- ~SyntheticSection() = default;
-};
-
-// .note.gnu.build-id section.
-template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
-public:
- BuildIdSection();
- void writeBuildId(llvm::MutableArrayRef<uint8_t> Buf);
-
-private:
- // First 16 bytes are a header.
- static const unsigned HeaderSize = 16;
-
- size_t getHashSize();
- size_t getOutputOffset();
-
- void
- computeHash(llvm::MutableArrayRef<uint8_t> Buf,
- std::function<void(ArrayRef<uint8_t> Arr, uint8_t *Hash)> Hash);
-
- std::vector<uint8_t> Buf;
- size_t HashSize;
};
template <class ELFT> class GotSection final : public SyntheticSection<ELFT> {
uintX_t Size = 0;
};
+// .note.gnu.build-id section.
+template <class ELFT> class BuildIdSection : public SyntheticSection<ELFT> {
+ // 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<uint8_t> Buf);
+
+private:
+ void computeHash(llvm::ArrayRef<uint8_t> Buf,
+ std::function<void(uint8_t *, ArrayRef<uint8_t>)> Hash);
+
+ size_t HashSize;
+ uint8_t *HashBuf;
+};
+
template <class ELFT> class MipsGotSection final : public SyntheticSection<ELFT> {
typedef typename ELFT::uint uintX_t;