[llvm] 135df21 - [llvm-readelf] Print raw ELF note contents if we can't parse it
Alex Richardson via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 9 08:59:51 PST 2021
Author: Alex Richardson
Date: 2021-02-09T16:59:22Z
New Revision: 135df21248985579710e0cd3013d369de52dd354
URL: https://github.com/llvm/llvm-project/commit/135df21248985579710e0cd3013d369de52dd354
DIFF: https://github.com/llvm/llvm-project/commit/135df21248985579710e0cd3013d369de52dd354.diff
LOG: [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
Added:
Modified:
llvm/test/tools/llvm-readobj/ELF/gnu-note-size.test
llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
llvm/test/tools/llvm-readobj/ELF/note-amd.s
llvm/test/tools/llvm-readobj/ELF/note-amdgpu-invalid.s
llvm/test/tools/llvm-readobj/ELF/note-amdgpu.test
llvm/tools/llvm-readobj/ELFDumper.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-note-size.test b/llvm/test/tools/llvm-readobj/ELF/gnu-note-size.test
index 1166acd3416b..2f131a6cb347 100644
--- a/llvm/test/tools/llvm-readobj/ELF/gnu-note-size.test
+++ b/llvm/test/tools/llvm-readobj/ELF/gnu-note-size.test
@@ -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: ]
diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
index 83b5be8ac57d..e73238e6093a 100644
--- a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
+++ b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
@@ -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 {
diff --git a/llvm/test/tools/llvm-readobj/ELF/note-amd.s b/llvm/test/tools/llvm-readobj/ELF/note-amd.s
index 8130ee575335..c54ebd7aa32c 100644
--- a/llvm/test/tools/llvm-readobj/ELF/note-amd.s
+++ b/llvm/test/tools/llvm-readobj/ELF/note-amd.s
@@ -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
diff --git a/llvm/test/tools/llvm-readobj/ELF/note-amdgpu-invalid.s b/llvm/test/tools/llvm-readobj/ELF/note-amdgpu-invalid.s
index 3f9665e0cd49..25e0d3fc6ab1 100644
--- a/llvm/test/tools/llvm-readobj/ELF/note-amdgpu-invalid.s
+++ b/llvm/test/tools/llvm-readobj/ELF/note-amdgpu-invalid.s
@@ -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'
diff --git a/llvm/test/tools/llvm-readobj/ELF/note-amdgpu.test b/llvm/test/tools/llvm-readobj/ELF/note-amdgpu.test
index 0a92ae5903f5..f2d89d103a3d 100644
--- a/llvm/test/tools/llvm-readobj/ELF/note-amdgpu.test
+++ b/llvm/test/tools/llvm-readobj/ELF/note-amdgpu.test
@@ -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'
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 81f79393c3a8..f800b650330e 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -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();
More information about the llvm-commits
mailing list