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]

[commit, s390] Fix GDB internal error after stack overflow in inferior call


Hello,

I'm seeing GDB internal errors on 31-bit s390 with the recently added
test that attempts an inferior call with $sp == 0.  The underflow
during stack frame setup results in a SP value with high bit set
(i.e. outside the 31-bit address space range), which confuses GDB
later on.

To fix this, I've added a check for stack overflow in s390_push_dummy_call
and just throw an error in this case.

Tested on s390-ibm-linux.  Committed to mainline.

Bye,
Ulrich


ChangeLog:

	* s390-tdep.c (s390_push_dummy_call): Error on stack overflow
	during inferior call stack frame setup.

Index: gdb/s390-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/s390-tdep.c,v
retrieving revision 1.188
diff -u -p -r1.188 s390-tdep.c
--- gdb/s390-tdep.c	4 Jan 2010 15:02:59 -0000	1.188
+++ gdb/s390-tdep.c	25 Jun 2010 17:43:25 -0000
@@ -2343,14 +2343,13 @@ s390_push_dummy_call (struct gdbarch *gd
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int word_size = gdbarch_ptr_bit (gdbarch) / 8;
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  ULONGEST orig_sp;
   int i;
 
   /* If the i'th argument is passed as a reference to a copy, then
      copy_addr[i] is the address of the copy we made.  */
   CORE_ADDR *copy_addr = alloca (nargs * sizeof (CORE_ADDR));
 
-  /* Build the reference-to-copy area.  */
+  /* Reserve space for the reference-to-copy area.  */
   for (i = 0; i < nargs; i++)
     {
       struct value *arg = args[i];
@@ -2361,7 +2360,6 @@ s390_push_dummy_call (struct gdbarch *gd
         {
           sp -= length;
           sp = align_down (sp, alignment_of (type));
-          write_memory (sp, value_contents (arg), length);
           copy_addr[i] = sp;
         }
     }
@@ -2376,13 +2374,26 @@ s390_push_dummy_call (struct gdbarch *gd
      boundary.  */
   sp = align_down (sp, 8);
 
+  /* Allocate the standard frame areas: the register save area, the
+     word reserved for the compiler (which seems kind of meaningless),
+     and the back chain pointer.  */
+  sp -= 16*word_size + 32;
+
+  /* Now we have the final SP value.  Make sure we didn't underflow;
+     on 31-bit, this would result in addresses with the high bit set,
+     which causes confusion elsewhere.  Note that if we error out
+     here, stack and registers remain untouched.  */
+  if (gdbarch_addr_bits_remove (gdbarch, sp) != sp)
+    error (_("Stack overflow"));
+
+
   /* Finally, place the actual parameters, working from SP towards
      higher addresses.  The code above is supposed to reserve enough
      space for this.  */
   {
     int fr = 0;
     int gr = 2;
-    CORE_ADDR starg = sp;
+    CORE_ADDR starg = sp + 16*word_size + 32;
 
     /* A struct is returned using general register 2.  */
     if (struct_return)
@@ -2400,6 +2411,10 @@ s390_push_dummy_call (struct gdbarch *gd
 
 	if (s390_function_arg_pass_by_reference (type))
 	  {
+	    /* Actually copy the argument contents to the stack slot
+	       that was reserved above.  */
+	    write_memory (copy_addr[i], value_contents (arg), length);
+
 	    if (gr <= 6)
 	      {
 		regcache_cooked_write_unsigned (regcache, S390_R0_REGNUM + gr,
@@ -2475,11 +2490,6 @@ s390_push_dummy_call (struct gdbarch *gd
       }
   }
 
-  /* Allocate the standard frame areas: the register save area, the
-     word reserved for the compiler (which seems kind of meaningless),
-     and the back chain pointer.  */
-  sp -= 16*word_size + 32;
-
   /* Store return address.  */
   regcache_cooked_write_unsigned (regcache, S390_RETADDR_REGNUM, bp_addr);
   
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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