Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* RE: MIPS stack tracing
@ 2002-02-06  9:40 Don Bowman
  2002-02-06 16:45 ` Daniel Jacobowitz
  0 siblings, 1 reply; 22+ messages in thread
From: Don Bowman @ 2002-02-06  9:40 UTC (permalink / raw)
  To: Don Bowman; +Cc: 'gdb@sources.redhat.com '


> 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.

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)

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.


^ permalink raw reply	[flat|nested] 22+ messages in thread
* RE: MIPS stack tracing
@ 2002-02-07  6:56 Don Bowman
  2002-02-07  7:30 ` Daniel Jacobowitz
  0 siblings, 1 reply; 22+ messages in thread
From: Don Bowman @ 2002-02-07  6:56 UTC (permalink / raw)
  To: 'Daniel Jacobowitz', Don Bowman; +Cc: 'gdb@sources.redhat.com '

> > 
> > 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.

The code in gas is wrapped in #ifdef MIPS_STABS_ELF.

There's also some curious jiggery-pokery with strcmp(target, "elf")
for not emitting the .reginfo... I'm thinking maybe I can make that
a runtime option since I really hate that reginfo section with
an absolute passion. It has on and off broken all of the mips
targets I've worked on for the past 10 years :)

> 
> > 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.

If I run objdump -r, there are no relocations, my image is fully
located.

Interestingly, my host is little endian, my target is little endian.
Any guess on why those addresses whould show up as big endian?
Also, from gas, it appears a .pdr record is 7 words long, but the
.pdr shows an 8-word recurrence of the address. I assume it aligns?

So should the endianess be swapped here [ie reverse of both my host
and target]? Or do I have a bug in gas to fix first :) Is PDR a
standard of any sort, or is it just a gas invention?

--don


^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: MIPS stack tracing
@ 2002-02-04  9:22 David Anderson
  0 siblings, 0 replies; 22+ messages in thread
From: David Anderson @ 2002-02-04  9:22 UTC (permalink / raw)
  To: gdb


Daniel Jacobowitz <drow@mvista.com>
> 
> .mdebug is the ECOFF/Third-Eye debugging info format; binutils recently
> switched to generating stabs-in-ELF like other targets instead.
> 
> To my complete surprise, we apparently get PDR information out of the
> .mdebug section.  This is somewhat bizarre, as it is also present in a
> .pdr section independent of data format.  We need to read in this
> information.  I'll investigate next week (if no one beats me to it :).

The original  third-eye was (as you say) added to COFF
by MIPS (SGI was separate then, mid 1980's). 
No real sections.  the PDR was inside the third-eye data.

When MIPS/SGI moved to Elf we made the third-eye
data be a section named  .mdebug  but with
bit-for-bit identical contents to the coff-object
third-eye. There was no .pdr section.

The third-eye data structures were not ideal, in that
they had absolute (not section-relative) file offsets,
and those, of course, were always wrong for objects-inside-archives
as such objects-inside-archives were simply plunked in by ar(1)
and extracted by ld with no update of the mdebug data.

Third-eye was designed this way precisely because
various object formats of the time  third-eye was
designed did not have real sections
and adding extra sections was a major hassle (compatibility-wise
and more). So section-relative offsets were an idea that
just did not work back then (and I guess Peter Rowell,
the designer (he was Third-eye Software), 
just did not think of making the mdebug-internal
offsets be mdebug-relative (or decided not to, I don't know...)).

Andrew Cagney <ac131313@cygnus.com>
>It would go back to SGI (Hmm, didn't sgi switch to dwarf2?) which was 
>using mdebug info.  A number of embedded MIPS toolchains would have been 
>mdebug for compatability (I know this as I filed gdb/150, gdb/152 and 
>gdb/149) and I have a sinking feeling that they haven't yet ``just gone 
>away''.

Ok. More than you want to know (sorry).
SGI has 3 ABIs, all ELF (since the mid 1990's).
An executable can be built in any ABI.

	o32.  Uses mdebug (third-eye). Follows
	 	the MIPS Processor Supplement.
		Intended for MIPS-1 (and now MIPS-2
		cpu chips only.
		This will never change, compiler in stasis :-)

	n32   Uses dwarf-2. For MIPS-3 and MIPS-4 cpu chips,
		takes advantage of 64bit integer registers
		and additional floating point registers.
		pointers are 32 bits.
		Not yet using dwarf-3.
		ABI defined in N32 Handbook (http://techpubs.sgi.com)

	64   Uses dwarf-2. For MIPS-3 and MIPS-4 cpu chips,
		takes advantage of 64bit integer registers
		and additional floating point registers.
		pointers are 64 bits.
		Not yet using dwarf-3.


David Anderson davea@sgi.com


^ permalink raw reply	[flat|nested] 22+ messages in thread
* RE: MIPS stack tracing
@ 2002-02-03 15:49 Don Bowman
  0 siblings, 0 replies; 22+ messages in thread
From: Don Bowman @ 2002-02-03 15:49 UTC (permalink / raw)
  To: 'Andrew Cagney ', 'Daniel Jacobowitz '
  Cc: Don Bowman, '''Stan Shebs' ' ',
	'''Greg McGary' ' ',
	'gdb@sources.redhat.com '


I'm going to give dwarf2 a try (as suggested in the thread 
@ http://sources.redhat.com/ml/crossgcc/2001-12/msg00039.html)



^ permalink raw reply	[flat|nested] 22+ messages in thread
* RE: MIPS stack tracing
@ 2002-02-03 12:29 Don Bowman
  2002-02-03 12:29 ` Daniel Jacobowitz
  0 siblings, 1 reply; 22+ messages in thread
From: Don Bowman @ 2002-02-03 12:29 UTC (permalink / raw)
  To: 'Daniel Jacobowitz ', Don Bowman
  Cc: ''Stan Shebs' ', ''Greg McGary' ',
	'gdb@sources.redhat.com ', 'echristo@redhat.com '


Daniel Jacobowitz wrote:

>Most of what it needs should be in .pdr, which is available regardless
>of -g.  I don't believe heuristics should be necessary in that case. 
>The logic is a bit twisted, though...

Has anyone checked out this older message from the mailing list?

Re: Questions about GCC MIPS R5900's mdebug section
http://sources.redhat.com/ml/gdb/1999-q4/msg00290.html

I indeed have no .mdebug section, and I indeed see an unsuccessful
search for "__GDB_EFI_INFO__". I do have a .pdr section. On the
surface this would seem to be my problem.
Should this sym lookup be prefaced with a check for a .mdebug
section?

Also, from scanning the sources, I would have to guess that the
alpha architecture is suffering the same problem.


^ permalink raw reply	[flat|nested] 22+ messages in thread
* RE: MIPS stack tracing
@ 2002-02-02 12:14 Don Bowman
  2002-02-02 14:45 ` Daniel Jacobowitz
  0 siblings, 1 reply; 22+ messages in thread
From: Don Bowman @ 2002-02-02 12:14 UTC (permalink / raw)
  To: 'Stan Shebs', Don Bowman
  Cc: 'Greg McGary', 'Daniel Jacobowitz', gdb, echristo


Stan Shebs wrote:

> Don Bowman wrote:
> > 
> > I've been debugging through gdb for a day or so now, I think
> > I'm on to something. It appears that find_proc_desc is switching
> > to the heuristic approach even though I have a symbol table.
> 
> That's a bug for sure.  The heuristic approach is only supposed
> to be used for tracing through frames with no debug info.
> 
> Stan
> 

Can you confirm that if there is no .stabs, but symbols are present,
that it shouldn't use the heuristic approach?

It appears that if all my objects are built with at least -g1 
then it works.

--don


^ permalink raw reply	[flat|nested] 22+ messages in thread
* RE: MIPS stack tracing
@ 2002-02-02 11:26 Don Bowman
  2002-02-02 12:11 ` Stan Shebs
  0 siblings, 1 reply; 22+ messages in thread
From: Don Bowman @ 2002-02-02 11:26 UTC (permalink / raw)
  To: 'Greg McGary', Don Bowman
  Cc: 'Daniel Jacobowitz', gdb, echristo


> Greg McGary <greg@mcgary.org> writes:
> 
> > The gist of it is, walk backwards until you find 'jr ra',
> > then walk forwards to the first non-null instruction. That's
> > the start of a function. Look for a [d]addiu to the sp, that's
> > the stack adjustment, look for a [d]addiu to the fp, that's
> > the frame. Look for a s[w|d] of ra to the stack.
> > Continue on up the stack.
> > 
> > However, gcc 3.0 is breaking the rules. It emits multiple
> > 'jr ra' per function. Unfortunately, this appears to be
> > rather tough to fix. The upshot is that the beginning of
> > a function can't be reliably found, and it all falls apart
> > from there. Prior to gcc 3.0 it was fine.
> 
> [ Cc'd to Eric Christopher who has a hand in the MIPS GCC backend, and
>   with whom I briefly discussed this very issue a couple weeks ago. ]
> 
> Hmm...  GCC emitted multiple returns for MIPS long before 3.0.
> I recall first observing it in early 1998, and it had probably
> done it before.  Maybe GCC 3.0 does it more often?
> 
> Anyway, I had the same gripe about multiple returns breaking the ABI,
> but since then I have had second thoughts that perhaps this isn't a
> real problem.  I haven't looked at MIPS code recently, so don't know
> for certain if my reasoning here is correct.  Since you have had your
> nose buried in the code, you can tell me if my argument makes sense:
> 
> If a function has a frame, it never has multiple returns.  It always
> branches to the epilogue where the call frame is torn down.  So, if a
> function has multiple returns, that means it is frameless,
> i.e. there's no prologue or epilogue.  Say you scan backward within a
> frameless function.  You might hit an interior `jr $ra' or the one
> that terminates the previous function.  When you then scan forward,
> you'll find no stack adjustment and no store of $ra in any case.  In
> call cases, you get the same answer: this function has no frame.
> Therefore, multiple returns are harmless since they give no false
> information about the call frame.

I've personally never observed multiple returns prior to 3.0, but perhaps 
I had some optimisation disabled which caused it.

I don't think you're correct about the no-multiple returns when there's
a frame. Here's a snippet of assembly from a function of mine.
As you can see, the stack is adjusted by 64 at the top. There
is an interior return which deadjusts the stack, and there's more
further down in the function.

 <osiSemaphore::Init(osiSemaphoreType)>:
0080102d        move    v0,a0
24470004        addiu   a3,v0,4
27bdffc0        addiu   sp,sp,-64
00a0402d        move    t0,a1
  ...
afa00030        sw      zero,48(sp)
dfbf0038        ld      ra,56(sp)
03e00008        jr      ra
27bd0040        addiu   sp,sp,64
00000000        nop
0c000000        jal     0 <osiSemaphore::Init(osiSemaphoreType)>
  ...

I've been debugging through gdb for a day or so now, I think 
I'm on to something. It appears that find_proc_desc is switching
to the heuristic approach even though I have a symbol table.
It sucessfully find the symbols, but given a PC, can't find
the symbol that its in. This may be due to the sign-extension
on the addresses (eg ffffffff80000000). I'm hoping to get a
fix for gdb today and send in a patch.

--don


^ permalink raw reply	[flat|nested] 22+ messages in thread
* MIPS stack tracing
@ 2002-02-02 10:58 David Anderson
  0 siblings, 0 replies; 22+ messages in thread
From: David Anderson @ 2002-02-02 10:58 UTC (permalink / raw)
  To: gdb


Don Bowman <don@sandvine.com> writes:
> Now, before I launch into fixing the gdb MIPS stack tracing
> code up, I thought I'd ask a few questions. I'd like to
> do it by using the symbols to find the start of each function,
> instead of by the heuristic of walking in the code. That
> would be much faster for me (I'm on an embedded platform,
> and its slow to walk the memory over the link). It would also
> be deterministic. The downside is that the stack trace won't
> work without a symbol file. Is that OK?

Whether it's ok for gdb is for others  to say.
SGI debuggers long ago went this route.

Daniel Jacobowitz <drow@mvista.com> writes:
|The stack tracing algorithm for MIPS is defined in
|the SYSV ABI, @ http://www.caldera.com/developers/devspecs/
|Its fairly straightforward and works reliably.
|
|The gist of it is, walk backwards until you find 'jr ra',
|then walk forwards to the first non-null instruction. That's
|the start of a function. Look for a [d]addiu to the sp, that's
|the stack adjustment, look for a [d]addiu to the fp, that's
|the frame. Look for a s[w|d] of ra to the stack.
|Continue on up the stack.
|
|However, gcc 3.0 is breaking the rules. It emits multiple
|'jr ra' per function. Unfortunately, this appears to be
|rather tough to fix. The upshot is that the beginning of
|a function can't be reliably found, and it all falls apart
|from there. Prior to gcc 3.0 it was fine.

That ABI document was written for and applies to the MIPS-I
processors available at the time.
AFAIK, the organization that maintained that document disbanded
a few years ago.

As I said in an earlier note, the ABI document was not always honored
(though it should have been) even back in the early 1990's
but today that Mips Processor Supplement is simply
not applicable.  Much has not changed, but key things
have changed (new registers and
new instructions).  I don't know of a replacement document
(other than SGI documents).

http://www.mips.com has the
MIPSpro assembly language document (vol 1 and 2)
which is (or was) an SGI document describing the n32 
calling conventions.   
(you have to register to see the document, but there is no charge).
Also available from http://techpubs.sgi.com

Corrections welcome.
David Anderson davea@sgi.com


^ permalink raw reply	[flat|nested] 22+ messages in thread
* MIPS stack tracing
@ 2002-02-02  9:57 David Anderson
  0 siblings, 0 replies; 22+ messages in thread
From: David Anderson @ 2002-02-02  9:57 UTC (permalink / raw)
  To: gdb


On Thu, Jan 31, 2002 at 05:27:30PM -0500, Don Bowman wrote:
...
> The problem is that the compiler emits multiple returns
> per function. The algorithm gdb follows is that specified
> by the SYSV ABI (which the compiler is breaking). I looked

The only SYSV ABI document on MIPS that I am aware of is the
MIPS Processor Supplement.  That document applies to what SGI
calls -32 or o32, the old-32bit ABI.
The section "Standard Called Function Rules" in that document
gives the rule, page 3-18 in my copy.

I am *presuming* that is what you refer to here.
If not, then... the following is 'incomplete'.

Modern gcc (for modern MIPS targets) emits code in
what SGI calls the n32 or 64 ABIs
(or variations thereof, for other MIPS users), 
and those ABIs are not defined by the SYSV ABI Mips Processor Supplement!  
For these other ABIs, multiple returns per function are allowed and normal.
For non-SGI ABIs the rules are, well, whatever they are.  
MIPS is  the best source
of info, and "See MIPS Run" by Sweetman has been mentioned by
others here as a good book on MIPS (I concur).
The SGI n32 ABI document is available
for anyone that wishes to see it.
	http://techpubs.sgi.com
specifically:
  http://techpubs.sgi.com/library/tpl/cgi-bin/browse.cgi?
  coll=0650&db=bks&cmd=toc&pth=/SGI_Developer/Mpro_n32_ABI
(I broke that long URL by hand: rejoin it for the URL to work)

Aside: in spite of the ABI rule, the MIPS compilers for the old-32bit
  ABI case when -O3 was used always could generate multiple
  returns for a function and did at times!! (but -O3 was
  relatively rarely used for old-32bit ABI compiles)

For SGI the n32 and 64 ABIs are defined by other SGI documents
(such as the n32 book)
and for other folks using MIPS processors they are defined by
MIPS or whoever 'controls' (whatever that means) the particular
target ABI.

In short, you've been mislead by a document which no longer
applies.  gcc is not violating any rule I know of by generating
multiple returns per function.


Corrections welcome.
David Anderson davea@sgi.com


^ permalink raw reply	[flat|nested] 22+ messages in thread
* RE: MIPS stack tracing
@ 2002-02-01 10:15 Don Bowman
  2002-02-01 11:32 ` Daniel Jacobowitz
  2002-02-02 11:16 ` Greg McGary
  0 siblings, 2 replies; 22+ messages in thread
From: Don Bowman @ 2002-02-01 10:15 UTC (permalink / raw)
  To: 'Daniel Jacobowitz', Don Bowman; +Cc: 'gdb@sources.redhat.com'

> From: Daniel Jacobowitz [mailto:drow@mvista.com]
> 
> I'd like to understand - and have documented somewhere - what it is
> about MIPS besides the somewhat-variable frame register that makes
> backtracing so much more complex.  Also, IMHO, if we have symbol
> information to find the start of the function we should certainly use
> it.

The stack tracing algorithm for MIPS is defined in
the SYSV ABI, @ http://www.caldera.com/developers/devspecs/
Its fairly straightforward and works reliably.

The gist of it is, walk backwards until you find 'jr ra',
then walk forwards to the first non-null instruction. That's
the start of a function. Look for a [d]addiu to the sp, that's
the stack adjustment, look for a [d]addiu to the fp, that's
the frame. Look for a s[w|d] of ra to the stack.
Continue on up the stack.

However, gcc 3.0 is breaking the rules. It emits multiple
'jr ra' per function. Unfortunately, this appears to be
rather tough to fix. The upshot is that the beginning of
a function can't be reliably found, and it all falls apart
from there. Prior to gcc 3.0 it was fine.

For embedded platforms this is a disaster: you don't have
the full symbols (or sometimes any symbols). In desperation
I added a function end marker of 'break 4', and search 
for that instead of 'jr ra'. This is obviously a hack, but
I was stuck on our embedded system.

Now I've got the same issue with gdb. I don't want to add
the 'hack'. The algorithm its using just doesn't work. gdb
in general has access to the symbols, so I can search for
a .ent by symbol instead of by algorithm. However, this
means gdb won't be able to work without symbols if I make
the change. But it would appear that it doesn't right now
anyway.

--don


^ permalink raw reply	[flat|nested] 22+ messages in thread
* MIPS stack tracing
@ 2002-01-31 14:27 Don Bowman
  2002-02-01  9:37 ` Daniel Jacobowitz
  0 siblings, 1 reply; 22+ messages in thread
From: Don Bowman @ 2002-01-31 14:27 UTC (permalink / raw)
  To: 'gdb@sources.redhat.com'


The MIPS / vxworks stack tracing has always been fairly weak
in gdb I've found. However, now with the 3.0.3 gdb, it
is quite broken.

The problem is that the compiler emits multiple returns
per function. The algorithm gdb follows is that specified
by the SYSV ABI (which the compiler is breaking). I looked
into fixing the compiler, but gave up in the short term.
In desperation I added a magic instruction (break 4) in the
epilogue of each function (by modifying gcc). This allowed
me to fix my VxWorks task trace (tt).

Now, before I launch into fixing the gdb MIPS stack tracing
code up, I thought I'd ask a few questions. I'd like to
do it by using the symbols to find the start of each function,
instead of by the heuristic of walking in the code. That
would be much faster for me (I'm on an embedded platform,
and its slow to walk the memory over the link). It would also
be deterministic. The downside is that the stack trace won't
work without a symbol file. Is that OK?
The alternative is I can add support for walking to find
my magic instruction. This isn't standard.
The only other alternative I can see is to fix gcc up
to not emit multiple returns. This seems to be difficult to
add as a constraint.

Does anyone have any suggestions on a course of action
for me to take?

--don


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2002-02-07 15:30 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-06  9:40 MIPS stack tracing Don Bowman
2002-02-06 16:45 ` Daniel Jacobowitz
  -- strict thread matches above, loose matches on Subject: below --
2002-02-07  6:56 Don Bowman
2002-02-07  7:30 ` Daniel Jacobowitz
2002-02-04  9:22 David Anderson
2002-02-03 15:49 Don Bowman
2002-02-03 12:29 Don Bowman
2002-02-03 12:29 ` Daniel Jacobowitz
2002-02-03 12:29   ` Andrew Cagney
2002-02-03 12:13     ` Daniel Jacobowitz
2002-02-03 12:29       ` Andrew Cagney
2002-02-02 12:14 Don Bowman
2002-02-02 14:45 ` Daniel Jacobowitz
2002-02-02 11:26 Don Bowman
2002-02-02 12:11 ` Stan Shebs
2002-02-02 10:58 David Anderson
2002-02-02  9:57 David Anderson
2002-02-01 10:15 Don Bowman
2002-02-01 11:32 ` Daniel Jacobowitz
2002-02-02 11:16 ` Greg McGary
2002-01-31 14:27 Don Bowman
2002-02-01  9:37 ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox