Commit 63ac3e5c authored by Jordan Rupprecht's avatar Jordan Rupprecht
Browse files

[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

llvm-svn: 368698
parent 94166029
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -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)
+146 −0
Original line number Diff line number Diff line
## 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
+95 −0
Original line number Diff line number Diff line
## 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: ]
+27 −2
Original line number Diff line number Diff line
@@ -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:
+27 −0
Original line number Diff line number Diff line
@@ -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:
Loading