This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC]: patch #3 for Sun C compiled target programs


Backtrace for Sun C -O compiled programs doesn't work (64 bit only?)

I verified against target programs compiled with

  Sun WorkShop 6 update 2 C 5.3 2001/05/15 (64 bit)
  Sun WorkShop 6 2000/04/07 C 5.1 (64 bit)

No problems found with:

  Sun C 5.5 2003/03/12
  Forte Developer 7 C 5.4 2002/03/09
  gcc 3.4.0


compile command cc -xarch=v9 -O p5.c -o p5

Test source file:

#include <stdio.h>

  void fun(int k)
    {
    int a, b;

    printf("fun %d %d\n", a, b);
    a = 10;
    b = 20;
    a = (a + b) / 2;
    printf("fun %d %d\n", a, b);
    }

  void main()
    {
    fun(10);
    printf("finished\n");
    }

gdb output

GNU gdb 2004-06-17-cvs
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.8"...(no debugging symbols found)
...
(gdb) b fun
Breakpoint 1 at 0x1000009a8
(gdb) run
Starting program: /export/home/michaelm/gdb/gdb-6.1.patch/tst/p5.O.64.51
(no debugging symbols found)...(no debugging symbols found)...(no debugging symb
ols found)...
Breakpoint 1, 0x00000001000009a8 in fun ()
(gdb) x/10i fun
0x1000009a8 <fun>: sethi %hi(0), %g2
0x1000009ac <fun+4>: sethi %hi(0x800), %g3
0x1000009b0 <fun+8>: or %g2, 1, %g2
0x1000009b4 <fun+12>: or %g3, 0x340, %g3
0x1000009b8 <fun+16>: sllx %g2, 0x20, %g2
0x1000009bc <fun+20>: save %sp, -192, %sp
0x1000009c0 <fun+24>: or %g3, %g2, %o0
0x1000009c4 <fun+28>: ld [ %fp + 0x7f7 ], %g2
0x1000009c8 <fun+32>: mov 0xf, %i1
0x1000009cc <fun+36>: sra %g2, 0, %o1
(gdb) bt
#0 0x00000001000009a8 in fun ()
#1 0x0000000100000a24 in main ()
(gdb) b *0x1000009c0
Breakpoint 2 at 0x1000009c0
(gdb) c
Continuing.


Breakpoint 2, 0x00000001000009c0 in fun ()
(gdb) bt
#0  0x00000001000009c0 in fun ()
#1  0x0000000000000008 in ?? ()
Previous frame identical to this frame (corrupt stack?)


=======================================================================


This is caused by function sparc_analyze_prologue in sparc-tdep.c which fails to find the SAVE instruction in the debugged function's prolog code. The reason is that sparc_analyze_prologue has very precise expectations about how the prolog code should be structured and some compiler versions break that. I changed it to be more tolerant.

I search a maximum of 32 instructions (hope that this is enough) until I find a 'save' or some kind of jump or return instruction.

For opcode details see "The SPARC Architecture Manual".

2004-06-22  Michael Mueller  <m.mueller99@kay-mueller.de>
    * sparc-tdep.c: make prolog analysis code more tolerant



Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.153
diff -c -p -r1.153 sparc-tdep.c
*** sparc-tdep.c	7 Jun 2004 02:02:55 -0000	1.153
--- sparc-tdep.c	22 Jun 2004 19:30:41 -0000
*************** sparc_analyze_prologue (CORE_ADDR pc, CO
*** 522,528 ****
    struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
    unsigned long insn;
    int offset = 0;
!   int dest = -1;
  
    if (current_pc <= pc)
      return current_pc;
--- 522,530 ----
    struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
    unsigned long insn;
    int offset = 0;
!   unsigned int op3;
!   unsigned int op3_3_0;
!   unsigned int op3_5_4;
  
    if (current_pc <= pc)
      return current_pc;
*************** sparc_analyze_prologue (CORE_ADDR pc, CO
*** 540,570 ****
    if (tdep->plt_entry_size > 0 && in_plt_section (current_pc, NULL))
      pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size);
  
!   insn = sparc_fetch_instruction (pc);
! 
!   /* Recognize a SETHI insn and record its destination.  */
!   if (X_OP (insn) == 0 && X_OP2 (insn) == 0x04)
!     {
!       dest = X_RD (insn);
!       offset += 4;
! 
!       insn = sparc_fetch_instruction (pc + 4);
!     }
! 
!   /* Allow for an arithmetic operation on DEST or %g1.  */
!   if (X_OP (insn) == 2 && X_I (insn)
!       && (X_RD (insn) == 1 || X_RD (insn) == dest))
!     {
!       offset += 4;
! 
!       insn = sparc_fetch_instruction (pc + 8);
!     }
! 
!   /* Check for the SAVE instruction that sets up the frame.  */
!   if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
!     {
!       cache->frameless_p = 0;
!       return pc + offset + 4;
      }
  
    return pc;
--- 542,606 ----
    if (tdep->plt_entry_size > 0 && in_plt_section (current_pc, NULL))
      pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size);
  
!   /*
!    * Optimized code can have a lot of other instructions in front of the save
!    * we are looking for. We try to be tolerant and search 32 instructions
!    * until we find a 'save' or some kind of jump or return instruction.
!    *
!    * For opcode details see "The SPARC Architecture Manual".
!    *
!    * Example:
!    *
!    * cc: Sun WorkShop 6 2000/04/07 C 5.1 (cc -xarch=v9 -O)
!    * 0x100555a34 <btnext>:           sethi  %hi(0), %g2
!    * 0x100555a38 <btnext+4>:         sethi  %hi(0xee6000), %g3
!    * 0x100555a3c <btnext+8>:         or  %g2, 1, %g2
!    * 0x100555a40 <btnext+12>:        or  %g3, 0x120, %g3
!    * 0x100555a44 <btnext+16>:        sllx  %g2, 0x20, %g2
!    * 0x100555a48 <btnext+20>:        sethi  %hi(0xee5800), %g4
!    * 0x100555a4c <btnext+24>:        or  %g3, %g2, %g2
!    * 0x100555a50 <btnext+28>:        sethi  %hi(0), %g3
!    * 0x100555a54 <btnext+32>:        or  %g3, 1, %g3 ! 0x1
!    * 0x100555a58 <btnext+36>:        or  %g4, 0x3f8, %g4
!    * 0x100555a5c <btnext+40>:        save  %sp, -1104, %sp
!    */
!   for (offset = 0; offset < 4*32; offset += 4)
!     {
!       insn = sparc_fetch_instruction (pc + offset);
! 
!       switch (X_OP (insn) )
! 	{
! 	case 0:
! 	  if (X_OP2 (insn) == 0x04) /* Skip SETHI instruction */
! 	    continue;
! 	  return pc; /* Branch instruction, inside the body */
! 	case 1:
! 	  return pc; /* CALL instruction, inside the body */
! 	case 2:
! 	  op3 = X_OP3 (insn);
! 	  op3_5_4 = (op3 & 0x30) >> 4;
!     
! 	  if (op3_5_4 == 3)
! 	    {
! 	    op3_3_0 = op3 & 0xf;
! 	    if (op3_3_0 == 0xc) /* found SAVE instruction */
!               {
! 	      if (current_pc > pc + offset)
!                 cache->frameless_p = 0;
!               return pc + offset + 4;
!               }
! 	    /* more jumps, etc.: we're inside the body */
! 	    if (op3_3_0 == 0x8) /* JMPL (and ret) instruction */
! 	      return pc;
! 	    if (op3_3_0 == 0x9) /* RETURN instruction */
! 	      return pc;
! 	    if (op3_3_0 == 0xa) /* Tcc trap instruction */
! 	      return pc;
! 	    if (op3_3_0 == 0xe) /* DONE, RETRY instruction */
! 	      return pc;
! 	    }
! 	  break;
! 	}
      }
  
    return pc;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]