From: Uros Bizjak Date: Tue, 8 Aug 2017 16:48:46 +0000 (+0200) Subject: re PR target/81708 (The x86 stack canary location should be customizable) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d5bf81b30f7d3faf58d52784013749ca0f9f980f;p=gcc.git re PR target/81708 (The x86 stack canary location should be customizable) PR target/81708 * config/i386/i386.opt (mstack-protector-guard-reg=): New option (mstack-protector-guard-offset=): Ditto. * config/i386/i386.c (ix86_option_override): Handle -mstack-protector-guard-reg= and -mstack-protector-guard-offset= options. (ix86_stack_protect_guard): Use ix86_stack_protect_guard_reg and ix86_stack_protect_guard_offset variables. (TARGET_STACK_PROTECT_GUARD): Always define. * doc/invoke.texi (x86 Options): Document -mstack-protector-guard-reg= and -mstack-protector-guard-offset= options. testsuite/ChangeLog: PR target/81708 * gcc.target/i386/stack-prot-guard.c: New test. From-SVN: r250965 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e62420b9ccb..321861a6d8c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2017-08-08 Uros Bizjak + + PR target/81708 + * config/i386/i386.opt (mstack-protector-guard-reg=): New option + (mstack-protector-guard-offset=): Ditto. + * config/i386/i386.c (ix86_option_override): Handle + -mstack-protector-guard-reg= and -mstack-protector-guard-offset= + options. + (ix86_stack_protect_guard): Use ix86_stack_protect_guard_reg and + ix86_stack_protect_guard_offset variables. + (TARGET_STACK_PROTECT_GUARD): Always define. + * doc/invoke.texi (x86 Options): Document -mstack-protector-guard-reg= + and -mstack-protector-guard-offset= options. + 2017-08-08 Bin Cheng * tree-ssa-loop-ivopts.c (relate_compare_use_with_all_cands): Handle @@ -25,7 +39,8 @@ * optabs.def (xorsign_optab): New. * tree-ssa-math-opts.c (is_copysign_call_with_1): New. (convert_expand_mult_copysign): New. - (pass_optimize_widening_mul::execute): Call convert_expand_mult_copysign. + (pass_optimize_widening_mul::execute): Call + convert_expand_mult_copysign. 2017-08-08 Bill Schmidt @@ -212,7 +227,7 @@ (vsx_set_, VSX_D): Rewrite vector set in terms of vector concat to allow optimizing inserts from previous extracts. -2017-08-06 Uros Bizjak +2017-08-07 Uros Bizjak * config/i386/i386.c (ix86_stack_protect_guard): Generate memory reference to a SSP offset in TLS address space. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index dfef996e36c..3f8519777f7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6662,6 +6662,69 @@ ix86_option_override_internal (bool main_args_p, opts->x_ix86_stack_protector_guard = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS; +#ifdef TARGET_THREAD_SSP_OFFSET + ix86_stack_protector_guard_offset = TARGET_THREAD_SSP_OFFSET; +#endif + + if (global_options_set.x_ix86_stack_protector_guard_offset_str) + { + char *endp; + const char *str = ix86_stack_protector_guard_offset_str; + + errno = 0; + int64_t offset; + +#if defined(INT64_T_IS_LONG) + offset = strtol (str, &endp, 0); +#else + offset = strtoll (str, &endp, 0); +#endif + + if (!*str || *endp || errno) + error ("%qs is not a valid number " + "in -mstack-protector-guard-offset=", str); + + if (!IN_RANGE (offset, HOST_WIDE_INT_C (-0x80000000), + HOST_WIDE_INT_C (0x7fffffff))) + error ("%qs is not a valid offset " + "in -mstack-protector-guard-offset=", str); + + ix86_stack_protector_guard_offset = offset; + } + + ix86_stack_protector_guard_reg = DEFAULT_TLS_SEG_REG; + + /* The kernel uses a different segment register for performance + reasons; a system call would not have to trash the userspace + segment register, which would be expensive. */ + if (ix86_cmodel == CM_KERNEL) + ix86_stack_protector_guard_reg = ADDR_SPACE_SEG_GS; + + if (global_options_set.x_ix86_stack_protector_guard_reg_str) + { + const char *str = ix86_stack_protector_guard_reg_str; + addr_space_t seg = ADDR_SPACE_GENERIC; + + /* Discard optional register prefix. */ + if (str[0] == '%') + str++; + + if (strlen (str) == 2 && str[1] == 's') + { + if (str[0] == 'f') + seg = ADDR_SPACE_SEG_FS; + else if (str[0] == 'g') + seg = ADDR_SPACE_SEG_GS; + } + + if (seg == ADDR_SPACE_GENERIC) + error ("%qs is not a valid base register " + "in -mstack-protector-guard-reg=", + ix86_stack_protector_guard_reg_str); + + ix86_stack_protector_guard_reg = seg; + } + /* Handle -mmemcpy-strategy= and -mmemset-strategy= */ if (opts->x_ix86_tune_memcpy_strategy) { @@ -45795,27 +45858,19 @@ ix86_mangle_type (const_tree type) } } -#ifdef TARGET_THREAD_SSP_OFFSET static tree ix86_stack_protect_guard (void) { if (TARGET_SSP_TLS_GUARD) { tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1); - addr_space_t as = DEFAULT_TLS_SEG_REG; - /* The kernel uses a different segment register for performance - reasons; a system call would not have to trash the userspace - segment register, which would be expensive. */ - if (ix86_cmodel == CM_KERNEL) - as = ADDR_SPACE_SEG_GS; - - int qual = ENCODE_QUAL_ADDR_SPACE (as); + int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg); tree type = build_qualified_type (type_node, qual); tree asptrtype = build_pointer_type (type); - tree sspoff = build_int_cst (asptrtype, TARGET_THREAD_SSP_OFFSET); - + tree sspoff = build_int_cst (asptrtype, + ix86_stack_protector_guard_offset); tree t = build2 (MEM_REF, asptrtype, sspoff, build_int_cst (asptrtype, 0)); return t; @@ -45823,7 +45878,6 @@ ix86_stack_protect_guard (void) return default_stack_protect_guard (); } -#endif /* For 32-bit code we can save PIC register setup by using __stack_chk_fail_local hidden function instead of calling @@ -52831,10 +52885,8 @@ ix86_run_selftests (void) #undef TARGET_MANGLE_TYPE #define TARGET_MANGLE_TYPE ix86_mangle_type -#ifdef TARGET_THREAD_SSP_OFFSET #undef TARGET_STACK_PROTECT_GUARD #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard -#endif #if !TARGET_MACHO #undef TARGET_STACK_PROTECT_FAIL diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index adc75f36602..72f2422b6d0 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -924,6 +924,20 @@ 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(ix86_stack_protector_guard_reg_str) +Use the given base register for addressing the stack-protector guard. + +TargetVariable +addr_space_t ix86_stack_protector_guard_reg = ADDR_SPACE_GENERIC + +mstack-protector-guard-offset= +Target RejectNegative Joined Integer Var(ix86_stack_protector_guard_offset_str) +Use the given offset for addressing the stack-protector guard. + +TargetVariable +HOST_WIDE_INT ix86_stack_protector_guard_offset = 0 + mmitigate-rop Target Var(flag_mitigate_rop) Init(0) Attempt to avoid generating instruction sequences containing ret bytes. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index b77de034e2e..cc0f5a00a4f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1215,7 +1215,9 @@ See RS/6000 and PowerPC Options. -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol --mmitigate-rop -mgeneral-regs-only -mcall-ms2sysv-xlogues} +-mstack-protector-guard-reg=@var{reg} @gol +-mstack-protector-guard-offset=@var{offset} -mmitigate-rop @gol +-mgeneral-regs-only -mcall-ms2sysv-xlogues} @emph{x86 Windows Options} @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol @@ -26147,12 +26149,23 @@ to 255, 8-bit unsigned integer divide is used instead of Split 32-byte AVX unaligned load and store. @item -mstack-protector-guard=@var{guard} -@opindex 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). This option has effect only when @option{-fstack-protector} or @option{-fstack-protector-all} is specified. +With the latter choice the options +@option{-mstack-protector-guard-reg=@var{reg}} and +@option{-mstack-protector-guard-offset=@var{offset}} furthermore specify +which segment register (@code{%fs} or @code{%gs}) 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. + @item -mmitigate-rop @opindex mmitigate-rop Try to avoid generating code sequences that contain unintended return diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9742dfa01d..2ec22e8fdca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-08 Uros Bizjak + + PR target/81708 + * gcc.target/i386/stack-prot-guard.c: New test. + 2017-08-08 Tamar Christina * gcc.target/aarch64/xorsign.c: New. diff --git a/gcc/testsuite/gcc.target/i386/stack-prot-guard.c b/gcc/testsuite/gcc.target/i386/stack-prot-guard.c new file mode 100644 index 00000000000..120ef3cf5c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stack-prot-guard.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=tls -mstack-protector-guard-reg=gs -mstack-protector-guard-offset=0x3038" } */ + +void f(void) { } + +/* { dg-final { scan-assembler "gs:12344" } } */