[lld] r265737 - ELF: Implement --build-id=md5.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 7 15:49:21 PDT 2016


Author: ruiu
Date: Thu Apr  7 17:49:21 2016
New Revision: 265737

URL: http://llvm.org/viewvc/llvm-project?rev=265737&view=rev
Log:
ELF: Implement --build-id=md5.

Previously, we supported only one hash function, FNV-1, so
BuildIdSection directly handled hash computation. In this patch,
I made BuildIdSection an abstract class and defined two subclasses,
BuildIdFnv1 and BuildIdMd5.

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/build-id.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Thu Apr  7 17:49:21 2016
@@ -30,6 +30,12 @@ enum ELFKind {
   ELF64BEKind
 };
 
+enum class BuildIdKind {
+  None,
+  Fnv1,
+  Md5,
+};
+
 // This struct contains the global configuration for the linker.
 // Most fields are direct mapping from the command line options
 // and such fields have the same name as the corresponding options.
@@ -54,7 +60,6 @@ struct Configuration {
   bool AsNeeded = false;
   bool Bsymbolic;
   bool BsymbolicFunctions;
-  bool BuildId;
   bool Demangle = true;
   bool DisableVerify;
   bool DiscardAll;
@@ -90,6 +95,7 @@ struct Configuration {
   bool ZNow;
   bool ZOrigin;
   bool ZRelro;
+  BuildIdKind BuildId = BuildIdKind::None;
   ELFKind EKind = ELFNoneKind;
   uint16_t EMachine = llvm::ELF::EM_NONE;
   uint64_t EntryAddr = -1;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Apr  7 17:49:21 2016
@@ -271,7 +271,6 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
-  Config->BuildId = Args.hasArg(OPT_build_id);
   Config->Demangle = !Args.hasArg(OPT_no_demangle);
   Config->DisableVerify = Args.hasArg(OPT_disable_verify);
   Config->DiscardAll = Args.hasArg(OPT_discard_all);
@@ -337,6 +336,17 @@ void LinkerDriver::readConfigs(opt::Inpu
       error("unknown hash style: " + S);
   }
 
+  // Parse --build-id or --build-id=<style>.
+  if (Args.hasArg(OPT_build_id))
+    Config->BuildId = BuildIdKind::Fnv1;
+  if (auto *Arg = Args.getLastArg(OPT_build_id_eq)) {
+    StringRef S = Arg->getValue();
+    if (S == "md5") {
+      Config->BuildId = BuildIdKind::Md5;
+    } else
+      error("unknown --build-id style: " + S);
+  }
+
   for (auto *Arg : Args.filtered(OPT_undefined))
     Config->Undefined.push_back(Arg->getValue());
 }

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Thu Apr  7 17:49:21 2016
@@ -15,6 +15,8 @@ def Bstatic: Flag<["-"], "Bstatic">,
 def build_id : Flag<["--", "-"], "build-id">,
   HelpText<"Generate build ID note">;
 
+def build_id_eq : Joined<["--", "-"], "build-id=">;
+
 def L : JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
   HelpText<"Directory to search for libraries">;
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Thu Apr  7 17:49:21 2016
@@ -14,6 +14,7 @@
 #include "Target.h"
 #include "lld/Core/Parallel.h"
 #include "llvm/Support/Dwarf.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include <map>
 
@@ -1521,23 +1522,24 @@ uint8_t SymbolTableSection<ELFT>::getSym
 }
 
 template <class ELFT>
-BuildIdSection<ELFT>::BuildIdSection()
-    : OutputSectionBase<ELFT>(".note.gnu.build-id", SHT_NOTE, SHF_ALLOC) {
-  // 16 bytes for the note section header and 8 bytes for FNV1 hash.
-  this->Header.sh_size = 24;
+BuildIdSection<ELFT>::BuildIdSection(size_t HashSize)
+    : OutputSectionBase<ELFT>(".note.gnu.build-id", SHT_NOTE, SHF_ALLOC),
+      HashSize(HashSize) {
+  // 16 bytes for the note section header.
+  this->Header.sh_size = 16 + HashSize;
 }
 
 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, sizeof(Hash));    // Content 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;
 }
 
-template <class ELFT> void BuildIdSection<ELFT>::update(ArrayRef<uint8_t> Buf) {
-  // 64-bit FNV1 hash
+template <class ELFT> void BuildIdFnv1<ELFT>::update(ArrayRef<uint8_t> Buf) {
+  // 64-bit FNV-1 hash
   const uint64_t Prime = 0x100000001b3;
   for (uint8_t B : Buf) {
     Hash *= Prime;
@@ -1545,9 +1547,19 @@ template <class ELFT> void BuildIdSectio
   }
 }
 
-template <class ELFT> void BuildIdSection<ELFT>::writeBuildId() {
+template <class ELFT> void BuildIdFnv1<ELFT>::writeBuildId() {
   const endianness E = ELFT::TargetEndianness;
-  write64<E>(HashBuf, Hash);
+  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() {
+  MD5::MD5Result Res;
+  Hash.final(Res);
+  memcpy(this->HashBuf, Res, 16);
 }
 
 template <class ELFT>
@@ -1658,5 +1670,15 @@ template class BuildIdSection<ELF32LE>;
 template class BuildIdSection<ELF32BE>;
 template class BuildIdSection<ELF64LE>;
 template class BuildIdSection<ELF64BE>;
+
+template class BuildIdFnv1<ELF32LE>;
+template class BuildIdFnv1<ELF32BE>;
+template class BuildIdFnv1<ELF64LE>;
+template class BuildIdFnv1<ELF64BE>;
+
+template class BuildIdMd5<ELF32LE>;
+template class BuildIdMd5<ELF32BE>;
+template class BuildIdMd5<ELF64LE>;
+template class BuildIdMd5<ELF64BE>;
 }
 }

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Thu Apr  7 17:49:21 2016
@@ -16,6 +16,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/ELF.h"
+#include "llvm/Support/MD5.h"
 
 namespace lld {
 namespace elf {
@@ -494,17 +495,37 @@ private:
   std::vector<FdeData> FdeList;
 };
 
-template <class ELFT>
-class BuildIdSection final : public OutputSectionBase<ELFT> {
+template <class ELFT> class BuildIdSection : public OutputSectionBase<ELFT> {
 public:
-  BuildIdSection();
   void writeTo(uint8_t *Buf) override;
-  void update(ArrayRef<uint8_t> Buf);
-  void writeBuildId();
+  virtual void update(ArrayRef<uint8_t> Buf) = 0;
+  virtual void writeBuildId() = 0;
+
+protected:
+  BuildIdSection(size_t HashSize);
+  size_t HashSize;
+  uint8_t *HashBuf = nullptr;
+};
+
+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;
+};
+
+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:
-  uint64_t Hash = 0xcbf29ce484222325; // FNV1 hash basis
-  uint8_t *HashBuf;
+  llvm::MD5 Hash;
 };
 
 // All output sections that are hadnled by the linker specially are

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Apr  7 17:49:21 2016
@@ -146,8 +146,11 @@ template <class ELFT> void elf::writeRes
   std::unique_ptr<SymbolTableSection<ELFT>> SymTabSec;
   std::unique_ptr<OutputSection<ELFT>> MipsRldMap;
 
-  if (Config->BuildId)
-    BuildId.reset(new BuildIdSection<ELFT>);
+  if (Config->BuildId == BuildIdKind::Fnv1)
+    BuildId.reset(new BuildIdFnv1<ELFT>);
+  else if (Config->BuildId == BuildIdKind::Md5)
+    BuildId.reset(new BuildIdMd5<ELFT>);
+
   if (Config->GnuHash)
     GnuHashTab.reset(new GnuHashTableSection<ELFT>);
   if (Config->SysvHash)

Modified: lld/trunk/test/ELF/build-id.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/build-id.s?rev=265737&r1=265736&r2=265737&view=diff
==============================================================================
--- lld/trunk/test/ELF/build-id.s (original)
+++ lld/trunk/test/ELF/build-id.s Thu Apr  7 17:49:21 2016
@@ -2,9 +2,11 @@
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 # RUN: ld.lld --build-id %t -o %t2
-# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=BUILDID %s
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s
+# RUN: ld.lld --build-id=md5 %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=MD5 %s
 # RUN: ld.lld %t -o %t2
-# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NO-BUILDID %s
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
 
 .globl _start;
 _start:
@@ -13,8 +15,11 @@ _start:
 .section .note.test, "a", @note
    .quad 42
 
-# BUILDID:      Contents of section .note.gnu.build-id:
-# BUILDID-NEXT: 04000000 08000000 03000000 474e5500  ............GNU.
-# BUILDID:      Contents of section .note.test:
+# DEFAULT:      Contents of section .note.gnu.build-id:
+# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500  ............GNU.
+# DEFAULT:      Contents of section .note.test:
 
-# NO-BUILDID-NOT: Contents of section .note.gnu.build-id:
+# MD5:      Contents of section .note.gnu.build-id:
+# MD5-NEXT: 04000000 10000000 03000000 474e5500  ............GNU.
+
+# NONE-NOT: Contents of section .note.gnu.build-id:




More information about the llvm-commits mailing list