This is the mail archive of the gdb-patches@sourceware.org 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]

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


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);


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