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