* 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 (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.
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) \
/* 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.
#include "regcache.h"
#include "gdb_assert.h"
#include "sim-regno.h"
-
+#include "gdbcore.h"
#include "osabi.h"
#include "version.h"
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)
/* 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.
/* 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;
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;
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
{
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);
/* 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);
# 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
"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);
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;
}
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)
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
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)