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:
parent
822c97322c
commit
b463213160
2 changed files with 46 additions and 17 deletions
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue