[RFA] Change gdbarch_return_value to take function type instead of return value type

Corinna Vinschen vinschen@redhat.com
Tue Oct 12 12:48:00 GMT 2004


Hi,

this is the third patch in the series of patches introducing the
calling_convention stuff.  This is also the last patch which adds or
changes generic functionality.  When all three patches get approved,
the follow-up patches will concentrate on using the calling_convention
information for the SH architecture.

This patch now has the following task.  The return_value functionality
currently gets only the return type of the function as parameter.  The
calling_convention information is given in the function type itself.
So the calling_convention information is missing in return_value.  The
below patch changes the return_value functionality throughout, to get
the function type as parameter instead of the return type.

When you look into the below patch, this looks a bit weird.  The
consequence of getting the function type instead of the return type
is, that all return_value function have to evaluate the return type
first:

  struct type *return_type = check_typedef (TYPE_TARGET_TYPE (func_type));

But apparently this approach is more generic and the additional function
type information is necessary to get calling convention specific into
this functionality.

The above change also requires a change of using_struct_return.  It now
gets the function type as well as the return value type.  Since
using_struct_return is the long arm of gdbarch_return_value anyway and
since all calling function have already evaluated the return value type,
this seems to make the most sense.  I also eliminated the "gcc_p"
parameter because it hasn't been used anymore for a while.

There's also an important change necessary to sparc-tdep.c.  sparc32 is the
only platform which calls using_struct_return from push_dummy_code.  Since
push_dummy_code only has the return value type, it can neither call 
using_struct_return nor gdbarch_return_value.  I've created a new static
function called "sparc32_using_struct_return" which only evaluates whether
a struct return condition exists or not.  The function is now used in
sparc32_push_dummy_code as well as in sparc32_return_value.

@Eli: I've also changed the gdbarch_return_value documentation in
      gdbint.texinfo.  I'm not quite sure if the @code brackets are
      correct here.  Can you advice?


Corinna


ChangeLog:

	* infcall.c (call_function_by_hand): Accomodate parameter change in
	calls to using_struct_return and gdbarch_return_value.
	* infcmd.c (print_return_value): Take function type instead of
	return value type. Accomodate parameter change in calls to 
	using_struct_return and gdbarch_return_value.
	(finish_command): Accomodate parameter change in calls to
	using_struct_return and print_return_value.
	* stack.c (return_command): Accomodate parameter change in calls to
	using_struct_return and gdbarch_return_value.
	* values.c (using_struct_return): Change to take function type and
	return value type. Drop gcc_p parameter.
	* value.h (using_struct_return): Change declaration accordingly.

	* gdbarch.sh (return_value): Change type parameter name to reflect
	getting the function type, not the return value type.
	* arch-utils.h (legacy_return_value): Ditto.
	* arch-utils.c (legacy_return_value): Change value type to function
	type parameter. Evaluate value type accordingly.
	* amd64-tdep.c (amd64_return_value): Ditto.
	* cris-tdep.c (cris_return_value): Ditto.
	* d10v-tdep.c (d10v_return_value): Ditto.
	* hppa-tdep.c (hppa32_return_value): Ditto.
	(hppa64_return_value): Ditto.
	* i386-tdep.c (i386_return_value): Ditto.
	* m32r-tdep.c (m32r_return_value): Ditto.
	* m68hc11-tdep.c (m68hc11_return_value): Ditto.
	* m68k-tdep.c (m68k_return_value): Ditto.
	(m68k_svr4_return_value): Ditto.
	* m88k-tdep.c (m88k_return_value): Ditto.
	* mips-tdep.c (mips_n32n64_return_value): Ditto.
	(mips_o32_return_value): Ditto.
	* mn10300-tdep.c (mn10300_return_value): Ditto.
	* ppc-linux-tdep.c (ppc_linux_return_value): Ditto.
	* ppc-sysv-tdep.c (ppc_sysv_abi_return_value): Ditto.
	(ppc_sysv_abi_broken_return_value): Ditto.
	* ppcnbsd-tdep.c (ppcnbsd_return_value): Ditto.
	* s390-tdep.c (s390_return_value): Ditto.
	* sh-tdep.c (sh_return_value_nofpu): Ditto.
	(sh_return_value_fpu): Ditto.
	* sparc-tdep.c (sparc32_using_struct_return): New static function.
	(sparc32_push_dummy_code): Call sparc32_using_struct_return instead
	of using_struct_return.
	(sparc32_return_value): Change value type to function type parameter.
	Evaluate value type accordingly.  Call sparc32_using_struct_return
	instead of self-evaluating struct_return condition.
	* sparc64-tdep.c (sparc64_return_value): Change value type to function
	type parameter. Evaluate value type accordingly.
	* vax-tdep.c (vax_return_value): Ditto.
	* xstormy16-tdep.c (xstormy16_return_value): Ditto.

doc/ChangeLog:

	* gdbint.texinfo (gdbarch_return_value): Change description to
	reflect the new menaing of the type parameter.

Index: amd64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64-tdep.c,v
retrieving revision 1.15
diff -u -p -r1.15 amd64-tdep.c
--- amd64-tdep.c	7 Jun 2004 02:02:45 -0000	1.15
+++ amd64-tdep.c	12 Oct 2004 11:37:42 -0000
@@ -404,11 +404,12 @@ amd64_classify (struct type *type, enum 
 }
 
 static enum return_value_convention
-amd64_return_value (struct gdbarch *gdbarch, struct type *type,
+amd64_return_value (struct gdbarch *gdbarch, struct type *functype,
 		    struct regcache *regcache,
 		    void *readbuf, const void *writebuf)
 {
   enum amd64_reg_class class[2];
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   int len = TYPE_LENGTH (type);
   static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM };
   static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM };
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.122
diff -u -p -r1.122 arch-utils.c
--- arch-utils.c	5 Aug 2004 14:12:38 -0000	1.122
+++ arch-utils.c	12 Oct 2004 11:37:42 -0000
@@ -67,10 +67,11 @@ always_use_struct_convention (int gcc_p,
 }
 
 enum return_value_convention
-legacy_return_value (struct gdbarch *gdbarch, struct type *valtype,
+legacy_return_value (struct gdbarch *gdbarch, struct type *functype,
 		     struct regcache *regcache, void *readbuf,
 		     const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
   /* 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
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.75
diff -u -p -r1.75 arch-utils.h
--- arch-utils.h	5 Aug 2004 14:12:38 -0000	1.75
+++ arch-utils.h	12 Oct 2004 11:37:42 -0000
@@ -36,7 +36,7 @@ extern int gdbarch_debug;
    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 type *functype,
 						  struct regcache *regcache,
 						  void *readbuf,
 						  const void *writebuf);
Index: cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.117
diff -u -p -r1.117 cris-tdep.c
--- cris-tdep.c	11 Oct 2004 15:02:20 -0000	1.117
+++ cris-tdep.c	12 Oct 2004 11:37:43 -0000
@@ -1580,10 +1580,12 @@ cris_extract_return_value (struct type *
 /* Handle the CRIS return value convention.  */
 
 static enum return_value_convention
-cris_return_value (struct gdbarch *gdbarch, struct type *type,
+cris_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *readbuf,
 		   const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (TYPE_CODE (type) == TYPE_CODE_STRUCT 
       || TYPE_CODE (type) == TYPE_CODE_UNION
       || TYPE_LENGTH (type) > 8)
Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.149
diff -u -p -r1.149 d10v-tdep.c
--- d10v-tdep.c	11 Sep 2004 10:24:45 -0000	1.149
+++ d10v-tdep.c	12 Oct 2004 11:37:43 -0000
@@ -371,10 +371,12 @@ d10v_integer_to_address (struct type *ty
 /* Handle the d10v's return_value convention.  */
 
 static enum return_value_convention
-d10v_return_value (struct gdbarch *gdbarch, struct type *valtype,
+d10v_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *readbuf,
 		   const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (TYPE_LENGTH (valtype) > 8)
     /* Anything larger than 8 bytes (4 registers) goes on the stack.  */
     return RETURN_VALUE_STRUCT_CONVENTION;
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.348
diff -u -p -r1.348 gdbarch.sh
--- gdbarch.sh	2 Sep 2004 17:22:08 -0000	1.348
+++ gdbarch.sh	12 Oct 2004 11:37:45 -0000
@@ -513,7 +513,7 @@ F:=:void:deprecated_store_struct_return:
 # 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
+M::enum return_value_convention:return_value:struct type *functype, struct regcache *regcache, void *readbuf, const void *writebuf:functype, regcache, readbuf, writebuf::legacy_return_value
 
 # The deprecated methods EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE,
 # DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS and
Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.173
diff -u -p -r1.173 hppa-tdep.c
--- hppa-tdep.c	31 Jul 2004 21:53:17 -0000	1.173
+++ hppa-tdep.c	12 Oct 2004 11:37:46 -0000
@@ -77,9 +77,11 @@ int hppa_instruction_nullified (void);
 
 static enum return_value_convention
 hppa32_return_value (struct gdbarch *gdbarch,
-		     struct type *type, struct regcache *regcache,
+		     struct type *functype, struct regcache *regcache,
 		     void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (TYPE_LENGTH (type) <= 2 * 4)
     {
       /* The value always lives in the right hand end of the register
@@ -117,9 +119,11 @@ hppa32_return_value (struct gdbarch *gdb
 
 static enum return_value_convention
 hppa64_return_value (struct gdbarch *gdbarch,
-		     struct type *type, struct regcache *regcache,
+		     struct type *functype, struct regcache *regcache,
 		     void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   /* RM: Floats are returned in FR4R, doubles in FR4.  Integral values
      are in r28, padded on the left.  Aggregates less that 65 bits are
      in r28, right padded.  Aggregates upto 128 bits are in r28 and
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.201
diff -u -p -r1.201 i386-tdep.c
--- i386-tdep.c	18 Sep 2004 20:16:37 -0000	1.201
+++ i386-tdep.c	12 Oct 2004 11:37:46 -0000
@@ -1429,10 +1429,11 @@ i386_reg_struct_return_p (struct gdbarch
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
-i386_return_value (struct gdbarch *gdbarch, struct type *type,
+i386_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *readbuf,
 		   const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   enum type_code code = TYPE_CODE (type);
 
   if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
@@ -1469,7 +1470,7 @@ i386_return_value (struct gdbarch *gdbar
   if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
     {
       type = check_typedef (TYPE_FIELD_TYPE (type, 0));
-      return i386_return_value (gdbarch, type, regcache, readbuf, writebuf);
+      return i386_return_value (gdbarch, functype, regcache, readbuf, writebuf);
     }
 
   if (readbuf)
Index: infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.58
diff -u -p -r1.58 infcall.c
--- infcall.c	8 Oct 2004 08:15:56 -0000	1.58
+++ infcall.c	12 Oct 2004 11:37:46 -0000
@@ -413,7 +413,7 @@ call_function_by_hand (struct value *fun
   /* Are we returning a value using a structure return or a normal
      value return? */
 
-  struct_return = using_struct_return (value_type, using_gcc);
+  struct_return = using_struct_return (VALUE_TYPE (function), value_type);
 
   /* Determine the location of the breakpoint (and possibly other
      stuff) that the called function will return to.  The SPARC, for a
@@ -857,11 +857,12 @@ the function call).", name);
       {
 	/* This code only handles "register convention".  */
 	retval = allocate_value (value_type);
-	gdb_assert (gdbarch_return_value (current_gdbarch, value_type,
+	gdb_assert (gdbarch_return_value (current_gdbarch,
+					  VALUE_TYPE (function),
 					  NULL, NULL, NULL)
 		    == RETURN_VALUE_REGISTER_CONVENTION);
-	gdbarch_return_value (current_gdbarch, value_type, retbuf,
-			      VALUE_CONTENTS_RAW (retval) /*read*/,
+	gdbarch_return_value (current_gdbarch, VALUE_TYPE (function),
+			      retbuf, VALUE_CONTENTS_RAW (retval) /*read*/,
 			      NULL /*write*/);
       }
     do_cleanups (retbuf_cleanup);
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.123
diff -u -p -r1.123 infcmd.c
--- infcmd.c	13 Sep 2004 18:26:28 -0000	1.123
+++ infcmd.c	12 Oct 2004 11:37:47 -0000
@@ -64,7 +64,7 @@ void interrupt_target_command (char *arg
 
 static void nofp_registers_info (char *, int);
 
-static void print_return_value (int struct_return, struct type *value_type);
+static void print_return_value (int struct_return, struct type *func_type);
 
 static void finish_command_continuation (struct continuation_arg *);
 
@@ -1075,12 +1075,13 @@ advance_command (char *arg, int from_tty
 /* Print the result of a function at the end of a 'finish' command.  */
 
 static void
-print_return_value (int struct_return, struct type *value_type)
+print_return_value (int struct_return, struct type *func_type)
 {
   struct gdbarch *gdbarch = current_gdbarch;
   struct cleanup *old_chain;
   struct ui_stream *stb;
   struct value *value;
+  struct type *value_type = TYPE_TARGET_TYPE (func_type);
 
   gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
 
@@ -1091,13 +1092,13 @@ 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.  */
 
-  switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL))
+  switch (gdbarch_return_value (gdbarch, func_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,
+      gdbarch_return_value (current_gdbarch, func_type, stop_registers,
 			    VALUE_CONTENTS_RAW (value), NULL);
       break;
     case RETURN_VALUE_STRUCT_CONVENTION:
@@ -1170,9 +1171,9 @@ finish_command_continuation (struct cont
 
       CHECK_TYPEDEF (value_type);
       gcc_compiled = BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function));
-      struct_return = using_struct_return (value_type, gcc_compiled);
+      struct_return = using_struct_return (SYMBOL_TYPE (function), value_type);
 
-      print_return_value (struct_return, value_type); 
+      print_return_value (struct_return, SYMBOL_TYPE (function)); 
     }
 
   do_exec_cleanups (cleanups);
@@ -1293,9 +1294,10 @@ finish_command (char *arg, int from_tty)
 
 	  CHECK_TYPEDEF (value_type);
 	  gcc_compiled = BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function));
-	  struct_return = using_struct_return (value_type, gcc_compiled);
+	  struct_return = using_struct_return (SYMBOL_TYPE (function),
+					       value_type);
 
-	  print_return_value (struct_return, value_type); 
+	  print_return_value (struct_return, SYMBOL_TYPE (function)); 
 	}
 
       do_cleanups (old_chain);
Index: m32r-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m32r-tdep.c,v
retrieving revision 1.33
diff -u -p -r1.33 m32r-tdep.c
--- m32r-tdep.c	7 Oct 2004 01:21:53 -0000	1.33
+++ m32r-tdep.c	12 Oct 2004 11:37:47 -0000
@@ -788,10 +788,12 @@ m32r_extract_return_value (struct type *
 }
 
 enum return_value_convention
-m32r_return_value (struct gdbarch *gdbarch, struct type *valtype,
+m32r_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *readbuf,
 		   const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (TYPE_LENGTH (valtype) > 8)
     return RETURN_VALUE_STRUCT_CONVENTION;
   else
Index: m68hc11-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68hc11-tdep.c,v
retrieving revision 1.104
diff -u -p -r1.104 m68hc11-tdep.c
--- m68hc11-tdep.c	31 Jul 2004 21:53:17 -0000	1.104
+++ m68hc11-tdep.c	12 Oct 2004 11:37:47 -0000
@@ -1333,10 +1333,12 @@ m68hc11_extract_return_value (struct typ
 }
 
 enum return_value_convention
-m68hc11_return_value (struct gdbarch *gdbarch, struct type *valtype,
+m68hc11_return_value (struct gdbarch *gdbarch, struct type *functype,
 		      struct regcache *regcache, void *readbuf,
 		      const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
       || TYPE_CODE (valtype) == TYPE_CODE_UNION
       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY 
Index: m68k-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68k-tdep.c,v
retrieving revision 1.95
diff -u -p -r1.95 m68k-tdep.c
--- m68k-tdep.c	2 Sep 2004 19:16:36 -0000	1.95
+++ m68k-tdep.c	12 Oct 2004 11:37:47 -0000
@@ -329,10 +329,11 @@ m68k_reg_struct_return_p (struct gdbarch
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
-m68k_return_value (struct gdbarch *gdbarch, struct type *type,
+m68k_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *readbuf,
 		   const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   enum type_code code = TYPE_CODE (type);
 
   if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
@@ -352,10 +353,11 @@ m68k_return_value (struct gdbarch *gdbar
 }
 
 static enum return_value_convention
-m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *type,
+m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *functype,
 			struct regcache *regcache, void *readbuf,
 			const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   enum type_code code = TYPE_CODE (type);
 
   if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
@@ -391,7 +393,7 @@ m68k_svr4_return_value (struct gdbarch *
   if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
     {
       type = check_typedef (TYPE_FIELD_TYPE (type, 0));
-      return m68k_svr4_return_value (gdbarch, type, regcache,
+      return m68k_svr4_return_value (gdbarch, functype, regcache,
 				     readbuf, writebuf);
     }
 
Index: m88k-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m88k-tdep.c,v
retrieving revision 1.14
diff -u -p -r1.14 m88k-tdep.c
--- m88k-tdep.c	31 Jul 2004 21:53:17 -0000	1.14
+++ m88k-tdep.c	12 Oct 2004 11:37:47 -0000
@@ -383,10 +383,11 @@ m88k_unwind_dummy_id (struct gdbarch *ar
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
-m88k_return_value (struct gdbarch *gdbarch, struct type *type,
+m88k_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *readbuf,
 		   const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   int len = TYPE_LENGTH (type);
   char buf[8];
 
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.331
diff -u -p -r1.331 mips-tdep.c
--- mips-tdep.c	11 Oct 2004 02:27:13 -0000	1.331
+++ mips-tdep.c	12 Oct 2004 11:37:48 -0000
@@ -3561,9 +3561,10 @@ mips_n32n64_push_dummy_call (struct gdba
 
 static enum return_value_convention
 mips_n32n64_return_value (struct gdbarch *gdbarch,
-			  struct type *type, struct regcache *regcache,
+			  struct type *functype, struct regcache *regcache,
 			  void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
       || TYPE_CODE (type) == TYPE_CODE_UNION
@@ -3975,10 +3976,11 @@ mips_o32_push_dummy_call (struct gdbarch
 }
 
 static enum return_value_convention
-mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
+mips_o32_return_value (struct gdbarch *gdbarch, struct type *functype,
 		       struct regcache *regcache,
 		       void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
Index: mn10300-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mn10300-tdep.c,v
retrieving revision 1.112
diff -u -p -r1.112 mn10300-tdep.c
--- mn10300-tdep.c	3 Aug 2004 02:02:22 -0000	1.112
+++ mn10300-tdep.c	12 Oct 2004 11:37:48 -0000
@@ -296,10 +296,12 @@ mn10300_use_struct_convention (struct ty
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
-mn10300_return_value (struct gdbarch *gdbarch, struct type *type,
+mn10300_return_value (struct gdbarch *gdbarch, struct type *functype,
 		      struct regcache *regcache, void *readbuf,
 		      const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (mn10300_use_struct_convention (type))
     return RETURN_VALUE_STRUCT_CONVENTION;
 
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.66
diff -u -p -r1.66 ppc-linux-tdep.c
--- ppc-linux-tdep.c	31 Jul 2004 21:53:17 -0000	1.66
+++ ppc-linux-tdep.c	12 Oct 2004 11:37:48 -0000
@@ -483,18 +483,20 @@ ppc_linux_memory_remove_breakpoint (CORE
    which were added later, do get returned in a register though.  */
 
 static enum return_value_convention
-ppc_linux_return_value (struct gdbarch *gdbarch, struct type *valtype,
+ppc_linux_return_value (struct gdbarch *gdbarch, struct type *functype,
 			struct regcache *regcache, void *readbuf,
 			const void *writebuf)
 {  
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
        || TYPE_CODE (valtype) == TYPE_CODE_UNION)
       && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
 	   && TYPE_VECTOR (valtype)))
     return RETURN_VALUE_STRUCT_CONVENTION;
   else
-    return ppc_sysv_abi_return_value (gdbarch, valtype, regcache, readbuf,
-				      writebuf);
+    return ppc_sysv_abi_return_value (gdbarch, functype, regcache,
+				      readbuf, writebuf);
 }
 
 /* Fetch (and possibly build) an appropriate link_map_offsets
Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.24
diff -u -p -r1.24 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c	7 Jun 2004 02:02:52 -0000	1.24
+++ ppc-sysv-tdep.c	12 Oct 2004 11:37:48 -0000
@@ -515,20 +515,22 @@ do_ppc_sysv_return_value (struct gdbarch
 }
 
 enum return_value_convention
-ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
+ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *functype,
 			   struct regcache *regcache, void *readbuf,
 			   const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
   return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf,
 				   writebuf, 0);
 }
 
 enum return_value_convention
 ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch,
-				  struct type *valtype,
+				  struct type *functype,
 				  struct regcache *regcache,
 				  void *readbuf, const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
   return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf,
 				   writebuf, 1);
 }
@@ -847,10 +849,11 @@ ppc64_sysv_abi_push_dummy_call (struct g
    location; when READBUF is non-NULL, fill the buffer from the
    corresponding register return-value location.  */
 enum return_value_convention
-ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
+ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *functype,
 			     struct regcache *regcache, void *readbuf,
 			     const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* This function exists to support a calling convention that
Index: ppcnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppcnbsd-tdep.c,v
retrieving revision 1.25
diff -u -p -r1.25 ppcnbsd-tdep.c
--- ppcnbsd-tdep.c	24 Jul 2004 01:00:20 -0000	1.25
+++ ppcnbsd-tdep.c	12 Oct 2004 11:37:49 -0000
@@ -245,10 +245,12 @@ static struct core_fns ppcnbsd_elfcore_f
    the moment use the broken convention.  Ulgh!.  */
 
 static enum return_value_convention
-ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype,
+ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *functype,
 		      struct regcache *regcache, void *readbuf,
 		      const void *writebuf)
 {
+  struct type *valtype = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
        || TYPE_CODE (valtype) == TYPE_CODE_UNION)
       && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
@@ -259,7 +261,7 @@ ppcnbsd_return_value (struct gdbarch *gd
 	   || TYPE_LENGTH (valtype) == 8))
     return RETURN_VALUE_STRUCT_CONVENTION;
   else
-    return ppc_sysv_abi_broken_return_value (gdbarch, valtype, regcache,
+    return ppc_sysv_abi_broken_return_value (gdbarch, functype, regcache,
 					     readbuf, writebuf);
 }
 
Index: s390-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/s390-tdep.c,v
retrieving revision 1.135
diff -u -p -r1.135 s390-tdep.c
--- s390-tdep.c	31 Jul 2004 21:53:17 -0000	1.135
+++ s390-tdep.c	12 Oct 2004 11:37:49 -0000
@@ -2771,10 +2771,11 @@ s390_return_value_convention (struct gdb
 }
 
 static enum return_value_convention
-s390_return_value (struct gdbarch *gdbarch, struct type *type, 
+s390_return_value (struct gdbarch *gdbarch, struct type *functype,
 		   struct regcache *regcache, void *out, const void *in)
 {
   int word_size = gdbarch_ptr_bit (gdbarch) / 8;
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   int length = TYPE_LENGTH (type);
   enum return_value_convention rvc = 
 			s390_return_value_convention (gdbarch, type);
Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.177
diff -u -p -r1.177 sh-tdep.c
--- sh-tdep.c	6 Oct 2004 08:59:02 -0000	1.177
+++ sh-tdep.c	12 Oct 2004 11:37:49 -0000
@@ -1282,10 +1282,12 @@ sh3e_sh4_store_return_value (struct type
 }
 
 static enum return_value_convention
-sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *type,
+sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *functype,
 		       struct regcache *regcache,
 		       void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (sh_use_struct_convention (0, type))
     return RETURN_VALUE_STRUCT_CONVENTION;
   if (writebuf)
@@ -1296,10 +1298,12 @@ sh_return_value_nofpu (struct gdbarch *g
 }
 
 static enum return_value_convention
-sh_return_value_fpu (struct gdbarch *gdbarch, struct type *type,
+sh_return_value_fpu (struct gdbarch *gdbarch, struct type *functype,
 		     struct regcache *regcache,
 		     void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (sh_use_struct_convention (0, type))
     return RETURN_VALUE_STRUCT_CONVENTION;
   if (writebuf)
Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.153
diff -u -p -r1.153 sparc-tdep.c
--- sparc-tdep.c	7 Jun 2004 02:02:55 -0000	1.153
+++ sparc-tdep.c	12 Oct 2004 12:28:27 -0000
@@ -241,6 +241,15 @@ sparc_structure_or_union_p (const struct
   return 0;
 }
 
+static int
+sparc32_using_struct_return (struct type *type)
+{
+  if (sparc_structure_or_union_p (type)
+      || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
+    return 1;
+  return 0;
+}
+
 /* Register information.  */
 
 static const char *sparc32_register_names[] =
@@ -343,7 +352,7 @@ sparc32_push_dummy_code (struct gdbarch 
   *bp_addr = sp - 4;
   *real_pc = funcaddr;
 
-  if (using_struct_return (value_type, using_gcc))
+  if (sparc32_using_struct_return (value_type))
     {
       char buf[4];
 
@@ -892,12 +901,13 @@ sparc32_store_return_value (struct type 
 }
 
 static enum return_value_convention
-sparc32_return_value (struct gdbarch *gdbarch, struct type *type,
+sparc32_return_value (struct gdbarch *gdbarch, struct type *functype,
 		      struct regcache *regcache, void *readbuf,
 		      const void *writebuf)
 {
-  if (sparc_structure_or_union_p (type)
-      || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
+  if (sparc32_using_struct_return (type))
     return RETURN_VALUE_STRUCT_CONVENTION;
 
   if (readbuf)
Index: sparc64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-tdep.c,v
retrieving revision 1.14
diff -u -p -r1.14 sparc64-tdep.c
--- sparc64-tdep.c	24 Jun 2004 19:36:41 -0000	1.14
+++ sparc64-tdep.c	12 Oct 2004 11:37:50 -0000
@@ -1060,10 +1060,12 @@ sparc64_store_return_value (struct type 
 }
 
 static enum return_value_convention
-sparc64_return_value (struct gdbarch *gdbarch, struct type *type,
+sparc64_return_value (struct gdbarch *gdbarch, struct type *functype,
 		      struct regcache *regcache, void *readbuf,
 		      const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (TYPE_LENGTH (type) > 32)
     return RETURN_VALUE_STRUCT_CONVENTION;
 
Index: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.112
diff -u -p -r1.112 stack.c
--- stack.c	3 Aug 2004 00:57:26 -0000	1.112
+++ stack.c	12 Oct 2004 11:37:50 -0000
@@ -1816,7 +1816,7 @@ A structure or union return type is not 
 If you continue, the return value that you specified will be ignored.\n";
 	  return_value = NULL;
 	}
-      else if (using_struct_return (return_type, 0))
+      else if (using_struct_return (SYMBOL_TYPE (thisfun), return_type))
 	{
 	  query_prefix = "\
 The location at which to store the function's return value is unknown.\n\
@@ -1866,11 +1866,10 @@ If you continue, the return value that y
   /* Store RETURN_VAUE in the just-returned register set.  */
   if (return_value != NULL)
     {
-      struct type *return_type = VALUE_TYPE (return_value);
-      gdb_assert (gdbarch_return_value (current_gdbarch, return_type,
-					NULL, NULL, NULL)
+      gdb_assert (gdbarch_return_value (current_gdbarch, SYMBOL_TYPE (thisfun),
+      					NULL, NULL, NULL)
 		  == RETURN_VALUE_REGISTER_CONVENTION);
-      gdbarch_return_value (current_gdbarch, return_type,
+      gdbarch_return_value (current_gdbarch, SYMBOL_TYPE (thisfun),
 			    current_regcache, NULL /*read*/,
 			    VALUE_CONTENTS (return_value) /*write*/);
     }
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.55
diff -u -p -r1.55 value.h
--- value.h	10 Jun 2004 17:39:28 -0000	1.55
+++ value.h	12 Oct 2004 11:37:50 -0000
@@ -423,7 +423,7 @@ extern struct value *value_in (struct va
 
 extern int value_bit_index (struct type *type, char *addr, int index);
 
-extern int using_struct_return (struct type *value_type, int gcc_p);
+extern int using_struct_return (struct type *func_type, struct type *value_type);
 
 extern struct value *evaluate_expression (struct expression *exp);
 
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.71
diff -u -p -r1.71 values.c
--- values.c	28 Jul 2004 02:46:24 -0000	1.71
+++ values.c	12 Oct 2004 11:37:50 -0000
@@ -1238,7 +1238,7 @@ generic_use_struct_convention (int gcc_p
    with GCC.  */
 
 int
-using_struct_return (struct type *value_type, int gcc_p)
+using_struct_return (struct type *func_type, struct type *value_type)
 {
   enum type_code code = TYPE_CODE (value_type);
 
@@ -1251,8 +1251,7 @@ using_struct_return (struct type *value_
     return 0;
 
   /* Probe the architecture for the return-value convention.  */
-  return (gdbarch_return_value (current_gdbarch, value_type,
-				NULL, NULL, NULL)
+  return (gdbarch_return_value (current_gdbarch, func_type, NULL, NULL, NULL)
 	  != RETURN_VALUE_REGISTER_CONVENTION);
 }
 
Index: vax-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/vax-tdep.c,v
retrieving revision 1.85
diff -u -p -r1.85 vax-tdep.c
--- vax-tdep.c	8 Aug 2004 10:38:29 -0000	1.85
+++ vax-tdep.c	12 Oct 2004 11:37:50 -0000
@@ -202,10 +202,11 @@ vax_unwind_dummy_id (struct gdbarch *gdb
 
 
 static enum return_value_convention
-vax_return_value (struct gdbarch *gdbarch, struct type *type,
+vax_return_value (struct gdbarch *gdbarch, struct type *functype,
 		  struct regcache *regcache, void *readbuf,
 		  const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
   int len = TYPE_LENGTH (type);
   char buf[8];
 
Index: xstormy16-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/xstormy16-tdep.c,v
retrieving revision 1.82
diff -u -p -r1.82 xstormy16-tdep.c
--- xstormy16-tdep.c	23 Sep 2004 17:00:16 -0000	1.82
+++ xstormy16-tdep.c	12 Oct 2004 11:37:50 -0000
@@ -199,10 +199,12 @@ xstormy16_store_return_value (struct typ
 }
 
 static enum return_value_convention
-xstormy16_return_value (struct gdbarch *gdbarch, struct type *type,
+xstormy16_return_value (struct gdbarch *gdbarch, struct type *functype,
 			struct regcache *regcache,
 			void *readbuf, const void *writebuf)
 {
+  struct type *type = check_typedef (TYPE_TARGET_TYPE (functype));
+
   if (xstormy16_use_struct_convention (type))
     return RETURN_VALUE_STRUCT_CONVENTION;
   if (writebuf)
Index: doc/gdbint.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.225
diff -u -p -r1.225 gdbint.texinfo
--- doc/gdbint.texinfo	8 Oct 2004 15:34:31 -0000	1.225
+++ doc/gdbint.texinfo	12 Oct 2004 11:43:40 -0000
@@ -3645,11 +3645,14 @@ allocated on the stack.  @xref{unwind_du
 Define this to convert sdb register numbers into @value{GDBN} regnums.  If not
 defined, no conversion will be done.
 
-@item enum return_value_convention gdbarch_return_value (struct gdbarch *@var{gdbarch}, struct type *@var{valtype}, struct regcache *@var{regcache}, void *@var{readbuf}, const void *@var{writebuf})
+@item enum return_value_convention gdbarch_return_value (struct gdbarch *@var{gdbarch}, struct type *@var{functype}, struct regcache *@var{regcache}, void *@var{readbuf}, const void *@var{writebuf})
 @findex gdbarch_return_value
-@anchor{gdbarch_return_value} Given a function with a return-value of
-type @var{rettype}, return which return-value convention that function
-would use.
+@anchor{gdbarch_return_value} Given a function with type @var{functype},
+return which return-value convention that function would use.
+Note that @var{functype} contains the function type, not the return type
+of the function.  To evaluate the correct return value,
+@code{gdbarch_return_value} needs to extract the return type first.
+This is usually done by calling @code{struct type *return_type = check_typedef (TYPE_TARGET_TYPE (functype));}
 
 @value{GDBN} currently recognizes two function return-value conventions:
 @code{RETURN_VALUE_REGISTER_CONVENTION} where the return value is found

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat, Inc.



More information about the Gdb-patches mailing list