On Tue, Aug 8, 2017 at 6:54 PM, Uros Bizjak <ubiz...@gmail.com> wrote: > Hello! > > Attached patch introduces -mstack-protector-guard-reg= and > -mstack-protector-guard-offset= options to make stack canary location > customizable. These are the same options powerpc has.
Attached addition adds -mstack-protector-guard-symbol= option that overrides the offset to TLS stack protector canary with a symbol name. Using this option, stack protector canary can be loaded from specified symbol, relative to guard reg: gcc -O2 -fstack-protector-all -mstack-protector-guard=tls -mstack-protector-guard-reg=gs -mstack-protector-guard-symbol=my_guard movq %gs:my_guard(%rip), %rax movq %rax, 8(%rsp) xorl %eax, %eax movq 8(%rsp), %rax xorq %gs:my_guard(%rip), %rax 2017-08-09 Uros Bizjak <ubiz...@gmail.com> PR target/81708 * config/i386/i386.opt (mstack-protector-guard-symbol=): New option * config/i386/i386.c (ix86_stack_protect_guard): Use ix86_stack_protect_guard_symbol_str to generate varible declaration. * doc/invoke.texi (x86 Options): Document -mstack-protector-guard-symbol= option. testsuite/ChangeLog: 2017-08-09 Uros Bizjak <ubiz...@gmail.com> PR target/81708 * gcc.target/i386/stack-prot-sym.c: New test. Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. I plan to commit the patch to mainline SVN in a couple of days. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 250999) +++ config/i386/i386.c (working copy) @@ -45858,6 +45858,8 @@ ix86_mangle_type (const_tree type) } } +static GTY(()) tree ix86_tls_stack_chk_guard_decl; + static tree ix86_stack_protect_guard (void) { @@ -45864,15 +45866,47 @@ ix86_stack_protect_guard (void) if (TARGET_SSP_TLS_GUARD) { tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1); - int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg); + tree type = build_qualified_type (type_node, qual); + tree t; - tree type = build_qualified_type (type_node, qual); - tree asptrtype = build_pointer_type (type); - tree sspoff = build_int_cst (asptrtype, - ix86_stack_protector_guard_offset); - tree t = build2 (MEM_REF, asptrtype, sspoff, - build_int_cst (asptrtype, 0)); + if (global_options_set.x_ix86_stack_protector_guard_symbol_str) + { + t = ix86_tls_stack_chk_guard_decl; + + if (t == NULL) + { + rtx x; + + t = build_decl + (UNKNOWN_LOCATION, VAR_DECL, + get_identifier (ix86_stack_protector_guard_symbol_str), + type); + TREE_STATIC (t) = 1; + TREE_PUBLIC (t) = 1; + DECL_EXTERNAL (t) = 1; + TREE_USED (t) = 1; + TREE_THIS_VOLATILE (t) = 1; + DECL_ARTIFICIAL (t) = 1; + DECL_IGNORED_P (t) = 1; + + /* Do not share RTL as the declaration is visible outside of + current function. */ + x = DECL_RTL (t); + RTX_FLAG (x, used) = 1; + + ix86_tls_stack_chk_guard_decl = t; + } + } + else + { + tree asptrtype = build_pointer_type (type); + + t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset); + t = build2 (MEM_REF, asptrtype, t, + build_int_cst (asptrtype, 0)); + } + return t; } Index: config/i386/i386.opt =================================================================== --- config/i386/i386.opt (revision 250999) +++ config/i386/i386.opt (working copy) @@ -938,6 +938,10 @@ Use the given offset for addressing the stack-prot TargetVariable HOST_WIDE_INT ix86_stack_protector_guard_offset = 0 +mstack-protector-guard-symbol= +Target RejectNegative Joined Integer Var(ix86_stack_protector_guard_symbol_str) +Use the given symbol for addressing the stack-protector guard. + mmitigate-rop Target Var(flag_mitigate_rop) Init(0) Attempt to avoid generating instruction sequences containing ret bytes. Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 250999) +++ doc/invoke.texi (working copy) @@ -1216,7 +1216,8 @@ See RS/6000 and PowerPC Options. -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol -mstack-protector-guard-reg=@var{reg} @gol --mstack-protector-guard-offset=@var{offset} -mmitigate-rop @gol +-mstack-protector-guard-offset=@var{offset} @gol +-mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol -mgeneral-regs-only -mcall-ms2sysv-xlogues} @emph{x86 Windows Options} @@ -22753,9 +22754,11 @@ The @option{-mno-compat-align-parm} option is the @item -mstack-protector-guard=@var{guard} @itemx -mstack-protector-guard-reg=@var{reg} @itemx -mstack-protector-guard-offset=@var{offset} +@itemx -mstack-protector-guard-symbol=@var{symbol} @opindex mstack-protector-guard @opindex mstack-protector-guard-reg @opindex mstack-protector-guard-offset +@opindex mstack-protector-guard-symbol 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). @@ -22765,7 +22768,8 @@ With the latter choice the options @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. +relevant ABI. @option{-mstack-protector-guard-symbol=@var{symbol}} overrides +the offset with a symbol reference to a canary in the TLS block. @end table @node RX Options Index: testsuite/gcc.target/i386/stack-prot-sym.c =================================================================== --- testsuite/gcc.target/i386/stack-prot-sym.c (nonexistent) +++ testsuite/gcc.target/i386/stack-prot-sym.c (working copy) @@ -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-symbol=my_guard" } */ + +void f(void) { } + +/* { dg-final { scan-assembler "gs:my_guard" } } */