[rfa] i386-tdep.c: add some insn's to prologue analyzer
Mark Kettenis
kettenis@chello.nl
Sun Aug 10 12:10:00 GMT 2003
Date: Mon, 4 Aug 2003 21:33:19 -0400
From: Michael Elizabeth Chastain <mec@shout.net>
This patch improves the i386 prologue analyzer so that it can
handle a few more instructions in the prologue. This fixes
pr gdb/1253 and pr gdb/1255.
Thanks, Michael. A minor nit though. When rewriting the prologue
analyzer I made an effort to make sure that the returned PC points at
the first instruction after the prologue. I think we should consider
the "xor" and "sub" instructions only part of the prologue if they're
followed by the "mov %esp, %ebp". So I rewrote your patch a bit. I
checked in the attached on mainline. Can you check whether it really
solves the problems you were seeing. I added a testcase to the
testsuite, and there it seems to do the job. I'll move this over to
the branch in a few days if things turn out to be allright.
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
Based on a patch from Michael Elizabeth Chastain (mec@shout.net):
* i386-tdep.c (i386_analyze_frame_setup): Recognize more
instructions that GCC likes to mingle into the prologue. Fixes
gdb/1253 and gdb/1255.
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.162
diff -u -p -r1.162 i386-tdep.c
--- i386-tdep.c 18 Jul 2003 21:31:50 -0000 1.162
+++ i386-tdep.c 10 Aug 2003 12:00:13 -0000
@@ -439,6 +439,7 @@ i386_analyze_frame_setup (CORE_ADDR pc,
struct i386_frame_cache *cache)
{
unsigned char op;
+ int skip = 0;
if (current_pc <= pc)
return current_pc;
@@ -456,25 +457,61 @@ i386_analyze_frame_setup (CORE_ADDR pc,
if (current_pc <= pc + 1)
return current_pc;
- /* Check for `movl %esp, %ebp' -- can be written in two ways. */
op = read_memory_unsigned_integer (pc + 1, 1);
+
+ /* Check for some special instructions that might be migrated
+ by GCC into the prologue. We check for
+
+ xorl %ebx, %ebx
+ xorl %ecx, %ecx
+ xorl %edx, %edx
+
+ and the equivalent
+
+ subl %ebx, %ebx
+ subl %ecx, %ecx
+ subl %edx, %edx
+
+ Make sure we only skip these instructions if we later see the
+ `movl %esp, %ebp' that actually sets up the frame. */
+ while (op == 0x29 || op == 0x31)
+ {
+ op = read_memory_unsigned_integer (pc + skip + 2, 1);
+ switch (op)
+ {
+ case 0xdb: /* %ebx */
+ case 0xc9: /* %ecx */
+ case 0xd2: /* %edx */
+ skip += 2;
+ break;
+ default:
+ return pc + 1;
+ }
+
+ op = read_memory_unsigned_integer (pc + skip + 1, 1);
+ }
+
+ /* Check for `movl %esp, %ebp' -- can be written in two ways. */
switch (op)
{
case 0x8b:
- if (read_memory_unsigned_integer (pc + 2, 1) != 0xec)
+ if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xec)
return pc + 1;
break;
case 0x89:
- if (read_memory_unsigned_integer (pc + 2, 1) != 0xe5)
+ if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xe5)
return pc + 1;
break;
default:
return pc + 1;
}
- /* OK, we actually have a frame. We just don't know how large it is
- yet. Set its size to zero. We'll adjust it if necessary. */
+ /* OK, we actually have a frame. We just don't know how large
+ it is yet. Set its size to zero. We'll adjust it if
+ necessary. We also now commit to skipping the special
+ instructions mentioned before. */
cache->locals = 0;
+ pc += skip;
/* If that's all, return now. */
if (current_pc <= pc + 3)
More information about the Gdb-patches
mailing list