[llvm] [llvm-readobj][AArch64][ELF][PAC] Support `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` (PR #85231)
Daniil Kovalev via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 14 07:47:25 PDT 2024
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/85231
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` defined in TODO:
- bit 0: `PointerAuthIntrinsics`;
- bit 1: `PointerAuthCalls`;
- bit 2: `PointerAuthReturns`;
- bit 3: `PointerAuthAuthTraps`;
- bit 4: `PointerAuthVTPtrAddressDiscrimination`;
- bit 5: `PointerAuthVTPtrTypeDiscrimination`;
- bit 6: `PointerAuthInitFini`.
>From 60d93466a31cdad36aa64dd065d183ad83f052d2 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] [llvm-readobj][AArch64][ELF][PAC] 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`.
---
llvm/include/llvm/BinaryFormat/ELF.h | 8 +
.../ELF/AArch64/aarch64-feature-pauth.s | 395 +++++++++++++++---
.../ELF/AArch64/aarch64-note-gnu-property.s | 2 +
llvm/tools/llvm-readobj/ELFDumper.cpp | 102 +++--
4 files changed, 413 insertions(+), 94 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index bace3a92677a82..178461daaf1a05 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1738,6 +1738,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 +1757,13 @@ 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,
+};
+
// 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..526e7debf769ec 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,69 +1,6 @@
# 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
+#--- tag-42-1.s
.section ".note.AARCH64-PAUTH-ABI-tag", "a"
.long 4
@@ -74,7 +11,101 @@
.quad 42 // platform
.quad 1 // version
-#--- abi-tag-short.s
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu tag-42-1.s -o tag-42-1.o
+# RUN: llvm-readelf --notes tag-42-1.o | \
+# RUN: FileCheck --check-prefix ELF-TAG -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
+# RUN: llvm-readobj --notes tag-42-1.o | \
+# RUN: FileCheck --check-prefix OBJ-TAG -DPLATFORM=42 -DPLATFORMDESC=unknown -DVERSION=1 %s
+
+# ELF-TAG: AArch64 PAuth ABI tag: platform [[PLATFORM]], version [[VERSION]]
+
+# OBJ-TAG: Notes [
+# OBJ-TAG-NEXT: NoteSection {
+# OBJ-TAG-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
+# OBJ-TAG-NEXT: Offset: 0x40
+# OBJ-TAG-NEXT: Size: 0x20
+# OBJ-TAG-NEXT: Note {
+# OBJ-TAG-NEXT: Owner: ARM
+# OBJ-TAG-NEXT: Data size: 0x10
+# OBJ-TAG-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
+# OBJ-TAG-NEXT: Platform: [[PLATFORM]]
+# OBJ-TAG-NEXT: PlatformDesc: [[PLATFORMDESC]]
+# OBJ-TAG-NEXT: Version: [[VERSION]]
+# OBJ-TAG-NEXT: }
+# OBJ-TAG-NEXT: }
+# OBJ-TAG-NEXT: ]
+
+#--- tag-0-0.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 16
+.long 1
+.asciz "ARM"
+
+.quad 0 // platform
+.quad 0 // version
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu tag-0-0.s -o tag-0-0.o
+# RUN: llvm-readelf --notes tag-0-0.o | \
+# RUN: FileCheck --check-prefix ELF-TAG -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
+# RUN: llvm-readobj --notes tag-0-0.o | \
+# RUN: FileCheck --check-prefix OBJ-TAG -DPLATFORM=0 -DPLATFORMDESC=invalid -DVERSION=0 %s
+
+#--- tag-1-0.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 16
+.long 1
+.asciz "ARM"
+
+.quad 1 // platform
+.quad 0 // version
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu tag-1-0.s -o tag-1-0.o
+# RUN: llvm-readelf --notes tag-1-0.o | \
+# RUN: FileCheck --check-prefix ELF-TAG -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
+# RUN: llvm-readobj --notes tag-1-0.o | \
+# RUN: FileCheck --check-prefix OBJ-TAG -DPLATFORM=1 -DPLATFORMDESC=baremetal -DVERSION=0 %s
+
+#--- tag-0x10000002-85.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 16
+.long 1
+.asciz "ARM"
+
+.quad 0x10000002 // platform
+.quad 85 // version
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu tag-0x10000002-85.s -o tag-0x10000002-85.o
+# RUN: llvm-readelf --notes tag-0x10000002-85.o | \
+# RUN: FileCheck --check-prefix ELF-TAG -DPLATFORM="0x10000002 (llvm_linux)" \
+# RUN: -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
+# RUN: llvm-readobj --notes tag-0x10000002-85.o | \
+# RUN: FileCheck --check-prefix OBJ-TAG-LINUX -DPLATFORM=268435458 -DPLATFORMDESC=llvm_linux -DVERSION=85 \
+# RUN: -DVERSIONDESC="PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini" %s
+
+# OBJ-TAG-LINUX: Notes [
+# OBJ-TAG-LINUX-NEXT: NoteSection {
+# OBJ-TAG-LINUX-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
+# OBJ-TAG-LINUX-NEXT: Offset: 0x40
+# OBJ-TAG-LINUX-NEXT: Size: 0x20
+# OBJ-TAG-LINUX-NEXT: Note {
+# OBJ-TAG-LINUX-NEXT: Owner: ARM
+# OBJ-TAG-LINUX-NEXT: Data size: 0x10
+# OBJ-TAG-LINUX-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
+# OBJ-TAG-LINUX-NEXT: Platform: [[PLATFORM]]
+# OBJ-TAG-LINUX-NEXT: PlatformDesc: [[PLATFORMDESC]]
+# OBJ-TAG-LINUX-NEXT: Version: [[VERSION]]
+# OBJ-TAG-LINUX-NEXT: VersionDesc: [[VERSIONDESC]]
+# OBJ-TAG-LINUX-NEXT: }
+# OBJ-TAG-LINUX-NEXT: }
+# OBJ-TAG-LINUX-NEXT: ]
+
+#--- tag-short.s
.section ".note.AARCH64-PAUTH-ABI-tag", "a"
.long 4
@@ -85,7 +116,29 @@
.quad 42
.word 1
-#--- abi-tag-long.s
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu tag-short.s -o tag-short.o
+# RUN: llvm-readelf --notes tag-short.o | FileCheck --check-prefix ELF-TAG-SHORT %s
+# RUN: llvm-readobj --notes tag-short.o | FileCheck --check-prefix OBJ-TAG-SHORT %s
+
+# ELF-TAG-SHORT: AArch64 PAuth ABI tag: <corrupted size: expected 16, got 12>
+
+# OBJ-TAG-SHORT: Notes [
+# OBJ-TAG-SHORT-NEXT: NoteSection {
+# OBJ-TAG-SHORT-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
+# OBJ-TAG-SHORT-NEXT: Offset: 0x40
+# OBJ-TAG-SHORT-NEXT: Size: 0x1C
+# OBJ-TAG-SHORT-NEXT: Note {
+# OBJ-TAG-SHORT-NEXT: Owner: ARM
+# OBJ-TAG-SHORT-NEXT: Data size: 0xC
+# OBJ-TAG-SHORT-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
+# OBJ-TAG-SHORT-NEXT: Description data (
+# OBJ-TAG-SHORT-NEXT: 0000: 2A000000 00000000 01000000
+# OBJ-TAG-SHORT-NEXT: )
+# OBJ-TAG-SHORT-NEXT: }
+# OBJ-TAG-SHORT-NEXT: }
+# OBJ-TAG-SHORT-NEXT: ]
+
+#--- tag-long.s
.section ".note.AARCH64-PAUTH-ABI-tag", "a"
.long 4
@@ -96,3 +149,213 @@
.quad 42 // platform
.quad 1 // version
.quad 0x0123456789ABCDEF // extra data
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu tag-long.s -o tag-long.o
+# RUN: llvm-readelf --notes tag-long.o | FileCheck --check-prefix ELF-TAG-LONG %s
+# RUN: llvm-readobj --notes tag-long.o | FileCheck --check-prefix OBJ-TAG-LONG %s
+
+# ELF-TAG-LONG: AArch64 PAuth ABI tag: <corrupted size: expected 16, got 24>
+
+# OBJ-TAG-LONG: Notes [
+# OBJ-TAG-LONG-NEXT: NoteSection {
+# OBJ-TAG-LONG-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
+# OBJ-TAG-LONG-NEXT: Offset: 0x40
+# OBJ-TAG-LONG-NEXT: Size: 0x28
+# OBJ-TAG-LONG-NEXT: Note {
+# OBJ-TAG-LONG-NEXT: Owner: ARM
+# OBJ-TAG-LONG-NEXT: Data size: 0x18
+# OBJ-TAG-LONG-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
+# OBJ-TAG-LONG-NEXT: Description data (
+# OBJ-TAG-LONG-NEXT: 0000: 2A000000 00000000 01000000 00000000
+# OBJ-TAG-LONG-NEXT: 0010: EFCDAB89 67452301
+# OBJ-TAG-LONG-NEXT: )
+# OBJ-TAG-LONG-NEXT: }
+# OBJ-TAG-LONG-NEXT: }
+# OBJ-TAG-LONG-NEXT: ]
+
+#--- 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 tag: 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 tag: 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 tag: [[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 tag: [[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..afbd6829c0f07f 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -5098,6 +5098,63 @@ template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() {
}
}
+std::pair<std::string, std::string>
+getAArch64PAuthABIPlatformVersionDesc(uint64_t Platform, uint64_t Version) {
+ return std::make_pair(
+ [Platform]() -> std::string {
+ 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";
+ }
+ }(),
+ [Platform, Version]() -> std::string {
+ if (Platform != AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
+ return "";
+ if (Version >= (1 << 7))
+ return "unknown";
+ return std::string("") + ((Version & (1 << 0)) ? "" : "!") +
+ "PointerAuthIntrinsics, " + ((Version & (1 << 1)) ? "" : "!") +
+ "PointerAuthCalls, " + ((Version & (1 << 2)) ? "" : "!") +
+ "PointerAuthReturns, " + ((Version & (1 << 3)) ? "" : "!") +
+ "PointerAuthAuthTraps, " + ((Version & (1 << 4)) ? "" : "!") +
+ "PointerAuthVTPtrAddressDiscrimination, " +
+ ((Version & (1 << 5)) ? "" : "!") +
+ "PointerAuthVTPtrTypeDiscrimination, " +
+ ((Version & (1 << 6)) ? "" : "!") + "PointerAuthInitFini";
+ }());
+}
+
+template <class ELFT>
+static bool printAArch64PAuthABITag(raw_ostream &OS, uint32_t DataSize,
+ ArrayRef<uint8_t> Desc) {
+ OS << " AArch64 PAuth ABI tag: ";
+ // 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);
+
+ auto [PlatformDesc, VersionDesc] =
+ getAArch64PAuthABIPlatformVersionDesc(Platform, Version);
+ 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 +5212,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:
+ printAArch64PAuthABITag<ELFT>(OS, DataSize, Data);
+ return OS.str();
case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
case GNU_PROPERTY_X86_FEATURE_2_USED:
OS << "x86 feature "
@@ -5359,26 +5419,11 @@ 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;
+ switch (NoteType) {
+ case NT_ARM_TYPE_PAUTH_ABI_TAG:
+ return printAArch64PAuthABITag<ELFT>(OS, Desc.size(), Desc);
}
-
- 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;
+ return false;
}
template <class ELFT>
@@ -7705,19 +7750,20 @@ static bool printAarch64NoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
if (NoteType != NT_ARM_TYPE_PAUTH_ABI_TAG)
return false;
- if (Desc.size() < 16)
+ if (Desc.size() != 16)
return false;
- uint64_t platform =
+ uint64_t Platform =
support::endian::read64<ELFT::TargetEndianness>(Desc.data() + 0);
- uint64_t version =
+ 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)));
+ auto [PlatformDesc, VersionDesc] =
+ getAArch64PAuthABIPlatformVersionDesc(Platform, Version);
+ W.printNumber("Platform", Platform);
+ W.printString("PlatformDesc", PlatformDesc);
+ W.printNumber("Version", Version);
+ if (!VersionDesc.empty())
+ W.printString("VersionDesc", VersionDesc);
return true;
}
More information about the llvm-commits
mailing list