aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/infcall.c51
2 files changed, 33 insertions, 23 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4665207..1f15d5df 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2005-08-21 Mark Kettenis <kettenis@gnu.org>
+ * infcall.c (call_function_by_hand): For
+ RETURN_VALUE_ABI_RETURNS_ADDRESS and
+ RETURN_VALUE_ABI_PRESERVES_ADDRESS, use gdbarch_return_value to
+ get return value.
+
* valarith.c (value_equal, value_less): Avoid compiler bug on
systems where `long double' values are returned in static storage.
diff --git a/gdb/infcall.c b/gdb/infcall.c
index f32f8e1..54d40d0 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -854,39 +854,44 @@ the function call)."), name);
leave the RETBUF alone. */
do_cleanups (inf_status_cleanup);
- /* Figure out the value returned by the function, return that. */
+ /* Figure out the value returned by the function. */
{
- struct value *retval;
+ struct value *retval = NULL;
+
if (TYPE_CODE (values_type) == TYPE_CODE_VOID)
- /* If the function returns void, don't bother fetching the
- return value. */
- retval = allocate_value (values_type);
- else if (struct_return)
- /* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL
- has correctly stored STRUCT_ADDR in the target. In the past
- that hasn't been the case, the old MIPS PUSH_ARGUMENTS
- (PUSH_DUMMY_CALL precursor) would silently move the location
- of the struct return value making STRUCT_ADDR bogus. If
- you're seeing problems with values being returned using the
- "struct return convention", check that PUSH_DUMMY_CALL isn't
- playing tricks. */
- retval = value_at (values_type, struct_addr);
- else
{
- /* This code only handles "register convention". */
+ /* If the function returns void, don't bother fetching the
+ return value. */
retval = allocate_value (values_type);
- gdb_assert (gdbarch_return_value (current_gdbarch, values_type,
- NULL, NULL, NULL)
- == RETURN_VALUE_REGISTER_CONVENTION);
- gdbarch_return_value (current_gdbarch, values_type, retbuf,
- value_contents_raw (retval) /*read*/,
- NULL /*write*/);
}
+ else
+ {
+ struct gdbarch *arch = current_gdbarch;
+
+ switch (gdbarch_return_value (arch, values_type, NULL, NULL, NULL))
+ {
+ case RETURN_VALUE_REGISTER_CONVENTION:
+ case RETURN_VALUE_ABI_RETURNS_ADDRESS:
+ case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
+ retval = allocate_value (values_type);
+ gdbarch_return_value (current_gdbarch, values_type, retbuf,
+ value_contents_raw (retval), NULL);
+ break;
+ case RETURN_VALUE_STRUCT_CONVENTION:
+ retval = value_at (values_type, struct_addr);
+ break;
+ }
+ }
+
do_cleanups (retbuf_cleanup);
+
+ gdb_assert(retval);
return retval;
}
}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
void _initialize_infcall (void);
void