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]

[RFC] mips-tdep.c: Sign extend values placed into registers for inferior function calls


The patch below fixes a significant number of failures for mips64
targets running in 32-bit mode.  In recent testing of mipsisa64-elf
with the target_board set to mips-sim-idt64/-EB/-mips32, I saw 529
fewer failures, though, admittedly, many of these are cascade
failures.

Here is an example, taken from the log file, of one failure fixed by
this patch:

    p t_short_values(10,-23)
    UNPREDICTABLE: PC = 0x800209d4
    Quit
    (gdb) FAIL: gdb.base/callfuncs.exp: p t_short_values(10,-23)

In creating the inferior function call, gdb is placing a negative
value, -23, sign extended only to 32-bits, into one of the 64-bit
argument registers.  When the simulator executes a move instruction
in the course of executing t_short_values(), it first checks to make
sure that the register value is correctly sign extended.  I.e. it looks
at bits 32-63 and makes sure that they all match the value in bit 31. 
If it's not correctly sign extended, it outputs the "UNPREDICTABLE"
message.  It then aborts back to GDB, often causing further problems
for later tests.

The following tests are all affected by this bug.  (There are many
other failures too, but most are due to GDB attempting to perform the
requested operation while it still thinks the target is running.)  Note
that some of these tests are listed as PASS.  There's still a problem
though.  Subsequent tests fail due to the abort caused due to the
incorrect sign extension.

FAIL: gdb.base/call-ar-st.exp: print sum_array_print(10, *list1, *list2, *list3, *list4)
FAIL: gdb.base/call-rt-st.exp: print print_struct_rep(*struct1)
FAIL: gdb.base/callfuncs.exp: p t_short_values(10,-23)
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 5 structs-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 3 structs-ts
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-ti
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tl
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tll
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tf
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-td
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tld
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 4 structs-ts-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-ti-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tl-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tll-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tf-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-td-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tld-tc
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 3 structs-tc-ts
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tc-ti
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tc-tl
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tc-tll
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tc-tf
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tc-td
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tc-tld
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-td-tf
PASS: gdb.base/structs.exp: call Fun<n>(foo<n>); call 2 structs-tf-td
FAIL: gdb.cp/classes.exp: call class_param.Aval_a (g_A)
FAIL: gdb.cp/virtfunc.exp: print pDe->vg()

I think the patch below is almost obvious.  We all know by now that
mips values usually need to be sign extended.

I should note too that there are several other instances in
mips-tdep.c where unsigned operations are still performed.  I'll
address some of those problems in other patches soon to be posted, but
only for those cases where I can demonstrate that a failure is fixed
as a result.

Comments?

Kevin

	* mips-tdep.c (mips_eabi_push_dummy_call): Place signed, rather
	than unsigned, values in registers.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.508
diff -u -p -r1.508 mips-tdep.c
--- mips-tdep.c	28 Nov 2010 04:31:24 -0000	1.508
+++ mips-tdep.c	7 Dec 2010 19:52:14 -0000
@@ -2755,7 +2755,7 @@ mips_eabi_push_dummy_call (struct gdbarc
 	fprintf_unfiltered (gdb_stdlog,
 			    "mips_eabi_push_dummy_call: struct_return reg=%d %s\n",
 			    argreg, paddress (gdbarch, struct_addr));
-      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
+      regcache_cooked_write_signed (regcache, argreg++, struct_addr);
     }
 
   /* Now load as many as possible of the first arguments into
@@ -2834,7 +2834,7 @@ mips_eabi_push_dummy_call (struct gdbarc
 	      if (mips_debug)
 		fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
 				    float_argreg, phex (regval, 4));
-	      regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+	      regcache_cooked_write_signed (regcache, float_argreg++, regval);
 
 	      /* Write the high word of the double to the odd register(s).  */
 	      regval = extract_unsigned_integer (val + 4 - low_offset,
@@ -2842,7 +2842,7 @@ mips_eabi_push_dummy_call (struct gdbarc
 	      if (mips_debug)
 		fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
 				    float_argreg, phex (regval, 4));
-	      regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+	      regcache_cooked_write_signed (regcache, float_argreg++, regval);
 	    }
 	  else
 	    {
@@ -2854,7 +2854,7 @@ mips_eabi_push_dummy_call (struct gdbarc
 	      if (mips_debug)
 		fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
 				    float_argreg, phex (regval, len));
-	      regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+	      regcache_cooked_write_signed (regcache, float_argreg++, regval);
 	    }
 	}
       else
@@ -2937,13 +2937,13 @@ mips_eabi_push_dummy_call (struct gdbarc
 		  && !fp_register_arg_p (gdbarch, typecode, arg_type))
 		{
 		  LONGEST regval =
-		    extract_unsigned_integer (val, partial_len, byte_order);
+		    extract_signed_integer (val, partial_len, byte_order);
 
 		  if (mips_debug)
 		    fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
 				      argreg,
 				      phex (regval, regsize));
-		  regcache_cooked_write_unsigned (regcache, argreg, regval);
+		  regcache_cooked_write_signed (regcache, argreg, regval);
 		  argreg++;
 		}
 


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