[llvm] r328012 - [llvm-objcopy] Implement support for section groups

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 20 11:20:43 PDT 2018


Author: alexshap
Date: Tue Mar 20 11:20:42 2018
New Revision: 328012

URL: http://llvm.org/viewvc/llvm-project?rev=328012&view=rev
Log:
[llvm-objcopy] Implement support for section groups

This diff adds support for SHT_GROUP sections to llvm-objcopy.
Some sections are interrelated and comprise a group.
For example, a definition of an inline function might require, 
in addition to the section containing its instructions, 
a read-only data section containing literals referenced inside the function.
A section of the type SHT_GROUP contains the indices of the group members,
therefore, it needs to be updated whenever the indices change.
Similarly, the fields sh_link, sh_info should be recalculated as well.

Test plan: make check-all

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

Added:
    llvm/trunk/test/tools/llvm-objcopy/Inputs/groups.o   (with props)
    llvm/trunk/test/tools/llvm-objcopy/group-unchanged.test
    llvm/trunk/test/tools/llvm-objcopy/group.test
    llvm/trunk/test/tools/llvm-objcopy/strip-dwo-groups.test
Modified:
    llvm/trunk/tools/llvm-objcopy/Object.cpp
    llvm/trunk/tools/llvm-objcopy/Object.h

Added: llvm/trunk/test/tools/llvm-objcopy/Inputs/groups.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/Inputs/groups.o?rev=328012&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-objcopy/Inputs/groups.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-objcopy/group-unchanged.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/group-unchanged.test?rev=328012&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/group-unchanged.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/group-unchanged.test Tue Mar 20 11:20:42 2018
@@ -0,0 +1,56 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -remove-section=.text.bar %t %t2
+# RUN: llvm-readobj -elf-section-groups %t2 | FileCheck %s
+
+# In this test the section .text.bar is getting removed, since this section
+# goes after all the sections comprising a group, the content of the
+# section .group doesn't change.
+
+# CHECK:           Name: .group
+# CHECK-NEXT:      Index: 1
+# CHECK-NEXT:      Link: 3
+# CHECK-NEXT:      Info: 2
+# CHECK-NEXT:      Type: COMDAT (0x1)
+# CHECK-NEXT:      Signature: foo
+# CHECK:           .text.foo (2)
+
+--- !ELF
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:        
+  - Name:            .group
+    Type:            SHT_GROUP
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            foo
+    Members:         
+      - SectionOrType:   GRP_COMDAT
+      - SectionOrType:   .text.foo
+  - Name:            .text.foo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+    AddressAlign:    0x0000000000000010
+  - Name:            .text.bar
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000010
+Symbols:
+  Local:           
+    - Name:            .text.foo
+      Type:            STT_SECTION
+      Section:         .text.foo         
+    - Name:            .text.bar
+      Type:            STT_SECTION
+      Section:         .text.bar
+  Weak:            
+    - Name:            foo
+      Type:            STT_FUNC
+      Section:         .text.foo
+      Size:            0x0000000000000000
+    - Name:            bar
+      Type:            STT_FUNC
+      Section:         .text.bar
+      Size:            0x0000000000000000

Added: llvm/trunk/test/tools/llvm-objcopy/group.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/group.test?rev=328012&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/group.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/group.test Tue Mar 20 11:20:42 2018
@@ -0,0 +1,56 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -remove-section=.text.bar %t %t2
+# RUN: llvm-readobj -elf-section-groups %t2 | FileCheck %s
+
+# In this test the section .text.bar is getting removed, as a result, 
+# the indices of the sections which go after .text.bar will change, 
+# thus the fields Link, Info and the content of .group should be updated.
+
+# CHECK:           Name: .group
+# CHECK-NEXT:      Index: 1
+# CHECK-NEXT:      Link: 3
+# CHECK-NEXT:      Info: 2
+# CHECK-NEXT:      Type: COMDAT (0x1)
+# CHECK-NEXT:      Signature: foo
+# CHECK:           .text.foo (2)
+
+--- !ELF
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:        
+  - Name:            .group
+    Type:            SHT_GROUP
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            foo
+    Members:         
+      - SectionOrType:   GRP_COMDAT
+      - SectionOrType:   .text.foo
+  - Name:            .text.bar
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000010
+  - Name:            .text.foo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+    AddressAlign:    0x0000000000000010
+Symbols:
+  Local:           
+    - Name:            .text.bar
+      Type:            STT_SECTION
+      Section:         .text.bar
+    - Name:            .text.foo
+      Type:            STT_SECTION
+      Section:         .text.foo         
+  Weak:            
+    - Name:            bar
+      Type:            STT_FUNC
+      Section:         .text.bar
+      Size:            0x0000000000000000
+    - Name:            foo
+      Type:            STT_FUNC
+      Section:         .text.foo
+      Size:            0x0000000000000000

Added: llvm/trunk/test/tools/llvm-objcopy/strip-dwo-groups.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/strip-dwo-groups.test?rev=328012&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/strip-dwo-groups.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/strip-dwo-groups.test Tue Mar 20 11:20:42 2018
@@ -0,0 +1,40 @@
+# RUN: cp %p/Inputs/groups.o %t
+# RUN: llvm-objcopy -strip-dwo %t
+# RUN: llvm-readobj -elf-section-groups %t | FileCheck %s
+
+// Source code of groups.o:
+//
+// template <class T>
+// struct S {
+//    static constexpr T X = T(1);
+//    T getX() { return X; }
+// };
+// void f() {
+//  S<int> A;
+//  S<double> B;
+//  int a = A.getX();
+//  int b = B.getX();
+// }
+//
+// clang -g -gsplit-dwarf -std=c++11 -c groups.cpp -o groups.o
+
+// `llvm-objcopy -strip-dwo` strips out dwo sections, as a result, the index of 
+// the symbol table, the indices of the symbols and the indices of the sections 
+// which go after the removed ones will change. Consequently, the fields 
+// Link, Info and the content of .group need to be updated. In the past 
+// `llvm-objcopy -strip-dwo` used to produce invalid binaries with 
+// broken .group section, this test verifies the correctness of 
+// Link, Info and the content of this section.
+
+CHECK:          Name: .group (179)
+CHECK-NEXT:     Index: 17
+CHECK-NEXT:     Link: 19
+CHECK-NEXT:     Info: 14
+CHECK:          .text._ZN1SIiE4getXEv (2)
+
+CHECK:          Name: .group (179)
+CHECK-NEXT:     Index: 18
+CHECK-NEXT:     Link: 19
+CHECK-NEXT:     Info: 13
+CHECK:          .text._ZN1SIdE4getXEv (4)
+CHECK-NEXT:     .rela.text._ZN1SIdE4getXEv (21)

Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=328012&r1=328011&r2=328012&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Tue Mar 20 11:20:42 2018
@@ -77,7 +77,11 @@ void BinarySectionWriter::visit(const Re
 }
 
 void BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {
-  error("Cannot write '.gnu_debuglink' out to binary");
+  error("Cannot write '" + Sec.Name + "' out to binary");
+}
+
+void BinarySectionWriter::visit(const GroupSection &Sec) {
+  error("Cannot write '" + Sec.Name + "' out to binary");
 }
 
 void SectionWriter::visit(const Section &Sec) {
@@ -155,6 +159,12 @@ uint16_t Symbol::getShndx() const {
   llvm_unreachable("Symbol with invalid ShndxType encountered");
 }
 
+void SymbolTableSection::assignIndices() {
+  uint32_t Index = 0;
+  for (auto &Sym : Symbols)
+    Sym->Index = Index++;
+}
+
 void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
                                    SectionBase *DefinedIn, uint64_t Value,
                                    uint8_t Visibility, uint16_t Shndx,
@@ -189,6 +199,7 @@ void SymbolTableSection::removeSectionRe
                      [=](const SymPtr &Sym) { return Sym->DefinedIn == Sec; });
   Size -= (std::end(Symbols) - Iter) * this->EntrySize;
   Symbols.erase(Iter, std::end(Symbols));
+  assignIndices();
 }
 
 void SymbolTableSection::localize(
@@ -203,11 +214,7 @@ void SymbolTableSection::localize(
   std::stable_partition(
       std::begin(Symbols), std::end(Symbols),
       [](const SymPtr &Sym) { return Sym->Binding == STB_LOCAL; });
-
-  // Lastly we fix the symbol indexes.
-  uint32_t Index = 0;
-  for (auto &Sym : Symbols)
-    Sym->Index = Index++;
+  assignIndices();
 }
 
 void SymbolTableSection::initialize(SectionTableRef SecTable) {
@@ -274,9 +281,10 @@ template <class SymTabType>
 void RelocSectionWithSymtabBase<SymTabType>::removeSectionReferences(
     const SectionBase *Sec) {
   if (Symbols == Sec) {
-    error("Symbol table " + Symbols->Name + " cannot be removed because it is "
-                                            "referenced by the relocation "
-                                            "section " +
+    error("Symbol table " + Symbols->Name +
+          " cannot be removed because it is "
+          "referenced by the relocation "
+          "section " +
           this->Name);
   }
 }
@@ -291,9 +299,9 @@ void RelocSectionWithSymtabBase<SymTabTy
           " is not a symbol table"));
 
   if (Info != SHN_UNDEF)
-    setSection(SecTable.getSection(Info,
-                                   "Info field value " + Twine(Info) +
-                                       " in section " + Name + " is invalid"));
+    setSection(SecTable.getSection(Info, "Info field value " + Twine(Info) +
+                                             " in section " + Name +
+                                             " is invalid"));
   else
     setSection(nullptr);
 }
@@ -347,20 +355,49 @@ void DynamicRelocationSection::accept(Se
 
 void SectionWithStrTab::removeSectionReferences(const SectionBase *Sec) {
   if (StrTab == Sec) {
-    error("String table " + StrTab->Name + " cannot be removed because it is "
-                                           "referenced by the section " +
+    error("String table " + StrTab->Name +
+          " cannot be removed because it is "
+          "referenced by the section " +
           this->Name);
   }
 }
 
+void GroupSection::initialize(SectionTableRef SecTable) {
+  SymTab = SecTable.getSectionOfType<SymbolTableSection>(
+      Link,
+      "Link field value " + Twine(Link) + " in section " + Name + " is invalid",
+      "Link field value " + Twine(Link) + " in section " + Name +
+          " is not a symbol table");
+  Sym = SymTab->getSymbolByIndex(Info);
+  if (!Sym)
+    error("Info field value " + Twine(Info) + " in section " + Name +
+          " is not a valid symbol index");
+  if (Contents.size() % sizeof(ELF::Elf32_Word) || Contents.empty())
+    error("The content of the section " + Name + " is malformed");
+  const ELF::Elf32_Word *Word =
+      reinterpret_cast<const ELF::Elf32_Word *>(Contents.data());
+  const ELF::Elf32_Word *End = Word + Contents.size() / sizeof(ELF::Elf32_Word);
+  FlagWord = *Word++;
+  for (; Word != End; ++Word) {
+    GroupMembers.push_back(
+        SecTable.getSection(*Word, "Group member index " + Twine(*Word) +
+                                       " in section " + Name + " is invalid"));
+  }
+}
+
+void GroupSection::finalize() {
+  this->Info = Sym->Index;
+  this->Link = SymTab->Index;
+}
+
 bool SectionWithStrTab::classof(const SectionBase *S) {
   return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S);
 }
 
 void SectionWithStrTab::initialize(SectionTableRef SecTable) {
-  auto StrTab = SecTable.getSection(Link,
-                                    "Link field value " + Twine(Link) +
-                                        " in section " + Name + " is invalid");
+  auto StrTab =
+      SecTable.getSection(Link, "Link field value " + Twine(Link) +
+                                    " in section " + Name + " is invalid");
   if (StrTab->Type != SHT_STRTAB) {
     error("Link field value " + Twine(Link) + " in section " + Name +
           " is not a string table");
@@ -416,6 +453,19 @@ void GnuDebugLinkSection::accept(Section
   Visitor.visit(*this);
 }
 
+template <class ELFT>
+void ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {
+  ELF::Elf32_Word *Buf =
+      reinterpret_cast<ELF::Elf32_Word *>(Out.getBufferStart() + Sec.Offset);
+  *Buf++ = Sec.FlagWord;
+  for (const auto *S : Sec.GroupMembers)
+    *Buf++ = S->Index;
+}
+
+void GroupSection::accept(SectionVisitor &Visitor) const {
+  Visitor.visit(*this);
+}
+
 // Returns true IFF a section is wholly inside the range of a segment
 static bool sectionWithinSegment(const SectionBase &Section,
                                  const Segment &Segment) {
@@ -455,8 +505,7 @@ static bool compareSegmentsByPAddr(const
   return A->Index < B->Index;
 }
 
-template <class ELFT>
-void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
+template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
   for (auto &Parent : Obj.segments()) {
     // Every segment will overlap with itself but we don't want a segment to
     // be it's own parent so we avoid that situation.
@@ -522,7 +571,7 @@ template <class ELFT> void ELFBuilder<EL
   PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = Ehdr.e_phoff;
   PrHdr.PAddr = 0;
   PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
-  // The spec requires us to naturally align all the fields. 
+  // The spec requires us to naturally align all the fields.
   PrHdr.Align = sizeof(Elf_Addr);
   PrHdr.Index = Index++;
 
@@ -552,9 +601,9 @@ void ELFBuilder<ELFT>::initSymbolTable(S
       }
     } else if (Sym.st_shndx != SHN_UNDEF) {
       DefSection = Obj.sections().getSection(
-          Sym.st_shndx,
-          "Symbol '" + Name + "' is defined in invalid section with index " +
-              Twine(Sym.st_shndx));
+          Sym.st_shndx, "Symbol '" + Name +
+                            "' is defined in invalid section with index " +
+                            Twine(Sym.st_shndx));
     }
 
     SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
@@ -623,6 +672,9 @@ SectionBase &ELFBuilder<ELFT>::makeSecti
     // Because of this we don't need to mess with the hash tables either.
     Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
     return Obj.addSection<Section>(Data);
+  case SHT_GROUP:
+    Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
+    return Obj.addSection<GroupSection>(Data);
   case SHT_DYNSYM:
     Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
     return Obj.addSection<DynamicSymbolTableSection>(Data);

Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=328012&r1=328011&r2=328012&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Tue Mar 20 11:20:42 2018
@@ -35,17 +35,17 @@ class SymbolTableSection;
 class RelocationSection;
 class DynamicRelocationSection;
 class GnuDebugLinkSection;
+class GroupSection;
 class Segment;
 class Object;
 
 class SectionTableRef {
-private:
   MutableArrayRef<std::unique_ptr<SectionBase>> Sections;
 
 public:
   using iterator = pointee_iterator<std::unique_ptr<SectionBase> *>;
 
-  SectionTableRef(MutableArrayRef<std::unique_ptr<SectionBase>> Secs)
+  explicit SectionTableRef(MutableArrayRef<std::unique_ptr<SectionBase>> Secs)
       : Sections(Secs) {}
   SectionTableRef(const SectionTableRef &) = default;
 
@@ -71,6 +71,7 @@ public:
   virtual void visit(const RelocationSection &Sec) = 0;
   virtual void visit(const DynamicRelocationSection &Sec) = 0;
   virtual void visit(const GnuDebugLinkSection &Sec) = 0;
+  virtual void visit(const GroupSection &Sec) = 0;
 };
 
 class SectionWriter : public SectionVisitor {
@@ -87,6 +88,7 @@ public:
   virtual void visit(const SymbolTableSection &Sec) override = 0;
   virtual void visit(const RelocationSection &Sec) override = 0;
   virtual void visit(const GnuDebugLinkSection &Sec) override = 0;
+  virtual void visit(const GroupSection &Sec) override = 0;
 
   SectionWriter(FileOutputBuffer &Buf) : Out(Buf) {}
 };
@@ -102,6 +104,7 @@ public:
   void visit(const SymbolTableSection &Sec) override;
   void visit(const RelocationSection &Sec) override;
   void visit(const GnuDebugLinkSection &Sec) override;
+  void visit(const GroupSection &Sec) override;
 
   ELFSectionWriter(FileOutputBuffer &Buf) : SectionWriter(Buf) {}
 };
@@ -117,6 +120,8 @@ public:
   void visit(const SymbolTableSection &Sec) override;
   void visit(const RelocationSection &Sec) override;
   void visit(const GnuDebugLinkSection &Sec) override;
+  void visit(const GroupSection &Sec) override;
+
   BinarySectionWriter(FileOutputBuffer &Buf) : SectionWriter(Buf) {}
 };
 
@@ -237,7 +242,7 @@ public:
   uint64_t OriginalOffset;
   Segment *ParentSegment = nullptr;
 
-  Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
+  explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
   Segment() {}
 
   const SectionBase *firstSection() const {
@@ -253,11 +258,10 @@ public:
 class Section : public SectionBase {
   MAKE_SEC_WRITER_FRIEND
 
-private:
   ArrayRef<uint8_t> Contents;
 
 public:
-  Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
+  explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
 
   void accept(SectionVisitor &Visitor) const override;
 };
@@ -265,7 +269,6 @@ public:
 class OwnedDataSection : public SectionBase {
   MAKE_SEC_WRITER_FRIEND
 
-private:
   std::vector<uint8_t> Data;
 
 public:
@@ -291,7 +294,6 @@ public:
 class StringTableSection : public SectionBase {
   MAKE_SEC_WRITER_FRIEND
 
-private:
   StringTableBuilder StrTabBuilder;
 
 public:
@@ -344,6 +346,7 @@ class SymbolTableSection : public Sectio
   MAKE_SEC_WRITER_FRIEND
 
   void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
+  void assignIndices();
 
 protected:
   std::vector<std::unique_ptr<Symbol>> Symbols;
@@ -402,7 +405,6 @@ public:
 // that code between the two symbol table types.
 template <class SymTabType>
 class RelocSectionWithSymtabBase : public RelocationSectionBase {
-private:
   SymTabType *Symbols = nullptr;
   void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
 
@@ -419,7 +421,6 @@ class RelocationSection
     : public RelocSectionWithSymtabBase<SymbolTableSection> {
   MAKE_SEC_WRITER_FRIEND
 
-private:
   std::vector<Relocation> Relocations;
 
 public:
@@ -433,14 +434,37 @@ public:
   }
 };
 
-class SectionWithStrTab : public Section {
-private:
-  const SectionBase *StrTab = nullptr;
+// TODO: The way stripping and groups interact is complicated
+// and still needs to be worked on.
+
+class GroupSection : public SectionBase {
+  MAKE_SEC_WRITER_FRIEND
+  // TODO: Contents is present in several classes of the hierarchy.
+  // This needs to be refactored to avoid duplication.
+  ArrayRef<uint8_t> Contents;
+  ELF::Elf32_Word FlagWord;
+  SmallVector<SectionBase *, 3> GroupMembers;
+  const SymbolTableSection *SymTab = nullptr;
+  const Symbol *Sym = nullptr;
 
 public:
-  SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {}
+  explicit GroupSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
+
+  void initialize(SectionTableRef SecTable) override;
+  void accept(SectionVisitor &) const override;
+  void finalize() override;
+
+  static bool classof(const SectionBase *S) {
+    return S->Type == ELF::SHT_GROUP;
+  }
+};
 
+class SectionWithStrTab : public Section {
+  const SectionBase *StrTab = nullptr;
   void setStrTab(const SectionBase *StringTable) { StrTab = StringTable; }
+
+public:
+  explicit SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {}
   void removeSectionReferences(const SectionBase *Sec) override;
   void initialize(SectionTableRef SecTable) override;
   void finalize() override;
@@ -449,7 +473,8 @@ public:
 
 class DynamicSymbolTableSection : public SectionWithStrTab {
 public:
-  DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
+  explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data)
+      : SectionWithStrTab(Data) {}
 
   static bool classof(const SectionBase *S) {
     return S->Type == ELF::SHT_DYNSYM;
@@ -458,7 +483,7 @@ public:
 
 class DynamicSection : public SectionWithStrTab {
 public:
-  DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
+  explicit DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
 
   static bool classof(const SectionBase *S) {
     return S->Type == ELF::SHT_DYNAMIC;
@@ -473,7 +498,7 @@ private:
   ArrayRef<uint8_t> Contents;
 
 public:
-  DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
+  explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
 
   void accept(SectionVisitor &) const override;
 
@@ -488,7 +513,6 @@ class GnuDebugLinkSection : public Secti
   MAKE_SEC_WRITER_FRIEND
 
 private:
-
   StringRef FileName;
   uint32_t CRC32;
 
@@ -496,7 +520,7 @@ private:
 
 public:
   // If we add this section from an external source we can use this ctor.
-  GnuDebugLinkSection(StringRef File);
+  explicit GnuDebugLinkSection(StringRef File);
   void accept(SectionVisitor &Visitor) const override;
 };
 
@@ -506,10 +530,10 @@ public:
   virtual std::unique_ptr<Object> create() const = 0;
 };
 
-using object::OwningBinary;
 using object::Binary;
 using object::ELFFile;
 using object::ELFObjectFile;
+using object::OwningBinary;
 
 template <class ELFT> class ELFBuilder {
 private:
@@ -582,7 +606,8 @@ public:
   StringTableSection *SectionNames = nullptr;
   SymbolTableSection *SymbolTable = nullptr;
 
-  Object(std::shared_ptr<MemoryBuffer> Data) : OwnedData(Data) {}
+  explicit Object(std::shared_ptr<MemoryBuffer> Data)
+      : OwnedData(std::move(Data)) {}
   virtual ~Object() = default;
 
   void sortSections();




More information about the llvm-commits mailing list