[llvm-readobj] Fix "Section" output when emitting relocations in JSON
authorPaul Kirth <paulkirth@google.com>
Sat, 18 Mar 2023 00:05:41 +0000 (00:05 +0000)
committerPaul Kirth <paulkirth@google.com>
Sat, 18 Mar 2023 01:35:50 +0000 (01:35 +0000)
Prior to this patch, the JSON output would emit an invalid key from the
shared LLVM implementation. This caused llvm-readobj to output invalid
JSON. This patch introduces a small helper function to print the
relocation information differently between the LLVM and JSON formats.

Before this patch:

```
    "Relocations": [Section (2) .rel.text {

      {
        "Relocation": {
          "Offset": 0,
          "Type": {
            "Value": "R_X86_64_NONE",
            "RawValue": 0
          },
          "Symbol": {
            "Value": "rel_0",
            "RawValue": 1
          }
        }
      },
      ...

```

After this patch:

```
   "Relocations": [
      {
        "SectionIdx": 2,
        "Relocs": [
          {
            "Relocation": {
              "Offset": 0,
              "Type": {
                "Name": "R_X86_64_NONE",
                "Value": 0
              },
              "Symbol": {
                "Name": "rel_0",
                "Value": 1
              }
            }
          },
          ...
```

Reviewed By: jhenderson

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

llvm/test/tools/llvm-readobj/ELF/relocations.test
llvm/tools/llvm-readobj/ELFDumper.cpp

index 34a610b..34cff40 100644 (file)
 # RUN: llvm-readobj -r --expand-relocs %t64 --elf-output-style=JSON --pretty-print \
 # RUN:   | FileCheck %s --check-prefix=JSON-EXPAND-64
 
-# JSON-EXPAND-64:      "Relocations": [Section (2) .rel.text {
-# JSON-EXPAND-64:        "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 0,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_NONE",
-# JSON-EXPAND-64-NEXT:       "Value": 0
+# JSON-EXPAND-64:      "Relocations": [
+# JSON-EXPAND-64-NEXT:   {
+# JSON-EXPAND-64-NEXT:   "SectionIndex": 2
+# JSON-EXPAND-64-NEXT:   "Relocs": [
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 0,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_NONE",
+# JSON-EXPAND-64-NEXT:           "Value": 0
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rel_0",
+# JSON-EXPAND-64-NEXT:           "Value": 1
+# JSON-EXPAND-64-NEXT:         }
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rel_0",
-# JSON-EXPAND-64-NEXT:       "Value": 1
-# JSON-EXPAND-64-NEXT:     }
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 1,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_PC32",
-# JSON-EXPAND-64-NEXT:       "Value": 2
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rel_neg",
-# JSON-EXPAND-64-NEXT:       "Value": 2
-# JSON-EXPAND-64-NEXT:     }
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 5,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_PLT32",
-# JSON-EXPAND-64-NEXT:       "Value": 4
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 1,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_PC32",
+# JSON-EXPAND-64-NEXT:           "Value": 2
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rel_neg",
+# JSON-EXPAND-64-NEXT:           "Value": 2
+# JSON-EXPAND-64-NEXT:         }
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rel_pos",
-# JSON-EXPAND-64-NEXT:       "Value": 3
-# JSON-EXPAND-64-NEXT:     }
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 9,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_64",
-# JSON-EXPAND-64-NEXT:       "Value": 1
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 5,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_PLT32",
+# JSON-EXPAND-64-NEXT:           "Value": 4
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rel_pos",
+# JSON-EXPAND-64-NEXT:           "Value": 3
+# JSON-EXPAND-64-NEXT:         }
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rel_64",
-# JSON-EXPAND-64-NEXT:       "Value": 4
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 9,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_64",
+# JSON-EXPAND-64-NEXT:           "Value": 1
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rel_64",
+# JSON-EXPAND-64-NEXT:           "Value": 4
+# JSON-EXPAND-64-NEXT:         }
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     }
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: }}
-# JSON-EXPAND-64-NEXT: Section (3) .rela.text {
-# JSON-EXPAND-64-NEXT: ,
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 0,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_NONE",
-# JSON-EXPAND-64-NEXT:       "Value": 0
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rela_0",
-# JSON-EXPAND-64-NEXT:       "Value": 5
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Addend": 0
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 1,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_PC32",
-# JSON-EXPAND-64-NEXT:       "Value": 2
+# JSON-EXPAND-64-NEXT:    ]
+# JSON-EXPAND-64-NEXT:   },
+# JSON-EXPAND-64-NEXT:   {
+# JSON-EXPAND-64-NEXT:   "SectionIndex": 3,
+# JSON-EXPAND-64-NEXT:   "Relocs": [
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 0,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_NONE",
+# JSON-EXPAND-64-NEXT:           "Value": 0
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rela_0",
+# JSON-EXPAND-64-NEXT:           "Value": 5
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Addend": 0
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rela_neg",
-# JSON-EXPAND-64-NEXT:       "Value": 6
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 1,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_PC32",
+# JSON-EXPAND-64-NEXT:           "Value": 2
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rela_neg",
+# JSON-EXPAND-64-NEXT:           "Value": 6
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Addend": 18446744073709551615
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Addend": 18446744073709551615
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 5,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_PLT32",
-# JSON-EXPAND-64-NEXT:       "Value": 4
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 5,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_PLT32",
+# JSON-EXPAND-64-NEXT:           "Value": 4
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rela_pos",
+# JSON-EXPAND-64-NEXT:           "Value": 7
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Addend": 2
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rela_pos",
-# JSON-EXPAND-64-NEXT:       "Value": 7
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 18446744073709551615,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_64",
+# JSON-EXPAND-64-NEXT:           "Value": 1
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rela_minneg",
+# JSON-EXPAND-64-NEXT:           "Value": 8
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Addend": 9223372036854775808
+# JSON-EXPAND-64-NEXT:       }
 # JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Addend": 2
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 18446744073709551615,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_64",
-# JSON-EXPAND-64-NEXT:       "Value": 1
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rela_minneg",
-# JSON-EXPAND-64-NEXT:       "Value": 8
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Addend": 9223372036854775808
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: },
-# JSON-EXPAND-64-NEXT: {
-# JSON-EXPAND-64-NEXT:   "Relocation": {
-# JSON-EXPAND-64-NEXT:     "Offset": 9,
-# JSON-EXPAND-64-NEXT:     "Type": {
-# JSON-EXPAND-64-NEXT:       "Name": "R_X86_64_32S",
-# JSON-EXPAND-64-NEXT:       "Value": 11
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Symbol": {
-# JSON-EXPAND-64-NEXT:       "Name": "rela_maxpos",
-# JSON-EXPAND-64-NEXT:       "Value": 9
-# JSON-EXPAND-64-NEXT:     },
-# JSON-EXPAND-64-NEXT:     "Addend": 9223372036854775807
-# JSON-EXPAND-64-NEXT:   }
-# JSON-EXPAND-64-NEXT: }}
+# JSON-EXPAND-64-NEXT:     {
+# JSON-EXPAND-64-NEXT:       "Relocation": {
+# JSON-EXPAND-64-NEXT:         "Offset": 9,
+# JSON-EXPAND-64-NEXT:         "Type": {
+# JSON-EXPAND-64-NEXT:           "Name": "R_X86_64_32S",
+# JSON-EXPAND-64-NEXT:           "Value": 11
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Symbol": {
+# JSON-EXPAND-64-NEXT:           "Name": "rela_maxpos",
+# JSON-EXPAND-64-NEXT:           "Value": 9
+# JSON-EXPAND-64-NEXT:         },
+# JSON-EXPAND-64-NEXT:         "Addend": 9223372036854775807
+# JSON-EXPAND-64-NEXT:       }
+# JSON-EXPAND-64-NEXT:     }
+# JSON-EXPAND-64-NEXT:    ]
+# JSON-EXPAND-64-NEXT:  }
+# JSON-EXPAND-64-NEXT: ]
 
 --- !ELF
 FileHeader:
index a0911de..7ff1435 100644 (file)
@@ -719,6 +719,8 @@ protected:
   virtual void printDefaultRelRelaReloc(const Relocation<ELFT> &R,
                                         StringRef SymbolName,
                                         StringRef RelocName);
+  virtual void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,
+                                          const unsigned SecNdx);
 
   ScopedPrinter &W;
 };
@@ -741,6 +743,9 @@ public:
                                 StringRef SymbolName,
                                 StringRef RelocName) override;
 
+  void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,
+                                  const unsigned SecNdx) override;
+
 private:
   std::unique_ptr<DictScope> FileScope;
 };
@@ -6741,11 +6746,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() {
 
     StringRef Name = this->getPrintableSectionName(Sec);
     unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front();
-    W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n";
-    W.indent();
-    this->printRelocationsHelper(Sec);
-    W.unindent();
-    W.startLine() << "}\n";
+    printRelocationSectionInfo(Sec, Name, SecNdx);
   }
 }
 
@@ -6779,6 +6780,14 @@ void LLVMELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R,
 }
 
 template <class ELFT>
+void LLVMELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,
+                                                     StringRef Name,
+                                                     const unsigned SecNdx) {
+  DictScope D(W, (Twine("Section (") + Twine(SecNdx) + ") " + Name).str());
+  this->printRelocationsHelper(Sec);
+}
+
+template <class ELFT>
 void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
                                             const RelSymbol<ELFT> &RelSym) {
   StringRef SymbolName = RelSym.Name;
@@ -7714,3 +7723,13 @@ void JSONELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R,
                                                    StringRef RelocName) {
   this->printExpandedRelRelaReloc(R, SymbolName, RelocName);
 }
+
+template <class ELFT>
+void JSONELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,
+                                                     StringRef Name,
+                                                     const unsigned SecNdx) {
+  DictScope Group(this->W);
+  this->W.printNumber("SectionIndex", SecNdx);
+  ListScope D(this->W, "Relocs");
+  this->printRelocationsHelper(Sec);
+}