Hi Cooper,
Great Job!
Tested-by: Guo Ren
Here is kernel related patch with tested result:
https://lore.kernel.org/linux-riscv/1594279697-72511-2-git-send-email-guo...@kernel.org/T/#u
Best Regards
Guo Ren
On 2020/7/8 上午10:51, cooper wrote:
The linux kernel guys are discussing about supporting TLS register based
stack proctector canary, the link is as follows:
https://lore.kernel.org/linux-riscv/202007051820.DABE7F87D7@keescook/T/#t
I implemented register based stack protector canary with reference to
aarch64 and x86. When adding -mstack-protector-guard=tls,
use -mstack-protector-guard= to specify a register such as tp
and mstack-protector-guard-offset= to specify the offset, then
the TLS stack protector canary code will be generated.
gcc/
* config/riscv/riscv-opts.h (stack_protector_guard): New enum.
* config/riscv/riscv.c (riscv_option_override): Handle
the new options.
* config/riscv/riscv.md (stack_protect_set): New pattern to handle
flexible stack protector guard settings.
(stack_protect_set_): Ditto.
(stack_protect_test): Ditto.
(stack_protect_test_): Ditto.
* config/riscv/riscv.opt (mstack-protector-guard=,
mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
options.
* doc/invoke.texi (Option Summary) [RISC-V Options]:
Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
-mstack-protector-guard-offset=.
(RISC-V Options): Ditto.
---
gcc/ChangeLog | 18
gcc/config/riscv/riscv-opts.h | 6 +++
gcc/config/riscv/riscv.c | 41 ++
gcc/config/riscv/riscv.md | 80 +++
gcc/config/riscv/riscv.opt| 28
gcc/doc/invoke.texi | 22 +-
6 files changed, 194 insertions(+), 1 deletion(-)
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ea2f78df22e..98745f9f946 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2020-07-07 Cooper Qu
+
+ * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
+ * config/riscv/riscv.c (riscv_option_override): Handle
+ the new options.
+ * config/riscv/riscv.md (stack_protect_set): New pattern to handle
+ flexible stack protector guard settings.
+ (stack_protect_set_): Ditto.
+ (stack_protect_test): Ditto.
+ (stack_protect_test_): Ditto.
+ * config/riscv/riscv.opt (mstack-protector-guard=,
+ mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
+ options.
+ * doc/invoke.texi (Option Summary) [RISC-V Options]:
+ Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
+ -mstack-protector-guard-offset=.
+ (RISC-V Options): Ditto.
+
2020-07-06 Richard Biener
PR tree-optimization/96075
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 8f12e50b9f1..2a3f9d9eef5 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -51,4 +51,10 @@ enum riscv_align_data {
riscv_align_data_type_natural
};
+/* Where to get the canary for the stack protector. */
+enum stack_protector_guard {
+ SSP_TLS, /* per-thread canary in TLS block */
+ SSP_GLOBAL /* global canary */
+};
+
#endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index bfb3885ed08..e606f24fa74 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -4775,6 +4775,47 @@ riscv_option_override (void)
" [%<-mriscv-attribute%>]");
#endif
+ if (riscv_stack_protector_guard == SSP_GLOBAL
+ && global_options_set.x_riscv_stack_protector_guard_offset_str)
+{
+ error ("incompatible options %<-mstack-protector-guard=global%> and "
+"%<-mstack-protector-guard-offset=%s%>",
+riscv_stack_protector_guard_offset_str);
+}
+
+ if (riscv_stack_protector_guard == SSP_TLS
+ && !(global_options_set.x_riscv_stack_protector_guard_offset_str
+ && global_options_set.x_riscv_stack_protector_guard_reg_str))
+{
+ error ("both %<-mstack-protector-guard-offset%> and "
+"%<-mstack-protector-guard-reg%> must be used "
+"with %<-mstack-protector-guard=sysreg%>");
+}
+
+ if (global_options_set.x_riscv_stack_protector_guard_reg_str)
+{
+ const char *str = riscv_stack_protector_guard_reg_str;
+ int reg = decode_reg_name (str);
+
+ if (!IN_RANGE (reg, 1, 31))
+ error ("%qs is not a valid base register in %qs", str,
+ "-mstack-protector-guard-reg=");
+
+ riscv_stack_protector_guard_reg = reg;
+}
+
+ if (global_options_set.x_riscv_stack_protector_guard_offset_str)
+{
+ char *end;
+ const char *str = riscv_stack_protector_guard_offset_str;
+ errno = 0;
+ long offs = strtol (riscv_stack_protector_guard_offset_str, &e