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]

Re: [patch] Remove BITS_BIG_ENDIAN from defs.h


Ulrich Weigand schrieb:
Markus Deuling wrote:

this patch removes BITS_BIG_ENDIAN from defs.h by replacing it with
its expression. The way to recognize endianess of a target is
gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG which is
widely used by most files.  So this macro is unnecessary.

As Dan and Eli pointed out, there *is* a difference between the two: - gdbarch_byte_order says whether in a multi-byte value, the least or most significant *byte* comes first - BITS_BIG_ENDIAN is intended to say whether in a bitfield, the least of most significant *bit* comes first

Looking at GCC, there are targets with big endian byte order but
little endian bit order (or vice versa), even though those are not supported in GDB today (or maybe they are but bitfields simply
do not work correctly).


Thus I think we should introduce a new gdbarch property to allow
to set the bit order.



Hi,

thank you very much for all of your valuable feedback. I rewrote the patch
and introduce a new gdbarch property bits_big_endian now to replace BITS_BIG_ENDIAN.

I tested this patch on both Little and Big Endian machine (x86/ppc) without regression.
If this patch is ok I'll post another one for the documentation. Ok to commit?

ChangeLog:

	* gdbarch.sh (function_list): Add new property bits_big_endian to
	gdbarch structure.
	* gdbarch.{c,h}: Regenerate.

	* value.c (struct value): Replace BITS_BIG_ENDIAN by
	gdbarch_bits_big_endian (comment).
	(unpack_field_as_long, modify_field): Likewise.
	* value.h: Likewise (comment).
	* valops.c (value_slice): Likewise.
	* valarith.c (value_subscript, value_bit_index): Likewise.
	* gdbtypes.h (field): Likewise (comment).
	* eval.c (evaluate_subexp_standard): Likewise.
	* dwarf2read.c (dwarf2_add_field): Likewise.
	* ada-lang.c (decode_packed_array, ada_value_primitive_packed_val)
	(move_bits, ada_value_assign, value_assign_to_component): Likewise.
	
	* defs.h (BITS_BIG_ENDIAN): Remove.




-- Markus Deuling GNU Toolchain for Linux on Cell BE deuling@de.ibm.com


diff -urpN src/gdb/ada-lang.c dev/gdb/ada-lang.c
--- src/gdb/ada-lang.c	2008-01-09 11:01:28.000000000 +0100
+++ dev/gdb/ada-lang.c	2008-01-15 08:02:37.000000000 +0100
@@ -1875,7 +1875,8 @@ decode_packed_array (struct value *arr)
       return NULL;
     }
 
-  if (BITS_BIG_ENDIAN && ada_is_modular_type (value_type (arr)))
+  if (gdbarch_bits_big_endian (current_gdbarch)
+      && ada_is_modular_type (value_type (arr)))
     {
        /* This is a (right-justified) modular type representing a packed
  	 array with no wrapper.  In order to interpret the value through
@@ -1998,7 +1999,7 @@ ada_value_primitive_packed_val (struct v
   int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
   /* Transmit bytes from least to most significant; delta is the direction
      the indices move.  */
-  int delta = BITS_BIG_ENDIAN ? -1 : 1;
+  int delta = gdbarch_bits_big_endian (current_gdbarch) ? -1 : 1;
 
   type = ada_check_typedef (type);
 
@@ -2047,7 +2048,7 @@ ada_value_primitive_packed_val (struct v
       memset (unpacked, 0, TYPE_LENGTH (type));
       return v;
     }
-  else if (BITS_BIG_ENDIAN)
+  else if (gdbarch_bits_big_endian (current_gdbarch))
     {
       src = len - 1;
       if (has_negatives (type)
@@ -2141,7 +2142,7 @@ move_bits (gdb_byte *target, int targ_of
   targ_offset %= HOST_CHAR_BIT;
   source += src_offset / HOST_CHAR_BIT;
   src_offset %= HOST_CHAR_BIT;
-  if (BITS_BIG_ENDIAN)
+  if (gdbarch_bits_big_endian (current_gdbarch))
     {
       accum = (unsigned char) *source;
       source += 1;
@@ -2229,7 +2230,7 @@ ada_value_assign (struct value *toval, s
         fromval = value_cast (type, fromval);
 
       read_memory (to_addr, buffer, len);
-      if (BITS_BIG_ENDIAN)
+      if (gdbarch_bits_big_endian (current_gdbarch))
         move_bits (buffer, value_bitpos (toval),
                    value_contents (fromval),
                    TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT -
@@ -2276,7 +2277,7 @@ value_assign_to_component (struct value 
   else
     bits = value_bitsize (component);
 
-  if (BITS_BIG_ENDIAN)
+  if (gdbarch_bits_big_endian (current_gdbarch))
     move_bits (value_contents_writeable (container) + offset_in_container, 
 	       value_bitpos (container) + bit_offset_in_container,
 	       value_contents (val),
diff -urpN src/gdb/defs.h dev/gdb/defs.h
--- src/gdb/defs.h	2008-01-11 13:28:02.000000000 +0100
+++ dev/gdb/defs.h	2008-01-15 08:04:32.000000000 +0100
@@ -1043,14 +1043,6 @@ enum { MAX_REGISTER_SIZE = 16 };
 #define HOST_CHAR_BIT TARGET_CHAR_BIT
 #endif
 
-/* The bit byte-order has to do just with numbering of bits in
-   debugging symbols and such.  Conceptually, it's quite separate
-   from byte/word byte order.  */
-
-#if !defined (BITS_BIG_ENDIAN)
-#define BITS_BIG_ENDIAN (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
-#endif
-
 /* In findvar.c.  */
 
 extern LONGEST extract_signed_integer (const gdb_byte *, int);
diff -urpN src/gdb/dwarf2read.c dev/gdb/dwarf2read.c
--- src/gdb/dwarf2read.c	2008-01-11 14:32:31.000000000 +0100
+++ dev/gdb/dwarf2read.c	2008-01-15 07:55:28.000000000 +0100
@@ -3502,7 +3502,7 @@ dwarf2_add_field (struct field_info *fip
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
 	{
-	  if (BITS_BIG_ENDIAN)
+	  if (gdbarch_bits_big_endian (current_gdbarch))
 	    {
 	      /* For big endian bits, the DW_AT_bit_offset gives the
 	         additional bit offset from the MSB of the containing
diff -urpN src/gdb/eval.c dev/gdb/eval.c
--- src/gdb/eval.c	2008-01-08 11:22:24.000000000 +0100
+++ dev/gdb/eval.c	2008-01-15 07:53:28.000000000 +0100
@@ -686,7 +686,7 @@ evaluate_subexp_standard (struct type *e
 	      for (; range_low <= range_high; range_low++)
 		{
 		  int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
-		  if (BITS_BIG_ENDIAN)
+		  if (gdbarch_bits_big_endian (current_gdbarch))
 		    bit_index = TARGET_CHAR_BIT - 1 - bit_index;
 		  valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
 		    |= 1 << bit_index;
diff -urpN src/gdb/gdbarch.c dev/gdb/gdbarch.c
--- src/gdb/gdbarch.c	2008-01-11 14:20:52.000000000 +0100
+++ dev/gdb/gdbarch.c	2008-01-15 08:04:34.000000000 +0100
@@ -130,6 +130,7 @@ struct gdbarch
 
      */
 
+  int bits_big_endian;
   int short_bit;
   int int_bit;
   int long_bit;
@@ -251,6 +252,7 @@ struct gdbarch startup_gdbarch =
   /*per-architecture data-pointers and swap regions */
   0, NULL, NULL,
   /* Multi-arch values */
+  0,  /* bits_big_endian */
   8 * sizeof (short),  /* short_bit */
   8 * sizeof (int),  /* int_bit */
   8 * sizeof (long),  /* long_bit */
@@ -382,6 +384,7 @@ gdbarch_alloc (const struct gdbarch_info
   gdbarch->target_desc = info->target_desc;
 
   /* Force the explicit initialization of these. */
+  gdbarch->bits_big_endian = (gdbarch->byte_order == BFD_ENDIAN_BIG);
   gdbarch->short_bit = 2*TARGET_CHAR_BIT;
   gdbarch->int_bit = 4*TARGET_CHAR_BIT;
   gdbarch->long_bit = 4*TARGET_CHAR_BIT;
@@ -480,6 +483,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   if (gdbarch->bfd_arch_info == NULL)
     fprintf_unfiltered (log, "\n\tbfd_arch_info");
   /* Check those that need to be defined for the given multi-arch level. */
+  /* Skip verify of bits_big_endian, invalid_p == 0 */
   /* Skip verify of short_bit, invalid_p == 0 */
   /* Skip verify of int_bit, invalid_p == 0 */
   /* Skip verify of long_bit, invalid_p == 0 */
@@ -648,6 +652,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: bfd_arch_info = %s\n",
                       gdbarch_bfd_arch_info (gdbarch)->printable_name);
   fprintf_unfiltered (file,
+                      "gdbarch_dump: bits_big_endian = %s\n",
+                      paddr_d (gdbarch->bits_big_endian));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: breakpoint_from_pc = <0x%lx>\n",
                       (long) gdbarch->breakpoint_from_pc);
   fprintf_unfiltered (file,
@@ -1060,6 +1067,23 @@ gdbarch_target_desc (struct gdbarch *gdb
 }
 
 int
+gdbarch_bits_big_endian (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Skip verify of bits_big_endian, invalid_p == 0 */
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_bits_big_endian called\n");
+  return gdbarch->bits_big_endian;
+}
+
+void
+set_gdbarch_bits_big_endian (struct gdbarch *gdbarch,
+                             int bits_big_endian)
+{
+  gdbarch->bits_big_endian = bits_big_endian;
+}
+
+int
 gdbarch_short_bit (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
diff -urpN src/gdb/gdbarch.h dev/gdb/gdbarch.h
--- src/gdb/gdbarch.h	2008-01-11 14:20:52.000000000 +0100
+++ dev/gdb/gdbarch.h	2008-01-15 08:04:28.000000000 +0100
@@ -71,6 +71,12 @@ extern const struct target_desc * gdbarc
 
 /* The following are initialized by the target dependent code. */
 
+/* The bit byte-order has to do just with numbering of bits in debugging symbols
+   and such.  Conceptually, it's quite separate from byte/word byte order. */
+
+extern int gdbarch_bits_big_endian (struct gdbarch *gdbarch);
+extern void set_gdbarch_bits_big_endian (struct gdbarch *gdbarch, int bits_big_endian);
+
 /* Number of bits in a char or unsigned char for the target machine.
    Just like CHAR_BIT in <limits.h> but describes the target machine.
    v:TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0:
diff -urpN src/gdb/gdbarch.sh dev/gdb/gdbarch.sh
--- src/gdb/gdbarch.sh	2008-01-11 14:20:52.000000000 +0100
+++ dev/gdb/gdbarch.sh	2008-01-15 08:04:22.000000000 +0100
@@ -343,6 +343,11 @@ i:int:byte_order:::BFD_ENDIAN_BIG
 i:enum gdb_osabi:osabi:::GDB_OSABI_UNKNOWN
 #
 i:const struct target_desc *:target_desc:::::::paddr_d ((long) gdbarch->target_desc)
+
+# The bit byte-order has to do just with numbering of bits in debugging symbols
+# and such.  Conceptually, it's quite separate from byte/word byte order.
+v:int:bits_big_endian:::0:(gdbarch->byte_order == BFD_ENDIAN_BIG)::0
+
 # Number of bits in a char or unsigned char for the target machine.
 # Just like CHAR_BIT in <limits.h> but describes the target machine.
 # v:TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0:
diff -urpN src/gdb/gdbtypes.h dev/gdb/gdbtypes.h
--- src/gdb/gdbtypes.h	2008-01-01 23:53:10.000000000 +0100
+++ dev/gdb/gdbtypes.h	2008-01-15 07:52:38.000000000 +0100
@@ -403,8 +403,8 @@ struct main_type
     {
       /* Position of this field, counting in bits from start of
 	 containing structure.
-	 For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
-	 For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
+	 For gdbarch_bits_big_endian=1 targets, it is the bit offset to the MSB.
+	 For gdbarch_bits_big_endian=0 targets, it is the bit offset to the LSB.
 	 For a range bound or enum value, this is the value itself. */
 
       int bitpos;
diff -urpN src/gdb/valarith.c dev/gdb/valarith.c
--- src/gdb/valarith.c	2008-01-08 11:22:24.000000000 +0100
+++ dev/gdb/valarith.c	2008-01-15 07:51:31.000000000 +0100
@@ -230,7 +230,8 @@ value_subscript (struct value *array, st
       offset = index / TARGET_CHAR_BIT;
       byte = *((char *) value_contents (array) + offset);
       bit_index = index % TARGET_CHAR_BIT;
-      byte >>= (BITS_BIG_ENDIAN ? TARGET_CHAR_BIT - 1 - bit_index : bit_index);
+      byte >>= (gdbarch_bits_big_endian (current_gdbarch) ?
+		TARGET_CHAR_BIT - 1 - bit_index : bit_index);
       v = value_from_longest (LA_BOOL_TYPE, byte & 1);
       set_value_bitpos (v, bit_index);
       set_value_bitsize (v, 1);
@@ -1573,7 +1574,7 @@ value_bit_index (struct type *type, cons
   word = unpack_long (builtin_type_unsigned_char,
 		      valaddr + (rel_index / TARGET_CHAR_BIT));
   rel_index %= TARGET_CHAR_BIT;
-  if (BITS_BIG_ENDIAN)
+  if (gdbarch_bits_big_endian (current_gdbarch))
     rel_index = TARGET_CHAR_BIT - 1 - rel_index;
   return (word >> rel_index) & 1;
 }
diff -urpN src/gdb/valops.c dev/gdb/valops.c
--- src/gdb/valops.c	2008-01-08 11:22:24.000000000 +0100
+++ dev/gdb/valops.c	2008-01-15 07:28:43.000000000 +0100
@@ -2743,7 +2743,7 @@ value_slice (struct value *array, int lo
 	  else if (element > 0)
 	    {
 	      int j = i % TARGET_CHAR_BIT;
-	      if (BITS_BIG_ENDIAN)
+	      if (gdbarch_bits_big_endian (current_gdbarch))
 		j = TARGET_CHAR_BIT - 1 - j;
 	      value_contents_raw (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
 	    }
diff -urpN src/gdb/value.c dev/gdb/value.c
--- src/gdb/value.c	2008-01-08 11:22:24.000000000 +0100
+++ dev/gdb/value.c	2008-01-15 07:26:01.000000000 +0100
@@ -72,8 +72,8 @@ struct value
   int bitsize;
 
   /* Only used for bitfields; position of start of field.  For
-     BITS_BIG_ENDIAN=0 targets, it is the position of the LSB.  For
-     BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */
+     gdbarch_bits_big_endian=0 targets, it is the position of the LSB.  For
+     gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */
   int bitpos;
 
   /* Frame register value is relative to.  This will be described in
@@ -1481,7 +1481,7 @@ unpack_field_as_long (struct type *type,
 
   /* Extract bits.  See comment above. */
 
-  if (BITS_BIG_ENDIAN)
+  if (gdbarch_bits_big_endian (current_gdbarch))
     lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
   else
     lsbcount = (bitpos % 8);
@@ -1537,7 +1537,7 @@ modify_field (gdb_byte *addr, LONGEST fi
   oword = extract_unsigned_integer (addr, sizeof oword);
 
   /* Shifting for bit field depends on endianness of the target machine.  */
-  if (BITS_BIG_ENDIAN)
+  if (gdbarch_bits_big_endian (current_gdbarch))
     bitpos = sizeof (oword) * 8 - bitpos - bitsize;
 
   oword &= ~(mask << bitpos);
diff -urpN src/gdb/value.h dev/gdb/value.h
--- src/gdb/value.h	2008-01-08 11:22:24.000000000 +0100
+++ dev/gdb/value.h	2008-01-15 07:27:58.000000000 +0100
@@ -62,8 +62,8 @@ extern int value_bitsize (struct value *
 extern void set_value_bitsize (struct value *, int bit);
 
 /* Only used for bitfields; position of start of field.  For
-   BITS_BIG_ENDIAN=0 targets, it is the position of the LSB.  For
-   BITS_BIG_ENDIAN=1 targets, it is the position of the MSB.  */
+   gdbarch_bits_big_endian=0 targets, it is the position of the LSB.  For
+   gdbarch_bits_big_endian=1 targets, it is the position of the MSB.  */
 
 extern int value_bitpos (struct value *);
 extern void set_value_bitpos (struct value *, int bit);


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