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

e1d87d
commit e93523245b704bc126705620969b4736b00350c5
e1d87d
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
e1d87d
Date:   Tue Jun 13 15:20:26 2017 +0200
e1d87d
e1d87d
    PR gdb/21226: Take DWARF stack value pieces from LSB end
e1d87d
    
e1d87d
    When taking a DW_OP_piece or DW_OP_bit_piece from a DW_OP_stack_value, the
e1d87d
    existing logic always takes the piece from the lowest-addressed end, which
e1d87d
    is wrong on big-endian targets.  The DWARF standard states that the
e1d87d
    "DW_OP_bit_piece operation describes a sequence of bits using the least
e1d87d
    significant bits of that value", and this also matches the current logic
e1d87d
    in GCC.  For instance, the GCC guality test case pr54970.c fails on s390x
e1d87d
    because of this.
e1d87d
    
e1d87d
    This fix adjusts the piece accordingly on big-endian targets.  It is
e1d87d
    assumed that:
e1d87d
    
e1d87d
    * DW_OP_piece shall take the piece from the LSB end as well;
e1d87d
    
e1d87d
    * pieces reaching outside the stack value bits are considered undefined,
e1d87d
      and a zero value can be used instead.
e1d87d
    
e1d87d
    gdb/ChangeLog:
e1d87d
    
e1d87d
            PR gdb/21226
e1d87d
            * dwarf2loc.c (read_pieced_value): Anchor stack value pieces at
e1d87d
            the LSB end, independent of endianness.
e1d87d
    
e1d87d
    gdb/testsuite/ChangeLog:
e1d87d
    
e1d87d
            PR gdb/21226
e1d87d
            * gdb.dwarf2/nonvar-access.exp: Add checks for verifying that
e1d87d
            stack value pieces are taken from the LSB end.
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
+	PR gdb/21226
e1d87d
+	* dwarf2loc.c (read_pieced_value): Anchor stack value pieces at
e1d87d
+	the LSB end, independent of endianness.
e1d87d
+
e1d87d
+2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
+
e1d87d
 	* dwarf2loc.c (write_pieced_value): Fix order of calculations for
e1d87d
 	size capping.
e1d87d
 
e1d87d
--- a/gdb/dwarf2loc.c
e1d87d
+++ b/gdb/dwarf2loc.c
e1d87d
@@ -1858,6 +1858,10 @@ read_pieced_value (struct value *v)
e1d87d
 		if (unavail)
e1d87d
 		  mark_value_bits_unavailable (v, offset, this_size_bits);
e1d87d
 	      }
e1d87d
+
e1d87d
+	    copy_bitwise (contents, dest_offset_bits,
e1d87d
+			  intermediate_buffer, source_offset_bits % 8,
e1d87d
+			  this_size_bits, bits_big_endian);
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
@@ -1866,26 +1870,30 @@ read_pieced_value (struct value *v)
e1d87d
 			     p->v.mem.in_stack_memory,
e1d87d
 			     p->v.mem.addr + source_offset,
e1d87d
 			     buffer.data (), this_size);
e1d87d
+	  copy_bitwise (contents, dest_offset_bits,
e1d87d
+			intermediate_buffer, source_offset_bits % 8,
e1d87d
+			this_size_bits, bits_big_endian);
e1d87d
 	  break;
e1d87d
 
e1d87d
 	case DWARF_VALUE_STACK:
e1d87d
 	  {
e1d87d
-	    size_t n = this_size;
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
+	      = 8 * TYPE_LENGTH (value_type (p->v.value));
e1d87d
 
e1d87d
-	    if (n > c->addr_size - source_offset)
e1d87d
-	      n = (c->addr_size >= source_offset
e1d87d
-		   ? c->addr_size - source_offset
e1d87d
-		   : 0);
e1d87d
-	    if (n == 0)
e1d87d
-	      {
e1d87d
-		/* Nothing.  */
e1d87d
-	      }
e1d87d
-	    else
e1d87d
-	      {
e1d87d
-		const gdb_byte *val_bytes = value_contents_all (p->v.value);
e1d87d
+	    /* Use zeroes if piece reaches beyond stack value.  */
e1d87d
+	    if (p->size > stack_value_size_bits)
e1d87d
+	      break;
e1d87d
 
e1d87d
-		intermediate_buffer = val_bytes + source_offset;
e1d87d
-	      }
e1d87d
+	    /* Piece is anchored at least significant bit end.  */
e1d87d
+	    if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
e1d87d
+	      source_offset_bits += stack_value_size_bits - p->size;
e1d87d
+
e1d87d
+	    copy_bitwise (contents, dest_offset_bits,
e1d87d
+			  value_contents_all (p->v.value),
e1d87d
+			  source_offset_bits,
e1d87d
+			  this_size_bits, bits_big_endian);
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
@@ -1899,6 +1907,10 @@ read_pieced_value (struct value *v)
e1d87d
 		   : 0);
e1d87d
 	    if (n != 0)
e1d87d
 	      intermediate_buffer = p->v.literal.data + source_offset;
e1d87d
+
e1d87d
+	    copy_bitwise (contents, dest_offset_bits,
e1d87d
+			  intermediate_buffer, source_offset_bits % 8,
e1d87d
+			  this_size_bits, bits_big_endian);
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
@@ -1915,12 +1927,6 @@ read_pieced_value (struct value *v)
e1d87d
 	  internal_error (__FILE__, __LINE__, _("invalid location type"));
e1d87d
 	}
e1d87d
 
e1d87d
-      if (p->location != DWARF_VALUE_OPTIMIZED_OUT
e1d87d
-	  && p->location != DWARF_VALUE_IMPLICIT_POINTER)
e1d87d
-	copy_bitwise (contents, dest_offset_bits,
e1d87d
-		      intermediate_buffer, source_offset_bits % 8,
e1d87d
-		      this_size_bits, bits_big_endian);
e1d87d
-
e1d87d
       offset += this_size_bits;
e1d87d
     }
e1d87d
 }
e1d87d
### a/gdb/testsuite/ChangeLog
e1d87d
### b/gdb/testsuite/ChangeLog
e1d87d
## -1,5 +1,11 @@
e1d87d
 2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
 
e1d87d
+	PR gdb/21226
e1d87d
+	* gdb.dwarf2/nonvar-access.exp: Add checks for verifying that
e1d87d
+	stack value pieces are taken from the LSB end.
e1d87d
+
e1d87d
+2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
+
e1d87d
 	* gdb.dwarf2/var-pieces.exp: Add test case for modifying a
e1d87d
 	variable at nonzero offset.
e1d87d
 
e1d87d
--- a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
e1d87d
+++ b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
e1d87d
@@ -128,14 +128,26 @@ Dwarf::assemble $asm_file {
e1d87d
 		    {name def_t}
e1d87d
 		    {type :$struct_t_label}
e1d87d
 		    {location {
e1d87d
-			const1u 0
e1d87d
+			const2s -184
e1d87d
 			stack_value
e1d87d
 			bit_piece 9 0
e1d87d
-			const1s -1
e1d87d
+			const4u 1752286
e1d87d
 			stack_value
e1d87d
 			bit_piece 23 0
e1d87d
 		    } SPECIAL_expr}
e1d87d
 		}
e1d87d
+		# Composite location with some empty pieces.
e1d87d
+		DW_TAG_variable {
e1d87d
+		    {name part_def_a}
e1d87d
+		    {type :$array_a9_label}
e1d87d
+		    {location {
e1d87d
+			piece 3
e1d87d
+			const4u 0xf1927314
e1d87d
+			stack_value
e1d87d
+			piece 4
e1d87d
+			piece 2
e1d87d
+		    } SPECIAL_expr}
e1d87d
+		}
e1d87d
 		# Implicit location: immediate value.
e1d87d
 		DW_TAG_variable {
e1d87d
 		    {name def_implicit_s}
e1d87d
@@ -221,9 +233,12 @@ gdb_test "print/x *implicit_b_ptr" " = $val"
e1d87d
 
e1d87d
 # Byte-aligned fields, pieced together from DWARF stack values.
e1d87d
 gdb_test "print def_s" " = \\{a = 0, b = -1\\}"
e1d87d
+switch $endian { big {set val 0x92} little {set val 0x73} }
e1d87d
+gdb_test "print/x part_def_a\[4\]" " = $val"
e1d87d
+gdb_test "print/x part_def_a\[8\]" " = <optimized out>"
e1d87d
 
e1d87d
 # Non-byte-aligned fields, pieced together from DWARF stack values.
e1d87d
-gdb_test "print def_t" " = \\{a = 0, b = -1\\}"
e1d87d
+gdb_test "print def_t" " = \\{a = -184, b = 1752286\\}"
e1d87d
 
e1d87d
 # Simple variable without location.
e1d87d
 gdb_test "print undef_int" " = <optimized out>"