[RFA/commit] Problem assigning big-endian bitfields (Ada)

Paul Hilfinger Hilfinger@adacore.com
Fri Jun 6 07:06:00 GMT 2008


I have committed this patch, as previously indicated.

Paul Hilfinger

------------------------------------------------------------

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-06-06  Paul N. Hilfinger  <hilfinger@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.148
diff -u -p -r1.148 ada-lang.c
--- gdb/ada-lang.c	27 May 2008 19:29:51 -0000	1.148
+++ gdb/ada-lang.c	6 Jun 2008 06:09:59 -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);



More information about the Gdb-patches mailing list