This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: MIPS stack tracing
- From: Daniel Jacobowitz <drow at mvista dot com>
- To: Don Bowman <don at sandvine dot com>
- Cc: "'gdb at sources dot redhat dot com '" <gdb at sources dot redhat dot com>
- Date: Wed, 6 Feb 2002 19:45:18 -0500
- Subject: Re: MIPS stack tracing
- References: <FE045D4D9F7AED4CBFF1B3B813C853371BC219@mail.sandvine.com>
On Wed, Feb 06, 2002 at 12:40:18PM -0500, Don Bowman wrote:
>
> > From: Don Bowman
> >
> > I'm going to give dwarf2 a try (as suggested in the thread
> > @ http://sources.redhat.com/ml/crossgcc/2001-12/msg00039.html)
> >
>
> To summarise:
>
> So the dwarf-2 gives the same affect, stack traces do not work
> on mips with gcc 3.0.3 and binutils 2.11.2. The root of the
> problem is that the multiple returns per function exist as
> of the new version of gcc, and there is no .mdebug section
> anymore. gdb doesn't read the .pdr section which is emitted
> with the information on how to unwind the stack, so it
> switches to its heuristic, which is now broken because of the
> multiple returns.
>
> Upon examination of gas, the .pdr section is only emitted if
> MIPS_STABS_ELF is defined. Am I to assume that if I'm using
> DWARF2 this won't occur? The code which actually emits it
> seems to be in ecoff.c.
No. It should be emitted unless we are emitting .mdebug, which we
don't do any more for mips-*-linux.
> Am I correct that the .pdr section is an array of:
>
> /*
> * Procedure Descriptor
> *
> * There is one of these for EVERY TEXT LABEL.
> * If a procedure is in a file with full symbols, then isym
> * will point to the PROC symbols, else it will point to the
> * global symbol for the label.
> */
>
> typedef struct pdr {
> bfd_vma adr; /* memory address of start of procedure */
> long isym; /* start of local symbol entries */
> long iline; /* start of line number entries*/
> long regmask; /* save register mask */
> long regoffset; /* save register offset */
> long iopt; /* start of optimization symbol entries*/
> long fregmask; /* save floating point register mask */
> long fregoffset; /* save floating point register offset */
> long frameoffset; /* frame size */
> short framereg; /* frame pointer register */
> short pcreg; /* offset or reg of return pc */
> long lnLow; /* lowest line in the procedure */
> long lnHigh; /* highest line in the procedure */
> bfd_vma cbLineOffset; /* byte offset for this procedure from the
> fd base */
> /* These fields are new for 64 bit ECOFF. */
> unsigned gp_prologue : 8; /* byte size of GP prologue */
> unsigned gp_used : 1; /* true if the procedure uses GP */
> unsigned reg_frame : 1; /* true if register frame procedure */
> unsigned prof : 1; /* true if compiled with -pg */
> unsigned reserved : 13; /* reserved: must be zero */
> unsigned localoff : 8; /* offset of local variables from vfp */
> } PDR, *pPDR;
> #define cbPDR sizeof(PDR)
I don't think that's the right one. The code in gas to emit them:
subseg_set (pdr_seg, 0);
/* Write the symbol. */
exp.X_op = O_symbol;
exp.X_add_symbol = p;
exp.X_add_number = 0;
emit_expr (&exp, 4);
fragp = frag_more (7 * 4);
md_number_to_chars (fragp, (valueT) cur_proc_ptr->reg_mask, 4);
md_number_to_chars (fragp + 4, (valueT) cur_proc_ptr->reg_offset, 4);
md_number_to_chars (fragp + 8, (valueT) cur_proc_ptr->fpreg_mask, 4);
md_number_to_chars (fragp + 12, (valueT) cur_proc_ptr->fpreg_offset, 4);
md_number_to_chars (fragp + 16, (valueT) cur_proc_ptr->frame_offset, 4);
md_number_to_chars (fragp + 20, (valueT) cur_proc_ptr->frame_reg, 4);
md_number_to_chars (fragp + 24, (valueT) cur_proc_ptr->pc_reg, 4);
subseg_set (saved_seg, saved_subseg);
So that is: symbol, regmask, regoffset, fpregmask, fpregoffset,
frameoffset, framereg, pcreg, and broken for 64-bit targets. Feh, I'll
have to fix that last one.
> This doesn't seem right to me, if I dump my .pdr section I get:
> Contents of section .pdr:
> 0000 00400080 00000000 00000000 00000000 .@..............
> 0010 00000000 00000000 00000000 00000000 ................
> 0020 74430080 00000000 00000000 00000000 tC..............
> 0030 00000000 00000000 00000000 00000000 ................
> 0040 b8430080 00000000 00000000 00000000 .C..............
> ...
>
> But all of my addresses start @ 0x80000000.
Careful, it has relocations if you look at it in an object. Also
careful, you have a host-target endian mismatch. That first word is
0x80000400.
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer