aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog19
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/arch-utils.c41
-rw-r--r--gdb/arch-utils.h13
-rw-r--r--gdb/gdbarch.c4
-rw-r--r--gdb/gdbarch.h5
-rwxr-xr-xgdb/gdbarch.sh6
-rw-r--r--gdb/infcall.c11
-rw-r--r--gdb/infcmd.c40
-rw-r--r--gdb/stack.c24
-rw-r--r--gdb/values.c14
11 files changed, 99 insertions, 80 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bf5798e..d80de75 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,24 @@
2004-06-20 Andrew Cagney <cagney@gnu.org>
+ * gdbarch.sh (RETURN_VALUE): Default to legacy_return_value.
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * Makefile.in (arch-utils.o): Update dependencies.
+ * values.c (using_struct_return): Move code calling
+ USE_STRUCT_CONVENTION to legacy_return_value, simplify.
+ * stack.c (return_command): Move code calling STORE_RETURN_VALUE
+ to legacy_return_value, simplify.
+ * infcmd.c (print_return_value): Move code calling
+ DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS and EXTRACT_RETURN_VALUE
+ to legacy_return_value, simplify.
+ * infcall.c (call_function_by_hand): Move code calling
+ EXTRACT_RETURN_VALUE to legacy_return_value, simplify.
+ * arch-utils.c: Update copyright. Include "gdbcore.h".
+ (legacy_return_value): New function.
+ * arch-utils.h: Update copyright.
+ (legacy_return_value): Declare.
+
+2004-06-20 Andrew Cagney <cagney@gnu.org>
+
* gdbarch.sh (DEPRECATED_USE_STRUCT_CONVENTION): Deprecated.
* gdbarch.h, gdbarch.c: Re-generate.
* values.c (using_struct_return): Update call.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index b113c9a..9eb471f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1598,7 +1598,7 @@ annotate.o: annotate.c $(defs_h) $(annotate_h) $(value_h) $(target_h) \
arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(buildsym_h) \
$(gdbcmd_h) $(inferior_h) $(gdb_string_h) $(regcache_h) \
$(gdb_assert_h) $(sim_regno_h) $(osabi_h) $(version_h) \
- $(floatformat_h)
+ $(floatformat_h) $(gdbcore_h)
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h)
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index 2ec0674..d7bbe6c 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -1,7 +1,7 @@
/* Dynamic architecture support for GDB, the GNU debugger.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
- Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
@@ -30,7 +30,7 @@
#include "regcache.h"
#include "gdb_assert.h"
#include "sim-regno.h"
-
+#include "gdbcore.h"
#include "osabi.h"
#include "version.h"
@@ -60,13 +60,46 @@ legacy_store_return_value (struct type *type, struct regcache *regcache,
DEPRECATED_STORE_RETURN_VALUE (type, b);
}
-
int
always_use_struct_convention (int gcc_p, struct type *value_type)
{
return 1;
}
+enum return_value_convention
+legacy_return_value (struct gdbarch *gdbarch, struct type *valtype,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
+{
+ /* 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
+ || TYPE_CODE (valtype) == TYPE_CODE_UNION
+ || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
+ && DEPRECATED_USE_STRUCT_CONVENTION (0, valtype));
+
+ if (writebuf != NULL)
+ {
+ gdb_assert (!struct_return);
+ /* NOTE: cagney/2004-06-13: See stack.c:return_command. Old
+ architectures don't expect STORE_RETURN_VALUE to handle small
+ structures. Should not be called with such types. */
+ gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (valtype) != TYPE_CODE_UNION);
+ STORE_RETURN_VALUE (valtype, regcache, writebuf);
+ }
+
+ if (readbuf != NULL)
+ {
+ gdb_assert (!struct_return);
+ EXTRACT_RETURN_VALUE (valtype, regcache, readbuf);
+ }
+
+ if (struct_return)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else
+ return RETURN_VALUE_REGISTER_CONVENTION;
+}
int
legacy_register_sim_regno (int regnum)
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
index de5ab3c..4d1e48e 100644
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -1,7 +1,7 @@
/* Dynamic architecture support for GDB, the GNU debugger.
- Copyright 1998, 1999, 2000, 2002, 2003 Free Software Foundation,
- Inc.
+ Copyright 1998, 1999, 2000, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
@@ -32,6 +32,15 @@ struct gdbarch_info;
/* gdbarch trace variable */
extern int gdbarch_debug;
+/* An implementation of return_value that props up architectures still
+ 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 regcache *regcache,
+ void *readbuf,
+ const void *writebuf);
+
/* Implementation of extract return value that grubs around in the
register cache. */
extern gdbarch_extract_return_value_ftype legacy_extract_return_value;
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index edb6bd7..20173af 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -457,6 +457,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
current_gdbarch->convert_register_p = generic_convert_register_p;
current_gdbarch->pointer_to_address = unsigned_pointer_to_address;
current_gdbarch->address_to_pointer = unsigned_address_to_pointer;
+ current_gdbarch->return_value = legacy_return_value;
current_gdbarch->extract_return_value = legacy_extract_return_value;
current_gdbarch->store_return_value = legacy_store_return_value;
current_gdbarch->deprecated_use_struct_convention = generic_use_struct_convention;
@@ -3456,7 +3457,7 @@ int
gdbarch_return_value_p (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
- return gdbarch->return_value != NULL;
+ return gdbarch->return_value != legacy_return_value;
}
enum return_value_convention
@@ -3464,6 +3465,7 @@ gdbarch_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regc
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->return_value != NULL);
+ /* Do not check predicate: gdbarch->return_value != legacy_return_value, allow call. */
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value called\n");
return gdbarch->return_value (gdbarch, valtype, regcache, readbuf, writebuf);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 99b8ebe..ae4e70b 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1093,7 +1093,10 @@ extern void set_gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch,
/* It has been suggested that this, well actually its predecessor,
should take the type/value of the function to be called and not the
- return type. This is left as an exercise for the reader. */
+ return type. This is left as an exercise for the reader.
+ NOTE: cagney/2004-06-13: The function stack.c:return_command uses
+ the predicate with default hack to avoid calling STORE_RETURN_VALUE
+ (via legacy_return_value), when a small struct is involved. */
extern int gdbarch_return_value_p (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index cd716f6..ac00784 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -541,7 +541,11 @@ F:DEPRECATED_STORE_STRUCT_RETURN:void:deprecated_store_struct_return:CORE_ADDR a
# should take the type/value of the function to be called and not the
# return type. This is left as an exercise for the reader.
-M::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf:valtype, regcache, readbuf, writebuf
+# NOTE: cagney/2004-06-13: The function stack.c:return_command uses
+# 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
# The deprecated methods EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE,
# DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS and
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 8d89101..9e3e479 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -939,7 +939,7 @@ the function call).", name);
"struct return convention", check that PUSH_DUMMY_CALL isn't
playing tricks. */
retval = value_at (value_type, struct_addr, NULL);
- else if (gdbarch_return_value_p (current_gdbarch))
+ else
{
/* This code only handles "register convention". */
retval = allocate_value (value_type);
@@ -950,15 +950,6 @@ the function call).", name);
VALUE_CONTENTS_RAW (retval) /*read*/,
NULL /*write*/);
}
- else
- {
- /* NOTE: cagney/2003-10-20: Unlike "gdbarch_return_value", the
- EXTRACT_RETURN_VALUE and DEPRECATED_USE_STRUCT_CONVENTION
- methods do not handle the edge case of a function returning
- a small structure / union in registers. */
- retval = allocate_value (value_type);
- EXTRACT_RETURN_VALUE (value_type, retbuf, VALUE_CONTENTS_RAW (retval));
- }
do_cleanups (retbuf_cleanup);
return retval;
}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 3aa6e41..46d57be 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1091,36 +1091,20 @@ print_return_value (int struct_return, struct type *value_type)
inferior function call code. In fact, when inferior function
calls are made async, this will likely be made the norm. */
- if (gdbarch_return_value_p (gdbarch))
- {
- switch (gdbarch_return_value (gdbarch, value_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,
- VALUE_CONTENTS_RAW (value), NULL);
- break;
- case RETURN_VALUE_STRUCT_CONVENTION:
- value = NULL;
- break;
- default:
- internal_error (__FILE__, __LINE__, "bad switch");
- }
- }
- else if (struct_return && DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
- {
- 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
+ switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL))
{
+ case RETURN_VALUE_REGISTER_CONVENTION:
+ case RETURN_VALUE_ABI_RETURNS_ADDRESS:
value = allocate_value (value_type);
- EXTRACT_RETURN_VALUE (value_type, stop_registers,
- VALUE_CONTENTS_RAW (value));
+ CHECK_TYPEDEF (value_type);
+ gdbarch_return_value (current_gdbarch, value_type, stop_registers,
+ VALUE_CONTENTS_RAW (value), NULL);
+ break;
+ case RETURN_VALUE_STRUCT_CONVENTION:
+ value = NULL;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
}
if (value)
diff --git a/gdb/stack.c b/gdb/stack.c
index ac4434c..ce986c7 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1870,24 +1870,12 @@ If you continue, the return value that you specified will be ignored.\n";
if (return_value != NULL)
{
struct type *return_type = VALUE_TYPE (return_value);
- if (!gdbarch_return_value_p (current_gdbarch))
- {
- STORE_RETURN_VALUE (return_type, current_regcache,
- VALUE_CONTENTS (return_value));
- }
- /* FIXME: cagney/2004-01-17: If extract_returned_value_address
- is available and the function is using
- RETURN_VALUE_STRUCT_CONVENTION, should use it to find the
- address of the returned value so that it can be assigned. */
- else
- {
- gdb_assert (gdbarch_return_value (current_gdbarch, return_type,
- NULL, NULL, NULL)
- == RETURN_VALUE_REGISTER_CONVENTION);
- gdbarch_return_value (current_gdbarch, return_type,
- current_regcache, NULL /*read*/,
- VALUE_CONTENTS (return_value) /*write*/);
- }
+ gdb_assert (gdbarch_return_value (current_gdbarch, return_type,
+ NULL, NULL, NULL)
+ == RETURN_VALUE_REGISTER_CONVENTION);
+ gdbarch_return_value (current_gdbarch, return_type,
+ current_regcache, NULL /*read*/,
+ VALUE_CONTENTS (return_value) /*write*/);
}
/* If we are at the end of a call dummy now, pop the dummy frame
diff --git a/gdb/values.c b/gdb/values.c
index 1b8e9b4..a42e53a 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -1247,20 +1247,6 @@ using_struct_return (struct type *value_type, int gcc_p)
code in "print_return_value". */
return 0;
- if (!gdbarch_return_value_p (current_gdbarch))
- {
- /* FIXME: cagney/2003-10-01: The below is dead. Instead an
- architecture should implement "gdbarch_return_value". Using
- that new function it is possible to exactly specify the ABIs
- "struct return" vs "register return" conventions. */
- if (code == TYPE_CODE_STRUCT
- || code == TYPE_CODE_UNION
- || code == TYPE_CODE_ARRAY)
- return DEPRECATED_USE_STRUCT_CONVENTION (gcc_p, value_type);
- else
- return 0;
- }
-
/* Probe the architecture for the return-value convention. */
return (gdbarch_return_value (current_gdbarch, value_type,
NULL, NULL, NULL)