Pass all buffers to BuildId hash function at once. NFC.
authorRui Ueyama <ruiu@google.com>
Mon, 2 May 2016 23:35:59 +0000 (23:35 +0000)
committerRui Ueyama <ruiu@google.com>
Mon, 2 May 2016 23:35:59 +0000 (23:35 +0000)
This change simplifies the BuildId classes by removing a few member
functions and variables from them. It should also make it easy to
parallelize hash computation in future because now each BuildId object
see all inputs rather than one at a time.

llvm-svn: 268333

lld/ELF/OutputSections.cpp
lld/ELF/OutputSections.h
lld/ELF/Writer.cpp

index 13d5805..922de77 100644 (file)
@@ -1636,35 +1636,36 @@ template <class ELFT> void BuildIdSection<ELFT>::writeTo(uint8_t *Buf) {
   HashBuf = Buf + 16;
 }
 
-template <class ELFT> void BuildIdFnv1<ELFT>::update(ArrayRef<uint8_t> Buf) {
+template <class ELFT>
+void BuildIdFnv1<ELFT>::writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) {
+  const endianness E = ELFT::TargetEndianness;
+
   // 64-bit FNV-1 hash
-  const uint64_t Prime = 0x100000001b3;
-  for (uint8_t B : Buf) {
-    Hash *= Prime;
-    Hash ^= B;
+  uint64_t Hash = 0xcbf29ce484222325;
+  for (ArrayRef<uint8_t> Buf : Bufs) {
+    for (uint8_t B : Buf) {
+      Hash *= 0x100000001b3;
+      Hash ^= B;
+    }
   }
-}
-
-template <class ELFT> void BuildIdFnv1<ELFT>::writeBuildId() {
-  const endianness E = ELFT::TargetEndianness;
   write64<E>(this->HashBuf, Hash);
 }
 
-template <class ELFT> void BuildIdMd5<ELFT>::update(ArrayRef<uint8_t> Buf) {
-  Hash.update(Buf);
-}
-
-template <class ELFT> void BuildIdMd5<ELFT>::writeBuildId() {
+template <class ELFT>
+void BuildIdMd5<ELFT>::writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) {
+  llvm::MD5 Hash;
+  for (ArrayRef<uint8_t> Buf : Bufs)
+    Hash.update(Buf);
   MD5::MD5Result Res;
   Hash.final(Res);
   memcpy(this->HashBuf, Res, 16);
 }
 
-template <class ELFT> void BuildIdSha1<ELFT>::update(ArrayRef<uint8_t> Buf) {
-  Hash.update(Buf);
-}
-
-template <class ELFT> void BuildIdSha1<ELFT>::writeBuildId() {
+template <class ELFT>
+void BuildIdSha1<ELFT>::writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) {
+  llvm::SHA1 Hash;
+  for (ArrayRef<uint8_t> Buf : Bufs)
+    Hash.update(Buf);
   memcpy(this->HashBuf, Hash.final().data(), 20);
 }
 
index f9c4b6e..64ed3d7 100644 (file)
@@ -541,8 +541,7 @@ private:
 template <class ELFT> class BuildIdSection : public OutputSectionBase<ELFT> {
 public:
   void writeTo(uint8_t *Buf) override;
-  virtual void update(ArrayRef<uint8_t> Buf) = 0;
-  virtual void writeBuildId() = 0;
+  virtual void writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) = 0;
 
 protected:
   BuildIdSection(size_t HashSize);
@@ -553,32 +552,19 @@ protected:
 template <class ELFT> class BuildIdFnv1 final : public BuildIdSection<ELFT> {
 public:
   BuildIdFnv1() : BuildIdSection<ELFT>(8) {}
-  void update(ArrayRef<uint8_t> Buf) override;
-  void writeBuildId() override;
-
-private:
-  // 64-bit FNV-1 initial value
-  uint64_t Hash = 0xcbf29ce484222325;
+  void writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) override;
 };
 
 template <class ELFT> class BuildIdMd5 final : public BuildIdSection<ELFT> {
 public:
   BuildIdMd5() : BuildIdSection<ELFT>(16) {}
-  void update(ArrayRef<uint8_t> Buf) override;
-  void writeBuildId() override;
-
-private:
-  llvm::MD5 Hash;
+  void writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) override;
 };
 
 template <class ELFT> class BuildIdSha1 final : public BuildIdSection<ELFT> {
 public:
   BuildIdSha1() : BuildIdSection<ELFT>(20) {}
-  void update(ArrayRef<uint8_t> Buf) override;
-  void writeBuildId() override;
-
-private:
-  llvm::SHA1 Hash;
+  void writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) override;
 };
 
 // All output sections that are hadnled by the linker specially are
index 98ad727..00004e7 100644 (file)
@@ -1907,16 +1907,15 @@ template <class ELFT> void Writer<ELFT>::writeBuildId() {
   // other sections are the same.
   uint8_t *Start = Buffer->getBufferStart();
   uint8_t *Last = Start;
+  std::vector<ArrayRef<uint8_t>> Regions;
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
     uint8_t *End = Start + Sec->getFileOff();
     if (!Sec->getName().startswith(".debug_"))
-      S->update({Last, End});
+      Regions.push_back({Last, End});
     Last = End;
   }
-  S->update({Last, Start + FileSize});
-
-  // Fill the hash value field in the .note.gnu.build-id section.
-  S->writeBuildId();
+  Regions.push_back({Last, Start + FileSize});
+  S->writeBuildId(Regions);
 }
 
 template void elf::writeResult<ELF32LE>(SymbolTable<ELF32LE> *Symtab);