2004-02-25 Roland McGrath <roland@redhat.com>
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 43fb7997855416c0ecd6df53a3c464ac4f6c060f..5eef8959115048aa8420fc7e4586b1a99e5b3444 100644 (file)
@@ -1,7 +1,8 @@
 /* Target-dependent code for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
@@ -27,7 +28,6 @@
 #include "target.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
-#include "symfile.h"
 #include "objfiles.h"
 #include "arch-utils.h"
 #include "regcache.h"
@@ -237,7 +237,7 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
                               struct type *type)
 {
   CORE_ADDR addr;
-  frame_read_register (frame, 3 + argi, &addr);
+  get_frame_register (frame, 3 + argi, &addr);
   return addr;
 }
 
@@ -425,6 +425,10 @@ static int max_skip_non_prologue_insns = 10;
    the line data in the symbol table.  If successful, a better guess
    on where the prologue ends is returned, otherwise the previous
    value of lim_pc is returned.  */
+
+/* FIXME: cagney/2004-02-14: This function and logic have largely been
+   superseded by skip_prologue_using_sal.  */
+
 static CORE_ADDR
 refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc)
 {
@@ -985,7 +989,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
             initializer function as well.  */
 
          tmp = find_pc_misc_function (pc);
-         if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, main_name ()))
+         if (tmp >= 0
+             && strcmp (misc_function_vector[tmp].name, main_name ()) == 0)
            return pc + 8;
        }
     }
@@ -1054,7 +1059,7 @@ rs6000_pop_frame (void)
       addr = prev_sp + fdata.gpr_offset;
       for (ii = fdata.saved_gpr; ii <= 31; ++ii)
        {
-         read_memory (addr, &deprecated_registers[REGISTER_BYTE (ii)],
+         read_memory (addr, &deprecated_registers[DEPRECATED_REGISTER_BYTE (ii)],
                       wordsize);
          addr += wordsize;
        }
@@ -1065,7 +1070,7 @@ rs6000_pop_frame (void)
       addr = prev_sp + fdata.fpr_offset;
       for (ii = fdata.saved_fpr; ii <= 31; ++ii)
        {
-         read_memory (addr, &deprecated_registers[REGISTER_BYTE (ii + FP0_REGNUM)], 8);
+         read_memory (addr, &deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + FP0_REGNUM)], 8);
          addr += 8;
        }
     }
@@ -1154,7 +1159,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
-      int reg_size = REGISTER_RAW_SIZE (ii + 3);
+      int reg_size = DEPRECATED_REGISTER_RAW_SIZE (ii + 3);
 
       arg = args[argno];
       type = check_typedef (VALUE_TYPE (arg));
@@ -1171,7 +1176,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
            printf_unfiltered (
                                "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
 
-         memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)],
+         memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)],
                  VALUE_CONTENTS (arg),
                  len);
          ++f_argno;
@@ -1183,9 +1188,9 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
          /* Argument takes more than one register.  */
          while (argbytes < len)
            {
-             memset (&deprecated_registers[REGISTER_BYTE (ii + 3)], 0,
+             memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)], 0,
                      reg_size);
-             memcpy (&deprecated_registers[REGISTER_BYTE (ii + 3)],
+             memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)],
                      ((char *) VALUE_CONTENTS (arg)) + argbytes,
                      (len - argbytes) > reg_size
                        ? reg_size : len - argbytes);
@@ -1201,8 +1206,8 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
        {
          /* Argument can fit in one register.  No problem.  */
          int adj = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? reg_size - len : 0;
-         memset (&deprecated_registers[REGISTER_BYTE (ii + 3)], 0, reg_size);
-         memcpy ((char *)&deprecated_registers[REGISTER_BYTE (ii + 3)] + adj, 
+         memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)], 0, reg_size);
+         memcpy ((char *)&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)] + adj, 
                  VALUE_CONTENTS (arg), len);
        }
       ++argno;
@@ -1246,6 +1251,14 @@ ran_out_of_registers_for_arguments:
       space = (space + 15) & -16;
       sp -= space;
 
+      /* This is another instance we need to be concerned about
+         securing our stack space. If we write anything underneath %sp
+         (r1), we might conflict with the kernel who thinks he is free
+         to use this area.  So, update %sp first before doing anything
+         else.  */
+
+      regcache_raw_write_signed (regcache, SP_REGNUM, sp);
+
       /* If the last argument copied into the registers didn't fit there 
          completely, push the rest of it into stack.  */
 
@@ -1276,7 +1289,7 @@ ran_out_of_registers_for_arguments:
                printf_unfiltered (
                                    "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
 
-             memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)],
+             memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)],
                      VALUE_CONTENTS (arg),
                      len);
              ++f_argno;
@@ -1287,16 +1300,18 @@ ran_out_of_registers_for_arguments:
        }
     }
 
-  /* set back chain properly */
-  store_unsigned_integer (tmp_buffer, 4, saved_sp);
-  write_memory (sp, tmp_buffer, 4);
-
   /* Set the stack pointer.  According to the ABI, the SP is meant to
-     be set _before_ the corresponding stack space is used.  No need
-     for that here though - the target has been completely stopped -
-     it isn't possible for an exception handler to stomp on the stack.  */
+     be set _before_ the corresponding stack space is used.  On AIX,
+     this even applies when the target has been completely stopped!
+     Not doing this can lead to conflicts with the kernel which thinks
+     that it still has control over this not-yet-allocated stack
+     region.  */
   regcache_raw_write_signed (regcache, SP_REGNUM, sp);
 
+  /* Set back chain properly.  */
+  store_unsigned_integer (tmp_buffer, 4, saved_sp);
+  write_memory (sp, tmp_buffer, 4);
+
   /* Point the inferior function call's return address at the dummy's
      breakpoint.  */
   regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
@@ -1313,65 +1328,6 @@ ran_out_of_registers_for_arguments:
   return sp;
 }
 
-/* Extract a function return value of type TYPE from raw register array
-   REGBUF, and copy that return value into VALBUF in virtual format.  */
-static void
-e500_extract_return_value (struct type *valtype, struct regcache *regbuf, void *valbuf)
-{
-  int offset = 0;
-  int vallen = TYPE_LENGTH (valtype);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
-  if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
-      && vallen == 8
-      && TYPE_VECTOR (valtype))
-    {
-      regcache_raw_read (regbuf, tdep->ppc_ev0_regnum + 3, valbuf);
-    }
-  else
-    {
-      /* Return value is copied starting from r3.  Note that r3 for us
-         is a pseudo register.  */
-      int offset = 0;
-      int return_regnum = tdep->ppc_gp0_regnum + 3;
-      int reg_size = REGISTER_RAW_SIZE (return_regnum);
-      int reg_part_size;
-      char *val_buffer;
-      int copied = 0;
-      int i = 0;
-
-      /* Compute where we will start storing the value from.  */ 
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-        {
-         if (vallen <= reg_size)
-           offset = reg_size - vallen;
-         else
-           offset = reg_size + (reg_size - vallen);
-        }
-
-      /* How big does the local buffer need to be?  */
-      if (vallen <= reg_size)
-       val_buffer = alloca (reg_size);
-      else
-       val_buffer = alloca (vallen);
-
-      /* Read all we need into our private buffer.  We copy it in
-         chunks that are as long as one register, never shorter, even
-         if the value is smaller than the register.  */
-      while (copied < vallen)
-        {
-          reg_part_size = REGISTER_RAW_SIZE (return_regnum + i);
-         /* It is a pseudo/cooked register.  */
-          regcache_cooked_read (regbuf, return_regnum + i,
-                               val_buffer + copied);
-          copied += reg_part_size;
-          i++;
-        }
-      /* Put the stuff in the return buffer.  */
-      memcpy (valbuf, val_buffer + offset, vallen);
-    }
-}
-
 /* PowerOpen always puts structures in memory.  Vectors, which were
    added later, do get returned in a register though.  */
 
@@ -1401,11 +1357,11 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
 
       if (TYPE_LENGTH (valtype) > 4)   /* this is a double */
        memcpy (valbuf,
-               &regbuf[REGISTER_BYTE (FP0_REGNUM + 1)],
+               &regbuf[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1)],
                TYPE_LENGTH (valtype));
       else
        {                       /* float */
-         memcpy (&dd, &regbuf[REGISTER_BYTE (FP0_REGNUM + 1)], 8);
+         memcpy (&dd, &regbuf[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1)], 8);
          ff = (float) dd;
          memcpy (valbuf, &ff, sizeof (float));
        }
@@ -1414,18 +1370,18 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
            && TYPE_LENGTH (valtype) == 16
            && TYPE_VECTOR (valtype))
     {
-      memcpy (valbuf, regbuf + REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
+      memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
              TYPE_LENGTH (valtype));
     }
   else
     {
       /* return value is copied starting from r3. */
       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-         && TYPE_LENGTH (valtype) < REGISTER_RAW_SIZE (3))
-       offset = REGISTER_RAW_SIZE (3) - TYPE_LENGTH (valtype);
+         && TYPE_LENGTH (valtype) < DEPRECATED_REGISTER_RAW_SIZE (3))
+       offset = DEPRECATED_REGISTER_RAW_SIZE (3) - TYPE_LENGTH (valtype);
 
       memcpy (valbuf,
-             regbuf + REGISTER_BYTE (3) + offset,
+             regbuf + DEPRECATED_REGISTER_BYTE (3) + offset,
              TYPE_LENGTH (valtype));
     }
 }
@@ -1628,7 +1584,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
   struct gdbarch_tdep * tdep = gdbarch_tdep (current_gdbarch);
   int wordsize = tdep->wordsize;
 
-  if (get_frame_saved_regs (fi))
+  if (deprecated_get_frame_saved_regs (fi))
     return;
 
   if (fdatap == NULL)
@@ -1670,7 +1626,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
       CORE_ADDR fpr_addr = frame_addr + fdatap->fpr_offset;
       for (i = fdatap->saved_fpr; i < 32; i++)
        {
-         get_frame_saved_regs (fi)[FP0_REGNUM + i] = fpr_addr;
+         deprecated_get_frame_saved_regs (fi)[FP0_REGNUM + i] = fpr_addr;
          fpr_addr += 8;
        }
     }
@@ -1684,7 +1640,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
       CORE_ADDR gpr_addr = frame_addr + fdatap->gpr_offset;
       for (i = fdatap->saved_gpr; i < 32; i++)
        {
-         get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = gpr_addr;
+         deprecated_get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = gpr_addr;
          gpr_addr += wordsize;
        }
     }
@@ -1699,8 +1655,8 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
          CORE_ADDR vr_addr = frame_addr + fdatap->vr_offset;
          for (i = fdatap->saved_vr; i < 32; i++)
            {
-             get_frame_saved_regs (fi)[tdep->ppc_vr0_regnum + i] = vr_addr;
-             vr_addr += REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
+             deprecated_get_frame_saved_regs (fi)[tdep->ppc_vr0_regnum + i] = vr_addr;
+             vr_addr += DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
            }
        }
     }
@@ -1715,9 +1671,9 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
          CORE_ADDR ev_addr = frame_addr + fdatap->ev_offset;
          for (i = fdatap->saved_ev; i < 32; i++)
            {
-             get_frame_saved_regs (fi)[tdep->ppc_ev0_regnum + i] = ev_addr;
-              get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = ev_addr + 4;
-             ev_addr += REGISTER_RAW_SIZE (tdep->ppc_ev0_regnum);
+             deprecated_get_frame_saved_regs (fi)[tdep->ppc_ev0_regnum + i] = ev_addr;
+              deprecated_get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = ev_addr + 4;
+             ev_addr += DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_ev0_regnum);
             }
        }
     }
@@ -1725,17 +1681,17 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
   /* If != 0, fdatap->cr_offset is the offset from the frame that holds
      the CR.  */
   if (fdatap->cr_offset != 0)
-    get_frame_saved_regs (fi)[tdep->ppc_cr_regnum] = frame_addr + fdatap->cr_offset;
+    deprecated_get_frame_saved_regs (fi)[tdep->ppc_cr_regnum] = frame_addr + fdatap->cr_offset;
 
   /* If != 0, fdatap->lr_offset is the offset from the frame that holds
      the LR.  */
   if (fdatap->lr_offset != 0)
-    get_frame_saved_regs (fi)[tdep->ppc_lr_regnum] = frame_addr + fdatap->lr_offset;
+    deprecated_get_frame_saved_regs (fi)[tdep->ppc_lr_regnum] = frame_addr + fdatap->lr_offset;
 
   /* If != 0, fdatap->vrsave_offset is the offset from the frame that holds
      the VRSAVE.  */
   if (fdatap->vrsave_offset != 0)
-    get_frame_saved_regs (fi)[tdep->ppc_vrsave_regnum] = frame_addr + fdatap->vrsave_offset;
+    deprecated_get_frame_saved_regs (fi)[tdep->ppc_vrsave_regnum] = frame_addr + fdatap->vrsave_offset;
 }
 
 /* Return the address of a frame. This is the inital %sp value when the frame
@@ -1762,7 +1718,7 @@ frame_initial_stack_address (struct frame_info *fi)
   /* If saved registers of this frame are not known yet, read and
      cache them.  */
 
-  if (!get_frame_saved_regs (fi))
+  if (!deprecated_get_frame_saved_regs (fi))
     frame_get_saved_regs (fi, &fdata);
 
   /* If no alloca register used, then fi->frame is the value of the %sp for
@@ -1782,7 +1738,7 @@ frame_initial_stack_address (struct frame_info *fi)
       {
        get_frame_extra_info (fi)->initial_sp
          = extract_unsigned_integer (tmpbuf,
-                                     REGISTER_RAW_SIZE (fdata.alloca_reg));
+                                     DEPRECATED_REGISTER_RAW_SIZE (fdata.alloca_reg));
       }
     else
       /* NOTE: cagney/2002-04-17: At present the only time
@@ -1824,7 +1780,8 @@ rs6000_frame_chain (struct frame_info *thisframe)
                           wordsize);
   else if (get_next_frame (thisframe) != NULL
           && (get_frame_type (get_next_frame (thisframe)) == SIGTRAMP_FRAME)
-          && FRAMELESS_FUNCTION_INVOCATION (thisframe))
+          && (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P ()
+              && DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (thisframe)))
     /* A frameless function interrupted by a signal did not change the
        frame pointer.  */
     fp = get_frame_base (thisframe);
@@ -1932,13 +1889,13 @@ static void
 rs6000_register_convert_to_virtual (int n, struct type *type,
                                    char *from, char *to)
 {
-  if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n))
+  if (TYPE_LENGTH (type) != DEPRECATED_REGISTER_RAW_SIZE (n))
     {
-      double val = deprecated_extract_floating (from, REGISTER_RAW_SIZE (n));
+      double val = deprecated_extract_floating (from, DEPRECATED_REGISTER_RAW_SIZE (n));
       deprecated_store_floating (to, TYPE_LENGTH (type), val);
     }
   else
-    memcpy (to, from, REGISTER_RAW_SIZE (n));
+    memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (n));
 }
 
 /* Convert data from virtual format with type TYPE in buffer FROM
@@ -1948,13 +1905,13 @@ static void
 rs6000_register_convert_to_raw (struct type *type, int n,
                                const char *from, char *to)
 {
-  if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n))
+  if (TYPE_LENGTH (type) != DEPRECATED_REGISTER_RAW_SIZE (n))
     {
       double val = deprecated_extract_floating (from, TYPE_LENGTH (type));
-      deprecated_store_floating (to, REGISTER_RAW_SIZE (n), val);
+      deprecated_store_floating (to, DEPRECATED_REGISTER_RAW_SIZE (n), val);
     }
   else
-    memcpy (to, from, REGISTER_RAW_SIZE (n));
+    memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (n));
 }
 
 static void
@@ -2046,30 +2003,6 @@ rs6000_stab_reg_to_regnum (int num)
   return regnum;
 }
 
-/* Write into appropriate registers a function return value
-   of type TYPE, given in virtual format.  */
-static void
-e500_store_return_value (struct type *type, char *valbuf)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
-  /* Everything is returned in GPR3 and up.  */
-  int copied = 0;
-  int i = 0;
-  int len = TYPE_LENGTH (type);
-  while (copied < len)
-    {
-      int regnum = gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3 + i;
-      int reg_size = REGISTER_RAW_SIZE (regnum);
-      char *reg_val_buf = alloca (reg_size);
-
-      memcpy (reg_val_buf, valbuf + copied, reg_size);
-      copied += reg_size;
-      deprecated_write_register_gen (regnum, reg_val_buf);
-      i++;
-    }
-}
-
 static void
 rs6000_store_return_value (struct type *type, char *valbuf)
 {
@@ -2081,18 +2014,18 @@ rs6000_store_return_value (struct type *type, char *valbuf)
        Say a double_double_double type could be returned in
        FPR1/FPR2/FPR3 triple.  */
 
-    deprecated_write_register_bytes (REGISTER_BYTE (FP0_REGNUM + 1), valbuf,
+    deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1), valbuf,
                                     TYPE_LENGTH (type));
   else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
     {
       if (TYPE_LENGTH (type) == 16
           && TYPE_VECTOR (type))
-       deprecated_write_register_bytes (REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
+       deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
                                         valbuf, TYPE_LENGTH (type));
     }
   else
     /* Everything else is returned in GPR3 and up.  */
-    deprecated_write_register_bytes (REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3),
+    deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3),
                                     valbuf, TYPE_LENGTH (type));
 }
 
@@ -2117,17 +2050,6 @@ rs6000_extract_struct_value_address (struct regcache *regcache)
   return 0;
 }
 
-/* Return whether PC is in a dummy function call.
-
-   FIXME: This just checks for the end of the stack, which is broken
-   for things like stepping through gcc nested function stubs.  */
-
-static int
-rs6000_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
-{
-  return sp < pc && pc < fp;
-}
-
 /* Hook called when a new child process is started.  */
 
 void
@@ -2137,7 +2059,7 @@ rs6000_create_inferior (int pid)
     rs6000_set_host_arch_hook (pid);
 }
 \f
-/* Support for CONVERT_FROM_FUNC_PTR_ADDR(ADDR).
+/* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).
 
    Usually a function pointer's representation is simply the address
    of the function. On the RS/6000 however, a function pointer is
@@ -2157,7 +2079,9 @@ rs6000_create_inferior (int pid)
    space and is therefore a special function pointer.  */
 
 static CORE_ADDR
-rs6000_convert_from_func_ptr_addr (CORE_ADDR addr)
+rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
+                                  CORE_ADDR addr,
+                                  struct target_ops *targ)
 {
   struct obj_section *s;
 
@@ -2830,9 +2754,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pc_regnum (gdbarch, 64);
   set_gdbarch_sp_regnum (gdbarch, 1);
   set_gdbarch_deprecated_fp_regnum (gdbarch, 1);
-  set_gdbarch_deprecated_extract_return_value (gdbarch,
-                                              rs6000_extract_return_value);
-  set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+  if (sysv_abi && wordsize == 8)
+    set_gdbarch_return_value (gdbarch, ppc64_sysv_abi_return_value);
+  else if (sysv_abi && wordsize == 4)
+    set_gdbarch_return_value (gdbarch, ppc_sysv_abi_return_value);
+  else
+    {
+      set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+    }
 
   if (v->arch == bfd_arch_powerpc)
     switch (v->mach)
@@ -2866,8 +2796,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
         set_gdbarch_dwarf2_reg_to_regnum (gdbarch, e500_dwarf2_reg_to_regnum);
         set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
         set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
-        set_gdbarch_extract_return_value (gdbarch, e500_extract_return_value);
-        set_gdbarch_deprecated_store_return_value (gdbarch, e500_store_return_value);
        break;
       default:
        tdep->ppc_vr0_regnum = -1;
@@ -2931,8 +2859,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     /* PPC64 SYSV.  */
     set_gdbarch_frame_red_zone_size (gdbarch, 288);
   else if (!sysv_abi && wordsize == 4)
-    /* PowerOpen / AIX 32 bit.  */
-    set_gdbarch_frame_red_zone_size (gdbarch, 220);
+    /* PowerOpen / AIX 32 bit.  The saved area or red zone consists of
+       19 4 byte GPRS + 18 8 byte FPRs giving a total of 220 bytes.
+       Problem is, 220 isn't frame (16 byte) aligned.  Round it up to
+       224.  */
+    set_gdbarch_frame_red_zone_size (gdbarch, 224);
   set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
@@ -2949,30 +2880,35 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      revisited.  */
   if (sysv_abi && wordsize == 4)
     set_gdbarch_push_dummy_call (gdbarch, ppc_sysv_abi_push_dummy_call);
+  else if (sysv_abi && wordsize == 8)
+    set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call);
   else
     set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call);
 
-  set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address);
+  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address);
   set_gdbarch_deprecated_pop_frame (gdbarch, rs6000_pop_frame);
 
   set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-  set_gdbarch_decr_pc_after_break (gdbarch, 0);
-  set_gdbarch_function_start_offset (gdbarch, 0);
   set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
 
+  /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
+     for the descriptor and ".FN" for the entry-point -- a user
+     specifying "break FN" will unexpectedly end up with a breakpoint
+     on the descriptor and not the function.  This architecture method
+     transforms any breakpoints on descriptors into breakpoints on the
+     corresponding entry point.  */
+  if (sysv_abi && wordsize == 8)
+    set_gdbarch_adjust_breakpoint_address (gdbarch, ppc64_sysv_abi_adjust_breakpoint_address);
+
   /* Not sure on this. FIXMEmgo */
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
-  if (sysv_abi)
-    set_gdbarch_use_struct_convention (gdbarch,
-                                      ppc_sysv_abi_use_struct_convention);
-  else
+  if (!sysv_abi)
     set_gdbarch_use_struct_convention (gdbarch,
                                       rs6000_use_struct_convention);
 
-  set_gdbarch_frameless_function_invocation (gdbarch,
-                                         rs6000_frameless_function_invocation);
+  set_gdbarch_deprecated_frameless_function_invocation (gdbarch, rs6000_frameless_function_invocation);
   set_gdbarch_deprecated_frame_chain (gdbarch, rs6000_frame_chain);
   set_gdbarch_deprecated_frame_saved_pc (gdbarch, rs6000_frame_saved_pc);
 
@@ -2996,6 +2932,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
+  if (from_xcoff_exec)
+    {
+      /* NOTE: jimix/2003-06-09: This test should really check for
+        GDB_OSABI_AIX when that is defined and becomes
+        available. (Actually, once things are properly split apart,
+        the test goes away.) */
+       /* RS6000/AIX does not support PT_STEP.  Has to be simulated.  */
+       set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
+    }
+
   return gdbarch;
 }
 
This page took 0.085094 seconds and 4 git commands to generate.