* [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 threadend 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