|
|
4dd737 |
2017-01-17 Segher Boessenkool <segher@kernel.crashing.org>
|
|
|
4dd737 |
|
|
|
4dd737 |
PR target/78875
|
|
|
4dd737 |
* config/rs6000/rs6000-opts.h (stack_protector_guard): New enum.
|
|
|
4dd737 |
* config/rs6000/rs6000.c (rs6000_option_override_internal): Handle
|
|
|
4dd737 |
the new options.
|
|
|
4dd737 |
* config/rs6000/rs6000.md (stack_protect_set): Handle the new more
|
|
|
4dd737 |
flexible settings.
|
|
|
4dd737 |
(stack_protect_test): Ditto.
|
|
|
4dd737 |
* config/rs6000/rs6000.opt (mstack-protector-guard=,
|
|
|
4dd737 |
mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
|
|
|
4dd737 |
options.
|
|
|
4dd737 |
* doc/invoke.texi (Option Summary) [RS/6000 and PowerPC Options]:
|
|
|
4dd737 |
Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
|
|
|
4dd737 |
-mstack-protector-guard-offset=.
|
|
|
4dd737 |
(RS/6000 and PowerPC Options): Ditto.
|
|
|
4dd737 |
|
|
|
4dd737 |
* gcc.target/powerpc/ssp-1.c: New testcase.
|
|
|
4dd737 |
* gcc.target/powerpc/ssp-2.c: New testcase.
|
|
|
4dd737 |
|
|
|
4dd737 |
--- gcc/config/rs6000/rs6000.opt (revision 244555)
|
|
|
4dd737 |
+++ gcc/config/rs6000/rs6000.opt (revision 244556)
|
|
|
4dd737 |
@@ -593,3 +593,31 @@ Allow float variables in upper registers
|
|
|
4dd737 |
moptimize-swaps
|
|
|
4dd737 |
Target Undocumented Var(rs6000_optimize_swaps) Init(1) Save
|
|
|
4dd737 |
Analyze and remove doubleword swaps from VSX computations.
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+mstack-protector-guard=
|
|
|
4dd737 |
+Target RejectNegative Joined Enum(stack_protector_guard) Var(rs6000_stack_protector_guard) Init(SSP_TLS)
|
|
|
4dd737 |
+Use given stack-protector guard.
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+Enum
|
|
|
4dd737 |
+Name(stack_protector_guard) Type(enum stack_protector_guard)
|
|
|
4dd737 |
+Valid arguments to -mstack-protector-guard=:
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+EnumValue
|
|
|
4dd737 |
+Enum(stack_protector_guard) String(tls) Value(SSP_TLS)
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+EnumValue
|
|
|
4dd737 |
+Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL)
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+mstack-protector-guard-reg=
|
|
|
4dd737 |
+Target RejectNegative Joined Var(rs6000_stack_protector_guard_reg_str)
|
|
|
4dd737 |
+Use the given base register for addressing the stack-protector guard.
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+TargetVariable
|
|
|
4dd737 |
+int rs6000_stack_protector_guard_reg = 0
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+mstack-protector-guard-offset=
|
|
|
4dd737 |
+Target RejectNegative Joined Integer Var(rs6000_stack_protector_guard_offset_str)
|
|
|
4dd737 |
+Use the given offset for addressing the stack-protector guard.
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+TargetVariable
|
|
|
4dd737 |
+long rs6000_stack_protector_guard_offset = 0
|
|
|
4dd737 |
--- gcc/config/rs6000/rs6000.c (revision 244555)
|
|
|
4dd737 |
+++ gcc/config/rs6000/rs6000.c (revision 244556)
|
|
|
4dd737 |
@@ -3727,6 +3727,54 @@ rs6000_option_override_internal (bool gl
|
|
|
4dd737 |
atoi (rs6000_sched_insert_nops_str));
|
|
|
4dd737 |
}
|
|
|
4dd737 |
|
|
|
4dd737 |
+ /* Handle stack protector */
|
|
|
4dd737 |
+ if (!global_options_set.x_rs6000_stack_protector_guard)
|
|
|
4dd737 |
+#ifdef TARGET_THREAD_SSP_OFFSET
|
|
|
4dd737 |
+ rs6000_stack_protector_guard = SSP_TLS;
|
|
|
4dd737 |
+#else
|
|
|
4dd737 |
+ rs6000_stack_protector_guard = SSP_GLOBAL;
|
|
|
4dd737 |
+#endif
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+#ifdef TARGET_THREAD_SSP_OFFSET
|
|
|
4dd737 |
+ rs6000_stack_protector_guard_offset = TARGET_THREAD_SSP_OFFSET;
|
|
|
4dd737 |
+ rs6000_stack_protector_guard_reg = TARGET_64BIT ? 13 : 2;
|
|
|
4dd737 |
+#endif
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ if (global_options_set.x_rs6000_stack_protector_guard_offset_str)
|
|
|
4dd737 |
+ {
|
|
|
4dd737 |
+ char *endp;
|
|
|
4dd737 |
+ const char *str = rs6000_stack_protector_guard_offset_str;
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ errno = 0;
|
|
|
4dd737 |
+ long offset = strtol (str, &endp, 0);
|
|
|
4dd737 |
+ if (!*str || *endp || errno)
|
|
|
4dd737 |
+ error ("%qs is not a valid number "
|
|
|
4dd737 |
+ "in -mstack-protector-guard-offset=", str);
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ if (!IN_RANGE (offset, -0x8000, 0x7fff)
|
|
|
4dd737 |
+ || (TARGET_64BIT && (offset & 3)))
|
|
|
4dd737 |
+ error ("%qs is not a valid offset "
|
|
|
4dd737 |
+ "in -mstack-protector-guard-offset=", str);
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ rs6000_stack_protector_guard_offset = offset;
|
|
|
4dd737 |
+ }
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ if (global_options_set.x_rs6000_stack_protector_guard_reg_str)
|
|
|
4dd737 |
+ {
|
|
|
4dd737 |
+ const char *str = rs6000_stack_protector_guard_reg_str;
|
|
|
4dd737 |
+ int reg = decode_reg_name (str);
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ if (!IN_RANGE (reg, 1, 31))
|
|
|
4dd737 |
+ error ("%qs is not a valid base register "
|
|
|
4dd737 |
+ "in -mstack-protector-guard-reg=", str);
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ rs6000_stack_protector_guard_reg = reg;
|
|
|
4dd737 |
+ }
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ if (rs6000_stack_protector_guard == SSP_TLS
|
|
|
4dd737 |
+ && !IN_RANGE (rs6000_stack_protector_guard_reg, 1, 31))
|
|
|
4dd737 |
+ error ("-mstack-protector-guard=tls needs a valid base register");
|
|
|
4dd737 |
+
|
|
|
4dd737 |
if (global_init_p)
|
|
|
4dd737 |
{
|
|
|
4dd737 |
#ifdef TARGET_REGNAMES
|
|
|
4dd737 |
--- gcc/config/rs6000/rs6000.md (revision 244555)
|
|
|
4dd737 |
+++ gcc/config/rs6000/rs6000.md (revision 244556)
|
|
|
4dd737 |
@@ -13092,19 +13092,23 @@
|
|
|
4dd737 |
|
|
|
4dd737 |
|
|
|
4dd737 |
(define_expand "stack_protect_set"
|
|
|
4dd737 |
- [(match_operand 0 "memory_operand" "")
|
|
|
4dd737 |
- (match_operand 1 "memory_operand" "")]
|
|
|
4dd737 |
+ [(match_operand 0 "memory_operand")
|
|
|
4dd737 |
+ (match_operand 1 "memory_operand")]
|
|
|
4dd737 |
""
|
|
|
4dd737 |
{
|
|
|
4dd737 |
-#ifdef TARGET_THREAD_SSP_OFFSET
|
|
|
4dd737 |
- rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
|
|
|
4dd737 |
- rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
|
|
|
4dd737 |
- operands[1] = gen_rtx_MEM (Pmode, addr);
|
|
|
4dd737 |
-#endif
|
|
|
4dd737 |
+ if (rs6000_stack_protector_guard == SSP_TLS)
|
|
|
4dd737 |
+ {
|
|
|
4dd737 |
+ rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
|
|
|
4dd737 |
+ rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
|
|
|
4dd737 |
+ rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
|
|
|
4dd737 |
+ operands[1] = gen_rtx_MEM (Pmode, addr);
|
|
|
4dd737 |
+ }
|
|
|
4dd737 |
+
|
|
|
4dd737 |
if (TARGET_64BIT)
|
|
|
4dd737 |
emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
|
|
|
4dd737 |
else
|
|
|
4dd737 |
emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
|
|
|
4dd737 |
+
|
|
|
4dd737 |
DONE;
|
|
|
4dd737 |
})
|
|
|
4dd737 |
|
|
|
4dd737 |
@@ -13127,21 +13131,26 @@
|
|
|
4dd737 |
(set_attr "length" "12")])
|
|
|
4dd737 |
|
|
|
4dd737 |
(define_expand "stack_protect_test"
|
|
|
4dd737 |
- [(match_operand 0 "memory_operand" "")
|
|
|
4dd737 |
- (match_operand 1 "memory_operand" "")
|
|
|
4dd737 |
- (match_operand 2 "" "")]
|
|
|
4dd737 |
+ [(match_operand 0 "memory_operand")
|
|
|
4dd737 |
+ (match_operand 1 "memory_operand")
|
|
|
4dd737 |
+ (match_operand 2 "")]
|
|
|
4dd737 |
""
|
|
|
4dd737 |
{
|
|
|
4dd737 |
- rtx test, op0, op1;
|
|
|
4dd737 |
-#ifdef TARGET_THREAD_SSP_OFFSET
|
|
|
4dd737 |
- rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
|
|
|
4dd737 |
- rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
|
|
|
4dd737 |
- operands[1] = gen_rtx_MEM (Pmode, addr);
|
|
|
4dd737 |
-#endif
|
|
|
4dd737 |
- op0 = operands[0];
|
|
|
4dd737 |
- op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
|
|
|
4dd737 |
- test = gen_rtx_EQ (VOIDmode, op0, op1);
|
|
|
4dd737 |
- emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
|
|
|
4dd737 |
+ rtx guard = operands[1];
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ if (rs6000_stack_protector_guard == SSP_TLS)
|
|
|
4dd737 |
+ {
|
|
|
4dd737 |
+ rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
|
|
|
4dd737 |
+ rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
|
|
|
4dd737 |
+ rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
|
|
|
4dd737 |
+ guard = gen_rtx_MEM (Pmode, addr);
|
|
|
4dd737 |
+ }
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+ operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
|
|
|
4dd737 |
+ rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
|
|
|
4dd737 |
+ rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
|
|
|
4dd737 |
+ emit_jump_insn (jump);
|
|
|
4dd737 |
+
|
|
|
4dd737 |
DONE;
|
|
|
4dd737 |
})
|
|
|
4dd737 |
|
|
|
4dd737 |
--- gcc/config/rs6000/rs6000-opts.h (revision 244555)
|
|
|
4dd737 |
+++ gcc/config/rs6000/rs6000-opts.h (revision 244556)
|
|
|
4dd737 |
@@ -154,6 +154,12 @@ enum rs6000_vector {
|
|
|
4dd737 |
VECTOR_OTHER /* Some other vector unit */
|
|
|
4dd737 |
};
|
|
|
4dd737 |
|
|
|
4dd737 |
+/* Where to get the canary for the stack protector. */
|
|
|
4dd737 |
+enum stack_protector_guard {
|
|
|
4dd737 |
+ SSP_TLS, /* per-thread canary in TLS block */
|
|
|
4dd737 |
+ SSP_GLOBAL /* global canary */
|
|
|
4dd737 |
+};
|
|
|
4dd737 |
+
|
|
|
4dd737 |
/* No enumeration is defined to index the -mcpu= values (entries in
|
|
|
4dd737 |
processor_target_table), with the type int being used instead, but
|
|
|
4dd737 |
we need to distinguish the special "native" value. */
|
|
|
4dd737 |
--- gcc/doc/invoke.texi (revision 244555)
|
|
|
4dd737 |
+++ gcc/doc/invoke.texi (revision 244556)
|
|
|
4dd737 |
@@ -862,7 +862,9 @@ See RS/6000 and PowerPC Options.
|
|
|
4dd737 |
-mcrypto -mno-crypto -mdirect-move -mno-direct-move @gol
|
|
|
4dd737 |
-mquad-memory -mno-quad-memory @gol
|
|
|
4dd737 |
-mquad-memory-atomic -mno-quad-memory-atomic @gol
|
|
|
4dd737 |
--mcompat-align-parm -mno-compat-align-parm}
|
|
|
4dd737 |
+-mcompat-align-parm -mno-compat-align-parm @gol
|
|
|
4dd737 |
+-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
|
|
|
4dd737 |
+-mstack-protector-guard-offset=@var{offset}}
|
|
|
4dd737 |
|
|
|
4dd737 |
@emph{RX Options}
|
|
|
4dd737 |
@gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol
|
|
|
4dd737 |
@@ -18295,6 +18297,23 @@ GCC.
|
|
|
4dd737 |
|
|
|
4dd737 |
In this version of the compiler, the @option{-mcompat-align-parm}
|
|
|
4dd737 |
is the default, except when using the Linux ELFv2 ABI.
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+@item -mstack-protector-guard=@var{guard}
|
|
|
4dd737 |
+@itemx -mstack-protector-guard-reg=@var{reg}
|
|
|
4dd737 |
+@itemx -mstack-protector-guard-offset=@var{offset}
|
|
|
4dd737 |
+@opindex mstack-protector-guard
|
|
|
4dd737 |
+@opindex mstack-protector-guard-reg
|
|
|
4dd737 |
+@opindex mstack-protector-guard-offset
|
|
|
4dd737 |
+Generate stack protection code using canary at @var{guard}. Supported
|
|
|
4dd737 |
+locations are @samp{global} for global canary or @samp{tls} for per-thread
|
|
|
4dd737 |
+canary in the TLS block (the default with GNU libc version 2.4 or later).
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+With the latter choice the options
|
|
|
4dd737 |
+@option{-mstack-protector-guard-reg=@var{reg}} and
|
|
|
4dd737 |
+@option{-mstack-protector-guard-offset=@var{offset}} furthermore specify
|
|
|
4dd737 |
+which register to use as base register for reading the canary, and from what
|
|
|
4dd737 |
+offset from that base register. The default for those is as specified in the
|
|
|
4dd737 |
+relevant ABI.
|
|
|
4dd737 |
@end table
|
|
|
4dd737 |
|
|
|
4dd737 |
@node RX Options
|
|
|
4dd737 |
--- gcc/testsuite/gcc.target/powerpc/ssp-1.c (nonexistent)
|
|
|
4dd737 |
+++ gcc/testsuite/gcc.target/powerpc/ssp-1.c (revision 244562)
|
|
|
4dd737 |
@@ -0,0 +1,6 @@
|
|
|
4dd737 |
+/* { dg-do compile } */
|
|
|
4dd737 |
+/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+/* { dg-final { scan-assembler "__stack_chk_guard" } } */
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+void f(void) { }
|
|
|
4dd737 |
--- gcc/testsuite/gcc.target/powerpc/ssp-2.c (nonexistent)
|
|
|
4dd737 |
+++ gcc/testsuite/gcc.target/powerpc/ssp-2.c (revision 244562)
|
|
|
4dd737 |
@@ -0,0 +1,6 @@
|
|
|
4dd737 |
+/* { dg-do compile } */
|
|
|
4dd737 |
+/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=tls -mstack-protector-guard-reg=r18 -mstack-protector-guard-offset=0x3038" } */
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+/* { dg-final { scan-assembler {\m12344\(r?18\)} } } */
|
|
|
4dd737 |
+
|
|
|
4dd737 |
+void f(void) { }
|