From: Luis Machado <lgustavo@codesourcery.com>
To: Pedro Alves <alves.ped@gmail.com>,
"'gdb-patches@sourceware.org'" <gdb-patches@sourceware.org>
Subject: Re: [PATCH] MIPS bit field failures in gdb.base/store.exp
Date: Mon, 29 Sep 2014 17:35:00 -0000 [thread overview]
Message-ID: <54299847.7010202@codesourcery.com> (raw)
In-Reply-To: <54295EEB.30009@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3598 bytes --]
On 09/29/2014 10:30 AM, Pedro Alves wrote:
> On 09/29/2014 01:36 PM, Luis Machado wrote:
>> Hi,
>>
>> On 09/26/2014 12:16 PM, Pedro Alves wrote:
>>> On 09/25/2014 08:31 PM, Luis Machado wrote:
>>>
>>>> ping! Any ideas on different approaches suitable for this problem or is
>>>> the proposed fix ok (with either passing a value struct or a bit size)?
>>>
>>> Sorry, it's not easy to have a quick opinion without thinking this
>>> through...
>>>
>>> So, in value_assign, the case in question, we see:
>>>
>>> gdbarch = get_frame_arch (frame);
>>> if (gdbarch_convert_register_p (gdbarch, VALUE_REGNUM (toval), type))
>>> {
>>> /* If TOVAL is a special machine register requiring
>>> conversion of program values to a special raw
>>> format. */
>>> gdbarch_value_to_register (gdbarch, frame,
>>> VALUE_REGNUM (toval), type,
>>> value_contents (fromval));
>>> }
>>>
>>> Notice how gdbarch_value_to_register takes the fromval's contents
>>> as a buffer, only, and isn't passed down anything that would make it
>>> possible to find out whether it's writing to a bitfield, so that
>>> the implementation could do a read-modify-write itself and
>>> write to the proper bitfield offset.
>>>
>>> So, it seems to me that until we find an arch that needs to handle
>>> bitfields especially (I'm having trouble imagining why that
>>> would be necessary), we should just change value_assign's
>>> lval_register handling from:
>>>
>>> if (gdbarch_convert_register_p (gdbarch, VALUE_REGNUM (toval), type))
>>> {
>>> gdbarch_value_to_register ();
>>> }
>>> else
>>> {
>>> if (value_bitsize (toval))
>>> {
>>> // read-modify-write
>>> }
>>> else
>>> {
>>> put_frame_register_bytes ();
>>> }
>>> }
>>>
>>> to:
>>>
>>> if (value_bitsize (toval))
>>> {
>>> // read-modify-write
>>> }
>>> else
>>> {
>>> if (gdbarch_convert_register_p (gdbarch, VALUE_REGNUM (toval), type))
>>> {
>>> gdbarch_value_to_register ();
>>> }
>>> else
>>> {
>>> put_frame_register_bytes ();
>>> }
>>> }
>>
>
>> Though a bit less generic, that also seems to be a reasonable solution
>> for now, and it fixes the failures i saw for MIPS.
>
> The proper solution for an arch that needs to treat bitfields differently
> might well be to do without gdbarch_convert_register_p and change
> gdbarch_value_to_register's parameters to
> 'gdbarch_value_to_register(gdbarch, toval, fromval)', and rename it
> to gdbarch_register_assign while at it, as it's only called by value_assign.
>
> Like:
>
> if (gdbarch_register_assign_p (gdbarch))
> {
> gdbarch_register_assign (gdbarch, toval, fromval);
> }
> else
> {
> // default fallback
> }
>
> (Or install the fallback code as fallback gdbarch_register_assign
> implementation and then just call gdbarch_register_assign directly.)
>
> Seems unnecessary to do until we find a user that wants to treat
> bitfields differently though. Or viewed another way, we're discussing
> what that "default fallback" code should look like. :-)
>
>> Out of the top of my
>> head i also don't recall a target that handles bit fields in a special
>> way. Should i go with this patch for the next submission
>
> Yes, please.
>
>> or do you want to author it?
>
> Nope.
How about the following small patch?
[-- Attachment #2: mips_bit_field.diff --]
[-- Type: text/x-patch, Size: 3399 bytes --]
2014-09-29 Luis Machado <lgustavo@codesourcery.com>
gdb/
* valops.c (value_assign): Check for bit field assignments
before calling architecture-specific register value
conversion functions.
diff --git a/gdb/valops.c b/gdb/valops.c
index e1decf0..f177907 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1112,52 +1112,54 @@ value_assign (struct value *toval, struct value *fromval)
error (_("Value being assigned to is no longer active."));
gdbarch = get_frame_arch (frame);
- if (gdbarch_convert_register_p (gdbarch, VALUE_REGNUM (toval), type))
+
+ if (value_bitsize (toval))
{
- /* If TOVAL is a special machine register requiring
- conversion of program values to a special raw
- format. */
- gdbarch_value_to_register (gdbarch, frame,
- VALUE_REGNUM (toval), type,
- value_contents (fromval));
+ struct value *parent = value_parent (toval);
+ int offset = value_offset (parent) + value_offset (toval);
+ int changed_len;
+ gdb_byte buffer[sizeof (LONGEST)];
+ int optim, unavail;
+
+ changed_len = (value_bitpos (toval)
+ + value_bitsize (toval)
+ + HOST_CHAR_BIT - 1)
+ / HOST_CHAR_BIT;
+
+ if (changed_len > (int) sizeof (LONGEST))
+ error (_("Can't handle bitfields which "
+ "don't fit in a %d bit word."),
+ (int) sizeof (LONGEST) * HOST_CHAR_BIT);
+
+ if (!get_frame_register_bytes (frame, value_reg, offset,
+ changed_len, buffer,
+ &optim, &unavail))
+ {
+ if (optim)
+ throw_error (OPTIMIZED_OUT_ERROR,
+ _("value has been optimized out"));
+ if (unavail)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("value is not available"));
+ }
+
+ modify_field (type, buffer, value_as_long (fromval),
+ value_bitpos (toval), value_bitsize (toval));
+
+ put_frame_register_bytes (frame, value_reg, offset,
+ changed_len, buffer);
}
else
{
- if (value_bitsize (toval))
+ if (gdbarch_convert_register_p (gdbarch, VALUE_REGNUM (toval),
+ type))
{
- struct value *parent = value_parent (toval);
- int offset = value_offset (parent) + value_offset (toval);
- int changed_len;
- gdb_byte buffer[sizeof (LONGEST)];
- int optim, unavail;
-
- changed_len = (value_bitpos (toval)
- + value_bitsize (toval)
- + HOST_CHAR_BIT - 1)
- / HOST_CHAR_BIT;
-
- if (changed_len > (int) sizeof (LONGEST))
- error (_("Can't handle bitfields which "
- "don't fit in a %d bit word."),
- (int) sizeof (LONGEST) * HOST_CHAR_BIT);
-
- if (!get_frame_register_bytes (frame, value_reg, offset,
- changed_len, buffer,
- &optim, &unavail))
- {
- if (optim)
- throw_error (OPTIMIZED_OUT_ERROR,
- _("value has been optimized out"));
- if (unavail)
- throw_error (NOT_AVAILABLE_ERROR,
- _("value is not available"));
- }
-
- modify_field (type, buffer, value_as_long (fromval),
- value_bitpos (toval), value_bitsize (toval));
-
- put_frame_register_bytes (frame, value_reg, offset,
- changed_len, buffer);
+ /* If TOVAL is a special machine register requiring
+ conversion of program values to a special raw
+ format. */
+ gdbarch_value_to_register (gdbarch, frame,
+ VALUE_REGNUM (toval), type,
+ value_contents (fromval));
}
else
{
next prev parent reply other threads:[~2014-09-29 17:35 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-12 20:11 Luis Machado
2014-09-19 16:45 ` Luis Machado
2014-09-19 17:12 ` Pedro Alves
2014-09-19 17:39 ` Luis Machado
2014-09-25 19:32 ` Luis Machado
2014-09-26 15:45 ` Pedro Alves
2014-09-29 12:36 ` Luis Machado
2014-09-29 13:30 ` Pedro Alves
2014-09-29 17:35 ` Luis Machado [this message]
2014-09-30 11:00 ` Pedro Alves
2014-10-03 11:23 ` Luis Machado
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54299847.7010202@codesourcery.com \
--to=lgustavo@codesourcery.com \
--cc=alves.ped@gmail.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox