[llvm] r354338 - [yaml2obj][obj2yaml] - Support SHT_GNU_versym (.gnu.version) section.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 19 07:29:07 PST 2019


Author: grimar
Date: Tue Feb 19 07:29:07 2019
New Revision: 354338

URL: http://llvm.org/viewvc/llvm-project?rev=354338&view=rev
Log:
[yaml2obj][obj2yaml] - Support SHT_GNU_versym (.gnu.version) section.

This patch adds support for parsing dumping the .gnu.version section.
Description of the section is: https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/symversion.html#SYMVERTBL

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

Added:
    llvm/trunk/test/tools/obj2yaml/versym-section.yaml
    llvm/trunk/test/tools/yaml2obj/versym-section.yaml
Modified:
    llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
    llvm/trunk/tools/obj2yaml/elf2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h?rev=354338&r1=354337&r2=354338&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h Tue Feb 19 07:29:07 2019
@@ -122,6 +122,7 @@ struct Section {
     Relocation,
     NoBits,
     Verneed,
+    Symver,
     MipsABIFlags
   };
   SectionKind Kind;
@@ -192,6 +193,16 @@ struct VerneedSection : Section {
   }
 };
 
+struct SymverSection : Section {
+  std::vector<uint16_t> Entries;
+
+  SymverSection() : Section(SectionKind::Symver) {}
+
+  static bool classof(const Section *S) {
+    return S->Kind == SectionKind::Symver;
+  }
+};
+
 struct Group : Section {
   // Members of a group contain a flag and a list of section indices
   // that are part of the group.

Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=354338&r1=354337&r2=354338&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Tue Feb 19 07:29:07 2019
@@ -872,6 +872,11 @@ static void sectionMapping(IO &IO, ELFYA
   IO.mapOptional("Size", Section.Size, Hex64(0));
 }
 
+static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
+  commonSectionMapping(IO, Section);
+  IO.mapRequired("Entries", Section.Entries);
+}
+
 static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapRequired("Info", Section.Info);
@@ -955,6 +960,11 @@ void MappingTraits<std::unique_ptr<ELFYA
       Section.reset(new ELFYAML::MipsABIFlags());
     sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
     break;
+  case ELF::SHT_GNU_versym:
+    if (!IO.outputting())
+      Section.reset(new ELFYAML::SymverSection());
+    sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
+    break;
   case ELF::SHT_GNU_verneed:
     if (!IO.outputting())
       Section.reset(new ELFYAML::VerneedSection());

Added: llvm/trunk/test/tools/obj2yaml/versym-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/versym-section.yaml?rev=354338&view=auto
==============================================================================
--- llvm/trunk/test/tools/obj2yaml/versym-section.yaml (added)
+++ llvm/trunk/test/tools/obj2yaml/versym-section.yaml Tue Feb 19 07:29:07 2019
@@ -0,0 +1,48 @@
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t | FileCheck %s
+
+## Check we are able to yamalize the SHT_GNU_versym section.
+
+# CHECK:      --- !ELF
+# CHECK-NEXT: FileHeader:
+# CHECK-NEXT:   Class:           ELFCLASS64
+# CHECK-NEXT:   Data:            ELFDATA2LSB
+# CHECK-NEXT:   Type:            ET_EXEC
+# CHECK-NEXT:   Machine:         EM_X86_64
+# CHECK-NEXT:   Entry:           0x0000000000201000
+# CHECK-NEXT: Sections:
+# CHECK-NEXT:   - Name:            .gnu.version
+# CHECK-NEXT:     Type:            SHT_GNU_versym
+# CHECK-NEXT:     Flags:           [ SHF_ALLOC ]
+# CHECK-NEXT:     Address:         0x0000000000200210
+# CHECK-NEXT:     Link:            .dynsym
+# CHECK-NEXT:     AddressAlign:    0x0000000000000002
+# CHECK-NEXT:     EntSize:         0x0000000000000002
+# CHECK-NEXT:     Entries:         [ 0, 3, 4 ]
+# CHECK-NEXT: Symbols:         {}
+# CHECK-NEXT: DynamicSymbols:
+# CHECK-NEXT:   Global:
+# CHECK-NEXT:     - Name:            f1
+# CHECK-NEXT:     - Name:            f2
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x0000000000201000
+Sections:
+  - Name:            .gnu.version
+    Type:            SHT_GNU_versym
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200210
+    Link:            .dynsym
+    AddressAlign:    0x0000000000000002
+    EntSize:         0x0000000000000002
+    Entries:         [ 0, 3, 4 ]
+DynamicSymbols:
+  Global:
+    - Name:            f1
+    - Name:            f2
+...

Added: llvm/trunk/test/tools/yaml2obj/versym-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/versym-section.yaml?rev=354338&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/versym-section.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/versym-section.yaml Tue Feb 19 07:29:07 2019
@@ -0,0 +1,88 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readelf -V %t | FileCheck %s
+
+## Check we are able to produce a valid SHT_GNU_versym
+## section from its description.
+
+# CHECK:      Version symbols {
+# CHECK-NEXT:   Section Name: .gnu.version
+# CHECK-NEXT:   Address: 0x200210
+# CHECK-NEXT:   Offset: 0x240
+# CHECK-NEXT:   Link: 6
+# CHECK-NEXT:   Symbols [
+# CHECK-NEXT:     Symbol {
+# CHECK-NEXT:       Version: 0
+# CHECK-NEXT:       Name:
+# CHECK-NEXT:     }
+# CHECK-NEXT:     Symbol {
+# CHECK-NEXT:       Version: 3
+# CHECK-NEXT:       Name: f1 at v1
+# CHECK-NEXT:     }
+# CHECK-NEXT:     Symbol {
+# CHECK-NEXT:       Version: 4
+# CHECK-NEXT:       Name: f2 at v2
+# CHECK-NEXT:     }
+# CHECK-NEXT:   ]
+# CHECK-NEXT: }
+# CHECK-NEXT: SHT_GNU_verdef {
+# CHECK-NEXT: }
+# CHECK-NEXT: SHT_GNU_verneed {
+# CHECK-NEXT:   Dependency {
+# CHECK-NEXT:     Version: 1
+# CHECK-NEXT:     Count: 2
+# CHECK-NEXT:     FileName: dso.so.0
+# CHECK-NEXT:     Entry {
+# CHECK-NEXT:       Hash: 1937
+# CHECK-NEXT:       Flags: 0x0
+# CHECK-NEXT:       Index: 3
+# CHECK-NEXT:       Name: v1
+# CHECK-NEXT:     }
+# CHECK-NEXT:     Entry {
+# CHECK-NEXT:       Hash: 1938
+# CHECK-NEXT:       Flags: 0x0
+# CHECK-NEXT:       Index: 4
+# CHECK-NEXT:       Name: v2
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT: }
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x0000000000201000
+Sections:
+  - Name:            .gnu.version
+    Type:            SHT_GNU_versym
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200210
+    Link:            .dynsym
+    AddressAlign:    0x0000000000000002
+    EntSize:         0x0000000000000002
+    Entries:         [ 0, 3, 4 ]
+  - Name:            .gnu.version_r
+    Type:            SHT_GNU_verneed
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200250
+    Link:            .dynstr
+    AddressAlign:    0x0000000000000004
+    Info:            0x0000000000000001
+    Dependencies:
+      - Version:         1
+        File:            dso.so.0
+        Entries:         
+          - Name:            v1
+            Hash:            1937
+            Flags:           0
+            Other:           3
+          - Name:            v2
+            Hash:            1938
+            Flags:           0
+            Other:           4
+DynamicSymbols:
+  Global:
+    - Name:            f1
+    - Name:            f2
+...

Modified: llvm/trunk/tools/obj2yaml/elf2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/elf2yaml.cpp?rev=354338&r1=354337&r2=354338&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/elf2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/elf2yaml.cpp Tue Feb 19 07:29:07 2019
@@ -57,6 +57,7 @@ class ELFDumper {
   ErrorOr<ELFYAML::RawContentSection *>
   dumpContentSection(const Elf_Shdr *Shdr);
   ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
+  ErrorOr<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
   ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
   ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
   ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
@@ -185,6 +186,13 @@ template <class ELFT> ErrorOr<ELFYAML::O
       Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
       break;
     }
+    case ELF::SHT_GNU_versym: {
+      ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
+      if (std::error_code EC = S.getError())
+        return EC;
+      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
+      break;
+    }
     case ELF::SHT_GNU_verneed: {
       ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec);
       if (std::error_code EC = S.getError())
@@ -450,6 +458,24 @@ ELFDumper<ELFT>::dumpNoBitsSection(const
 
   return S.release();
 }
+
+template <class ELFT>
+ErrorOr<ELFYAML::SymverSection *>
+ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
+  typedef typename ELFT::Half Elf_Half;
+
+  auto S = make_unique<ELFYAML::SymverSection>();
+  if (std::error_code EC = dumpCommonSection(Shdr, *S))
+    return EC;
+
+  auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
+  if (!VersionsOrErr)
+    return errorToErrorCode(VersionsOrErr.takeError());
+  for (const Elf_Half &E : *VersionsOrErr)
+    S->Entries.push_back(E);
+
+  return S.release();
+}
 
 template <class ELFT>
 ErrorOr<ELFYAML::VerneedSection *>

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=354338&r1=354337&r2=354338&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Tue Feb 19 07:29:07 2019
@@ -157,6 +157,9 @@ class ELFState {
   bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
                            ContiguousBlobAccumulator &CBA);
   bool writeSectionContent(Elf_Shdr &SHeader,
+                           const ELFYAML::SymverSection &Section,
+                           ContiguousBlobAccumulator &CBA);
+  bool writeSectionContent(Elf_Shdr &SHeader,
                            const ELFYAML::VerneedSection &Section,
                            ContiguousBlobAccumulator &CBA);
   bool writeSectionContent(Elf_Shdr &SHeader,
@@ -303,6 +306,8 @@ bool ELFState<ELFT>::initSectionHeaders(
       CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
     } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
       writeSectionContent(SHeader, *S, CBA);
+    } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) {
+      writeSectionContent(SHeader, *S, CBA);
     } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
       writeSectionContent(SHeader, *S, CBA);
     } else
@@ -567,6 +572,24 @@ bool ELFState<ELFT>::writeSectionContent
   return true;
 }
 
+template <class ELFT>
+bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+                                         const ELFYAML::SymverSection &Section,
+                                         ContiguousBlobAccumulator &CBA) {
+  typedef typename ELFT::Half Elf_Half;
+
+  raw_ostream &OS =
+      CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+  for (uint16_t V : Section.Entries) {
+    Elf_Half Version = (Elf_Half)V;
+    OS.write((const char *)&Version, sizeof(Elf_Half));
+  }
+
+  SHeader.sh_size = Section.Entries.size() * sizeof(Elf_Half);
+  SHeader.sh_entsize = sizeof(Elf_Half);
+  return true;
+}
+
 template <class ELFT>
 bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
                                          const ELFYAML::VerneedSection &Section,




More information about the llvm-commits mailing list