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>
PR target/56010
......
......@@ -18385,13 +18385,14 @@
{
rtx mem, reg_ssp;
mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
3 * GET_MODE_SIZE (Pmode)));
reg_ssp = gen_reg_rtx (Pmode);
mem = gen_rtx_MEM (word_mode,
plus_constant (Pmode, operands[0],
3 * GET_MODE_SIZE (ptr_mode)));
reg_ssp = gen_reg_rtx (word_mode);
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
emit_insn ((Pmode == SImode)
? gen_rdsspsi (reg_ssp, reg_ssp)
: gen_rdsspdi (reg_ssp, reg_ssp));
emit_insn ((word_mode == SImode)
? gen_rdsspsi (reg_ssp, reg_ssp)
: gen_rdsspdi (reg_ssp, reg_ssp));
emit_move_insn (mem, reg_ssp);
}
DONE;
......@@ -18433,18 +18434,18 @@
/* Get the current shadow stack pointer. The code below will check if
SHSTK feature is enabled. If it is not enabled the RDSSP instruction
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 ((Pmode == SImode)
emit_insn ((word_mode == SImode)
? gen_rdsspsi (reg_ssp, reg_ssp)
: gen_rdsspdi (reg_ssp, reg_ssp));
mem_buf = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
3 * GET_MODE_SIZE (Pmode)));
mem_buf = gen_rtx_MEM (word_mode,
plus_constant (Pmode, operands[0],
3 * GET_MODE_SIZE (ptr_mode)));
/* Compare through substraction the saved and the current ssp to decide
if ssp has to be adjusted. */
reg_adj = gen_reg_rtx (Pmode);
tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (Pmode, reg_ssp, mem_buf));
tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, mem_buf));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
emit_insn (tmp);
......@@ -18460,9 +18461,11 @@
JUMP_LABEL (jump) = noadj_label;
/* Compute the numebr of frames to adjust. */
reg_adj = gen_lowpart (ptr_mode, reg_ssp);
tmp = gen_rtx_SET (reg_adj,
gen_rtx_LSHIFTRT (Pmode, negate_rtx (Pmode, reg_adj),
GEN_INT ((Pmode == SImode)
gen_rtx_LSHIFTRT (ptr_mode,
negate_rtx (ptr_mode, reg_adj),
GEN_INT ((word_mode == SImode)
? 2
: 3)));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
......@@ -18487,10 +18490,10 @@
emit_label (loop_label);
LABEL_NUSES (loop_label) = 1;
emit_insn ((Pmode == SImode)
? gen_incsspsi (reg_adj)
: gen_incsspdi (reg_adj));
tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (Pmode,
emit_insn ((word_mode == SImode)
? gen_incsspsi (reg_ssp)
: gen_incsspdi (reg_ssp));
tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
reg_adj,
GEN_INT (255)));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
......@@ -18511,25 +18514,27 @@
emit_label (inc_label);
LABEL_NUSES (inc_label) = 1;
emit_insn ((Pmode == SImode)
? gen_incsspsi (reg_adj)
: gen_incsspdi (reg_adj));
emit_insn ((word_mode == SImode)
? gen_incsspsi (reg_ssp)
: gen_incsspdi (reg_ssp));
emit_label (noadj_label);
LABEL_NUSES (noadj_label) = 1;
}
/* This code is the same as in expand_buildin_longjmp. */
fp = gen_rtx_MEM (Pmode, operands[0]);
lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
GET_MODE_SIZE (Pmode)));
fp = gen_rtx_MEM (ptr_mode, operands[0]);
lab = gen_rtx_MEM (ptr_mode, plus_constant (Pmode, operands[0],
GET_MODE_SIZE (ptr_mode)));
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);
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
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_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>
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