Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Question: Checking register value in buffer
@ 2005-05-19  2:49 Joel Brobecker
  2005-05-19  3:03 ` Richard Henderson
  2005-05-19 16:41 ` Andrew Cagney
  0 siblings, 2 replies; 9+ messages in thread
From: Joel Brobecker @ 2005-05-19  2:49 UTC (permalink / raw)
  To: gdb-patches

Hello,

I'm wondering if there is a usual way for what I'm trying to do.
Basically, I have fetched a 64bit floating point register on alpha
using:

      regcache_cooked_read (current_regcache, (insn >> 21) & 0x1f, reg);

where reg is a ``char reg[8]''.

Now, I'd like to perform the following tests:

  zero          (reg & 0x7fff_ffff_ffff_ffff) == 0
  sign          (reg & 0x8000_0000_0000_0000) != 0

Right now, I'm juggling with each byte of the buffer, and doing checks
like this:

    fp_register_zero_p (char *buf)
    {
      return ((buf[1] & 0x0f) == 0 && buf[2] == 0 && buf[3] == 0
              && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0);

I thought about something like:

        LONGEST rav = extract_signed_integer (buf, 8)

and then do the test using integer arithmetics. But then I'm not guarantied
that LONGEST is at least 64bit long, am I.

How are these sort of checks usually done in GDB?

Thanks,
-- 
Joel


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

* Re: Question: Checking register value in buffer
  2005-05-19  2:49 Question: Checking register value in buffer Joel Brobecker
@ 2005-05-19  3:03 ` Richard Henderson
  2005-05-19  3:07   ` Joel Brobecker
  2005-05-19  3:26   ` Daniel Jacobowitz
  2005-05-19 16:41 ` Andrew Cagney
  1 sibling, 2 replies; 9+ messages in thread
From: Richard Henderson @ 2005-05-19  3:03 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Thu, May 19, 2005 at 12:04:44PM +1000, Joel Brobecker wrote:
>         LONGEST rav = extract_signed_integer (buf, 8)
> 
> and then do the test using integer arithmetics. But then I'm not guarantied
> that LONGEST is at least 64bit long, am I.

It had better be, or the rest of alpha_next_pc is broken too.

Since it isn't, or isn't reported to be, you might as well 
assume it is large enough.

> How are these sort of checks usually done in GDB?

In gcc-land we have a "need_64bit_hwint" bit in config.gcc, and it
is set for targets that require the equivalent of LONGEST be at 
least 64 bits, or we error out of configure.

Dunno what's done in gdb.


r~


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

* Re: Question: Checking register value in buffer
  2005-05-19  3:03 ` Richard Henderson
@ 2005-05-19  3:07   ` Joel Brobecker
  2005-05-19  3:23     ` Richard Henderson
  2005-05-19  3:26   ` Daniel Jacobowitz
  1 sibling, 1 reply; 9+ messages in thread
From: Joel Brobecker @ 2005-05-19  3:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gdb-patches

> On Thu, May 19, 2005 at 12:04:44PM +1000, Joel Brobecker wrote:
> >         LONGEST rav = extract_signed_integer (buf, 8)
> > 
> > and then do the test using integer arithmetics. But then I'm not guarantied
> > that LONGEST is at least 64bit long, am I.
> 
> It had better be, or the rest of alpha_next_pc is broken too.
> 
> Since it isn't, or isn't reported to be, you might as well 
> assume it is large enough.

Ah yes, of course.

In terms of computing the mask, I'm thinking of using something
like this:

  sign_mask = 1 << (sizeof (rav) * TARGET_CHAR_BIT - 1);
  zero_mask = sign_mask ^ -1;

Are there better ways of computing these masks?

> > How are these sort of checks usually done in GDB?
> 
> In gcc-land we have a "need_64bit_hwint" bit in config.gcc, and it
> is set for targets that require the equivalent of LONGEST be at 
> least 64 bits, or we error out of configure.
> 
> Dunno what's done in gdb.

I just noticed in extract_signed_integer() that we actually do a size
check before doing the extraction, so we would get an error if LONGEST
was not large enough.

Thanks,
-- 
Joel


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

* Re: Question: Checking register value in buffer
  2005-05-19  3:07   ` Joel Brobecker
@ 2005-05-19  3:23     ` Richard Henderson
  2005-05-19  3:33       ` Joel Brobecker
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2005-05-19  3:23 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Thu, May 19, 2005 at 12:48:57PM +1000, Joel Brobecker wrote:
> In terms of computing the mask, I'm thinking of using something
> like this:
> 
>   sign_mask = 1 << (sizeof (rav) * TARGET_CHAR_BIT - 1);

This confuses host and target notions.  You would have wanted
the *host* CHAR_BIT, since you're using the host sizeof.

>   zero_mask = sign_mask ^ -1;

This fails if rav is *wider* than 64-bits.

> Are there better ways of computing these masks?

How about just 

  sign = (LONGEST)1 << 63
  zero = sign - 1;



r~


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

* Re: Question: Checking register value in buffer
  2005-05-19  3:03 ` Richard Henderson
  2005-05-19  3:07   ` Joel Brobecker
@ 2005-05-19  3:26   ` Daniel Jacobowitz
  1 sibling, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2005-05-19  3:26 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Joel Brobecker, gdb-patches

On Wed, May 18, 2005 at 07:22:56PM -0700, Richard Henderson wrote:
> On Thu, May 19, 2005 at 12:04:44PM +1000, Joel Brobecker wrote:
> >         LONGEST rav = extract_signed_integer (buf, 8)
> > 
> > and then do the test using integer arithmetics. But then I'm not guarantied
> > that LONGEST is at least 64bit long, am I.
> 
> It had better be, or the rest of alpha_next_pc is broken too.
> 
> Since it isn't, or isn't reported to be, you might as well 
> assume it is large enough.
> 
> > How are these sort of checks usually done in GDB?
> 
> In gcc-land we have a "need_64bit_hwint" bit in config.gcc, and it
> is set for targets that require the equivalent of LONGEST be at 
> least 64 bits, or we error out of configure.
> 
> Dunno what's done in gdb.

Because GDB doesn't have the same performance concerns with LONGEST
that GCC does with H_W_I, it's the biggest thing we can find.  Joel,
the definitions in defs.h are pretty clear - it will only be smaller
than 64-bit if we're really strapped for a 64-bit type, and if that's
the case, there's no way you're loading 64-bit ELF files.

-- 
Daniel Jacobowitz
CodeSourcery, LLC


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

* Re: Question: Checking register value in buffer
  2005-05-19  3:23     ` Richard Henderson
@ 2005-05-19  3:33       ` Joel Brobecker
  2005-05-19  4:52         ` Richard Henderson
  2005-05-19  5:37         ` Daniel Jacobowitz
  0 siblings, 2 replies; 9+ messages in thread
From: Joel Brobecker @ 2005-05-19  3:33 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gdb-patches

> > In terms of computing the mask, I'm thinking of using something
> > like this:
> > 
> >   sign_mask = 1 << (sizeof (rav) * TARGET_CHAR_BIT - 1);
> 
> This confuses host and target notions.  You would have wanted
> the *host* CHAR_BIT, since you're using the host sizeof.

Ah yes, of course.

> >   zero_mask = sign_mask ^ -1;
> 
> This fails if rav is *wider* than 64-bits.
> 
> > Are there better ways of computing these masks?
> 
> How about just 
> 
>   sign = (LONGEST)1 << 63
>   zero = sign - 1;

Isn't this assument that LONGEST is exactly 64 bits? I think
extract_signed_integer expands the value held in the given buffer
to fit the size of LONGEST. Here is the implementation:

    LONGEST
    extract_signed_integer (const void *addr, int len)
    {
      LONGEST retval;
      const unsigned char *p;
      const unsigned char *startaddr = addr;
      const unsigned char *endaddr = startaddr + len;
    
      if (len > (int) sizeof (LONGEST))
        error (_("\
    That operation is not available on integers of more than %d bytes."),
               (int) sizeof (LONGEST));
    
      /* Start at the most significant end of the integer, and work towards
         the least significant.  */
      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        {
          p = startaddr;
          /* Do the sign extension once at the start.  */
          retval = ((LONGEST) * p ^ 0x80) - 0x80;
          for (++p; p < endaddr; ++p)
            retval = (retval << 8) | *p;
        }
      else
        {
          p = endaddr - 1;
          /* Do the sign extension once at the start.  */
          retval = ((LONGEST) * p ^ 0x80) - 0x80;
          for (--p; p >= startaddr; --p)
            retval = (retval << 8) | *p;
        }
      return retval;
    }

Using an example where we have len = 1 and sizeof LONGEST = 2, then
the extract from "0xff" would lead to "0xffff", no?

That's why I thought the little dance with sizeof and xor was necessary.

-- 
Joel


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

* Re: Question: Checking register value in buffer
  2005-05-19  3:33       ` Joel Brobecker
@ 2005-05-19  4:52         ` Richard Henderson
  2005-05-19  5:37         ` Daniel Jacobowitz
  1 sibling, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2005-05-19  4:52 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Thu, May 19, 2005 at 01:23:32PM +1000, Joel Brobecker wrote:
> >   sign = (LONGEST)1 << 63
> >   zero = sign - 1;
> 
> Isn't this assument that LONGEST is exactly 64 bits?

No.  Since you're extracting a signed 8-byte int, the bits
above 63 will all be replicas of bit 63.


r~


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

* Re: Question: Checking register value in buffer
  2005-05-19  3:33       ` Joel Brobecker
  2005-05-19  4:52         ` Richard Henderson
@ 2005-05-19  5:37         ` Daniel Jacobowitz
  1 sibling, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2005-05-19  5:37 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Richard Henderson, gdb-patches

On Thu, May 19, 2005 at 01:23:32PM +1000, Joel Brobecker wrote:
> Isn't this assument that LONGEST is exactly 64 bits? I think
> extract_signed_integer expands the value held in the given buffer
> to fit the size of LONGEST. Here is the implementation:

If you're confusing yourself with sign extension, use ULONGEST instead.
But this isn't the only thing that would break in GDB with 128-bit
types.  You really don't need to be this paranoid.

-- 
Daniel Jacobowitz
CodeSourcery, LLC


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

* Re: Question: Checking register value in buffer
  2005-05-19  2:49 Question: Checking register value in buffer Joel Brobecker
  2005-05-19  3:03 ` Richard Henderson
@ 2005-05-19 16:41 ` Andrew Cagney
  1 sibling, 0 replies; 9+ messages in thread
From: Andrew Cagney @ 2005-05-19 16:41 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

Joel Brobecker wrote:
> Hello,
> 
> I'm wondering if there is a usual way for what I'm trying to do.
> Basically, I have fetched a 64bit floating point register on alpha
> using:

Have you looked at doublest.[hc]?

>       regcache_cooked_read (current_regcache, (insn >> 21) & 0x1f, reg);
> 
> where reg is a ``char reg[8]''.
> 
> Now, I'd like to perform the following tests:
> 
>   zero          (reg & 0x7fff_ffff_ffff_ffff) == 0
>   sign          (reg & 0x8000_0000_0000_0000) != 0
> 
> Right now, I'm juggling with each byte of the buffer, and doing checks
> like this:
> 
>     fp_register_zero_p (char *buf)
>     {
>       return ((buf[1] & 0x0f) == 0 && buf[2] == 0 && buf[3] == 0
>               && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0);
> 
> I thought about something like:
> 
>         LONGEST rav = extract_signed_integer (buf, 8)
> 
> and then do the test using integer arithmetics. But then I'm not guarantied
> that LONGEST is at least 64bit long, am I.
> 
> How are these sort of checks usually done in GDB?
> 
> Thanks,


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

end of thread, other threads:[~2005-05-19 14:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-19  2:49 Question: Checking register value in buffer Joel Brobecker
2005-05-19  3:03 ` Richard Henderson
2005-05-19  3:07   ` Joel Brobecker
2005-05-19  3:23     ` Richard Henderson
2005-05-19  3:33       ` Joel Brobecker
2005-05-19  4:52         ` Richard Henderson
2005-05-19  5:37         ` Daniel Jacobowitz
2005-05-19  3:26   ` Daniel Jacobowitz
2005-05-19 16:41 ` Andrew Cagney

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