; Stack Protector
UNSPECV_SP_GET_TP
+ UNSPECV_SP_GLOBAL_GUARD_ADDR
])
;;
; Stack Protector Patterns
;
+(define_insn "stack_protect_global_guard_addr<mode>"
+ [(set (match_operand:P 0 "register_operand" "=d")
+ (unspec_volatile:P [(const_int 0)] UNSPECV_SP_GLOBAL_GUARD_ADDR))]
+ ""
+{
+ if (flag_s390_stack_protector_guard_record)
+ fprintf (asm_out_file, "1:\n");
+ if (flag_pic)
+ {
+ if (TARGET_Z10)
+ output_asm_insn ("l<g>rl\t%0,__stack_chk_guard@GOTENT", operands);
+ else
+ {
+ output_asm_insn ("larl\t%0,__stack_chk_guard@GOTENT", operands);
+ output_asm_insn ("l<g>\t%0,0(%0)", operands);
+ }
+ }
+ else
+ output_asm_insn ("larl\t%0,__stack_chk_guard", operands);
+ if (flag_s390_stack_protector_guard_record)
+ fprintf (asm_out_file, "\t.section __stack_protector_loc,\\"a\\",@progbits\n"
+ "\t.%s 1b\n"
+ "\t.previous\n", TARGET_64BIT ? "quad" : "long");
+ return "";
+}
+ [(set (attr "mnemonic")
+ (cond [(match_test "flag_pic && TARGET_Z10") (const_string "l<g>rl")
+ (match_test "flag_pic && !TARGET_Z10") (const_string "*")]
+ (const_string "larl")))])
+
; Insns stack_protect_get_tp{si,di} are similar to *get_tp_{31,64} but still
; distinct in the sense that they force recomputation of the thread pointer
; instead of potentially reloading it from stack.
(match_operand 1 "memory_operand" ""))]
""
{
-#ifdef TARGET_THREAD_SSP_OFFSET
- rtx tp = gen_reg_rtx (Pmode);
- if (TARGET_64BIT)
- emit_insn (gen_stack_protect_get_tpdi (tp));
+ if (TARGET_SP_GLOBAL_GUARD)
+ {
+ rtx addr = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_global_guard_addrdi (addr));
+ else
+ emit_insn (gen_stack_protect_global_guard_addrsi (addr));
+ operands[1] = gen_rtx_MEM (Pmode, addr);
+ }
else
- emit_insn (gen_stack_protect_get_tpsi (tp));
- operands[1]
- = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tp,
- GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+ {
+#ifdef TARGET_THREAD_SSP_OFFSET
+ rtx tp = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_get_tpdi (tp));
+ else
+ emit_insn (gen_stack_protect_get_tpsi (tp));
+ operands[1]
+ = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tp,
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
#endif
+ }
if (TARGET_64BIT)
emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
else
""
{
rtx cc_reg, test;
-#ifdef TARGET_THREAD_SSP_OFFSET
- rtx tp = gen_reg_rtx (Pmode);
- if (TARGET_64BIT)
- emit_insn (gen_stack_protect_get_tpdi (tp));
+ if (TARGET_SP_GLOBAL_GUARD)
+ {
+ rtx addr = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_global_guard_addrdi (addr));
+ else
+ emit_insn (gen_stack_protect_global_guard_addrsi (addr));
+ operands[1] = gen_rtx_MEM (Pmode, addr);
+ }
else
- emit_insn (gen_stack_protect_get_tpsi (tp));
- operands[1]
- = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tp,
- GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+ {
+#ifdef TARGET_THREAD_SSP_OFFSET
+ rtx tp = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_get_tpdi (tp));
+ else
+ emit_insn (gen_stack_protect_get_tpsi (tp));
+ operands[1]
+ = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tp,
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
#endif
+ }
if (TARGET_64BIT)
emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
else
Target RejectNegative Alias(mstack-guard=,0) Negative(mstack-guard=)
Switches off the -mstack-guard= option.
+mstack-protector-guard=
+Target RejectNegative Joined Enum(stack_protector_guard) Var(s390_stack_protector_guard) Init(SP_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(SP_TLS)
+
+EnumValue
+Enum(stack_protector_guard) String(global) Value(SP_GLOBAL)
+
+mstack-protector-guard-record
+Target Var(flag_s390_stack_protector_guard_record)
+Generate section __stack_protector_loc containing pointers to all instructions which load the address of the global guard.
+
mstack-size=
Target RejectNegative Joined UInteger Var(s390_stack_size) Save
Emit extra code in the function prologue in order to trap if the stack size exceeds the given limit.