This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH/RFC/RFA] Print in-memory struct return values
- From: Mark Kettenis <kettenis at chello dot nl>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 7 May 2004 19:07:46 +0200 (CEST)
- Subject: [PATCH/RFC/RFA] Print in-memory struct return values
The current GDB doesn't print the return value when using `finish' for
functions return structures that are not returned in registers. Note
that this is a regression from GDB 6.0 for many systems. Anyway, the
attached patch provides a way to fix this, and adds the necessary
support to the i386 target.
If there are no comments, I'll check this in in a few days. Eli, is
the doc bit OK?
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* gdbarch.sh (gdbarch_return_value_address): New method.
* gdbarch.h, gdbarch.c: Re-generate.
* infcmd.c (print_return_value): Use new
gdbarch_return_value_address method if provided.
* i386-tdep.c (i386_return_value_address): New function.
(i386_gdbarch_init): Set return_value_address.
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.108
diff -u -p -r1.108 infcmd.c
--- infcmd.c 28 Apr 2004 16:36:25 -0000 1.108
+++ infcmd.c 7 May 2004 17:05:04 -0000
@@ -1061,9 +1061,6 @@ print_return_value (int struct_return, s
/* The return value can be found in the inferior's registers. */
value = register_value_being_returned (value_type, stop_registers);
}
- /* FIXME: cagney/2004-01-17: When both return_value and
- extract_returned_value_address are available, should use that to
- find the address of and then extract the returned value. */
/* FIXME: 2003-09-27: When returning from a nested inferior function
call, it's possible (with no help from the architecture vector)
to locate and return/print a "struct return" value. This is just
@@ -1079,11 +1076,23 @@ print_return_value (int struct_return, s
gdb_assert (gdbarch_return_value (current_gdbarch, value_type,
NULL, NULL, NULL)
== RETURN_VALUE_STRUCT_CONVENTION);
- ui_out_text (uiout, "Value returned has type: ");
- ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
- ui_out_text (uiout, ".");
- ui_out_text (uiout, " Cannot determine contents\n");
- return;
+
+ if (gdbarch_return_value_address_p (current_gdbarch))
+ {
+ CORE_ADDR addr;
+
+ addr = gdbarch_return_value_address (current_gdbarch,
+ stop_registers);
+ value = value_at (value_type, addr, NULL);
+ }
+ else
+ {
+ ui_out_text (uiout, "Value returned has type: ");
+ ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
+ ui_out_text (uiout, ".");
+ ui_out_text (uiout, " Cannot determine contents\n");
+ return;
+ }
}
else
{
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.311
diff -u -p -r1.311 gdbarch.sh
--- gdbarch.sh 5 May 2004 15:42:52 -0000 1.311
+++ gdbarch.sh 7 May 2004 17:05:05 -0000
@@ -594,6 +594,8 @@ F:2:DEPRECATED_STORE_STRUCT_RETURN:void:
M:::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf:valtype, regcache, readbuf, writebuf
+M:::CORE_ADDR:return_value_address:struct regcache *regcache:regcache
+
# The deprecated methods RETURN_VALUE_ON_STACK, EXTRACT_RETURN_VALUE,
# STORE_RETURN_VALUE and USE_STRUCT_CONVENTION have all been folded
# into RETURN_VALUE.
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.190
diff -u -p -r1.190 i386-tdep.c
--- i386-tdep.c 30 Apr 2004 21:13:58 -0000 1.190
+++ i386-tdep.c 7 May 2004 17:05:05 -0000
@@ -1373,6 +1373,20 @@ i386_return_value (struct gdbarch *gdbar
return RETURN_VALUE_REGISTER_CONVENTION;
}
+
+/* Return the address where the return value can be found for
+ functions that use the REGISTER_VALUE_STRUCT_RETURN convention.
+ REGCACHE contains a copy of the registers from the just returned
+ function. */
+
+static CORE_ADDR
+i386_return_value_address (struct gdbarch *gdbarch, struct regcache *regcache)
+{
+ ULONGEST addr;
+
+ regcache_cooked_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
+ return addr;
+}
/* Return the GDB type object for the "standard" data type of data in
@@ -2041,6 +2055,7 @@ i386_gdbarch_init (struct gdbarch_info i
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
set_gdbarch_return_value (gdbarch, i386_return_value);
+ set_gdbarch_return_value_address (gdbarch, i386_return_value_address);
set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);
Index: doc/ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* gdbint.texinfo (Target Architecture Definition): Document
gdbarch_return_value_address.
Index: doc/gdbint.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.198
diff -u -p -r1.198 gdbint.texinfo
--- doc/gdbint.texinfo 1 May 2004 16:52:30 -0000 1.198
+++ doc/gdbint.texinfo 7 May 2004 17:05:07 -0000
@@ -3786,6 +3786,16 @@ to the inner most frame. While replacin
@code{struct frame_info} @var{frame} parameter would remove that
limitation there has yet to be a demonstrated need for such a change.}
+@item CORE_ADDR gdbarch_return_value_address (struct gdbarch *@var{gdbarch}, struct regcache *@var{regcache})
+@findex gdbarch_return_value_address
+@anchor{gdbarch_return_value_address} Return the address where the
+return value can be found for functions that use the
+@code{RETURN_VALUE_STRUCT_CONVENTION} return-value convention
+(@pxref{gdbarch_return_value}). A copy of the registers from the just
+returned function can be found in @var{regcache}. @emph{This method
+should only be provided if the address of the return value can be found
+reliably from the register contents upon function return.}
+
@item SKIP_PERMANENT_BREAKPOINT
@findex SKIP_PERMANENT_BREAKPOINT
Advance the inferior's PC past a permanent breakpoint. @value{GDBN} normally