[llvm] 14f292d - [llvm-readobj] Output valid JSON for GroupSections

Paul Kirth via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 17 20:14:25 PDT 2023


Author: Paul Kirth
Date: 2023-03-18T03:14:17Z
New Revision: 14f292d00e26cb99909e4d192bc78d7e715ecc8c

URL: https://github.com/llvm/llvm-project/commit/14f292d00e26cb99909e4d192bc78d7e715ecc8c
DIFF: https://github.com/llvm/llvm-project/commit/14f292d00e26cb99909e4d192bc78d7e715ecc8c.diff

LOG: [llvm-readobj] Output valid JSON for GroupSections

The current implementation output the LLVM formatted heading for group
sections, which was not valid JSON. This patch provides two small
customization points that allow the heading to vary between the two
implementations, and another that allows the section members to be
output as valid JSON objects.

Reviewed By: jhenderson

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

Added: 
    

Modified: 
    llvm/test/tools/llvm-readobj/ELF/groups.test
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-readobj/ELF/groups.test b/llvm/test/tools/llvm-readobj/ELF/groups.test
index afa5fb05b91e..8bb80c019ee7 100644
--- a/llvm/test/tools/llvm-readobj/ELF/groups.test
+++ b/llvm/test/tools/llvm-readobj/ELF/groups.test
@@ -4,6 +4,7 @@
 # RUN: yaml2obj %s -o %t.o
 # RUN: llvm-readobj -g %t.o | FileCheck %s
 # RUN: llvm-readobj --elf-section-groups %t.o | FileCheck %s
+# RUN: llvm-readobj --elf-section-groups %t.o --elf-output-style=JSON --pretty-print | FileCheck %s --check-prefix=JSON
 # RUN: llvm-readelf -g %t.o | FileCheck --check-prefix=GNU %s
 
 # CHECK:      Groups {
@@ -41,6 +42,57 @@
 # GNU-NEXT:  [    5] .text.bar
 # GNU-NEXT:  [    6] .rela.text.bar
 
+# JSON:      "Groups": {
+# JSON-NEXT:   "Group": {
+# JSON-NEXT:     "Name": {
+# JSON-NEXT:       "Name": ".group",
+# JSON-NEXT:       "Value": 16
+# JSON-NEXT:     },
+# JSON-NEXT:     "Index": 1,
+# JSON-NEXT:     "Link": 7,
+# JSON-NEXT:     "Info": 1,
+# JSON-NEXT:     "Type": {
+# JSON-NEXT:       "Name": "COMDAT",
+# JSON-NEXT:       "Value": 1
+# JSON-NEXT:     },
+# JSON-NEXT:     "Signature": "foo",
+# JSON-NEXT:     "GroupSections": [
+# JSON-NEXT:       {
+# JSON-NEXT:         "Name": ".text.foo",
+# JSON-NEXT:         "Index": 3
+# JSON-NEXT:       },
+# JSON-NEXT:       {
+# JSON-NEXT:         "Name": ".rela.text.foo",
+# JSON-NEXT:         "Index": 4
+# JSON-NEXT:       }
+# JSON-NEXT:     ]
+# JSON-NEXT:   },
+# JSON-NEXT:   "Group": {
+# JSON-NEXT:     "Name": {
+# JSON-NEXT:       "Name": ".group1",
+# JSON-NEXT:       "Value": 64
+# JSON-NEXT:     },
+# JSON-NEXT:     "Index": 2,
+# JSON-NEXT:     "Link": 7,
+# JSON-NEXT:     "Info": 2,
+# JSON-NEXT:     "Type": {
+# JSON-NEXT:       "Name": "COMDAT",
+# JSON-NEXT:       "Value": 1
+# JSON-NEXT:     },
+# JSON-NEXT:     "Signature": "bar",
+# JSON-NEXT:     "GroupSections": [
+# JSON-NEXT:       {
+# JSON-NEXT:         "Name": ".text.bar",
+# JSON-NEXT:         "Index": 5
+# JSON-NEXT:       },
+# JSON-NEXT:       {
+# JSON-NEXT:         "Name": ".rela.text.bar",
+# JSON-NEXT:         "Index": 6
+# JSON-NEXT:       }
+# JSON-NEXT:     ]
+# JSON-NEXT:   }
+# JSON-NEXT: }
+
 --- !ELF
 FileHeader:
   Class: ELFCLASS64

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 7ff1435fc808..2434aa7b59cf 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -712,6 +712,7 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
   virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;
 
 protected:
+  virtual std::string getGroupSectionHeaderName() const;
   void printSymbolOtherField(const Elf_Sym &Symbol) const;
   virtual void printExpandedRelRelaReloc(const Relocation<ELFT> &R,
                                          StringRef SymbolName,
@@ -721,6 +722,8 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
                                         StringRef RelocName);
   virtual void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,
                                           const unsigned SecNdx);
+  virtual void printSectionGroupMembers(StringRef Name, uint64_t Idx) const;
+  virtual void printEmptyGroupMessage() const;
 
   ScopedPrinter &W;
 };
@@ -734,6 +737,8 @@ template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {
   JSONELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
       : LLVMELFDumper<ELFT>(ObjF, Writer) {}
 
+  std::string getGroupSectionHeaderName() const override;
+
   void printFileSummary(StringRef FileStr, ObjectFile &Obj,
                         ArrayRef<std::string> InputFilenames,
                         const Archive *A) override;
@@ -746,6 +751,10 @@ template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {
   void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,
                                   const unsigned SecNdx) override;
 
+  void printSectionGroupMembers(StringRef Name, uint64_t Idx) const override;
+
+  void printEmptyGroupMessage() const override;
+
 private:
   std::unique_ptr<DictScope> FileScope;
 };
@@ -6717,9 +6726,9 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() {
     W.printNumber("Link", G.Link);
     W.printNumber("Info", G.Info);
     W.printHex("Type", getGroupType(G.Type), G.Type);
-    W.startLine() << "Signature: " << G.Signature << "\n";
+    W.printString("Signature", G.Signature);
 
-    ListScope L(W, "Section(s) in group");
+    ListScope L(W, getGroupSectionHeaderName());
     for (const GroupMember &GM : G.Members) {
       const GroupSection *MainGroup = Map[GM.Index];
       if (MainGroup != &G)
@@ -6729,12 +6738,23 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() {
             Twine(MainGroup->Index) +
             ", was also found in the group section with index " +
             Twine(G.Index));
-      W.startLine() << GM.Name << " (" << GM.Index << ")\n";
+      printSectionGroupMembers(GM.Name, GM.Index);
     }
   }
 
   if (V.empty())
-    W.startLine() << "There are no group sections in the file.\n";
+    printEmptyGroupMessage();
+}
+
+template <class ELFT>
+std::string LLVMELFDumper<ELFT>::getGroupSectionHeaderName() const {
+  return "Section(s) in group";
+}
+
+template <class ELFT>
+void LLVMELFDumper<ELFT>::printSectionGroupMembers(StringRef Name,
+                                                   uint64_t Idx) const {
+  W.startLine() << Name << " (" << Idx << ")\n";
 }
 
 template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() {
@@ -6787,6 +6807,10 @@ void LLVMELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,
   this->printRelocationsHelper(Sec);
 }
 
+template <class ELFT> void LLVMELFDumper<ELFT>::printEmptyGroupMessage() const {
+  W.startLine() << "There are no group sections in the file.\n";
+}
+
 template <class ELFT>
 void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
                                             const RelSymbol<ELFT> &RelSym) {
@@ -7733,3 +7757,20 @@ void JSONELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,
   ListScope D(this->W, "Relocs");
   this->printRelocationsHelper(Sec);
 }
+
+template <class ELFT>
+std::string JSONELFDumper<ELFT>::getGroupSectionHeaderName() const {
+  return "GroupSections";
+}
+
+template <class ELFT>
+void JSONELFDumper<ELFT>::printSectionGroupMembers(StringRef Name,
+                                                   uint64_t Idx) const {
+  DictScope Grp(this->W);
+  this->W.printString("Name", Name);
+  this->W.printNumber("Index", Idx);
+}
+
+template <class ELFT> void JSONELFDumper<ELFT>::printEmptyGroupMessage() const {
+  // JSON output does not need to print anything for empty groups
+}


        


More information about the llvm-commits mailing list