*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / ppc-sysv-tdep.c
index 8091c2f56c2907ad2a6b9454585093bbe85c0dd0..a1f52824398cf7b73e7eccc31b8dbf3f2daa92a1 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for PowerPC systems using the SVR4 ABI
    for GDB, the GNU debugger.
 
-   Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -28,6 +28,7 @@
 #include "gdb_string.h"
 #include "gdb_assert.h"
 #include "ppc-tdep.h"
+#include "target.h"
 
 /* Pass the arguments in either registers, or in the stack. Using the
    ppc sysv ABI, the first eight words of the argument list (that might
@@ -305,21 +306,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   return sp;
 }
 
-/* Potential ways that a function can return a value of a given type.  */
-enum return_value_convention
-{
-  /* Where the return value has been squeezed into one or more
-     registers.  */
-  RETURN_VALUE_REGISTER_CONVENTION,
-  /* Commonly known as the "struct return convention".  The caller
-     passes an additional hidden first parameter to the caller.  That
-     parameter contains the address at which the value being returned
-     should be stored.  While typically, and historically, used for
-     large structs, this is convention is applied to values of many
-     different types.  */
-  RETURN_VALUE_STRUCT_CONVENTION
-};
-
 /* Handle the return-value conventions specified by the SysV 32-bit
    PowerPC ABI (including all the supplements):
 
@@ -336,22 +322,22 @@ enum return_value_convention
    when returned in general-purpose registers.  */
 
 static enum return_value_convention
-do_ppc_sysv_return_value (struct type *type, struct regcache *regcache,
-                         const void *inval, void *outval, int broken_gcc)
+do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
+                         struct regcache *regcache, const void *inval,
+                         void *outval, int broken_gcc)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   gdb_assert (tdep->wordsize == 4);
   if (TYPE_CODE (type) == TYPE_CODE_FLT
       && TYPE_LENGTH (type) <= 8
-      && ppc_floating_point_unit_p (current_gdbarch))
+      && ppc_floating_point_unit_p (gdbarch))
     {
       if (outval)
        {
          /* Floats and doubles stored in "f1".  Convert the value to
             the required type.  */
          char regval[MAX_REGISTER_SIZE];
-         struct type *regtype = register_type (current_gdbarch,
-                                               FP0_REGNUM + 1);
+         struct type *regtype = register_type (gdbarch, FP0_REGNUM + 1);
          regcache_cooked_read (regcache, FP0_REGNUM + 1, regval);
          convert_typed_floating (regval, regtype, outval, type);
        }
@@ -360,7 +346,7 @@ do_ppc_sysv_return_value (struct type *type, struct regcache *regcache,
          /* Floats and doubles stored in "f1".  Convert the value to
             the register's "double" type.  */
          char regval[MAX_REGISTER_SIZE];
-         struct type *regtype = register_type (current_gdbarch, FP0_REGNUM);
+         struct type *regtype = register_type (gdbarch, FP0_REGNUM);
          convert_typed_floating (inval, type, regval, regtype);
          regcache_cooked_write (regcache, FP0_REGNUM + 1, regval);
        }
@@ -524,43 +510,19 @@ do_ppc_sysv_return_value (struct type *type, struct regcache *regcache,
   return RETURN_VALUE_STRUCT_CONVENTION;
 }
 
-void
-ppc_sysv_abi_extract_return_value (struct type *type,
-                                  struct regcache *regcache, void *valbuf)
-{
-  do_ppc_sysv_return_value (type, regcache, NULL, valbuf, 0);
-}
-
-void
-ppc_sysv_abi_broken_extract_return_value (struct type *type,
-                                         struct regcache *regcache,
-                                         void *valbuf)
-{
-  do_ppc_sysv_return_value (type, regcache, NULL, valbuf, 1);
-}
-
-void
-ppc_sysv_abi_store_return_value (struct type *type, struct regcache *regcache,
-                                const void *valbuf)
-{
-  do_ppc_sysv_return_value (type, regcache, valbuf, NULL, 0);
-}
-
-void
-ppc_sysv_abi_broken_store_return_value (struct type *type,
-                                       struct regcache *regcache,
-                                       const void *valbuf)
+enum return_value_convention
+ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                          struct regcache *regcache, const void *inval, void *outval)
 {
-  do_ppc_sysv_return_value (type, regcache, valbuf, NULL, 1);
+  return do_ppc_sysv_return_value (gdbarch, valtype, regcache, inval, outval, 0);
 }
 
-/* Structures 8 bytes or less long are returned in the r3 & r4
-   registers, according to the SYSV ABI. */
-int
-ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
+enum return_value_convention
+ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                                 struct regcache *regcache, const void *inval,
+                                 void *outval)
 {
-  return (do_ppc_sysv_return_value (value_type, NULL, NULL, NULL, 0)
-         == RETURN_VALUE_STRUCT_CONVENTION);
+  return do_ppc_sysv_return_value (gdbarch, valtype, regcache, inval, outval, 1);
 }
 
 /* Pass the arguments in either registers, or in the stack. Using the
@@ -863,16 +825,17 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
    copy the buffer to the corresponding register return-value location
    location; when OUTVAL is non-NULL, fill the buffer from the
    corresponding register return-value location.  */
-static enum return_value_convention
-ppc64_sysv_abi_return_value (struct type *valtype, struct regcache *regcache,
-                            const void *inval, void *outval)
+enum return_value_convention
+ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                            struct regcache *regcache, const void *inval,
+                            void *outval)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   /* Floats and doubles in F1.  */
   if (TYPE_CODE (valtype) == TYPE_CODE_FLT && TYPE_LENGTH (valtype) <= 8)
     {
       char regval[MAX_REGISTER_SIZE];
-      struct type *regtype = register_type (current_gdbarch, FP0_REGNUM);
+      struct type *regtype = register_type (gdbarch, FP0_REGNUM);
       if (inval != NULL)
        {
          convert_typed_floating (inval, valtype, regval, regtype);
@@ -921,7 +884,7 @@ ppc64_sysv_abi_return_value (struct type *valtype, struct regcache *regcache,
       && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1)
     {
       /* Small character arrays are returned, right justified, in r3.  */
-      int offset = (register_size (current_gdbarch, tdep->ppc_gp0_regnum + 3)
+      int offset = (register_size (gdbarch, tdep->ppc_gp0_regnum + 3)
                    - TYPE_LENGTH (valtype));
       if (inval != NULL)
        regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3,
@@ -1004,27 +967,20 @@ ppc64_sysv_abi_return_value (struct type *valtype, struct regcache *regcache,
   return RETURN_VALUE_STRUCT_CONVENTION;
 }
 
-int
-ppc64_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
-{
-  return (ppc64_sysv_abi_return_value (value_type, NULL, NULL, NULL)
-         == RETURN_VALUE_STRUCT_CONVENTION);
-}
-
-void
-ppc64_sysv_abi_extract_return_value (struct type *valtype,
-                                    struct regcache *regbuf, void *valbuf)
-{
-  if (ppc64_sysv_abi_return_value (valtype, regbuf, NULL, valbuf)
-      != RETURN_VALUE_REGISTER_CONVENTION)
-    error ("Function return value unknown");
-}
-
-void
-ppc64_sysv_abi_store_return_value (struct type *valtype,
-                                  struct regcache *regbuf,
-                                  const void *valbuf)
+CORE_ADDR
+ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch,
+                                         CORE_ADDR bpaddr)
 {
-  if (!ppc64_sysv_abi_return_value (valtype, regbuf, valbuf, NULL))
-    error ("Function return value location unknown");
+  /* PPC64 SYSV specifies that the minimal-symbol "FN" should point at
+     a function-descriptor while the corresponding minimal-symbol
+     ".FN" should point at the entry point.  Consequently, a command
+     like "break FN" applied to an object file with only minimal
+     symbols, will insert the breakpoint into the descriptor at "FN"
+     and not the function at ".FN".  Avoid this confusion by adjusting
+     any attempt to set a descriptor breakpoint into a corresponding
+     function breakpoint.  Note that GDB warns the user when this
+     adjustment is applied - that's ok as otherwise the user will have
+     no way of knowing why their breakpoint at "FN" resulted in the
+     program stopping at ".FN".  */
+  return gdbarch_convert_from_func_ptr_addr (gdbarch, bpaddr, &current_target);
 }
This page took 0.025972 seconds and 4 git commands to generate.