[llvm] r346371 - [llvm-readobj] Implement LLVM style printer for --notes
Jordan Rupprecht via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 7 15:53:50 PST 2018
Author: rupprecht
Date: Wed Nov 7 15:53:50 2018
New Revision: 346371
URL: http://llvm.org/viewvc/llvm-project?rev=346371&view=rev
Log:
[llvm-readobj] Implement LLVM style printer for --notes
Summary:
Port the GNU style printNotes method to the LLVMStyle subclass.
This is basically just a heavy refactor so that the note parsing/formatting logic from the GNUStyle::printNotes can be shared with LLVMStyle::printNotes.
Reviewers: MaskRay
Reviewed By: MaskRay
Subscribers: dschuff, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D54220
Modified:
llvm/trunk/test/tools/llvm-readobj/gnu-notes.test
llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s
llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s
llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
Modified: llvm/trunk/test/tools/llvm-readobj/gnu-notes.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/gnu-notes.test?rev=346371&r1=346370&r2=346371&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/gnu-notes.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/gnu-notes.test Wed Nov 7 15:53:50 2018
@@ -1,15 +1,55 @@
# RUN: yaml2obj %s > %t.so
-# RUN: llvm-readobj -elf-output-style GNU --notes %t.so | FileCheck %s
+# RUN: llvm-readobj -elf-output-style GNU --notes %t.so | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj -elf-output-style LLVM --notes %t.so | FileCheck %s --check-prefix=LLVM
-# CHECK: Displaying notes found at file offset 0x00000300 with length 0x00000020:
-# CHECK: Owner Data size Description
-# CHECK: GNU 0x00000010 NT_GNU_BUILD_ID (unique build ID bitstring)
-# CHECK: Build ID: 4fcb712aa6387724a9f465a32cd8c14b
+# GNU: Displaying notes found at file offset 0x00000340 with length 0x00000020:
+# 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
-# CHECK: Displaying notes found at file offset 0x0000036c with length 0x0000001c:
-# CHECK: Owner Data size Description
-# CHECK: GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
-# CHECK: Version: gold 1.11
+# GNU: Displaying notes found at file offset 0x00000360 with length 0x00000020:
+# 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 at file offset 0x000003cc with length 0x0000001c:
+# GNU-NEXT: Owner Data size Description
+# GNU-NEXT: GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version)
+# GNU-NEXT: Version: gold 1.11
+
+# LLVM: Notes [
+# LLVM-NEXT: NoteSection {
+# LLVM-NEXT: Offset: 0x340
+# LLVM-NEXT: Size: 0x20
+# LLVM-NEXT: Note {
+# LLVM-NEXT: Owner: GNU
+# LLVM-NEXT: Data size: 0x10
+# LLVM-NEXT: Type: NT_GNU_ABI_TAG (ABI version tag)
+# LLVM-NEXT: OS: Linux
+# LLVM-NEXT: ABI: 2.6.32
+# LLVM-NEXT: }
+# LLVM-NEXT: }
+# LLVM-NEXT: NoteSection {
+# LLVM-NEXT: Offset: 0x360
+# LLVM-NEXT: Size: 0x20
+# LLVM-NEXT: Note {
+# LLVM-NEXT: Owner: GNU
+# LLVM-NEXT: Data size: 0x10
+# LLVM-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
+# LLVM-NEXT: Build ID: 4fcb712aa6387724a9f465a32cd8c14b
+# LLVM-NEXT: }
+# LLVM-NEXT: }
+# LLVM-NEXT: NoteSection {
+# LLVM-NEXT: Offset: 0x3CC
+# LLVM-NEXT: Size: 0x1C
+# LLVM-NEXT: Note {
+# LLVM-NEXT: Owner: GNU
+# LLVM-NEXT: Data size: 0x9
+# LLVM-NEXT: Type: NT_GNU_GOLD_VERSION (gold version)
+# LLVM-NEXT: Version: gold 1.11
+# LLVM-NEXT: }
+# LLVM-NEXT: }
+# LLVM-NEXT: ]
--- !ELF
FileHeader:
@@ -18,6 +58,10 @@ FileHeader:
Type: ET_EXEC
Machine: EM_X86_64
Sections:
+ - Name: .note.ABI-tag
+ Type: SHT_NOTE
+ AddressAlign: 0x0000000000000004
+ Content: 040000001000000001000000474E550000000000020000000600000020000000
- Name: .note.gnu.build-id
Type: SHT_NOTE
Flags: [ SHF_ALLOC ]
Modified: llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s?rev=346371&r1=346370&r2=346371&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s (original)
+++ llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s Wed Nov 7 15:53:50 2018
@@ -1,23 +1,51 @@
// REQUIRES: x86-registered-target
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
-// RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s
+// RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s --check-prefix=GNU
+// RUN: llvm-readobj -elf-output-style LLVM --notes %t | FileCheck %s --check-prefix=LLVM
-// CHECK: Displaying notes found at file offset 0x00000040 with length 0x000000b8:
-// CHECK-NEXT: Owner Data size Description
-// CHECK-NEXT: GNU 0x000000a8 NT_GNU_PROPERTY_TYPE_0 (property note)
-// CHECK-NEXT: Properties: stack size: 0x100
-// CHECK-NEXT: stack size: 0x100
-// CHECK-NEXT: no copy on protected
-// CHECK-NEXT: X86 features: SHSTK
-// CHECK-NEXT: X86 features: IBT, SHSTK
-// CHECK-NEXT: X86 features: none
-// CHECK-NEXT: <application-specific type 0xfefefefe>
-// CHECK-NEXT: stack size: <corrupt length: 0x0>
-// CHECK-NEXT: stack size: <corrupt length: 0x4>
-// CHECK-NEXT: no copy on protected <corrupt length: 0x1>
-// CHECK-NEXT: X86 features: <corrupt length: 0x0>
-// CHECK-NEXT: X86 features: IBT, <unknown flags: 0xf000f000f000f000>
-// CHECK-NEXT: <corrupt type (0x2) datasz: 0x1>
+// GNU: Displaying notes found at file offset 0x00000040 with length 0x000000b8:
+// GNU-NEXT: Owner Data size Description
+// GNU-NEXT: GNU 0x000000a8 NT_GNU_PROPERTY_TYPE_0 (property note)
+// GNU-NEXT: Properties: stack size: 0x100
+// GNU-NEXT: stack size: 0x100
+// GNU-NEXT: no copy on protected
+// GNU-NEXT: X86 features: SHSTK
+// GNU-NEXT: X86 features: IBT, SHSTK
+// GNU-NEXT: X86 features: none
+// GNU-NEXT: <application-specific type 0xfefefefe>
+// GNU-NEXT: stack size: <corrupt length: 0x0>
+// GNU-NEXT: stack size: <corrupt length: 0x4>
+// GNU-NEXT: no copy on protected <corrupt length: 0x1>
+// GNU-NEXT: X86 features: <corrupt length: 0x0>
+// GNU-NEXT: X86 features: IBT, <unknown flags: 0xf000f000f000f000>
+// GNU-NEXT: <corrupt type (0x2) datasz: 0x1>
+
+// LLVM: Notes [
+// LLVM-NEXT: NoteSection {
+// LLVM-NEXT: Offset: 0x40
+// LLVM-NEXT: Size: 0xB8
+// LLVM-NEXT: Note {
+// LLVM-NEXT: Owner: GNU
+// LLVM-NEXT: Data size: 0xA8
+// LLVM-NEXT: Type: NT_GNU_PROPERTY_TYPE_0 (property note)
+// LLVM-NEXT: Property [
+// LLVM-NEXT: stack size: 0x100
+// LLVM-NEXT: stack size: 0x100
+// LLVM-NEXT: no copy on protected
+// LLVM-NEXT: X86 features: SHSTK
+// LLVM-NEXT: X86 features: IBT, SHSTK
+// LLVM-NEXT: X86 features: none
+// LLVM-NEXT: <application-specific type 0xfefefefe>
+// LLVM-NEXT: stack size: <corrupt length: 0x0>
+// LLVM-NEXT: stack size: <corrupt length: 0x4>
+// LLVM-NEXT: no copy on protected <corrupt length: 0x1>
+// LLVM-NEXT: X86 features: <corrupt length: 0x0>
+// LLVM-NEXT: X86 features: IBT, <unknown flags: 0xf000f000f000f000>
+// LLVM-NEXT: <corrupt type (0x2) datasz: 0x1>
+// LLVM-NEXT: ]
+// LLVM-NEXT: }
+// LLVM-NEXT: }
+// LLVM-NEXT: ]
.section ".note.gnu.property", "a"
.align 4
Modified: llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s?rev=346371&r1=346370&r2=346371&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s (original)
+++ llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s Wed Nov 7 15:53:50 2018
@@ -1,11 +1,27 @@
// REQUIRES: x86-registered-target
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
-// RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s
+// RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s --check-prefix=GNU
+// RUN: llvm-readobj -elf-output-style LLVM --notes %t | FileCheck %s --check-prefix=LLVM
-// CHECK: Displaying notes found at file offset 0x00000040 with length 0x00000014:
-// CHECK-NEXT: Owner Data size Description
-// CHECK-NEXT: GNU 0x00000004 NT_GNU_PROPERTY_TYPE_0 (property note)
-// CHECK-NEXT: Properties: <corrupted GNU_PROPERTY_TYPE_0>
+// GNU: Displaying notes found at file offset 0x00000040 with length 0x00000014:
+// GNU-NEXT: Owner Data size Description
+// GNU-NEXT: GNU 0x00000004 NT_GNU_PROPERTY_TYPE_0 (property note)
+// GNU-NEXT: Properties: <corrupted GNU_PROPERTY_TYPE_0>
+
+// LLVM: Notes [
+// LLVM-NEXT: NoteSection {
+// LLVM-NEXT: Offset: 0x40
+// LLVM-NEXT: Size: 0x14
+// LLVM-NEXT: Note {
+// LLVM-NEXT: Owner: GNU
+// LLVM-NEXT: Data size: 0x4
+// LLVM-NEXT: Type: NT_GNU_PROPERTY_TYPE_0 (property note)
+// LLVM-NEXT: Property [
+// LLVM-NEXT: <corrupted GNU_PROPERTY_TYPE_0>
+// LLVM-NEXT: ]
+// LLVM-NEXT: }
+// LLVM-NEXT: }
+// LLVM-NEXT: ]
// Section below is broken, check we report that.
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=346371&r1=346370&r2=346371&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Nov 7 15:53:50 2018
@@ -22,9 +22,9 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -43,6 +43,7 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
@@ -3654,40 +3655,41 @@ static std::string getAMDGPUNoteTypeName
}
template <typename ELFT>
-static void printGNUProperty(raw_ostream &OS, uint32_t Type, uint32_t DataSize,
- ArrayRef<uint8_t> Data) {
+static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
+ ArrayRef<uint8_t> Data) {
+ std::string str;
+ raw_string_ostream OS(str);
switch (Type) {
default:
- OS << format(" <application-specific type 0x%x>\n", Type);
- return;
+ OS << format("<application-specific type 0x%x>", Type);
+ return OS.str();
case GNU_PROPERTY_STACK_SIZE: {
- OS << " stack size: ";
+ OS << "stack size: ";
if (DataSize == sizeof(typename ELFT::uint))
- OS << format("0x%llx\n",
- (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
+ OS << formatv("{0:x}",
+ (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
else
- OS << format("<corrupt length: 0x%x>\n", DataSize);
- break;
+ OS << format("<corrupt length: 0x%x>", DataSize);
+ return OS.str();
}
case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
- OS << " no copy on protected";
+ OS << "no copy on protected";
if (DataSize)
OS << format(" <corrupt length: 0x%x>", DataSize);
- OS << "\n";
- break;
+ return OS.str();
case GNU_PROPERTY_X86_FEATURE_1_AND:
- OS << " X86 features: ";
+ OS << "X86 features: ";
if (DataSize != 4 && DataSize != 8) {
- OS << format("<corrupt length: 0x%x>\n", DataSize);
- break;
+ OS << format("<corrupt length: 0x%x>", DataSize);
+ return OS.str();
}
uint64_t CFProtection =
(DataSize == 4)
? support::endian::read32<ELFT::TargetEndianness>(Data.data())
: support::endian::read64<ELFT::TargetEndianness>(Data.data());
if (CFProtection == 0) {
- OS << "none\n";
- break;
+ OS << "none";
+ return OS.str();
}
if (CFProtection & GNU_PROPERTY_X86_FEATURE_1_IBT) {
OS << "IBT";
@@ -3703,105 +3705,144 @@ static void printGNUProperty(raw_ostream
}
if (CFProtection)
OS << format("<unknown flags: 0x%llx>", CFProtection);
- OS << "\n";
- break;
+ return OS.str();
}
}
template <typename ELFT>
-static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
- ArrayRef<typename ELFT::Word> Words, size_t Size) {
+static SmallVector<std::string, 4>
+getGNUPropertyList(ArrayRef<typename ELFT::Word> Words) {
using Elf_Word = typename ELFT::Word;
+ SmallVector<std::string, 4> Properties;
+ ArrayRef<uint8_t> Arr(reinterpret_cast<const uint8_t *>(Words.data()),
+ Words.size());
+ while (Arr.size() >= 8) {
+ uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
+ uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
+ Arr = Arr.drop_front(8);
+
+ // Take padding size into account if present.
+ uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
+ std::string str;
+ raw_string_ostream OS(str);
+ if (Arr.size() < PaddedSize) {
+ OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize);
+ Properties.push_back(OS.str());
+ break;
+ }
+ Properties.push_back(
+ getGNUProperty<ELFT>(Type, DataSize, Arr.take_front(PaddedSize)));
+ Arr = Arr.drop_front(PaddedSize);
+ }
+
+ if (!Arr.empty())
+ Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>");
+
+ return Properties;
+}
+
+struct GNUAbiTag {
+ std::string OSName;
+ std::string ABI;
+ bool IsValid;
+};
+
+template <typename ELFT>
+static GNUAbiTag getGNUAbiTag(ArrayRef<typename ELFT::Word> Words) {
+ if (Words.size() < 4)
+ return {"", "", /*IsValid=*/false};
+
+ static const char *OSNames[] = {
+ "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
+ };
+ StringRef OSName = "Unknown";
+ if (Words[0] < array_lengthof(OSNames))
+ OSName = OSNames[Words[0]];
+ uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];
+ std::string str;
+ raw_string_ostream ABI(str);
+ ABI << Major << "." << Minor << "." << Patch;
+ return {OSName, ABI.str(), /*IsValid=*/true};
+}
+
+template <typename ELFT>
+static std::string getGNUBuildId(ArrayRef<typename ELFT::Word> Words) {
+ std::string str;
+ raw_string_ostream OS(str);
+ ArrayRef<uint8_t> ID(reinterpret_cast<const uint8_t *>(Words.data()),
+ Words.size());
+ for (const auto &B : ID)
+ OS << format_hex_no_prefix(B, 2);
+ return OS.str();
+}
+
+template <typename ELFT>
+static StringRef getGNUGoldVersion(ArrayRef<typename ELFT::Word> Words) {
+ return StringRef(reinterpret_cast<const char *>(Words.data()), Words.size());
+}
+
+template <typename ELFT>
+static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
+ ArrayRef<typename ELFT::Word> Words) {
switch (NoteType) {
default:
return;
case ELF::NT_GNU_ABI_TAG: {
- static const char *OSNames[] = {
- "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
- };
-
- StringRef OSName = "Unknown";
- if (Words[0] < array_lengthof(OSNames))
- OSName = OSNames[Words[0]];
- uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];
-
- if (Words.size() < 4)
+ const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Words);
+ if (!AbiTag.IsValid)
OS << " <corrupt GNU_ABI_TAG>";
else
- OS << " OS: " << OSName << ", ABI: " << Major << "." << Minor << "."
- << Patch;
+ OS << " OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI;
break;
}
case ELF::NT_GNU_BUILD_ID: {
- OS << " Build ID: ";
- ArrayRef<uint8_t> ID(reinterpret_cast<const uint8_t *>(Words.data()), Size);
- for (const auto &B : ID)
- OS << format_hex_no_prefix(B, 2);
+ OS << " Build ID: " << getGNUBuildId<ELFT>(Words);
break;
}
case ELF::NT_GNU_GOLD_VERSION:
- OS << " Version: "
- << StringRef(reinterpret_cast<const char *>(Words.data()), Size);
+ OS << " Version: " << getGNUGoldVersion<ELFT>(Words);
break;
case ELF::NT_GNU_PROPERTY_TYPE_0:
OS << " Properties:";
-
- ArrayRef<uint8_t> Arr(reinterpret_cast<const uint8_t *>(Words.data()),
- Size);
- while (Arr.size() >= 8) {
- uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
- uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
- Arr = Arr.drop_front(8);
-
- // Take padding size into account if present.
- uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
- if (Arr.size() < PaddedSize) {
- OS << format(" <corrupt type (0x%x) datasz: 0x%x>\n", Type,
- DataSize);
- break;
- }
- printGNUProperty<ELFT>(OS, Type, DataSize, Arr.take_front(PaddedSize));
- Arr = Arr.drop_front(PaddedSize);
- }
-
- if (!Arr.empty())
- OS << " <corrupted GNU_PROPERTY_TYPE_0>";
+ for (const auto &Property : getGNUPropertyList<ELFT>(Words))
+ OS << " " << Property << "\n";
break;
}
OS << '\n';
}
+struct AMDGPUNote {
+ std::string type;
+ std::string value;
+};
+
template <typename ELFT>
-static void printAMDGPUNote(raw_ostream &OS, uint32_t NoteType,
- ArrayRef<typename ELFT::Word> Words, size_t Size) {
+static AMDGPUNote getAMDGPUNote(uint32_t NoteType,
+ ArrayRef<typename ELFT::Word> Words) {
switch (NoteType) {
default:
- return;
- case ELF::NT_AMD_AMDGPU_HSA_METADATA:
- OS << " HSA Metadata:\n"
- << StringRef(reinterpret_cast<const char *>(Words.data()), Size);
- break;
- case ELF::NT_AMD_AMDGPU_ISA:
- OS << " ISA Version:\n"
- << " "
- << StringRef(reinterpret_cast<const char *>(Words.data()), Size);
- break;
- case ELF::NT_AMD_AMDGPU_PAL_METADATA:
- const uint32_t *PALMetadataBegin = reinterpret_cast<const uint32_t *>(Words.data());
- const uint32_t *PALMetadataEnd = PALMetadataBegin + Size;
- std::vector<uint32_t> PALMetadata(PALMetadataBegin, PALMetadataEnd);
- std::string PALMetadataString;
- auto Error = AMDGPU::PALMD::toString(PALMetadata, PALMetadataString);
- OS << " PAL Metadata:\n";
- if (Error) {
- OS << " Invalid";
- return;
- }
- OS << PALMetadataString;
- break;
+ return {"", ""};
+ case ELF::NT_AMD_AMDGPU_HSA_METADATA:
+ return {"HSA Metadata",
+ std::string(reinterpret_cast<const char *>(Words.data()),
+ Words.size())};
+ case ELF::NT_AMD_AMDGPU_ISA:
+ return {"ISA Version",
+ std::string(reinterpret_cast<const char *>(Words.data()),
+ Words.size())};
+ case ELF::NT_AMD_AMDGPU_PAL_METADATA:
+ const uint32_t *PALMetadataBegin =
+ reinterpret_cast<const uint32_t *>(Words.data());
+ const uint32_t *PALMetadataEnd = PALMetadataBegin + Words.size();
+ std::vector<uint32_t> PALMetadata(PALMetadataBegin, PALMetadataEnd);
+ std::string PALMetadataString;
+ auto Error = AMDGPU::PALMD::toString(PALMetadata, PALMetadataString);
+ if (Error) {
+ return {"PAL Metadata", "Invalid"};
+ }
+ return {"PAL Metadata", PALMetadataString};
}
- OS.flush();
}
template <class ELFT>
@@ -3826,12 +3867,14 @@ void GNUStyle<ELFT>::printNotes(const EL
if (Name == "GNU") {
OS << getGNUNoteTypeName(Type) << '\n';
- printGNUNote<ELFT>(OS, Type, Descriptor, Descriptor.size());
+ printGNUNote<ELFT>(OS, Type, Descriptor);
} else if (Name == "FreeBSD") {
OS << getFreeBSDNoteTypeName(Type) << '\n';
} else if (Name == "AMD") {
OS << getAMDGPUNoteTypeName(Type) << '\n';
- printAMDGPUNote<ELFT>(OS, Type, Descriptor, Descriptor.size());
+ const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
+ if (!N.type.empty())
+ OS << " " << N.type << ":\n " << N.value << '\n';
} else {
OS << "Unknown note type: (" << format_hex(Type, 10) << ')';
}
@@ -4435,9 +4478,98 @@ void LLVMStyle<ELFT>::printAddrsig(const
}
}
+template <typename ELFT>
+static void printGNUNoteLLVMStyle(uint32_t NoteType,
+ ArrayRef<typename ELFT::Word> Words,
+ ScopedPrinter &W) {
+ switch (NoteType) {
+ default:
+ return;
+ case ELF::NT_GNU_ABI_TAG: {
+ const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Words);
+ if (!AbiTag.IsValid) {
+ W.printString("ABI", "<corrupt GNU_ABI_TAG>");
+ } else {
+ W.printString("OS", AbiTag.OSName);
+ W.printString("ABI", AbiTag.ABI);
+ }
+ break;
+ }
+ case ELF::NT_GNU_BUILD_ID: {
+ W.printString("Build ID", getGNUBuildId<ELFT>(Words));
+ break;
+ }
+ case ELF::NT_GNU_GOLD_VERSION:
+ W.printString("Version", getGNUGoldVersion<ELFT>(Words));
+ break;
+ case ELF::NT_GNU_PROPERTY_TYPE_0:
+ ListScope D(W, "Property");
+ for (const auto &Property : getGNUPropertyList<ELFT>(Words))
+ W.printString(Property);
+ break;
+ }
+}
+
template <class ELFT>
void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
- W.startLine() << "printNotes not implemented!\n";
+ ListScope L(W, "Notes");
+ const Elf_Ehdr *e = Obj->getHeader();
+ bool IsCore = e->e_type == ELF::ET_CORE;
+
+ auto PrintHeader = [&](const typename ELFT::Off Offset,
+ const typename ELFT::Addr Size) {
+ W.printHex("Offset", Offset);
+ W.printHex("Size", Size);
+ };
+
+ auto ProcessNote = [&](const Elf_Note &Note) {
+ DictScope D2(W, "Note");
+ StringRef Name = Note.getName();
+ ArrayRef<Elf_Word> Descriptor = Note.getDesc();
+ Elf_Word Type = Note.getType();
+
+ 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", getAMDGPUNoteTypeName(Type));
+ const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
+ if (!N.type.empty())
+ W.printString(N.type, N.value);
+ } else {
+ W.getOStream() << "Unknown note type: (" << format_hex(Type, 10) << ')';
+ }
+ };
+
+ if (IsCore) {
+ for (const auto &P : unwrapOrError(Obj->program_headers())) {
+ if (P.p_type != PT_NOTE)
+ continue;
+ DictScope D(W, "NoteSection");
+ PrintHeader(P.p_offset, P.p_filesz);
+ Error Err = Error::success();
+ for (const auto &Note : Obj->notes(P, Err))
+ ProcessNote(Note);
+ if (Err)
+ error(std::move(Err));
+ }
+ } else {
+ for (const auto &S : unwrapOrError(Obj->sections())) {
+ if (S.sh_type != SHT_NOTE)
+ continue;
+ DictScope D(W, "NoteSection");
+ PrintHeader(S.sh_offset, S.sh_size);
+ Error Err = Error::success();
+ for (const auto &Note : Obj->notes(S, Err))
+ ProcessNote(Note);
+ if (Err)
+ error(std::move(Err));
+ }
+ }
}
template <class ELFT>
More information about the llvm-commits
mailing list