[lld] r285682 - Convert BuildIdSection to input section

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 1 02:49:24 PDT 2016


Author: evgeny777
Date: Tue Nov  1 04:49:24 2016
New Revision: 285682

URL: http://llvm.org/viewvc/llvm-project?rev=285682&view=rev
Log:
Convert BuildIdSection to input section

Differential revision: https://reviews.llvm.org/D25627

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    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/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=285682&r1=285681&r2=285682&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Nov  1 04:49:24 2016
@@ -19,6 +19,8 @@
 
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
+#include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/Support/xxhash.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
@@ -480,6 +482,9 @@ template <class ELFT> void InputSection<
   if (this->Type == SHT_NOBITS)
     return;
 
+  // Set output location.
+  this->OutputLoc = Buf + OutSecOff;
+
   // If -r is given, then an InputSection may be a relocation section.
   if (this->Type == SHT_RELA) {
     copyRelocations(Buf + OutSecOff, this->template getDataAs<Elf_Rela>());
@@ -848,6 +853,60 @@ InputSection<ELFT> InputSection<ELFT>::c
   return Ret;
 }
 
+template <class ELFT>
+BuildIdSection<ELFT>::BuildIdSection(size_t HashSize)
+    : InputSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ArrayRef<uint8_t>(),
+                         ".note.gnu.build-id") {
+  Buf.resize(16 + 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);
+}
+
+template <class ELFT>
+void BuildIdFastHash<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
+  const endianness E = ELFT::TargetEndianness;
+
+  // 64-bit xxhash
+  uint64_t Hash = xxHash64(toStringRef(Buf));
+  write64<E>(this->OutputLoc + 16, Hash);
+}
+
+template <class ELFT>
+void BuildIdMd5<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
+  MD5 Hash;
+  Hash.update(Buf);
+  MD5::MD5Result Res;
+  Hash.final(Res);
+  memcpy(this->OutputLoc + 16, Res, 16);
+}
+
+template <class ELFT>
+void BuildIdSha1<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
+  SHA1 Hash;
+  Hash.update(Buf);
+  memcpy(this->OutputLoc + 16, Hash.final().data(), 20);
+}
+
+template <class ELFT>
+void BuildIdUuid<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
+  if (getRandomBytes(this->OutputLoc + 16, 16))
+    error("entropy source failure");
+}
+
+template <class ELFT>
+BuildIdHexstring<ELFT>::BuildIdHexstring()
+    : BuildIdSection<ELFT>(Config->BuildIdVector.size()) {}
+
+template <class ELFT>
+void BuildIdHexstring<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
+  memcpy(this->OutputLoc + 16, Config->BuildIdVector.data(),
+         Config->BuildIdVector.size());
+}
+
 template class elf::InputSectionBase<ELF32LE>;
 template class elf::InputSectionBase<ELF32BE>;
 template class elf::InputSectionBase<ELF64LE>;
@@ -882,3 +941,33 @@ template class elf::MipsAbiFlagsInputSec
 template class elf::MipsAbiFlagsInputSection<ELF32BE>;
 template class elf::MipsAbiFlagsInputSection<ELF64LE>;
 template class elf::MipsAbiFlagsInputSection<ELF64BE>;
+
+template class elf::BuildIdSection<ELF32LE>;
+template class elf::BuildIdSection<ELF32BE>;
+template class elf::BuildIdSection<ELF64LE>;
+template class elf::BuildIdSection<ELF64BE>;
+
+template class elf::BuildIdFastHash<ELF32LE>;
+template class elf::BuildIdFastHash<ELF32BE>;
+template class elf::BuildIdFastHash<ELF64LE>;
+template class elf::BuildIdFastHash<ELF64BE>;
+
+template class elf::BuildIdMd5<ELF32LE>;
+template class elf::BuildIdMd5<ELF32BE>;
+template class elf::BuildIdMd5<ELF64LE>;
+template class elf::BuildIdMd5<ELF64BE>;
+
+template class elf::BuildIdSha1<ELF32LE>;
+template class elf::BuildIdSha1<ELF32BE>;
+template class elf::BuildIdSha1<ELF64LE>;
+template class elf::BuildIdSha1<ELF64BE>;
+
+template class elf::BuildIdUuid<ELF32LE>;
+template class elf::BuildIdUuid<ELF32BE>;
+template class elf::BuildIdUuid<ELF64LE>;
+template class elf::BuildIdUuid<ELF64BE>;
+
+template class elf::BuildIdHexstring<ELF32LE>;
+template class elf::BuildIdHexstring<ELF32BE>;
+template class elf::BuildIdHexstring<ELF64LE>;
+template class elf::BuildIdHexstring<ELF64BE>;

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=285682&r1=285681&r2=285682&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Tue Nov  1 04:49:24 2016
@@ -252,6 +252,9 @@ public:
   // to. The writer sets a value.
   uint64_t OutSecOff = 0;
 
+  // Location of this section in the output buffer
+  uint8_t *OutputLoc = nullptr;
+
   // InputSection that is dependent on us (reverse dependency for GC)
   InputSectionBase<ELFT> *DependentSection = nullptr;
 
@@ -339,6 +342,58 @@ public:
   const llvm::object::Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
 };
 
+template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
+  typedef OutputSectionBase<ELFT> Base;
+
+public:
+  virtual void writeBuildId(ArrayRef<uint8_t> Buf) = 0;
+  virtual ~BuildIdSection() = default;
+
+protected:
+  BuildIdSection(size_t HashSize);
+  std::vector<uint8_t> Buf;
+};
+
+template <class ELFT>
+class BuildIdFastHash final : public BuildIdSection<ELFT> {
+public:
+  BuildIdFastHash() : BuildIdSection<ELFT>(8) {}
+  void writeBuildId(ArrayRef<uint8_t> Buf) override;
+};
+
+template <class ELFT> class BuildIdMd5 final : public BuildIdSection<ELFT> {
+public:
+  BuildIdMd5() : BuildIdSection<ELFT>(16) {}
+  void writeBuildId(ArrayRef<uint8_t> Buf) override;
+};
+
+template <class ELFT> class BuildIdSha1 final : public BuildIdSection<ELFT> {
+public:
+  BuildIdSha1() : BuildIdSection<ELFT>(20) {}
+  void writeBuildId(ArrayRef<uint8_t> Buf) override;
+};
+
+template <class ELFT> class BuildIdUuid final : public BuildIdSection<ELFT> {
+public:
+  BuildIdUuid() : BuildIdSection<ELFT>(16) {}
+  void writeBuildId(ArrayRef<uint8_t> Buf) override;
+};
+
+template <class ELFT>
+class BuildIdHexstring final : public BuildIdSection<ELFT> {
+public:
+  BuildIdHexstring();
+  void writeBuildId(ArrayRef<uint8_t>) override;
+};
+
+// Linker generated sections which can be used as inputs.
+template <class ELFT> struct In {
+  static BuildIdSection<ELFT> *BuildId;
+  static std::vector<InputSection<ELFT> *> Sections;
+};
+
+template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
+template <class ELFT> std::vector<InputSection<ELFT> *> In<ELFT>::Sections;
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=285682&r1=285681&r2=285682&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Nov  1 04:49:24 2016
@@ -19,9 +19,7 @@
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/SHA1.h"
-#include "llvm/Support/xxhash.h"
 
 using namespace llvm;
 using namespace llvm::dwarf;
@@ -1739,64 +1737,6 @@ template <class ELFT> void VersionNeedSe
 }
 
 template <class ELFT>
-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, 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 BuildIdFastHash<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
-  const endianness E = ELFT::TargetEndianness;
-
-  // 64-bit xxhash
-  uint64_t Hash = xxHash64(toStringRef(Buf));
-  write64<E>(this->HashBuf, Hash);
-}
-
-template <class ELFT>
-void BuildIdMd5<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
-  MD5 Hash;
-  Hash.update(Buf);
-  MD5::MD5Result Res;
-  Hash.final(Res);
-  memcpy(this->HashBuf, Res, 16);
-}
-
-template <class ELFT>
-void BuildIdSha1<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
-  SHA1 Hash;
-  Hash.update(Buf);
-  memcpy(this->HashBuf, Hash.final().data(), 20);
-}
-
-template <class ELFT>
-void BuildIdUuid<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
-  if (getRandomBytes(this->HashBuf, 16))
-    error("entropy source failure");
-}
-
-template <class ELFT>
-BuildIdHexstring<ELFT>::BuildIdHexstring()
-    : BuildIdSection<ELFT>(Config->BuildIdVector.size()) {}
-
-template <class ELFT>
-void BuildIdHexstring<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
-  memcpy(this->HashBuf, Config->BuildIdVector.data(),
-         Config->BuildIdVector.size());
-}
-
-template <class ELFT>
 MipsReginfoOutputSection<ELFT>::MipsReginfoOutputSection()
     : OutputSectionBase<ELFT>(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) {
   this->Header.sh_addralign = 4;
@@ -2101,36 +2041,6 @@ template class VersionDefinitionSection<
 template class VersionDefinitionSection<ELF64LE>;
 template class VersionDefinitionSection<ELF64BE>;
 
-template class BuildIdSection<ELF32LE>;
-template class BuildIdSection<ELF32BE>;
-template class BuildIdSection<ELF64LE>;
-template class BuildIdSection<ELF64BE>;
-
-template class BuildIdFastHash<ELF32LE>;
-template class BuildIdFastHash<ELF32BE>;
-template class BuildIdFastHash<ELF64LE>;
-template class BuildIdFastHash<ELF64BE>;
-
-template class BuildIdMd5<ELF32LE>;
-template class BuildIdMd5<ELF32BE>;
-template class BuildIdMd5<ELF64LE>;
-template class BuildIdMd5<ELF64BE>;
-
-template class BuildIdSha1<ELF32LE>;
-template class BuildIdSha1<ELF32BE>;
-template class BuildIdSha1<ELF64LE>;
-template class BuildIdSha1<ELF64BE>;
-
-template class BuildIdUuid<ELF32LE>;
-template class BuildIdUuid<ELF32BE>;
-template class BuildIdUuid<ELF64LE>;
-template class BuildIdUuid<ELF64BE>;
-
-template class BuildIdHexstring<ELF32LE>;
-template class BuildIdHexstring<ELF32BE>;
-template class BuildIdHexstring<ELF64LE>;
-template class BuildIdHexstring<ELF64BE>;
-
 template class GdbIndexSection<ELF32LE>;
 template class GdbIndexSection<ELF32BE>;
 template class GdbIndexSection<ELF64LE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=285682&r1=285681&r2=285682&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Nov  1 04:49:24 2016
@@ -51,7 +51,6 @@ public:
   typedef typename ELFT::Shdr Elf_Shdr;
   enum Kind {
     Base,
-    BuildId,
     Dynamic,
     EHFrame,
     EHFrameHdr,
@@ -738,60 +737,12 @@ private:
   std::vector<FdeData> Fdes;
 };
 
-template <class ELFT> class BuildIdSection : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
-
-public:
-  void writeTo(uint8_t *Buf) override;
-  virtual void writeBuildId(ArrayRef<uint8_t> Buf) = 0;
-  typename Base::Kind getKind() const override { return Base::BuildId; }
-  static bool classof(const Base *B) { return B->getKind() == Base::BuildId; }
-
-protected:
-  BuildIdSection(size_t HashSize);
-  size_t HashSize;
-  uint8_t *HashBuf = nullptr;
-};
-
-template <class ELFT>
-class BuildIdFastHash final : public BuildIdSection<ELFT> {
-public:
-  BuildIdFastHash() : BuildIdSection<ELFT>(8) {}
-  void writeBuildId(ArrayRef<uint8_t> Buf) override;
-};
-
-template <class ELFT> class BuildIdMd5 final : public BuildIdSection<ELFT> {
-public:
-  BuildIdMd5() : BuildIdSection<ELFT>(16) {}
-  void writeBuildId(ArrayRef<uint8_t> Buf) override;
-};
-
-template <class ELFT> class BuildIdSha1 final : public BuildIdSection<ELFT> {
-public:
-  BuildIdSha1() : BuildIdSection<ELFT>(20) {}
-  void writeBuildId(ArrayRef<uint8_t> Buf) override;
-};
-
-template <class ELFT> class BuildIdUuid final : public BuildIdSection<ELFT> {
-public:
-  BuildIdUuid() : BuildIdSection<ELFT>(16) {}
-  void writeBuildId(ArrayRef<uint8_t> Buf) override;
-};
-
-template <class ELFT>
-class BuildIdHexstring final : public BuildIdSection<ELFT> {
-public:
-  BuildIdHexstring();
-  void writeBuildId(ArrayRef<uint8_t>) override;
-};
-
 // All output sections that are hadnled by the linker specially are
 // globally accessible. Writer initializes them, so don't use them
 // until Writer is initialized.
 template <class ELFT> struct Out {
   typedef typename ELFT::uint uintX_t;
   typedef typename ELFT::Phdr Elf_Phdr;
-  static BuildIdSection<ELFT> *BuildId;
   static DynamicSection<ELFT> *Dynamic;
   static EhFrameHeader<ELFT> *EhFrameHdr;
   static EhOutputSection<ELFT> *EhFrame;
@@ -862,7 +813,6 @@ template <class ELFT> uint64_t getHeader
   return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
 }
 
-template <class ELFT> BuildIdSection<ELFT> *Out<ELFT>::BuildId;
 template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
 template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
 template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=285682&r1=285681&r2=285682&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Nov  1 04:49:24 2016
@@ -50,6 +50,7 @@ private:
 
   void copyLocalSymbols();
   void addReservedSymbols();
+  void addInputSec(InputSectionBase<ELFT> *S);
   void createSections();
   void forEachRelSec(std::function<void(InputSectionBase<ELFT> &,
                                         const typename ELFT::Shdr &)> Fn);
@@ -209,7 +210,6 @@ template <class ELFT> void elf::writeRes
     VerDef.reset(new VersionDefinitionSection<ELFT>());
 
   Out<ELFT>::Bss = &Bss;
-  Out<ELFT>::BuildId = BuildId.get();
   Out<ELFT>::DynStrTab = DynStrTab.get();
   Out<ELFT>::DynSymTab = DynSymTab.get();
   Out<ELFT>::Dynamic = &Dynamic;
@@ -241,6 +241,10 @@ template <class ELFT> void elf::writeRes
   Out<ELFT>::InitArray = nullptr;
   Out<ELFT>::FiniArray = nullptr;
 
+  // Initialize linker generated sections
+  In<ELFT>::BuildId = BuildId.get();
+  In<ELFT>::Sections = {BuildId.get()};
+
   Writer<ELFT>().run();
   Out<ELFT>::Pool.clear();
 }
@@ -696,28 +700,29 @@ void Writer<ELFT>::forEachRelSec(
   }
 }
 
-template <class ELFT> void Writer<ELFT>::createSections() {
-  auto Add = [&](InputSectionBase<ELFT> *IS) {
-    if (isDiscarded(IS)) {
-      reportDiscarded(IS);
-      return;
-    }
-    OutputSectionBase<ELFT> *Sec;
-    bool IsNew;
-    StringRef OutsecName = getOutputSectionName(IS->Name);
-    std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
-    if (IsNew)
-      OutputSections.push_back(Sec);
-    Sec->addSection(IS);
-  };
+template <class ELFT>
+void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
+  if (isDiscarded(IS)) {
+    reportDiscarded(IS);
+    return;
+  }
+  OutputSectionBase<ELFT> *Sec;
+  bool IsNew;
+  StringRef OutsecName = getOutputSectionName(IS->Name);
+  std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
+  if (IsNew)
+    OutputSections.push_back(Sec);
+  Sec->addSection(IS);
+}
 
+template <class ELFT> void Writer<ELFT>::createSections() {
   for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
     for (InputSectionBase<ELFT> *IS : F->getSections())
-      Add(IS);
+      addInputSec(IS);
 
   for (BinaryFile *F : Symtab<ELFT>::X->getBinaryFiles())
     for (InputSectionData *ID : F->getSections())
-      Add(cast<InputSection<ELFT>>(ID));
+      addInputSec(cast<InputSection<ELFT>>(ID));
 
   sortInitFini(findSection(".init_array"));
   sortInitFini(findSection(".fini_array"));
@@ -847,6 +852,11 @@ template <class ELFT> void Writer<ELFT>:
   // This function adds linker-created Out<ELFT>::* sections.
   addPredefinedSections();
 
+  // Adds linker generated input sections to
+  // corresponding output sections.
+  for (InputSection<ELFT> *S : In<ELFT>::Sections)
+    addInputSec(S);
+
   sortSections();
 
   unsigned I = 1;
@@ -855,6 +865,11 @@ template <class ELFT> void Writer<ELFT>:
     Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
   }
 
+  // Finalize linker generated sections.
+  for (InputSection<ELFT> *S : In<ELFT>::Sections)
+    if (S && S->OutSec)
+      S->OutSec->assignOffsets();
+
   // Finalizers fix each section's size.
   // .dynsym is finalized early since that may fill up .gnu.hash.
   if (Out<ELFT>::DynSymTab)
@@ -899,12 +914,6 @@ template <class ELFT> void Writer<ELFT>:
       OutputSections.push_back(OS);
   };
 
-  // A core file does not usually contain unmodified segments except
-  // the first page of the executable. Add the build ID section to beginning of
-  // the file so that the section is included in the first page.
-  if (Out<ELFT>::BuildId)
-    OutputSections.insert(OutputSections.begin(), Out<ELFT>::BuildId);
-
   // Add .interp at first because some loaders want to see that section
   // on the first page of the executable file when loaded into memory.
   if (Out<ELFT>::Interp)
@@ -1484,13 +1493,13 @@ template <class ELFT> void Writer<ELFT>:
 }
 
 template <class ELFT> void Writer<ELFT>::writeBuildId() {
-  if (!Out<ELFT>::BuildId)
+  if (!In<ELFT>::BuildId || !In<ELFT>::BuildId->OutSec)
     return;
 
   // Compute a hash of all sections of the output file.
   uint8_t *Start = Buffer->getBufferStart();
   uint8_t *End = Start + FileSize;
-  Out<ELFT>::BuildId->writeBuildId({Start, End});
+  In<ELFT>::BuildId->writeBuildId({Start, End});
 }
 
 template void elf::writeResult<ELF32LE>();

Modified: lld/trunk/test/ELF/build-id.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/build-id.s?rev=285682&r1=285681&r2=285682&view=diff
==============================================================================
--- lld/trunk/test/ELF/build-id.s (original)
+++ lld/trunk/test/ELF/build-id.s Tue Nov  1 04:49:24 2016
@@ -23,9 +23,9 @@ _start:
 .section .note.test, "a", @note
    .quad 42
 
+# DEFAULT:      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:
 
 # MD5:      Contents of section .note.gnu.build-id:
 # MD5-NEXT: 04000000 10000000 03000000 474e5500  ............GNU.




More information about the llvm-commits mailing list