This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch/rfc] Add legacy_return_value for old struct-return code, eliminateextract_struct_value_address


Hello,

This adds a new function legacy_return_value, making it the default for the return_value architecture method, and moving the calls to the old struct-return code to that function.

To do this, however, I had to compromise a bit:

- deprecated_extract_struct_value_address call gone
As noted in gdbarch.sh, the correctness of this method is highly questionable. Most ABIs do not require the preservation of the struct-return address across inferior function calls making a correct implementation of this method impossible.


- [deprecated] extract_return_value no longer called for struct-return
Architectures that didn't provide extract_struct_value_address (v850 and AVR) ended having extract_return_value being called for a struct-return. However, as with extract_struct_value_address, the correctness of code trying to handle that case is equally questionable.
(The AVR doesn't even have code to handle this so removing the call fixes a bug).


comments?

I'm leaving this on the table for a week,
Andrew
2004-06-13  Andrew Cagney  <cagney@gnu.org>

	* gdbarch.sh (RETURN_VALUE): Default to legacy_return_value.
	* gdbarch.h, gdbarch.c: Re-generate.
	* Makefile.in (arch-utils.o): Update dependencies.
	* values.c (using_struct_return): Move code calling
	USE_STRUCT_CONVENTION to legacy_return_value, simplify.
	* stack.c (return_command): Move code calling STORE_RETURN_VALUE
	to legacy_return_value, simplify.
	* infcmd.c (print_return_value): Move code calling
	DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS and EXTRACT_RETURN_VALUE
	to legacy_return_value, simplify.
	* infcall.c (call_function_by_hand): Move code calling
	EXTRACT_RETURN_VALUE to legacy_return_value, simplify.
	* arch-utils.c: Update copyright.  Include "gdbcore.h".
	(legacy_return_value): New function.
	* arch-utils.h: Update copyright.
	(legacy_return_value): Declare.
	
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.586
diff -p -u -r1.586 Makefile.in
--- Makefile.in	8 Jun 2004 05:32:51 -0000	1.586
+++ Makefile.in	13 Jun 2004 17:49:25 -0000
@@ -1598,7 +1598,7 @@ annotate.o: annotate.c $(defs_h) $(annot
 arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(buildsym_h) \
 	$(gdbcmd_h) $(inferior_h) $(gdb_string_h) $(regcache_h) \
 	$(gdb_assert_h) $(sim_regno_h) $(osabi_h) $(version_h) \
-	$(floatformat_h)
+	$(floatformat_h) $(gdbcore_h)
 arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
 	$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h)
 arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.119
diff -p -u -r1.119 arch-utils.c
--- arch-utils.c	13 Jun 2004 13:42:31 -0000	1.119
+++ arch-utils.c	13 Jun 2004 17:49:26 -0000
@@ -1,7 +1,7 @@
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
-   Inc.
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
@@ -30,7 +30,7 @@
 #include "regcache.h"
 #include "gdb_assert.h"
 #include "sim-regno.h"
-
+#include "gdbcore.h"
 #include "osabi.h"
 
 #include "version.h"
@@ -60,13 +60,46 @@ legacy_store_return_value (struct type *
   DEPRECATED_STORE_RETURN_VALUE (type, b);
 }
 
-
 int
 always_use_struct_convention (int gcc_p, struct type *value_type)
 {
   return 1;
 }
 
+enum return_value_convention
+legacy_return_value (struct gdbarch *gdbarch, struct type *valtype,
+		     struct regcache *regcache, void *readbuf,
+		     const void *writebuf)
+{
+  /* NOTE: cagney/2004-06-13: The gcc_p parameter to
+     USE_STRUCT_CONVENTION isn't used.  */
+  int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+			|| TYPE_CODE (valtype) == TYPE_CODE_UNION
+			|| TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
+		       && USE_STRUCT_CONVENTION (0, valtype));
+
+  if (writebuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      /* NOTE: cagney/2004-06-13: See stack.c:return_command.  Old
+	 architectures don't expect STORE_RETURN_VALUE to handle small
+	 structures.  Should not be called with such types.  */
+      gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_STRUCT
+		  && TYPE_CODE (valtype) != TYPE_CODE_UNION);
+      STORE_RETURN_VALUE (valtype, regcache, writebuf);
+    }
+
+  if (readbuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      EXTRACT_RETURN_VALUE (valtype, regcache, readbuf);
+    }
+
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
+}
 
 int
 legacy_register_sim_regno (int regnum)
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.72
diff -p -u -r1.72 arch-utils.h
--- arch-utils.h	13 Jun 2004 13:42:31 -0000	1.72
+++ arch-utils.h	13 Jun 2004 17:49:26 -0000
@@ -1,7 +1,7 @@
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright 1998, 1999, 2000, 2002, 2003 Free Software Foundation,
-   Inc.
+   Copyright 1998, 1999, 2000, 2002, 2003, 2004 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
@@ -32,6 +32,15 @@ struct gdbarch_info;
 /* gdbarch trace variable */
 extern int gdbarch_debug;
 
+/* An implementation of return_value that props up architectures still
+   using USE_STRUCT_RETURN, EXTRACT_RETURN_VALUE and
+   STORE_RETURN_VALUE.  See also the hacks in "stack.c".  */
+enum return_value_convention legacy_return_value (struct gdbarch *gdbarch,
+						  struct type *valtype,
+						  struct regcache *regcache,
+						  void *readbuf,
+						  const void *writebuf);
+
 /* Implementation of extract return value that grubs around in the
    register cache.  */
 extern gdbarch_extract_return_value_ftype legacy_extract_return_value;
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.325
diff -p -u -r1.325 gdbarch.sh
--- gdbarch.sh	13 Jun 2004 17:04:49 -0000	1.325
+++ gdbarch.sh	13 Jun 2004 17:49:28 -0000
@@ -541,7 +541,11 @@ F:DEPRECATED_STORE_STRUCT_RETURN:void:de
 # should take the type/value of the function to be called and not the
 # return type.  This is left as an exercise for the reader.
 
-M::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf:valtype, regcache, readbuf, writebuf
+# NOTE: cagney/2004-06-13: The function stack.c:return_command uses
+# the predicate with default hack to avoid calling STORE_RETURN_VALUE
+# (via legacy_return_value), when a small struct is involved.
+
+M:::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf:valtype, regcache, readbuf, writebuf:::legacy_return_value
 
 # The deprecated methods EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE and
 # USE_STRUCT_CONVENTION have all been folded into RETURN_VALUE.
Index: infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.50
diff -p -u -r1.50 infcall.c
--- infcall.c	12 Jun 2004 18:02:29 -0000	1.50
+++ infcall.c	13 Jun 2004 17:49:29 -0000
@@ -939,7 +939,7 @@ the function call).", name);
 	 "struct return convention", check that PUSH_DUMMY_CALL isn't
 	 playing tricks.  */
       retval = value_at (value_type, struct_addr, NULL);
-    else if (gdbarch_return_value_p (current_gdbarch))
+    else
       {
 	/* This code only handles "register convention".  */
 	retval = allocate_value (value_type);
@@ -950,15 +950,6 @@ the function call).", name);
 			      VALUE_CONTENTS_RAW (retval) /*read*/,
 			      NULL /*write*/);
       }
-    else
-      {
-	/* 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.  */
-	retval = allocate_value (value_type);
-	EXTRACT_RETURN_VALUE (value_type, retbuf, VALUE_CONTENTS_RAW (retval));
-      }
     do_cleanups (retbuf_cleanup);
     return retval;
   }
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.116
diff -p -u -r1.116 infcmd.c
--- infcmd.c	13 Jun 2004 17:05:55 -0000	1.116
+++ infcmd.c	13 Jun 2004 17:49:34 -0000
@@ -1091,36 +1091,20 @@ print_return_value (int struct_return, s
      inferior function call code.  In fact, when inferior function
      calls are made async, this will likely be made the norm.  */
 
-  if (gdbarch_return_value_p (gdbarch))
-    {
-      switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL))
-	{
-	case RETURN_VALUE_REGISTER_CONVENTION:
-	case RETURN_VALUE_ABI_RETURNS_ADDRESS:
-	  value = allocate_value (value_type);
-	  CHECK_TYPEDEF (value_type);
-	  gdbarch_return_value (current_gdbarch, value_type, stop_registers,
-				VALUE_CONTENTS_RAW (value), NULL);
-	  break;
-	case RETURN_VALUE_STRUCT_CONVENTION:
-	  value = NULL;
-	  break;
-	default:
-	  internal_error (__FILE__, __LINE__, "bad switch");
-	}
-    }
-  else if (struct_return && DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
-    {
-      CORE_ADDR addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers);
-      if (!addr)
-	error ("Function return value unknown.");
-      value = value_at (value_type, addr, NULL);
-    }
-  else
+  switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL))
     {
+    case RETURN_VALUE_REGISTER_CONVENTION:
+    case RETURN_VALUE_ABI_RETURNS_ADDRESS:
       value = allocate_value (value_type);
-      EXTRACT_RETURN_VALUE (value_type, stop_registers,
-			    VALUE_CONTENTS_RAW (value));
+      CHECK_TYPEDEF (value_type);
+      gdbarch_return_value (current_gdbarch, value_type, stop_registers,
+			    VALUE_CONTENTS_RAW (value), NULL);
+      break;
+    case RETURN_VALUE_STRUCT_CONVENTION:
+      value = NULL;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
     }
 
   if (value)
Index: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.108
diff -p -u -r1.108 stack.c
--- stack.c	1 May 2004 21:11:16 -0000	1.108
+++ stack.c	13 Jun 2004 17:49:35 -0000
@@ -1870,24 +1870,12 @@ If you continue, the return value that y
   if (return_value != NULL)
     {
       struct type *return_type = VALUE_TYPE (return_value);
-      if (!gdbarch_return_value_p (current_gdbarch))
-	{
-	  STORE_RETURN_VALUE (return_type, current_regcache,
-			      VALUE_CONTENTS (return_value));
-	}
-      /* FIXME: cagney/2004-01-17: If extract_returned_value_address
-         is available and the function is using
-         RETURN_VALUE_STRUCT_CONVENTION, should use it to find the
-         address of the returned value so that it can be assigned.  */
-      else
-	{
-	  gdb_assert (gdbarch_return_value (current_gdbarch, return_type,
-					    NULL, NULL, NULL)
-		      == RETURN_VALUE_REGISTER_CONVENTION);
-	  gdbarch_return_value (current_gdbarch, return_type,
-				current_regcache, NULL /*read*/,
-				VALUE_CONTENTS (return_value) /*write*/);
-	}
+      gdb_assert (gdbarch_return_value (current_gdbarch, return_type,
+					NULL, NULL, NULL)
+		  == RETURN_VALUE_REGISTER_CONVENTION);
+      gdbarch_return_value (current_gdbarch, return_type,
+			    current_regcache, NULL /*read*/,
+			    VALUE_CONTENTS (return_value) /*write*/);
     }
 
   /* If we are at the end of a call dummy now, pop the dummy frame
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.68
diff -p -u -r1.68 values.c
--- values.c	13 Jun 2004 15:15:59 -0000	1.68
+++ values.c	13 Jun 2004 17:49:37 -0000
@@ -1247,20 +1247,6 @@ using_struct_return (struct type *value_
        code in "print_return_value".  */
     return 0;
 
-  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 USE_STRUCT_CONVENTION (gcc_p, value_type);
-      else
-	return 0;
-    }
-
   /* Probe the architecture for the return-value convention.  */
   return (gdbarch_return_value (current_gdbarch, value_type,
 				NULL, NULL, NULL)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]