Skip to content

Commit a65404a

Browse files
Rollup merge of #129316 - dingxiangfei2009:riscv64-imac-scs, r=nnethercote
riscv64imac: allow shadow call stack sanitizer cc `@Darksonn` for shadow call stack sanitizer support on RV64IMAC and RV64GC
2 parents d5c40d0 + 9c29b33 commit a65404a

File tree

4 files changed

+52
-9
lines changed

4 files changed

+52
-9
lines changed

compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn target() -> Target {
2828
code_model: Some(CodeModel::Medium),
2929
emit_debug_gdb_scripts: false,
3030
eh_frame_header: false,
31-
supported_sanitizers: SanitizerSet::KERNELADDRESS,
31+
supported_sanitizers: SanitizerSet::KERNELADDRESS | SanitizerSet::SHADOWCALLSTACK,
3232
..Default::default()
3333
},
3434
}

compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn target() -> Target {
2727
code_model: Some(CodeModel::Medium),
2828
emit_debug_gdb_scripts: false,
2929
eh_frame_header: false,
30-
supported_sanitizers: SanitizerSet::KERNELADDRESS,
30+
supported_sanitizers: SanitizerSet::KERNELADDRESS | SanitizerSet::SHADOWCALLSTACK,
3131
..Default::default()
3232
},
3333
}

src/doc/unstable-book/src/compiler-flags/sanitizer.md

+33-7
Original file line numberDiff line numberDiff line change
@@ -775,22 +775,47 @@ See the [Clang SafeStack documentation][clang-safestack] for more details.
775775
776776
# ShadowCallStack
777777
778-
ShadowCallStack provides backward edge control flow protection by storing a function's return address in a separately allocated 'shadow call stack' and loading the return address from that shadow call stack.
779-
780-
ShadowCallStack requires a platform ABI which reserves `x18` as the instrumentation makes use of this register.
778+
ShadowCallStack provides backward edge control flow protection by storing a function's return address in a separately allocated 'shadow call stack'
779+
and loading the return address from that shadow call stack.
780+
AArch64 and RISC-V both have a platform register defined in their ABIs, which is `x18` and `x3`/`gp` respectively, that can optionally be reserved for this purpose.
781+
Software support from the operating system and runtime may be required depending on the target platform which is detailed in the remaining section.
782+
See the [Clang ShadowCallStack documentation][clang-scs] for more details.
781783
782784
ShadowCallStack can be enabled with `-Zsanitizer=shadow-call-stack` option and is supported on the following targets:
783785
784-
* `aarch64-linux-android`
786+
## AArch64 family
785787
786-
A runtime must be provided by the application or operating system.
788+
ShadowCallStack requires the use of the ABI defined platform register, `x18`, which is required for code generation purposes.
789+
When `x18` is not reserved, and is instead used as a scratch register subsequently, enabling ShadowCallStack would lead to undefined behaviour
790+
due to corruption of return address or invalid memory access when the instrumentation restores return register to the link register `lr` from the
791+
already clobbered `x18` register.
792+
In other words, code that is calling into or called by functions instrumented with ShadowCallStack must reserve the `x18` register or preserve its value.
787793
788-
See the [Clang ShadowCallStack documentation][clang-scs] for more details.
794+
### `aarch64-linux-android` and `aarch64-unknown-fuchsia`/`aarch64-fuchsia`
789795
790-
* `aarch64-unknown-none`
796+
This target already reserves the `x18` register.
797+
A runtime must be provided by the application or operating system.
798+
If `bionic` is used on this target, the software support is provided.
799+
Otherwise, a runtime needs to prepare a memory region and points `x18` to the region which serves as the shadow call stack.
800+
801+
### `aarch64-unknown-none`
791802
792803
In addition to support from a runtime by the application or operating system, the `-Zfixed-x18` flag is also mandatory.
793804
805+
## RISC-V 64 family
806+
807+
ShadowCallStack uses either the `gp` register for software shadow stack, also known as `x3`, or the `ssp` register if [`Zicfiss`][riscv-zicfiss] extension is available.
808+
`gp`/`x3` is currently always reserved and available for ShadowCallStack instrumentation, and `ssp` in case of `Zicfiss` is only accessible through its dedicated shadow stack instructions.
809+
810+
Support from the runtime and operating system is required when `gp`/`x3` is used for software shadow stack.
811+
A runtime must prepare a memory region and point `gp`/`x3` to the region before executing the code.
812+
813+
The following targets support ShadowCallStack.
814+
815+
* `riscv64imac-unknown-none-elf`
816+
* `riscv64gc-unknown-none-elf`
817+
* `riscv64gc-unknown-fuchsia`
818+
794819
# ThreadSanitizer
795820
796821
ThreadSanitizer is a data race detection tool. It is supported on the following
@@ -912,3 +937,4 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT
912937
[clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html
913938
[linux-kasan]: https://www.kernel.org/doc/html/latest/dev-tools/kasan.html
914939
[llvm-memtag]: https://llvm.org/docs/MemTagSanitizer.html
940+
[riscv-zicfiss]: https://github.com/riscv/riscv-cfi/blob/3f8e450c481ac303bd5643444f7a89672f24476e/src/cfi_backward.adoc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: --target riscv64imac-unknown-none-elf -Zsanitizer=shadow-call-stack
2+
//@ needs-llvm-components: riscv
3+
4+
#![allow(internal_features)]
5+
#![crate_type = "rlib"]
6+
#![feature(no_core, lang_items)]
7+
#![no_core]
8+
9+
#[lang = "sized"]
10+
trait Sized {}
11+
12+
// CHECK: ; Function Attrs:{{.*}}shadowcallstack
13+
// CHECK: define dso_local void @foo() unnamed_addr #0
14+
#[no_mangle]
15+
pub fn foo() {}
16+
17+
// CHECK: attributes #0 = {{.*}}shadowcallstack{{.*}}

0 commit comments

Comments
 (0)