This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [patch/rfc] Add legacy_return_value for old struct-return code,eliminate extract_struct_value_address
- From: Andrew Cagney <cagney at gnu dot org>
- To: Andrew Cagney <cagney at gnu dot org>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Sun, 20 Jun 2004 14:09:18 -0400
- Subject: Re: [patch/rfc] Add legacy_return_value for old struct-return code,eliminate extract_struct_value_address
- References: <40CC9A20.4010809@gnu.org>
Hello,
This adds a new function legacy_return_value, making it the default for the return_value architecture method, and moving the calls to the old struct-return code to that function.
To do this, however, I had to compromise a bit:
- deprecated_extract_struct_value_address call gone
As noted in gdbarch.sh, the correctness of this method is highly questionable. Most ABIs do not require the preservation of the struct-return address across inferior function calls making a correct implementation of this method impossible.
- [deprecated] extract_return_value no longer called for struct-return
Architectures that didn't provide extract_struct_value_address (v850 and AVR) ended having extract_return_value being called for a struct-return. However, as with extract_struct_value_address, the correctness of code trying to handle that case is equally questionable.
(The AVR doesn't even have code to handle this so removing the call fixes a bug).
comments?
I'm leaving this on the table for a week,
I've checked this in (tweaked per attached to build with current sources),
Andrew
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.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.587
diff -p -u -r1.587 Makefile.in
--- Makefile.in 14 Jun 2004 20:40:39 -0000 1.587
+++ Makefile.in 20 Jun 2004 18:05:02 -0000
@@ -1598,7 +1598,7 @@ annotate.o: annotate.c $(defs_h) $(annot
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) \
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.119
diff -p -u -r1.119 arch-utils.c
--- arch-utils.c 13 Jun 2004 13:42:31 -0000 1.119
+++ arch-utils.c 20 Jun 2004 18:05:02 -0000
@@ -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 *
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)
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.73
diff -p -u -r1.73 arch-utils.h
--- arch-utils.h 20 Jun 2004 17:18:04 -0000 1.73
+++ arch-utils.h 20 Jun 2004 18:05:02 -0000
@@ -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;
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.298
diff -p -u -r1.298 gdbarch.c
--- gdbarch.c 20 Jun 2004 17:18:04 -0000 1.298
+++ gdbarch.c 20 Jun 2004 18:05:02 -0000
@@ -457,6 +457,7 @@ gdbarch_alloc (const struct gdbarch_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 *gd
{
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);
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.262
diff -p -u -r1.262 gdbarch.h
--- gdbarch.h 20 Jun 2004 17:18:04 -0000 1.262
+++ gdbarch.h 20 Jun 2004 18:05:02 -0000
@@ -1093,7 +1093,10 @@ extern void set_gdbarch_deprecated_store
/* 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);
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.327
diff -p -u -r1.327 gdbarch.sh
--- gdbarch.sh 20 Jun 2004 17:18:05 -0000 1.327
+++ gdbarch.sh 20 Jun 2004 18:05:02 -0000
@@ -541,7 +541,11 @@ F:DEPRECATED_STORE_STRUCT_RETURN:void:de
# 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
Index: infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.52
diff -p -u -r1.52 infcall.c
--- infcall.c 20 Jun 2004 17:18:05 -0000 1.52
+++ infcall.c 20 Jun 2004 18:05:03 -0000
@@ -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;
}
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.116
diff -p -u -r1.116 infcmd.c
--- infcmd.c 13 Jun 2004 17:05:55 -0000 1.116
+++ infcmd.c 20 Jun 2004 18:05:03 -0000
@@ -1091,36 +1091,20 @@ print_return_value (int struct_return, s
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)
Index: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.108
diff -p -u -r1.108 stack.c
--- stack.c 1 May 2004 21:11:16 -0000 1.108
+++ stack.c 20 Jun 2004 18:05:03 -0000
@@ -1870,24 +1870,12 @@ If you continue, the return value that y
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
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.69
diff -p -u -r1.69 values.c
--- values.c 20 Jun 2004 17:18:06 -0000 1.69
+++ values.c 20 Jun 2004 18:05:03 -0000
@@ -1247,20 +1247,6 @@ using_struct_return (struct type *value_
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)