[llvm] [PAC][llvm-readobj][AArch64][ELF] Support `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` (PR #85231)

Daniil Kovalev via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 25 00:25:20 PDT 2024


https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/85231

>From 34bae39444c16080852539b6cd9ca003f01bd984 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 12 Mar 2024 20:40:16 +0300
Subject: [PATCH 1/5] [PAC][llvm-readobj][AArch64][ELF] Support
 `GNU_PROPERTY_AARCH64_FEATURE_PAUTH`

This adds support for `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` feature
handling in llvm-readobj and llvm-readelf. The following constants for
supported platforms are also introduced:

- `AARCH64_PAUTH_PLATFORM_INVALID = 0x0`
- `AARCH64_PAUTH_PLATFORM_BAREMETAL = 0x1`
- `AARCH64_PAUTH_PLATFORM_LLVM_LINUX = 0x10000002`

For the llvm_linux platform, output of the tools contains descriptions of
PAuth features which are enabled/disabled depending on the version value.
Version value bits correspond to the following `LangOptions`:

- bit 0: `PointerAuthIntrinsics`;
- bit 1: `PointerAuthCalls`;
- bit 2: `PointerAuthReturns`;
- bit 3: `PointerAuthAuthTraps`;
- bit 4: `PointerAuthVTPtrAddressDiscrimination`;
- bit 5: `PointerAuthVTPtrTypeDiscrimination`;
- bit 6: `PointerAuthInitFini`.

Support for `.note.AARCH64-PAUTH-ABI-tag` is dropped since it's deleted
from the spec in https://github.com/ARM-software/abi-aa/pull/250.
---
 llvm/include/llvm/BinaryFormat/ELF.h          |  26 +-
 .../ELF/AArch64/aarch64-feature-pauth.s       | 282 ++++++++++++------
 .../ELF/AArch64/aarch64-note-gnu-property.s   |   2 +
 llvm/tools/llvm-readobj/ELFDumper.cpp         | 140 +++++----
 4 files changed, 289 insertions(+), 161 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index bace3a92677a82..ca01be089c47f2 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1710,11 +1710,6 @@ enum {
   NT_ANDROID_TYPE_MEMTAG = 4,
 };
 
-// ARM note types.
-enum {
-  NT_ARM_TYPE_PAUTH_ABI_TAG = 1,
-};
-
 // Memory tagging values used in NT_ANDROID_TYPE_MEMTAG notes.
 enum {
   // Enumeration to determine the tagging mode. In Android-land, 'SYNC' means
@@ -1738,6 +1733,7 @@ enum : unsigned {
   GNU_PROPERTY_STACK_SIZE = 1,
   GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2,
   GNU_PROPERTY_AARCH64_FEATURE_1_AND = 0xc0000000,
+  GNU_PROPERTY_AARCH64_FEATURE_PAUTH = 0xc0000001,
   GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002,
 
   GNU_PROPERTY_X86_UINT32_OR_LO = 0xc0008000,
@@ -1756,6 +1752,26 @@ enum : unsigned {
   GNU_PROPERTY_AARCH64_FEATURE_1_GCS = 1 << 2,
 };
 
+// aarch64 PAuth platforms.
+enum : unsigned {
+  AARCH64_PAUTH_PLATFORM_INVALID = 0x0,
+  AARCH64_PAUTH_PLATFORM_BAREMETAL = 0x1,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX = 0x10000002,
+};
+
+// Bit positions of version flags for AARCH64_PAUTH_PLATFORM_LLVM_LINUX.
+enum : unsigned {
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS = 0,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS = 1,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS = 2,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS = 3,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR = 4,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR = 5,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI = 6,
+  AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST =
+      AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI,
+};
+
 // x86 processor feature bits.
 enum : unsigned {
   GNU_PROPERTY_X86_FEATURE_1_IBT = 1 << 0,
diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
index f28d92eae85754..3f171acde8eb92 100644
--- a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
@@ -1,98 +1,188 @@
 # RUN: rm -rf %t && split-file %s %t && cd %t
 
-# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag.s       -o tag.o
-# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o tag-short.o
-# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-long.s  -o tag-long.o
-
-# RUN: llvm-readelf --notes tag.o       | FileCheck --check-prefix NORMAL %s
-# RUN: llvm-readelf --notes tag-short.o | FileCheck --check-prefix SHORT  %s
-# RUN: llvm-readelf --notes tag-long.o  | FileCheck --check-prefix LONG   %s
-
-# NORMAL: AArch64 PAuth ABI tag: platform 0x2a, version 0x1
-# SHORT:  AArch64 PAuth ABI tag: <corrupted size: expected at least 16, got 12>
-# LONG:   AArch64 PAuth ABI tag: platform 0x2a, version 0x1, additional info 0xEFCDAB8967452301
-
-# RUN: llvm-readobj --notes tag.o       | FileCheck --check-prefix LLVM-NORMAL %s
-# RUN: llvm-readobj --notes tag-short.o | FileCheck --check-prefix LLVM-SHORT %s
-# RUN: llvm-readobj --notes tag-long.o  | FileCheck --check-prefix LLVM-LONG %s
-
-# LLVM-SHORT:      Notes [
-# LLVM-SHORT-NEXT:   NoteSection {
-# LLVM-SHORT-NEXT:     Name: .note.AARCH64-PAUTH-ABI-tag
-# LLVM-SHORT-NEXT:     Offset: 0x40
-# LLVM-SHORT-NEXT:     Size: 0x1C
-# LLVM-SHORT-NEXT:     Note {
-# LLVM-SHORT-NEXT:       Owner: ARM
-# LLVM-SHORT-NEXT:       Data size: 0xC
-# LLVM-SHORT-NEXT:       Type: NT_ARM_TYPE_PAUTH_ABI_TAG
-# LLVM-SHORT-NEXT:       Description data (
-# LLVM-SHORT-NEXT:         0000: 2A000000 00000000 01000000
-# LLVM-SHORT-NEXT:       )
-# LLVM-SHORT-NEXT:     }
-# LLVM-SHORT-NEXT:   }
-# LLVM-SHORT-NEXT: ]
-
-# LLVM-NORMAL:      Notes [
-# LLVM-NORMAL-NEXT:   NoteSection {
-# LLVM-NORMAL-NEXT:     Name: .note.AARCH64-PAUTH-ABI-tag
-# LLVM-NORMAL-NEXT:     Offset: 0x40
-# LLVM-NORMAL-NEXT:     Size: 0x20
-# LLVM-NORMAL-NEXT:     Note {
-# LLVM-NORMAL-NEXT:       Owner: ARM
-# LLVM-NORMAL-NEXT:       Data size: 0x10
-# LLVM-NORMAL-NEXT:       Type: NT_ARM_TYPE_PAUTH_ABI_TAG
-# LLVM-NORMAL-NEXT:       Platform: 42
-# LLVM-NORMAL-NEXT:       Version: 1
-# LLVM-NORMAL-NEXT:     }
-# LLVM-NORMAL-NEXT:   }
-# LLVM-NORMAL-NEXT: ]
-
-# LLVM-LONG:      Notes [
-# LLVM-LONG-NEXT:   NoteSection {
-# LLVM-LONG-NEXT:     Name: .note.AARCH64-PAUTH-ABI-tag
-# LLVM-LONG-NEXT:     Offset: 0x40
-# LLVM-LONG-NEXT:     Size: 0x28
-# LLVM-LONG-NEXT:     Note {
-# LLVM-LONG-NEXT:       Owner: ARM
-# LLVM-LONG-NEXT:       Data size: 0x18
-# LLVM-LONG-NEXT:       Type: NT_ARM_TYPE_PAUTH_ABI_TAG
-# LLVM-LONG-NEXT:       Platform: 42
-# LLVM-LONG-NEXT:       Version: 1
-# LLVM-LONG-NEXT:       Additional info: EFCDAB8967452301
-# LLVM-LONG-NEXT:     }
-# LLVM-LONG-NEXT:   }
-# LLVM-LONG-NEXT: ]
-
-#--- abi-tag.s
-
-.section ".note.AARCH64-PAUTH-ABI-tag", "a"
-.long 4
-.long 16
-.long 1
-.asciz "ARM"
-
-.quad 42         // platform
-.quad 1          // version
-
-#--- abi-tag-short.s
-
-.section ".note.AARCH64-PAUTH-ABI-tag", "a"
-.long 4
-.long 12
-.long 1
-.asciz "ARM"
-
-.quad 42
-.word 1
-
-#--- abi-tag-long.s
-
-.section ".note.AARCH64-PAUTH-ABI-tag", "a"
-.long 4
-.long 24
-.long 1
-.asciz "ARM"
-
-.quad 42         // platform
-.quad 1          // version
-.quad 0x0123456789ABCDEF // extra data
+#--- gnu-42-1.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 16          /* Data size */
+  .quad 42          /* PAuth ABI platform */
+  .quad 1           /* PAuth ABI version */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-42-1.s -o gnu-42-1.o
+# RUN: llvm-readelf --notes gnu-42-1.o | \
+# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
+# RUN: llvm-readobj --notes gnu-42-1.o | \
+# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
+
+# ELF-GNU: Displaying notes found in: .note.gnu.property
+# ELF-GNU-NEXT:   Owner                 Data size	Description
+# ELF-GNU-NEXT:   GNU                   0x00000018	NT_GNU_PROPERTY_TYPE_0 (property note)
+# ELF-GNU-NEXT:   AArch64 PAuth ABI core info: platform [[PLATFORM]], version [[VERSION]]
+
+# OBJ-GNU:      Notes [
+# OBJ-GNU-NEXT:   NoteSection {
+# OBJ-GNU-NEXT:     Name: .note.gnu.property
+# OBJ-GNU-NEXT:     Offset: 0x40
+# OBJ-GNU-NEXT:     Size: 0x28
+# OBJ-GNU-NEXT:     Note {
+# OBJ-GNU-NEXT:       Owner: GNU
+# OBJ-GNU-NEXT:       Data size: 0x18
+# OBJ-GNU-NEXT:       Type: NT_GNU_PROPERTY_TYPE_0 (property note)
+# OBJ-GNU-NEXT:       Property [
+# OBJ-GNU-NEXT:         AArch64 PAuth ABI core info: platform [[PLATFORM]], version [[VERSION]]
+# OBJ-GNU-NEXT:       ]
+# OBJ-GNU-NEXT:     }
+# OBJ-GNU-NEXT:   }
+# OBJ-GNU-NEXT: ]
+
+#--- gnu-0-0.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 16          /* Data size */
+  .quad 0           /* PAuth ABI platform */
+  .quad 0           /* PAuth ABI version */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-0-0.s -o gnu-0-0.o
+# RUN: llvm-readelf --notes gnu-0-0.o | \
+# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
+# RUN: llvm-readobj --notes gnu-0-0.o | \
+# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
+
+#--- gnu-1-0.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 16          /* Data size */
+  .quad 1           /* PAuth ABI platform */
+  .quad 0           /* PAuth ABI version */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-1-0.s -o gnu-1-0.o
+# RUN: llvm-readelf --notes gnu-1-0.o | \
+# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
+# RUN: llvm-readobj --notes gnu-1-0.o | \
+# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
+
+#--- gnu-0x10000002-85.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 16          /* Data size */
+  .quad 0x10000002  /* PAuth ABI platform */
+  .quad 85          /* PAuth ABI version */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-0x10000002-85.s -o gnu-0x10000002-85.o
+# RUN: llvm-readelf --notes gnu-0x10000002-85.o | \
+# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x10000002 (llvm_linux)" \
+# RUN:   -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
+# RUN: llvm-readobj --notes gnu-0x10000002-85.o | \
+# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x10000002 (llvm_linux)" \
+# RUN:   -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
+
+#--- gnu-short.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 12          /* Data size */
+  .quad 42          /* PAuth ABI platform */
+  .word 1           /* PAuth ABI version */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-short.s -o gnu-short.o
+# RUN: llvm-readelf --notes gnu-short.o | \
+# RUN:   FileCheck --check-prefix=ELF-GNU-ERR -DSIZE=28 -DDATASIZE=18 \
+# RUN:   -DERR="<corrupted size: expected 16, got 12>" %s
+# RUN: llvm-readobj --notes gnu-short.o | \
+# RUN:   FileCheck --check-prefix=OBJ-GNU-ERR -DSIZE=28 -DDATASIZE=18 \
+# RUN:   -DERR="<corrupted size: expected 16, got 12>" %s
+
+# ELF-GNU-ERR: Displaying notes found in: .note.gnu.property
+# ELF-GNU-ERR-NEXT:   Owner                 Data size	Description
+# ELF-GNU-ERR-NEXT:   GNU                   0x000000[[DATASIZE]]	NT_GNU_PROPERTY_TYPE_0 (property note)
+# ELF-GNU-ERR-NEXT:   AArch64 PAuth ABI core info: [[ERR]]
+
+# OBJ-GNU-ERR:      Notes [
+# OBJ-GNU-ERR-NEXT:   NoteSection {
+# OBJ-GNU-ERR-NEXT:     Name: .note.gnu.property
+# OBJ-GNU-ERR-NEXT:     Offset: 0x40
+# OBJ-GNU-ERR-NEXT:     Size: 0x[[SIZE]]
+# OBJ-GNU-ERR-NEXT:     Note {
+# OBJ-GNU-ERR-NEXT:       Owner: GNU
+# OBJ-GNU-ERR-NEXT:       Data size: 0x[[DATASIZE]]
+# OBJ-GNU-ERR-NEXT:       Type: NT_GNU_PROPERTY_TYPE_0 (property note)
+# OBJ-GNU-ERR-NEXT:       Property [
+# OBJ-GNU-ERR-NEXT:         AArch64 PAuth ABI core info: [[ERR]]
+# OBJ-GNU-ERR-NEXT:       ]
+# OBJ-GNU-ERR-NEXT:     }
+# OBJ-GNU-ERR-NEXT:   }
+# OBJ-GNU-ERR-NEXT: ]
+
+#--- gnu-long.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 24          /* Data size */
+  .quad 42          /* PAuth ABI platform */
+  .quad 1           /* PAuth ABI version */
+  .quad 0x0123456789ABCDEF
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-long.s -o gnu-long.o
+# RUN: llvm-readelf --notes gnu-long.o | \
+# RUN:   FileCheck --check-prefix=ELF-GNU-ERR -DSIZE=30 -DDATASIZE=20 \
+# RUN:   -DERR="<corrupted size: expected 16, got 24>" %s
+# RUN: llvm-readobj --notes gnu-long.o | \
+# RUN:   FileCheck --check-prefix=OBJ-GNU-ERR -DSIZE=30 -DDATASIZE=20 \
+# RUN:   -DERR="<corrupted size: expected 16, got 24>" %s
diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-note-gnu-property.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-note-gnu-property.s
index 377e6f93448ca7..b517f0b3815547 100644
--- a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-note-gnu-property.s
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-note-gnu-property.s
@@ -1,3 +1,5 @@
+// See tests for GNU_PROPERTY_AARCH64_FEATURE_PAUTH in aarch64-feature-pauth.s
+
 // RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu %s -o %t
 // RUN: llvm-readelf --notes %t | FileCheck %s --check-prefix=GNU
 // RUN: llvm-readobj --notes %t | FileCheck %s --check-prefix=LLVM
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index e78732353cc877..ff620e944e1b56 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -5098,6 +5098,83 @@ 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::TargetEndianness>(Desc.data() + 0);
+  uint64_t Version =
+      support::endian::read64<ELFT::TargetEndianness>(Desc.data() + 8);
+
+  std::string 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";
+    return std::string("") +
+           ((Version &
+             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS))
+                ? ""
+                : "!") +
+           "PointerAuthIntrinsics, " +
+           ((Version & (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS))
+                ? ""
+                : "!") +
+           "PointerAuthCalls, " +
+           ((Version & (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS))
+                ? ""
+                : "!") +
+           "PointerAuthReturns, " +
+           ((Version &
+             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS))
+                ? ""
+                : "!") +
+           "PointerAuthAuthTraps, " +
+           ((Version &
+             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR))
+                ? ""
+                : "!") +
+           "PointerAuthVTPtrAddressDiscrimination, " +
+           ((Version &
+             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR))
+                ? ""
+                : "!") +
+           "PointerAuthVTPtrTypeDiscrimination, " +
+           ((Version &
+             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI))
+                ? ""
+                : "!") +
+           "PointerAuthInitFini";
+  }();
+
+  OS << format("platform 0x%x (%s), version 0x%x", Platform,
+               PlatformDesc.c_str(), 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) {
@@ -5155,6 +5232,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 "
@@ -5356,31 +5436,6 @@ static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType,
   return true;
 }
 
-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 =
-      support::endian::read64<ELFT::TargetEndianness>(Desc.data() + 0);
-  uint64_t Version =
-      support::endian::read64<ELFT::TargetEndianness>(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,
@@ -5780,10 +5835,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)"},
@@ -5902,8 +5953,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);
@@ -6059,9 +6108,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:";
@@ -7699,29 +7745,6 @@ static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
   return true;
 }
 
-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 =
-      support::endian::read64<ELFT::TargetEndianness>(Desc.data() + 0);
-  uint64_t version =
-      support::endian::read64<ELFT::TargetEndianness>(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,
@@ -7858,9 +7881,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);

>From d2c4d2a69b4112815e68f6eff0f58ef837bed4b3 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 19 Mar 2024 18:14:21 +0300
Subject: [PATCH 2/5] Simplify check prefixes

---
 .../ELF/AArch64/aarch64-feature-pauth.s       | 106 +++++++++---------
 1 file changed, 53 insertions(+), 53 deletions(-)

diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
index 3f171acde8eb92..7d901712c45107 100644
--- a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
@@ -19,30 +19,30 @@ end:
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-42-1.s -o gnu-42-1.o
 # RUN: llvm-readelf --notes gnu-42-1.o | \
-# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
+# RUN:   FileCheck --check-prefix=ELF -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
 # RUN: llvm-readobj --notes gnu-42-1.o | \
-# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
-
-# ELF-GNU: Displaying notes found in: .note.gnu.property
-# ELF-GNU-NEXT:   Owner                 Data size	Description
-# ELF-GNU-NEXT:   GNU                   0x00000018	NT_GNU_PROPERTY_TYPE_0 (property note)
-# ELF-GNU-NEXT:   AArch64 PAuth ABI core info: platform [[PLATFORM]], version [[VERSION]]
-
-# OBJ-GNU:      Notes [
-# OBJ-GNU-NEXT:   NoteSection {
-# OBJ-GNU-NEXT:     Name: .note.gnu.property
-# OBJ-GNU-NEXT:     Offset: 0x40
-# OBJ-GNU-NEXT:     Size: 0x28
-# OBJ-GNU-NEXT:     Note {
-# OBJ-GNU-NEXT:       Owner: GNU
-# OBJ-GNU-NEXT:       Data size: 0x18
-# OBJ-GNU-NEXT:       Type: NT_GNU_PROPERTY_TYPE_0 (property note)
-# OBJ-GNU-NEXT:       Property [
-# OBJ-GNU-NEXT:         AArch64 PAuth ABI core info: platform [[PLATFORM]], version [[VERSION]]
-# OBJ-GNU-NEXT:       ]
-# OBJ-GNU-NEXT:     }
-# OBJ-GNU-NEXT:   }
-# OBJ-GNU-NEXT: ]
+# RUN:   FileCheck --check-prefix=OBJ -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
+
+# ELF: Displaying notes found in: .note.gnu.property
+# ELF-NEXT:   Owner                 Data size	Description
+# ELF-NEXT:   GNU                   0x00000018	NT_GNU_PROPERTY_TYPE_0 (property note)
+# ELF-NEXT:   AArch64 PAuth ABI core info: platform [[PLATFORM]], version [[VERSION]]
+
+# OBJ:      Notes [
+# OBJ-NEXT:   NoteSection {
+# OBJ-NEXT:     Name: .note.gnu.property
+# OBJ-NEXT:     Offset: 0x40
+# OBJ-NEXT:     Size: 0x28
+# OBJ-NEXT:     Note {
+# OBJ-NEXT:       Owner: GNU
+# OBJ-NEXT:       Data size: 0x18
+# OBJ-NEXT:       Type: NT_GNU_PROPERTY_TYPE_0 (property note)
+# OBJ-NEXT:       Property [
+# OBJ-NEXT:         AArch64 PAuth ABI core info: platform [[PLATFORM]], version [[VERSION]]
+# OBJ-NEXT:       ]
+# OBJ-NEXT:     }
+# OBJ-NEXT:   }
+# OBJ-NEXT: ]
 
 #--- gnu-0-0.s
 
@@ -63,9 +63,9 @@ end:
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-0-0.s -o gnu-0-0.o
 # RUN: llvm-readelf --notes gnu-0-0.o | \
-# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
+# RUN:   FileCheck --check-prefix=ELF -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
 # RUN: llvm-readobj --notes gnu-0-0.o | \
-# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
+# RUN:   FileCheck --check-prefix=OBJ -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
 
 #--- gnu-1-0.s
 
@@ -86,9 +86,9 @@ end:
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-1-0.s -o gnu-1-0.o
 # RUN: llvm-readelf --notes gnu-1-0.o | \
-# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
+# RUN:   FileCheck --check-prefix=ELF -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
 # RUN: llvm-readobj --notes gnu-1-0.o | \
-# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
+# RUN:   FileCheck --check-prefix=OBJ -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
 
 #--- gnu-0x10000002-85.s
 
@@ -109,10 +109,10 @@ end:
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-0x10000002-85.s -o gnu-0x10000002-85.o
 # RUN: llvm-readelf --notes gnu-0x10000002-85.o | \
-# RUN:   FileCheck --check-prefix=ELF-GNU -DPLATFORM="0x10000002 (llvm_linux)" \
+# RUN:   FileCheck --check-prefix=ELF -DPLATFORM="0x10000002 (llvm_linux)" \
 # RUN:   -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
 # RUN: llvm-readobj --notes gnu-0x10000002-85.o | \
-# RUN:   FileCheck --check-prefix=OBJ-GNU -DPLATFORM="0x10000002 (llvm_linux)" \
+# RUN:   FileCheck --check-prefix=OBJ -DPLATFORM="0x10000002 (llvm_linux)" \
 # RUN:   -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
 
 #--- gnu-short.s
@@ -134,32 +134,32 @@ end:
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-short.s -o gnu-short.o
 # RUN: llvm-readelf --notes gnu-short.o | \
-# RUN:   FileCheck --check-prefix=ELF-GNU-ERR -DSIZE=28 -DDATASIZE=18 \
+# RUN:   FileCheck --check-prefix=ELF-ERR -DSIZE=28 -DDATASIZE=18 \
 # RUN:   -DERR="<corrupted size: expected 16, got 12>" %s
 # RUN: llvm-readobj --notes gnu-short.o | \
-# RUN:   FileCheck --check-prefix=OBJ-GNU-ERR -DSIZE=28 -DDATASIZE=18 \
+# RUN:   FileCheck --check-prefix=OBJ-ERR -DSIZE=28 -DDATASIZE=18 \
 # RUN:   -DERR="<corrupted size: expected 16, got 12>" %s
 
-# ELF-GNU-ERR: Displaying notes found in: .note.gnu.property
-# ELF-GNU-ERR-NEXT:   Owner                 Data size	Description
-# ELF-GNU-ERR-NEXT:   GNU                   0x000000[[DATASIZE]]	NT_GNU_PROPERTY_TYPE_0 (property note)
-# ELF-GNU-ERR-NEXT:   AArch64 PAuth ABI core info: [[ERR]]
-
-# OBJ-GNU-ERR:      Notes [
-# OBJ-GNU-ERR-NEXT:   NoteSection {
-# OBJ-GNU-ERR-NEXT:     Name: .note.gnu.property
-# OBJ-GNU-ERR-NEXT:     Offset: 0x40
-# OBJ-GNU-ERR-NEXT:     Size: 0x[[SIZE]]
-# OBJ-GNU-ERR-NEXT:     Note {
-# OBJ-GNU-ERR-NEXT:       Owner: GNU
-# OBJ-GNU-ERR-NEXT:       Data size: 0x[[DATASIZE]]
-# OBJ-GNU-ERR-NEXT:       Type: NT_GNU_PROPERTY_TYPE_0 (property note)
-# OBJ-GNU-ERR-NEXT:       Property [
-# OBJ-GNU-ERR-NEXT:         AArch64 PAuth ABI core info: [[ERR]]
-# OBJ-GNU-ERR-NEXT:       ]
-# OBJ-GNU-ERR-NEXT:     }
-# OBJ-GNU-ERR-NEXT:   }
-# OBJ-GNU-ERR-NEXT: ]
+# ELF-ERR: Displaying notes found in: .note.gnu.property
+# ELF-ERR-NEXT:   Owner                 Data size	Description
+# ELF-ERR-NEXT:   GNU                   0x000000[[DATASIZE]]	NT_GNU_PROPERTY_TYPE_0 (property note)
+# ELF-ERR-NEXT:   AArch64 PAuth ABI core info: [[ERR]]
+
+# OBJ-ERR:      Notes [
+# OBJ-ERR-NEXT:   NoteSection {
+# OBJ-ERR-NEXT:     Name: .note.gnu.property
+# OBJ-ERR-NEXT:     Offset: 0x40
+# OBJ-ERR-NEXT:     Size: 0x[[SIZE]]
+# OBJ-ERR-NEXT:     Note {
+# OBJ-ERR-NEXT:       Owner: GNU
+# OBJ-ERR-NEXT:       Data size: 0x[[DATASIZE]]
+# OBJ-ERR-NEXT:       Type: NT_GNU_PROPERTY_TYPE_0 (property note)
+# OBJ-ERR-NEXT:       Property [
+# OBJ-ERR-NEXT:         AArch64 PAuth ABI core info: [[ERR]]
+# OBJ-ERR-NEXT:       ]
+# OBJ-ERR-NEXT:     }
+# OBJ-ERR-NEXT:   }
+# OBJ-ERR-NEXT: ]
 
 #--- gnu-long.s
 
@@ -181,8 +181,8 @@ end:
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-long.s -o gnu-long.o
 # RUN: llvm-readelf --notes gnu-long.o | \
-# RUN:   FileCheck --check-prefix=ELF-GNU-ERR -DSIZE=30 -DDATASIZE=20 \
+# RUN:   FileCheck --check-prefix=ELF-ERR -DSIZE=30 -DDATASIZE=20 \
 # RUN:   -DERR="<corrupted size: expected 16, got 24>" %s
 # RUN: llvm-readobj --notes gnu-long.o | \
-# RUN:   FileCheck --check-prefix=OBJ-GNU-ERR -DSIZE=30 -DDATASIZE=20 \
+# RUN:   FileCheck --check-prefix=OBJ-ERR -DSIZE=30 -DDATASIZE=20 \
 # RUN:   -DERR="<corrupted size: expected 16, got 24>" %s

>From 732c4e61ff45248671f06e0220e143401c9aad99 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 19 Mar 2024 22:45:04 +0300
Subject: [PATCH 3/5] Test invalid version for llvm_linux platform

---
 .../ELF/AArch64/aarch64-feature-pauth.s       | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
index 7d901712c45107..fc44bb6f650370 100644
--- a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
@@ -115,6 +115,29 @@ end:
 # RUN:   FileCheck --check-prefix=OBJ -DPLATFORM="0x10000002 (llvm_linux)" \
 # RUN:   -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
 
+#--- gnu-0x10000002-128.s
+
+.section ".note.gnu.property", "a"
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  /* PAuth ABI property note */
+  .long 0xc0000001  /* Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH */
+  .long 16          /* Data size */
+  .quad 0x10000002  /* PAuth ABI platform */
+  .quad 128         /* PAuth ABI version */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu gnu-0x10000002-128.s -o gnu-0x10000002-128.o
+# RUN: llvm-readelf --notes gnu-0x10000002-128.o | \
+# RUN:   FileCheck --check-prefix=ELF -DPLATFORM="0x10000002 (llvm_linux)" -DVERSION="0x80 (unknown)" %s
+# RUN: llvm-readobj --notes gnu-0x10000002-128.o | \
+# RUN:   FileCheck --check-prefix=OBJ -DPLATFORM="0x10000002 (llvm_linux)" -DVERSION="0x80 (unknown)" %s
+
 #--- gnu-short.s
 
 .section ".note.gnu.property", "a"

>From 8a375228670a32ef66a1a4d6e65540bd9afefa5b Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 20 Mar 2024 00:27:04 +0300
Subject: [PATCH 4/5] Add static assertion against number of pauth flags

---
 llvm/tools/llvm-readobj/ELFDumper.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index ff620e944e1b56..9c888cf26b68a6 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -5165,6 +5165,9 @@ static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize,
                 ? ""
                 : "!") +
            "PointerAuthInitFini";
+    static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI ==
+                      AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
+                  "Update when new enum items are defined");
   }();
 
   OS << format("platform 0x%x (%s), version 0x%x", Platform,

>From 8b562626454a9f6f9f9e41b8f84e17535924104d Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 25 Mar 2024 10:24:23 +0300
Subject: [PATCH 5/5] Address review comments

---
 llvm/tools/llvm-readobj/ELFDumper.cpp | 63 +++++++++++----------------
 1 file changed, 26 insertions(+), 37 deletions(-)

diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 692f703128460d..35809d75fb9ea5 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>
@@ -5119,7 +5120,7 @@ static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize,
   uint64_t Version =
       support::endian::read64<ELFT::TargetEndianness>(Desc.data() + 8);
 
-  std::string PlatformDesc = [Platform]() {
+  const char *PlatformDesc = [Platform]() {
     switch (Platform) {
     case AARCH64_PAUTH_PLATFORM_INVALID:
       return "invalid";
@@ -5137,47 +5138,35 @@ static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize,
       return "";
     if (Version >= (1 << (AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1)))
       return "unknown";
-    return std::string("") +
-           ((Version &
-             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS))
-                ? ""
-                : "!") +
-           "PointerAuthIntrinsics, " +
-           ((Version & (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS))
-                ? ""
-                : "!") +
-           "PointerAuthCalls, " +
-           ((Version & (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS))
-                ? ""
-                : "!") +
-           "PointerAuthReturns, " +
-           ((Version &
-             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS))
-                ? ""
-                : "!") +
-           "PointerAuthAuthTraps, " +
-           ((Version &
-             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR))
-                ? ""
-                : "!") +
-           "PointerAuthVTPtrAddressDiscrimination, " +
-           ((Version &
-             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR))
-                ? ""
-                : "!") +
-           "PointerAuthVTPtrTypeDiscrimination, " +
-           ((Version &
-             (1 << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI))
-                ? ""
-                : "!") +
-           "PointerAuthInitFini";
+
+    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; I < Flags.size(); ++I) {
+      if (!(Version & (1 << I)))
+        Desc += '!';
+      Desc += Twine("PointerAuth" + Flags[I] + ", ").str();
+    }
+    Desc.resize(Desc.size() - 2); // Trim last ", "
+    return Desc;
   }();
 
-  OS << format("platform 0x%x (%s), version 0x%x", Platform,
-               PlatformDesc.c_str(), Version);
+  OS << format("platform 0x%x (%s), version 0x%x", Platform, PlatformDesc,
+               Version);
   if (!VersionDesc.empty())
     OS << format(" (%s)", VersionDesc.c_str());
 



More information about the llvm-commits mailing list