mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[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
This commit is contained in:
parent
68d1415581
commit
3abe0b3ab9
@ -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
test/tools/llvm-readobj/note-core-ntfile-bad.test
Normal file
146
test/tools/llvm-readobj/note-core-ntfile-bad.test
Normal file
@ -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
|
95
test/tools/llvm-readobj/note-core-ntfile.test
Normal file
95
test/tools/llvm-readobj/note-core-ntfile.test
Normal file
@ -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: ]
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -4363,6 +4363,78 @@ 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)
|
||||
// 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 ELFFile<ELFT> *Obj) {
|
||||
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_t NoteType, ArrayRef<uint8_t> Desc,
|
||||
}
|
||||
}
|
||||
|
||||
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 ELFFile<ELFT> *Obj) {
|
||||
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 ELFFile<ELFT> *Obj) {
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user