Add self.
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index deb555521dffe8e381a08e81b47dd688ae7dbe44..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"
@@ -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;
        }
     }
@@ -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.  */
 
@@ -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 = DEPRECATED_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 = DEPRECATED_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.  */
 
@@ -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);
@@ -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 = DEPRECATED_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)
 {
@@ -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;
@@ -2952,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);
 
@@ -2999,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.02799 seconds and 4 git commands to generate.