[RFA/i386] 2 more patterns in i386_analyze_stack_align

Joel Brobecker brobecker@adacore.com
Wed Dec 20 10:49:00 GMT 2006


Hello,

A coworker and I noticed a problem when we tried gdb-6.4 to debug
some code compiled with GCC 4.1: Some stack alignment code was added
at the start of certain functions. I soon found out that this problem
had been reported under breakpoints/2080 and fixed. However, when
I looked at the fix, I noticed that it was incomplete. According
to my collegue (who worked on the compiler part), the register used
during the stack alignment is either ecx, edx, or eax (in this order
of preference).

So I enhanced the function i386_analyze_stack_align to recognize all
three patterns. I also added testing for these cases in i386-prologue.exp.

2006-12-20  Joel Brobecker  <brobecker@adacore.com>

        * i386-tdep.c (i386_analyze_stack_align): Add handling of two
        other possible code sequences that perform a stack realignment.

2006-12-20  Joel Brobecker  <brobecker@adacore.com>

        * gdb.arch/i386-prologue.c (stack_align_ecx): Renamed from stack_align.
        (stack_align_edx): New function.
        (stack_align_eax): New function.
        (main): Add calls to stack_align_edx and stack_align_eax.
        * gdb.arch/i386-prologue.exp: Replace stack_align with stack_align_ecx.
        Add testing for the cases where the register used during a stack
        realignment is edx. Same for eax.

Fix and testsuite modification tested on x86-linux. No regression.
The new tests fail before my change is applied, and pass after.

OK to apply?

Thanks,
-- 
Joel
-------------- next part --------------
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.225
diff -u -p -r1.225 i386-tdep.c
--- i386-tdep.c	8 Aug 2006 21:36:46 -0000	1.225
+++ i386-tdep.c	20 Dec 2006 10:21:58 -0000
@@ -497,15 +497,27 @@ static CORE_ADDR
 i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
 			  struct i386_frame_cache *cache)
 {
-  static const gdb_byte insns[10] = { 
+  static const gdb_byte insns_ecx[10] = { 
     0x8d, 0x4c, 0x24, 0x04,	/* leal  4(%esp), %ecx */
     0x83, 0xe4, 0xf0,		/* andl  $-16, %esp */
     0xff, 0x71, 0xfc		/* pushl -4(%ecx) */
   };
+  static const gdb_byte insns_edx[10] = { 
+    0x8d, 0x54, 0x24, 0x04,	/* leal  4(%esp), %edx */
+    0x83, 0xe4, 0xf0,		/* andl  $-16, %esp */
+    0xff, 0x72, 0xfc		/* pushl -4(%edx) */
+  };
+  static const gdb_byte insns_eax[10] = { 
+    0x8d, 0x44, 0x24, 0x04,	/* leal  4(%esp), %eax */
+    0x83, 0xe4, 0xf0,		/* andl  $-16, %esp */
+    0xff, 0x70, 0xfc		/* pushl -4(%eax) */
+  };
   gdb_byte buf[10];
 
   if (target_read_memory (pc, buf, sizeof buf)
-      || memcmp (buf, insns, sizeof buf) != 0)
+      || (memcmp (buf, insns_ecx, sizeof buf) != 0
+          && memcmp (buf, insns_edx, sizeof buf) != 0
+          && memcmp (buf, insns_eax, sizeof buf) != 0))
     return pc;
 
   if (current_pc > pc + 4)
-------------- next part --------------
Index: gdb.arch/i386-prologue.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/i386-prologue.c,v
retrieving revision 1.7
diff -u -p -r1.7 i386-prologue.c
--- gdb.arch/i386-prologue.c	13 Feb 2006 22:33:26 -0000	1.7
+++ gdb.arch/i386-prologue.c	20 Dec 2006 10:43:10 -0000
@@ -34,7 +34,9 @@ int
 main (void)
 {
   standard ();
-  stack_align ();
+  stack_align_ecx ();
+  stack_align_edx ();
+  stack_align_eax ();
   gdb1253 ();
   gdb1718 ();
   gdb1338 ();
@@ -114,7 +116,7 @@ asm(".text\n"
 
 asm(".text\n"
     "    .align 8\n"
-    SYMBOL (stack_align) ":\n"
+    SYMBOL (stack_align_ecx) ":\n"
     "    leal  4(%esp), %ecx\n"
     "    andl  $-16, %esp\n"
     "    pushl -4(%ecx)\n"
@@ -128,3 +130,38 @@ asm(".text\n"
     "    popl  %ebp\n"
     "    leal  -4(%ecx), %esp\n"
     "    ret\n");
+
+asm(".text\n"
+    "    .align 8\n"
+    SYMBOL (stack_align_edx) ":\n"
+    "    leal  4(%esp), %edx\n"
+    "    andl  $-16, %esp\n"
+    "    pushl -4(%edx)\n"
+    "    pushl %ebp\n"
+    "    movl  %esp, %ebp\n"
+    "    pushl %edi\n"
+    "    pushl %ecx\n"
+    "    int   $0x03\n"
+    "    popl  %ecx\n"
+    "    popl  %edi\n"
+    "    popl  %ebp\n"
+    "    leal  -4(%edx), %esp\n"
+    "    ret\n");
+
+asm(".text\n"
+    "    .align 8\n"
+    SYMBOL (stack_align_eax) ":\n"
+    "    leal  4(%esp), %eax\n"
+    "    andl  $-16, %esp\n"
+    "    pushl -4(%eax)\n"
+    "    pushl %ebp\n"
+    "    movl  %esp, %ebp\n"
+    "    pushl %edi\n"
+    "    pushl %ecx\n"
+    "    int   $0x03\n"
+    "    popl  %ecx\n"
+    "    popl  %edi\n"
+    "    popl  %ebp\n"
+    "    leal  -4(%eax), %esp\n"
+    "    ret\n");
+
Index: gdb.arch/i386-prologue.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/i386-prologue.exp,v
retrieving revision 1.13
diff -u -p -r1.13 i386-prologue.exp
--- gdb.arch/i386-prologue.exp	20 Dec 2006 09:51:52 -0000	1.13
+++ gdb.arch/i386-prologue.exp	20 Dec 2006 10:43:10 -0000
@@ -95,32 +95,88 @@ gdb_test "info frame" \
 	"saved registers in standard"
 
 
-# Testcase from breakpoints/2080.
+# Testcase from breakpoints/2080 (when %ecx is used)
 
-gdb_test "break *(stack_align + 7)" \
+gdb_test "break *(stack_align_ecx + 7)" \
 	"Breakpoint \[0-9\]* at $hex"
 
 gdb_test "continue" \
-	"Breakpoint \[0-9\]*.*stack_align.*" \
-	"continue to stack_align + 7"
+	"Breakpoint \[0-9\]*.*stack_align_ecx.*" \
+	"continue to stack_align_ecx + 7"
 
 gdb_test "backtrace 10" \
-	"#0\[ \t\]*$hex in stack_align.*\r\n#1\[ \t\]*$hex in main.*" \
-	"first backtrace in stack_align"
+	"#0\[ \t\]*$hex in stack_align_ecx.*\r\n#1\[ \t\]*$hex in main.*" \
+	"first backtrace in stack_align_ecx"
 
 gdb_test "continue" \
 	"Program received signal SIGTRAP.*" \
-	"continue in stack_align"
+	"continue in stack_align_ecx"
 
-skip_breakpoint stack_align
+skip_breakpoint stack_align_ecx
 
 gdb_test "backtrace 10" \
-	"#0\[ \t\]*$hex in stack_align.*\r\n#1\[ \t\]*$hex in main.*" \
-	"second backtrace in stack_align"
+	"#0\[ \t\]*$hex in stack_align_ecx.*\r\n#1\[ \t\]*$hex in main.*" \
+	"second backtrace in stack_align_ecx"
 
 gdb_test "info frame" \
 	".*Saved registers:.*ecx at.*ebp at.*edi at.*eip at.*" \
-	"saved registers in stack_align"
+	"saved registers in stack_align_ecx"
+
+
+# Testcase from breakpoints/2080 (when %edx is used)
+
+gdb_test "break *(stack_align_edx + 7)" \
+	"Breakpoint \[0-9\]* at $hex"
+
+gdb_test "continue" \
+	"Breakpoint \[0-9\]*.*stack_align_edx.*" \
+	"continue to stack_align_edx + 7"
+
+gdb_test "backtrace 10" \
+	"#0\[ \t\]*$hex in stack_align_edx.*\r\n#1\[ \t\]*$hex in main.*" \
+	"first backtrace in stack_align_edx"
+
+gdb_test "continue" \
+	"Program received signal SIGTRAP.*" \
+	"continue in stack_align_edx"
+
+skip_breakpoint stack_align_edx
+
+gdb_test "backtrace 10" \
+	"#0\[ \t\]*$hex in stack_align_edx.*\r\n#1\[ \t\]*$hex in main.*" \
+	"second backtrace in stack_align_edx"
+
+gdb_test "info frame" \
+	".*Saved registers:.*ecx at.*ebp at.*edi at.*eip at.*" \
+	"saved registers in stack_align_edx"
+
+
+# Testcase from breakpoints/2080 (when %eax is used)
+
+gdb_test "break *(stack_align_eax + 7)" \
+	"Breakpoint \[0-9\]* at $hex"
+
+gdb_test "continue" \
+	"Breakpoint \[0-9\]*.*stack_align_eax.*" \
+	"continue to stack_align_eax + 7"
+
+gdb_test "backtrace 10" \
+	"#0\[ \t\]*$hex in stack_align_eax.*\r\n#1\[ \t\]*$hex in main.*" \
+	"first backtrace in stack_align_eax"
+
+gdb_test "continue" \
+	"Program received signal SIGTRAP.*" \
+	"continue in stack_align_eax"
+
+skip_breakpoint stack_align_eax
+
+gdb_test "backtrace 10" \
+	"#0\[ \t\]*$hex in stack_align_eax.*\r\n#1\[ \t\]*$hex in main.*" \
+	"second backtrace in stack_align_eax"
+
+gdb_test "info frame" \
+	".*Saved registers:.*ecx at.*ebp at.*edi at.*eip at.*" \
+	"saved registers in stack_align_eax"
 
 
 # Testcase from symtab/1253.


More information about the Gdb-patches mailing list