Partial fix for PR backtrace/1718.

* i386-tdep.c (i386_analyze_frame_setup): Handle more instructions
that GCC migrates into the prolugue.  Don't handle any
instructions that clobber %ebx.
This commit is contained in:
Mark Kettenis 2004-07-24 12:59:52 +00:00
parent 822c97322c
commit b463213160
2 changed files with 46 additions and 17 deletions

View file

@ -1,3 +1,10 @@
2004-07-24 Mark Kettenis <kettenis@gnu.org>
Partial fix for PR backtrace/1718.
* i386-tdep.c (i386_analyze_frame_setup): Handle more instructions
that GCC migrates into the prolugue. Don't handle any
instructions that clobber %ebx.
2004-07-23 Andrew Cagney <cagney@gnu.org> 2004-07-23 Andrew Cagney <cagney@gnu.org>
Use regcache_raw_collect instead of regcache_collect. Use regcache_raw_collect instead of regcache_collect.

View file

@ -503,20 +503,28 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
op = read_memory_unsigned_integer (pc + 1, 1); op = read_memory_unsigned_integer (pc + 1, 1);
/* Check for some special instructions that might be migrated /* Check for some special instructions that might be migrated by
by GCC into the prologue. We check for GCC into the prologue. At this point in the prologue, code
should only touch the scratch registers %eax, %ecx and %edx,
so we check for
xorl %ebx, %ebx movl $XXX, %eax
movl $XXX, %ecx
movl $XXX, %edx
These instructions have opcodes 0xb8, 0xb9 and 0xba.
We also check for
xorl %eax, %eax
xorl %ecx, %ecx xorl %ecx, %ecx
xorl %edx, %edx xorl %edx, %edx
xorl %eax, %eax
and the equivalent and the equivalent
subl %ebx, %ebx subl %eax, %eax
subl %ecx, %ecx subl %ecx, %ecx
subl %edx, %edx subl %edx, %edx
subl %eax, %eax
Because of the symmetry, there are actually two ways to Because of the symmetry, there are actually two ways to
encode these instructions; with opcode bytes 0x29 and 0x2b encode these instructions; with opcode bytes 0x29 and 0x2b
@ -524,20 +532,34 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
Make sure we only skip these instructions if we later see the Make sure we only skip these instructions if we later see the
`movl %esp, %ebp' that actually sets up the frame. */ `movl %esp, %ebp' that actually sets up the frame. */
while (op == 0x29 || op == 0x2b || op == 0x31 || op == 0x33) while ((op >= 0xb8 && op <= 0xba)
|| op == 0x29 || op == 0x2b
|| op == 0x31 || op == 0x33)
{ {
if (op >= 0xb8 && op <= 0xba)
{
/* Skip the `movl' instructions cited above. */
skip += 5;
}
else
{
/* Skip the `subl' and `xorl' instructions cited above. */
op = read_memory_unsigned_integer (pc + skip + 2, 1); op = read_memory_unsigned_integer (pc + skip + 2, 1);
switch (op) switch (op)
{ {
case 0xdb: /* %ebx */ case 0xc0: /* %eax */
case 0xc9: /* %ecx */ case 0xc9: /* %ecx */
case 0xd2: /* %edx */ case 0xd2: /* %edx */
case 0xc0: /* %eax */
skip += 2; skip += 2;
break; break;
default: default:
return pc + 1; return pc + 1;
} }
}
/* If that's all, return now. */
if (current_pc <= pc + skip + 1)
return current_pc;
op = read_memory_unsigned_integer (pc + skip + 1, 1); op = read_memory_unsigned_integer (pc + skip + 1, 1);
} }