From 924e2261d50475d5d185e4710620a496d1071d50 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 24 Jan 2018 15:13:15 -0700 Subject: [PATCH] - Fix -fstack-clash-protection codegen issue on 32 bit x86 (#1536555) --- gcc.spec | 7 +++- gcc7-rh1536555.patch | 98 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 gcc7-rh1536555.patch diff --git a/gcc.spec b/gcc.spec index ea11ab8..8a570d2 100644 --- a/gcc.spec +++ b/gcc.spec @@ -4,7 +4,7 @@ %global gcc_major 7 # Note, gcc_release must be integer, if you want to add suffixes to # %{release}, append them after %{gcc_release} on Release: line. -%global gcc_release 7 +%global gcc_release 8 %global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f %global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24 %global _unpackaged_files_terminate_build 0 @@ -237,6 +237,7 @@ Patch10: gcc7-foffload-default.patch Patch11: gcc7-Wno-format-security.patch Patch12: gcc7-aarch64-sanitizer-fix.patch Patch13: gcc7-rh1512529-aarch64.patch +Patch14: gcc7-rh1536555.patch Patch1000: nvptx-tools-no-ptxas.patch Patch1001: nvptx-tools-build.patch @@ -832,6 +833,7 @@ package or when debugging this package. %patch12 -p0 -b .aarch64-sanitizer-fix~ %endif %patch13 -p0 -b .rh1512529-aarch64~ +%patch14 -p0 -b .rh1537979~ cd nvptx-tools-%{nvptx_tools_gitrev} %patch1000 -p1 -b .nvptx-tools-no-ptxas~ @@ -3259,6 +3261,9 @@ fi %endif %changelog +* Wed Jan 24 2018 Jeff Law 7.2.1-8 +- Fix -fstack-clash-protection codegen issue on 32 bit x86 (#1536555) + * Wed Jan 17 2018 Jakub Jelinek 7.2.1-7 - update from the 7 branch - PRs fortran/78814, fortran/82367, fortran/82841, fortran/83093, diff --git a/gcc7-rh1536555.patch b/gcc7-rh1536555.patch new file mode 100644 index 0000000..65714ee --- /dev/null +++ b/gcc7-rh1536555.patch @@ -0,0 +1,98 @@ +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 346fb4f..f0b8346 100644 +--- gcc/config/i386/i386.c ++++ gcc/config/i386/i386.c +@@ -12763,6 +12763,18 @@ ix86_builtin_setjmp_frame_value (void) + return stack_realign_fp ? hard_frame_pointer_rtx : virtual_stack_vars_rtx; + } + ++/* Return the probing interval for -fstack-clash-protection. */ ++ ++static HOST_WIDE_INT ++get_probe_interval (void) ++{ ++ if (flag_stack_clash_protection) ++ return (HOST_WIDE_INT_1U ++ << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL)); ++ else ++ return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP); ++} ++ + /* When using -fsplit-stack, the allocation routines set a field in + the TCB to the bottom of the stack plus this much space, measured + in bytes. */ +@@ -12948,7 +12960,14 @@ ix86_compute_frame_layout (void) + to_allocate = offset - frame->sse_reg_save_offset; + + if ((!to_allocate && frame->nregs <= 1) +- || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))) ++ || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000)) ++ /* If stack clash probing needs a loop, then it needs a ++ scratch register. But the returned register is only guaranteed ++ to be safe to use after register saves are complete. So if ++ stack clash protections are enabled and the allocated frame is ++ larger than the probe interval, then use pushes to save ++ callee saved registers. */ ++ || (flag_stack_clash_protection && to_allocate > get_probe_interval ())) + frame->save_regs_using_mov = false; + + if (ix86_using_red_zone () +@@ -13619,18 +13638,6 @@ release_scratch_register_on_entry (struct scratch_reg *sr) + } + } + +-/* Return the probing interval for -fstack-clash-protection. */ +- +-static HOST_WIDE_INT +-get_probe_interval (void) +-{ +- if (flag_stack_clash_protection) +- return (HOST_WIDE_INT_1U +- << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL)); +- else +- return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP); +-} +- + /* Emit code to adjust the stack pointer by SIZE bytes while probing it. + + This differs from the next routine in that it tries hard to prevent +@@ -14558,12 +14565,11 @@ ix86_expand_prologue (void) + && (flag_stack_check == STATIC_BUILTIN_STACK_CHECK + || flag_stack_clash_protection)) + { +- /* This assert wants to verify that integer registers were saved +- prior to probing. This is necessary when probing may be implemented +- as a function call (Windows). It is not necessary for stack clash +- protection probing. */ +- if (!flag_stack_clash_protection) +- gcc_assert (int_registers_saved); ++ /* We expect the GP registers to be saved when probes are used ++ as the probing sequences might need a scratch register and ++ the routine to allocate one assumes the integer registers ++ have already been saved. */ ++ gcc_assert (int_registers_saved); + + if (flag_stack_clash_protection) + { +diff --git a/gcc/testsuite/gcc.target/i386/pr83994.c b/gcc/testsuite/gcc.target/i386/pr83994.c +new file mode 100644 +index 0000000..dc0b7cb +--- /dev/null ++++ gcc/testsuite/gcc.target/i386/pr83994.c +@@ -0,0 +1,16 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -march=i686 -fpic -fstack-clash-protection" } */ ++/* { dg-require-effective-target ia32 } */ ++ ++void f1 (char *); ++ ++__attribute__ ((regparm (3))) ++int ++f2 (int arg1, int arg2, int arg3) ++{ ++ char buf[16384]; ++ f1 (buf); ++ f1 (buf); ++ return 0; ++} ++