Blame SOURCES/gdb-rhbz1420304-s390x-18of35.patch

e1d87d
commit 359b19bb24d048750aa5367ad56a33267300d1a8
e1d87d
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
e1d87d
Date:   Tue Jun 13 15:20:28 2017 +0200
e1d87d
e1d87d
    write_pieced_value: Transfer least significant bits into bit-field
e1d87d
    
e1d87d
    On big-endian targets, when targeting a bit-field, write_pieced_value
e1d87d
    currently transfers the source value's *most* significant bits to the
e1d87d
    target value, instead of its least significant bits.  This is fixed.
e1d87d
    
e1d87d
    In particular the fix adjusts the initial value of 'offset', which can now
e1d87d
    potentially be nonzero.  Thus the variable 'type_len' is renamed to
e1d87d
    'max_offset', to avoid confusion.  And for consistency, the affected logic
e1d87d
    that was mirrored in read_pieced_value is changed there in the same way.
e1d87d
    
e1d87d
    gdb/ChangeLog:
e1d87d
    
e1d87d
            * dwarf2loc.c (write_pieced_value): When writing to a bit-field,
e1d87d
            transfer the source value's least significant bits, instead of its
e1d87d
            lowest-addressed ones.  Rename type_len to max_offset.
e1d87d
            (read_pieced_value): Mirror above changes to write_pieced_value as
e1d87d
            applicable.
e1d87d
e1d87d
### a/gdb/ChangeLog
e1d87d
### b/gdb/ChangeLog
e1d87d
## -1,5 +1,13 @@
e1d87d
 2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
 
e1d87d
+	* dwarf2loc.c (write_pieced_value): When writing to a bit-field,
e1d87d
+	transfer the source value's least significant bits, instead of its
e1d87d
+	lowest-addressed ones.  Rename type_len to max_offset.
e1d87d
+	(read_pieced_value): Mirror above changes to write_pieced_value as
e1d87d
+	applicable.
e1d87d
+
e1d87d
+2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
+
e1d87d
 	* dwarf2loc.c (write_pieced_value): In DWARF_VALUE_MEMORY,
e1d87d
 	truncate full bytes from dest_offset_bits before using it as an
e1d87d
 	offset into the buffer.
e1d87d
--- a/gdb/dwarf2loc.c
e1d87d
+++ b/gdb/dwarf2loc.c
e1d87d
@@ -1756,12 +1756,11 @@ static void
e1d87d
 read_pieced_value (struct value *v)
e1d87d
 {
e1d87d
   int i;
e1d87d
-  long offset = 0;
e1d87d
+  LONGEST offset = 0, max_offset;
e1d87d
   ULONGEST bits_to_skip;
e1d87d
   gdb_byte *contents;
e1d87d
   struct piece_closure *c
e1d87d
     = (struct piece_closure *) value_computed_closure (v);
e1d87d
-  size_t type_len;
e1d87d
   size_t buffer_size = 0;
e1d87d
   std::vector<gdb_byte> buffer;
e1d87d
   int bits_big_endian
e1d87d
@@ -1778,12 +1777,12 @@ read_pieced_value (struct value *v)
e1d87d
     {
e1d87d
       bits_to_skip += (8 * value_offset (value_parent (v))
e1d87d
 		       + value_bitpos (v));
e1d87d
-      type_len = value_bitsize (v);
e1d87d
+      max_offset = value_bitsize (v);
e1d87d
     }
e1d87d
   else
e1d87d
-    type_len = 8 * TYPE_LENGTH (value_type (v));
e1d87d
+    max_offset = 8 * TYPE_LENGTH (value_type (v));
e1d87d
 
e1d87d
-  for (i = 0; i < c->n_pieces && offset < type_len; i++)
e1d87d
+  for (i = 0; i < c->n_pieces && offset < max_offset; i++)
e1d87d
     {
e1d87d
       struct dwarf_expr_piece *p = &c->pieces[i];
e1d87d
       size_t this_size, this_size_bits;
e1d87d
@@ -1798,20 +1797,13 @@ read_pieced_value (struct value *v)
e1d87d
 	  bits_to_skip -= this_size_bits;
e1d87d
 	  continue;
e1d87d
 	}
e1d87d
-      if (bits_to_skip > 0)
e1d87d
-	{
e1d87d
-	  dest_offset_bits = 0;
e1d87d
-	  source_offset_bits = bits_to_skip;
e1d87d
-	  this_size_bits -= bits_to_skip;
e1d87d
-	  bits_to_skip = 0;
e1d87d
-	}
e1d87d
-      else
e1d87d
-	{
e1d87d
-	  dest_offset_bits = offset;
e1d87d
-	  source_offset_bits = 0;
e1d87d
-	}
e1d87d
-      if (this_size_bits > type_len - offset)
e1d87d
-	this_size_bits = type_len - offset;
e1d87d
+      source_offset_bits = bits_to_skip;
e1d87d
+      this_size_bits -= bits_to_skip;
e1d87d
+      bits_to_skip = 0;
e1d87d
+      dest_offset_bits = offset;
e1d87d
+
e1d87d
+      if (this_size_bits > max_offset - offset)
e1d87d
+	this_size_bits = max_offset - offset;
e1d87d
 
e1d87d
       this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
e1d87d
       source_offset = source_offset_bits / 8;
e1d87d
@@ -1932,12 +1924,11 @@ static void
e1d87d
 write_pieced_value (struct value *to, struct value *from)
e1d87d
 {
e1d87d
   int i;
e1d87d
-  long offset = 0;
e1d87d
   ULONGEST bits_to_skip;
e1d87d
+  LONGEST offset = 0, max_offset;
e1d87d
   const gdb_byte *contents;
e1d87d
   struct piece_closure *c
e1d87d
     = (struct piece_closure *) value_computed_closure (to);
e1d87d
-  size_t type_len;
e1d87d
   size_t buffer_size = 0;
e1d87d
   std::vector<gdb_byte> buffer;
e1d87d
   int bits_big_endian
e1d87d
@@ -1949,12 +1940,20 @@ write_pieced_value (struct value *to, struct value *from)
e1d87d
     {
e1d87d
       bits_to_skip += (8 * value_offset (value_parent (to))
e1d87d
 		       + value_bitpos (to));
e1d87d
-      type_len = value_bitsize (to);
e1d87d
-    }
e1d87d
+      /* Use the least significant bits of FROM.  */
e1d87d
+      if (gdbarch_byte_order (get_type_arch (value_type (from)))
e1d87d
+	  == BFD_ENDIAN_BIG)
e1d87d
+	{
e1d87d
+	  max_offset = 8 * TYPE_LENGTH (value_type (from));
e1d87d
+	  offset = max_offset - value_bitsize (to);
e1d87d
+	}
e1d87d
+      else
e1d87d
+	max_offset = value_bitsize (to);
e1d87d
+   }
e1d87d
   else
e1d87d
-    type_len = 8 * TYPE_LENGTH (value_type (to));
e1d87d
+    max_offset = 8 * TYPE_LENGTH (value_type (to));
e1d87d
 
e1d87d
-  for (i = 0; i < c->n_pieces && offset < type_len; i++)
e1d87d
+  for (i = 0; i < c->n_pieces && offset < max_offset; i++)
e1d87d
     {
e1d87d
       struct dwarf_expr_piece *p = &c->pieces[i];
e1d87d
       size_t this_size_bits, this_size;
e1d87d
@@ -1968,20 +1967,13 @@ write_pieced_value (struct value *to, struct value *from)
e1d87d
 	  bits_to_skip -= this_size_bits;
e1d87d
 	  continue;
e1d87d
 	}
e1d87d
-      if (bits_to_skip > 0)
e1d87d
-	{
e1d87d
-	  dest_offset_bits = bits_to_skip;
e1d87d
-	  source_offset_bits = 0;
e1d87d
-	  this_size_bits -= bits_to_skip;
e1d87d
-	  bits_to_skip = 0;
e1d87d
-	}
e1d87d
-      else
e1d87d
-	{
e1d87d
-	  dest_offset_bits = 0;
e1d87d
-	  source_offset_bits = offset;
e1d87d
-	}
e1d87d
-      if (this_size_bits > type_len - offset)
e1d87d
-	this_size_bits = type_len - offset;
e1d87d
+      dest_offset_bits = bits_to_skip;
e1d87d
+      this_size_bits -= bits_to_skip;
e1d87d
+      bits_to_skip = 0;
e1d87d
+      source_offset_bits = offset;
e1d87d
+
e1d87d
+      if (this_size_bits > max_offset - offset)
e1d87d
+	this_size_bits = max_offset - offset;
e1d87d
 
e1d87d
       this_size = (this_size_bits + dest_offset_bits % 8 + 7) / 8;
e1d87d
       source_offset = source_offset_bits / 8;