This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA/commit] Problem assigning big-endian bitfields (Ada)
- From: Paul Hilfinger <Hilfinger at adacore dot com>
- To: gdb-patches at sourceware dot org
- Date: Fri, 23 May 2008 15:59:10 -0400 (EDT)
- Subject: [RFA/commit] Problem assigning big-endian bitfields (Ada)
- Reply-to: Hilfinger at adacore dot com
Recent changes in GNAT uncovered an error in some code that assigns
to bitfields in Ada programs. Specifically, on big-endian machines, the
assignment works only when the source has a bitsize of 0 (indicating an
unpacked quantity).
A note of explanation: there is similar bit-assigning machinery in core
GDB, but it applies only to bitfields whose size is <= that of LONGEST.
Ada can actually pack records (structs) into bitfields, which required
a more general function. This capability does not appear to be used for
other languages, and at the time we introduced it, we decided to be
conservative about introducing it into the core. However, it would probably
make sense in the future to fold our move_bits routine into value_assign
Ran the testsuite without new errors on Linux. I will commit this in a week
in the absence of complaint.
Paul Hilfinger
AdaCore Consultant
Changelog:
2008-05-23 Paul N. Hilfinger <hilfingr@adacore.com>
* ada-lang.c (ada_value_assign): Correct big-endian case to take into
account the bitsize of the 'from' operand.
Index: gdb/ada-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-lang.c,v
retrieving revision 1.147
diff -u -p -r1.147 ada-lang.c
--- gdb/ada-lang.c 22 May 2008 17:00:07 -0000 1.147
+++ gdb/ada-lang.c 23 May 2008 19:56:30 -0000
@@ -2252,6 +2252,7 @@ ada_value_assign (struct value *toval, s
{
int len = (value_bitpos (toval)
+ bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ int from_size;
char *buffer = (char *) alloca (len);
struct value *val;
CORE_ADDR to_addr = VALUE_ADDRESS (toval) + value_offset (toval);
@@ -2260,11 +2261,12 @@ ada_value_assign (struct value *toval, s
fromval = value_cast (type, fromval);
read_memory (to_addr, buffer, len);
+ from_size = value_bitsize (fromval);
+ if (from_size == 0)
+ from_size = TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT;
if (gdbarch_bits_big_endian (current_gdbarch))
move_bits (buffer, value_bitpos (toval),
- value_contents (fromval),
- TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT -
- bits, bits);
+ value_contents (fromval), from_size - bits, bits);
else
move_bits (buffer, value_bitpos (toval), value_contents (fromval),
0, bits);