Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [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