[llvm] [llvm-readobj] Fixes malformed json on JSON printed corefiles (PR #92835)

via llvm-commits llvm-commits at lists.llvm.org
Mon May 20 15:49:11 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: Fred Grim (feg208)

<details>
<summary>Changes</summary>

This patch fixes an issue where, when printing corefile notes with llvm-readobj as json, the dumper generated llvm formatted output which isn't valid json. This alters the dumper to, in the NT_FILE, note use a JSON particular method and dump properly formatted json data.

---
Full diff: https://github.com/llvm/llvm-project/pull/92835.diff


2 Files Affected:

- (modified) llvm/test/tools/llvm-readobj/ELF/note-core-ntfile.test (+38) 
- (modified) llvm/tools/llvm-readobj/ELFDumper.cpp (+27-12) 


``````````diff
diff --git a/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile.test b/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile.test
index 752cb723cd221..dab539821f6de 100644
--- a/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile.test
+++ b/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile.test
@@ -3,6 +3,8 @@
 # RUN: yaml2obj %s -o %t.o
 # RUN: llvm-readelf --notes %t.o | FileCheck %s --check-prefix=GNU
 # RUN: llvm-readobj --notes %t.o | FileCheck %s --check-prefix=LLVM
+# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --notes %t.o | FileCheck %s --check-prefix=JSON
+# RUN: llvm-readobj --elf-output-style=JSON --pretty-print --notes %t.o | FileCheck %s --check-prefix=JSON
 
 ## llvm-mc doesn't support generating ET_CORE files; the 'Content' field was
 ## generated with the following steps:
@@ -93,3 +95,39 @@ ProgramHeaders:
 # LLVM-NEXT:     }
 # LLVM-NEXT:   }
 # LLVM-NEXT: ]
+
+# JSON:      "Notes": [
+# JSON-NEXT:  {
+# JSON-NEXT:      "NoteSection": {
+# JSON-NEXT:          "Name": "<?>",
+# JSON-NEXT:          "Offset": 120,
+# JSON-NEXT:          "Size": 148,
+# JSON-NEXT:          "Note": {
+# JSON-NEXT:              "Owner": "CORE",
+# JSON-NEXT:              "Data size": 128,
+# JSON-NEXT:              "Type": "NT_FILE (mapped files)",
+# JSON-NEXT:              "Page Size": 4096,
+# JSON-NEXT:              "Mappings": [
+# JSON-NEXT:                {
+# JSON-NEXT:                  "Start": 4096,
+# JSON-NEXT:                  "End": 8192,
+# JSON-NEXT:                  "Offset": 12288,
+# JSON-NEXT:                  "Filename": "/path/to/a.out"
+# JSON-NEXT:                },
+# JSON-NEXT:                {
+# JSON-NEXT:                  "Start": 16384,
+# JSON-NEXT:                  "End": 20480,
+# JSON-NEXT:                  "Offset": 24576,
+# JSON-NEXT:                  "Filename": "/path/to/libc.so"
+# JSON-NEXT:                },
+# JSON-NEXT:                {
+# JSON-NEXT:                  "Start": 28672,
+# JSON-NEXT:                  "End": 32768,
+# JSON-NEXT:                  "Offset": 36864,
+# JSON-NEXT:                  "Filename": "[stack]"
+# JSON-NEXT:                }
+# JSON-NEXT:            ]
+# JSON-NEXT:          }
+# JSON-NEXT:      }
+# JSON-NEXT: }
+# JSON-NEXT: ]
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index a752cc4015293..4558dcdf62bfe 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -180,6 +180,16 @@ struct GroupSection {
   std::vector<GroupMember> Members;
 };
 
+struct CoreFileMapping {
+  uint64_t Start, End, Offset;
+  StringRef Filename;
+};
+
+struct CoreNote {
+  uint64_t PageSize;
+  std::vector<CoreFileMapping> Mappings;
+};
+
 namespace {
 
 struct NoteType {
@@ -762,6 +772,7 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
                                           const unsigned SecNdx);
   virtual void printSectionGroupMembers(StringRef Name, uint64_t Idx) const;
   virtual void printEmptyGroupMessage() const;
+  virtual void printCoreNote(const CoreNote &Note, ScopedPrinter &W) const;
 
   ScopedPrinter &W;
 };
@@ -793,6 +804,8 @@ template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {
 
   void printEmptyGroupMessage() const override;
 
+  void printCoreNote(const CoreNote &Note, ScopedPrinter &W) const override;
+
 private:
   std::unique_ptr<DictScope> FileScope;
 };
@@ -5736,16 +5749,6 @@ static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
   }
 }
 
-struct CoreFileMapping {
-  uint64_t Start, End, Offset;
-  StringRef Filename;
-};
-
-struct CoreNote {
-  uint64_t PageSize;
-  std::vector<CoreFileMapping> Mappings;
-};
-
 static Expected<CoreNote> readCoreNote(DataExtractor Desc) {
   // Expected format of the NT_FILE note description:
   // 1. # of file mappings (call it N)
@@ -7838,7 +7841,7 @@ static bool printLLVMOMPOFFLOADNoteLLVMStyle(uint32_t NoteType,
   return true;
 }
 
-static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
+template <class ELFT> void LLVMELFDumper<ELFT>::printCoreNote(const CoreNote &Note, ScopedPrinter &W) const {
   W.printNumber("Page Size", Note.PageSize);
   for (const CoreFileMapping &Mapping : Note.Mappings) {
     ListScope D(W, "Mapping");
@@ -7849,6 +7852,18 @@ static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
   }
 }
 
+template <class ELFT> void JSONELFDumper<ELFT>::printCoreNote(const CoreNote &Note, ScopedPrinter &W) const {
+  W.printNumber("Page Size", Note.PageSize);
+  ListScope D(W, "Mappings");
+  for (const CoreFileMapping &Mapping : Note.Mappings) {
+    auto MappingDict = std::make_unique<DictScope>(W);
+    W.printHex("Start", Mapping.Start);
+    W.printHex("End", Mapping.End);
+    W.printHex("Offset", Mapping.Offset);
+    W.printString("Filename", Mapping.Filename);
+  }
+}
+
 template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
   ListScope L(W, "Notes");
 
@@ -7916,7 +7931,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
             Descriptor, ELFT::Endianness == llvm::endianness::little,
             sizeof(Elf_Addr));
         if (Expected<CoreNote> N = readCoreNote(DescExtractor)) {
-          printCoreNoteLLVMStyle(*N, W);
+          printCoreNote(*N, W);
           return Error::success();
         } else {
           return N.takeError();

``````````

</details>


https://github.com/llvm/llvm-project/pull/92835


More information about the llvm-commits mailing list