Skip to content

Commit

Permalink
[PAC][llvm-readobj][AArch64][ELF] Support `GNU_PROPERTY_AARCH64_FEATU…
Browse files Browse the repository at this point in the history
…RE_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 ARM-software/abi-aa#250.
  • Loading branch information
kovdan01 committed Mar 19, 2024
1 parent 4a6bc9f commit 54854fc
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 161 deletions.
26 changes: 21 additions & 5 deletions llvm/include/llvm/BinaryFormat/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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,
Expand Down
282 changes: 186 additions & 96 deletions llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading

0 comments on commit 54854fc

Please sign in to comment.