This is the mail archive of the mailing list for the GDB project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

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


+2008-06-06  Paul N. Hilfinger  <>
+	* 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);
         move_bits (buffer, value_bitpos (toval), value_contents (fromval),
                    0, bits);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]