diff --git a/llvm/include/llvm/Support/ARMAttributeParser.h b/llvm/include/llvm/Support/ARMAttributeParser.h --- a/llvm/include/llvm/Support/ARMAttributeParser.h +++ b/llvm/include/llvm/Support/ARMAttributeParser.h @@ -67,6 +67,10 @@ 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: diff --git a/llvm/include/llvm/Support/ARMBuildAttributes.h b/llvm/include/llvm/Support/ARMBuildAttributes.h --- a/llvm/include/llvm/Support/ARMBuildAttributes.h +++ b/llvm/include/llvm/Support/ARMBuildAttributes.h @@ -70,9 +70,13 @@ 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 @@ // 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 diff --git a/llvm/lib/Support/ARMAttributeParser.cpp b/llvm/lib/Support/ARMAttributeParser.cpp --- a/llvm/lib/Support/ARMAttributeParser.cpp +++ b/llvm/lib/Support/ARMAttributeParser.cpp @@ -59,6 +59,10 @@ 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 @@ 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"); diff --git a/llvm/lib/Support/ARMBuildAttrs.cpp b/llvm/lib/Support/ARMBuildAttrs.cpp --- a/llvm/lib/Support/ARMBuildAttrs.cpp +++ b/llvm/lib/Support/ARMBuildAttrs.cpp @@ -50,6 +50,10 @@ {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"}, diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -763,6 +763,32 @@ int EnumBuildAttr = EnumWidth == 1 ? 1 : 2; ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr); } + + auto *PACValue = mdconst::extract_or_null( + 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( + 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); + } } } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp @@ -299,4 +299,9 @@ 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); + } } diff --git a/llvm/test/CodeGen/ARM/build-attributes-encoding.s b/llvm/test/CodeGen/ARM/build-attributes-encoding.s --- a/llvm/test/CodeGen/ARM/build-attributes-encoding.s +++ b/llvm/test/CodeGen/ARM/build-attributes-encoding.s @@ -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: ) diff --git a/llvm/test/CodeGen/ARM/build-attributes.ll b/llvm/test/CodeGen/ARM/build-attributes.ll --- a/llvm/test/CodeGen/ARM/build-attributes.ll +++ b/llvm/test/CodeGen/ARM/build-attributes.ll @@ -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 diff --git a/llvm/test/CodeGen/ARM/pacbti-module-attrs.ll b/llvm/test/CodeGen/ARM/pacbti-module-attrs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/ARM/pacbti-module-attrs.ll @@ -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} diff --git a/llvm/test/MC/ARM/directive-eabi_attribute.s b/llvm/test/MC/ARM/directive-eabi_attribute.s --- a/llvm/test/MC/ARM/directive-eabi_attribute.s +++ b/llvm/test/MC/ARM/directive-eabi_attribute.s @@ -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 ---===