Skip to content

Commit 40d5c2b

Browse files
[clang][AArch64] Add a -mbranch-protection option to enable GCS (#75486)
-mbranch-protection=gcs (enabled by -mbranch-protection=standard) causes generated objects to be marked with the gcs feature. This is done via the guarded-control-stack module flag, in a similar way to branch-target-enforcement and sign-return-address. Enabling GCS causes the GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit to be set on generated objects. No code generation changes are required, as GCS just requires that functions are called using BL and returned from using RET (or other similar variant instructions), which is already the case.
1 parent b7770be commit 40d5c2b

File tree

15 files changed

+90
-18
lines changed

15 files changed

+90
-18
lines changed

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddres
457457
"Key used for return address signing")
458458
LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled")
459459
LANGOPT(BranchProtectionPAuthLR, 1, 0, "Use PC as a diversifier using PAuthLR NOP instructions.")
460+
LANGOPT(GuardedControlStack, 1, 0, "Guarded control stack enabled")
460461

461462
LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled")
462463

clang/include/clang/Basic/TargetInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,7 @@ class TargetInfo : public TransferrableTargetInfo,
13731373
LangOptions::SignReturnAddressKeyKind::AKey;
13741374
bool BranchTargetEnforcement = false;
13751375
bool BranchProtectionPAuthLR = false;
1376+
bool GuardedControlStack = false;
13761377
};
13771378

13781379
/// Determine if the Architecture in this TargetInfo supports branch

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7012,6 +7012,8 @@ def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">,
70127012
MarshallingInfoFlag<LangOpts<"BranchTargetEnforcement">>;
70137013
def mbranch_protection_pauth_lr : Flag<["-"], "mbranch-protection-pauth-lr">,
70147014
MarshallingInfoFlag<LangOpts<"BranchProtectionPAuthLR">>;
7015+
def mguarded_control_stack : Flag<["-"], "mguarded-control-stack">,
7016+
MarshallingInfoFlag<LangOpts<"GuardedControlStack">>;
70157017
def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">,
70167018
MarshallingInfoNegativeFlag<LangOpts<"DllExportInlines">>;
70177019
def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
226226

227227
BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
228228
BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
229+
BPI.GuardedControlStack = PBP.GuardedControlStack;
229230
return true;
230231
}
231232

@@ -532,6 +533,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
532533
if (Opts.BranchTargetEnforcement)
533534
Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
534535

536+
if (Opts.GuardedControlStack)
537+
Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
538+
535539
if (HasLS64)
536540
Builder.defineMacro("__ARM_FEATURE_LS64", "1");
537541

@@ -544,6 +548,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
544548
if (HasD128)
545549
Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
546550

551+
if (HasGCS)
552+
Builder.defineMacro("__ARM_FEATURE_GCS", "1");
553+
547554
if (*ArchInfo == llvm::AArch64::ARMV8_1A)
548555
getTargetDefinesARMV81A(Opts, Builder);
549556
else if (*ArchInfo == llvm::AArch64::ARMV8_2A)

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,8 @@ void CodeGenModule::Release() {
11091109
if (LangOpts.BranchProtectionPAuthLR)
11101110
getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr",
11111111
1);
1112+
if (LangOpts.GuardedControlStack)
1113+
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1);
11121114
if (LangOpts.hasSignReturnAddress())
11131115
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1);
11141116
if (LangOpts.isSignReturnAddressScopeAll())

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
138138
BPI.BranchTargetEnforcement ? "true" : "false");
139139
Fn->addFnAttr("branch-protection-pauth-lr",
140140
BPI.BranchProtectionPAuthLR ? "true" : "false");
141+
Fn->addFnAttr("guarded-control-stack",
142+
BPI.GuardedControlStack ? "true" : "false");
141143
}
142144

143145
bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15081508
<< Triple.getArchName();
15091509

15101510
StringRef Scope, Key;
1511-
bool IndirectBranches, BranchProtectionPAuthLR;
1511+
bool IndirectBranches, BranchProtectionPAuthLR, GuardedControlStack;
15121512

15131513
if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
15141514
Scope = A->getValue();
@@ -1518,6 +1518,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15181518
Key = "a_key";
15191519
IndirectBranches = false;
15201520
BranchProtectionPAuthLR = false;
1521+
GuardedControlStack = false;
15211522
} else {
15221523
StringRef DiagMsg;
15231524
llvm::ARM::ParsedBranchProtection PBP;
@@ -1531,6 +1532,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15311532
Key = PBP.Key;
15321533
BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
15331534
IndirectBranches = PBP.BranchTargetEnforcement;
1535+
GuardedControlStack = PBP.GuardedControlStack;
15341536
}
15351537

15361538
CmdArgs.push_back(
@@ -1543,6 +1545,8 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15431545
Args.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
15441546
if (IndirectBranches)
15451547
CmdArgs.push_back("-mbranch-target-enforce");
1548+
if (GuardedControlStack)
1549+
CmdArgs.push_back("-mguarded-control-stack");
15461550
}
15471551

15481552
void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,

clang/test/CodeGen/aarch64-branch-protection-attr.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,29 +63,33 @@ __attribute__ ((target("branch-protection=pac-ret+pc+bti")))
6363
void pauthlr_bti() {}
6464
// CHECK: define{{.*}} void @pauthlr_bti() #[[#PAUTHLR_BTI:]]
6565

66+
__attribute__ ((target("branch-protection=gcs")))
67+
void gcs() {}
68+
// CHECK: define{{.*}} void @gcs() #[[#GCS:]]
6669

67-
// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="none"
70+
// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="none"
6871

69-
// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
72+
// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
7073

71-
// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="none"
74+
// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}} "sign-return-address"="none"
7275

73-
// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
76+
// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
7477

75-
// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
78+
// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
7679

77-
// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}}"branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
80+
// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
7881

79-
// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="b_key"
82+
// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="b_key"
8083

81-
// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key"
84+
// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key"
8285

8386

84-
// CHECK-DAG: attributes #[[#PAUTHLR]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
87+
// 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"
8588

86-
// 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"
89+
// 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"
8790

88-
// CHECK-DAG: attributes #[[#PAUTHLR_LEAF]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
91+
// 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"
8992

90-
// 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"
93+
// 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"
9194

95+
// CHECK-DAG: attributes #[[#GCS]] = { {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="true" {{.*}} "sign-return-address"="none"

clang/test/CodeGen/aarch64-targetattr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,6 @@ void minusarch() {}
110110
// CHECK: attributes #13 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-sve2" }
111111
// CHECK: attributes #14 = { {{.*}} "target-features"="+fullfp16" }
112112
// 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" }
113-
// 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" }
113+
// 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" }
114114
// CHECK: attributes #17 = { {{.*}} "target-features"="-neon" }
115115
// CHECK: attributes #18 = { {{.*}} "target-features"="-v9.3a" }

clang/test/Driver/aarch64-security-options.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Check the -msign-return-address= option, which has a required argument to
22
// select scope.
33
// RUN: %clang --target=aarch64 -c %s -### -msign-return-address=none 2>&1 | \
4-
// RUN: FileCheck %s --check-prefix=RA-OFF --check-prefix=KEY --check-prefix=BTE-OFF --check-prefix=WARN
4+
// RUN: FileCheck %s --check-prefix=RA-OFF --check-prefix=KEY --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN
55

66
// RUN: %clang --target=aarch64 -c %s -### -msign-return-address=non-leaf 2>&1 | \
7-
// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=WARN
7+
// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN
88

99
// RUN: %clang --target=aarch64 -c %s -### -msign-return-address=all 2>&1 | \
10-
// RUN: FileCheck %s --check-prefix=RA-ALL --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=WARN
10+
// RUN: FileCheck %s --check-prefix=RA-ALL --check-prefix=KEY-A --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN
1111

1212
// -mbranch-protection with standard
1313
// RUN: %clang --target=aarch64 -c %s -### -mbranch-protection=standard 2>&1 | \
14-
// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=WARN
14+
// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=GCS-ON --check-prefix=WARN
1515

1616
// If the -msign-return-address and -mbranch-protection are both used, the
1717
// right-most one controls return address signing.
@@ -42,6 +42,9 @@
4242
// BTE-OFF-NOT: "-mbranch-target-enforce"
4343
// BTE-ON: "-mbranch-target-enforce"
4444

45+
// GCS-OFF-NOT: "-mguarded-control-stack"
46+
// GCS-ON: "-mguarded-control-stack"
47+
4548
// CONFLICT: "-msign-return-address=none"
4649

4750
// BAD-RA-PROTECTION: unsupported argument 'foo' to option '-msign-return-address='

clang/test/Preprocessor/aarch64-target-features.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
// CHECK-NOT: __ARM_FEATURE_DOTPROD
5151
// CHECK-NOT: __ARM_FEATURE_PAC_DEFAULT
5252
// CHECK-NOT: __ARM_FEATURE_BTI_DEFAULT
53+
// CHECK-NOT: __ARM_FEATURE_GCS_DEFAULT
5354
// CHECK-NOT: __ARM_BF16_FORMAT_ALTERNATIVE 1
5455
// CHECK-NOT: __ARM_FEATURE_BF16 1
5556
// CHECK-NOT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1
@@ -588,6 +589,20 @@
588589
// CHECK-SYS128: __ARM_FEATURE_SYSREG128 1
589590
// CHECK-NOSYS128-NOT: __ARM_FEATURE_SYSREG128 1
590591

592+
// ================== Check Armv8.9-A/Armv9.4-A Guarded Control Stack (FEAT_GCS)
593+
// 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
594+
// 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
595+
// 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
596+
// 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
597+
// 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
598+
// 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
599+
// 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
600+
// 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
601+
// CHECK-GCS: __ARM_FEATURE_GCS 1
602+
// CHECK-NOGCS-NOT: __ARM_FEATURE_GCS 1
603+
// CHECK-GCS-DEFAULT: __ARM_FEATURE_GCS_DEFAULT 1
604+
// CHECK-NOGCS-DEFAULT-NOT: __ARM_FEATURE_GCS_DEFAULT 1
605+
591606
// ================== Check default macros for Armv8.1-A and later
592607
// 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
593608
// 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

llvm/include/llvm/TargetParser/ARMTargetParserCommon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct ParsedBranchProtection {
4242
StringRef Key;
4343
bool BranchTargetEnforcement;
4444
bool BranchProtectionPAuthLR;
45+
bool GuardedControlStack;
4546
};
4647

4748
bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
256256
if (BTE->getZExtValue())
257257
Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
258258

259+
if (const auto *GCS = mdconst::extract_or_null<ConstantInt>(
260+
M.getModuleFlag("guarded-control-stack")))
261+
if (GCS->getZExtValue())
262+
Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
263+
259264
if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
260265
M.getModuleFlag("sign-return-address")))
261266
if (Sign->getZExtValue())

llvm/lib/TargetParser/ARMTargetParserCommon.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
147147
if (Spec == "standard") {
148148
PBP.Scope = "non-leaf";
149149
PBP.BranchTargetEnforcement = true;
150+
PBP.GuardedControlStack = true;
150151
return true;
151152
}
152153

@@ -173,6 +174,10 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
173174
}
174175
continue;
175176
}
177+
if (Opt == "gcs") {
178+
PBP.GuardedControlStack = true;
179+
continue;
180+
}
176181
if (Opt == "")
177182
Err = "<empty>";
178183
else
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc -mtriple=aarch64-linux %s -o - | \
2+
; RUN: FileCheck %s --check-prefix=ASM
3+
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
4+
; RUN: llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ
5+
6+
define dso_local i32 @f() {
7+
entry:
8+
ret i32 0
9+
}
10+
11+
!llvm.module.flags = !{!0}
12+
13+
!0 = !{i32 8, !"guarded-control-stack", i32 1}
14+
15+
; GCS attribute present
16+
; ASM: .word 3221225472
17+
; ASM-NEXT: .word 4
18+
; ASM-NEXT: .word 4
19+
20+
; OBJ: Properties: aarch64 feature: GCS

0 commit comments

Comments
 (0)