[ARM] emit PACBTI-M build attributes

This patch is part of a series that adds support for the PACBTI-M extension of
the Armv8.1-M architecture, as detailed here:

https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension

The PACBTI-M specification can be found in the Armv8-M Architecture Reference
Manual:

https://developer.arm.com/documentation/ddi0553/latest

The following people contributed to this patch:

- Victor Campos
- Ties Stuij

Reviewed By: ostannard

Differential Revision: https://reviews.llvm.org/D112425
This commit is contained in:
Ties Stuij 2021-12-01 10:52:31 +00:00
parent d688b31628
commit b430782be3
10 changed files with 169 additions and 20 deletions

View File

@ -67,6 +67,10 @@ class ARMAttributeParser : public ELFAttributeParser {
Error DSP_extension(ARMBuildAttrs::AttrType tag);
Error T2EE_use(ARMBuildAttrs::AttrType tag);
Error Virtualization_use(ARMBuildAttrs::AttrType tag);
Error PAC_extension(ARMBuildAttrs::AttrType tag);
Error BTI_extension(ARMBuildAttrs::AttrType tag);
Error PACRET_use(ARMBuildAttrs::AttrType tag);
Error BTI_use(ARMBuildAttrs::AttrType tag);
Error nodefaults(ARMBuildAttrs::AttrType tag);
public:

View File

@ -70,9 +70,13 @@ enum AttrType : unsigned {
DIV_use = 44,
DSP_extension = 46,
MVE_arch = 48,
PAC_extension = 50,
BTI_extension = 52,
also_compatible_with = 65,
conformance = 67,
Virtualization_use = 68,
BTI_use = 74,
PACRET_use = 76,
/// Legacy Tags
Section = 2, // deprecated (ABI r2.09)
@ -237,7 +241,25 @@ enum {
// Tag_Virtualization_use, (=68), uleb128
AllowTZ = 1,
AllowVirtualization = 2,
AllowTZVirtualization = 3
AllowTZVirtualization = 3,
// Tag_PAC_extension, (=50), uleb128
DisallowPAC = 0,
AllowPACInNOPSpace = 1,
AllowPAC = 2,
// Tag_BTI_extension, (=52), uleb128
DisallowBTI = 0,
AllowBTIInNOPSpace = 1,
AllowBTI = 2,
// Tag_BTI_use, (=74), uleb128
BTINotUsed = 0,
BTIUsed = 1,
// Tag_PACRET_use, (=76), uleb128
PACRETNotUsed = 0,
PACRETUsed = 1
};
} // namespace ARMBuildAttrs

View File

@ -59,6 +59,10 @@ const ARMAttributeParser::DisplayHandler ARMAttributeParser::displayRoutines[] =
ATTRIBUTE_HANDLER(DSP_extension),
ATTRIBUTE_HANDLER(T2EE_use),
ATTRIBUTE_HANDLER(Virtualization_use),
ATTRIBUTE_HANDLER(PAC_extension),
ATTRIBUTE_HANDLER(BTI_extension),
ATTRIBUTE_HANDLER(PACRET_use),
ATTRIBUTE_HANDLER(BTI_use),
ATTRIBUTE_HANDLER(nodefaults),
};
@ -350,6 +354,28 @@ Error ARMAttributeParser::Virtualization_use(AttrType tag) {
return parseStringAttribute("Virtualization_use", tag, makeArrayRef(strings));
}
Error ARMAttributeParser::PAC_extension(ARMBuildAttrs::AttrType tag) {
static const char *strings[] = {"Not Permitted", "Permitted in NOP space",
"Permitted"};
return parseStringAttribute("PAC_extension", tag, makeArrayRef(strings));
}
Error ARMAttributeParser::BTI_extension(ARMBuildAttrs::AttrType tag) {
static const char *strings[] = {"Not Permitted", "Permitted in NOP space",
"Permitted"};
return parseStringAttribute("BTI_extension", tag, makeArrayRef(strings));
}
Error ARMAttributeParser::PACRET_use(ARMBuildAttrs::AttrType tag) {
static const char *strings[] = {"Not Used", "Used"};
return parseStringAttribute("PACRET_use", tag, makeArrayRef(strings));
}
Error ARMAttributeParser::BTI_use(ARMBuildAttrs::AttrType tag) {
static const char *strings[] = {"Not Used", "Used"};
return parseStringAttribute("BTI_use", tag, makeArrayRef(strings));
}
Error ARMAttributeParser::nodefaults(AttrType tag) {
uint64_t value = de.getULEB128(cursor);
printAttribute(tag, value, "Unspecified Tags UNDEFINED");

View File

@ -50,6 +50,10 @@ static const TagNameItem tagData[] = {
{ARMBuildAttrs::MPextension_use, "Tag_MPextension_use"},
{ARMBuildAttrs::DIV_use, "Tag_DIV_use"},
{ARMBuildAttrs::DSP_extension, "Tag_DSP_extension"},
{ARMBuildAttrs::PAC_extension, "Tag_PAC_extension"},
{ARMBuildAttrs::BTI_extension, "Tag_BTI_extension"},
{ARMBuildAttrs::BTI_use, "Tag_BTI_use"},
{ARMBuildAttrs::PACRET_use, "Tag_PACRET_use"},
{ARMBuildAttrs::nodefaults, "Tag_nodefaults"},
{ARMBuildAttrs::also_compatible_with, "Tag_also_compatible_with"},
{ARMBuildAttrs::T2EE_use, "Tag_T2EE_use"},

View File

@ -763,6 +763,32 @@ void ARMAsmPrinter::emitAttributes() {
int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr);
}
auto *PACValue = mdconst::extract_or_null<ConstantInt>(
SourceModule->getModuleFlag("sign-return-address"));
if (PACValue && PACValue->getZExtValue() == 1) {
// If "+pacbti" is used as an architecture extension,
// Tag_PAC_extension is emitted in
// ARMTargetStreamer::emitTargetAttributes().
if (!STI.hasPACBTI()) {
ATS.emitAttribute(ARMBuildAttrs::PAC_extension,
ARMBuildAttrs::AllowPACInNOPSpace);
}
ATS.emitAttribute(ARMBuildAttrs::PACRET_use, ARMBuildAttrs::PACRETUsed);
}
auto *BTIValue = mdconst::extract_or_null<ConstantInt>(
SourceModule->getModuleFlag("branch-target-enforcement"));
if (BTIValue && BTIValue->getZExtValue() == 1) {
// If "+pacbti" is used as an architecture extension,
// Tag_BTI_extension is emitted in
// ARMTargetStreamer::emitTargetAttributes().
if (!STI.hasPACBTI()) {
ATS.emitAttribute(ARMBuildAttrs::BTI_extension,
ARMBuildAttrs::AllowBTIInNOPSpace);
}
ATS.emitAttribute(ARMBuildAttrs::BTI_use, ARMBuildAttrs::BTIUsed);
}
}
}

View File

@ -299,4 +299,9 @@ void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
else if (STI.hasFeature(ARM::FeatureVirtualization))
emitAttribute(ARMBuildAttrs::Virtualization_use,
ARMBuildAttrs::AllowVirtualization);
if (STI.hasFeature(ARM::FeaturePACBTI)) {
emitAttribute(ARMBuildAttrs::PAC_extension, ARMBuildAttrs::AllowPAC);
emitAttribute(ARMBuildAttrs::BTI_extension, ARMBuildAttrs::AllowBTI);
}
}

View File

@ -57,6 +57,18 @@
// Tag_DSP_extension (=46)
.eabi_attribute 46, 1
// Tag_PAC_extension (=50)
.eabi_attribute 50, 0
// Tag_BTI_extension (=52)
.eabi_attribute 52, 0
// Tag_BTI_use (=74)
.eabi_attribute 74, 0
// Tag_PACRET_use (=76)
.eabi_attribute 76, 0
// Tag_Virtualization_use (=68)
.eabi_attribute 68, 3
@ -67,22 +79,23 @@
.eabi_attribute 129, "1"
.eabi_attribute 250, 1
// CHECK: Section {
// CHECK: Name: .ARM.attributes
// CHECK-NEXT: Type: SHT_ARM_ATTRIBUTES
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x34
// CHECK-NEXT: Size: 73
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 41480000 00616561 62690001 3E000000
// CHECK-NEXT: 0010: 05636F72 7465782D 61380006 0A074108
// CHECK-NEXT: 0020: 0109020A 030C0214 01150117 01180119
// CHECK-NEXT: 0030: 011B001C 0124012A 012C022E 0144036E
// CHECK-NEXT: 0040: A0018101 3100FA01 01
// CHECK-NEXT: )
// CHECK: Section {
// CHECK: Name: .ARM.attributes (7)
// CHECK-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x34
// CHECK-NEXT: Size: 81
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 41500000 00616561 62690001 46000000 |AP...aeabi..F...|
// CHECK-NEXT: 0010: 05636F72 7465782D 61380006 0A074108 |.cortex-a8....A.|
// CHECK-NEXT: 0020: 0109020A 030C0214 01150117 01180119 |................|
// CHECK-NEXT: 0030: 011B001C 0124012A 012C022E 01320034 |.....$.*.,...2.4|
// CHECK-NEXT: 0040: 0044034A 004C006E A0018101 3100FA01 |.D.J.L.n....1...|
// CHECK-NEXT: 0050: 01 |.|
// CHECK-NEXT: )

View File

@ -233,6 +233,7 @@
; RUN: llc < %s -mtriple=thumbv8.1m.main-none-none-eabi | FileCheck %s --check-prefix=ARMv81M-MAIN
; RUN: llc < %s -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve | FileCheck %s --check-prefix=ARMv81M-MAIN-MVEINT
; RUN: llc < %s -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp | FileCheck %s --check-prefix=ARMv81M-MAIN-MVEFP
; RUN: llc < %s -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+pacbti | FileCheck %s --check-prefix=ARMv81M-MAIN-PACBTI
; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-m55 | FileCheck %s --check-prefix=CORTEX-M55
; CPU-SUPPORTED-NOT: is not a recognized processor for this target
@ -1723,6 +1724,8 @@
; ARMv81M-MAIN-MVEINT: .eabi_attribute 48, 1 @ Tag_MVE_arch
; ARMv81M-MAIN-MVEFP: .eabi_attribute 6, 21 @ Tag_CPU_arch
; ARMv81M-MAIN-MVEFP: .eabi_attribute 48, 2 @ Tag_MVE_arch
; ARMv81M-MAIN-PACBTI: .eabi_attribute 50, 2 @ Tag_PAC_extension
; ARMv81M-MAIN-PACBTI: .eabi_attribute 52, 2 @ Tag_BTI_extension
; CORTEX-M55: .cpu cortex-m55
; CORTEX-M55: .eabi_attribute 6, 21

View File

@ -0,0 +1,21 @@
; RUN: llc -mtriple thumbv8.1m.main-arm-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-USE
; RUN: llc -mtriple thumbv8.1m.main-arm-none-eabi -mattr=+pacbti %s -o - | FileCheck %s --check-prefixes=CHECK-ARCHEXT,CHECK-USE
; CHECK-DAG: .eabi_attribute 50, 1 @ Tag_PAC_extension
; CHECK-ARCHEXT-DAG: .eabi_attribute 50, 2 @ Tag_PAC_extension
; CHECK-DAG: .eabi_attribute 52, 1 @ Tag_BTI_extension
; CHECK-ARCHEXT-DAG: .eabi_attribute 52, 2 @ Tag_BTI_extension
; CHECK-USE-DAG: .eabi_attribute 76, 1 @ Tag_PACRET_use
; CHECK-USE-DAG: .eabi_attribute 74, 1 @ Tag_BTI_use
define i32 @foo(i32 %a) {
entry:
%add = add nsw i32 %a, 1
ret i32 %add
}
!llvm.module.flags = !{!0, !1, !2}
!0 = !{i32 1, !"branch-target-enforcement", i32 1}
!1 = !{i32 1, !"sign-return-address", i32 1}
!2 = !{i32 1, !"sign-return-address-all", i32 0}

View File

@ -214,6 +214,18 @@
@ CHECK-OBJ: Tag: 46
@ CHECK-OBJ-NEXT: Value: 0
@ CHECK-OBJ-NEXT: TagName: DSP_extension
@ CHECK-OBJ-NEXT: Description: Not Permitted
.eabi_attribute Tag_PAC_extension, 0
@ CHECK: .eabi_attribute 50, 0
@ CHECK-OBJ: Tag: 50
@ CHECK-OBJ-NEXT: Value: 0
@ CHECK-OBJ-NEXT: TagName: PAC_extension
@ CHECK-OBJ-NEXT: Description: Not Permitted
.eabi_attribute Tag_BTI_extension, 0
@ CHECK: .eabi_attribute 52, 0
@ CHECK-OBJ: Tag: 52
@ CHECK-OBJ-NEXT: Value: 0
@ CHECK-OBJ-NEXT: TagName: BTI_extension
@ CHECK-OBJ-NEXT: Description: Not Permitted
.eabi_attribute Tag_nodefaults, 0
@ CHECK: .eabi_attribute 64, 0
@ -238,6 +250,19 @@
@ CHECK-OBJ-NEXT: Value: 0
@ CHECK-OBJ-NEXT: TagName: Virtualization_use
@ CHECK-OBJ-NEXT: Description: Not Permitted
.eabi_attribute Tag_BTI_use, 0
@ CHECK: .eabi_attribute 74, 0
@ CHECK-OBJ: Tag: 74
@ CHECK-OBJ-NEXT: Value: 0
@ CHECK-OBJ-NEXT: TagName: BTI_use
@ CHECK-OBJ-NEXT: Description: Not Used
.eabi_attribute Tag_PACRET_use, 0
@ CHECK: .eabi_attribute 76, 0
@ CHECK-OBJ: Tag: 76
@ CHECK-OBJ-NEXT: Value: 0
@ CHECK-OBJ-NEXT: TagName: PACRET_use
@ CHECK-OBJ-NEXT: Description: Not Used
@ ===--- Compatibility Checks ---===