mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 16:06:06 +00:00
[PAC][llvm-readobj][AArch64][ELF] Support GNU_PROPERTY_AARCH64_FEATURE_PAUTH
(#87545)
Reland #85231 after fixing build failure https://lab.llvm.org/buildbot/#/builders/186/builds/15631. Use `PRIx64` for format output of `uint64_t` as hex. Original PR description below. This adds support for `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` feature (as defined in https://github.com/ARM-software/abi-aa/pull/240) 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 #85232: - 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.
This commit is contained in:
parent
d89914f30b
commit
4f19f15a60
@ -1712,11 +1712,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
|
||||
@ -1740,6 +1735,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,
|
||||
@ -1758,6 +1754,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,
|
||||
|
@ -1,98 +1,204 @@
|
||||
# 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
|
||||
#--- 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-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
|
||||
# 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 -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %s
|
||||
# RUN: llvm-readobj --notes gnu-42-1.o | \
|
||||
# RUN: FileCheck --check-prefix=OBJ -DPLATFORM="0x2a (unknown)" -DVERSION=0x1 %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
|
||||
# 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]]
|
||||
|
||||
# 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
|
||||
# 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: ]
|
||||
|
||||
# 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: ]
|
||||
#--- 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:
|
||||
|
||||
# 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: ]
|
||||
# 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 -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
|
||||
# RUN: llvm-readobj --notes gnu-0-0.o | \
|
||||
# RUN: FileCheck --check-prefix=OBJ -DPLATFORM="0x0 (invalid)" -DVERSION=0x0 %s
|
||||
|
||||
# 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: ]
|
||||
#--- 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:
|
||||
|
||||
#--- abi-tag.s
|
||||
# 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 -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
|
||||
# RUN: llvm-readobj --notes gnu-1-0.o | \
|
||||
# RUN: FileCheck --check-prefix=OBJ -DPLATFORM="0x1 (baremetal)" -DVERSION=0x0 %s
|
||||
|
||||
.section ".note.AARCH64-PAUTH-ABI-tag", "a"
|
||||
.long 4
|
||||
.long 16
|
||||
.long 1
|
||||
.asciz "ARM"
|
||||
#--- 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:
|
||||
|
||||
.quad 42 // platform
|
||||
.quad 1 // version
|
||||
# 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 -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 -DPLATFORM="0x10000002 (llvm_linux)" \
|
||||
# RUN: -DVERSION="0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)" %s
|
||||
|
||||
#--- abi-tag-short.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:
|
||||
|
||||
.section ".note.AARCH64-PAUTH-ABI-tag", "a"
|
||||
.long 4
|
||||
.long 12
|
||||
.long 1
|
||||
.asciz "ARM"
|
||||
# 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
|
||||
|
||||
.quad 42
|
||||
.word 1
|
||||
#--- 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:
|
||||
|
||||
#--- abi-tag-long.s
|
||||
# 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-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-ERR -DSIZE=28 -DDATASIZE=18 \
|
||||
# RUN: -DERR="<corrupted size: expected 16, got 12>" %s
|
||||
|
||||
.section ".note.AARCH64-PAUTH-ABI-tag", "a"
|
||||
.long 4
|
||||
.long 24
|
||||
.long 1
|
||||
.asciz "ARM"
|
||||
# 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]]
|
||||
|
||||
.quad 42 // platform
|
||||
.quad 1 // version
|
||||
.quad 0x0123456789ABCDEF // extra data
|
||||
# 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
|
||||
.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-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-ERR -DSIZE=30 -DDATASIZE=20 \
|
||||
# RUN: -DERR="<corrupted size: expected 16, got 24>" %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
|
||||
|
@ -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 & (1 << 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 "
|
||||
@ -5363,29 +5434,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 = 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,
|
||||
@ -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:";
|
||||
@ -7702,27 +7741,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 = 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,
|
||||
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user