diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 21abc346cf17a..0428b70c60206 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -457,6 +457,7 @@ ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddres "Key used for return address signing") LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled") LANGOPT(BranchProtectionPAuthLR, 1, 0, "Use PC as a diversifier using PAuthLR NOP instructions.") +LANGOPT(GuardedControlStack, 1, 0, "Guarded control stack enabled") LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled") diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index ac3c324c6c29c..3eb23ebdacf0e 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1373,6 +1373,7 @@ class TargetInfo : public TransferrableTargetInfo, LangOptions::SignReturnAddressKeyKind::AKey; bool BranchTargetEnforcement = false; bool BranchProtectionPAuthLR = false; + bool GuardedControlStack = false; }; /// Determine if the Architecture in this TargetInfo supports branch diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 19becba4a5ad8..a7c4c1cc1b5e7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7012,6 +7012,8 @@ def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">, MarshallingInfoFlag>; def mbranch_protection_pauth_lr : Flag<["-"], "mbranch-protection-pauth-lr">, MarshallingInfoFlag>; +def mguarded_control_stack : Flag<["-"], "mguarded-control-stack">, + MarshallingInfoFlag>; def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">, MarshallingInfoNegativeFlag>; def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 2f8395cb8932f..9ebaf4d40cd7e 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -226,6 +226,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; + BPI.GuardedControlStack = PBP.GuardedControlStack; return true; } @@ -532,6 +533,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.BranchTargetEnforcement) Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + if (Opts.GuardedControlStack) + Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1"); + if (HasLS64) Builder.defineMacro("__ARM_FEATURE_LS64", "1"); @@ -544,6 +548,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasD128) Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1"); + if (HasGCS) + Builder.defineMacro("__ARM_FEATURE_GCS", "1"); + if (*ArchInfo == llvm::AArch64::ARMV8_1A) getTargetDefinesARMV81A(Opts, Builder); else if (*ArchInfo == llvm::AArch64::ARMV8_2A) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4fd32337cccc0..ad6fc71c1e503 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1109,6 +1109,8 @@ void CodeGenModule::Release() { if (LangOpts.BranchProtectionPAuthLR) getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", 1); + if (LangOpts.GuardedControlStack) + getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1); if (LangOpts.hasSignReturnAddress()) getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1); if (LangOpts.isSignReturnAddressScopeAll()) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7102d190fe008..ee7f95084d2e0 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -138,6 +138,8 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { BPI.BranchTargetEnforcement ? "true" : "false"); Fn->addFnAttr("branch-protection-pauth-lr", BPI.BranchProtectionPAuthLR ? "true" : "false"); + Fn->addFnAttr("guarded-control-stack", + BPI.GuardedControlStack ? "true" : "false"); } bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2d8ef841d4f6b..1ee7ae602f3ce 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1508,7 +1508,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, << Triple.getArchName(); StringRef Scope, Key; - bool IndirectBranches, BranchProtectionPAuthLR; + bool IndirectBranches, BranchProtectionPAuthLR, GuardedControlStack; if (A->getOption().matches(options::OPT_msign_return_address_EQ)) { Scope = A->getValue(); @@ -1518,6 +1518,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, Key = "a_key"; IndirectBranches = false; BranchProtectionPAuthLR = false; + GuardedControlStack = false; } else { StringRef DiagMsg; llvm::ARM::ParsedBranchProtection PBP; @@ -1531,6 +1532,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, Key = PBP.Key; BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; IndirectBranches = PBP.BranchTargetEnforcement; + GuardedControlStack = PBP.GuardedControlStack; } CmdArgs.push_back( @@ -1543,6 +1545,8 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, Args.MakeArgString(Twine("-mbranch-protection-pauth-lr"))); if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); + if (GuardedControlStack) + CmdArgs.push_back("-mguarded-control-stack"); } void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, diff --git a/clang/test/CodeGen/aarch64-branch-protection-attr.c b/clang/test/CodeGen/aarch64-branch-protection-attr.c index 8ab3e17ade426..f0e1dcccd1e82 100644 --- a/clang/test/CodeGen/aarch64-branch-protection-attr.c +++ b/clang/test/CodeGen/aarch64-branch-protection-attr.c @@ -63,29 +63,33 @@ __attribute__ ((target("branch-protection=pac-ret+pc+bti"))) void pauthlr_bti() {} // CHECK: define{{.*}} void @pauthlr_bti() #[[#PAUTHLR_BTI:]] +__attribute__ ((target("branch-protection=gcs"))) +void gcs() {} +// CHECK: define{{.*}} void @gcs() #[[#GCS:]] -// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="none" +// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="none" -// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="none" +// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}} "sign-return-address"="none" -// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}}"branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PAUTHLR]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PAUTHLR]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PAUTHLR_BKEY]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PAUTHLR_BKEY]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#PAUTHLR_LEAF]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PAUTHLR_LEAF]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PAUTHLR_BTI]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="true" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PAUTHLR_BTI]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#GCS]] = { {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="true" {{.*}} "sign-return-address"="none" diff --git a/clang/test/CodeGen/aarch64-targetattr.c b/clang/test/CodeGen/aarch64-targetattr.c index 9664b723a2b2c..5f557532a4b4a 100644 --- a/clang/test/CodeGen/aarch64-targetattr.c +++ b/clang/test/CodeGen/aarch64-targetattr.c @@ -110,6 +110,6 @@ void minusarch() {} // CHECK: attributes #13 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-sve2" } // CHECK: attributes #14 = { {{.*}} "target-features"="+fullfp16" } // CHECK: attributes #15 = { {{.*}} "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } -// CHECK: attributes #16 = { {{.*}} "branch-target-enforcement"="true" {{.*}} "target-features"="+aes,+bf16,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } +// CHECK: attributes #16 = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="true" {{.*}} "target-features"="+aes,+bf16,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } // CHECK: attributes #17 = { {{.*}} "target-features"="-neon" } // CHECK: attributes #18 = { {{.*}} "target-features"="-v9.3a" } diff --git a/clang/test/Driver/aarch64-security-options.c b/clang/test/Driver/aarch64-security-options.c index e1f3013c41137..146add2d1cf70 100644 --- a/clang/test/Driver/aarch64-security-options.c +++ b/clang/test/Driver/aarch64-security-options.c @@ -1,17 +1,17 @@ // Check the -msign-return-address= option, which has a required argument to // select scope. // RUN: %clang --target=aarch64 -c %s -### -msign-return-address=none 2>&1 | \ -// RUN: FileCheck %s --check-prefix=RA-OFF --check-prefix=KEY --check-prefix=BTE-OFF --check-prefix=WARN +// RUN: FileCheck %s --check-prefix=RA-OFF --check-prefix=KEY --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN // RUN: %clang --target=aarch64 -c %s -### -msign-return-address=non-leaf 2>&1 | \ -// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=WARN +// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN // RUN: %clang --target=aarch64 -c %s -### -msign-return-address=all 2>&1 | \ -// RUN: FileCheck %s --check-prefix=RA-ALL --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=WARN +// RUN: FileCheck %s --check-prefix=RA-ALL --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN // -mbranch-protection with standard // RUN: %clang --target=aarch64 -c %s -### -mbranch-protection=standard 2>&1 | \ -// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=WARN +// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=GCS-ON --check-prefix=WARN // If the -msign-return-address and -mbranch-protection are both used, the // right-most one controls return address signing. @@ -42,6 +42,9 @@ // BTE-OFF-NOT: "-mbranch-target-enforce" // BTE-ON: "-mbranch-target-enforce" +// GCS-OFF-NOT: "-mguarded-control-stack" +// GCS-ON: "-mguarded-control-stack" + // CONFLICT: "-msign-return-address=none" // BAD-RA-PROTECTION: unsupported argument 'foo' to option '-msign-return-address=' diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 96c7e39a18af7..80ce5a75c0477 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -50,6 +50,7 @@ // CHECK-NOT: __ARM_FEATURE_DOTPROD // CHECK-NOT: __ARM_FEATURE_PAC_DEFAULT // CHECK-NOT: __ARM_FEATURE_BTI_DEFAULT +// CHECK-NOT: __ARM_FEATURE_GCS_DEFAULT // CHECK-NOT: __ARM_BF16_FORMAT_ALTERNATIVE 1 // CHECK-NOT: __ARM_FEATURE_BF16 1 // CHECK-NOT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1 @@ -588,6 +589,20 @@ // CHECK-SYS128: __ARM_FEATURE_SYSREG128 1 // CHECK-NOSYS128-NOT: __ARM_FEATURE_SYSREG128 1 +// ================== Check Armv8.9-A/Armv9.4-A Guarded Control Stack (FEAT_GCS) +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.9-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-NOGCS,CHECK-NOGCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.4-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-NOGCS,CHECK-NOGCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.9-a+gcs -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-GCS,CHECK-NOGCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.4-a+gcs -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-GCS,CHECK-NOGCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.9-a -mbranch-protection=gcs -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-NOGCS,CHECK-GCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.4-a -mbranch-protection=gcs -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-NOGCS,CHECK-GCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.9-a+gcs -mbranch-protection=gcs -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-GCS,CHECK-GCS-DEFAULT %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.4-a+gcs -mbranch-protection=gcs -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-GCS,CHECK-GCS-DEFAULT %s +// CHECK-GCS: __ARM_FEATURE_GCS 1 +// CHECK-NOGCS-NOT: __ARM_FEATURE_GCS 1 +// CHECK-GCS-DEFAULT: __ARM_FEATURE_GCS_DEFAULT 1 +// CHECK-NOGCS-DEFAULT-NOT: __ARM_FEATURE_GCS_DEFAULT 1 + // ================== Check default macros for Armv8.1-A and later // RUN: %clang -target aarch64-none-elf -march=armv8.1-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-BEFORE-V83,CHECK-BEFORE-V85 %s // RUN: %clang -target aarch64-none-elf -march=armv8.2-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-BEFORE-V83,CHECK-BEFORE-V85 %s diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h index 1e4187c6fb111..8ae553ca80ddc 100644 --- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h +++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h @@ -42,6 +42,7 @@ struct ParsedBranchProtection { StringRef Key; bool BranchTargetEnforcement; bool BranchProtectionPAuthLR; + bool GuardedControlStack; }; bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 90e1ce9ddf66b..7d2ff146a340b 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -256,6 +256,11 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { if (BTE->getZExtValue()) Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + if (const auto *GCS = mdconst::extract_or_null( + M.getModuleFlag("guarded-control-stack"))) + if (GCS->getZExtValue()) + Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + if (const auto *Sign = mdconst::extract_or_null( M.getModuleFlag("sign-return-address"))) if (Sign->getZExtValue()) diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp index 6d3a59d532fd3..9ce6c502016ee 100644 --- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp +++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp @@ -147,6 +147,7 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, if (Spec == "standard") { PBP.Scope = "non-leaf"; PBP.BranchTargetEnforcement = true; + PBP.GuardedControlStack = true; return true; } @@ -173,6 +174,10 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, } continue; } + if (Opt == "gcs") { + PBP.GuardedControlStack = true; + continue; + } if (Opt == "") Err = ""; else diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-gcs.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-gcs.ll new file mode 100644 index 0000000000000..7dbb7c4ec9008 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-gcs.ll @@ -0,0 +1,20 @@ +; RUN: llc -mtriple=aarch64-linux %s -o - | \ +; RUN: FileCheck %s --check-prefix=ASM +; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \ +; RUN: llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ + +define dso_local i32 @f() { +entry: + ret i32 0 +} + +!llvm.module.flags = !{!0} + +!0 = !{i32 8, !"guarded-control-stack", i32 1} + +; GCS attribute present +; ASM: .word 3221225472 +; ASM-NEXT: .word 4 +; ASM-NEXT: .word 4 + +; OBJ: Properties: aarch64 feature: GCS