aboutsummaryrefslogtreecommitdiff
path: root/gdb/infcmd.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2004-05-08 23:02:10 +0000
committerMark Kettenis <kettenis@gnu.org>2004-05-08 23:02:10 +0000
commit31db7b6c38e66697f1353f6fbfba62c306d84240 (patch)
tree8837c3b26c49054e0d70bf118a97a36394fa6c88 /gdb/infcmd.c
parent0543f3876c21499784e5f3624fd74bee30951874 (diff)
downloadgdb-31db7b6c38e66697f1353f6fbfba62c306d84240.zip
gdb-31db7b6c38e66697f1353f6fbfba62c306d84240.tar.gz
gdb-31db7b6c38e66697f1353f6fbfba62c306d84240.tar.bz2
* defs.h (enum return_value_convention): Add
RETURN_VALUE_ABI_RETURNS_ADDRESS and RETURN_VALUE_ABI_PRESERVES_ADDRESS. * infcmd.c (legacy_return_value): New function. (print_return_value): Rwerite to implement RETURN_VALUE_ABI_RETURNS_ADDRESS. * values.c (using_struct_return): Check for inequality to RETURN_VALUE_REGISTER_CONVENTION instead of equality to RETURN_VALUE_STRUCT_CONVENTION. * i386-tdep.c (i386_return_value): Implement RETURN_VALUE_ABI_RETURNS_ADDRESS.
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r--gdb/infcmd.c122
1 files changed, 70 insertions, 52 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index bedc5a5..2cbfce3 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1047,79 +1047,97 @@ advance_command (char *arg, int from_tty)
}
+static struct value *
+legacy_return_value (int struct_return, struct type *value_type)
+{
+ struct value *value;
+
+ if (!struct_return)
+ {
+ /* The return value can be found in the inferior's registers. */
+ return register_value_being_returned (value_type, stop_registers);
+ }
+
+ if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
+ {
+ CORE_ADDR addr;
+
+ addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers);
+ if (!addr)
+ error ("Function return value unknown.");
+ return value_at (value_type, addr, NULL);
+ }
+
+ /* It is "struct return" yet the value is being extracted,
+ presumably from registers, using EXTRACT_RETURN_VALUE. This
+ doesn't make sense. Unfortunately, the legacy interfaces allowed
+ this behavior. Sigh! */
+ value = allocate_value (value_type);
+ CHECK_TYPEDEF (value_type);
+ /* If the function returns void, don't bother fetching the return
+ value. */
+ EXTRACT_RETURN_VALUE (value_type, stop_registers,
+ VALUE_CONTENTS_RAW (value));
+ return value;
+}
+
/* 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)
{
+ struct gdbarch *gdbarch = current_gdbarch;
struct cleanup *old_chain;
struct ui_stream *stb;
- struct value *value;
+ struct value *value = NULL;
- if (!struct_return)
- {
- /* 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
a more complicated case of what is already being done in in the
inferior function call code. In fact, when inferior function
calls are made async, this will likely be made the norm. */
- else if (gdbarch_return_value_p (current_gdbarch))
- /* We cannot determine the contents of the structure because it is
- on the stack, and we don't know where, since we did not
- initiate the call, as opposed to the call_function_by_hand
- case. */
- {
- 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;
- }
- else
+
+ if (gdbarch_return_value_p (gdbarch))
{
- if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
+ switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL))
{
- 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
- {
- /* It is "struct return" yet the value is being extracted,
- presumably from registers, using EXTRACT_RETURN_VALUE.
- This doesn't make sense. Unfortunately, the legacy
- interfaces allowed this behavior. Sigh! */
+ case RETURN_VALUE_REGISTER_CONVENTION:
+ case RETURN_VALUE_ABI_RETURNS_ADDRESS:
value = allocate_value (value_type);
CHECK_TYPEDEF (value_type);
- /* If the function returns void, don't bother fetching the
- return value. */
- EXTRACT_RETURN_VALUE (value_type, stop_registers,
- VALUE_CONTENTS_RAW (value));
+ gdbarch_return_value (current_gdbarch, value_type, stop_registers,
+ VALUE_CONTENTS_RAW (value), NULL);
+ break;
+
+ case RETURN_VALUE_STRUCT_CONVENTION:
+ break;
}
}
+ else
+ value = legacy_return_value (struct_return, value_type);
- /* Print it. */
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
- ui_out_text (uiout, "Value returned is ");
- ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
- record_latest_value (value));
- ui_out_text (uiout, " = ");
- value_print (value, stb->stream, 0, Val_no_prettyprint);
- ui_out_field_stream (uiout, "return-value", stb);
- ui_out_text (uiout, "\n");
- do_cleanups (old_chain);
+ if (value)
+ {
+ /* Print it. */
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+ ui_out_text (uiout, "Value returned is ");
+ ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
+ record_latest_value (value));
+ ui_out_text (uiout, " = ");
+ value_print (value, stb->stream, 0, Val_no_prettyprint);
+ ui_out_field_stream (uiout, "return-value", stb);
+ ui_out_text (uiout, "\n");
+ do_cleanups (old_chain);
+ }
+ 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");
+ }
}
/* Stuff that needs to be done by the finish command after the target