2003-10-20 Andrew Cagney <cagney@redhat.com>

* values.c (register_value_being_returned): Update comments.  Use
	"gdbarch_return_value" when available.
	(using_struct_return): Ditto.
	(set_return_value): Ditto.  Use "gdbarch_return_value" when
	available..  Print a warning, and not an error, when an unhandled
	return type is encountered.
	* infcmd.c: Include "gdb_assert.h".
	(print_return_value): When gdbarch_return_value_p, and using
	struct return, assume that the value is not available.
	* defs.h (return_value_convention): Define.
	* gdbarch.sh (gdbarch_return_value): New predicate method.
	* gdbarch.h, gdbarch.c: Re-generate
	* ppc-sysv-tdep.c (return_value_convention): Delete definition.

Index: doc/ChangeLog
2003-10-20  Andrew Cagney  <cagney@redhat.com>

	* gdbint.texinfo (Target Architecture Definition): Document
	gdbarch_return_value.  Add cross references from
	USE_STRUCT_CONVENTION, EXTRACT_RETURN_VALUE, and
	STORE_RETURN_VALUE, and from/to EXTRACT_STRUCT_VALUE_ADDRESS.
This commit is contained in:
Andrew Cagney 2003-10-20 15:38:02 +00:00
parent 198beae2cf
commit 92ad9cd90f
10 changed files with 329 additions and 113 deletions

View File

@ -1,3 +1,19 @@
2003-10-20 Andrew Cagney <cagney@redhat.com>
* values.c (register_value_being_returned): Update comments. Use
"gdbarch_return_value" when available.
(using_struct_return): Ditto.
(set_return_value): Ditto. Use "gdbarch_return_value" when
available.. Print a warning, and not an error, when an unhandled
return type is encountered.
* infcmd.c: Include "gdb_assert.h".
(print_return_value): When gdbarch_return_value_p, and using
struct return, assume that the value is not available.
* defs.h (return_value_convention): Define.
* gdbarch.sh (gdbarch_return_value): New predicate method.
* gdbarch.h, gdbarch.c: Re-generate
* ppc-sysv-tdep.c (return_value_convention): Delete definition.
2003-10-20 Andrew Cagney <cagney@redhat.com>
* symtab.c: Replace "struct sec" with "struct bfd_section".

View File

@ -230,6 +230,21 @@ enum auto_boolean
AUTO_BOOLEAN_AUTO
};
/* Potential ways that a function can return a value of a given type. */
enum return_value_convention
{
/* Where the return value has been squeezed into one or more
registers. */
RETURN_VALUE_REGISTER_CONVENTION,
/* Commonly known as the "struct return convention". The caller
passes an additional hidden first parameter to the caller. That
parameter contains the address at which the value being returned
should be stored. While typically, and historically, used for
large structs, this is convention is applied to values of many
different types. */
RETURN_VALUE_STRUCT_CONVENTION
};
/* the cleanup list records things that have to be undone
if an error happens (descriptors to be closed, memory to be freed, etc.)
Each link in the chain records a function to call and an

View File

@ -1,3 +1,10 @@
2003-10-20 Andrew Cagney <cagney@redhat.com>
* gdbint.texinfo (Target Architecture Definition): Document
gdbarch_return_value. Add cross references from
USE_STRUCT_CONVENTION, EXTRACT_RETURN_VALUE, and
STORE_RETURN_VALUE, and from/to EXTRACT_STRUCT_VALUE_ADDRESS.
2003-10-18 Mark Kettenis <kettenis@gnu.org>
* gdbint.texinfo (Target Architecture Definition): Document

View File

@ -3219,13 +3219,17 @@ Define this to extract a function's return value of type @var{type} from
the raw register state @var{regbuf} and copy that, in virtual format,
into @var{valbuf}.
This method has been deprecated in favour of @code{gdbarch_return_value}
(@pxref{gdbarch_return_value}).
@item EXTRACT_STRUCT_VALUE_ADDRESS(@var{regbuf})
@findex EXTRACT_STRUCT_VALUE_ADDRESS
@anchor{EXTRACT_STRUCT_VALUE_ADDRESS}
When defined, extract from the array @var{regbuf} (containing the raw
register state) the @code{CORE_ADDR} at which a function should return
its structure value.
If not defined, @code{EXTRACT_RETURN_VALUE} is used.
@xref{gdbarch_return_value}.
@item EXTRACT_STRUCT_VALUE_ADDRESS_P()
@findex EXTRACT_STRUCT_VALUE_ADDRESS_P
@ -3824,6 +3828,48 @@ allocated on the stack. @xref{unwind_dummy_id}.
Define this to convert sdb register numbers into @value{GDBN} regnums. If not
defined, no conversion will be done.
@item enum return_value_convention gdbarch_return_value (struct gdbarch *@var{gdbarch}, struct type *@var{valtype}, struct regcache *@var{regcache}, const void *@var{inval}, void *@var{outval})
@findex gdbarch_return_value
@anchor{gdbarch_return_value} Given a function with a return-value of
type @var{rettype}, return which return-value convention that function
would use.
@value{GDBN} currently recognizes two function return-value conventions:
@code{RETURN_VALUE_REGISTER_CONVENTION} where the return value is found
in registers; and @code{RETURN_VALUE_STRUCT_CONVENTION} where the return
value is found in memory and the address of that memory location is
passed in as the function's first parameter.
If the register convention is being used, and @var{inval} is
non-@code{NULL}, also copy the return-value in @var{inval} into
@var{regcache}.
If the register convention is being used, and @var{outval} is
non-@code{NULL}, also copy the return value from @var{regcache} into
@var{outval} (@var{regcache} contains a copy of the registers from the
just returned function).
@xref{EXTRACT_STRUCT_VALUE_ADDRESS}, for a description of how
return-values that use the struct convention are handled.
@emph{Maintainer note: This method replaces separate predicate, extract,
store methods. By having only one method, the logic needed to determine
the return-value convention need only be implemented in one place. If
@value{GDBN} were written in an @sc{oo} language, this method would
instead return an object that knew how to perform the register
return-value extract and store.}
@emph{Maintainer note: This method does not take a @var{gcc_p}
parameter, and such a parameter should not be added. If an architecture
that requires per-compiler or per-function information be identified,
then the replacement of @var{rettype} with @code{struct value}
@var{function} should be persued.}
@emph{Maintainer note: The @var{regcache} parameter limits this methods
to the inner most frame. While replacing @var{regcache} with a
@code{struct frame_info} @var{frame} parameter would remove that
limitation there has yet to be a demonstrated need for such a change.}
@item SKIP_PERMANENT_BREAKPOINT
@findex SKIP_PERMANENT_BREAKPOINT
Advance the inferior's PC past a permanent breakpoint. @value{GDBN} normally
@ -3882,6 +3928,9 @@ A C expression that writes the function return value, found in
@var{valbuf}, into the @var{regcache}. @var{type} is the type of the
value that is to be returned.
This method has been deprecated in favour of @code{gdbarch_return_value}
(@pxref{gdbarch_return_value}).
@item SUN_FIXED_LBRAC_BUG
@findex SUN_FIXED_LBRAC_BUG
(Used only for Sun-3 and Sun-4 targets.)
@ -4017,6 +4066,9 @@ being considered is known to have been compiled by GCC; this is helpful
for systems where GCC is known to use different calling convention than
other compilers.
This method has been deprecated in favour of @code{gdbarch_return_value}
(@pxref{gdbarch_return_value}).
@item VALUE_TO_REGISTER(@var{type}, @var{regnum}, @var{from}, @var{to})
@findex VALUE_TO_REGISTER
Convert a value of type @var{type} into the raw contents of register

View File

@ -203,16 +203,17 @@ struct gdbarch
gdbarch_pointer_to_address_ftype *pointer_to_address;
gdbarch_address_to_pointer_ftype *address_to_pointer;
gdbarch_integer_to_address_ftype *integer_to_address;
gdbarch_return_value_on_stack_ftype *return_value_on_stack;
gdbarch_deprecated_pop_frame_ftype *deprecated_pop_frame;
gdbarch_deprecated_store_struct_return_ftype *deprecated_store_struct_return;
gdbarch_return_value_ftype *return_value;
gdbarch_return_value_on_stack_ftype *return_value_on_stack;
gdbarch_extract_return_value_ftype *extract_return_value;
gdbarch_store_return_value_ftype *store_return_value;
gdbarch_deprecated_extract_return_value_ftype *deprecated_extract_return_value;
gdbarch_deprecated_store_return_value_ftype *deprecated_store_return_value;
gdbarch_use_struct_convention_ftype *use_struct_convention;
gdbarch_extract_struct_value_address_ftype *extract_struct_value_address;
gdbarch_deprecated_extract_struct_value_address_ftype *deprecated_extract_struct_value_address;
gdbarch_use_struct_convention_ftype *use_struct_convention;
gdbarch_deprecated_frame_init_saved_regs_ftype *deprecated_frame_init_saved_regs;
gdbarch_deprecated_init_extra_frame_info_ftype *deprecated_init_extra_frame_info;
gdbarch_skip_prologue_ftype *skip_prologue;
@ -374,16 +375,17 @@ struct gdbarch startup_gdbarch =
0, /* pointer_to_address */
0, /* address_to_pointer */
0, /* integer_to_address */
0, /* return_value_on_stack */
0, /* deprecated_pop_frame */
0, /* deprecated_store_struct_return */
0, /* return_value */
0, /* return_value_on_stack */
0, /* extract_return_value */
0, /* store_return_value */
0, /* deprecated_extract_return_value */
0, /* deprecated_store_return_value */
0, /* use_struct_convention */
0, /* extract_struct_value_address */
0, /* deprecated_extract_struct_value_address */
0, /* use_struct_convention */
0, /* deprecated_frame_init_saved_regs */
0, /* deprecated_init_extra_frame_info */
0, /* skip_prologue */
@ -692,14 +694,15 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of pointer_to_address, invalid_p == 0 */
/* Skip verify of address_to_pointer, invalid_p == 0 */
/* Skip verify of integer_to_address, has predicate */
/* Skip verify of return_value_on_stack, invalid_p == 0 */
/* Skip verify of deprecated_pop_frame, has predicate */
/* Skip verify of deprecated_store_struct_return, has predicate */
/* Skip verify of return_value, has predicate */
/* Skip verify of return_value_on_stack, invalid_p == 0 */
/* Skip verify of extract_return_value, invalid_p == 0 */
/* Skip verify of store_return_value, invalid_p == 0 */
/* Skip verify of use_struct_convention, invalid_p == 0 */
/* Skip verify of extract_struct_value_address, has predicate */
/* Skip verify of deprecated_extract_struct_value_address, has predicate */
/* Skip verify of use_struct_convention, invalid_p == 0 */
/* Skip verify of deprecated_frame_init_saved_regs, has predicate */
/* Skip verify of deprecated_init_extra_frame_info, has predicate */
if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
@ -807,6 +810,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: regset_from_core_section = 0x%08lx\n",
(long) current_gdbarch->regset_from_core_section);
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_return_value_p() = %d\n",
gdbarch_return_value_p (current_gdbarch));
fprintf_unfiltered (file,
"gdbarch_dump: return_value = 0x%08lx\n",
(long) current_gdbarch->return_value);
fprintf_unfiltered (file,
"gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
(long) current_gdbarch->in_function_epilogue_p);
@ -4229,23 +4238,6 @@ set_gdbarch_integer_to_address (struct gdbarch *gdbarch,
gdbarch->integer_to_address = integer_to_address;
}
int
gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->return_value_on_stack != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value_on_stack called\n");
return gdbarch->return_value_on_stack (type);
}
void
set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch,
gdbarch_return_value_on_stack_ftype return_value_on_stack)
{
gdbarch->return_value_on_stack = return_value_on_stack;
}
int
gdbarch_deprecated_pop_frame_p (struct gdbarch *gdbarch)
{
@ -4294,6 +4286,47 @@ set_gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch,
gdbarch->deprecated_store_struct_return = deprecated_store_struct_return;
}
int
gdbarch_return_value_p (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
return gdbarch->return_value != NULL;
}
enum return_value_convention
gdbarch_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, const void *inval, void *outval)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->return_value != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value called\n");
return gdbarch->return_value (gdbarch, valtype, regcache, inval, outval);
}
void
set_gdbarch_return_value (struct gdbarch *gdbarch,
gdbarch_return_value_ftype return_value)
{
gdbarch->return_value = return_value;
}
int
gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->return_value_on_stack != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value_on_stack called\n");
return gdbarch->return_value_on_stack (type);
}
void
set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch,
gdbarch_return_value_on_stack_ftype return_value_on_stack)
{
gdbarch->return_value_on_stack = return_value_on_stack;
}
void
gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, void *valbuf)
{
@ -4362,6 +4395,23 @@ set_gdbarch_deprecated_store_return_value (struct gdbarch *gdbarch,
gdbarch->deprecated_store_return_value = deprecated_store_return_value;
}
int
gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->use_struct_convention != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_use_struct_convention called\n");
return gdbarch->use_struct_convention (gcc_p, value_type);
}
void
set_gdbarch_use_struct_convention (struct gdbarch *gdbarch,
gdbarch_use_struct_convention_ftype use_struct_convention)
{
gdbarch->use_struct_convention = use_struct_convention;
}
int
gdbarch_extract_struct_value_address_p (struct gdbarch *gdbarch)
{
@ -4410,23 +4460,6 @@ set_gdbarch_deprecated_extract_struct_value_address (struct gdbarch *gdbarch,
gdbarch->deprecated_extract_struct_value_address = deprecated_extract_struct_value_address;
}
int
gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->use_struct_convention != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_use_struct_convention called\n");
return gdbarch->use_struct_convention (gcc_p, value_type);
}
void
set_gdbarch_use_struct_convention (struct gdbarch *gdbarch,
gdbarch_use_struct_convention_ftype use_struct_convention)
{
gdbarch->use_struct_convention = use_struct_convention;
}
int
gdbarch_deprecated_frame_init_saved_regs_p (struct gdbarch *gdbarch)
{

View File

@ -1392,16 +1392,6 @@ extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_int
#define INTEGER_TO_ADDRESS(type, buf) (gdbarch_integer_to_address (current_gdbarch, type, buf))
#endif
typedef int (gdbarch_return_value_on_stack_ftype) (struct type *type);
extern int gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type);
extern void set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch, gdbarch_return_value_on_stack_ftype *return_value_on_stack);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (RETURN_VALUE_ON_STACK)
#error "Non multi-arch definition of RETURN_VALUE_ON_STACK"
#endif
#if !defined (RETURN_VALUE_ON_STACK)
#define RETURN_VALUE_ON_STACK(type) (gdbarch_return_value_on_stack (current_gdbarch, type))
#endif
#if defined (DEPRECATED_POP_FRAME)
/* Legacy for systems yet to multi-arch DEPRECATED_POP_FRAME */
#if !defined (DEPRECATED_POP_FRAME_P)
@ -1454,6 +1444,34 @@ extern void set_gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch,
#define DEPRECATED_STORE_STRUCT_RETURN(addr, sp) (gdbarch_deprecated_store_struct_return (current_gdbarch, addr, sp))
#endif
/* 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. */
extern int gdbarch_return_value_p (struct gdbarch *gdbarch);
typedef enum return_value_convention (gdbarch_return_value_ftype) (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, const void *inval, void *outval);
extern enum return_value_convention gdbarch_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, const void *inval, void *outval);
extern void set_gdbarch_return_value (struct gdbarch *gdbarch, gdbarch_return_value_ftype *return_value);
/* The deprecated methods RETURN_VALUE_ON_STACK, EXTRACT_RETURN_VALUE,
STORE_RETURN_VALUE and USE_STRUCT_CONVENTION have all been folded
into RETURN_VALUE. For the moment do not try to fold in
EXTRACT_STRUCT_VALUE_ADDRESS as, dependant on the ABI, the debug
info, and the level of effort, it may well be possible to find the
address of a structure being return on the stack. Someone else can
make that change. */
typedef int (gdbarch_return_value_on_stack_ftype) (struct type *type);
extern int gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type);
extern void set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch, gdbarch_return_value_on_stack_ftype *return_value_on_stack);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (RETURN_VALUE_ON_STACK)
#error "Non multi-arch definition of RETURN_VALUE_ON_STACK"
#endif
#if !defined (RETURN_VALUE_ON_STACK)
#define RETURN_VALUE_ON_STACK(type) (gdbarch_return_value_on_stack (current_gdbarch, type))
#endif
typedef void (gdbarch_extract_return_value_ftype) (struct type *type, struct regcache *regcache, void *valbuf);
extern void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, void *valbuf);
extern void set_gdbarch_extract_return_value (struct gdbarch *gdbarch, gdbarch_extract_return_value_ftype *extract_return_value);
@ -1494,6 +1512,16 @@ extern void set_gdbarch_deprecated_store_return_value (struct gdbarch *gdbarch,
#define DEPRECATED_STORE_RETURN_VALUE(type, valbuf) (gdbarch_deprecated_store_return_value (current_gdbarch, type, valbuf))
#endif
typedef int (gdbarch_use_struct_convention_ftype) (int gcc_p, struct type *value_type);
extern int gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type);
extern void set_gdbarch_use_struct_convention (struct gdbarch *gdbarch, gdbarch_use_struct_convention_ftype *use_struct_convention);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (USE_STRUCT_CONVENTION)
#error "Non multi-arch definition of USE_STRUCT_CONVENTION"
#endif
#if !defined (USE_STRUCT_CONVENTION)
#define USE_STRUCT_CONVENTION(gcc_p, value_type) (gdbarch_use_struct_convention (current_gdbarch, gcc_p, value_type))
#endif
#if defined (EXTRACT_STRUCT_VALUE_ADDRESS)
/* Legacy for systems yet to multi-arch EXTRACT_STRUCT_VALUE_ADDRESS */
#if !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P)
@ -1544,16 +1572,6 @@ extern void set_gdbarch_deprecated_extract_struct_value_address (struct gdbarch
#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) (gdbarch_deprecated_extract_struct_value_address (current_gdbarch, regbuf))
#endif
typedef int (gdbarch_use_struct_convention_ftype) (int gcc_p, struct type *value_type);
extern int gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type);
extern void set_gdbarch_use_struct_convention (struct gdbarch *gdbarch, gdbarch_use_struct_convention_ftype *use_struct_convention);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (USE_STRUCT_CONVENTION)
#error "Non multi-arch definition of USE_STRUCT_CONVENTION"
#endif
#if !defined (USE_STRUCT_CONVENTION)
#define USE_STRUCT_CONVENTION(gcc_p, value_type) (gdbarch_use_struct_convention (current_gdbarch, gcc_p, value_type))
#endif
#if defined (DEPRECATED_FRAME_INIT_SAVED_REGS)
/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_INIT_SAVED_REGS */
#if !defined (DEPRECATED_FRAME_INIT_SAVED_REGS_P)

View File

@ -593,19 +593,33 @@ f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, const voi
f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
F:2:INTEGER_TO_ADDRESS:CORE_ADDR:integer_to_address:struct type *type, void *buf:type, buf
#
f:2:RETURN_VALUE_ON_STACK:int:return_value_on_stack:struct type *type:type:::generic_return_value_on_stack_not::0
F:2:DEPRECATED_POP_FRAME:void:deprecated_pop_frame:void:-
# NOTE: cagney/2003-03-24: Replaced by PUSH_ARGUMENTS.
F:2:DEPRECATED_STORE_STRUCT_RETURN:void:deprecated_store_struct_return:CORE_ADDR addr, CORE_ADDR sp:addr, sp
#
# 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.
M:::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, const void *inval, void *outval:valtype, regcache, inval, outval
# The deprecated methods RETURN_VALUE_ON_STACK, EXTRACT_RETURN_VALUE,
# STORE_RETURN_VALUE and USE_STRUCT_CONVENTION have all been folded
# into RETURN_VALUE. For the moment do not try to fold in
# EXTRACT_STRUCT_VALUE_ADDRESS as, dependant on the ABI, the debug
# info, and the level of effort, it may well be possible to find the
# address of a structure being return on the stack. Someone else can
# make that change.
f:2:RETURN_VALUE_ON_STACK:int:return_value_on_stack:struct type *type:type:::generic_return_value_on_stack_not::0
f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, struct regcache *regcache, void *valbuf:type, regcache, valbuf:::legacy_extract_return_value::0
f:2:STORE_RETURN_VALUE:void:store_return_value:struct type *type, struct regcache *regcache, const void *valbuf:type, regcache, valbuf:::legacy_store_return_value::0
f:2:DEPRECATED_EXTRACT_RETURN_VALUE:void:deprecated_extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf
f:2:DEPRECATED_STORE_RETURN_VALUE:void:deprecated_store_return_value:struct type *type, char *valbuf:type, valbuf
#
f:2:USE_STRUCT_CONVENTION:int:use_struct_convention:int gcc_p, struct type *value_type:gcc_p, value_type:::generic_use_struct_convention::0
F:2:EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:extract_struct_value_address:struct regcache *regcache:regcache
F:2:DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:deprecated_extract_struct_value_address:char *regbuf:regbuf
f:2:USE_STRUCT_CONVENTION:int:use_struct_convention:int gcc_p, struct type *value_type:gcc_p, value_type:::generic_use_struct_convention::0
#
F:2:DEPRECATED_FRAME_INIT_SAVED_REGS:void:deprecated_frame_init_saved_regs:struct frame_info *frame:frame
F:2:DEPRECATED_INIT_EXTRA_FRAME_INFO:void:deprecated_init_extra_frame_info:int fromleaf, struct frame_info *frame:fromleaf, frame

View File

@ -44,6 +44,7 @@
#include "reggroups.h"
#include "block.h"
#include <ctype.h>
#include "gdb_assert.h"
/* Functions exported for general use, in inferior.h: */
@ -1079,25 +1080,34 @@ print_return_value (int structure_return, struct type *value_type)
ui_out_field_stream (uiout, "return-value", stb);
ui_out_text (uiout, "\n");
}
else
{
/* 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. */
/* 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 */
/* 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. */
#ifdef DEPRECATED_VALUE_RETURNED_FROM_STACK
value = 0;
#define DEPRECATED_VALUE_RETURNED_FROM_STACK_P 1
#else
#define DEPRECATED_VALUE_RETURNED_FROM_STACK_P 0
#endif
else if (gdbarch_return_value_p (current_gdbarch)
|| DEPRECATED_VALUE_RETURNED_FROM_STACK_P)
/* 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");
#else
return;
}
else
{
if (EXTRACT_STRUCT_VALUE_ADDRESS_P ())
{
CORE_ADDR addr = EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers);
@ -1133,7 +1143,6 @@ print_return_value (int structure_return, struct type *value_type)
value_print (value, stb->stream, 0, Val_no_prettyprint);
ui_out_field_stream (uiout, "return-value", stb);
ui_out_text (uiout, "\n");
#endif
}
}

View File

@ -305,21 +305,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
return sp;
}
/* Potential ways that a function can return a value of a given type. */
enum return_value_convention
{
/* Where the return value has been squeezed into one or more
registers. */
RETURN_VALUE_REGISTER_CONVENTION,
/* Commonly known as the "struct return convention". The caller
passes an additional hidden first parameter to the caller. That
parameter contains the address at which the value being returned
should be stored. While typically, and historically, used for
large structs, this is convention is applied to values of many
different types. */
RETURN_VALUE_STRUCT_CONVENTION
};
/* Handle the return-value conventions specified by the SysV 32-bit
PowerPC ABI (including all the supplements):

View File

@ -1202,25 +1202,48 @@ value_from_double (struct type *type, DOUBLEST num)
return val;
}
/* Deal with the value that is "about to be returned".
/* Deal with the return-value of a function that has "just returned".
Return the value that a function, using the register convention,
returning now would be returning to its caller, assuming its type
is VALTYPE. RETBUF is where we look for what ought to be the
contents of the registers (in raw form). This is because it is
often desirable to restore old values to those registers after
saving the contents of interest, and then call this function using
the saved values. */
Extract the return-value (as a "struct value") that a function,
using register convention, has just returned to its caller. Assume
that the type of the function is VALTYPE, and that the "just
returned" register state is found in RETBUF.
The function has "just returned" because GDB halts a returning
function by setting a breakpoint at the return address (in the
caller), and not the return instruction (in the callee).
Because, in the case of a return from an inferior function call,
GDB needs to restore the inferiors registers, RETBUF is normally a
copy of the inferior's registers. */
struct value *
register_value_being_returned (struct type *valtype, struct regcache *retbuf)
{
struct value *val = allocate_value (valtype);
CHECK_TYPEDEF (valtype);
/* If the function returns void, don't bother fetching the return
value. */
if (TYPE_CODE (valtype) != TYPE_CODE_VOID)
EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
if (TYPE_CODE (valtype) == TYPE_CODE_VOID)
return val;
if (!gdbarch_return_value_p (current_gdbarch))
{
/* NOTE: cagney/2003-10-20: Unlike "gdbarch_return_value", the
EXTRACT_RETURN_VALUE and USE_STRUCT_CONVENTION methods do not
handle the edge case of a function returning a small
structure / union in registers. */
CHECK_TYPEDEF (valtype);
EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
return val;
}
/* This function only handles "register convention". */
gdb_assert (gdbarch_return_value (current_gdbarch, valtype,
NULL, NULL, NULL)
== RETURN_VALUE_REGISTER_CONVENTION);
gdbarch_return_value (current_gdbarch, valtype, retbuf,
NULL, VALUE_CONTENTS_RAW (val));
return val;
}
@ -1262,13 +1285,25 @@ using_struct_return (struct type *value_type, int gcc_p)
if (code == TYPE_CODE_ERROR)
error ("Function return type unknown.");
if (code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_UNION
|| code == TYPE_CODE_ARRAY
|| RETURN_VALUE_ON_STACK (value_type))
return USE_STRUCT_CONVENTION (gcc_p, value_type);
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_VALUE_ON_STACK (value_type))
return USE_STRUCT_CONVENTION (gcc_p, value_type);
else
return 0;
}
return 0;
/* Probe the architecture for the return-value convention. */
return (gdbarch_return_value (current_gdbarch, value_type,
NULL, NULL, NULL)
== RETURN_VALUE_STRUCT_CONVENTION);
}
/* Store VAL so it will be returned if a function returns now.
@ -1284,9 +1319,41 @@ set_return_value (struct value *val)
if (code == TYPE_CODE_ERROR)
error ("Function return type unknown.");
if (gdbarch_return_value_p (current_gdbarch))
{
switch (gdbarch_return_value (current_gdbarch, type, NULL, NULL, NULL))
{
case RETURN_VALUE_REGISTER_CONVENTION:
/* Success. The architecture can deal with it, write it to
the regcache. */
gdbarch_return_value (current_gdbarch, type, current_regcache,
VALUE_CONTENTS (val), NULL);
return;
case RETURN_VALUE_STRUCT_CONVENTION:
/* Failure. For the moment, assume that it is not possible
to find the location, on the stack, at which the "struct
return" value should be stored. Only a warning because
an error aborts the "return" command leaving GDB in a
weird state. */
warning ("Location of return value unknown");
return;
}
}
if (code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_UNION) /* FIXME, implement struct return. */
error ("GDB does not support specifying a struct or union return value.");
/* FIXME: cagney/2003-10-20: This should be an internal-warning.
The problem is that while GDB's core supports "struct return"
using "register convention", many architectures haven't been
updated to implement the mechanisms needed to make it work.
It's a warning, and not an error, as otherwize it will jump out
of the "return" command leaving both GDB and the user in a very
confused state. */
{
warning ("This architecture does not support specifying a struct or union return-value.");
return;
}
STORE_RETURN_VALUE (type, current_regcache, VALUE_CONTENTS (val));
}