Re: [PATCH 0/2] Support the new PPC476 processor

Thiago Jung Bauermann
2009-12-30T03:13:09Z

Hi Eli,

Thanks for the review!

On Fri 18 Dec 2009 08:21:50 Eli Zaretskii wrote:
> I have a few preliminary comments and questions about the proposed UI:
> > * Simple Hardware Watchpoints: Monitors accesses to a single data
> > address. For the PPC476, 2 of them are available provided that no
> > Range/Mask watchpoints are being used. There is also the possibility of
> > using conditions when monitoring the values. In this case, GDB will
> > place the condition inside a register, and the evaluation will be
> > hardware-accelerated, which will speed- up significantly the debugging
> > process. The PPC476 processor has two registers that can be used to
> > hardware-accelerate the condition evaluation.
> >
> > - Available GDB commands: [r|a]watch <variable> (rwatch/awatch/watch)
> > or [r|a]watch <variable> if <variable> == <4-bytes unsigned constant>
> >
> > - Usage example: awatch i / rwatch *0xbffff8e8 / watch i if i == 28
>
> Will GDB decide automatically whether to use hardware-accelerated
> conditions or the current implementation, whereby an unconditional
> hardware watchpoint is set, and when it breaks, GDB itself evaluates
> the condition? I think this should be done automatically.

Yes, GDB will use hardware-accelerated conditions automatically, when
available on the target.

> > * Range Hardware Watchpoints: Monitors accesses to an interval of data
> > addresses. For the 476, a single Range Hardware Watchpoint can be used
> > provided that no Simple/Mask watchpoints are being used.
> >
> > - Available GDB commands: [r|a]watch-range <address1>:<address2 |
> > +<uint length>>, where <address1> <= <address2>
> > (rwatch-range/awatch-range/watch- range)
> >
> > - Usage example: watch-range &i,&k / awatch-range
> > 0xbffff8e8,0xbffff8f8 / rwatch-range 0xbffff8e8,+8
>
> Why is there a need for a separate GDB command? What are the
> use-cases where the user would want to watch a region that is spanned
> by more than one (albeit large) variable? If such use-cases are
> infrequent enough or obscure, then we could simply use the normal
> watch commands, and support any corner use-cases with something like
>
> watch *0xbffff8e8@8
>
> using what is a normal GDB semantics for artificial arrays. IOW, no
> need for either the comma-separated list of 2 addresses or a separate
> command.

I agree that it is convenient to support ranged watchpoints with an
established GDB syntax. So I implemented that. If the user asks to watch an
array (natural or artificial) or struct, and ranged watchpoints are available
then it will use them automatically.

I'm reluctant to remove the watch-range command though, because with the
artificial array syntax it's not straightforward to say "watch len *bytes*
starting at addr". Using:

watch *addr@len

is not correct, since it will watch len *integers* starting at addr. To do
what he/she wants, the user will have to type:

watch *((char *) addr)@len

Compare with:

watch-range addr, +len

(or perhaps I'm missing a simpler way to use artificial arrays in the example
above..)

> > * Mask Hardware Watchpoints: Monitors accesses to data addresses that
> > match a specific pattern. For the 476, a single Mask Hardware Watchpoint
> > can be used provided that no Simple/Range watchpoints are being used.
> > Due to the processor's design, the precise data address of the watchpoint
> > trigger is not available, so the user must check the instruction that
> > caused the trigger (usually at PC - 4) to obtain such data address. With
> > such data address in hand, it's possible to tell if its contents have
> > changed.
> >
> > - Available GDB commands: [r|a]watch <variable | address> mask
> > <mask_value>
> >
> > - Usage example: watch i mask 0xffffff00 / awatch *0xbffff8e8 mask
> > 0xffffff00
>
> I'm not sure about the semantics of this: what exactly does the mask
> do? how does it modify the unmasked command for the same address?

The mask makes the processor ignore the address bits that are 0 in the mask
when matching the data access address. In the example above, the watchpoint
will hit whenever there's a memory access to an address that is equal to the
address of i, but ignoring the last eight bits in the comparison.
The PowerPC 440 user manual has an interesting example:

This comparison mode is useful for detecting accesses to a particular byte
address, when the accesses may be of various sizes. For example, if the
debugger is interested in detecting accesses to byte address 0x00000003,
then these accesses may occur due to a byte access to that specific address,
or due to a halfword access to address 0x00000002, or due to a word access
to address 0x00000000. By using address bit mask mode and specifying that
the low-order two bits of the address should be ignored (that is, setting
the address bit mask in DAC2 to 0xFFFFFFFC), the debugger can detect each of
these types of access to byte address 0x00000003.

> > * Range Hardware Breakpoint: Monitors an interval of instruction
> > addresses.
> >
> > - Available GDB commands: hbreak-range <address1>:<address2 |
> > +<unsigned int length>> where <address1> <= <address2> / hbreak-range
> > <line number start>:<line number end>
> >
> > - Usage example: hbreak-range 0x10000658,0x10000660 / hbreak-range
> > 0x10000658,+8 / hbreak-range 20,30
>
> Again, what are the use-cases where such breakpoints would be useful?

They don't seem to be useful for C-level debugging, but can be for assembly-
level debugging. For instance, if you have a block of code that has more than
one entrypoint and therefore you don't know where it will get jumped into, you
can put a ranged breakpoint to cover the entire block.
--
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center