summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2005-08-12 13:49:18 +0000
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2005-08-12 13:49:18 +0000
commitcc87d0c59d6c0818f8001944b1a93ef1b4949af1 (patch)
tree91f866195d5f6ec59a988d9fde406e5b65966998
parent16b1c40e60b579639387e5ba7b9d535d00343ed7 (diff)
downloadgcc-cc87d0c59d6c0818f8001944b1a93ef1b4949af1.tar.gz
2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com>
Jakub Jelinek <jakub@redhat.com> * config/s390/linux.h (TARGET_THREAD_SSP_OFFSET): Define. * config/s390/s390-protos.h (s390_get_thread_pointer): Prototype added. * config/s390/s390.c (print_operand): New output modifier 'G' added. (get_thread_pointer): Renamed to s390_get_thread_pointer. * config/s390/s390.md (stack_protect_set, stack_protect_test): If TARGET_THREAD_SSP_OFFSET is defined, change operands[1] to (MEM:P (PLUS:P (tp, TARGET_THREAD_SSP_OFFSET))). (UNSPEC_SP_SET, UNSPEC_SP_TEST): New constants. ("stack_protect_set", "stack_protect_test"): New expanders. ("stack_protect_setsi", "stack_protect_setdi", "stack_protect_testsi", "stack_protect_testdi"): New insn definitions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103034 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/s390/linux.h6
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c17
-rw-r--r--gcc/config/s390/s390.md68
5 files changed, 100 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 844115840fd..6c0fae6f6a9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,19 @@
2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * config/s390/linux.h (TARGET_THREAD_SSP_OFFSET): Define.
+ * config/s390/s390-protos.h (s390_get_thread_pointer): Prototype added.
+ * config/s390/s390.c (print_operand): New output modifier 'G' added.
+ (get_thread_pointer): Renamed to s390_get_thread_pointer.
+ * config/s390/s390.md (stack_protect_set, stack_protect_test): If
+ TARGET_THREAD_SSP_OFFSET is defined, change operands[1] to
+ (MEM:P (PLUS:P (tp, TARGET_THREAD_SSP_OFFSET))).
+ (UNSPEC_SP_SET, UNSPEC_SP_TEST): New constants.
+ ("stack_protect_set", "stack_protect_test"): New expanders.
+ ("stack_protect_setsi", "stack_protect_setdi", "stack_protect_testsi",
+ "stack_protect_testdi"): New insn definitions.
+
+2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390.md ("*movdf_31"): Changed constraint from P to K.
diff --git a/gcc/config/s390/linux.h b/gcc/config/s390/linux.h
index 866ed5edd47..4f58c734547 100644
--- a/gcc/config/s390/linux.h
+++ b/gcc/config/s390/linux.h
@@ -94,4 +94,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define MD_UNWIND_SUPPORT "config/s390/linux-unwind.h"
+#ifdef TARGET_LIBC_PROVIDES_SSP
+/* s390 glibc provides __stack_chk_guard in 0x14(tp),
+ s390x glibc provides it at 0x28(tp). */
+#define TARGET_THREAD_SSP_OFFSET (TARGET_64BIT ? 0x28 : 0x14)
+#endif
+
#endif
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 7d63c7503e3..c9480591b23 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -91,6 +91,7 @@ extern void s390_initialize_trampoline (rtx, rtx, rtx);
extern rtx s390_gen_rtx_const_DI (int, int);
extern int s390_agen_dep_p (rtx, rtx);
extern rtx s390_load_got (void);
+extern rtx s390_get_thread_pointer (void);
extern void s390_emit_tpf_eh_return (rtx);
extern bool s390_legitimate_address_without_index_p (rtx);
extern int s390_branch_condition_mask (rtx);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 277006f6473..b5e1bf7f6fd 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2832,8 +2832,8 @@ legitimize_pic_address (rtx orig, rtx reg)
/* Load the thread pointer into a register. */
-static rtx
-get_thread_pointer (void)
+rtx
+s390_get_thread_pointer (void)
{
rtx tp = gen_reg_rtx (Pmode);
@@ -2893,7 +2893,7 @@ legitimize_tls_address (rtx addr, rtx reg)
temp = gen_reg_rtx (Pmode);
emit_libcall_block (insn, temp, r2, new);
- new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
+ new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
if (reg != 0)
{
s390_load_address (reg, new);
@@ -2916,7 +2916,7 @@ legitimize_tls_address (rtx addr, rtx reg)
temp = gen_reg_rtx (Pmode);
emit_libcall_block (insn, temp, r2, new);
- new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
+ new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
base = gen_reg_rtx (Pmode);
s390_load_address (base, new);
@@ -3003,7 +3003,7 @@ legitimize_tls_address (rtx addr, rtx reg)
emit_insn (gen_rtx_SET (Pmode, temp, new));
}
- new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
+ new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
if (reg != 0)
{
s390_load_address (reg, new);
@@ -3018,7 +3018,7 @@ legitimize_tls_address (rtx addr, rtx reg)
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
- new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
+ new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
if (reg != 0)
{
s390_load_address (reg, new);
@@ -3931,6 +3931,7 @@ print_operand_address (FILE *file, rtx addr)
'C': print opcode suffix for branch condition.
'D': print opcode suffix for inverse branch condition.
'J': print tls_load/tls_gdcall/tls_ldcall suffix
+ 'G': print the size of the operand in bytes.
'O': print only the displacement of a memory reference.
'R': print only the base register of a memory reference.
'S': print S-type memory reference (base+displacement).
@@ -3977,6 +3978,10 @@ print_operand (FILE *file, rtx x, int code)
gcc_unreachable ();
return;
+ case 'G':
+ fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
+ return;
+
case 'O':
{
struct s390_address ad;
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 26e0e792918..85e0b60b30d 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -122,7 +122,11 @@
(UNSPEC_TLS_LOAD 512)
; String Functions
- (UNSPEC_SRST 600)
+ (UNSPEC_SRST 600)
+
+ ; Stack Smashing Protector
+ (UNSPEC_SP_SET 700)
+ (UNSPEC_SP_TEST 701)
])
;;
@@ -7145,3 +7149,65 @@
DONE;
})
+;
+; Stack Protector Patterns
+;
+
+(define_expand "stack_protect_set"
+ [(set (match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" ""))]
+ ""
+{
+#ifdef TARGET_THREAD_SSP_OFFSET
+ operands[1]
+ = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+#endif
+ 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;
+})
+
+(define_insn "stack_protect_set<mode>"
+ [(set (match_operand:DSI 0 "memory_operand" "=Q")
+ (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
+ ""
+ "mvc\t%O0(%G0,%R0),%S1"
+ [(set_attr "op_type" "SS")])
+
+(define_expand "stack_protect_test"
+ [(set (reg:CC CC_REGNUM)
+ (compare (match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" "")))
+ (match_operand 2 "" "")]
+ ""
+{
+#ifdef TARGET_THREAD_SSP_OFFSET
+ operands[1]
+ = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+#endif
+ s390_compare_op0 = operands[0];
+ s390_compare_op1 = operands[1];
+ s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
+ else
+ emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
+
+ emit_jump_insn (gen_beq (operands[2]));
+
+ DONE;
+})
+
+(define_insn "stack_protect_test<mode>"
+ [(set (reg:CCZ CC_REGNUM)
+ (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
+ (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
+ ""
+ "clc\t%O0(%G0,%R0),%S1"
+ [(set_attr "op_type" "SS")])