https://github.com/keith-packard updated https://github.com/llvm/llvm-project/pull/108942
>From 156b989feea26694b291cde9be637947be9aca67 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 16 Sep 2024 15:41:38 +0200 Subject: [PATCH 1/4] 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 <kei...@keithp.com> --- clang/lib/Driver/ToolChains/Clang.cpp | 28 ++++++++++++++++++--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 8 ++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3fe4ce5d893b8d..76692bf8176cf5 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; @@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, 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 +3698,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..0593fbf403dfcb 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()->getModule(); + + if (M->getStackProtectorGuard() == "tls") { + // Users must specify the offset explicitly + int Offset = M->getStackProtectorGuardOffset(); + return useTpOffset(IRB, Offset); + } + return TargetLowering::getIRStackGuard(IRB); } >From 32cf791269138c2d983741617c5581109aa96864 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 16 Sep 2024 11:27:19 -0700 Subject: [PATCH 2/4] 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 <kei...@keithp.com> --- clang/test/CodeGen/stack-protector-guard.c | 9 +++++++++ clang/test/Driver/stack-protector-guard.c | 19 +++++++++++++++++++ 2 files changed, 28 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..d8475a70e3709f 100644 --- a/clang/test/Driver/stack-protector-guard.c +++ b/clang/test/Driver/stack-protector-guard.c @@ -85,3 +85,22 @@ // 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: %clang -### -target riscv64-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=tp %s 2>&1 | \ +// RUN: FileCheck -v -check-prefix=CHECK-TLS-RISCV %s +// RUN: %clang -### -target riscv64-unknown-elf -mstack-protector-guard=global %s 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s + +// CHECK-TLS-RISCV: "-cc1" {{.*}}"-mstack-protector-guard=tls" "-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=tp" + +// 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=sysreg %s 2>&1 | \ +// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s + +// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=tls \ +// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=sp %s 2>&1 | \ +// RUN: FileCheck -check-prefix=INVALID-REG-RISCV %s + +// INVALID-REG-RISCV: error: invalid value 'sp' in 'mstack-protector-guard-reg=', expected one of: tp >From d4f3d78ffc1eefb40fc353d1c8a74d7fc2e10932 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 16 Sep 2024 12:36:06 -0700 Subject: [PATCH 3/4] 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 <kei...@keithp.com> --- llvm/test/CodeGen/RISCV/stack-guard-tls.ll | 45 ++++++++++++++++++++++ 1 file changed, 45 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..34bd7030656294 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/stack-guard-tls.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=riscv64-unknown-elf -verify-machineinstrs < %s \ +; RUN: | FileCheck %s + +define void @foo(i64 %t) sspstrong { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; CHECK-NEXT: .cfi_offset ra, -8 +; CHECK-NEXT: .cfi_offset s0, -16 +; CHECK-NEXT: addi s0, sp, 32 +; CHECK-NEXT: .cfi_def_cfa s0, 0 +; CHECK-NEXT: ld a1, 500(tp) +; CHECK-NEXT: sd a1, -24(s0) +; CHECK-NEXT: slli a0, a0, 2 +; CHECK-NEXT: addi a0, a0, 15 +; CHECK-NEXT: andi a0, a0, -16 +; CHECK-NEXT: sub a0, sp, a0 +; CHECK-NEXT: mv sp, a0 +; CHECK-NEXT: call baz +; CHECK-NEXT: ld a0, 500(tp) +; CHECK-NEXT: ld a1, -24(s0) +; CHECK-NEXT: bne a0, a1, .LBB0_2 +; CHECK-NEXT: # %bb.1: # %SP_return +; CHECK-NEXT: addi sp, s0, -32 +; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; CHECK-NEXT: addi sp, sp, 32 +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB0_2: # %CallStackCheckFailBlk +; CHECK-NEXT: call __stack_chk_fail + %vla = alloca i32, i64 %t, align 4 + call void @baz(ptr nonnull %vla) + ret void +} + +declare void @baz(ptr) + +!llvm.module.flags = !{!1, !2, !3} +!1 = !{i32 2, !"stack-protector-guard", !"tls"} +!2 = !{i32 2, !"stack-protector-guard-reg", !"tp"} +!3 = !{i32 2, !"stack-protector-guard-offset", i32 500} >From 5b4f01e094d8e96f25d2fbd1064d7fc5d157ba4b Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 23 Sep 2024 11:34:21 -0700 Subject: [PATCH 4/4] riscv: Add codegen test for global stack canary Make sure the code generated for a global stack guard canary references __stack_chk_guard before and after intervening function code. Signed-off-by: Keith Packard <kei...@keithp.com> --- llvm/test/CodeGen/RISCV/stack-guard-global.ll | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 llvm/test/CodeGen/RISCV/stack-guard-global.ll diff --git a/llvm/test/CodeGen/RISCV/stack-guard-global.ll b/llvm/test/CodeGen/RISCV/stack-guard-global.ll new file mode 100644 index 00000000000000..b3000703003d57 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/stack-guard-global.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=riscv64-unknown-elf -verify-machineinstrs < %s \ +; RUN: | FileCheck %s + +define void @foo(i64 %t) sspstrong { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; CHECK-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; CHECK-NEXT: .cfi_offset ra, -8 +; CHECK-NEXT: .cfi_offset s0, -16 +; CHECK-NEXT: .cfi_offset s1, -24 +; CHECK-NEXT: addi s0, sp, 32 +; CHECK-NEXT: .cfi_def_cfa s0, 0 +; CHECK-NEXT: lui s1, %hi(__stack_chk_guard) +; CHECK-NEXT: ld a1, %lo(__stack_chk_guard)(s1) +; CHECK-NEXT: sd a1, -32(s0) +; CHECK-NEXT: slli a0, a0, 2 +; CHECK-NEXT: addi a0, a0, 15 +; CHECK-NEXT: andi a0, a0, -16 +; CHECK-NEXT: sub a0, sp, a0 +; CHECK-NEXT: mv sp, a0 +; CHECK-NEXT: call baz +; CHECK-NEXT: ld a0, %lo(__stack_chk_guard)(s1) +; CHECK-NEXT: ld a1, -32(s0) +; CHECK-NEXT: bne a0, a1, .LBB0_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: addi sp, s0, -32 +; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; CHECK-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; CHECK-NEXT: addi sp, sp, 32 +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: call __stack_chk_fail + %vla = alloca i32, i64 %t, align 4 + call void @baz(ptr nonnull %vla) + ret void +} + +declare void @baz(ptr) + +!llvm.module.flags = !{!1} +!1 = !{i32 2, !"stack-protector-guard", !"global"} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits