- fix -fstack-clash-protection codegen issue on 32 bit x86
(#1540221, PR target/84128)
This commit is contained in:
parent
872459a238
commit
b8ffb32f78
8
gcc.spec
8
gcc.spec
@ -4,7 +4,7 @@
|
|||||||
%global gcc_major 7
|
%global gcc_major 7
|
||||||
# Note, gcc_release must be integer, if you want to add suffixes to
|
# Note, gcc_release must be integer, if you want to add suffixes to
|
||||||
# %{release}, append them after %{gcc_release} on Release: line.
|
# %{release}, append them after %{gcc_release} on Release: line.
|
||||||
%global gcc_release 2
|
%global gcc_release 3
|
||||||
%global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f
|
%global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f
|
||||||
%global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24
|
%global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24
|
||||||
%global _unpackaged_files_terminate_build 0
|
%global _unpackaged_files_terminate_build 0
|
||||||
@ -238,6 +238,7 @@ Patch11: gcc7-Wno-format-security.patch
|
|||||||
Patch12: gcc7-aarch64-sanitizer-fix.patch
|
Patch12: gcc7-aarch64-sanitizer-fix.patch
|
||||||
Patch13: gcc7-rh1512529-aarch64.patch
|
Patch13: gcc7-rh1512529-aarch64.patch
|
||||||
Patch14: gcc7-pr84064.patch
|
Patch14: gcc7-pr84064.patch
|
||||||
|
Patch15: gcc7-pr84128.patch
|
||||||
|
|
||||||
Patch1000: nvptx-tools-no-ptxas.patch
|
Patch1000: nvptx-tools-no-ptxas.patch
|
||||||
Patch1001: nvptx-tools-build.patch
|
Patch1001: nvptx-tools-build.patch
|
||||||
@ -834,6 +835,7 @@ package or when debugging this package.
|
|||||||
%endif
|
%endif
|
||||||
%patch13 -p0 -b .rh1512529-aarch64~
|
%patch13 -p0 -b .rh1512529-aarch64~
|
||||||
%patch14 -p0 -b .pr84064~
|
%patch14 -p0 -b .pr84064~
|
||||||
|
%patch15 -p0 -b .pr84128~
|
||||||
|
|
||||||
cd nvptx-tools-%{nvptx_tools_gitrev}
|
cd nvptx-tools-%{nvptx_tools_gitrev}
|
||||||
%patch1000 -p1 -b .nvptx-tools-no-ptxas~
|
%patch1000 -p1 -b .nvptx-tools-no-ptxas~
|
||||||
@ -3261,6 +3263,10 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Feb 1 2018 Jeff Law <law@redhat.com> 7.3.1-3
|
||||||
|
- fix -fstack-clash-protection codegen issue on 32 bit x86
|
||||||
|
(#1540221, PR target/84128)
|
||||||
|
|
||||||
* Tue Jan 30 2018 Jakub Jelinek <jakub@redhat.com> 7.3.1-2
|
* Tue Jan 30 2018 Jakub Jelinek <jakub@redhat.com> 7.3.1-2
|
||||||
- update from the 7 branch
|
- update from the 7 branch
|
||||||
- PRs c++/82461, c++/82878, libstdc++/81076, libstdc++/83658,
|
- PRs c++/82461, c++/82878, libstdc++/81076, libstdc++/83658,
|
||||||
|
180
gcc7-pr84128.patch
Normal file
180
gcc7-pr84128.patch
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
|
||||||
|
PR target/84128
|
||||||
|
* config/i386/i386.c (release_scratch_register_on_entry): Add new
|
||||||
|
OFFSET and RELEASE_VIA_POP arguments. Use SP+OFFSET to restore
|
||||||
|
the scratch if RELEASE_VIA_POP is false.
|
||||||
|
(ix86_adjust_stack_and_probe_stack_clash): Un-constify SIZE.
|
||||||
|
If we have to save a temporary register, decrement SIZE appropriately.
|
||||||
|
Pass new arguments to release_scratch_register_on_entry.
|
||||||
|
(ix86_adjust_stack_and_probe): Likewise.
|
||||||
|
(ix86_emit_probe_stack_range): Pass new arguments to
|
||||||
|
release_scratch_register_on_entry.
|
||||||
|
|
||||||
|
PR target/84128
|
||||||
|
* gcc.target/i386/pr84128.c: New test.
|
||||||
|
|
||||||
|
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||||
|
index fef34a1..3196ac4 100644
|
||||||
|
--- gcc/config/i386/i386.c
|
||||||
|
+++ gcc/config/i386/i386.c
|
||||||
|
@@ -12567,22 +12567,39 @@ get_scratch_register_on_entry (struct scratch_reg *sr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Release a scratch register obtained from the preceding function. */
|
||||||
|
+/* Release a scratch register obtained from the preceding function.
|
||||||
|
+
|
||||||
|
+ If RELEASE_VIA_POP is true, we just pop the register off the stack
|
||||||
|
+ to release it. This is what non-Linux systems use with -fstack-check.
|
||||||
|
+
|
||||||
|
+ Otherwise we use OFFSET to locate the saved register and the
|
||||||
|
+ allocated stack space becomes part of the local frame and is
|
||||||
|
+ deallocated by the epilogue. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
-release_scratch_register_on_entry (struct scratch_reg *sr)
|
||||||
|
+release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
|
||||||
|
+ bool release_via_pop)
|
||||||
|
{
|
||||||
|
if (sr->saved)
|
||||||
|
{
|
||||||
|
- struct machine_function *m = cfun->machine;
|
||||||
|
- rtx x, insn = emit_insn (gen_pop (sr->reg));
|
||||||
|
+ if (release_via_pop)
|
||||||
|
+ {
|
||||||
|
+ struct machine_function *m = cfun->machine;
|
||||||
|
+ rtx x, insn = emit_insn (gen_pop (sr->reg));
|
||||||
|
|
||||||
|
- /* The RTX_FRAME_RELATED_P mechanism doesn't know about pop. */
|
||||||
|
- RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
- x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
|
||||||
|
- x = gen_rtx_SET (stack_pointer_rtx, x);
|
||||||
|
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
|
||||||
|
- m->fs.sp_offset -= UNITS_PER_WORD;
|
||||||
|
+ /* The RX FRAME_RELATED_P mechanism doesn't know about pop. */
|
||||||
|
+ RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
+ x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
|
||||||
|
+ x = gen_rtx_SET (stack_pointer_rtx, x);
|
||||||
|
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
|
||||||
|
+ m->fs.sp_offset -= UNITS_PER_WORD;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
|
||||||
|
+ x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
|
||||||
|
+ emit_insn (x);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -12597,7 +12614,7 @@ release_scratch_register_on_entry (struct scratch_reg *sr)
|
||||||
|
pushed on the stack. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
-ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
|
||||||
|
+ix86_adjust_stack_and_probe_stack_clash (HOST_WIDE_INT size,
|
||||||
|
const bool int_registers_saved)
|
||||||
|
{
|
||||||
|
struct machine_function *m = cfun->machine;
|
||||||
|
@@ -12713,6 +12730,12 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
|
||||||
|
struct scratch_reg sr;
|
||||||
|
get_scratch_register_on_entry (&sr);
|
||||||
|
|
||||||
|
+ /* If we needed to save a register, then account for any space
|
||||||
|
+ that was pushed (we are not going to pop the register when
|
||||||
|
+ we do the restore). */
|
||||||
|
+ if (sr.saved)
|
||||||
|
+ size -= UNITS_PER_WORD;
|
||||||
|
+
|
||||||
|
/* Step 1: round SIZE down to a multiple of the interval. */
|
||||||
|
HOST_WIDE_INT rounded_size = size & -probe_interval;
|
||||||
|
|
||||||
|
@@ -12761,7 +12784,9 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
|
||||||
|
m->fs.cfa_reg == stack_pointer_rtx);
|
||||||
|
dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
|
||||||
|
|
||||||
|
- release_scratch_register_on_entry (&sr);
|
||||||
|
+ /* This does not deallocate the space reserved for the scratch
|
||||||
|
+ register. That will be deallocated in the epilogue. */
|
||||||
|
+ release_scratch_register_on_entry (&sr, size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure nothing is scheduled before we are done. */
|
||||||
|
@@ -12774,7 +12799,7 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
|
||||||
|
pushed on the stack. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
-ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
|
||||||
|
+ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
|
||||||
|
const bool int_registers_saved)
|
||||||
|
{
|
||||||
|
/* We skip the probe for the first interval + a small dope of 4 words and
|
||||||
|
@@ -12847,6 +12872,11 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
|
||||||
|
|
||||||
|
get_scratch_register_on_entry (&sr);
|
||||||
|
|
||||||
|
+ /* If we needed to save a register, then account for any space
|
||||||
|
+ that was pushed (we are not going to pop the register when
|
||||||
|
+ we do the restore). */
|
||||||
|
+ if (sr.saved)
|
||||||
|
+ size -= UNITS_PER_WORD;
|
||||||
|
|
||||||
|
/* Step 1: round SIZE to the previous multiple of the interval. */
|
||||||
|
|
||||||
|
@@ -12906,7 +12936,9 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
|
||||||
|
(get_probe_interval ()
|
||||||
|
+ dope))));
|
||||||
|
|
||||||
|
- release_scratch_register_on_entry (&sr);
|
||||||
|
+ /* This does not deallocate the space reserved for the scratch
|
||||||
|
+ register. That will be deallocated in the epilogue. */
|
||||||
|
+ release_scratch_register_on_entry (&sr, size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Even if the stack pointer isn't the CFA register, we need to correctly
|
||||||
|
@@ -13055,7 +13087,7 @@ ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
|
||||||
|
sr.reg),
|
||||||
|
rounded_size - size));
|
||||||
|
|
||||||
|
- release_scratch_register_on_entry (&sr);
|
||||||
|
+ release_scratch_register_on_entry (&sr, size, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure nothing is scheduled before we are done. */
|
||||||
|
|
||||||
|
diff --git a/gcc/testsuite/gcc.target/i386/pr84128.c b/gcc/testsuite/gcc.target/i386/pr84128.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..a8323fd6
|
||||||
|
--- /dev/null
|
||||||
|
+++ gcc/testsuite/gcc.target/i386/pr84128.c
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* { dg-do run } */
|
||||||
|
+/* { dg-options "-O2 -march=i686 -mtune=generic -fstack-clash-protection" } */
|
||||||
|
+/* { dg-require-effective-target ia32 } */
|
||||||
|
+
|
||||||
|
+__attribute__ ((noinline, noclone, weak, regparm (3)))
|
||||||
|
+int
|
||||||
|
+f1 (long arg0, int (*pf) (long, void *))
|
||||||
|
+{
|
||||||
|
+ unsigned char buf[32768];
|
||||||
|
+ return pf (arg0, buf);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+__attribute__ ((noinline, noclone, weak))
|
||||||
|
+int
|
||||||
|
+f2 (long arg0, void *ignored)
|
||||||
|
+{
|
||||||
|
+ if (arg0 != 17)
|
||||||
|
+ __builtin_abort ();
|
||||||
|
+ return 19;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main (void)
|
||||||
|
+{
|
||||||
|
+ if (f1 (17, f2) != 19)
|
||||||
|
+ __builtin_abort ();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
Loading…
Reference in New Issue
Block a user