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

e1d87d
commit 55acdf2242372ae52abb25c80db8e75df5578b23
e1d87d
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
e1d87d
Date:   Tue Jun 13 15:20:32 2017 +0200
e1d87d
e1d87d
    read/write_pieced_value: Merge into one function
e1d87d
    
e1d87d
    Since read_pieced_value and write_pieced_value share significant logic,
e1d87d
    this patch merges them into a single function rw_pieced_value.
e1d87d
    
e1d87d
    gdb/ChangeLog:
e1d87d
    
e1d87d
            * dwarf2loc.c (rw_pieced_value): New.  Merge logic from...
e1d87d
            (read_pieced_value, write_pieced_value): ...here.  Reduce to
e1d87d
            wrappers that just call rw_pieced_value.
e1d87d
e1d87d
### a/gdb/ChangeLog
e1d87d
### b/gdb/ChangeLog
e1d87d
## -1,5 +1,11 @@
e1d87d
 2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
 
e1d87d
+	* dwarf2loc.c (rw_pieced_value): New.  Merge logic from...
e1d87d
+	(read_pieced_value, write_pieced_value): ...here.  Reduce to
e1d87d
+	wrappers that just call rw_pieced_value.
e1d87d
+
e1d87d
+2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
+
e1d87d
 	* dwarf2loc.c (write_pieced_value): When writing the data for a
e1d87d
 	memory piece, use write_memory_with_notification instead of
e1d87d
 	write_memory.
e1d87d
--- a/gdb/dwarf2loc.c
e1d87d
+++ b/gdb/dwarf2loc.c
e1d87d
@@ -1761,31 +1761,55 @@ bits_to_bytes (ULONGEST start, ULONGEST n_bits)
e1d87d
   return (start % 8 + n_bits + 7) / 8;
e1d87d
 }
e1d87d
 
e1d87d
+/* Read or write a pieced value V.  If FROM != NULL, operate in "write
e1d87d
+   mode": copy FROM into the pieces comprising V.  If FROM == NULL,
e1d87d
+   operate in "read mode": fetch the contents of the (lazy) value V by
e1d87d
+   composing it from its pieces.  */
e1d87d
+
e1d87d
 static void
e1d87d
-read_pieced_value (struct value *v)
e1d87d
+rw_pieced_value (struct value *v, struct value *from)
e1d87d
 {
e1d87d
   int i;
e1d87d
   LONGEST offset = 0, max_offset;
e1d87d
   ULONGEST bits_to_skip;
e1d87d
-  gdb_byte *contents;
e1d87d
+  gdb_byte *v_contents;
e1d87d
+  const gdb_byte *from_contents;
e1d87d
   struct piece_closure *c
e1d87d
     = (struct piece_closure *) value_computed_closure (v);
e1d87d
   std::vector<gdb_byte> buffer;
e1d87d
   int bits_big_endian
e1d87d
     = gdbarch_bits_big_endian (get_type_arch (value_type (v)));
e1d87d
 
e1d87d
-  if (value_type (v) != value_enclosing_type (v))
e1d87d
-    internal_error (__FILE__, __LINE__,
e1d87d
-		    _("Should not be able to create a lazy value with "
e1d87d
-		      "an enclosing type"));
e1d87d
+  if (from != NULL)
e1d87d
+    {
e1d87d
+      from_contents = value_contents (from);
e1d87d
+      v_contents = NULL;
e1d87d
+    }
e1d87d
+  else
e1d87d
+    {
e1d87d
+      if (value_type (v) != value_enclosing_type (v))
e1d87d
+	internal_error (__FILE__, __LINE__,
e1d87d
+			_("Should not be able to create a lazy value with "
e1d87d
+			  "an enclosing type"));
e1d87d
+      v_contents = value_contents_raw (v);
e1d87d
+      from_contents = NULL;
e1d87d
+    }
e1d87d
 
e1d87d
-  contents = value_contents_raw (v);
e1d87d
   bits_to_skip = 8 * value_offset (v);
e1d87d
   if (value_bitsize (v))
e1d87d
     {
e1d87d
       bits_to_skip += (8 * value_offset (value_parent (v))
e1d87d
 		       + value_bitpos (v));
e1d87d
-      max_offset = value_bitsize (v);
e1d87d
+      if (from != NULL
e1d87d
+	  && (gdbarch_byte_order (get_type_arch (value_type (from)))
e1d87d
+	      == BFD_ENDIAN_BIG))
e1d87d
+	{
e1d87d
+	  /* Use the least significant bits of FROM.  */
e1d87d
+	  max_offset = 8 * TYPE_LENGTH (value_type (from));
e1d87d
+	  offset = max_offset - value_bitsize (v);
e1d87d
+	}
e1d87d
+      else
e1d87d
+	max_offset = value_bitsize (v);
e1d87d
     }
e1d87d
   else
e1d87d
     max_offset = 8 * TYPE_LENGTH (value_type (v));
e1d87d
@@ -1797,13 +1821,12 @@ read_pieced_value (struct value *v)
e1d87d
   for (; 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
+      size_t this_size_bits, this_size;
e1d87d
 
e1d87d
       this_size_bits = p->size - bits_to_skip;
e1d87d
       if (this_size_bits > max_offset - offset)
e1d87d
 	this_size_bits = max_offset - offset;
e1d87d
 
e1d87d
-      /* Copy from the source to DEST_BUFFER.  */
e1d87d
       switch (p->location)
e1d87d
 	{
e1d87d
 	case DWARF_VALUE_REGISTER:
e1d87d
@@ -1826,39 +1849,137 @@ read_pieced_value (struct value *v)
e1d87d
 	    this_size = bits_to_bytes (bits_to_skip, this_size_bits);
e1d87d
 	    buffer.reserve (this_size);
e1d87d
 
e1d87d
-	    if (!get_frame_register_bytes (frame, gdb_regnum,
e1d87d
-					   bits_to_skip / 8,
e1d87d
-					   this_size, buffer.data (),
e1d87d
-					   &optim, &unavail))
e1d87d
+	    if (from == NULL)
e1d87d
 	      {
e1d87d
-		if (optim)
e1d87d
-		  mark_value_bits_optimized_out (v, offset, this_size_bits);
e1d87d
-		if (unavail)
e1d87d
-		  mark_value_bits_unavailable (v, offset, this_size_bits);
e1d87d
-		break;
e1d87d
+		/* Read mode.  */
e1d87d
+		if (!get_frame_register_bytes (frame, gdb_regnum,
e1d87d
+					       bits_to_skip / 8,
e1d87d
+					       this_size, buffer.data (),
e1d87d
+					       &optim, &unavail))
e1d87d
+		  {
e1d87d
+		    if (optim)
e1d87d
+		      mark_value_bits_optimized_out (v, offset,
e1d87d
+						     this_size_bits);
e1d87d
+		    if (unavail)
e1d87d
+		      mark_value_bits_unavailable (v, offset,
e1d87d
+						   this_size_bits);
e1d87d
+		    break;
e1d87d
+		  }
e1d87d
+
e1d87d
+		copy_bitwise (v_contents, offset,
e1d87d
+			      buffer.data (), bits_to_skip % 8,
e1d87d
+			      this_size_bits, bits_big_endian);
e1d87d
+	      }
e1d87d
+	    else
e1d87d
+	      {
e1d87d
+		/* Write mode.  */
e1d87d
+		if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
e1d87d
+		  {
e1d87d
+		    /* Data is copied non-byte-aligned into the register.
e1d87d
+		       Need some bits from original register value.  */
e1d87d
+		    get_frame_register_bytes (frame, gdb_regnum,
e1d87d
+					      bits_to_skip / 8,
e1d87d
+					      this_size, buffer.data (),
e1d87d
+					      &optim, &unavail);
e1d87d
+		    if (optim)
e1d87d
+		      throw_error (OPTIMIZED_OUT_ERROR,
e1d87d
+				   _("Can't do read-modify-write to "
e1d87d
+				     "update bitfield; containing word "
e1d87d
+				     "has been optimized out"));
e1d87d
+		    if (unavail)
e1d87d
+		      throw_error (NOT_AVAILABLE_ERROR,
e1d87d
+				   _("Can't do read-modify-write to "
e1d87d
+				     "update bitfield; containing word "
e1d87d
+				     "is unavailable"));
e1d87d
+		  }
e1d87d
+
e1d87d
+		copy_bitwise (buffer.data (), bits_to_skip % 8,
e1d87d
+			      from_contents, offset,
e1d87d
+			      this_size_bits, bits_big_endian);
e1d87d
+		put_frame_register_bytes (frame, gdb_regnum,
e1d87d
+					  bits_to_skip / 8,
e1d87d
+					  this_size, buffer.data ());
e1d87d
 	      }
e1d87d
-	    copy_bitwise (contents, offset,
e1d87d
-			  buffer.data (), bits_to_skip % 8,
e1d87d
-			  this_size_bits, bits_big_endian);
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
 	case DWARF_VALUE_MEMORY:
e1d87d
-	  bits_to_skip += p->offset;
e1d87d
-	  this_size = bits_to_bytes (bits_to_skip, this_size_bits);
e1d87d
-	  buffer.reserve (this_size);
e1d87d
-
e1d87d
-	  read_value_memory (v, offset,
e1d87d
-			     p->v.mem.in_stack_memory,
e1d87d
-			     p->v.mem.addr + bits_to_skip / 8,
e1d87d
-			     buffer.data (), this_size);
e1d87d
-	  copy_bitwise (contents, offset,
e1d87d
-			buffer.data (), bits_to_skip % 8,
e1d87d
-			this_size_bits, bits_big_endian);
e1d87d
+	  {
e1d87d
+	    bits_to_skip += p->offset;
e1d87d
+
e1d87d
+	    CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
e1d87d
+
e1d87d
+	    if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
e1d87d
+		&& offset % 8 == 0)
e1d87d
+	      {
e1d87d
+		/* Everything is byte-aligned; no buffer needed.  */
e1d87d
+		if (from != NULL)
e1d87d
+		  write_memory_with_notification (start_addr,
e1d87d
+						  (from_contents
e1d87d
+						   + offset / 8),
e1d87d
+						  this_size_bits / 8);
e1d87d
+		else
e1d87d
+		  read_value_memory (v, offset,
e1d87d
+				     p->v.mem.in_stack_memory,
e1d87d
+				     p->v.mem.addr + bits_to_skip / 8,
e1d87d
+				     v_contents + offset / 8,
e1d87d
+				     this_size_bits / 8);
e1d87d
+		break;
e1d87d
+	      }
e1d87d
+
e1d87d
+	    this_size = bits_to_bytes (bits_to_skip, this_size_bits);
e1d87d
+	    buffer.reserve (this_size);
e1d87d
+
e1d87d
+	    if (from == NULL)
e1d87d
+	      {
e1d87d
+		/* Read mode.  */
e1d87d
+		read_value_memory (v, offset,
e1d87d
+				   p->v.mem.in_stack_memory,
e1d87d
+				   p->v.mem.addr + bits_to_skip / 8,
e1d87d
+				   buffer.data (), this_size);
e1d87d
+		copy_bitwise (v_contents, offset,
e1d87d
+			      buffer.data (), bits_to_skip % 8,
e1d87d
+			      this_size_bits, bits_big_endian);
e1d87d
+	      }
e1d87d
+	    else
e1d87d
+	      {
e1d87d
+		/* Write mode.  */
e1d87d
+		if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
e1d87d
+		  {
e1d87d
+		    if (this_size <= 8)
e1d87d
+		      {
e1d87d
+			/* Perform a single read for small sizes.  */
e1d87d
+			read_memory (start_addr, buffer.data (),
e1d87d
+				     this_size);
e1d87d
+		      }
e1d87d
+		    else
e1d87d
+		      {
e1d87d
+			/* Only the first and last bytes can possibly have
e1d87d
+			   any bits reused.  */
e1d87d
+			read_memory (start_addr, buffer.data (), 1);
e1d87d
+			read_memory (start_addr + this_size - 1,
e1d87d
+				     &buffer[this_size - 1], 1);
e1d87d
+		      }
e1d87d
+		  }
e1d87d
+
e1d87d
+		copy_bitwise (buffer.data (), bits_to_skip % 8,
e1d87d
+			      from_contents, offset,
e1d87d
+			      this_size_bits, bits_big_endian);
e1d87d
+		write_memory_with_notification (start_addr,
e1d87d
+						buffer.data (),
e1d87d
+						this_size);
e1d87d
+	      }
e1d87d
+	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
 	case DWARF_VALUE_STACK:
e1d87d
 	  {
e1d87d
+	    if (from != NULL)
e1d87d
+	      {
e1d87d
+		mark_value_bits_optimized_out (v, offset, this_size_bits);
e1d87d
+		break;
e1d87d
+	      }
e1d87d
+
e1d87d
 	    struct objfile *objfile = dwarf2_per_cu_objfile (c->per_cu);
e1d87d
 	    struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
e1d87d
 	    ULONGEST stack_value_size_bits
e1d87d
@@ -1874,7 +1995,7 @@ read_pieced_value (struct value *v)
e1d87d
 	    else
e1d87d
 	      bits_to_skip += p->offset;
e1d87d
 
e1d87d
-	    copy_bitwise (contents, offset,
e1d87d
+	    copy_bitwise (v_contents, offset,
e1d87d
 			  value_contents_all (p->v.value),
e1d87d
 			  bits_to_skip,
e1d87d
 			  this_size_bits, bits_big_endian);
e1d87d
@@ -1883,6 +2004,12 @@ read_pieced_value (struct value *v)
e1d87d
 
e1d87d
 	case DWARF_VALUE_LITERAL:
e1d87d
 	  {
e1d87d
+	    if (from != NULL)
e1d87d
+	      {
e1d87d
+		mark_value_bits_optimized_out (v, offset, this_size_bits);
e1d87d
+		break;
e1d87d
+	      }
e1d87d
+
e1d87d
 	    ULONGEST literal_size_bits = 8 * p->v.literal.length;
e1d87d
 	    size_t n = this_size_bits;
e1d87d
 
e1d87d
@@ -1893,15 +2020,21 @@ read_pieced_value (struct value *v)
e1d87d
 	    if (n > literal_size_bits - bits_to_skip)
e1d87d
 	      n = literal_size_bits - bits_to_skip;
e1d87d
 
e1d87d
-	    copy_bitwise (contents, offset,
e1d87d
+	    copy_bitwise (v_contents, offset,
e1d87d
 			  p->v.literal.data, bits_to_skip,
e1d87d
 			  n, bits_big_endian);
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
-	  /* These bits show up as zeros -- but do not cause the value
e1d87d
-	     to be considered optimized-out.  */
e1d87d
 	case DWARF_VALUE_IMPLICIT_POINTER:
e1d87d
+	    if (from != NULL)
e1d87d
+	      {
e1d87d
+		mark_value_bits_optimized_out (v, offset, this_size_bits);
e1d87d
+		break;
e1d87d
+	      }
e1d87d
+
e1d87d
+	  /* These bits show up as zeros -- but do not cause the value to
e1d87d
+	     be considered optimized-out.  */
e1d87d
 	  break;
e1d87d
 
e1d87d
 	case DWARF_VALUE_OPTIMIZED_OUT:
e1d87d
@@ -1917,154 +2050,17 @@ read_pieced_value (struct value *v)
e1d87d
     }
e1d87d
 }
e1d87d
 
e1d87d
+
e1d87d
 static void
e1d87d
-write_pieced_value (struct value *to, struct value *from)
e1d87d
+read_pieced_value (struct value *v)
e1d87d
 {
e1d87d
-  int i;
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
-  std::vector<gdb_byte> buffer;
e1d87d
-  int bits_big_endian
e1d87d
-    = gdbarch_bits_big_endian (get_type_arch (value_type (to)));
e1d87d
-
e1d87d
-  contents = value_contents (from);
e1d87d
-  bits_to_skip = 8 * value_offset (to);
e1d87d
-  if (value_bitsize (to))
e1d87d
-    {
e1d87d
-      bits_to_skip += (8 * value_offset (value_parent (to))
e1d87d
-		       + value_bitpos (to));
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
-    max_offset = 8 * TYPE_LENGTH (value_type (to));
e1d87d
-
e1d87d
-  /* Advance to the first non-skipped piece.  */
e1d87d
-  for (i = 0; i < c->n_pieces && bits_to_skip >= c->pieces[i].size; i++)
e1d87d
-    bits_to_skip -= c->pieces[i].size;
e1d87d
-
e1d87d
-  for (; 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
-
e1d87d
-      this_size_bits = p->size - bits_to_skip;
e1d87d
-      if (this_size_bits > max_offset - offset)
e1d87d
-	this_size_bits = max_offset - offset;
e1d87d
-
e1d87d
-      switch (p->location)
e1d87d
-	{
e1d87d
-	case DWARF_VALUE_REGISTER:
e1d87d
-	  {
e1d87d
-	    struct frame_info *frame = frame_find_by_id (c->frame_id);
e1d87d
-	    struct gdbarch *arch = get_frame_arch (frame);
e1d87d
-	    int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
e1d87d
-	    ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
e1d87d
-
e1d87d
-	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
e1d87d
-		&& p->offset + p->size < reg_bits)
e1d87d
-	      {
e1d87d
-		/* Big-endian, and we want less than full size.  */
e1d87d
-		bits_to_skip += reg_bits - (p->offset + p->size);
e1d87d
-	      }
e1d87d
-	    else
e1d87d
-	      bits_to_skip += p->offset;
e1d87d
-
e1d87d
-	    this_size = bits_to_bytes (bits_to_skip, this_size_bits);
e1d87d
-	    buffer.reserve (this_size);
e1d87d
-
e1d87d
-	    if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
e1d87d
-	      {
e1d87d
-		/* Data is copied non-byte-aligned into the register.
e1d87d
-		   Need some bits from original register value.  */
e1d87d
-		int optim, unavail;
e1d87d
-
e1d87d
-		if (!get_frame_register_bytes (frame, gdb_regnum,
e1d87d
-					       bits_to_skip / 8,
e1d87d
-					       this_size, buffer.data (),
e1d87d
-					       &optim, &unavail))
e1d87d
-		  {
e1d87d
-		    if (optim)
e1d87d
-		      throw_error (OPTIMIZED_OUT_ERROR,
e1d87d
-				   _("Can't do read-modify-write to "
e1d87d
-				     "update bitfield; containing word "
e1d87d
-				     "has been optimized out"));
e1d87d
-		    if (unavail)
e1d87d
-		      throw_error (NOT_AVAILABLE_ERROR,
e1d87d
-				   _("Can't do read-modify-write to update "
e1d87d
-				     "bitfield; containing word "
e1d87d
-				     "is unavailable"));
e1d87d
-		  }
e1d87d
-	      }
e1d87d
-
e1d87d
-	    copy_bitwise (buffer.data (), bits_to_skip % 8,
e1d87d
-			  contents, offset,
e1d87d
-			  this_size_bits, bits_big_endian);
e1d87d
-	    put_frame_register_bytes (frame, gdb_regnum,
e1d87d
-				      bits_to_skip / 8,
e1d87d
-				      this_size, buffer.data ());
e1d87d
-	  }
e1d87d
-	  break;
e1d87d
-	case DWARF_VALUE_MEMORY:
e1d87d
-	  {
e1d87d
-	    bits_to_skip += p->offset;
e1d87d
-
e1d87d
-	    CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
e1d87d
-
e1d87d
-	    if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
e1d87d
-		&& offset % 8 == 0)
e1d87d
-	      {
e1d87d
-		/* Everything is byte-aligned; no buffer needed.  */
e1d87d
-		write_memory_with_notification (start_addr,
e1d87d
-						contents + offset / 8,
e1d87d
-						this_size_bits / 8);
e1d87d
-		break;
e1d87d
-	      }
e1d87d
-
e1d87d
-	    this_size = bits_to_bytes (bits_to_skip, this_size_bits);
e1d87d
-	    buffer.reserve (this_size);
e1d87d
-
e1d87d
-	    if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
e1d87d
-	      {
e1d87d
-		if (this_size <= 8)
e1d87d
-		  {
e1d87d
-		    /* Perform a single read for small sizes.  */
e1d87d
-		    read_memory (start_addr, buffer.data (), this_size);
e1d87d
-		  }
e1d87d
-		else
e1d87d
-		  {
e1d87d
-		    /* Only the first and last bytes can possibly have any
e1d87d
-		       bits reused.  */
e1d87d
-		    read_memory (start_addr, buffer.data (), 1);
e1d87d
-		    read_memory (start_addr + this_size - 1,
e1d87d
-				 &buffer[this_size - 1], 1);
e1d87d
-		  }
e1d87d
-	      }
e1d87d
+  rw_pieced_value (v, NULL);
e1d87d
+}
e1d87d
 
e1d87d
-	    copy_bitwise (buffer.data (), bits_to_skip % 8,
e1d87d
-			  contents, offset,
e1d87d
-			  this_size_bits, bits_big_endian);
e1d87d
-	    write_memory_with_notification (start_addr, buffer.data (),
e1d87d
-					    this_size);
e1d87d
-	  }
e1d87d
-	  break;
e1d87d
-	default:
e1d87d
-	  mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to)));
e1d87d
-	  break;
e1d87d
-	}
e1d87d
-      offset += this_size_bits;
e1d87d
-      bits_to_skip = 0;
e1d87d
-    }
e1d87d
+static void
e1d87d
+write_pieced_value (struct value *to, struct value *from)
e1d87d
+{
e1d87d
+  rw_pieced_value (to, from);
e1d87d
 }
e1d87d
 
e1d87d
 /* An implementation of an lval_funcs method to see whether a value is