forked from OSchip/llvm-project
[llvm-readelf] Print raw ELF note contents if we can't parse it
Currently, if the note name is known, but the value isn't we don't print the contents. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D74367
This commit is contained in:
parent
d613d8eb0e
commit
135df21248
|
@ -1,11 +1,15 @@
|
|||
## Check that a malformed NT_GNU_ABI_TAG note can be dumped without crashing.
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU
|
||||
# RUN: llvm-readobj --elf-output-style LLVM --notes %t | FileCheck %s --check-prefix=LLVM
|
||||
## GNU binutils does not print the raw description data when encountering an
|
||||
## invalid NT_GNU_ABI_TAG, but in LLVM style we print it.
|
||||
|
||||
# GNU: Displaying notes found in: .note.ABI-tag
|
||||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: GNU 0x00000004 NT_GNU_ABI_TAG (ABI version tag)
|
||||
# GNU-NEXT: <corrupt GNU_ABI_TAG>
|
||||
# GNU-EMPTY:
|
||||
|
||||
# LLVM: Notes [
|
||||
# LLVM-NEXT: NoteSection {
|
||||
|
@ -17,6 +21,9 @@
|
|||
# LLVM-NEXT: Data size: 0x4
|
||||
# LLVM-NEXT: Type: NT_GNU_ABI_TAG (ABI version tag)
|
||||
# LLVM-NEXT: ABI: <corrupt GNU_ABI_TAG>
|
||||
# LLVM-NEXT: Description data (
|
||||
# LLVM-NEXT: 0000: 00000000 |....|
|
||||
# LLVM-NEXT: )
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: ]
|
||||
|
|
|
@ -11,16 +11,22 @@
|
|||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
|
||||
# GNU-NEXT: OS: Linux, ABI: 2.6.32
|
||||
|
||||
# GNU:Displaying notes found in: .note.gnu.build-id
|
||||
# GNU-EMPTY:
|
||||
# GNU-NEXT:Displaying notes found in: .note.gnu.build-id
|
||||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: GNU 0x00000010 NT_GNU_BUILD_ID (unique build ID bitstring)
|
||||
# GNU-NEXT: Build ID: 4fcb712aa6387724a9f465a32cd8c14b
|
||||
|
||||
# GNU:Displaying notes found in: .note.gnu.gold-version
|
||||
# GNU-EMPTY:
|
||||
# GNU-NEXT:Displaying notes found in: .note.gnu.gold-version
|
||||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
|
||||
# GNU-NEXT: Version: gold 1.11
|
||||
# GNU-EMPTY:
|
||||
# GNU-NEXT:Displaying notes found in: .note.gnu.unknown
|
||||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: GNU 0x00000004 Unknown note type: (0x0000abcd)
|
||||
# GNU-NEXT: description data: 61 62 63 64
|
||||
# GNU-EMPTY:
|
||||
|
||||
# LLVM: Notes [
|
||||
# LLVM-NEXT: NoteSection {
|
||||
|
@ -57,6 +63,19 @@
|
|||
# LLVM-NEXT: Version: gold 1.11
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: NoteSection {
|
||||
# LLVM-NEXT: Name: .note.gnu.unknown
|
||||
# LLVM-NEXT: Offset: 0xD4
|
||||
# LLVM-NEXT: Size: 0x14
|
||||
# LLVM-NEXT: Note {
|
||||
# LLVM-NEXT: Owner: GNU
|
||||
# LLVM-NEXT: Data size: 0x4
|
||||
# LLVM-NEXT: Type: Unknown (0x0000abcd)
|
||||
# LLVM-NEXT: Description data (
|
||||
# LLVM-NEXT: 0000: 61626364 |abcd|
|
||||
# LLVM-NEXT: )
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: ]
|
||||
|
||||
## Note: the section name is <?> here because the section header table is not present.
|
||||
|
@ -103,6 +122,10 @@ Sections:
|
|||
Type: SHT_NOTE
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 040000000900000004000000474E5500676F6C6420312E3131000000
|
||||
- Name: .note.gnu.unknown
|
||||
Type: SHT_NOTE
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 0400000004000000cdab0000474E550061626364
|
||||
ProgramHeaders:
|
||||
- Type: PT_NOTE
|
||||
FileSize: 0x20
|
||||
|
@ -119,7 +142,7 @@ ProgramHeaders:
|
|||
# ERR1-GNU: Displaying notes found in: .note
|
||||
# ERR1-GNU-NEXT: Owner Data size Description
|
||||
# ERR1-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0xffff0000) or size (0x0)
|
||||
# ERR1-GNU-NOT: {{.}}
|
||||
# ERR1-GNU-EMPTY:
|
||||
|
||||
# ERR1-LLVM: Notes [
|
||||
# ERR1-LLVM-NEXT: NoteSection {
|
||||
|
@ -152,7 +175,7 @@ Sections:
|
|||
# ERR2-GNU: Displaying notes found in: .note
|
||||
# ERR2-GNU-NEXT: Owner Data size Description
|
||||
# ERR2-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x40) or size (0xffff0000)
|
||||
# ERR2-GNU-NOT: {{.}}
|
||||
# ERR2-GNU-EMPTY:
|
||||
|
||||
# ERR2-LLVM: Notes [
|
||||
# ERR2-LLVM-NEXT: NoteSection {
|
||||
|
@ -204,7 +227,7 @@ ProgramHeaders:
|
|||
# ERR4-GNU: Displaying notes found at file offset 0x00000000 with length 0xffff0000:
|
||||
# ERR4-GNU-NEXT: Owner Data size Description
|
||||
# ERR4-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 0: invalid offset (0x0) or size (0xffff0000)
|
||||
# ERR4-GNU-NOT: {{.}}
|
||||
# ERR4-GNU-EMPTY:
|
||||
|
||||
# ERR4-LLVM: Notes [
|
||||
# ERR4-LLVM-NEXT: NoteSection {
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
// GNU-NEXT: Owner Data size Description
|
||||
// GNU-NEXT: AMD 0x00000000 NT_AMD_AMDGPU_PAL_METADATA (PAL Metadata)
|
||||
// GNU-EMPTY:
|
||||
// GNU-NEXT: Displaying notes found in: .note.unknown
|
||||
// GNU-NEXT: Owner Data size Description
|
||||
// GNU-NEXT: AMD 0x00000007 Unknown note type: (0x000004d2)
|
||||
// GNU-NEXT: description data: 61 62 63 64 65 66 00
|
||||
// GNU-EMPTY:
|
||||
|
||||
// LLVM: Notes [
|
||||
// LLVM-NEXT: NoteSection {
|
||||
|
@ -72,6 +77,19 @@
|
|||
// LLVM-NEXT: Type: NT_AMD_AMDGPU_PAL_METADATA (PAL Metadata)
|
||||
// LLVM-NEXT: }
|
||||
// LLVM-NEXT: }
|
||||
// LLVM-NEXT: NoteSection {
|
||||
// LLVM-NEXT: Name: .note.unknown
|
||||
// LLVM-NEXT: Offset:
|
||||
// LLVM-NEXT: Size:
|
||||
// LLVM-NEXT: Note {
|
||||
// LLVM-NEXT: Owner: AMD
|
||||
// LLVM-NEXT: Data size: 0x7
|
||||
// LLVM-NEXT: Type: Unknown (0x000004d2)
|
||||
// LLVM-NEXT: Description data (
|
||||
// LLVM-NEXT: 0000: 61626364 656600 |abcdef.|
|
||||
// LLVM-NEXT: )
|
||||
// LLVM-NEXT: }
|
||||
// LLVM-NEXT: }
|
||||
// LLVM-NEXT: ]
|
||||
|
||||
.section ".note.no.desc", "a"
|
||||
|
@ -108,3 +126,13 @@ end.isa:
|
|||
.long 0 /* descsz */
|
||||
.long 12 /* type = NT_AMD_AMDGPU_PAL_METADATA */
|
||||
.asciz "AMD"
|
||||
.section ".note.unknown", "a"
|
||||
.align 4
|
||||
.long 4 /* namesz */
|
||||
.long end.unknown_data - begin.unknown_data /* descsz */
|
||||
.long 1234 /* type = unknown */
|
||||
.asciz "AMD"
|
||||
begin.unknown_data:
|
||||
.asciz "abcdef"
|
||||
end.unknown_data:
|
||||
.align 4
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
# GNU-NEXT: .wavefront_size: 5
|
||||
# GNU-NEXT: ...
|
||||
# GNU-EMPTY:
|
||||
# GNU-EMPTY:
|
||||
# GNU-NEXT: Displaying notes found in: .note.bar
|
||||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: AMDGPU 0x00000003 NT_AMDGPU_METADATA (AMDGPU Metadata)
|
||||
# GNU-NEXT: description data: 12 34 56
|
||||
# GNU-EMPTY:
|
||||
|
||||
# LLVM: Notes [
|
||||
# LLVM-NEXT: NoteSection {
|
||||
|
@ -48,7 +54,20 @@
|
|||
# LLVM-EMPTY:
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: ]
|
||||
# LLVM-NEXT: NoteSection {
|
||||
# LLVM-NEXT: Name: .note.bar
|
||||
# LLVM-NEXT: Offset: 0x128
|
||||
# LLVM-NEXT: Size: 0x18
|
||||
# LLVM-NEXT: Note {
|
||||
# LLVM-NEXT: Owner: AMDGPU
|
||||
# LLVM-NEXT: Data size: 0x3
|
||||
# LLVM-NEXT: Type: NT_AMDGPU_METADATA (AMDGPU Metadata)
|
||||
# LLVM-NEXT: Description data (
|
||||
# LLVM-NEXT: 0000: 123456 |.4V|
|
||||
# LLVM-NEXT: )
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT:]
|
||||
|
||||
## Use yaml2obj instead of llvm-mc for more test portability. This was
|
||||
## generated by grabbing section data from note-amdgpu.s and removing the amdhsa.version field.
|
||||
|
@ -62,3 +81,13 @@ Sections:
|
|||
- Name: .note.foo
|
||||
Type: SHT_NOTE
|
||||
Content: 07000000D400000020000000414D44475055000081ae616d646873612e6b65726e656c73918ab92e67726f75705f7365676d656e745f66697865645f73697a6502b62e6b65726e6172675f7365676d656e745f616c69676e04b52e6b65726e6172675f7365676d656e745f73697a6501b82e6d61785f666c61745f776f726b67726f75705f73697a6508a52e6e616d65a3666f6fbb2e707269766174655f7365676d656e745f66697865645f73697a6503ab2e736770725f636f756e7406a72e73796d626f6ca3666f6fab2e766770725f636f756e7407af2e7761766566726f6e745f73697a6505
|
||||
- Name: .note.bar
|
||||
Type: SHT_NOTE
|
||||
Notes:
|
||||
- Name: AMDGPU
|
||||
Type: NT_AMDGPU_METADATA
|
||||
Desc: '123456'
|
||||
# TODO: https://bugs.llvm.org/show_bug.cgi?id=49034
|
||||
# - Name: AMDGPU
|
||||
# Type: NT_AMDGPU_METADATA
|
||||
# Desc: 'abcdef'
|
||||
|
|
|
@ -22,6 +22,13 @@
|
|||
# GNU-NEXT: - 1
|
||||
# GNU-NEXT: - 0
|
||||
# GNU-NEXT: ...
|
||||
# GNU-EMPTY:
|
||||
# GNU-EMPTY:
|
||||
# GNU-NEXT: Displaying notes found in: .note.unknown
|
||||
# GNU-NEXT: Owner Data size Description
|
||||
# GNU-NEXT: AMDGPU 0x00000002 Unknown note type: (0x00000101)
|
||||
# GNU-NEXT: description data: ab cd
|
||||
# GNU-EMPTY:
|
||||
|
||||
# LLVM: Notes [
|
||||
# LLVM-NEXT: NoteSection {
|
||||
|
@ -51,6 +58,19 @@
|
|||
# LLVM-EMPTY:
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: NoteSection {
|
||||
# LLVM-NEXT: Name: .note.unknown
|
||||
# LLVM-NEXT: Offset: 0x13C
|
||||
# LLVM-NEXT: Size: 0x18
|
||||
# LLVM-NEXT: Note {
|
||||
# LLVM-NEXT: Owner: AMDGPU
|
||||
# LLVM-NEXT: Data size: 0x2
|
||||
# LLVM-NEXT: Type: Unknown (0x00000101)
|
||||
# LLVM-NEXT: Description data (
|
||||
# LLVM-NEXT: 0000: ABCD |..|
|
||||
# LLVM-NEXT: )
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: }
|
||||
# LLVM-NEXT: ]
|
||||
|
||||
## Use yaml2obj instead of llvm-mc for more test portability. This was
|
||||
|
@ -83,3 +103,9 @@ Sections:
|
|||
- Name: .note.foo
|
||||
Type: SHT_NOTE
|
||||
Content: 07000000E600000020000000414D44475055000082AE616D646873612E6B65726E656C73918AB92E67726F75705F7365676D656E745F66697865645F73697A6502B62E6B65726E6172675F7365676D656E745F616C69676E04B52E6B65726E6172675F7365676D656E745F73697A6501B82E6D61785F666C61745F776F726B67726F75705F73697A6508A52E6E616D65A3666F6FBB2E707269766174655F7365676D656E745F66697865645F73697A6503AB2E736770725F636F756E7406A72E73796D626F6CA3666F6FAB2E766770725F636F756E7407AF2E7761766566726F6E745F73697A6505AE616D646873612E76657273696F6E9201000000
|
||||
- Name: .note.unknown
|
||||
Type: SHT_NOTE
|
||||
Notes:
|
||||
- Name: AMDGPU
|
||||
Type: NT_GNU_BUILD_ATTRIBUTE_FUNC
|
||||
Desc: 'abcd'
|
||||
|
|
|
@ -4877,11 +4877,12 @@ static StringRef getGNUGoldVersion(ArrayRef<uint8_t> Desc) {
|
|||
}
|
||||
|
||||
template <typename ELFT>
|
||||
static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
|
||||
static bool printGNUNote(raw_ostream &OS, uint32_t NoteType,
|
||||
ArrayRef<uint8_t> Desc) {
|
||||
// Return true if we were able to pretty-print the note, false otherwise.
|
||||
switch (NoteType) {
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
case ELF::NT_GNU_ABI_TAG: {
|
||||
const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
|
||||
if (!AbiTag.IsValid)
|
||||
|
@ -4904,6 +4905,7 @@ static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
|
|||
break;
|
||||
}
|
||||
OS << '\n';
|
||||
return true;
|
||||
}
|
||||
|
||||
struct AMDNote {
|
||||
|
@ -4942,7 +4944,7 @@ static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
|
|||
StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
|
||||
msgpack::Document MsgPackDoc;
|
||||
if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
|
||||
return {"AMDGPU Metadata", "Invalid AMDGPU Metadata"};
|
||||
return {"", ""};
|
||||
|
||||
AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);
|
||||
std::string HSAMetadataString;
|
||||
|
@ -4950,8 +4952,14 @@ static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
|
|||
HSAMetadataString = "Invalid AMDGPU Metadata\n";
|
||||
|
||||
raw_string_ostream StrOS(HSAMetadataString);
|
||||
if (MsgPackDoc.getRoot().isScalar()) {
|
||||
// TODO: passing a scalar root to toYAML() asserts:
|
||||
// (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar &&
|
||||
// "plain scalar documents are not supported")
|
||||
// To avoid this crash we print the raw data instead.
|
||||
return {"", ""};
|
||||
}
|
||||
MsgPackDoc.toYAML(StrOS);
|
||||
|
||||
return {"AMDGPU Metadata", StrOS.str()};
|
||||
}
|
||||
}
|
||||
|
@ -5271,28 +5279,36 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
|
|||
OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n";
|
||||
|
||||
// Print the description, or fallback to printing raw bytes for unknown
|
||||
// owners.
|
||||
// owners/if we fail to pretty-print the contents.
|
||||
if (Name == "GNU") {
|
||||
printGNUNote<ELFT>(OS, Type, Descriptor);
|
||||
if (printGNUNote<ELFT>(OS, Type, Descriptor))
|
||||
return Error::success();
|
||||
} else if (Name == "AMD") {
|
||||
const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
|
||||
if (!N.Type.empty())
|
||||
if (!N.Type.empty()) {
|
||||
OS << " " << N.Type << ":\n " << N.Value << '\n';
|
||||
return Error::success();
|
||||
}
|
||||
} else if (Name == "AMDGPU") {
|
||||
const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
|
||||
if (!N.Type.empty())
|
||||
if (!N.Type.empty()) {
|
||||
OS << " " << N.Type << ":\n " << N.Value << '\n';
|
||||
return Error::success();
|
||||
}
|
||||
} else if (Name == "CORE") {
|
||||
if (Type == ELF::NT_FILE) {
|
||||
DataExtractor DescExtractor(Descriptor,
|
||||
ELFT::TargetEndianness == support::little,
|
||||
sizeof(Elf_Addr));
|
||||
if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor))
|
||||
if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor)) {
|
||||
printCoreNote<ELFT>(OS, *NoteOrErr);
|
||||
else
|
||||
return Error::success();
|
||||
} else {
|
||||
return NoteOrErr.takeError();
|
||||
}
|
||||
}
|
||||
} else if (!Descriptor.empty()) {
|
||||
}
|
||||
if (!Descriptor.empty()) {
|
||||
OS << " description data:";
|
||||
for (uint8_t B : Descriptor)
|
||||
OS << " " << format("%02x", B);
|
||||
|
@ -6456,15 +6472,17 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() {
|
|||
}
|
||||
|
||||
template <typename ELFT>
|
||||
static void printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
|
||||
static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
|
||||
ScopedPrinter &W) {
|
||||
// Return true if we were able to pretty-print the note, false otherwise.
|
||||
switch (NoteType) {
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
case ELF::NT_GNU_ABI_TAG: {
|
||||
const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
|
||||
if (!AbiTag.IsValid) {
|
||||
W.printString("ABI", "<corrupt GNU_ABI_TAG>");
|
||||
return false;
|
||||
} else {
|
||||
W.printString("OS", AbiTag.OSName);
|
||||
W.printString("ABI", AbiTag.ABI);
|
||||
|
@ -6484,6 +6502,7 @@ static void printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
|
|||
W.printString(Property);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
|
||||
|
@ -6531,28 +6550,36 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
|
|||
"Unknown (" + to_string(format_hex(Type, 10)) + ")");
|
||||
|
||||
// Print the description, or fallback to printing raw bytes for unknown
|
||||
// owners.
|
||||
// owners/if we fail to pretty-print the contents.
|
||||
if (Name == "GNU") {
|
||||
printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W);
|
||||
if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W))
|
||||
return Error::success();
|
||||
} else if (Name == "AMD") {
|
||||
const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
|
||||
if (!N.Type.empty())
|
||||
if (!N.Type.empty()) {
|
||||
W.printString(N.Type, N.Value);
|
||||
return Error::success();
|
||||
}
|
||||
} else if (Name == "AMDGPU") {
|
||||
const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
|
||||
if (!N.Type.empty())
|
||||
if (!N.Type.empty()) {
|
||||
W.printString(N.Type, N.Value);
|
||||
return Error::success();
|
||||
}
|
||||
} else if (Name == "CORE") {
|
||||
if (Type == ELF::NT_FILE) {
|
||||
DataExtractor DescExtractor(Descriptor,
|
||||
ELFT::TargetEndianness == support::little,
|
||||
sizeof(Elf_Addr));
|
||||
if (Expected<CoreNote> Note = readCoreNote(DescExtractor))
|
||||
printCoreNoteLLVMStyle(*Note, W);
|
||||
else
|
||||
return Note.takeError();
|
||||
if (Expected<CoreNote> N = readCoreNote(DescExtractor)) {
|
||||
printCoreNoteLLVMStyle(*N, W);
|
||||
return Error::success();
|
||||
} else {
|
||||
return N.takeError();
|
||||
}
|
||||
}
|
||||
} else if (!Descriptor.empty()) {
|
||||
}
|
||||
if (!Descriptor.empty()) {
|
||||
W.printBinaryBlock("Description data", Descriptor);
|
||||
}
|
||||
return Error::success();
|
||||
|
|
Loading…
Reference in New Issue