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]

[PATCH 4/5] ARM: read_pieced_value do big endian processing only in case of valid gdb_regnum


During armv7b testing gdb.base/store.exp test was failling with
'GDB internal error'. It turns out that compiler generated DWARF
with non-existent register numbers. The compiler issue is present
in both little endian (armv7) and big endian (armv7b) (it is
separate issue). In both case gdbarch_dwarf2_reg_to_regnum returns
-1 which is stored into gdb_regnum. But it cause severe problem
only in big endian case because in read_pieced_value and
write_pieced_value functions BFD_ENDIAN_BIG related processing
happen regardless of gdb_regnum value, and in case of gdb_regnum=-1,
it cause 'GDB internal error' and crash.

Solution is to move BFD_ENDIAN_BIG related processing under
(gdb_regnum != -1) branch of processing.
---
 gdb/ChangeLog   |  6 ++++++
 gdb/dwarf2loc.c | 30 +++++++++++++++---------------
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c32fb3f..6a735b8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2014-10-13  Victor Kamensky  <victor.kamensky@linaro.org>
 
+	* dwarf2loc.c (read_pieced_value): do BE processing only if
+	gdb_regnum is not -1.
+	(write_pieced_value): Ditto.
+
+2014-10-13  Victor Kamensky  <victor.kamensky@linaro.org>
+
 	* arm-tdep.c: (extract_arm_insn): use dbarch_byte_order_for_code
 	to read arm instruction.
 
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index e347e59..fbe99bb 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1686,20 +1686,20 @@ read_pieced_value (struct value *v)
 	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = source_offset;
 
-	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
-		&& this_size < register_size (arch, gdb_regnum))
-	      {
-		/* Big-endian, and we want less than full size.  */
-		reg_offset = register_size (arch, gdb_regnum) - this_size;
-		/* We want the lower-order THIS_SIZE_BITS of the bytes
-		   we extract from the register.  */
-		source_offset_bits += 8 * this_size - this_size_bits;
-	      }
-
 	    if (gdb_regnum != -1)
 	      {
 		int optim, unavail;
 
+		if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
+		    && this_size < register_size (arch, gdb_regnum))
+		  {
+		    /* Big-endian, and we want less than full size.  */
+		    reg_offset = register_size (arch, gdb_regnum) - this_size;
+		    /* We want the lower-order THIS_SIZE_BITS of the bytes
+		       we extract from the register.  */
+		    source_offset_bits += 8 * this_size - this_size_bits;
+		 }
+
 		if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
 					       this_size, buffer,
 					       &optim, &unavail))
@@ -1878,13 +1878,13 @@ write_pieced_value (struct value *to, struct value *from)
 	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = dest_offset;
 
-	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
-		&& this_size <= register_size (arch, gdb_regnum))
-	      /* Big-endian, and we want less than full size.  */
-	      reg_offset = register_size (arch, gdb_regnum) - this_size;
-
 	    if (gdb_regnum != -1)
 	      {
+		if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
+		    && this_size <= register_size (arch, gdb_regnum))
+		  /* Big-endian, and we want less than full size.  */
+		  reg_offset = register_size (arch, gdb_regnum) - this_size;
+
 		if (need_bitwise)
 		  {
 		    int optim, unavail;
-- 
1.8.1.4


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