AIX 4.3 changes.
authorKevin Buettner <kevinb@redhat.com>
Tue, 15 Feb 2000 21:17:04 +0000 (21:17 +0000)
committerKevin Buettner <kevinb@redhat.com>
Tue, 15 Feb 2000 21:17:04 +0000 (21:17 +0000)
gdb/ChangeLog
gdb/config/powerpc/tm-ppc-aix.h
gdb/rs6000-nat.c
gdb/rs6000-tdep.c

index f45561d688b2bd80387c0c77bae3986b2a3949f4..7f74a0cfeb7c77fa99905ed3f596b947687eb3a4 100644 (file)
@@ -1,3 +1,41 @@
+2000-02-15  Kevin Buettner  <kevinb@redhat.com>
+
+       Changes for AIX 4.3:
+       * rs6000-tdep.c (rs6000_fix_call_dummy): Set TOC register
+       to correct value for generic dummy frames.  When using
+       generic dummy frames, don't attempt to write TOC value or
+       function to call into the call dummy.
+        (rs6000_push_arguments): Adapt USE_GENERIC_DUMMY_FRAMES
+       code to also handle the PowerOpen ABI.
+       (ppc_push_return_address): Enable for all ports.
+       * config/powerpc/tm-ppc-aix.h (USE_GENERIC_DUMMY_FRAMES,
+       PUSH_DUMMY_FRAME, PUSH_RETURN_ADDRESS, GET_SAVED_REGISTER, 
+       CALL_DUMMY_BREAKPOINT_OFFSET, CALL_DUMMY_LOCATION,
+       CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET): Override defaults
+       provided by generic RS6000 definitions so that call dummies
+       are implemented using generic dummy frames instead.
+
+       * rs6000-nat.c (store_inferior_registers): Call exec_one_dummy_insn()
+       prior to changing the stack pointer via ptrace().  Also, ignore
+       attempts to store to undefined registers that are less than
+       NUM_REGS.
+
+       * rs6000-tdep.c (DUMMY_FRAME_SIZE): Change size of the dummy
+       frame from 436 to 448 to account for alignment padding.
+       (rs6000_push_arguments): Obtain actual register size instead
+       of assuming the register is 4 bytes long.  [There's still
+       more work to be done to totally remove the 4 byte assumption,
+       however.]  Make sure the stack is 16 byte aligned as required
+       by the PowerOpen ABI.  Also, make sure that small structures
+       passed in registers are properly aligned within the register.
+
+2000-02-15  Jesper Skov  <jskov@cygnus.co.uk>
+
+       Patch applied by Kevin Buettner <kevinb@redhat.com>
+       
+       * rs6000-tdep.c (skip_prologue): skip copying of argument
+       registers to local variable registers.
+
 2000-02-14  Jim Kingdon  <kingdon@redhat.com>
 
        * elfread.c (elf_symtab_read): Revert changes by Amit S. Kale.  A
index d3afbd5d0a797c2a27c5f0a97623a727457b665c..ae55e07578055debf52dd734e46f5f2ba6583573 100644 (file)
 
 #define GDB_TARGET_POWERPC
 
+#undef PUSH_DUMMY_FRAME
+#define PUSH_DUMMY_FRAME             generic_push_dummy_frame ()
+
+#define PUSH_RETURN_ADDRESS(PC, SP)      ppc_push_return_address (PC, SP)
+
+/* override the standard get_saved_register function with 
+   one that takes account of generic CALL_DUMMY frames */
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+      generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+#define CALL_DUMMY_LOCATION          AT_ENTRY_POINT
+#define CALL_DUMMY_ADDRESS()         entry_point_address ()
+#undef CALL_DUMMY_START_OFFSET
+#define CALL_DUMMY_START_OFFSET      0
+
 #endif /* TM_PPC_AIX_H */
index d109f3319e85e05378d670c0d37e1e10d0918bb1..63fadcf9616e90e5baad7521c38231a6b2c6a59e 100644 (file)
@@ -215,6 +215,8 @@ store_inferior_registers (regno)
 
   else if (regno < FP0_REGNUM) /* a GPR */
     {
+      if (regno == SP_REGNUM)
+       exec_one_dummy_insn ();
       ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) regno,
              *(int *) &registers[REGISTER_BYTE (regno)], 0);
     }
@@ -233,6 +235,11 @@ store_inferior_registers (regno)
              *(int *) &registers[REGISTER_BYTE (regno)], 0);
     }
 
+  else if (regno < NUM_REGS)
+    {
+      /* Ignore it.  */
+    }
+
   else
     fprintf_unfiltered (gdb_stderr,
                        "Gdb error: register no %d not implemented.\n",
index fa483b237f43d9b29bbb5cd076969ff9d0a0ea80..5b6dcad08481b8229a1f95cc1717a2d2abffd049 100644 (file)
@@ -481,6 +481,16 @@ skip_prologue (pc, fdata)
          minimal_toc_loaded = 1;
          continue;
 
+         /* move parameters from argument registers to local variable
+             registers */
+       }
+      else if ((op & 0xfc0007fe) == 0x7c000378 &&      /* mr(.)  Rx,Ry */
+               (((op >> 21) & 31) >= 3) &&              /* R3 >= Ry >= R10 */
+               (((op >> 21) & 31) <= 10) &&
+               (((op >> 16) & 31) >= fdata->saved_gpr)) /* Rx: local var reg */
+       {
+         continue;
+
          /* store parameters in stack */
        }
       else if ((op & 0xfc1f0000) == 0x90010000 ||      /* st rx,NUM(r1) */
@@ -559,20 +569,22 @@ skip_prologue (pc, fdata)
 
 
 /*************************************************************************
-  Support for creating pushind a dummy frame into the stack, and popping
+  Support for creating pushing a dummy frame into the stack, and popping
   frames, etc. 
 *************************************************************************/
 
 /* The total size of dummy frame is 436, which is;
 
-   32 gpr's     - 128 bytes
-   32 fpr's     - 256   "
-   7  the rest  - 28    "
-   and 24 extra bytes for the callee's link area. The last 24 bytes
-   for the link area might not be necessary, since it will be taken
-   care of by push_arguments(). */
+   32 gpr's           - 128 bytes
+   32 fpr's           - 256 bytes
+   7  the rest        -  28 bytes
+   callee's link area -  24 bytes
+   padding            -  12 bytes
 
-#define DUMMY_FRAME_SIZE 436
+   Note that the last 24 bytes for the link area might not be necessary,
+   since it will be taken care of by push_arguments(). */
+
+#define DUMMY_FRAME_SIZE 448
 
 #define        DUMMY_FRAME_ADDR_SIZE 10
 
@@ -834,28 +846,39 @@ rs6000_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
   int ii;
   CORE_ADDR target_addr;
 
-  if (find_toc_address_hook != NULL)
+  if (USE_GENERIC_DUMMY_FRAMES)
+    {
+      if (find_toc_address_hook != NULL)
+       {
+         CORE_ADDR tocvalue = (*find_toc_address_hook) (fun);
+         write_register (TOC_REGNUM, tocvalue);
+       }
+    }
+  else
     {
-      CORE_ADDR tocvalue;
+      if (find_toc_address_hook != NULL)
+       {
+         CORE_ADDR tocvalue;
 
-      tocvalue = (*find_toc_address_hook) (fun);
-      ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET);
-      ii = (ii & 0xffff0000) | (tocvalue >> 16);
-      *(int *) ((char *) dummyname + TOC_ADDR_OFFSET) = ii;
+         tocvalue = (*find_toc_address_hook) (fun);
+         ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET);
+         ii = (ii & 0xffff0000) | (tocvalue >> 16);
+         *(int *) ((char *) dummyname + TOC_ADDR_OFFSET) = ii;
 
-      ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4);
-      ii = (ii & 0xffff0000) | (tocvalue & 0x0000ffff);
-      *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4) = ii;
-    }
+         ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4);
+         ii = (ii & 0xffff0000) | (tocvalue & 0x0000ffff);
+         *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4) = ii;
+       }
 
-  target_addr = fun;
-  ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET);
-  ii = (ii & 0xffff0000) | (target_addr >> 16);
-  *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET) = ii;
+      target_addr = fun;
+      ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET);
+      ii = (ii & 0xffff0000) | (target_addr >> 16);
+      *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET) = ii;
 
-  ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4);
-  ii = (ii & 0xffff0000) | (target_addr & 0x0000ffff);
-  *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4) = ii;
+      ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4);
+      ii = (ii & 0xffff0000) | (target_addr & 0x0000ffff);
+      *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4) = ii;
+    }
 }
 
 /* Pass the arguments in either registers, or in the stack. In RS6000,
@@ -928,6 +951,7 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
 
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
+      int reg_size = REGISTER_RAW_SIZE (ii + 3);
 
       arg = args[argno];
       type = check_typedef (VALUE_TYPE (arg));
@@ -950,17 +974,18 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
          ++f_argno;
        }
 
-      if (len > 4)
+      if (len > reg_size)
        {
 
          /* Argument takes more than one register. */
          while (argbytes < len)
            {
-             memset (&registers[REGISTER_BYTE (ii + 3)], 0, sizeof (int));
+             memset (&registers[REGISTER_BYTE (ii + 3)], 0, reg_size);
              memcpy (&registers[REGISTER_BYTE (ii + 3)],
                      ((char *) VALUE_CONTENTS (arg)) + argbytes,
-                     (len - argbytes) > 4 ? 4 : len - argbytes);
-             ++ii, argbytes += 4;
+                     (len - argbytes) > reg_size
+                       ? reg_size : len - argbytes);
+             ++ii, argbytes += reg_size;
 
              if (ii >= 8)
                goto ran_out_of_registers_for_arguments;
@@ -970,8 +995,10 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
        }
       else
        {                       /* Argument can fit in one register. No problem. */
-         memset (&registers[REGISTER_BYTE (ii + 3)], 0, sizeof (int));
-         memcpy (&registers[REGISTER_BYTE (ii + 3)], VALUE_CONTENTS (arg), len);
+         int adj = TARGET_BYTE_ORDER == BIG_ENDIAN ? reg_size - len : 0;
+         memset (&registers[REGISTER_BYTE (ii + 3)], 0, reg_size);
+         memcpy ((char *)&registers[REGISTER_BYTE (ii + 3)] + adj, 
+                 VALUE_CONTENTS (arg), len);
        }
       ++argno;
     }
@@ -981,6 +1008,16 @@ ran_out_of_registers_for_arguments:
   if (USE_GENERIC_DUMMY_FRAMES)
     {
       saved_sp = read_sp ();
+#ifndef ELF_OBJECT_FORMAT
+      /* location for 8 parameters are always reserved. */
+      sp -= 4 * 8;
+
+      /* another six words for back chain, TOC register, link register, etc. */
+      sp -= 24;
+
+      /* stack pointer must be quadword aligned */
+      sp &= -16;
+#endif
     }
   else
     {
@@ -989,6 +1026,9 @@ ran_out_of_registers_for_arguments:
 
       /* another six words for back chain, TOC register, link register, etc. */
       sp -= 24;
+
+      /* stack pointer must be quadword aligned */
+      sp &= -16;
     }
 
   /* if there are more arguments, allocate space for them in 
@@ -1013,7 +1053,7 @@ ran_out_of_registers_for_arguments:
        }
 
       /* add location required for the rest of the parameters */
-      space = (space + 7) & -8;
+      space = (space + 15) & -16;
       sp -= space;
 
       /* This is another instance we need to be concerned about securing our
@@ -1083,7 +1123,7 @@ ran_out_of_registers_for_arguments:
   target_store_registers (-1);
   return sp;
 }
-#ifdef ELF_OBJECT_FORMAT
+/* #ifdef ELF_OBJECT_FORMAT */
 
 /* Function: ppc_push_return_address (pc, sp)
    Set up the return address for the inferior function call. */
@@ -1097,7 +1137,7 @@ ppc_push_return_address (pc, sp)
   return sp;
 }
 
-#endif
+/* #endif */
 
 /* a given return value in `regbuf' with a type `valtype', extract and copy its
    value into `valbuf' */