Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* SH breakpoint problem
@ 2001-08-06 19:45 Jonathan Larmour
  2001-08-07  5:53 ` Jonathan Larmour
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-06 19:45 UTC (permalink / raw)
  To: gdb

I've been sanity checking both the GCC 3.0.1 candidate and the GDB 5.1
candidate, and I've found an issue on the SH, which I'm debugging remotely.
Setting a breakpoint on this simple function:

void
cyg_test_exit(void)
{
    for(;;);
}

fails - it reports a SIGILL. I believe this is probably a watchdog timer.
The problem is that, given the disassembly:

Dump of assembler code for function cyg_test_exit:
0x800b130 <cyg_test_exit>:	mov.l	r14,@-r15
0x800b132 <cyg_test_exit+2>:	mov	r15,r14
0x800b134 <cyg_test_exit+4>:	bra	0x800b134 <cyg_test_exit+4>
0x800b136 <cyg_test_exit+6>:	nop	

GDB sets the breakpoint at 0x800b136, rather than 0x800b134. Tracing
through GDB, I found after_prologue() in sh-tdep.c does:

  /* Get the line associated with FUNC_ADDR.  */
  sal = find_pc_line (func_addr, 0);

  /* There are only two cases to consider.  First, the end of the source
line
     is within the function bounds.  In that case we return the end of the
     source line.  Second is the end of the source line extends beyond the
     bounds of the current function.  We need to use the slow code to
     examine instructions in that case.  */
  if (sal.end < func_end)
    return sal.end;

The problem is, I believe, that the debug info is probably right and the
end of the source line is indeed 0x800b136 (as is returned from
find_pc_line) since the nop is in a delay slot, but it is mistaken to
assume that is where the breakpoint should be set.

But I don't know what way I should try to fix it. Matching instructions
with delay slots like branches explicitly by reading from the target is my
first thought but it seems awfully wasteful, and I'm sure there is received
knowledge on this subject. So, what is it :-).

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-06 19:45 SH breakpoint problem Jonathan Larmour
@ 2001-08-07  5:53 ` Jonathan Larmour
  2001-08-07  7:26 ` Elena Zannoni
  2001-08-07 15:42 ` Kevin Buettner
  2 siblings, 0 replies; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-07  5:53 UTC (permalink / raw)
  To: gdb

Jonathan Larmour wrote:
> 
> But I don't know what way I should try to fix it. Matching instructions
> with delay slots like branches explicitly by reading from the target is my
> first thought but it seems awfully wasteful, and I'm sure there is received
> knowledge on this subject. So, what is it :-).

Actually, perhaps it's better to fix this in the target's GDB stub and let
it recognise whether the op occured in a delay slot.

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-06 19:45 SH breakpoint problem Jonathan Larmour
  2001-08-07  5:53 ` Jonathan Larmour
@ 2001-08-07  7:26 ` Elena Zannoni
  2001-08-07  7:33   ` Jonathan Larmour
  2001-08-07 15:42 ` Kevin Buettner
  2 siblings, 1 reply; 18+ messages in thread
From: Elena Zannoni @ 2001-08-07  7:26 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: gdb

Jonathan Larmour writes:
 > I've been sanity checking both the GCC 3.0.1 candidate and the GDB 5.1
 > candidate, and I've found an issue on the SH, which I'm debugging remotely.
 > Setting a breakpoint on this simple function:
 > 
 > void
 > cyg_test_exit(void)
 > {
 >     for(;;);
 > }
 > 
 > fails - it reports a SIGILL. I believe this is probably a watchdog timer.
 > The problem is that, given the disassembly:
 > 
 > Dump of assembler code for function cyg_test_exit:
 > 0x800b130 <cyg_test_exit>:	mov.l	r14,@-r15
 > 0x800b132 <cyg_test_exit+2>:	mov	r15,r14
 > 0x800b134 <cyg_test_exit+4>:	bra	0x800b134 <cyg_test_exit+4>
 > 0x800b136 <cyg_test_exit+6>:	nop	
 > 
 > GDB sets the breakpoint at 0x800b136, rather than 0x800b134. Tracing
 > through GDB, I found after_prologue() in sh-tdep.c does:
 > 
 >   /* Get the line associated with FUNC_ADDR.  */
 >   sal = find_pc_line (func_addr, 0);
 > 
 >   /* There are only two cases to consider.  First, the end of the source
 > line
 >      is within the function bounds.  In that case we return the end of the
 >      source line.  Second is the end of the source line extends beyond the
 >      bounds of the current function.  We need to use the slow code to
 >      examine instructions in that case.  */
 >   if (sal.end < func_end)
 >     return sal.end;
 > 
 > The problem is, I believe, that the debug info is probably right and the
 > end of the source line is indeed 0x800b136 (as is returned from
 > find_pc_line) since the nop is in a delay slot, but it is mistaken to
 > assume that is where the breakpoint should be set.
 > 
 > But I don't know what way I should try to fix it. Matching instructions
 > with delay slots like branches explicitly by reading from the target is my
 > first thought but it seems awfully wasteful, and I'm sure there is received
 > knowledge on this subject. So, what is it :-).

I should know, but I don't (I am the gdb sh person). :-(
What does gdb do with the same program against the simulator?

Elena


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

* Re: SH breakpoint problem
  2001-08-07  7:26 ` Elena Zannoni
@ 2001-08-07  7:33   ` Jonathan Larmour
  2001-08-07  7:54     ` Elena Zannoni
  0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-07  7:33 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb

Elena Zannoni wrote:
> 
> Jonathan Larmour writes:
>  > I've been sanity checking both the GCC 3.0.1 candidate and the GDB 5.1
>  > candidate, and I've found an issue on the SH, which I'm debugging remotely.
>  > Setting a breakpoint on this simple function:
>  >
>  > void
>  > cyg_test_exit(void)
>  > {
>  >     for(;;);
>  > }
>  >
>  > fails - it reports a SIGILL. I believe this is probably a watchdog timer.
>  > The problem is that, given the disassembly:
>  >
>  > Dump of assembler code for function cyg_test_exit:
>  > 0x800b130 <cyg_test_exit>:   mov.l   r14,@-r15
>  > 0x800b132 <cyg_test_exit+2>: mov     r15,r14
>  > 0x800b134 <cyg_test_exit+4>: bra     0x800b134 <cyg_test_exit+4>
>  > 0x800b136 <cyg_test_exit+6>: nop
>  >
>  > GDB sets the breakpoint at 0x800b136, rather than 0x800b134. Tracing
>  > through GDB, I found after_prologue() in sh-tdep.c does:
>  >
>  >   /* Get the line associated with FUNC_ADDR.  */
>  >   sal = find_pc_line (func_addr, 0);
>  >
>  >   /* There are only two cases to consider.  First, the end of the source
>  > line
>  >      is within the function bounds.  In that case we return the end of the
>  >      source line.  Second is the end of the source line extends beyond the
>  >      bounds of the current function.  We need to use the slow code to
>  >      examine instructions in that case.  */
>  >   if (sal.end < func_end)
>  >     return sal.end;
>  >
>  > The problem is, I believe, that the debug info is probably right and the
>  > end of the source line is indeed 0x800b136 (as is returned from
>  > find_pc_line) since the nop is in a delay slot, but it is mistaken to
>  > assume that is where the breakpoint should be set.
>  >
>  > But I don't know what way I should try to fix it. Matching instructions
>  > with delay slots like branches explicitly by reading from the target is my
>  > first thought but it seems awfully wasteful, and I'm sure there is received
>  > knowledge on this subject. So, what is it :-).
> 
> I should know, but I don't (I am the gdb sh person). :-(
> What does gdb do with the same program against the simulator?

It has the same failing:

(gdb) disass cyg_test_exit
Dump of assembler code for function cyg_test_exit:
0x10e4 <cyg_test_exit>:	mov.l	r14,@-r15
0x10e6 <cyg_test_exit+2>:	mov	r15,r14
0x10e8 <cyg_test_exit+4>:	bra	0x10e8 <cyg_test_exit+4>
0x10ea <cyg_test_exit+6>:	nop	
End of assembler dump.
(gdb) b cyg_test_exit
Breakpoint 1 at 0x10ea: file foo.c, line 3.
(gdb) run
Starting program: /export/pot/ecc-obj/sh/edk/foo 

Program received signal SIGTRAP, Trace/breakpoint trap.
0x000010e8 in cyg_test_exit () at foo.c:2
2	{
(gdb) 

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-07  7:33   ` Jonathan Larmour
@ 2001-08-07  7:54     ` Elena Zannoni
  2001-08-07  8:05       ` Jonathan Larmour
  2001-08-09 14:49       ` Andrew Cagney
  0 siblings, 2 replies; 18+ messages in thread
From: Elena Zannoni @ 2001-08-07  7:54 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Elena Zannoni, gdb

Jonathan Larmour writes:
 > Elena Zannoni wrote:
 > > 
 > > Jonathan Larmour writes:
 > >  > I've been sanity checking both the GCC 3.0.1 candidate and the GDB 5.1
 > >  > candidate, and I've found an issue on the SH, which I'm debugging remotely.
 > >  > Setting a breakpoint on this simple function:
 > >  >
 > >  > void
 > >  > cyg_test_exit(void)
 > >  > {
 > >  >     for(;;);
 > >  > }
 > >  >
 > >  > fails - it reports a SIGILL. I believe this is probably a watchdog timer.
 > >  > The problem is that, given the disassembly:
 > >  >
 > >  > Dump of assembler code for function cyg_test_exit:
 > >  > 0x800b130 <cyg_test_exit>:   mov.l   r14,@-r15
 > >  > 0x800b132 <cyg_test_exit+2>: mov     r15,r14
 > >  > 0x800b134 <cyg_test_exit+4>: bra     0x800b134 <cyg_test_exit+4>
 > >  > 0x800b136 <cyg_test_exit+6>: nop
 > >  >
 > >  > GDB sets the breakpoint at 0x800b136, rather than 0x800b134. Tracing
 > >  > through GDB, I found after_prologue() in sh-tdep.c does:
 > >  >
 > >  >   /* Get the line associated with FUNC_ADDR.  */
 > >  >   sal = find_pc_line (func_addr, 0);
 > >  >
 > >  >   /* There are only two cases to consider.  First, the end of the source
 > >  > line
 > >  >      is within the function bounds.  In that case we return the end of the
 > >  >      source line.  Second is the end of the source line extends beyond the
 > >  >      bounds of the current function.  We need to use the slow code to
 > >  >      examine instructions in that case.  */
 > >  >   if (sal.end < func_end)
 > >  >     return sal.end;
 > >  >
 > >  > The problem is, I believe, that the debug info is probably right and the
 > >  > end of the source line is indeed 0x800b136 (as is returned from
 > >  > find_pc_line) since the nop is in a delay slot, but it is mistaken to
 > >  > assume that is where the breakpoint should be set.
 > >  >
 > >  > But I don't know what way I should try to fix it. Matching instructions
 > >  > with delay slots like branches explicitly by reading from the target is my
 > >  > first thought but it seems awfully wasteful, and I'm sure there is received
 > >  > knowledge on this subject. So, what is it :-).
 > > 
 > > I should know, but I don't (I am the gdb sh person). :-(
 > > What does gdb do with the same program against the simulator?
 > 
 > It has the same failing:
 > 
 > (gdb) disass cyg_test_exit
 > Dump of assembler code for function cyg_test_exit:
 > 0x10e4 <cyg_test_exit>:	mov.l	r14,@-r15
 > 0x10e6 <cyg_test_exit+2>:	mov	r15,r14
 > 0x10e8 <cyg_test_exit+4>:	bra	0x10e8 <cyg_test_exit+4>
 > 0x10ea <cyg_test_exit+6>:	nop	
 > End of assembler dump.
 > (gdb) b cyg_test_exit
 > Breakpoint 1 at 0x10ea: file foo.c, line 3.
 > (gdb) run
 > Starting program: /export/pot/ecc-obj/sh/edk/foo 
 > 
 > Program received signal SIGTRAP, Trace/breakpoint trap.
 > 0x000010e8 in cyg_test_exit () at foo.c:2
 > 2	{
 > (gdb) 

Ok, I guess we'll (or I) have to cook up something similar to what mips does
for delay slots.

Elena


 > 
 > Jifl
 > -- 
 > Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
 > Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-07  7:54     ` Elena Zannoni
@ 2001-08-07  8:05       ` Jonathan Larmour
  2001-08-09 14:49       ` Andrew Cagney
  1 sibling, 0 replies; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-07  8:05 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb

Elena Zannoni wrote:
> Ok, I guess we'll (or I) have to cook up something similar to what mips does
> for delay slots.

Looking at mips-tdep.c, I would have thought it would have the same problem
in the same situation (although I haven't tried it).

Since I'd like this to be in 5.1 if possible, I'm prepared to have a go
myself if that's quicker. But can you expand more about what you'd have in
mind? 

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-06 19:45 SH breakpoint problem Jonathan Larmour
  2001-08-07  5:53 ` Jonathan Larmour
  2001-08-07  7:26 ` Elena Zannoni
@ 2001-08-07 15:42 ` Kevin Buettner
  2001-08-07 21:54   ` Alexandre Oliva
  2 siblings, 1 reply; 18+ messages in thread
From: Kevin Buettner @ 2001-08-07 15:42 UTC (permalink / raw)
  To: Jonathan Larmour, gdb

On Aug 7,  3:44am, Jonathan Larmour wrote:

> Setting a breakpoint on this simple function:
> 
> void
> cyg_test_exit(void)
> {
>     for(;;);
> }
> 
> fails - it reports a SIGILL. I believe this is probably a watchdog timer.
> The problem is that, given the disassembly:
> 
> Dump of assembler code for function cyg_test_exit:
> 0x800b130 <cyg_test_exit>:	mov.l	r14,@-r15
> 0x800b132 <cyg_test_exit+2>:	mov	r15,r14
> 0x800b134 <cyg_test_exit+4>:	bra	0x800b134 <cyg_test_exit+4>
> 0x800b136 <cyg_test_exit+6>:	nop	
> 
> GDB sets the breakpoint at 0x800b136, rather than 0x800b134. Tracing
> through GDB, I found after_prologue() in sh-tdep.c does:
> 
>   /* Get the line associated with FUNC_ADDR.  */
>   sal = find_pc_line (func_addr, 0);
> 
>   /* There are only two cases to consider.  First, the end of the source
> line
>      is within the function bounds.  In that case we return the end of the
>      source line.  Second is the end of the source line extends beyond the
>      bounds of the current function.  We need to use the slow code to
>      examine instructions in that case.  */
>   if (sal.end < func_end)
>     return sal.end;
> 
> The problem is, I believe, that the debug info is probably right and the
> end of the source line is indeed 0x800b136 (as is returned from
> find_pc_line) since the nop is in a delay slot, but it is mistaken to
> assume that is where the breakpoint should be set.
> 
> But I don't know what way I should try to fix it. Matching instructions
> with delay slots like branches explicitly by reading from the target is my
> first thought but it seems awfully wasteful, and I'm sure there is received
> knowledge on this subject. So, what is it :-).

My opinion is that gdb should use the information obtained from
find_pc_line() only to refine the limit searched by the prologue
scanner.  The prologue scanner needs to be taught that it must
never scan past an instruction which modifies the flow of control
(i.e, branch or call instructions).

Kevin


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

* Re: SH breakpoint problem
  2001-08-07 15:42 ` Kevin Buettner
@ 2001-08-07 21:54   ` Alexandre Oliva
  2001-08-07 22:46     ` Kevin Buettner
  0 siblings, 1 reply; 18+ messages in thread
From: Alexandre Oliva @ 2001-08-07 21:54 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: Jonathan Larmour, gdb

On Aug  7, 2001, Kevin Buettner <kevinb@cygnus.com> wrote:

> My opinion is that gdb should use the information obtained from
> find_pc_line() only to refine the limit searched by the prologue
> scanner.  The prologue scanner needs to be taught that it must
> never scan past an instruction which modifies the flow of control
> (i.e, branch or call instructions).

This would cause a yet-to-be-contributed port I worked on to stop the
search too early, because some peculiarities of the ABI require
function calls to be inserted in the prologue in certain
circumstances.

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me


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

* Re: SH breakpoint problem
  2001-08-07 21:54   ` Alexandre Oliva
@ 2001-08-07 22:46     ` Kevin Buettner
  2001-08-09 12:48       ` Jonathan Larmour
  0 siblings, 1 reply; 18+ messages in thread
From: Kevin Buettner @ 2001-08-07 22:46 UTC (permalink / raw)
  To: Alexandre Oliva, Kevin Buettner; +Cc: Jonathan Larmour, gdb

On Aug 8,  1:54am, Alexandre Oliva wrote:

> On Aug  7, 2001, Kevin Buettner <kevinb@cygnus.com> wrote:
> 
> > My opinion is that gdb should use the information obtained from
> > find_pc_line() only to refine the limit searched by the prologue
> > scanner.  The prologue scanner needs to be taught that it must
> > never scan past an instruction which modifies the flow of control
> > (i.e, branch or call instructions).
> 
> This would cause a yet-to-be-contributed port I worked on to stop the
> search too early, because some peculiarities of the ABI require
> function calls to be inserted in the prologue in certain
> circumstances.

That sort of thing is okay so long as you teach the prologue analyzer
about these special functions.

Kevin


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

* Re: SH breakpoint problem
  2001-08-07 22:46     ` Kevin Buettner
@ 2001-08-09 12:48       ` Jonathan Larmour
  2001-08-09 13:29         ` Kevin Buettner
  0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-09 12:48 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: Alexandre Oliva, gdb

Kevin Buettner wrote:
> 
> On Aug 8,  1:54am, Alexandre Oliva wrote:
> 
> > On Aug  7, 2001, Kevin Buettner <kevinb@cygnus.com> wrote:
> >
> > > My opinion is that gdb should use the information obtained from
> > > find_pc_line() only to refine the limit searched by the prologue
> > > scanner.  The prologue scanner needs to be taught that it must
> > > never scan past an instruction which modifies the flow of control
> > > (i.e, branch or call instructions).
> >
> > This would cause a yet-to-be-contributed port I worked on to stop the
> > search too early, because some peculiarities of the ABI require
> > function calls to be inserted in the prologue in certain
> > circumstances.
> 
> That sort of thing is okay so long as you teach the prologue analyzer
> about these special functions.

It depends if it can be distinguished from a branch that we do want to
ignore though.

I tried Kevin's suggestion anyway, and hit a problem in that even if I
return the correct address from sh_skip_prologue(), the code that calls it
in find_function_start_sal() in symtab.c "corrects" it due to the check:

2055	  /* Check if SKIP_PROLOGUE left us in mid-line, and the next
2056	     line is still part of the same function.  */

So even if we do correct it, it will still put it back :-|. Perhaps it
would be better (assuming it is allowed) to modify the PC in
sh_breakpoint_from_pc()?

One semi-related question: sh_breakpoint_from_pc() in sh-tdep.c says:

  /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
  static unsigned char breakpoint[] =  {0xc3, 0xc3};

whereas config/sh/tm-sh.h says:

#define BIG_REMOTE_BREAKPOINT    { 0xc3, 0x20 } /* Used in remote.c */
#define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */

Which is right?

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-09 12:48       ` Jonathan Larmour
@ 2001-08-09 13:29         ` Kevin Buettner
  2001-08-09 14:05           ` Jonathan Larmour
  0 siblings, 1 reply; 18+ messages in thread
From: Kevin Buettner @ 2001-08-09 13:29 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: gdb

On Aug 9,  8:48pm, Jonathan Larmour wrote:

> Kevin Buettner wrote:
> > 
> > On Aug 8,  1:54am, Alexandre Oliva wrote:
> > 
> > > On Aug  7, 2001, Kevin Buettner <kevinb@cygnus.com> wrote:
> > >
> > > > My opinion is that gdb should use the information obtained from
> > > > find_pc_line() only to refine the limit searched by the prologue
> > > > scanner.  The prologue scanner needs to be taught that it must
> > > > never scan past an instruction which modifies the flow of control
> > > > (i.e, branch or call instructions).
> > >
> > > This would cause a yet-to-be-contributed port I worked on to stop the
> > > search too early, because some peculiarities of the ABI require
> > > function calls to be inserted in the prologue in certain
> > > circumstances.
> > 
> > That sort of thing is okay so long as you teach the prologue analyzer
> > about these special functions.
> 
> It depends if it can be distinguished from a branch that we do want to
> ignore though.
> 
> I tried Kevin's suggestion anyway, and hit a problem in that even if I
> return the correct address from sh_skip_prologue(), the code that calls it
> in find_function_start_sal() in symtab.c "corrects" it due to the check:
> 
> 2055	  /* Check if SKIP_PROLOGUE left us in mid-line, and the next
> 2056	     line is still part of the same function.  */
> 
> So even if we do correct it, it will still put it back :-|.

You might try defining PROLOGUE_FIRSTLINE_OVERLAP for your port.  (This
might cause other things to break though.)

> Perhaps it would be better (assuming it is allowed) to modify the PC
> in sh_breakpoint_from_pc()?

It is allowed, but is generally used for such things as clearing
bits which might make the address odd (see mips).

I don't recall the details, but changing the address in
*_breakpoint_from_pc() didn't work when I had a (sort of) similar
problem about a year ago.  I ended up submitting the following patch
which may be used for adjusting the breakpoint address:

    http://sources.redhat.com/ml/gdb-patches/2000-06/msg00257.html

Unfortunately, this patch needs a bit of work before it can go in.
(See Eli Zaretskii's comments.)

> One semi-related question: sh_breakpoint_from_pc() in sh-tdep.c says:
> 
>   /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
>   static unsigned char breakpoint[] =  {0xc3, 0xc3};
> 
> whereas config/sh/tm-sh.h says:
> 
> #define BIG_REMOTE_BREAKPOINT    { 0xc3, 0x20 } /* Used in remote.c */
> #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
> 
> Which is right?

Maybe both of them?

They're both trapa instructions.  The sh_breakpoint_from_pc() version
is ``trapa #c3'' and the {BIG,LITTLE}_REMOTE_BREAKPOINT version is
``trapa #20''.

Kevin


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

* Re: SH breakpoint problem
  2001-08-09 13:29         ` Kevin Buettner
@ 2001-08-09 14:05           ` Jonathan Larmour
  2001-08-09 14:28             ` Andrew Cagney
  2001-08-09 14:57             ` Kevin Buettner
  0 siblings, 2 replies; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-09 14:05 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb

Kevin Buettner wrote:
> 
> On Aug 9,  8:48pm, Jonathan Larmour wrote:
> > I tried Kevin's suggestion anyway, and hit a problem in that even if I
> > return the correct address from sh_skip_prologue(), the code that calls it
> > in find_function_start_sal() in symtab.c "corrects" it due to the check:
> >
> > 2055    /* Check if SKIP_PROLOGUE left us in mid-line, and the next
> > 2056       line is still part of the same function.  */
> >
> > So even if we do correct it, it will still put it back :-|.
> 
> You might try defining PROLOGUE_FIRSTLINE_OVERLAP for your port.  (This
> might cause other things to break though.)

This would be defined for the whole SH architecture then. What
ramifications would it have? i.e. what would/could break?

It does seem a bit odd that after going to lengths to analyze the prologue
etc. to determine the right address, it goes and basically ignores that in
favour of the debug info. Why did it bother since it already knew the
address of the start of the function?

> > Perhaps it would be better (assuming it is allowed) to modify the PC
> > in sh_breakpoint_from_pc()?
> 
> It is allowed, but is generally used for such things as clearing
> bits which might make the address odd (see mips).
> 
> I don't recall the details, but changing the address in
> *_breakpoint_from_pc() didn't work when I had a (sort of) similar
> problem about a year ago.  I ended up submitting the following patch
> which may be used for adjusting the breakpoint address:
> 
>     http://sources.redhat.com/ml/gdb-patches/2000-06/msg00257.html
> 
> Unfortunately, this patch needs a bit of work before it can go in.
> (See Eli Zaretskii's comments.)

I'm surprised a function like this only needs using in such a small number
of places, rather than whereever BREAKPOINT_FROM_PC is used. I suppose I
can't really see the difference between them :-|.

Also, I can't help but think people might be annoyed that "b *0x12345678"
may not actually set a bp at exactly that address. As for hardware
breakpoints, I don't know either what would be different.

Anyway, I can't see how that approach wouldn't be required for mips, but
whatever. I was just rather expecting that this type of issue (end of
source line is a delay slot) must have been solved somewhere already.
Surely on some archs the end of the line containing a call to a function
_must_ be a delay slot. Or did the debug info (IMHO if so, erroneously) not
used to include the delay slot as being a part of that line?

> > One semi-related question: sh_breakpoint_from_pc() in sh-tdep.c says:
> >
> >   /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
> >   static unsigned char breakpoint[] =  {0xc3, 0xc3};
> >
> > whereas config/sh/tm-sh.h says:
> >
> > #define BIG_REMOTE_BREAKPOINT    { 0xc3, 0x20 } /* Used in remote.c */
> > #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
> >
> > Which is right?
> 
> Maybe both of them?
> 
> They're both trapa instructions.  The sh_breakpoint_from_pc() version
> is ``trapa #c3'' and the {BIG,LITTLE}_REMOTE_BREAKPOINT version is
> ``trapa #20''.

But on the target, we have to know what traps are assigned to breakpoints,
and what are free for other uses (genuine traps). Is there a right answer,
or should we just pick one?

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-09 14:05           ` Jonathan Larmour
@ 2001-08-09 14:28             ` Andrew Cagney
  2001-08-09 14:57             ` Kevin Buettner
  1 sibling, 0 replies; 18+ messages in thread
From: Andrew Cagney @ 2001-08-09 14:28 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Kevin Buettner, gdb

> 
> This would be defined for the whole SH architecture then. What
> ramifications would it have? i.e. what would/could break?
> 
> It does seem a bit odd that after going to lengths to analyze the prologue
> etc. to determine the right address, it goes and basically ignores that in
> favour of the debug info. Why did it bother since it already knew the
> address of the start of the function?


Prologue analysis does many things: determines the address of the 
function proper; figures out what registes were saved where; and 
computes the frame base address.

GDB normally prefers debug info (hopefully the compiler knew what it was 
doing - er, except in this case) over hardwired analysis.

Andrew


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

* Re: SH breakpoint problem
  2001-08-07  7:54     ` Elena Zannoni
  2001-08-07  8:05       ` Jonathan Larmour
@ 2001-08-09 14:49       ` Andrew Cagney
  2001-08-09 16:52         ` Jonathan Larmour
  1 sibling, 1 reply; 18+ messages in thread
From: Andrew Cagney @ 2001-08-09 14:49 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: Jonathan Larmour, gdb

> Ok, I guess we'll (or I) have to cook up something similar to what mips does
> for delay slots.


(Or TiC80 - er oops, deleted that :-)

I think there are two bugs:

	o	GCC is marking the end of the prologue
		and the start of the code proper
		with an instruction sitting in a delay slot.

		Put simply OUTCH!

		I'd consider that a GCC bug.  Especially
		if it was compiled without -O.

	o	The SH has delay slots and the subsequent
		features.

The delay slot problem tends to only occure when a user explicitly 
inserts a breakpoint at a specific address (or GCC gets nasty and starts 
outputting source-and-line info that contains delay slots).

Any way, the first problem is handed by fixing GCC :-)

The second problem is more interesting, targets handle delay slots by:

	o	have code such as software
		instruction-step detect and skip
		both the jmp and the delay slot

	o	have the target when doing hardware
		single step skip both (I suspect
		the SH does this)

	o	have the hardware provide sufficient
		information to allow GDB to detect
		a delay-slot breakpoint.

If either of the first two options are taken (they are both reasonable!) 
then it is a ``the user is always right'' situtation when they enter:

	(gdb) break *address_of_delay_slot

This is because, in general, GDB can't tell if what looks like and 
smells like a delay slot really is.  GDB just has to assume that the 
USER (who is always right and in this case, since they are using 
assembler level features, must understand the ISA's delay slot :-) 
really is trying to debug something like:

	jump bar
	nop
	.....
	jump foo
   bar:	move r1 to r2

enjoy,
	Andrew




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

* Re: SH breakpoint problem
  2001-08-09 14:05           ` Jonathan Larmour
  2001-08-09 14:28             ` Andrew Cagney
@ 2001-08-09 14:57             ` Kevin Buettner
  1 sibling, 0 replies; 18+ messages in thread
From: Kevin Buettner @ 2001-08-09 14:57 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: gdb

On Aug 9, 10:05pm, Jonathan Larmour wrote:

> Kevin Buettner wrote:
> > 
> > On Aug 9,  8:48pm, Jonathan Larmour wrote:
> > > I tried Kevin's suggestion anyway, and hit a problem in that even if I
> > > return the correct address from sh_skip_prologue(), the code that calls it
> > > in find_function_start_sal() in symtab.c "corrects" it due to the check:
> > >
> > > 2055    /* Check if SKIP_PROLOGUE left us in mid-line, and the next
> > > 2056       line is still part of the same function.  */
> > >
> > > So even if we do correct it, it will still put it back :-|.
> > 
> > You might try defining PROLOGUE_FIRSTLINE_OVERLAP for your port.  (This
> > might cause other things to break though.)
> 
> This would be defined for the whole SH architecture then.

Not necessarily.  You could put the define in your target specific
tm-*.h file.  BTW, for PROLOGUE_FIRSTLINE_OVERLAP to survive (long
term), it will have to be multiarched and it'll be the responsibility
of the target's tdep.c file to make sure it gets set correctly.

> What ramifications would it have?  i.e. what would/could break?

It's been a number of years since I tinkered with it.  My recollection
is that I didn't always see the correct values of the parameters when
stopping at the beginning of a function.  This problem could be fixed
in the prologue analyzer though.  It could also be fixed by making some
improvements to the core of gdb.

> It does seem a bit odd that after going to lengths to analyze the prologue
> etc. to determine the right address, it goes and basically ignores that in
> favour of the debug info. Why did it bother since it already knew the
> address of the start of the function?

I've sometimes wondered about this myself.  I think the answer is that
it doesn't necessarily trust that the prologue analyzer will have
gotten all the way to the end of the prologue.  Therefore, it attempts
to adjust the address based upon the debug info.  For your scenario,
this is definitely wrong.

> > > Perhaps it would be better (assuming it is allowed) to modify the PC
> > > in sh_breakpoint_from_pc()?
> > 
> > It is allowed, but is generally used for such things as clearing
> > bits which might make the address odd (see mips).
> > 
> > I don't recall the details, but changing the address in
> > *_breakpoint_from_pc() didn't work when I had a (sort of) similar
> > problem about a year ago.  I ended up submitting the following patch
> > which may be used for adjusting the breakpoint address:
> > 
> >     http://sources.redhat.com/ml/gdb-patches/2000-06/msg00257.html
> > 
> > Unfortunately, this patch needs a bit of work before it can go in.
> > (See Eli Zaretskii's comments.)
> 
> I'm surprised a function like this only needs using in such a small number
> of places, rather than whereever BREAKPOINT_FROM_PC is used. I suppose I
> can't really see the difference between them :-|.

On mips, all that's happening is that the breakpoint address is being
cleaned up a bit so that the breakpoint will get written to the
correct address.  Ideally, BREAKPOINT_FROM_PC() should only be
returning the sequence of bits that represents a breakpoint at the
given address.  It shouldn't have to muck with the address at all.

In any event, BREAKPOINT_FROM_PC() is called when it's time to obtain
insert a breakpoint on the target.  TARGET_ADJUST_BREAKPOINT_ADDRESS
is called to fix up the breakpoint address at the time the breakpoint
is created.  The user is warned if the breakpoint is actually moved.
(I believe that one of Eli's criticism's of the patch is that it should
also warn you when you hit one of these breakpoints which was moved.)
If we put the warning in BREAKPOINT_FROM_PC(), we'd see the warning
*every time* that breakpoints were inserted or removed from the target.
This happens a lot and would be extremely undesirable.

> Also, I can't help but think people might be annoyed that "b *0x12345678"
> may not actually set a bp at exactly that address. As for hardware
> breakpoints, I don't know either what would be different.

I agree; it is annoying when your breakpoints are moved on you.  OTOH,
for the architecture that I created this patch for, it was *impossible*
to set breakpoints at certain addresses due to architectural limitations.
Yet, the compiler would still indicate these addresses in its debug
info.

> > > One semi-related question: sh_breakpoint_from_pc() in sh-tdep.c says:
> > >
> > >   /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
> > >   static unsigned char breakpoint[] =  {0xc3, 0xc3};
> > >
> > > whereas config/sh/tm-sh.h says:
> > >
> > > #define BIG_REMOTE_BREAKPOINT    { 0xc3, 0x20 } /* Used in remote.c */
> > > #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
> > >
> > > Which is right?
> > 
> > Maybe both of them?
> > 
> > They're both trapa instructions.  The sh_breakpoint_from_pc() version
> > is ``trapa #c3'' and the {BIG,LITTLE}_REMOTE_BREAKPOINT version is
> > ``trapa #20''.
> 
> But on the target, we have to know what traps are assigned to breakpoints,
> and what are free for other uses (genuine traps).

I agree.

> Is there a right answer, or should we just pick one?

It seems to me that the answer is target dependent and you've stumbled
across a case where two different targets encode the trap number via
different mechanisms.  For the remote board, the
{BIG,LITTLE}_REMOTE_BREAKPOINT encoding is used.  For a native port,
the sh_breakpoint_from_pc() encoding is used.

Ideally, the various target specific encodings ought to be collected
together in sh-tdep.c.  The multiarch mechanism ought to be able to
decide (or be told) which one to use...  Another solution is to
create a target specific tdep.c file which has specifies alternate
methods for things like BREAKPOINT_FROM_PC().


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

* Re: SH breakpoint problem
  2001-08-09 14:49       ` Andrew Cagney
@ 2001-08-09 16:52         ` Jonathan Larmour
  2001-08-09 18:05           ` Andrew Cagney
  0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-09 16:52 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Elena Zannoni, gdb

Andrew Cagney wrote:
> I think there are two bugs:
> 
>         o       GCC is marking the end of the prologue
>                 and the start of the code proper
>                 with an instruction sitting in a delay slot.
> 
>                 Put simply OUTCH!
> 
>                 I'd consider that a GCC bug.  Especially
>                 if it was compiled without -O.

Maybe I didn't quite understand what was meant to happen then. In the case
of:

1: {
2: for (;;);
3: }

where is the compiler meant to mark the end of the first source line in the
debug info? You are saying it is 1, not 2 as I previously had been
assuming.

>         o       The SH has delay slots and the subsequent
>                 features.

So this bug _would_ be revealed if we set a breakpoint on line 2 above,
right?
 
> The delay slot problem tends to only occure when a user explicitly
> inserts a breakpoint at a specific address (or GCC gets nasty and starts
> outputting source-and-line info that contains delay slots).

So which source line _should_ the delay slot be associated with in the
above example, if GCC is being nasty?
 
> Any way, the first problem is handed by fixing GCC :-)

And I know even less about GCC than GDB. Oh dear.

> The second problem is more interesting, targets handle delay slots by:
> 
>         o       have code such as software
>                 instruction-step detect and skip
>                 both the jmp and the delay slot
> 
>         o       have the target when doing hardware
>                 single step skip both (I suspect
>                 the SH does this)

We've been doing both on our target.

>         o       have the hardware provide sufficient
>                 information to allow GDB to detect
>                 a delay-slot breakpoint.
> 
> If either of the first two options are taken (they are both reasonable!)
> then it is a ``the user is always right'' situtation when they enter:
> 
>         (gdb) break *address_of_delay_slot
> 
> This is because, in general, GDB can't tell if what looks like and
> smells like a delay slot really is.  GDB just has to assume that the
> USER (who is always right and in this case, since they are using
> assembler level features, must understand the ISA's delay slot :-)
> really is trying to debug something like:
> 
>         jump bar
>         nop
>         .....
>         jump foo
>    bar: move r1 to r2

Yuck, but I suppose it's possible. The implication of what you are saying
is that it is up to the target to detect that the trap occured in a delay
slot, and return the address of the delay slot instead of the reported
address at the time of the exception. Right?

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

* Re: SH breakpoint problem
  2001-08-09 16:52         ` Jonathan Larmour
@ 2001-08-09 18:05           ` Andrew Cagney
  2001-08-10 14:24             ` Jonathan Larmour
  0 siblings, 1 reply; 18+ messages in thread
From: Andrew Cagney @ 2001-08-09 18:05 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Elena Zannoni, gdb

> Maybe I didn't quite understand what was meant to happen then. In the case
> of:
> 
> 1: {
> 2: for (;;);
> 3: }
> 
> where is the compiler meant to mark the end of the first source line in the
> debug info? You are saying it is 1, not 2 as I previously had been
> assuming.


Ignore the source, worry about the instruction stream.  Say the 
generated code looks like:

	foo:
(a) 
	move sp to fp
(b) 
1 
jmp b1
(c) 
	nop
(d) 
	return

The function's source-and-line is at (a), the start of the real code is 
at (b).  If the frame (move sp to fp) were to be omitted, then both 
would be at (b). So refering to your code there should be:

	1(a)
	2(b)
	3(d) (if you're lucky)

If the debug info for 2 is ending up on (c) then, yes, I really think 
things in GCC are wrong.

Compare it to the equivalent MIPS code.


>> o       The SH has delay slots and the subsequent
>> features.


_Features_ not bugs :-)


> So this bug _would_ be revealed if we set a breakpoint on line 2 above,
> right?


No, a breakpoint at 2 should end up on (b).


>> The delay slot problem tends to only occure when a user explicitly
>> inserts a breakpoint at a specific address (or GCC gets nasty and starts
>> outputting source-and-line info that contains delay slots).
> 
> 
> So which source line _should_ the delay slot be associated with in the
> above example, if GCC is being nasty?


In the above example, it shouldn't.


>> Any way, the first problem is handed by fixing GCC  [:-)] 
> 
> 
> And I know even less about GCC than GDB. Oh dear.
> 
> 
>> The second problem is more interesting, targets handle delay slots by:
>> 
>> o       have code such as software
>> instruction-step detect and skip
>> both the jmp and the delay slot
>> 
>> o       have the target when doing hardware
>> single step skip both (I suspect
>> the SH does this)
> 
> 
> We've been doing both on our target.
> 
> 
>> o       have the hardware provide sufficient
>> information to allow GDB to detect
>> a delay-slot breakpoint.
>> 
>> If either of the first two options are taken (they are both reasonable!)
>> then it is a ``the user is always right'' situtation when they enter:
>> 
>> (gdb) break *address_of_delay_slot
>> 
>> This is because, in general, GDB can't tell if what looks like and
>> smells like a delay slot really is.  GDB just has to assume that the
>> USER (who is always right and in this case, since they are using
>> assembler level features, must understand the ISA's delay slot  [:-)] 
>> really is trying to debug something like:
>> 
>> jump bar
>> nop
>> .....
>> jump foo
>> bar: move r1 to r2
> 
> 
> Yuck, but I suppose it's possible. The implication of what you are saying
> is that it is up to the target to detect that the trap occured in a delay
> slot, and return the address of the delay slot instead of the reported
> address at the time of the exception. Right?


Possibly.  I think you're better off documenting this as a ``feature''. 
  If the user does this then they get what they deserve :-)

FWIW, things get quickly messy here.  Due to a bad case of history, both 
GDB and the remote protocol confuse the hardware program-counter with 
the more abstract stop/resume-address.  Eg, given:

	a:	jump foo
	b:	nop
		...
	foo:	

and a breakpoint on *b, then an architecture might represent/implement 
this in several different ways.  SPARC has:

	PC = b
	NPC = foo

a second target could have:

	PC = a
	status register indicates a delay slot implying PC is really B

(From memory this is what the MIPS does, restart after a breakpoint in a 
delay slot and you resume at the branch instruction)

In the case of the latter, you'd need to pretend that the PC is really 
at B and return that XOR have GDB modified to notice this case and have 
read_pc() return B.  Only, then you probably find that $pc has different 
values in different contexts (vis $fp on ARM).

Sigh

	Andrew


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

* Re: SH breakpoint problem
  2001-08-09 18:05           ` Andrew Cagney
@ 2001-08-10 14:24             ` Jonathan Larmour
  0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Larmour @ 2001-08-10 14:24 UTC (permalink / raw)
  To: egcs; +Cc: gdb

[snip]

Thanks to Kevin, Andrew and Elena for the help: after some private e-mail
with Elena, I'm now going to beat on GCC's door. There's still an issue if
people deliberately try to set a bp in a delay slot, but I'll leave that
for another day :-).

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


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

end of thread, other threads:[~2001-08-10 14:24 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-06 19:45 SH breakpoint problem Jonathan Larmour
2001-08-07  5:53 ` Jonathan Larmour
2001-08-07  7:26 ` Elena Zannoni
2001-08-07  7:33   ` Jonathan Larmour
2001-08-07  7:54     ` Elena Zannoni
2001-08-07  8:05       ` Jonathan Larmour
2001-08-09 14:49       ` Andrew Cagney
2001-08-09 16:52         ` Jonathan Larmour
2001-08-09 18:05           ` Andrew Cagney
2001-08-10 14:24             ` Jonathan Larmour
2001-08-07 15:42 ` Kevin Buettner
2001-08-07 21:54   ` Alexandre Oliva
2001-08-07 22:46     ` Kevin Buettner
2001-08-09 12:48       ` Jonathan Larmour
2001-08-09 13:29         ` Kevin Buettner
2001-08-09 14:05           ` Jonathan Larmour
2001-08-09 14:28             ` Andrew Cagney
2001-08-09 14:57             ` Kevin Buettner

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