[llvm] r368698 - [llvm-readelf] Implement note parsing for NT_FILE and unknown descriptors

Jordan Rupprecht via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 13 07:38:45 PDT 2019


Author: rupprecht
Date: Tue Aug 13 07:38:45 2019
New Revision: 368698

URL: http://llvm.org/viewvc/llvm-project?rev=368698&view=rev
Log:
[llvm-readelf] Implement note parsing for NT_FILE and unknown descriptors

Summary:
This patch implements two note parsers; one for NT_FILE coredumps, e.g.:

```
  CORE                  0x00000080      NT_FILE (mapped files)
    Page size: 4096
                 Start                 End         Page Offset
    0x0000000000001000  0x0000000000002000  0x0000000000003000
        /path/to/a.out
    0x0000000000004000  0x0000000000005000  0x0000000000006000
        /path/to/libc.so
    0x0000000000007000  0x0000000000008000  0x0000000000009000
        [stack]
```

(A more realistic example can be tested locally by creating a crashing program and running `llvm-readelf -n core`)

And also implements a raw hex dump for unknown descriptor data for unhandled descriptor types.

Reviewers: MaskRay, jhenderson, grimar, alexshap

Reviewed By: MaskRay, grimar

Subscribers: emaste, llvm-commits, labath

Tags: #llvm

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

Added:
    llvm/trunk/test/tools/llvm-readobj/note-core-ntfile-bad.test
    llvm/trunk/test/tools/llvm-readobj/note-core-ntfile.test
Modified:
    llvm/trunk/test/tools/llvm-readobj/note-amd.s
    llvm/trunk/test/tools/llvm-readobj/note-freebsd.s
    llvm/trunk/test/tools/llvm-readobj/note-unknown.s
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/test/tools/llvm-readobj/note-amd.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-amd.s?rev=368698&r1=368697&r2=368698&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-amd.s (original)
+++ llvm/trunk/test/tools/llvm-readobj/note-amd.s Tue Aug 13 07:38:45 2019
@@ -9,21 +9,17 @@
 // GNU-NEXT:   AMD                  0x00000000       NT_AMD_AMDGPU_HSA_METADATA (HSA Metadata)
 // GNU-NEXT:     HSA Metadata:
 // GNU-NEXT: {{^ +$}}
-// GNU-EMPTY:
 // GNU-NEXT:   AMD                  0x00000000       NT_AMD_AMDGPU_ISA (ISA Version)
 // GNU-NEXT:     ISA Version:
 // GNU-NEXT: {{^ +$}}
-// GNU-EMPTY:
 // GNU-NEXT: Displaying notes found
 // GNU-NEXT:   Owner                Data size        Description
 // GNU-NEXT:   AMD                  0x0000000a       NT_AMD_AMDGPU_HSA_METADATA (HSA Metadata)
 // GNU-NEXT:     HSA Metadata:
 // GNU-NEXT:     meta_blah
-// GNU-EMPTY:
 // GNU-NEXT:   AMD                  0x00000009       NT_AMD_AMDGPU_ISA (ISA Version)
 // GNU-NEXT:     ISA Version:
 // GNU-NEXT:     isa_blah
-// GNU-EMPTY:
 // GNU-NEXT: Displaying notes found
 // GNU-NEXT:   Owner                Data size        Description
 // GNU-NEXT:   AMD                  0x00000000       NT_AMD_AMDGPU_PAL_METADATA (PAL Metadata)

Added: llvm/trunk/test/tools/llvm-readobj/note-core-ntfile-bad.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-core-ntfile-bad.test?rev=368698&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-core-ntfile-bad.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/note-core-ntfile-bad.test Tue Aug 13 07:38:45 2019
@@ -0,0 +1,146 @@
+## Test that malformed NT_FILE sections in core files are gracefully ignored.
+
+## llvm-mc doesn't support generating ET_CORE files; the 'Content' field in
+## each of the following test cases were generated with the following steps:
+# $ llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu tmp.s -o tmp.o
+# $ bin/llvm-objcopy --dump-section=.note.foo=tmp.txt tmp.o /dev/null
+# $ xxd -p tmp.txt | tr -d '\n'; echo
+# using the assembly shown with each test case.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1.o
+# RUN: llvm-readelf -n %t1.o 2>&1 | FileCheck %s --check-prefix=ERR-HEADER-SHORT
+# ERR-HEADER-SHORT: warning: malformed note: header too short
+
+# .section ".note.foo", "a"
+#       .align 4
+#       .long 5 /* namesz */
+#       .long end - begin /* descsz */
+#       .long 0x46494c45 /* type = NT_FILE */
+#       .asciz "CORE"
+#       .align 4
+# begin:
+#       .quad 0 /* no file mappings */
+# end:
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_CORE
+  Machine: EM_X86_64
+Sections:
+  - Name:    .note.foo
+    Type:    SHT_NOTE
+    Content: 0500000008000000454C4946434F5245000000000000000000000000
+ProgramHeaders:
+  - Type:        PT_NOTE
+    Sections:
+      - Section: .note.foo
+
+# RUN: yaml2obj --docnum=2 %s -o %t2.o
+# RUN: llvm-readelf -n %t2.o 2>&1 | FileCheck %s --check-prefix=ERR-NULL-TERM
+# ERR-NULL-TERM: warning: malformed note: not NUL terminated
+
+# .section ".note.foo", "a"
+#       .align 4
+#       .long 5 /* namesz */
+#       .long end - begin /* descsz */
+#       .long 0x46494c45 /* type = NT_FILE */
+#       .asciz "CORE"
+#       .align 4
+# begin:
+#       .quad 1 /* 1 file mapping */
+#       .quad 4096 /* page size */
+#       .quad 0x1000 /* start #1 */
+#       .quad 0x2000 /* end #1 */
+#       .quad 0x3000 /* offset #1 */
+#       .ascii "xxxx"
+# end:
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_CORE
+  Machine: EM_X86_64
+Sections:
+  - Name:    .note.foo
+    Type:    SHT_NOTE
+    Content: 050000002C000000454C4946434F5245000000000100000000000000001000000000000000100000000000000020000000000000003000000000000078787878
+ProgramHeaders:
+  - Type:        PT_NOTE
+    Sections:
+      - Section: .note.foo
+
+# RUN: yaml2obj --docnum=3 %s -o %t3.o
+# RUN: llvm-readelf -n %t3.o 2>&1 | FileCheck %s --check-prefix=ERR-FILE-COUNT
+# ERR-FILE-COUNT: warning: malformed note: too short for number of files
+
+# .section ".note.foo", "a"
+#       .align 4
+#       .long 5 /* namesz */
+#       .long end - begin /* descsz */
+#       .long 0x46494c45 /* type = NT_FILE */
+#       .asciz "CORE"
+#       .align 4
+# begin:
+#       .quad 2 /* 2 file mappings */
+#       .quad 4096 /* page size */
+#       .quad 0x1000 /* start #1 */
+#       .quad 0x2000 /* end #1 */
+#       .quad 0x3000 /* offset #1 */
+#       .asciz "xyz"
+# end:
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_CORE
+  Machine: EM_X86_64
+Sections:
+  - Name:    .note.foo
+    Type:    SHT_NOTE
+    Content: 050000002C000000454C4946434F5245000000000200000000000000001000000000000000100000000000000020000000000000003000000000000078797A00
+ProgramHeaders:
+  - Type:        PT_NOTE
+    Sections:
+      - Section: .note.foo
+
+# RUN: yaml2obj --docnum=4 %s -o %t4.o
+# RUN: llvm-readelf -n %t4.o 2>&1 | FileCheck %s --check-prefix=ERR-FILE-END-EARLY
+# ERR-FILE-END-EARLY: warning: malformed note: too few filenames
+
+# .section ".note.foo", "a"
+#       .align 4
+#       .long 5 /* namesz */
+#       .long end - begin /* descsz */
+#       .long 0x46494c45 /* type = NT_FILE */
+#       .asciz "CORE"
+#       .align 4
+# begin:
+#       .quad 2 /* 2 file mappings */
+#       .quad 4096 /* page size */
+#       .quad 0x1000 /* start #1 */
+#       .quad 0x2000 /* end #1 */
+#       .quad 0x3000 /* offset #1 */
+#       .quad 0x4000 /* start #2 */
+#       .quad 0x5000 /* end #2 */
+#       .quad 0x6000 /* offset #2 */
+#       .asciz "xyz"
+# end:
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_CORE
+  Machine: EM_X86_64
+Sections:
+  - Name:    .note.foo
+    Type:    SHT_NOTE
+    Content: 0500000044000000454C4946434F5245000000000200000000000000001000000000000000100000000000000020000000000000003000000000000000400000000000000050000000000000006000000000000078797A00
+ProgramHeaders:
+  - Type:        PT_NOTE
+    Sections:
+      - Section: .note.foo

Added: llvm/trunk/test/tools/llvm-readobj/note-core-ntfile.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-core-ntfile.test?rev=368698&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-core-ntfile.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/note-core-ntfile.test Tue Aug 13 07:38:45 2019
@@ -0,0 +1,95 @@
+## Test that NT_FILE sections in core files are interpreted correctly.
+
+# RUN: yaml2obj %s > %t.o
+# RUN: llvm-readelf --notes %t.o | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj --notes %t.o | FileCheck %s --check-prefix=LLVM
+
+## llvm-mc doesn't support generating ET_CORE files; the 'Content' field was
+## generated with the following steps:
+# $ llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu tmp.s -o tmp.o
+# $ bin/llvm-objcopy --dump-section=.note.foo=tmp.txt tmp.o /dev/null
+# $ xxd -p tmp.txt | tr -d '\n'; echo
+## Using the following input:
+# .section ".note.foo", "a"
+#       .align 4
+#       .long 5 /* namesz */
+#       .long end - begin /* descsz */
+#       .long 0x46494c45 /* type = NT_FILE */
+#       .asciz "CORE"
+#       .align 4
+# begin:
+#       .quad 3 /* 3 file mappings */
+#       .quad 4096 /* page size */
+#       .quad 0x1000 /* start #1 */
+#       .quad 0x2000 /* end #1 */
+#       .quad 0x3000 /* offset #1 */
+#       .quad 0x4000 /* start #2 */
+#       .quad 0x5000 /* end #2 */
+#       .quad 0x6000 /* offset #2 */
+#       .quad 0x7000 /* start #3 */
+#       .quad 0x8000 /* end #3 */
+#       .quad 0x9000 /* offset #3 */
+#       .asciz "/path/to/a.out"
+#       .asciz "/path/to/libc.so"
+#       .asciz "[stack]"
+#       .align 4
+# end:
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_CORE
+  Machine: EM_X86_64
+Sections:
+  - Name:        .note.foo
+    Type:        SHT_NOTE
+    Content:     0500000080000000454C4946434F524500000000030000000000000000100000000000000010000000000000002000000000000000300000000000000040000000000000005000000000000000600000000000000070000000000000008000000000000000900000000000002F706174682F746F2F612E6F7574002F706174682F746F2F6C6962632E736F005B737461636B5D00
+ProgramHeaders:
+  - Type:        PT_NOTE
+    Sections:
+      - Section: .note.foo
+
+# GNU:      Displaying notes found
+# GNU-NEXT:   Owner                 Data size       Description
+# GNU-NEXT:   CORE                  0x00000080      NT_FILE (mapped files)
+# GNU-NEXT:     Page size: 4096
+# GNU-NEXT:                  Start                 End         Page Offset
+# GNU-NEXT:     0x0000000000001000  0x0000000000002000  0x0000000000003000
+# GNU-NEXT:         /path/to/a.out
+# GNU-NEXT:     0x0000000000004000  0x0000000000005000  0x0000000000006000
+# GNU-NEXT:         /path/to/libc.so
+# GNU-NEXT:     0x0000000000007000  0x0000000000008000  0x0000000000009000
+# GNU-NEXT:         [stack]
+# GNU-NOT:  {{.}}
+
+# LLVM:      Notes [
+# LLVM-NEXT:   NoteSection {
+# LLVM-NEXT:     Offset:
+# LLVM-NEXT:     Size:
+# LLVM-NEXT:     Note {
+# LLVM-NEXT:       Owner: CORE
+# LLVM-NEXT:       Data size: 0x80
+# LLVM-NEXT:       Type: NT_FILE (mapped files)
+# LLVM-NEXT:       Page Size: 4096
+# LLVM-NEXT:       Mapping [
+# LLVM-NEXT:         Start: 0x1000
+# LLVM-NEXT:         End: 0x2000
+# LLVM-NEXT:         Offset: 0x3000
+# LLVM-NEXT:         Filename: /path/to/a.out
+# LLVM-NEXT:       ]
+# LLVM-NEXT:       Mapping [
+# LLVM-NEXT:         Start: 0x4000
+# LLVM-NEXT:         End: 0x5000
+# LLVM-NEXT:         Offset: 0x6000
+# LLVM-NEXT:         Filename: /path/to/libc.so
+# LLVM-NEXT:       ]
+# LLVM-NEXT:       Mapping [
+# LLVM-NEXT:         Start: 0x7000
+# LLVM-NEXT:         End: 0x8000
+# LLVM-NEXT:         Offset: 0x9000
+# LLVM-NEXT:         Filename: [stack]
+# LLVM-NEXT:       ]
+# LLVM-NEXT:     }
+# LLVM-NEXT:   }
+# LLVM-NEXT: ]

Modified: llvm/trunk/test/tools/llvm-readobj/note-freebsd.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-freebsd.s?rev=368698&r1=368697&r2=368698&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-freebsd.s (original)
+++ llvm/trunk/test/tools/llvm-readobj/note-freebsd.s Tue Aug 13 07:38:45 2019
@@ -7,12 +7,14 @@
 // GNU:      Displaying notes found
 // GNU-NEXT:   Owner                Data size        Description
 // GNU-NEXT:   FreeBSD              0x00000000       NT_THRMISC (thrmisc structure)
-// GNU-EMPTY:
 // GNU-NEXT:   FreeBSD              0x00000000       NT_PROCSTAT_PROC (proc data)
-// GNU-EMPTY:
 // GNU-NEXT: Displaying notes found
 // GNU-NEXT:   Owner                Data size        Description
 // GNU-NEXT:   FreeBSD              0x00000000       NT_PROCSTAT_FILES (files data)
+// GNU-NEXT: Displaying notes found
+// GNU-NEXT:   Owner                Data size        Description
+// GNU-NEXT:   FreeBSD              0x0000001c       Unknown note type (0x00000003)
+// GNU-NEXT:    description data: 4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 20 61 6d 65 74 00 00
 
 // LLVM:      Notes [
 // LLVM-NEXT:   NoteSection {
@@ -38,6 +40,19 @@
 // LLVM-NEXT:       Type: NT_PROCSTAT_FILES (files data)
 // LLVM-NEXT:     }
 // LLVM-NEXT:   }
+// LLVM-NEXT:   NoteSection {
+// LLVM-NEXT:     Offset: 0x7C
+// LLVM-NEXT:     Size: 0x30
+// LLVM-NEXT:     Note {
+// LLVM-NEXT:       Owner: FreeBSD
+// LLVM-NEXT:       Data size: 0x1C
+// LLVM-NEXT:       Type: Unknown note type (0x00000003)
+// LLVM-NEXT:       Description data (
+// LLVM-NEXT:         0000: 4C6F7265 6D206970 73756D20 646F6C6F  |Lorem ipsum dolo|
+// LLVM-NEXT:         0010: 72207369 7420616D 65740000           |r sit amet..|
+// LLVM-NEXT:       )
+// LLVM-NEXT:     }
+// LLVM-NEXT:   }
 // LLVM-NEXT: ]
 
 .section ".note.foo", "a"
@@ -56,3 +71,13 @@
 	.long 0 /* descsz */
 	.long 9 /* type = NT_FREEBSD_FILES */
 	.asciz "FreeBSD"
+.section ".note.baz", "a"
+       .align 4
+       .long 8 /* namesz */
+       .long end - begin /* descsz */
+       .long 3 /* type */
+       .asciz "FreeBSD"
+begin:
+       .asciz "Lorem ipsum dolor sit amet"
+       .align 4
+end:

Modified: llvm/trunk/test/tools/llvm-readobj/note-unknown.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-unknown.s?rev=368698&r1=368697&r2=368698&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-unknown.s (original)
+++ llvm/trunk/test/tools/llvm-readobj/note-unknown.s Tue Aug 13 07:38:45 2019
@@ -7,6 +7,10 @@
 // GNU:      Displaying notes found at file offset 0x00000040 with length 0x00000010:
 // GNU-NEXT:   Owner                 Data size       Description
 // GNU-NEXT:   XYZ                  0x00000000       Unknown note type: (0x00000003)
+// GNU-NEXT: Displaying notes found at file offset 0x00000050 with length 0x0000002c:
+// GNU-NEXT:   Owner                 Data size       Description
+// GNU-NEXT:   XYZ                  0x0000001c       Unknown note type: (0x00000003)
+// GNU-NEXT:     description data: 4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 20 61 6d 65 74 00 00
 
 // LLVM:      Notes [
 // LLVM-NEXT:   NoteSection {
@@ -18,6 +22,19 @@
 // LLVM-NEXT:       Type: Unknown (0x00000003)
 // LLVM-NEXT:     }
 // LLVM-NEXT:   }
+// LLVM-NEXT:   NoteSection {
+// LLVM-NEXT:     Offset: 0x50
+// LLVM-NEXT:     Size: 0x2C
+// LLVM-NEXT:     Note {
+// LLVM-NEXT:       Owner: XYZ
+// LLVM-NEXT:       Data size: 0x1C
+// LLVM-NEXT:       Type: Unknown (0x00000003)
+// LLVM-NEXT:       Description data (
+// LLVM-NEXT:         0000: 4C6F7265 6D206970 73756D20 646F6C6F  |Lorem ipsum dolo|
+// LLVM-NEXT:         0010: 72207369 7420616D 65740000           |r sit amet..|
+// LLVM-NEXT:       )
+// LLVM-NEXT:     }
+// LLVM-NEXT:   }
 // LLVM-NEXT: ]
 
 .section ".note.foo", "a"
@@ -26,3 +43,13 @@
 	.long 0 /* descsz */
 	.long 3 /* type */
 	.asciz "XYZ"
+.section ".note.bar", "a"
+       .align 4
+       .long 4 /* namesz */
+       .long end - begin /* descsz */
+       .long 3 /* type */
+       .asciz "XYZ"
+begin:
+       .asciz "Lorem ipsum dolor sit amet"
+       .align 4
+end:

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=368698&r1=368697&r2=368698&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Tue Aug 13 07:38:45 2019
@@ -4363,6 +4363,78 @@ static AMDGPUNote getAMDGPUNote(uint32_t
   }
 }
 
+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)
+  // 2. Page size
+  // 3. N (start, end, offset) triples
+  // 4. N packed filenames (null delimited)
+  // Each field is an Elf_Addr, except for filenames which are char* strings.
+
+  CoreNote Ret;
+  const int Bytes = Desc.getAddressSize();
+
+  if (!Desc.isValidOffsetForAddress(2))
+    return createStringError(object_error::parse_failed,
+                             "malformed note: header too short");
+  if (Desc.getData().back() != 0)
+    return createStringError(object_error::parse_failed,
+                             "malformed note: not NUL terminated");
+
+  uint64_t DescOffset = 0;
+  uint64_t FileCount = Desc.getAddress(&DescOffset);
+  Ret.PageSize = Desc.getAddress(&DescOffset);
+
+  if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes))
+    return createStringError(object_error::parse_failed,
+                             "malformed note: too short for number of files");
+
+  uint64_t FilenamesOffset = 0;
+  DataExtractor Filenames(
+      Desc.getData().drop_front(DescOffset + 3 * FileCount * Bytes),
+      Desc.isLittleEndian(), Desc.getAddressSize());
+
+  Ret.Mappings.resize(FileCount);
+  for (CoreFileMapping &Mapping : Ret.Mappings) {
+    if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1))
+      return createStringError(object_error::parse_failed,
+                               "malformed note: too few filenames");
+    Mapping.Start = Desc.getAddress(&DescOffset);
+    Mapping.End = Desc.getAddress(&DescOffset);
+    Mapping.Offset = Desc.getAddress(&DescOffset);
+    Mapping.Filename = Filenames.getCStrRef(&FilenamesOffset);
+  }
+
+  return Ret;
+}
+
+template <typename ELFT>
+static void printCoreNote(raw_ostream &OS, const CoreNote &Note) {
+  // Length of "0x<address>" string.
+  const int FieldWidth = ELFT::Is64Bits ? 18 : 10;
+
+  OS << "    Page size: " << format_decimal(Note.PageSize, 0) << '\n';
+  OS << "    " << right_justify("Start", FieldWidth) << "  "
+     << right_justify("End", FieldWidth) << "  "
+     << right_justify("Page Offset", FieldWidth) << '\n';
+  for (const CoreFileMapping &Mapping : Note.Mappings) {
+    OS << "    " << format_hex(Mapping.Start, FieldWidth) << "  "
+       << format_hex(Mapping.End, FieldWidth) << "  "
+       << format_hex(Mapping.Offset, FieldWidth) << "\n        "
+       << Mapping.Filename << '\n';
+  }
+}
+
 template <class ELFT>
 void GNUStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
   auto PrintHeader = [&](const typename ELFT::Off Offset,
@@ -4377,34 +4449,57 @@ void GNUStyle<ELFT>::printNotes(const EL
     ArrayRef<uint8_t> Descriptor = Note.getDesc();
     Elf_Word Type = Note.getType();
 
+    // Print the note owner/type.
     OS << "  " << left_justify(Name, 20) << ' '
        << format_hex(Descriptor.size(), 10) << '\t';
-
     if (Name == "GNU") {
       OS << getGNUNoteTypeName(Type) << '\n';
-      printGNUNote<ELFT>(OS, Type, Descriptor);
     } else if (Name == "FreeBSD") {
       OS << getFreeBSDNoteTypeName(Type) << '\n';
     } else if (Name == "AMD") {
       OS << getAMDNoteTypeName(Type) << '\n';
-      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
-      if (!N.Type.empty())
-        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
     } else if (Name == "AMDGPU") {
       OS << getAMDGPUNoteTypeName(Type) << '\n';
-      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
-      if (!N.Type.empty())
-        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
     } else {
       StringRef NoteType = Obj->getHeader()->e_type == ELF::ET_CORE
                                ? getCoreNoteTypeName(Type)
                                : getGenericNoteTypeName(Type);
       if (!NoteType.empty())
-        OS << NoteType;
+        OS << NoteType << '\n';
       else
-        OS << "Unknown note type: (" << format_hex(Type, 10) << ')';
+        OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n";
+    }
+
+    // Print the description, or fallback to printing raw bytes for unknown
+    // owners.
+    if (Name == "GNU") {
+      printGNUNote<ELFT>(OS, Type, Descriptor);
+    } else if (Name == "AMD") {
+      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
+      if (!N.Type.empty())
+        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
+    } else if (Name == "AMDGPU") {
+      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
+      if (!N.Type.empty())
+        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
+    } else if (Name == "CORE") {
+      if (Type == ELF::NT_FILE) {
+        DataExtractor DescExtractor(
+            StringRef(reinterpret_cast<const char *>(Descriptor.data()),
+                      Descriptor.size()),
+            ELFT::TargetEndianness == support::little, sizeof(Elf_Addr));
+        Expected<CoreNote> Note = readCoreNote(DescExtractor);
+        if (Note)
+          printCoreNote<ELFT>(OS, *Note);
+        else
+          warn(Note.takeError());
+      }
+    } else if (!Descriptor.empty()) {
+      OS << "   description data:";
+      for (uint8_t B : Descriptor)
+        OS << " " << format("%02x", B);
+      OS << '\n';
     }
-    OS << '\n';
   };
 
   if (Obj->getHeader()->e_type == ELF::ET_CORE) {
@@ -5513,6 +5608,17 @@ static void printGNUNoteLLVMStyle(uint32
   }
 }
 
+static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
+  W.printNumber("Page Size", Note.PageSize);
+  for (const CoreFileMapping &Mapping : Note.Mappings) {
+    ListScope D(W, "Mapping");
+    W.printHex("Start", Mapping.Start);
+    W.printHex("End", Mapping.End);
+    W.printHex("Offset", Mapping.Offset);
+    W.printString("Filename", Mapping.Filename);
+  }
+}
+
 template <class ELFT>
 void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
   ListScope L(W, "Notes");
@@ -5529,23 +5635,17 @@ void LLVMStyle<ELFT>::printNotes(const E
     ArrayRef<uint8_t> Descriptor = Note.getDesc();
     Elf_Word Type = Note.getType();
 
+    // Print the note owner/type.
     W.printString("Owner", Name);
     W.printHex("Data size", Descriptor.size());
     if (Name == "GNU") {
       W.printString("Type", getGNUNoteTypeName(Type));
-      printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W);
     } else if (Name == "FreeBSD") {
       W.printString("Type", getFreeBSDNoteTypeName(Type));
     } else if (Name == "AMD") {
       W.printString("Type", getAMDNoteTypeName(Type));
-      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
-      if (!N.Type.empty())
-        W.printString(N.Type, N.Value);
     } else if (Name == "AMDGPU") {
       W.printString("Type", getAMDGPUNoteTypeName(Type));
-      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
-      if (!N.Type.empty())
-        W.printString(N.Type, N.Value);
     } else {
       StringRef NoteType = Obj->getHeader()->e_type == ELF::ET_CORE
                                ? getCoreNoteTypeName(Type)
@@ -5556,6 +5656,34 @@ void LLVMStyle<ELFT>::printNotes(const E
         W.printString("Type",
                       "Unknown (" + to_string(format_hex(Type, 10)) + ")");
     }
+
+    // Print the description, or fallback to printing raw bytes for unknown
+    // owners.
+    if (Name == "GNU") {
+      printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W);
+    } else if (Name == "AMD") {
+      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
+      if (!N.Type.empty())
+        W.printString(N.Type, N.Value);
+    } else if (Name == "AMDGPU") {
+      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
+      if (!N.Type.empty())
+        W.printString(N.Type, N.Value);
+    } else if (Name == "CORE") {
+      if (Type == ELF::NT_FILE) {
+        DataExtractor DescExtractor(
+            StringRef(reinterpret_cast<const char *>(Descriptor.data()),
+                      Descriptor.size()),
+            ELFT::TargetEndianness == support::little, sizeof(Elf_Addr));
+        Expected<CoreNote> Note = readCoreNote(DescExtractor);
+        if (Note)
+          printCoreNoteLLVMStyle(*Note, W);
+        else
+          warn(Note.takeError());
+      }
+    } else if (!Descriptor.empty()) {
+      W.printBinaryBlock("Description data", Descriptor);
+    }
   };
 
   if (Obj->getHeader()->e_type == ELF::ET_CORE) {




More information about the llvm-commits mailing list