[clang] [llvm] riscv: Support -mstack-protector-guard=tls (PR #108942)
Keith Packard via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 17 01:53:36 PDT 2024
https://github.com/keith-packard created https://github.com/llvm/llvm-project/pull/108942
Add support for using a thread-local variable with a specified offsetfor holding the stack guard canary value.
>From 7822a1ee2eed923a3014577668bdd8f1c8145d4c Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 1/3] riscv: Support -mstack-protector-guard=tls
Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
clang/lib/Driver/ToolChains/Clang.cpp | 33 +++++++++++++++++++--
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 8 +++++
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3fe4ce5d893b8d..4c7756b3883b8c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
- !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+ !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+ !EffectiveTriple.isRISCV())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< A->getOption().getName() << Value << "sysreg global";
return;
}
+ if (EffectiveTriple.isRISCV()) {
+ if (Value != "tls" && Value != "global") {
+ D.Diag(diag::err_drv_invalid_value_with_suggestion)
+ << A->getOption().getName() << Value << "tls global";
+ return;
+ }
+ if (Value == "tls") {
+ if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+ D.Diag(diag::err_drv_ssp_missing_offset_argument)
+ << A->getAsString(Args);
+ return;
+ }
+ }
+ }
A->render(Args, CmdArgs);
}
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) {
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
- !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+ !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+ !EffectiveTriple.isRISCV())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
int Offset;
@@ -3664,12 +3680,18 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< A->getOption().getName() << Value;
return;
}
+ if (EffectiveTriple.isRISCV() && (Offset <= -2048 || Offset >= 2048)) {
+ D.Diag(diag::err_drv_invalid_int_value)
+ << A->getOption().getName() << Value;
+ return;
+ }
A->render(Args, CmdArgs);
}
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
StringRef Value = A->getValue();
- if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+ if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+ !EffectiveTriple.isRISCV())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3703,11 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
return;
}
+ if (EffectiveTriple.isRISCV() && Value != "tp") {
+ D.Diag(diag::err_drv_invalid_value_with_suggestion)
+ << A->getOption().getName() << Value << "tp";
+ return;
+ }
A->render(Args, CmdArgs);
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7d2a7b20ba2508..c52ef550495052 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21228,6 +21228,14 @@ Value *RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
if (Subtarget.isTargetAndroid())
return useTpOffset(IRB, -0x18);
+ Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+
+ if (M->getStackProtectorGuard() == "tls") {
+ // Specially, some users may customize the base reg and offset.
+ int Offset = M->getStackProtectorGuardOffset();
+ return useTpOffset(IRB, Offset);
+ }
+
return TargetLowering::getIRStackGuard(IRB);
}
>From 9f589d801fa62a1bb46c2b8f3d56b653396028c6 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 2/3] Driver: add stack protector tests for riscv
Add tests ensuring that the driver correctly handles stack protector
guard options for risc-v.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
clang/test/CodeGen/stack-protector-guard.c | 9 +++++++++
clang/test/Driver/stack-protector-guard.c | 10 ++++++++++
2 files changed, 19 insertions(+)
diff --git a/clang/test/CodeGen/stack-protector-guard.c b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..81e0ddc8753966 100644
--- a/clang/test/CodeGen/stack-protector-guard.c
+++ b/clang/test/CodeGen/stack-protector-guard.c
@@ -9,6 +9,9 @@
// RUN: %clang_cc1 -mstack-protector-guard=sysreg -triple aarch64-linux-gnu \
// RUN: -mstack-protector-guard-offset=1024 -mstack-protector-guard-reg=sp_el0 \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=AARCH64
+// RUN: %clang_cc1 -mstack-protector-guard=tls -triple riscv64-unknown-elf \
+// RUN: -mstack-protector-guard-offset=44 -mstack-protector-guard-reg=tp \
+// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=RISCV
void foo(int*);
void bar(int x) {
int baz[x];
@@ -23,3 +26,9 @@ void bar(int x) {
// AARCH64: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"sysreg"}
// AARCH64: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"sp_el0"}
// AARCH64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 1024}
+
+// RISCV: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
+// RISCV: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
+// RISCV: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"tp"}
+// RISCV: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 44}
+
diff --git a/clang/test/Driver/stack-protector-guard.c b/clang/test/Driver/stack-protector-guard.c
index af4e11f8eaabce..be95d1d5798e3c 100644
--- a/clang/test/Driver/stack-protector-guard.c
+++ b/clang/test/Driver/stack-protector-guard.c
@@ -85,3 +85,13 @@
// CHECK-AARCH64: "-cc1" {{.*}}"-mstack-protector-guard=sysreg" "-mstack-protector-guard-offset=0" "-mstack-protector-guard-reg=sp_el0"
// INVALID-VALUE-AARCH64: error: invalid value 'tls' in 'mstack-protector-guard=', expected one of: sysreg global
// INVALID-REG-AARCH64: error: invalid value 'foo' in 'mstack-protector-guard-reg='
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=tls %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard-offset=1048576 %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-OFFSET %s
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
+
>From 7636faf1430efe05a1c90a088c5ba195efac933f Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Mon, 16 Sep 2024 12:36:06 -0700
Subject: [PATCH 3/3] riscv: Add codegen test for TLS stack canary
Make sure the code generated for a TLS-relative stack guard canary
references the right location before and after intervening function
code.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
llvm/test/CodeGen/RISCV/stack-guard-tls.ll | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/stack-guard-tls.ll
diff --git a/llvm/test/CodeGen/RISCV/stack-guard-tls.ll b/llvm/test/CodeGen/RISCV/stack-guard-tls.ll
new file mode 100644
index 00000000000000..a42feeb7e12fba
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/stack-guard-tls.ll
@@ -0,0 +1,19 @@
+; RUN: llc -mtriple=riscv64-unknown-elf < %s | \
+; RUN: FileCheck %s
+
+declare void @baz(ptr)
+
+define void @foo(i64 %t) sspstrong {
+ %vla = alloca i32, i64 %t, align 4
+ call void @baz(ptr nonnull %vla)
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1, !2}
+!0 = !{i32 2, !"stack-protector-guard", !"tls"}
+!1 = !{i32 1, !"stack-protector-guard-reg", !"tp"}
+!2 = !{i32 2, !"stack-protector-guard-offset", i32 500}
+
+; CHECK: ld [[REG1:.*]], 500(tp)
+; CHECK: call baz
+; CHECK: ld [[REG2:.*]], 500(tp)
More information about the cfe-commits
mailing list