summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj/ELFDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp127
1 files changed, 71 insertions, 56 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 4b406ef12aec..d3534820c117 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -61,6 +61,7 @@
#include "llvm/Support/SystemZ/zOSSupport.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <array>
#include <cinttypes>
#include <cstddef>
#include <cstdint>
@@ -5105,6 +5106,73 @@ template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() {
}
}
+template <class ELFT>
+static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize,
+ ArrayRef<uint8_t> Desc) {
+ OS << " AArch64 PAuth ABI core info: ";
+ // DataSize - size without padding, Desc.size() - size with padding
+ if (DataSize != 16) {
+ OS << format("<corrupted size: expected 16, got %d>", DataSize);
+ return false;
+ }
+
+ uint64_t Platform =
+ support::endian::read64<ELFT::Endianness>(Desc.data() + 0);
+ uint64_t Version = support::endian::read64<ELFT::Endianness>(Desc.data() + 8);
+
+ const char *PlatformDesc = [Platform]() {
+ switch (Platform) {
+ case AARCH64_PAUTH_PLATFORM_INVALID:
+ return "invalid";
+ case AARCH64_PAUTH_PLATFORM_BAREMETAL:
+ return "baremetal";
+ case AARCH64_PAUTH_PLATFORM_LLVM_LINUX:
+ return "llvm_linux";
+ default:
+ return "unknown";
+ }
+ }();
+
+ std::string VersionDesc = [Platform, Version]() -> std::string {
+ if (Platform != AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
+ return "";
+ if (Version >= (1 << (AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1)))
+ return "unknown";
+
+ std::array<StringRef, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1>
+ Flags;
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS] = "Intrinsics";
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS] = "Calls";
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS] = "Returns";
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS] = "AuthTraps";
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR] =
+ "VTPtrAddressDiscrimination";
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR] =
+ "VTPtrTypeDiscrimination";
+ Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI] = "InitFini";
+
+ static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI ==
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
+ "Update when new enum items are defined");
+
+ std::string Desc;
+ for (uint32_t I = 0, End = Flags.size(); I < End; ++I) {
+ if (!(Version & (1ULL << I)))
+ Desc += '!';
+ Desc +=
+ Twine("PointerAuth" + Flags[I] + (I == End - 1 ? "" : ", ")).str();
+ }
+ return Desc;
+ }();
+
+ OS << format("platform 0x%" PRIx64 " (%s), version 0x%" PRIx64, Platform,
+ PlatformDesc, Version);
+ if (!VersionDesc.empty())
+ OS << format(" (%s)", VersionDesc.c_str());
+
+ return true;
+}
+
template <typename ELFT>
static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
ArrayRef<uint8_t> Data) {
@@ -5162,6 +5230,9 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
if (PrData)
OS << format("<unknown flags: 0x%x>", PrData);
return OS.str();
+ case GNU_PROPERTY_AARCH64_FEATURE_PAUTH:
+ printAArch64PAuthABICoreInfo<ELFT>(OS, DataSize, Data);
+ return OS.str();
case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
case GNU_PROPERTY_X86_FEATURE_2_USED:
OS << "x86 feature "
@@ -5364,29 +5435,6 @@ static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType,
}
template <class ELFT>
-static bool printAArch64Note(raw_ostream &OS, uint32_t NoteType,
- ArrayRef<uint8_t> Desc) {
- if (NoteType != NT_ARM_TYPE_PAUTH_ABI_TAG)
- return false;
-
- OS << " AArch64 PAuth ABI tag: ";
- if (Desc.size() < 16) {
- OS << format("<corrupted size: expected at least 16, got %d>", Desc.size());
- return false;
- }
-
- uint64_t Platform = endian::read64<ELFT::Endianness>(Desc.data() + 0);
- uint64_t Version = endian::read64<ELFT::Endianness>(Desc.data() + 8);
- OS << format("platform 0x%" PRIx64 ", version 0x%" PRIx64, Platform, Version);
-
- if (Desc.size() > 16)
- OS << ", additional info 0x"
- << toHex(ArrayRef<uint8_t>(Desc.data() + 16, Desc.size() - 16));
-
- return true;
-}
-
-template <class ELFT>
void GNUELFDumper<ELFT>::printMemtag(
const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
const ArrayRef<uint8_t> AndroidNoteDesc,
@@ -5783,10 +5831,6 @@ const NoteType AndroidNoteTypes[] = {
"NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"},
};
-const NoteType ARMNoteTypes[] = {
- {ELF::NT_ARM_TYPE_PAUTH_ABI_TAG, "NT_ARM_TYPE_PAUTH_ABI_TAG"},
-};
-
const NoteType CoreNoteTypes[] = {
{ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"},
{ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"},
@@ -5905,8 +5949,6 @@ StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) {
return FindNote(LLVMOMPOFFLOADNoteTypes);
if (Name == "Android")
return FindNote(AndroidNoteTypes);
- if (Name == "ARM")
- return FindNote(ARMNoteTypes);
if (ELFType == ELF::ET_CORE)
return FindNote(CoreNoteTypes);
@@ -6062,9 +6104,6 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
} else if (Name == "Android") {
if (printAndroidNote(OS, Type, Descriptor))
return Error::success();
- } else if (Name == "ARM") {
- if (printAArch64Note<ELFT>(OS, Type, Descriptor))
- return Error::success();
}
if (!Descriptor.empty()) {
OS << " description data:";
@@ -7703,27 +7742,6 @@ static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
}
template <class ELFT>
-static bool printAarch64NoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
- ScopedPrinter &W) {
- if (NoteType != NT_ARM_TYPE_PAUTH_ABI_TAG)
- return false;
-
- if (Desc.size() < 16)
- return false;
-
- uint64_t platform = endian::read64<ELFT::Endianness>(Desc.data() + 0);
- uint64_t version = endian::read64<ELFT::Endianness>(Desc.data() + 8);
- W.printNumber("Platform", platform);
- W.printNumber("Version", version);
-
- if (Desc.size() > 16)
- W.printString("Additional info",
- toHex(ArrayRef<uint8_t>(Desc.data() + 16, Desc.size() - 16)));
-
- return true;
-}
-
-template <class ELFT>
void LLVMELFDumper<ELFT>::printMemtag(
const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
const ArrayRef<uint8_t> AndroidNoteDesc,
@@ -7859,9 +7877,6 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
} else if (Name == "Android") {
if (printAndroidNoteLLVMStyle(Type, Descriptor, W))
return Error::success();
- } else if (Name == "ARM") {
- if (printAarch64NoteLLVMStyle<ELFT>(Type, Descriptor, W))
- return Error::success();
}
if (!Descriptor.empty()) {
W.printBinaryBlock("Description data", Descriptor);