[llvm] r317789 - Reapply: Allow yaml2obj to order implicit sections for ELF

Dave Lee via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 06:53:43 PST 2017


Author: kastiglione
Date: Thu Nov  9 06:53:43 2017
New Revision: 317789

URL: http://llvm.org/viewvc/llvm-project?rev=317789&view=rev
Log:
Reapply: Allow yaml2obj to order implicit sections for ELF

Summary:
This change allows yaml input to control the order of implicitly added sections
(`.symtab`, `.strtab`, `.shstrtab`). The order is controlled by adding a
placeholder section of the given name to the Sections field.

This change is to support changes in D39582, where it is desirable to control
the location of the `.dynsym` section.

This reapplied version fixes:
  1. use of a function call within an assert
  2. failing lld test which has an unnamed section
  3. incorrect section count when given an unnamed section

Additionally, one more test to cover the unnamed section failure.

Reviewers: compnerd, jakehehrlich

Reviewed By: jakehehrlich

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D39749

Added:
    llvm/trunk/test/tools/yaml2obj/section-ordering.yaml
    llvm/trunk/test/tools/yaml2obj/unnamed-section.yaml
Modified:
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=317789&r1=317788&r2=317789&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Thu Nov  9 06:53:43 2017
@@ -388,7 +388,7 @@ void ScalarEnumerationTraits<ELFYAML::EL
 #define ECase(X) IO.enumCase(Value, #X, ELF::X)
   ECase(SHT_NULL);
   ECase(SHT_PROGBITS);
-  // No SHT_SYMTAB. Use the top-level `Symbols` key instead.
+  ECase(SHT_SYMTAB);
   // FIXME: Issue a diagnostic with this information.
   ECase(SHT_STRTAB);
   ECase(SHT_RELA);

Added: llvm/trunk/test/tools/yaml2obj/section-ordering.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/section-ordering.yaml?rev=317789&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/section-ordering.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/section-ordering.yaml Thu Nov  9 06:53:43 2017
@@ -0,0 +1,29 @@
+# Ensures that implicitly added sections can be ordered within Sections.
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj -sections %t | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name:            .symtab
+    Type:            SHT_SYMTAB
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_WRITE ]
+  - Name:            .shstrtab
+    Type:            SHT_STRTAB
+  - Name:            .strtab
+    Type:            SHT_STRTAB
+
+# CHECK: Name: .text
+# CHECK: Name: .symtab
+# CHECK: Name: .data
+# CHECK: Name: .shstrtab
+# CHECK: Name: .strtab

Added: llvm/trunk/test/tools/yaml2obj/unnamed-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/unnamed-section.yaml?rev=317789&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/unnamed-section.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/unnamed-section.yaml Thu Nov  9 06:53:43 2017
@@ -0,0 +1,22 @@
+# Ensure yaml2obj doesn't crash on unnamed sections
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj -sections %t | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Sections:
+  - Type:            SHT_PROGBITS
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+
+# CHECK: Name:  (
+# CHECK-NEXT: Type: SHT_NULL
+# CHECK: Name:  (
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK: Name: .text
+# CHECK-NEXT: Type: SHT_PROGBITS

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=317789&r1=317788&r2=317789&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Thu Nov  9 06:53:43 2017
@@ -74,6 +74,15 @@ public:
     Idx = I->getValue();
     return false;
   }
+  /// asserts if name is not present in the map
+  unsigned get(StringRef Name) const {
+    unsigned Idx = 0;
+    auto missing = lookup(Name, Idx);
+    (void)missing;
+    assert(!missing && "Expected section not found in index");
+    return Idx;
+  }
+  unsigned size() const { return Map.size(); }
 };
 } // end anonymous namespace
 
@@ -144,19 +153,21 @@ class ELFState {
                            ContiguousBlobAccumulator &CBA);
 
   // - SHT_NULL entry (placed first, i.e. 0'th entry)
-  // - symbol table (.symtab) (placed third to last)
-  // - string table (.strtab) (placed second to last)
-  // - section header string table (.shstrtab) (placed last)
-  unsigned getDotSymTabSecNo() const { return Doc.Sections.size() + 1; }
-  unsigned getDotStrTabSecNo() const { return Doc.Sections.size() + 2; }
-  unsigned getDotShStrTabSecNo() const { return Doc.Sections.size() + 3; }
-  unsigned getSectionCount() const { return Doc.Sections.size() + 4; }
+  // - symbol table (.symtab) (defaults to third to last)
+  // - string table (.strtab) (defaults to second to last)
+  // - section header string table (.shstrtab) (defaults to last)
+  unsigned getDotSymTabSecNo() const { return SN2I.get(".symtab"); }
+  unsigned getDotStrTabSecNo() const { return SN2I.get(".strtab"); }
+  unsigned getDotShStrTabSecNo() const { return SN2I.get(".shstrtab"); }
+  unsigned getSectionCount() const { return SN2I.size() + 1; }
 
   ELFState(const ELFYAML::Object &D) : Doc(D) {}
 
 public:
   static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
 };
+
+static const char * const ImplicitSecNames[] = {".symtab", ".strtab", ".shstrtab"};
 } // end anonymous namespace
 
 template <class ELFT>
@@ -211,10 +222,6 @@ bool ELFState<ELFT>::initSectionHeaders(
   zero(SHeader);
   SHeaders.push_back(SHeader);
 
-  for (const auto &Sec : Doc.Sections)
-    DotShStrtab.add(Sec->Name);
-  DotShStrtab.finalize();
-
   for (const auto &Sec : Doc.Sections) {
     zero(SHeader);
     SHeader.sh_name = DotShStrtab.getOffset(Sec->Name);
@@ -547,14 +554,9 @@ bool ELFState<ELFT>::writeSectionContent
 }
 
 template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
-  SN2I.addName(".symtab", getDotSymTabSecNo());
-  SN2I.addName(".strtab", getDotStrTabSecNo());
-  SN2I.addName(".shstrtab", getDotShStrTabSecNo());
-
   for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
     StringRef Name = Doc.Sections[i]->Name;
-    if (Name.empty())
-      continue;
+    DotShStrtab.add(Name);
     // "+ 1" to take into account the SHT_NULL entry.
     if (SN2I.addName(Name, i + 1)) {
       errs() << "error: Repeated section name: '" << Name
@@ -562,6 +564,17 @@ template <class ELFT> bool ELFState<ELFT
       return false;
     }
   }
+
+  auto SecNo = 1 + Doc.Sections.size();
+  // Add special sections after input sections, if necessary.
+  for (const auto &Name : ImplicitSecNames)
+    if (!SN2I.addName(Name, SecNo)) {
+      // Account for this section, since it wasn't in the Doc
+      ++SecNo;
+      DotShStrtab.add(Name);
+    }
+
+  DotShStrtab.finalize();
   return true;
 }
 
@@ -608,32 +621,22 @@ int ELFState<ELFT>::writeELF(raw_ostream
                                            Header.e_shentsize * Header.e_shnum;
   ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
 
-  // Doc might not contain .symtab, .strtab and .shstrtab sections,
-  // but we will emit them, so make sure to add them to ShStrTabSHeader.
-  State.DotShStrtab.add(".symtab");
-  State.DotShStrtab.add(".strtab");
-  State.DotShStrtab.add(".shstrtab");
-
   std::vector<Elf_Shdr> SHeaders;
   if(!State.initSectionHeaders(SHeaders, CBA))
     return 1;
 
-  // .symtab section.
-  Elf_Shdr SymtabSHeader;
-  State.initSymtabSectionHeader(SymtabSHeader, CBA);
-  SHeaders.push_back(SymtabSHeader);
-
-  // .strtab string table header.
-  Elf_Shdr DotStrTabSHeader;
-  State.initStrtabSectionHeader(DotStrTabSHeader, ".strtab", State.DotStrtab,
-                                CBA);
-  SHeaders.push_back(DotStrTabSHeader);
-
-  // .shstrtab string table header.
-  Elf_Shdr ShStrTabSHeader;
-  State.initStrtabSectionHeader(ShStrTabSHeader, ".shstrtab", State.DotShStrtab,
-                                CBA);
-  SHeaders.push_back(ShStrTabSHeader);
+  // Populate SHeaders with implicit sections not present in the Doc
+  for (const auto &Name : ImplicitSecNames)
+    if (State.SN2I.get(Name) >= SHeaders.size())
+      SHeaders.push_back({});
+
+  // Initialize the implicit sections
+  auto Index = State.SN2I.get(".symtab");
+  State.initSymtabSectionHeader(SHeaders[Index], CBA);
+  Index = State.SN2I.get(".strtab");
+  State.initStrtabSectionHeader(SHeaders[Index], ".strtab", State.DotStrtab, CBA);
+  Index = State.SN2I.get(".shstrtab");
+  State.initStrtabSectionHeader(SHeaders[Index], ".shstrtab", State.DotShStrtab, CBA);
 
   // Now we can decide segment offsets
   State.setProgramHeaderLayout(PHeaders, SHeaders);




More information about the llvm-commits mailing list