Skip to content

Commit cceb876

Browse files
[clang][AArch64] Add a -mbranch-protection option to enable GCS
-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 fc9dbc9 commit cceb876

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
@@ -7002,6 +7002,8 @@ def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">,
70027002
MarshallingInfoFlag<LangOpts<"BranchTargetEnforcement">>;
70037003
def mbranch_protection_pauth_lr : Flag<["-"], "mbranch-protection-pauth-lr">,
70047004
MarshallingInfoFlag<LangOpts<"BranchProtectionPAuthLR">>;
7005+
def mguarded_control_stack : Flag<["-"], "mguarded-control-stack">,
7006+
MarshallingInfoFlag<LangOpts<"GuardedControlStack">>;
70057007
def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">,
70067008
MarshallingInfoNegativeFlag<LangOpts<"DllExportInlines">>;
70077009
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
@@ -1497,7 +1497,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
14971497
<< Triple.getArchName();
14981498

14991499
StringRef Scope, Key;
1500-
bool IndirectBranches, BranchProtectionPAuthLR;
1500+
bool IndirectBranches, BranchProtectionPAuthLR, GuardedControlStack;
15011501

15021502
if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
15031503
Scope = A->getValue();
@@ -1507,6 +1507,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15071507
Key = "a_key";
15081508
IndirectBranches = false;
15091509
BranchProtectionPAuthLR = false;
1510+
GuardedControlStack = false;
15101511
} else {
15111512
StringRef DiagMsg;
15121513
llvm::ARM::ParsedBranchProtection PBP;
@@ -1520,6 +1521,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15201521
Key = PBP.Key;
15211522
BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
15221523
IndirectBranches = PBP.BranchTargetEnforcement;
1524+
GuardedControlStack = PBP.GuardedControlStack;
15231525
}
15241526

15251527
CmdArgs.push_back(
@@ -1532,6 +1534,8 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15321534
Args.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
15331535
if (IndirectBranches)
15341536
CmdArgs.push_back("-mbranch-target-enforce");
1537+
if (GuardedControlStack)
1538+
CmdArgs.push_back("-mguarded-control-stack");
15351539
}
15361540

15371541
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
@@ -49,6 +49,7 @@
4949
// CHECK-NOT: __ARM_FEATURE_DOTPROD
5050
// CHECK-NOT: __ARM_FEATURE_PAC_DEFAULT
5151
// CHECK-NOT: __ARM_FEATURE_BTI_DEFAULT
52+
// CHECK-NOT: __ARM_FEATURE_GCS_DEFAULT
5253
// CHECK-NOT: __ARM_BF16_FORMAT_ALTERNATIVE 1
5354
// CHECK-NOT: __ARM_FEATURE_BF16 1
5455
// CHECK-NOT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1
@@ -587,6 +588,20 @@
587588
// CHECK-SYS128: __ARM_FEATURE_SYSREG128 1
588589
// CHECK-NOSYS128-NOT: __ARM_FEATURE_SYSREG128 1
589590

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