Commit e8a5a6f6 by Igor Tsimbalist Committed by Igor Tsimbalist

PR84066 Wrong shadow stack register size is saved for x32

x32 is a 64-bit process with 32-bit software pointer and kernel may
place x32 shadow stack above 4GB.  We need to save and restore 64-bit
shadow stack register for x32. builtin jmp buf size is 5 pointers.  We
have space to save 64-bit shadow stack pointers: 32-bit SP, 32-bit FP,
32-bit IP, 64-bit SSP for x32.

	PR target/84066
	* gcc/config/i386/i386.md: Replace Pmode with word_mode in
	builtin_setjmp_setup and builtin_longjmp to support x32.
	* gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c: New test.
	* gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c: Likewise.

From-SVN: r257326
parent fe23b12a
2018-02-02 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
PR target/84066
* config/i386/i386.md: Replace Pmode with word_mode in
builtin_setjmp_setup and builtin_longjmp to support x32.
2018-02-01 Peter Bergner <bergner@vnet.ibm.com> 2018-02-01 Peter Bergner <bergner@vnet.ibm.com>
PR target/56010 PR target/56010
......
...@@ -18385,13 +18385,14 @@ ...@@ -18385,13 +18385,14 @@
{ {
rtx mem, reg_ssp; rtx mem, reg_ssp;
mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], mem = gen_rtx_MEM (word_mode,
3 * GET_MODE_SIZE (Pmode))); plus_constant (Pmode, operands[0],
reg_ssp = gen_reg_rtx (Pmode); 3 * GET_MODE_SIZE (ptr_mode)));
reg_ssp = gen_reg_rtx (word_mode);
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
emit_insn ((Pmode == SImode) emit_insn ((word_mode == SImode)
? gen_rdsspsi (reg_ssp, reg_ssp) ? gen_rdsspsi (reg_ssp, reg_ssp)
: gen_rdsspdi (reg_ssp, reg_ssp)); : gen_rdsspdi (reg_ssp, reg_ssp));
emit_move_insn (mem, reg_ssp); emit_move_insn (mem, reg_ssp);
} }
DONE; DONE;
...@@ -18433,18 +18434,18 @@ ...@@ -18433,18 +18434,18 @@
/* Get the current shadow stack pointer. The code below will check if /* Get the current shadow stack pointer. The code below will check if
SHSTK feature is enabled. If it is not enabled the RDSSP instruction SHSTK feature is enabled. If it is not enabled the RDSSP instruction
is a NOP. */ is a NOP. */
reg_ssp = gen_reg_rtx (Pmode); reg_ssp = gen_reg_rtx (word_mode);
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
emit_insn ((Pmode == SImode) emit_insn ((word_mode == SImode)
? gen_rdsspsi (reg_ssp, reg_ssp) ? gen_rdsspsi (reg_ssp, reg_ssp)
: gen_rdsspdi (reg_ssp, reg_ssp)); : gen_rdsspdi (reg_ssp, reg_ssp));
mem_buf = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], mem_buf = gen_rtx_MEM (word_mode,
3 * GET_MODE_SIZE (Pmode))); plus_constant (Pmode, operands[0],
3 * GET_MODE_SIZE (ptr_mode)));
/* Compare through substraction the saved and the current ssp to decide /* Compare through substraction the saved and the current ssp to decide
if ssp has to be adjusted. */ if ssp has to be adjusted. */
reg_adj = gen_reg_rtx (Pmode); tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, mem_buf));
tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (Pmode, reg_ssp, mem_buf));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
emit_insn (tmp); emit_insn (tmp);
...@@ -18460,9 +18461,11 @@ ...@@ -18460,9 +18461,11 @@
JUMP_LABEL (jump) = noadj_label; JUMP_LABEL (jump) = noadj_label;
/* Compute the numebr of frames to adjust. */ /* Compute the numebr of frames to adjust. */
reg_adj = gen_lowpart (ptr_mode, reg_ssp);
tmp = gen_rtx_SET (reg_adj, tmp = gen_rtx_SET (reg_adj,
gen_rtx_LSHIFTRT (Pmode, negate_rtx (Pmode, reg_adj), gen_rtx_LSHIFTRT (ptr_mode,
GEN_INT ((Pmode == SImode) negate_rtx (ptr_mode, reg_adj),
GEN_INT ((word_mode == SImode)
? 2 ? 2
: 3))); : 3)));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
...@@ -18487,10 +18490,10 @@ ...@@ -18487,10 +18490,10 @@
emit_label (loop_label); emit_label (loop_label);
LABEL_NUSES (loop_label) = 1; LABEL_NUSES (loop_label) = 1;
emit_insn ((Pmode == SImode) emit_insn ((word_mode == SImode)
? gen_incsspsi (reg_adj) ? gen_incsspsi (reg_ssp)
: gen_incsspdi (reg_adj)); : gen_incsspdi (reg_ssp));
tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (Pmode, tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
reg_adj, reg_adj,
GEN_INT (255))); GEN_INT (255)));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
...@@ -18511,25 +18514,27 @@ ...@@ -18511,25 +18514,27 @@
emit_label (inc_label); emit_label (inc_label);
LABEL_NUSES (inc_label) = 1; LABEL_NUSES (inc_label) = 1;
emit_insn ((Pmode == SImode) emit_insn ((word_mode == SImode)
? gen_incsspsi (reg_adj) ? gen_incsspsi (reg_ssp)
: gen_incsspdi (reg_adj)); : gen_incsspdi (reg_ssp));
emit_label (noadj_label); emit_label (noadj_label);
LABEL_NUSES (noadj_label) = 1; LABEL_NUSES (noadj_label) = 1;
} }
/* This code is the same as in expand_buildin_longjmp. */ /* This code is the same as in expand_buildin_longjmp. */
fp = gen_rtx_MEM (Pmode, operands[0]); fp = gen_rtx_MEM (ptr_mode, operands[0]);
lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], lab = gen_rtx_MEM (ptr_mode, plus_constant (Pmode, operands[0],
GET_MODE_SIZE (Pmode))); GET_MODE_SIZE (ptr_mode)));
stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0], stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0],
2 * GET_MODE_SIZE (Pmode))); 2 * GET_MODE_SIZE (ptr_mode)));
lab = copy_to_reg (lab); lab = copy_to_reg (lab);
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
if (GET_MODE (fp) != Pmode)
fp = convert_to_mode (Pmode, fp, 1);
emit_move_insn (hard_frame_pointer_rtx, fp); emit_move_insn (hard_frame_pointer_rtx, fp);
emit_stack_restore (SAVE_NONLOCAL, stack); emit_stack_restore (SAVE_NONLOCAL, stack);
......
2018-02-02 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
PR target/84066
* gcc.target/i386/cet-sjlj-6a.c: New test.
* gcc.target/i386/cet-sjlj-6b.c: Likewise.
2018-02-01 Marek Polacek <polacek@redhat.com> 2018-02-01 Marek Polacek <polacek@redhat.com>
PR c++/84125 PR c++/84125
......
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-require-effective-target maybe_x32 } */
/* { dg-options "-O -maddress-mode=short -fcf-protection -mcet -mx32" } */
/* { dg-final { scan-assembler-times "endbr64" 2 } } */
/* { dg-final { scan-assembler-times "movq\t.*buf\\+12" 1 } } */
/* { dg-final { scan-assembler-times "subq\tbuf\\+12" 1 } } */
/* { dg-final { scan-assembler-times "shrl\t\\\$3," 1 } } */
/* { dg-final { scan-assembler-times "rdsspq" 2 } } */
/* { dg-final { scan-assembler-times "incsspq" 2 } } */
void *buf[5];
void raise0(void)
{
__builtin_longjmp (buf, 1);
}
void execute(int cmd)
{
__builtin_setjmp (buf);
}
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O -maddress-mode=long -fcf-protection -mcet -mx32" } */
/* { dg-final { scan-assembler-times "endbr64" 2 } } */
/* { dg-final { scan-assembler-times "movq\t.*buf\\+12" 1 } } */
/* { dg-final { scan-assembler-times "subq\tbuf\\+12" 1 } } */
/* { dg-final { scan-assembler-times "shrl\t\\\$3," 1 } } */
/* { dg-final { scan-assembler-times "rdsspq" 2 } } */
/* { dg-final { scan-assembler-times "incsspq" 2 } } */
#include "cet-sjlj-6a.c"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment