2003-10-20 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / values.c
index 7b6ce6fc210f46ff81487a48138b1e408aa9bd65..da5c18022d6a5bdd3acee6d6851c08ba9f45ff46 100644 (file)
@@ -739,7 +739,14 @@ unpack_double (struct type *type, const char *valaddr, int *invp)
         also not defined either.  Oops!
 
          Hopefully someone will add both the missing floatformat
-         definitions and floatformat_is_invalid() function.  */
+         definitions and the new cases for floatformat_is_valid ().  */
+
+      if (!floatformat_is_valid (floatformat_from_type (type), valaddr))
+       {
+         *invp = 1;
+         return 0.0;
+       }
+
       return extract_typed_floating (valaddr, type);
     }
   else if (nosign)
@@ -876,7 +883,7 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type)
 
 struct value *
 value_primitive_field (struct value *arg1, int offset,
-                      register int fieldno, register struct type *arg_type)
+                      int fieldno, struct type *arg_type)
 {
   struct value *v;
   struct type *type;
@@ -945,7 +952,7 @@ value_primitive_field (struct value *arg1, int offset,
    FIELDNO says which field. */
 
 struct value *
-value_field (struct value *arg1, register int fieldno)
+value_field (struct value *arg1, int fieldno)
 {
   return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1));
 }
@@ -1107,7 +1114,7 @@ modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
 /* Convert C numbers into newly allocated values */
 
 struct value *
-value_from_longest (struct type *type, register LONGEST num)
+value_from_longest (struct type *type, LONGEST num)
 {
   struct value *val = allocate_value (type);
   enum type_code code;
@@ -1195,55 +1202,48 @@ value_from_double (struct type *type, DOUBLEST num)
   return val;
 }
 \f
-/* Deal with the value that is "about to be returned".  */
-
-/* Return the value that a function returning now
-   would be returning to its caller, assuming its type is VALTYPE.
-   RETBUF is where we look for what ought to be the contents
-   of the registers (in raw form).  This is because it is often
-   desirable to restore old values to those registers
-   after saving the contents of interest, and then call
-   this function using the saved values.
-   struct_return is non-zero when the function in question is
-   using the structure return conventions on the machine in question;
-   0 when it is using the value returning conventions (this often
-   means returning pointer to where structure is vs. returning value). */
-
-/* ARGSUSED */
+/* Deal with the return-value of a function that has "just returned".
+
+   Extract the return-value (as a "struct value") that a function,
+   using register convention, has just returned to its caller.  Assume
+   that the type of the function is VALTYPE, and that the "just
+   returned" register state is found in RETBUF.
+
+   The function has "just returned" because GDB halts a returning
+   function by setting a breakpoint at the return address (in the
+   caller), and not the return instruction (in the callee).
+
+   Because, in the case of a return from an inferior function call,
+   GDB needs to restore the inferiors registers, RETBUF is normally a
+   copy of the inferior's registers.  */
+
 struct value *
-value_being_returned (struct type *valtype, struct regcache *retbuf,
-                     int struct_return)
+register_value_being_returned (struct type *valtype, struct regcache *retbuf)
 {
-  struct value *val;
-  CORE_ADDR addr;
+  struct value *val = allocate_value (valtype);
 
-  /* If this is not defined, just use EXTRACT_RETURN_VALUE instead.  */
-  if (EXTRACT_STRUCT_VALUE_ADDRESS_P ())
-    if (struct_return)
-      {
-       addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf);
-       if (!addr)
-         error ("Function return value unknown.");
-       return value_at (valtype, addr, NULL);
-      }
+  /* If the function returns void, don't bother fetching the return
+     value.  */
+  if (TYPE_CODE (valtype) == TYPE_CODE_VOID)
+    return val;
 
-  /* If this is not defined, just use EXTRACT_RETURN_VALUE instead.  */
-  if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
-    if (struct_return)
-      {
-       char *buf = deprecated_grub_regcache_for_registers (retbuf);
-       addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (buf);
-       if (!addr)
-         error ("Function return value unknown.");
-       return value_at (valtype, addr, NULL);
-      }
-
-  val = allocate_value (valtype);
-  CHECK_TYPEDEF (valtype);
-  /* If the function returns void, don't bother fetching the return value.  */
-  if (TYPE_CODE (valtype) != TYPE_CODE_VOID)
-    EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
+  if (!gdbarch_return_value_p (current_gdbarch))
+    {
+      /* NOTE: cagney/2003-10-20: Unlike "gdbarch_return_value", the
+         EXTRACT_RETURN_VALUE and USE_STRUCT_CONVENTION methods do not
+         handle the edge case of a function returning a small
+         structure / union in registers.  */
+      CHECK_TYPEDEF (valtype);
+      EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
+      return val;
+    }
 
+  /* This function only handles "register convention".  */
+  gdb_assert (gdbarch_return_value (current_gdbarch, valtype,
+                                   NULL, NULL, NULL)
+             == RETURN_VALUE_REGISTER_CONVENTION);
+  gdbarch_return_value (current_gdbarch, valtype, retbuf,
+                       NULL, VALUE_CONTENTS_RAW (val));
   return val;
 }
 
@@ -1285,13 +1285,25 @@ using_struct_return (struct type *value_type, int gcc_p)
   if (code == TYPE_CODE_ERROR)
     error ("Function return type unknown.");
 
-  if (code == TYPE_CODE_STRUCT
-      || code == TYPE_CODE_UNION
-      || code == TYPE_CODE_ARRAY
-      || RETURN_VALUE_ON_STACK (value_type))
-    return USE_STRUCT_CONVENTION (gcc_p, value_type);
+  if (!gdbarch_return_value_p (current_gdbarch))
+    {
+      /* FIXME: cagney/2003-10-01: The below is dead.  Instead an
+        architecture should implement "gdbarch_return_value".  Using
+        that new function it is possible to exactly specify the ABIs
+        "struct return" vs "register return" conventions.  */
+      if (code == TYPE_CODE_STRUCT
+         || code == TYPE_CODE_UNION
+         || code == TYPE_CODE_ARRAY
+         || RETURN_VALUE_ON_STACK (value_type))
+       return USE_STRUCT_CONVENTION (gcc_p, value_type);
+      else
+       return 0;
+    }
 
-  return 0;
+  /* Probe the architecture for the return-value convention.  */
+  return (gdbarch_return_value (current_gdbarch, value_type,
+                               NULL, NULL, NULL)
+         == RETURN_VALUE_STRUCT_CONVENTION);
 }
 
 /* Store VAL so it will be returned if a function returns now.
@@ -1307,9 +1319,41 @@ set_return_value (struct value *val)
   if (code == TYPE_CODE_ERROR)
     error ("Function return type unknown.");
 
+  if (gdbarch_return_value_p (current_gdbarch))
+    {
+      switch (gdbarch_return_value (current_gdbarch, type, NULL, NULL, NULL))
+       {
+       case RETURN_VALUE_REGISTER_CONVENTION:
+         /* Success.  The architecture can deal with it, write it to
+             the regcache.  */
+         gdbarch_return_value (current_gdbarch, type, current_regcache,
+                               VALUE_CONTENTS (val), NULL);
+         return;
+       case RETURN_VALUE_STRUCT_CONVENTION:
+         /* Failure.  For the moment, assume that it is not possible
+             to find the location, on the stack, at which the "struct
+             return" value should be stored.  Only a warning because
+             an error aborts the "return" command leaving GDB in a
+             weird state.  */
+         warning ("Location of return value unknown");
+         return;
+       }
+    }
+
+
   if (code == TYPE_CODE_STRUCT
       || code == TYPE_CODE_UNION)      /* FIXME, implement struct return.  */
-    error ("GDB does not support specifying a struct or union return value.");
+    /* FIXME: cagney/2003-10-20: This should be an internal-warning.
+       The problem is that while GDB's core supports "struct return"
+       using "register convention", many architectures haven't been
+       updated to implement the mechanisms needed to make it work.
+       It's a warning, and not an error, as otherwize it will jump out
+       of the "return" command leaving both GDB and the user in a very
+       confused state.  */
+    {
+      warning ("This architecture does not support specifying a struct or union return-value.");
+      return;
+    }
 
   STORE_RETURN_VALUE (type, current_regcache, VALUE_CONTENTS (val));
 }
This page took 0.026127 seconds and 4 git commands to generate.