This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 ());

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]