This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFC]: patch #3 for Sun C compiled target programs
- From: Michael Mueller <m dot mueller99 at kay-mueller dot de>
- To: gdb-patches at sources dot redhat dot com
- Date: Tue, 22 Jun 2004 21:56:58 +0200
- Subject: [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;