* [PATCH] Partial fix for PR backtrace/1718
@ 2004-07-24 12:59 Mark Kettenis
2004-07-24 17:58 ` Eli Zaretskii
2004-07-30 18:35 ` Eli Zaretskii
0 siblings, 2 replies; 9+ messages in thread
From: Mark Kettenis @ 2004-07-24 12:59 UTC (permalink / raw)
To: gdb-patches
This fixes the backtrace problem with Emacs that Eli reported. It's a
partial fix since the prologue analyzer still doesn't notice that %ebx
gets saved on the stack, but that's not terribly important. This
patch also doesn't handle all the other instructions that might end up
in the prologue.
Committed,
Mark
Index: ChangeLog
from 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.
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.197
diff -u -p -r1.197 i386-tdep.c
--- i386-tdep.c 18 Jun 2004 16:06:24 -0000 1.197
+++ i386-tdep.c 24 Jul 2004 12:53:37 -0000
@@ -503,20 +503,28 @@ i386_analyze_frame_setup (CORE_ADDR pc,
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
+ /* Check for some special instructions that might be migrated by
+ 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
+
+ movl $XXX, %eax
+ movl $XXX, %ecx
+ movl $XXX, %edx
- xorl %ebx, %ebx
+ These instructions have opcodes 0xb8, 0xb9 and 0xba.
+
+ We also check for
+
+ xorl %eax, %eax
xorl %ecx, %ecx
xorl %edx, %edx
- xorl %eax, %eax
and the equivalent
- subl %ebx, %ebx
+ subl %eax, %eax
subl %ecx, %ecx
subl %edx, %edx
- subl %eax, %eax
Because of the symmetry, there are actually two ways to
encode these instructions; with opcode bytes 0x29 and 0x2b
@@ -524,21 +532,35 @@ 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 == 0x29 || op == 0x2b || op == 0x31 || op == 0x33)
+ while ((op >= 0xb8 && op <= 0xba)
+ || op == 0x29 || op == 0x2b
+ || op == 0x31 || op == 0x33)
{
- op = read_memory_unsigned_integer (pc + skip + 2, 1);
- switch (op)
+ if (op >= 0xb8 && op <= 0xba)
+ {
+ /* Skip the `movl' instructions cited above. */
+ skip += 5;
+ }
+ else
{
- case 0xdb: /* %ebx */
- case 0xc9: /* %ecx */
- case 0xd2: /* %edx */
- case 0xc0: /* %eax */
- skip += 2;
- break;
- default:
- return pc + 1;
+ /* Skip the `subl' and `xorl' instructions cited above. */
+ op = read_memory_unsigned_integer (pc + skip + 2, 1);
+ switch (op)
+ {
+ case 0xc0: /* %eax */
+ case 0xc9: /* %ecx */
+ case 0xd2: /* %edx */
+ skip += 2;
+ break;
+ default:
+ 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);
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-24 12:59 [PATCH] Partial fix for PR backtrace/1718 Mark Kettenis
@ 2004-07-24 17:58 ` Eli Zaretskii
2004-07-30 18:35 ` Eli Zaretskii
1 sibling, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2004-07-24 17:58 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Date: Sat, 24 Jul 2004 14:59:56 +0200 (CEST)
> From: Mark Kettenis <kettenis@chello.nl>
>
> This fixes the backtrace problem with Emacs that Eli reported.
Alas, it doesn't fix the problem for me: after applying the patch to
i386-tdep.c that shipped with GDB 6.1, I still get the same mess in
the backtrace at the same place. Should the patch work for GDB 6.1?
Let me know how can I help you further.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-24 12:59 [PATCH] Partial fix for PR backtrace/1718 Mark Kettenis
2004-07-24 17:58 ` Eli Zaretskii
@ 2004-07-30 18:35 ` Eli Zaretskii
2004-07-30 20:08 ` Mark Kettenis
1 sibling, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2004-07-30 18:35 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Date: Sat, 24 Jul 2004 14:59:56 +0200 (CEST)
> From: Mark Kettenis <kettenis@chello.nl>
>
> This fixes the backtrace problem with Emacs that Eli reported.
Mark, I reported a few days ago that the patch didn't fix the problem
for me when I applied it to GDB 6.1. I asked whether the patch is
supposed to work with GDB 6.1, but didn't see your reply. Did I miss
it?
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-30 18:35 ` Eli Zaretskii
@ 2004-07-30 20:08 ` Mark Kettenis
2004-07-31 13:41 ` Eli Zaretskii
0 siblings, 1 reply; 9+ messages in thread
From: Mark Kettenis @ 2004-07-30 20:08 UTC (permalink / raw)
To: eliz; +Cc: gdb-patches
Date: Fri, 30 Jul 2004 21:32:52 +0300
From: "Eli Zaretskii" <eliz@gnu.org>
> Date: Sat, 24 Jul 2004 14:59:56 +0200 (CEST)
> From: Mark Kettenis <kettenis@chello.nl>
>
> This fixes the backtrace problem with Emacs that Eli reported.
Mark, I reported a few days ago that the patch didn't fix the problem
for me when I applied it to GDB 6.1. I asked whether the patch is
supposed to work with GDB 6.1, but didn't see your reply. Did I miss
it?
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.
Mark
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-30 20:08 ` Mark Kettenis
@ 2004-07-31 13:41 ` Eli Zaretskii
2004-07-31 15:09 ` Michael Chastain
0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2004-07-31 13:41 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> 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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-31 13:41 ` Eli Zaretskii
@ 2004-07-31 15:09 ` Michael Chastain
2004-07-31 18:44 ` Eli Zaretskii
0 siblings, 1 reply; 9+ messages in thread
From: Michael Chastain @ 2004-07-31 15:09 UTC (permalink / raw)
To: kettenis, eliz; +Cc: gdb-patches
"Eli Zaretskii" <eliz@gnu.org> wrote:
> 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.
Ah, I think the real difference is that Mark's code is for
"eax = 0x12345678", but Eli's code was "eax = * (int *) 0x12345678".
Naturally those are different instructions; there's no mystical
context-dependent assembly going on, thank goodness.
I'm gonna beat this into the ground ... apologies to those who already
know all this stuff.
I'm looking at an opcode table:
http://developer.intel.com/design/pentium/manuals/24319101.pdf
page 3-286 (page 316 in the pdf)
Opcodes 0xb8 to 0xba are for "move immediate", which moves a constant
immediate value into a register. Opcodes 0xa1 and 0x8b are for "move
register/memory".
These are different instructions. In C terms,
eax = 0x375aa0; /* move immediate, opcode 0xb8 + rd */
ebx = 0x375aa0; /* move immediate, opcode 0xb8 + rd */
eax = * (int *) 0x375aa0; /* move r/m, opcode 0xa1 */
ebx = * (int *) 0x375aa0; /* move r/m, opcode 0x8b + /r */
Eli posted the code for recursive_edit_1:
0x0005f7b0 <recursive_edit_1+0>: push %ebp
0x0005f7b1 <recursive_edit_1+1>: mov 0x375aa0,%eax
0x0005f7b6 <recursive_edit_1+6>: mov %esp,%ebp
0x0005f7b8 <recursive_edit_1+8>: push %esi
That instruction is a memory move, "eax = * (int *) 0x375aa0". Indeed,
recursive_edit_1 reads two global variables near the top of the
function:
Lisp_Object
recursive_edit_1 ()
{
int count = specpdl_ptr - specpdl;
...
}
Mark's test code is:
asm(".text\n"
" .align 8\n"
SYMBOL (gdb1718) ":\n"
" pushl %ebp\n"
" movl $0x11111111, %eax\n"
That instruction is an immediate constant move.
The '$' in the assembly code means constant. Lack of '$" means
memory address. The two forms are confusingly similar:
mov $0x1234, ax # constant value, ax = 0x1234
mov 0x1234, ax # memory location, ax = * (int *) 1234
So Mark's patch is okay but that's why it doesn't touch Eli's bug. A
lot of code in the wild will have Eli's instructions. I haven't
read or tested Eli's patch, though.
It would be nice to add more instructions to gdb1718 in
gdb.arch/i386-prologue.exp to cover this:
movl memory, %eax
movl memory, %ecx
movl %eax, %ecx
movl %ecx, %eax
The memory location has to be a real location, of course.
Michael C
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-31 15:09 ` Michael Chastain
@ 2004-07-31 18:44 ` Eli Zaretskii
2004-08-01 5:35 ` Michael Chastain
0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2004-07-31 18:44 UTC (permalink / raw)
To: Michael Chastain; +Cc: kettenis, gdb-patches
> Date: Sat, 31 Jul 2004 11:09:35 -0400
> From: Michael Chastain <mec.gnu@mindspring.com>
>
> Opcodes 0xb8 to 0xba are for "move immediate", which moves a constant
> immediate value into a register. Opcodes 0xa1 and 0x8b are for "move
> register/memory".
>
> These are different instructions. In C terms,
>
> eax = 0x375aa0; /* move immediate, opcode 0xb8 + rd */
> ebx = 0x375aa0; /* move immediate, opcode 0xb8 + rd */
> eax = * (int *) 0x375aa0; /* move r/m, opcode 0xa1 */
> ebx = * (int *) 0x375aa0; /* move r/m, opcode 0x8b + /r */
Right.
Perhaps, then, you could post a list of all the opcodes and subsequent
bytes that we need to cover in i386_analyze_frame_setup?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
2004-07-31 18:44 ` Eli Zaretskii
@ 2004-08-01 5:35 ` Michael Chastain
0 siblings, 0 replies; 9+ messages in thread
From: Michael Chastain @ 2004-08-01 5:35 UTC (permalink / raw)
To: eliz; +Cc: kettenis, gdb-patches
"Eli Zaretskii" <eliz@gnu.org> wrote:
> Perhaps, then, you could post a list of all the opcodes and subsequent
> bytes that we need to cover in i386_analyze_frame_setup?
The compiler could schedule just about anything into the prologue!
Let's get empirical. I ran cc1plus and gdb through "objdump -d" and
some perl fu.
We have to have "mov 0xADDRESS, %reg". After that, recognizing
"cmpl $IMMEDIATE, 0xADDRESS" would help. That instruction gets scheduled
even before "push %ebp". Those two additions would cover 99.9% of cc1plus
and gdb.
This cc1plus is for gcc HEAD on native i686-pc-linux-gnu.
It was built with gcc 3.3.4 on native i686-pc-linux-gnu on an Intel Celeron.
cc1plus has 10849 symbols, broken down as:
10849 total symbols
9271 push %ebp | mov %esp, %ebp
1549 push %ebp | INSN | mov %esp, %ebp
19 push %ebp | INSN | INSN | mov %esp, %ebp
10 all other
The 1549 single-instruction interleaves break down as:
2 push %ebp | fldz | mov %esp, %ebp
1 push %ebp | mov $0xIMMEDIATE, %al | mov %esp, %ebp
1 push %ebp | mov $0xIMMEDIATE, %cl | mov %esp, %ebp
473 push %ebp | mov $0xIMMEDIATE, %eax | mov %esp, %ebp
185 push %ebp | mov $0xIMMEDIATE, %ecx | mov %esp, %ebp
126 push %ebp | mov $0xIMMEDIATE, %edx | mov %esp, %ebp
76 push %ebp | mov 0xADDRESS, %eax | mov %esp, %ebp
8 push %ebp | mov 0xADDRESS, %ecx | mov %esp, %ebp
20 push %ebp | mov 0xADDRESS, %edx | mov %esp, %ebp
404 push %ebp | xor %eax, %eax | mov %esp, %ebp
124 push %ebp | xor %ecx, %ecx | mov %esp, %ebp
129 push %ebp | xor %edx, %edx | mov %esp, %ebp
The 19 double-instruction interleaves are innocuous, just more MOV and XOR:
clear_aux_for_edges : push %ebp | mov 0xADDRESS, %edx | mov 0xADDRESS, %ecx | mov %esp, %ebp
cplus_demangle_set_style : push %ebp | mov 0xADDRESS, %eax | mov $0xIMMEDIATE, %edx | mov %esp, %ebp
default_spill_heuristic : push %ebp | mov 0xADDRESS, %eax | mov $0xIMMEDIATE, %edx | mov %esp, %ebp
dwarf2out_do_frame : push %ebp | mov 0xADDRESS, %edx | xor %eax, %eax | mov %esp, %ebp
earlyclobber_operand_p : push %ebp | mov 0xADDRESS, %edx | xor %eax, %eax | mov %esp, %ebp
enumerate_ldsts : push %ebp | mov 0xADDRESS, %edx | xor %ecx, %ecx | mov %esp, %ebp
fast_math_flags_set_p : push %ebp | mov 0xADDRESS, %ecx | xor %eax, %eax | mov %esp, %ebp
free_block_changes : push %ebp | mov 0xADDRESS, %eax | xor %edx, %edx | mov %esp, %ebp
gate_all_optimizations : push %ebp | mov 0xADDRESS, %edx | xor %eax, %eax | mov %esp, %ebp
ia32_multipass_dfa_lookahead : push %ebp | mov 0xADDRESS, %eax | mov $0xIMMEDIATE, %edx | mov %esp, %ebp
kept_level_p : push %ebp | mov 0xADDRESS, %edx | xor %ecx, %ecx | mov %esp, %ebp
move_replacements : push %ebp | mov 0xADDRESS, %ecx | xor %edx, %edx | mov %esp, %ebp
optimization_options : push %ebp | xor %eax, %eax | mov 0xADDRESS, %ecx | mov %esp, %ebp
pop_topmost_sequence : push %ebp | mov 0xADDRESS, %edx | xor %ecx, %ecx | mov %esp, %ebp
reg_alternate_class : push %ebp | mov 0xADDRESS, %edx | mov $0xIMMEDIATE, %eax | mov %esp, %ebp
reg_preferred_class : push %ebp | mov 0xADDRESS, %edx | mov $0xIMMEDIATE, %eax | mov %esp, %ebp
schedule_more_p : push %ebp | mov 0xADDRESS, %eax | xor %edx, %edx | mov %esp, %ebp
transfer_replacements : push %ebp | mov 0xADDRESS, %ecx | xor %edx, %edx | mov %esp, %ebp
tree_ssa_lim_finalize : push %ebp | mov 0xADDRESS, %eax | mov 0xADDRESS, %edx | mov %esp, %ebp
The 10 truly freaky prologues are:
.plt : pushl 0x86039e8 | jmp *0x86039ec | add %al, (%eax) | add %al, (%eax) | jmp *0x86039f0 | push $0x0 | jmp 80494cc <_init+0x18>
_start : xor %ebp, %ebp | pop %esi | mov %esp, %ecx | and $0xfffffff0, %esp | push %eax | push %esp | push %edx
constrain_operands_cached : cmpl $0xffffffff, 0x8619c0c | push %ebp | mov %esp, %ebp | je 841d293 <constrain_operands_cached+0x13> | pop %ebp | mov $0x1, %eax | ret
default_elf_select_rtx_section : cmpl $0x0, 0x8610da8 | push %ebp | mov %esp, %ebp | mov 0x8(%ebp), %ecx | mov 0xc(%ebp), %eax | mov 0x10(%ebp), %edx | je 84898d4 <default_elf_select_rtx_section+0x24>
get_best_mode : movzbl 0x85b0e0c, %ecx | push %ebp | mov %esp, %ebp | push %edi | test %ecx, %ecx | mov 0x8(%ebp), %edi | push %esi
get_pending_sizes : push %ebp | mov 0x867793c, %eax | xor %edx, %edx | mov %edx, 0x867793c | mov %esp, %ebp | pop %ebp | ret
init_branch_prob : push %ebp | xor %eax, %eax | xor %ecx, %ecx | mov %eax, 0x8611090 | xor %edx, %edx | mov %esp, %ebp | mov %ecx, 0x8611088
init_temp_slots : push %ebp | mov 0x860ff64, %eax | xor %edx, %edx | xor %ecx, %ecx | mov %esp, %ebp | mov %edx, 0xa8(%eax) | xor %edx, %edx
is_body_block : cmpb $0x0, 0x8563326 | push %ebp | mov %esp, %ebp | mov 0x8(%ebp), %eax | jne 84548a5 <is_body_block+0x15> | cmpb $0x4, 0xc(%eax) | je 84548b0 <is_body_block+0x20>
ix86_init_builtins : testb $0x20, 0x8677745 | push %ebp | mov %esp, %ebp | jne 84a7bd0 <ix86_init_builtins+0x10> | pop %ebp | ret | mov %esi, %esi
Next I did the same for gdb:
6612 total symbols
5492 push %ebp | mov %esp, %ebp
1087 push %ebp | INSN | mov %esp, %ebp
19 push %ebp | INSN | INSN | mov %esp, %ebp
18 all other
There weren't any new surprise in the push|INSN|mov and push|INSN|INSN|mov
prologues. Here are the "all other":
.plt : pushl 0x8282f2c | jmp *0x8282f30 | add %al, (%eax) | add %al, (%eax) | jmp *0x8282f34 | push $0x0 | jmp 80797dc <_init+0x18>
NOP_Fixup : cmpl $0x1, 0x829c3c4 | push %ebp | mov %esp, %ebp | je 81ed520 <NOP_Fixup+0x10> | pop %ebp | ret | mov %esi, %esi
OP_0f07 : cmpl $0x3, 0x829c4d4 | push %ebp | mov %esp, %ebp | mov 0x8(%ebp), %edx | mov 0xc(%ebp), %eax | je 81ed458 <OP_0f07+0x18> | pop %ebp
OP_M : cmpl $0x3, 0x829c4d4 | push %ebp | mov %esp, %ebp | mov 0x8(%ebp), %edx | mov 0xc(%ebp), %eax | je 81ed430 <OP_M+0x20> | mov %eax, 0xc(%ebp)
OP_MS : cmpl $0x3, 0x829c4d4 | push %ebp | mov %esp, %ebp | je 81ed3e2 <OP_MS+0x12> | pop %ebp | jmp 81ed8b0 <BadOp> | pop %ebp
OP_Rd : cmpl $0x3, 0x829c4d4 | push %ebp | mov %esp, %ebp | je 81ed192 <OP_Rd+0x12> | pop %ebp | jmp 81ed8b0 <BadOp> | pop %ebp
OP_XS : cmpl $0x3, 0x829c4d4 | push %ebp | mov %esp, %ebp | je 81ed402 <OP_XS+0x12> | pop %ebp | jmp 81ed8b0 <BadOp> | pop %ebp
__i686.get_pc_thunk.cx : mov (%esp, 1), %ecx | ret
_initialize_annotate : cmpl $0x1, 0x82873ec | push %ebp | mov %esp, %ebp | jle 80cc800 <_initialize_annotate+0x20> | mov $0x80cc7d0, %eax | mov %eax, 0x829ca64 | mov $0x80cc7d0, %eax
_start : xor %ebp, %ebp | pop %esi | mov %esp, %ecx | and $0xfffffff0, %esp | push %eax | push %esp | push %edx
annotate_ignore_count_change : cmpl $0x1, 0x82873ec | push %ebp | mov %esp, %ebp | jle 80cba96 <annotate_ignore_count_change+0x16> | mov $0x1, %eax | mov %eax, 0x8286d6c | pop %ebp
init_child_ops : push %ebp | mov $0x82031d0, %eax | mov $0x80967c0, %ecx | mov %eax, 0x829cf04 | mov $0x80a2ab0, %edx | mov %esp, %ebp | mov %ecx, 0x829cf20
init_remote_async_ops : push %ebp | mov $0x8207f00, %eax | mov $0x8209094, %ecx | mov %eax, 0x8284e0c | mov $0x8208020, %edx | mov %esp, %ebp | mov %ecx, 0x8284e04
init_remote_ops : push %ebp | mov $0x820ec28, %eax | mov $0x80a50d0, %ecx | mov %eax, 0x8284b44 | mov $0x80a4d10, %edx | mov %esp, %ebp | mov %ecx, 0x8284b54
rl_insert : cmpl $0x1, 0x827f794 | push %ebp | mov %esp, %ebp | mov 0x8(%ebp), %edx | mov 0xc(%ebp), %eax | je 81e4c20 <rl_insert+0x20> | mov %eax, 0xc(%ebp)
selected_architecture_name : push %ebp | xor %eax, %eax | mov 0x82877a8, %edx | cmpl $0x0, 0x827d7b4 | mov %esp, %ebp | pop %ebp | setne %al
set_inferior_args : push %ebp | mov 0x8287320, %eax | xor %ecx, %ecx | mov %ecx, 0x8287324 | mov %esp, %ebp | mov 0x8(%ebp), %edx | pop %ebp
tui_clear_source_windows : push %ebp | mov 0x827f210, %eax | xor %ecx, %ecx | mov %ecx, 0x827f214 | mov %esp, %ebp | movl $0x0, (%eax) | movl $0x0, 0x4(%eax)
These are both C programs, I'd feel better if I could do this on eclipse
(java) and mozilla (c++) as well. Also some PIC code would be nice.
I'm also ignoring floating point programs -- I bet a lot of floating
point instructions could get scheduled into the prologue.
Michael C
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Partial fix for PR backtrace/1718
@ 2004-08-01 13:54 Mark Kettenis
0 siblings, 0 replies; 9+ messages in thread
From: Mark Kettenis @ 2004-08-01 13:54 UTC (permalink / raw)
To: mec.gnu; +Cc: eliz, gdb-patches
[Sorry Michael and Eli, I managed to remove the Subject: line and
therefore the list didn't accept this message]
Date: Sun, 01 Aug 2004 01:35:39 -0400
From: Michael Chastain <mec.gnu@mindspring.com>
"Eli Zaretskii" <eliz@gnu.org> wrote:
> Perhaps, then, you could post a list of all the opcodes and subsequent
> bytes that we need to cover in i386_analyze_frame_setup?
The compiler could schedule just about anything into the prologue!
There are some restrictions though, given that GCC can only play with
a limited set of registers.
Let's get empirical. I ran cc1plus and gdb through "objdump -d" and
some perl fu.
Thanks! This really is the info I need. Could you post (or mail me)
the perl fu?
We have to have "mov 0xADDRESS, %reg". After that, recognizing
"cmpl $IMMEDIATE, 0xADDRESS" would help. That instruction gets scheduled
even before "push %ebp". Those two additions would cover 99.9% of cc1plus
and gdb.
On System V ABI conforming systems, yes. On systems that use the
-freg-struct-return by default (FreeBSD, OpenBSD, Cygwin and a few
others) I guess there are a bit more possibilities. I'll try to
address -freg-struct-return too.
Anyway, I've got some ideas to make the prologue analyzer easily
extendable.
[snip]
The 10 truly freaky prologues are:
.plt : pushl 0x86039e8 | jmp *0x86039ec | add %al, (%eax) | add %al, (%eax) | jmp *0x86039f0 | push $0x0 | jmp 80494cc <_init+0x18>
That's the PLT. GDB should already handle that one, and otherwise
it'd deserve (and need) a special frame unwinder anyway like I did for
SPARC.
_start : xor %ebp, %ebp | pop %esi | mov %esp, %ecx | and $0xfffffff0, %esp | push %eax | push %esp | push %edx
This one is rather special since it's the entry point.
Thanks!
Mark
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-08-01 13:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-24 12:59 [PATCH] Partial fix for PR backtrace/1718 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
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox