Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: David Miller <davem@davemloft.net>
To: mark.kettenis@xs4all.nl
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH] Allow struct 'return' on 32-bit sparc.
Date: Tue, 05 Feb 2013 01:03:00 -0000	[thread overview]
Message-ID: <20130204.200254.1810401167797646953.davem@davemloft.net> (raw)
In-Reply-To: <201302042357.r14NvFNC023715@glazunov.sibelius.xs4all.nl>

From: Mark Kettenis <mark.kettenis@xs4all.nl>
Date: Tue, 5 Feb 2013 00:57:15 +0100 (CET)

> The sparc-tdep.c bits are correct as far as I can see.
> 
> I think it would be better if your new function would still have
> "struct_return" in its name.  My suggestion would be
> "struct_return_convention".
> 
> Also,
 ...
> Return RETURN_VALUE_REGISTER_CONVENTION if there is nothing to return
> seems to be a bit odd.  But since convention_for_return() is never
> called with code being TYPE_CODE (there is an explicit check for that
> in stack.c:return_command()) you could simply leave the check in
> using_struct_return().

Agreed on all counts, thanks for the feedback.

Here is the updated patch:

gdb/

	* sparc-tdep.c (sparc32_return_value): Handle writing return value when
	using RETURN_VALUE_ABI_PRESERVES_ADDRESS.
	* value.c (struct_return_convention): New function.
	(using_struct_return): Implement in terms of struct_return_convention.
	* value.h (struct_return_convention): Declare.
	* stack.c (return_command): Allow successful overriding of the return
	value when RETURN_VALUE_ABI_PRESERVES_ADDRESS.


diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 3ae7395..2b38521 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1370,15 +1370,21 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
   if (sparc_structure_or_union_p (type)
       || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
     {
+      ULONGEST sp;
+      CORE_ADDR addr;
+
       if (readbuf)
 	{
-	  ULONGEST sp;
-	  CORE_ADDR addr;
-
 	  regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
 	  addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
 	  read_memory (addr, readbuf, TYPE_LENGTH (type));
 	}
+      if (writebuf)
+	{
+	  regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
+	  addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
+	  write_memory (addr, writebuf, TYPE_LENGTH (type));
+	}
 
       return RETURN_VALUE_ABI_PRESERVES_ADDRESS;
     }
diff --git a/gdb/stack.c b/gdb/stack.c
index c8a6a7e..218fc01 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2274,6 +2274,7 @@ down_command (char *count_exp, int from_tty)
 void
 return_command (char *retval_exp, int from_tty)
 {
+  enum return_value_convention rv_conv;
   struct frame_info *thisframe;
   struct gdbarch *gdbarch;
   struct symbol *thisfun;
@@ -2327,6 +2328,7 @@ return_command (char *retval_exp, int from_tty)
       if (thisfun != NULL)
 	function = read_var_value (thisfun, thisframe);
 
+      rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
       if (TYPE_CODE (return_type) == TYPE_CODE_VOID)
 	/* If the return-type is "void", don't try to find the
            return-value's location.  However, do still evaluate the
@@ -2334,14 +2336,18 @@ return_command (char *retval_exp, int from_tty)
            is discarded, side effects such as "return i++" still
            occur.  */
 	return_value = NULL;
-      else if (thisfun != NULL
-	       && using_struct_return (gdbarch, function, return_type))
+      else if (thisfun != NULL)
 	{
-	  query_prefix = "The location at which to store the "
-	    "function's return value is unknown.\n"
-	    "If you continue, the return value "
-	    "that you specified will be ignored.\n";
-	  return_value = NULL;
+	  rv_conv = struct_return_convention (gdbarch, function, return_type);
+	  if (rv_conv == RETURN_VALUE_STRUCT_CONVENTION
+	      || rv_conv == RETURN_VALUE_ABI_RETURNS_ADDRESS)
+	    {
+	      query_prefix = "The location at which to store the "
+		"function's return value is unknown.\n"
+		"If you continue, the return value "
+		"that you specified will be ignored.\n";
+	      return_value = NULL;
+	    }
 	}
     }
 
@@ -2371,9 +2377,8 @@ return_command (char *retval_exp, int from_tty)
       struct type *return_type = value_type (return_value);
       struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
 
-      gdb_assert (gdbarch_return_value (gdbarch, function, return_type, NULL,
-					NULL, NULL)
-		  == RETURN_VALUE_REGISTER_CONVENTION);
+      gdb_assert (rv_conv != RETURN_VALUE_STRUCT_CONVENTION
+		  && rv_conv != RETURN_VALUE_ABI_RETURNS_ADDRESS);
       gdbarch_return_value (gdbarch, function, return_type,
 			    get_current_regcache (), NULL /*read*/,
 			    value_contents (return_value) /*write*/);
diff --git a/gdb/value.c b/gdb/value.c
index dbf1c37..4b70ece 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3323,6 +3323,23 @@ coerce_array (struct value *arg)
 }
 \f
 
+/* Return the return value convention that will be used for the
+   specified type.  */
+
+enum return_value_convention
+struct_return_convention (struct gdbarch *gdbarch,
+			  struct value *function, struct type *value_type)
+{
+  enum type_code code = TYPE_CODE (value_type);
+
+  if (code == TYPE_CODE_ERROR)
+    error (_("Function return type unknown."));
+
+  /* Probe the architecture for the return-value convention.  */
+  return gdbarch_return_value (gdbarch, function, value_type,
+			       NULL, NULL, NULL);
+}
+
 /* Return true if the function returning the specified type is using
    the convention of returning structures in memory (passing in the
    address as a hidden first parameter).  */
@@ -3331,19 +3348,12 @@ int
 using_struct_return (struct gdbarch *gdbarch,
 		     struct value *function, struct type *value_type)
 {
-  enum type_code code = TYPE_CODE (value_type);
-
-  if (code == TYPE_CODE_ERROR)
-    error (_("Function return type unknown."));
-
-  if (code == TYPE_CODE_VOID)
+  if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
     /* A void return value is never in memory.  See also corresponding
        code in "print_return_value".  */
     return 0;
 
-  /* Probe the architecture for the return-value convention.  */
-  return (gdbarch_return_value (gdbarch, function, value_type,
-				NULL, NULL, NULL)
+  return (struct_return_convention (gdbarch, function, value_type)
 	  != RETURN_VALUE_REGISTER_CONVENTION);
 }
 
diff --git a/gdb/value.h b/gdb/value.h
index b9013fd..c10c3ec 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -696,6 +696,10 @@ extern int value_in (struct value *element, struct value *set);
 extern int value_bit_index (struct type *type, const gdb_byte *addr,
 			    int index);
 
+extern enum return_value_convention
+struct_return_convention (struct gdbarch *gdbarch, struct value *function,
+			  struct type *value_type);
+
 extern int using_struct_return (struct gdbarch *gdbarch,
 				struct value *function,
 				struct type *value_type);


  reply	other threads:[~2013-02-05  1:03 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-01 21:13 David Miller
2013-02-04 23:57 ` Mark Kettenis
2013-02-05  1:03   ` David Miller [this message]
2013-02-05 20:19     ` Mark Kettenis
2013-02-05 20:31       ` David Miller
2013-02-06 19:41     ` David Miller
2013-02-08 18:17 ` Ulrich Weigand
2013-02-08 19:10   ` David Miller
2013-02-08 19:13     ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130204.200254.1810401167797646953.davem@davemloft.net \
    --to=davem@davemloft.net \
    --cc=gdb-patches@sourceware.org \
    --cc=mark.kettenis@xs4all.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox