This is the mail archive of the gdb-patches@sources.redhat.com 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]

Re: [patch/rfa] fix call-dummies for hppa


This fixes a few bugs in the 32-bit version of the hppa push_dummy_call
method.

Tested against hppa2.0w-hp-hpux11.11 and hppa-linux.

Which compilers? I'm suspicious of GCC - it too often gets struct parameters and return values internally consistent but wrong :-(


All of structs.exp pass, there are still some failures in call-sc.exp
and callfuncs.exp. In the latter case it appears most are due to
problems with calling malloc() in the inferior (at least on hppa-linux).

We simply allocate the appropriate amount of stack space and put
arguments into their proper slots. */
- +

Be careful of white space change, this shouldn't be included. If you want to fix some indention just do it separatly.


 CORE_ADDR
 hppa32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 			struct regcache *regcache, CORE_ADDR bp_addr,
 			int nargs, struct value **args, CORE_ADDR sp,
 			int struct_return, CORE_ADDR struct_addr)
 {
-  /* NOTE: cagney/2004-02-27: This is a guess - its implemented by
-     reverse engineering testsuite failures.  */
-

(I've now got a copy of the 32-bit ABI but it doesn't help much)


   /* Stack base address at which any pass-by-reference parameters are
      stored.  */
   CORE_ADDR struct_end = 0;
@@ -781,12 +779,15 @@ hppa32_push_dummy_call (struct gdbarch *
   /* Two passes.  First pass computes the location of everything,
      second pass writes the bytes out.  */
   int write_pass;
+
   for (write_pass = 0; write_pass < 2; write_pass++)
     {
       CORE_ADDR struct_ptr = 0;
-      CORE_ADDR param_ptr = 0;
-      int reg = 27;	      /* NOTE: Registers go down.  */

the comment doesn't match the assignment.


+      /* The first parameter goes into sp-36, each stack slot is 4-bytes.  */
+      CORE_ADDR param_ptr = 32;
       int i;
+      int small_struct = 0;
+
       for (i = 0; i < nargs; i++)
 	{
 	  struct value *arg = args[i];
@@ -795,6 +796,7 @@ hppa32_push_dummy_call (struct gdbarch *
 	     stack, and [possibly] passed in a register.  */
 	  char param_val[8];
 	  int param_len;
+
 	  memset (param_val, 0, sizeof param_val);
 	  if (TYPE_LENGTH (type) > 8)
 	    {
@@ -813,27 +815,76 @@ hppa32_push_dummy_call (struct gdbarch *
 	      /* Integer value store, right aligned.  "unpack_long"
 		 takes care of any sign-extension problems.  */
 	      param_len = align_up (TYPE_LENGTH (type), 4);
+
white space
 	      store_unsigned_integer (param_val, param_len,
 				      unpack_long (type,
 						   VALUE_CONTENTS (arg)));
 	    }
+	  else if (TYPE_CODE (type) == TYPE_CODE_FLT)
+            {

more comments (the rest is well commented), ``&& TYPE_LENGTH () == 4'' test needed?


+	      param_len = align_up (TYPE_LENGTH (type), 4);
+	      memcpy (param_val, VALUE_CONTENTS (arg), param_len);
+            }
 	  else
 	    {
-	      /* Small struct value, store right aligned?  */
 	      param_len = align_up (TYPE_LENGTH (type), 4);
+
+	      /* Small struct value are stored right-aligned.  */
 	      memcpy (param_val + param_len - TYPE_LENGTH (type),
 		      VALUE_CONTENTS (arg), TYPE_LENGTH (type));
+
+	      /* Structures of size 5, 6 and 7 bytes are special in that
+	         the higher-ordered word is stored in the lower-ordered
+		 argument, and even though it is a 8-byte quantity the
+		 registers need not be 8-byte aligned.  */
+	      if (param_len > 4)
+		small_struct = 1;
 	    }
+
 	  param_ptr += param_len;
-	  reg -= param_len / 4;
+	  if (param_len == 8 && !small_struct)
+	    param_ptr += (param_ptr & 4);

align_up?


Otherwize, yep, thanks for fixing this.

Andrew



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