From: "Eli Zaretskii" <eliz@gnu.org>
To: Mark Kettenis <kettenis@chello.nl>
Cc: gdb-patches@sources.redhat.com
Subject: Re: [PATCH] Partial fix for PR backtrace/1718
Date: Sat, 31 Jul 2004 13:41:00 -0000 [thread overview]
Message-ID: <8632-Sat31Jul2004163849+0300-eliz@gnu.org> (raw)
In-Reply-To: <200407302007.i6UK7ufh028813@elgar.kettenis.dyndns.org> (message from Mark Kettenis on Fri, 30 Jul 2004 22:07:56 +0200 (CEST))
> Date: Fri, 30 Jul 2004 22:07:56 +0200 (CEST)
> From: Mark Kettenis <kettenis@chello.nl>
>
> Oops sorry, no that slipped through. AFAICT the patch should work
> with the GDB 6.1 release. So there must be something else wrong.
> Unforunately I can't really help you here. Can you try to debug this
> yourself. The question here is why i386_analyze_prologue() which is
> called from i386_frame_cache() isn't properly detecting the frame.
I debugged this. The reason it doesn't work (and AFAICT shouldn't
work for anyone else on any i386 platform) is that, at least with GCC,
the opcode produced by "mov 0x375aa0,%eax" and its ilk is _not_ 0xb8
to 0xba, but rather 0xa1 for a mov to EAX and 0x8b for other
registers. Obviously, GAS somehow produces a different opcode when
invoked for asm blocks in C code, as you did in i386-prologue.c in the
test suite, and for code produced from plain C. Just try to
disassemble any C program and watch the opcodes produced for these
instructions; I believe you will see what I saw.
I was able to fix the problem with the following patch to i386-tdep.c.
Note that the list of possible ModR/M values for the opcodes 0x8b and
0x89 probably needs to be expanded, but for the moment I put there
only those which are needed to cover the same ground as your original
partial fix.
If you agree with the patch, I will commit it.
2004-07-31 Eli Zaretskii <eliz@gnu.org>
* i386-tdep.c (i386_analyze_frame_setup): Handle more opcodes that
GCC puts into function prolugues for MOV instructions.
--- gdb/i386-tdep.c~0 2004-07-24 20:46:26.000000000 +0300
+++ gdb/i386-tdep.c 2004-07-31 16:05:46.000000000 +0300
@@ -473,8 +473,9 @@ static CORE_ADDR
i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
struct i386_frame_cache *cache)
{
- unsigned char op;
+ unsigned char op, modrm;
int skip = 0;
+ int break_loop = 0;
if (current_pc <= pc)
return current_pc;
@@ -502,8 +503,14 @@ i386_analyze_frame_setup (CORE_ADDR pc,
movl $XXX, %eax
movl $XXX, %ecx
movl $XXX, %edx
+ movl %eax, $XXX
+ movl %ecx, $XXX
+ movl %edx, $XXX
+ movl %eax, %ebx
+ ....
- These instructions have opcodes 0xb8, 0xb9 and 0xba.
+ These instructions may have many different opcodes:
+ 0xb8-0xba, 0xa1, 0x89,0x8b(+modr/m), and 0xc7.
We also check for
@@ -524,14 +531,64 @@ i386_analyze_frame_setup (CORE_ADDR pc,
Make sure we only skip these instructions if we later see the
`movl %esp, %ebp' that actually sets up the frame. */
while ((op >= 0xb8 && op <= 0xba)
+ || op == 0xa1 || op == 0xc7
+ || op == 0x89 || op == 0x8b
|| op == 0x29 || op == 0x2b
|| op == 0x31 || op == 0x33)
{
- if (op >= 0xb8 && op <= 0xba)
+ if ((op >= 0xb8 && op <= 0xba) || op == 0xa1 || op ==0xc7)
{
- /* Skip the `movl' instructions cited above. */
+ /* Skip the `movl' instructions cited above and their
+ 4-byte operand. */
skip += 5;
}
+ else if (op == 0x89) /* movl r32, r32 */
+ {
+ /* Skip the instruction and read the ModR/M byte. */
+ modrm = read_memory_unsigned_integer (pc + skip + 2, 1);
+ switch (modrm)
+ {
+ case 0xc1: /* %ecx,%eax */
+ case 0xc2: /* %edx,%eax */
+ case 0xc3: /* %ebx,%eax */
+ case 0xc8: /* %eax,%ecx */
+ case 0xca: /* %edx,%ecx */
+ case 0xcb: /* %ebx,%ecx */
+ case 0xd0: /* %eax,%edx */
+ case 0xd1: /* %ecx,%edx */
+ case 0xd3: /* %ebx,%edx */
+ case 0xd8: /* %eax,%ebx */
+ case 0xd9: /* %ecx,%ebx */
+ case 0xda: /* %edx,%ebx */
+ skip += 2;
+ break;
+ case 0xe5: /* movl %esp,%ebp--found frame setup end */
+ break_loop = 1;
+ break;
+ default:
+ return pc + 1;
+ }
+ }
+ else if (op == 0x8b)
+ {
+ /* Skip the instruction and read the ModR/M byte. */
+ modrm = read_memory_unsigned_integer (pc + skip + 2, 1);
+ switch (modrm)
+ {
+ case 0x05: /* %eax,... */
+ case 0x0d: /* %ecx,... */
+ case 0x15: /* %edx,... */
+ case 0x1d: /* %ebx,... */
+ /* Skip the instruction, ModR/M, and the operand. */
+ skip += 6;
+ break;
+ case 0xec: /* movl %esp,%ebp--found frame setup end */
+ break_loop = 1;
+ break;
+ default:
+ return pc + 1;
+ }
+ }
else
{
/* Skip the `subl' and `xorl' instructions cited above. */
@@ -547,6 +604,8 @@ i386_analyze_frame_setup (CORE_ADDR pc,
return pc + 1;
}
}
+ if (break_loop)
+ break;
/* If that's all, return now. */
if (current_pc <= pc + skip + 1)
@@ -555,21 +614,6 @@ i386_analyze_frame_setup (CORE_ADDR pc,
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 + skip + 2, 1) != 0xec)
- return pc + 1;
- break;
- case 0x89:
- 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. We also now commit to skipping the special
@@ -581,7 +625,7 @@ i386_analyze_frame_setup (CORE_ADDR pc,
if (current_pc <= pc + 3)
return current_pc;
- /* Check for stack adjustment
+ /* Check for stack adjustment
subl $XXX, %esp
next prev parent reply other threads:[~2004-07-31 13:41 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-07-24 12:59 Mark Kettenis
2004-07-24 17:58 ` Eli Zaretskii
2004-07-30 18:35 ` Eli Zaretskii
2004-07-30 20:08 ` Mark Kettenis
2004-07-31 13:41 ` Eli Zaretskii [this message]
2004-07-31 15:09 ` Michael Chastain
2004-07-31 18:44 ` Eli Zaretskii
2004-08-01 5:35 ` Michael Chastain
2004-08-01 13:54 Mark Kettenis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8632-Sat31Jul2004163849+0300-eliz@gnu.org \
--to=eliz@gnu.org \
--cc=gdb-patches@sources.redhat.com \
--cc=kettenis@chello.nl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox