[llvm] r366677 - [yaml2obj] - Change how we handle implicit sections.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 22 05:01:53 PDT 2019


Author: grimar
Date: Mon Jul 22 05:01:52 2019
New Revision: 366677

URL: http://llvm.org/viewvc/llvm-project?rev=366677&view=rev
Log:
[yaml2obj] - Change how we handle implicit sections.

Instead of having the special list of implicit sections,
that are mixed with the sections read from YAML on late
stages, I just create the placeholders and add them to
the main sections list early.

That allows to significantly simplify the code.

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

Modified:
    llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
    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=366677&r1=366676&r2=366677&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h Mon Jul 22 05:01:52 2019
@@ -148,7 +148,12 @@ struct Section {
   // content written.
   Optional<llvm::yaml::Hex64> ShSize;
 
-  Section(SectionKind Kind) : Kind(Kind) {}
+  // Usually sections are not created implicitly, but loaded from YAML.
+  // When they are, this flag is used to signal about that.
+  bool IsImplicit;
+
+  Section(SectionKind Kind, bool IsImplicit = false)
+      : Kind(Kind), IsImplicit(IsImplicit) {}
   virtual ~Section();
 };
 

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=366677&r1=366676&r2=366677&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Mon Jul 22 05:01:52 2019
@@ -17,6 +17,7 @@
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/ObjectYAML/ELFYAML.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/EndianStream.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/WithColor.h"
@@ -130,7 +131,7 @@ class ELFState {
 
   NameToIdxMap SN2I;
   NameToIdxMap SymN2I;
-  const ELFYAML::Object &Doc;
+  ELFYAML::Object &Doc;
 
   bool buildSectionIndex();
   bool buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols);
@@ -174,12 +175,10 @@ class ELFState {
   bool writeSectionContent(Elf_Shdr &SHeader,
                            const ELFYAML::DynamicSection &Section,
                            ContiguousBlobAccumulator &CBA);
-  std::vector<StringRef> implicitSectionNames() const;
-
-  ELFState(const ELFYAML::Object &D) : Doc(D) {}
+  ELFState(ELFYAML::Object &D);
 
 public:
-  static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
+  static int writeELF(raw_ostream &OS, ELFYAML::Object &Doc);
 
 private:
   void finalizeStrings();
@@ -187,6 +186,30 @@ private:
 } // end anonymous namespace
 
 template <class ELFT>
+ELFState<ELFT>::ELFState(ELFYAML::Object &D) : Doc(D) {
+  StringSet<> DocSections;
+  for (std::unique_ptr<ELFYAML::Section> &D : Doc.Sections)
+    if (!D->Name.empty())
+      DocSections.insert(D->Name);
+
+  std::vector<StringRef> ImplicitSections = {".symtab", ".strtab", ".shstrtab"};
+  if (!Doc.DynamicSymbols.empty())
+    ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"});
+
+  // Insert placeholders for implicit sections that are not
+  // defined explicitly in YAML.
+  for (StringRef SecName : ImplicitSections) {
+    if (DocSections.count(SecName))
+      continue;
+
+    std::unique_ptr<ELFYAML::Section> Sec = llvm::make_unique<ELFYAML::Section>(
+        ELFYAML::Section::SectionKind::RawContent, true /*IsImplicit*/);
+    Sec->Name = SecName;
+    Doc.Sections.push_back(std::move(Sec));
+  }
+}
+
+template <class ELFT>
 void ELFState<ELFT>::initELFHeader(Elf_Ehdr &Header) {
   using namespace llvm::ELF;
   zero(Header);
@@ -292,36 +315,28 @@ template <class ELFT>
 bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
                                         std::vector<Elf_Shdr> &SHeaders,
                                         ContiguousBlobAccumulator &CBA) {
-  // Build a list of sections we are going to add implicitly.
-  std::vector<StringRef> ImplicitSections;
-  for (StringRef Name : State.implicitSectionNames())
-    if (State.SN2I.get(Name) > Doc.Sections.size())
-      ImplicitSections.push_back(Name);
-
   // Ensure SHN_UNDEF entry is present. An all-zero section header is a
   // valid SHN_UNDEF entry since SHT_NULL == 0.
-  SHeaders.resize(Doc.Sections.size() + ImplicitSections.size() + 1);
+  SHeaders.resize(Doc.Sections.size() + 1);
   zero(SHeaders[0]);
 
-  for (size_t I = 1; I < Doc.Sections.size() + ImplicitSections.size() + 1; ++I) {
+  for (size_t I = 1; I < Doc.Sections.size() + 1; ++I) {
     Elf_Shdr &SHeader = SHeaders[I];
     zero(SHeader);
-    ELFYAML::Section *Sec =
-        I > Doc.Sections.size() ? nullptr : Doc.Sections[I - 1].get();
+    ELFYAML::Section *Sec = Doc.Sections[I - 1].get();
 
     // We have a few sections like string or symbol tables that are usually
     // added implicitly to the end. However, if they are explicitly specified
     // in the YAML, we need to write them here. This ensures the file offset
     // remains correct.
-    StringRef SecName =
-        Sec ? Sec->Name : ImplicitSections[I - Doc.Sections.size() - 1];
-    if (initImplicitHeader(State, CBA, SHeader, SecName, Sec))
+    if (initImplicitHeader(State, CBA, SHeader, Sec->Name,
+                           Sec->IsImplicit ? nullptr : Sec))
       continue;
 
     assert(Sec && "It can't be null unless it is an implicit section. But all "
                   "implicit sections should already have been handled above.");
 
-    SHeader.sh_name = DotShStrtab.getOffset(dropUniqueSuffix(SecName));
+    SHeader.sh_name = DotShStrtab.getOffset(dropUniqueSuffix(Sec->Name));
     SHeader.sh_type = Sec->Type;
     if (Sec->Flags)
       SHeader.sh_flags = *Sec->Flags;
@@ -940,15 +955,6 @@ template <class ELFT> bool ELFState<ELFT
     }
   }
 
-  auto SecNo = 1 + Doc.Sections.size();
-  // Add special sections after input sections, if necessary.
-  for (StringRef Name : implicitSectionNames())
-    if (SN2I.addName(Name, SecNo)) {
-      // Account for this section, since it wasn't in the Doc
-      ++SecNo;
-      DotShStrtab.add(Name);
-    }
-
   DotShStrtab.finalize();
   return true;
 }
@@ -1007,7 +1013,7 @@ template <class ELFT> void ELFState<ELFT
 }
 
 template <class ELFT>
-int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
+int ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
   ELFState<ELFT> State(Doc);
 
   // Finalize .strtab and .dynstr sections. We do that early because want to
@@ -1050,13 +1056,6 @@ int ELFState<ELFT>::writeELF(raw_ostream
   return 0;
 }
 
-template <class ELFT>
-std::vector<StringRef> ELFState<ELFT>::implicitSectionNames() const {
-  if (Doc.DynamicSymbols.empty())
-    return {".symtab", ".strtab", ".shstrtab"};
-  return {".symtab", ".strtab", ".shstrtab", ".dynsym", ".dynstr"};
-}
-
 int yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) {
   bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
   bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);




More information about the llvm-commits mailing list