This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.3 PATCH, i386]: Fix PR target/39118, x86_64 red zone violation
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jan Hubicka <jh at suse dot cz>
- Date: Sun, 08 Feb 2009 21:57:35 +0100
- Subject: [4.3 PATCH, i386]: Fix PR target/39118, x86_64 red zone violation
Hello!
The offset between frame pointer and stack pointer is calculated
relative to the stack pointer value at the end of function prologue.
When frame pointer is used to access temporaries in the red zone area,
there is nothing to prevent scheduler from moving red-zone access insns
to function prologue.
The problem arises when registers are saved using pushes and red-zone
access insn gets scheduled before (or into) push sequence. There is a
short time window when redzone is not at the correct position, and since
temp value gets saved below the redzone area, it _can_ be overwritten by
an interrupt handler.
Attached patch fixes this problem by emitting scheduling barrier at the
end of function prologue if frame pointer is needed to access redzone
area. This is very rare situation, since frame pointer is omitted by
default on x86_64.
2009-02-08 Uros Bizjak <ubizjak@gmail.com>
PR target/39118
* config/i386/i386.c (expand_prologue): Emit blockage at the end
of function prologue when frame pointer is used to access
red zone area.
I'll wait for possible comments on this approach, but I think this patch
is 4.3 as well as 4.4 material.
Uros.
Index: i386.c
===================================================================
--- i386.c (revision 144002)
+++ i386.c (working copy)
@@ -6304,6 +6304,7 @@ ix86_expand_prologue (void)
{
rtx insn;
bool pic_reg_used;
+ bool emit_blockage = false;
struct ix86_frame frame;
HOST_WIDE_INT allocate;
@@ -6489,9 +6490,21 @@ ix86_expand_prologue (void)
{
if (pic_reg_used)
emit_insn (gen_prologue_use (pic_offset_table_rtx));
- emit_insn (gen_blockage ());
+ emit_blockage = true;
}
+ /* Prevent instructions from being scheduled into register save push
+ sequence when access to the redzone area is done through frame pointer.
+ The offset betweeh the frame pointer and the stack pointer is calculated
+ relative to the value of the stack pointer at the end of the function
+ prologue, and moving instructions that access redzone area via frame
+ pointer inside push sequence violates this assumption. */
+ if (frame_pointer_needed && frame.red_zone_size)
+ emit_blockage = true;
+
+ if (emit_blockage)
+ emit_insn (gen_blockage ());
+
/* Emit cld instruction if stringops are used in the function. */
if (TARGET_CLD && ix86_current_function_needs_cld)
emit_insn (gen_cld ());