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:
parent
198beae2cf
commit
92ad9cd90f
10 changed files with 329 additions and 113 deletions
|
@ -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>
|
2003-10-20 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
* symtab.c: Replace "struct sec" with "struct bfd_section".
|
* symtab.c: Replace "struct sec" with "struct bfd_section".
|
||||||
|
|
15
gdb/defs.h
15
gdb/defs.h
|
@ -230,6 +230,21 @@ enum auto_boolean
|
||||||
AUTO_BOOLEAN_AUTO
|
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
|
/* the cleanup list records things that have to be undone
|
||||||
if an error happens (descriptors to be closed, memory to be freed, etc.)
|
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
|
Each link in the chain records a function to call and an
|
||||||
|
|
|
@ -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>
|
2003-10-18 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
* gdbint.texinfo (Target Architecture Definition): Document
|
* gdbint.texinfo (Target Architecture Definition): Document
|
||||||
|
|
|
@ -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,
|
the raw register state @var{regbuf} and copy that, in virtual format,
|
||||||
into @var{valbuf}.
|
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})
|
@item EXTRACT_STRUCT_VALUE_ADDRESS(@var{regbuf})
|
||||||
@findex EXTRACT_STRUCT_VALUE_ADDRESS
|
@findex EXTRACT_STRUCT_VALUE_ADDRESS
|
||||||
|
@anchor{EXTRACT_STRUCT_VALUE_ADDRESS}
|
||||||
When defined, extract from the array @var{regbuf} (containing the raw
|
When defined, extract from the array @var{regbuf} (containing the raw
|
||||||
register state) the @code{CORE_ADDR} at which a function should return
|
register state) the @code{CORE_ADDR} at which a function should return
|
||||||
its structure value.
|
its structure value.
|
||||||
|
|
||||||
If not defined, @code{EXTRACT_RETURN_VALUE} is used.
|
@xref{gdbarch_return_value}.
|
||||||
|
|
||||||
@item EXTRACT_STRUCT_VALUE_ADDRESS_P()
|
@item EXTRACT_STRUCT_VALUE_ADDRESS_P()
|
||||||
@findex 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
|
Define this to convert sdb register numbers into @value{GDBN} regnums. If not
|
||||||
defined, no conversion will be done.
|
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
|
@item SKIP_PERMANENT_BREAKPOINT
|
||||||
@findex SKIP_PERMANENT_BREAKPOINT
|
@findex SKIP_PERMANENT_BREAKPOINT
|
||||||
Advance the inferior's PC past a permanent breakpoint. @value{GDBN} normally
|
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
|
@var{valbuf}, into the @var{regcache}. @var{type} is the type of the
|
||||||
value that is to be returned.
|
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
|
@item SUN_FIXED_LBRAC_BUG
|
||||||
@findex SUN_FIXED_LBRAC_BUG
|
@findex SUN_FIXED_LBRAC_BUG
|
||||||
(Used only for Sun-3 and Sun-4 targets.)
|
(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
|
for systems where GCC is known to use different calling convention than
|
||||||
other compilers.
|
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})
|
@item VALUE_TO_REGISTER(@var{type}, @var{regnum}, @var{from}, @var{to})
|
||||||
@findex VALUE_TO_REGISTER
|
@findex VALUE_TO_REGISTER
|
||||||
Convert a value of type @var{type} into the raw contents of register
|
Convert a value of type @var{type} into the raw contents of register
|
||||||
|
|
113
gdb/gdbarch.c
113
gdb/gdbarch.c
|
@ -203,16 +203,17 @@ struct gdbarch
|
||||||
gdbarch_pointer_to_address_ftype *pointer_to_address;
|
gdbarch_pointer_to_address_ftype *pointer_to_address;
|
||||||
gdbarch_address_to_pointer_ftype *address_to_pointer;
|
gdbarch_address_to_pointer_ftype *address_to_pointer;
|
||||||
gdbarch_integer_to_address_ftype *integer_to_address;
|
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_pop_frame_ftype *deprecated_pop_frame;
|
||||||
gdbarch_deprecated_store_struct_return_ftype *deprecated_store_struct_return;
|
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_extract_return_value_ftype *extract_return_value;
|
||||||
gdbarch_store_return_value_ftype *store_return_value;
|
gdbarch_store_return_value_ftype *store_return_value;
|
||||||
gdbarch_deprecated_extract_return_value_ftype *deprecated_extract_return_value;
|
gdbarch_deprecated_extract_return_value_ftype *deprecated_extract_return_value;
|
||||||
gdbarch_deprecated_store_return_value_ftype *deprecated_store_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_extract_struct_value_address_ftype *extract_struct_value_address;
|
||||||
gdbarch_deprecated_extract_struct_value_address_ftype *deprecated_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_frame_init_saved_regs_ftype *deprecated_frame_init_saved_regs;
|
||||||
gdbarch_deprecated_init_extra_frame_info_ftype *deprecated_init_extra_frame_info;
|
gdbarch_deprecated_init_extra_frame_info_ftype *deprecated_init_extra_frame_info;
|
||||||
gdbarch_skip_prologue_ftype *skip_prologue;
|
gdbarch_skip_prologue_ftype *skip_prologue;
|
||||||
|
@ -374,16 +375,17 @@ struct gdbarch startup_gdbarch =
|
||||||
0, /* pointer_to_address */
|
0, /* pointer_to_address */
|
||||||
0, /* address_to_pointer */
|
0, /* address_to_pointer */
|
||||||
0, /* integer_to_address */
|
0, /* integer_to_address */
|
||||||
0, /* return_value_on_stack */
|
|
||||||
0, /* deprecated_pop_frame */
|
0, /* deprecated_pop_frame */
|
||||||
0, /* deprecated_store_struct_return */
|
0, /* deprecated_store_struct_return */
|
||||||
|
0, /* return_value */
|
||||||
|
0, /* return_value_on_stack */
|
||||||
0, /* extract_return_value */
|
0, /* extract_return_value */
|
||||||
0, /* store_return_value */
|
0, /* store_return_value */
|
||||||
0, /* deprecated_extract_return_value */
|
0, /* deprecated_extract_return_value */
|
||||||
0, /* deprecated_store_return_value */
|
0, /* deprecated_store_return_value */
|
||||||
|
0, /* use_struct_convention */
|
||||||
0, /* extract_struct_value_address */
|
0, /* extract_struct_value_address */
|
||||||
0, /* deprecated_extract_struct_value_address */
|
0, /* deprecated_extract_struct_value_address */
|
||||||
0, /* use_struct_convention */
|
|
||||||
0, /* deprecated_frame_init_saved_regs */
|
0, /* deprecated_frame_init_saved_regs */
|
||||||
0, /* deprecated_init_extra_frame_info */
|
0, /* deprecated_init_extra_frame_info */
|
||||||
0, /* skip_prologue */
|
0, /* skip_prologue */
|
||||||
|
@ -692,14 +694,15 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||||
/* Skip verify of pointer_to_address, invalid_p == 0 */
|
/* Skip verify of pointer_to_address, invalid_p == 0 */
|
||||||
/* Skip verify of address_to_pointer, invalid_p == 0 */
|
/* Skip verify of address_to_pointer, invalid_p == 0 */
|
||||||
/* Skip verify of integer_to_address, has predicate */
|
/* 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_pop_frame, has predicate */
|
||||||
/* Skip verify of deprecated_store_struct_return, 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 extract_return_value, invalid_p == 0 */
|
||||||
/* Skip verify of store_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 extract_struct_value_address, has predicate */
|
||||||
/* Skip verify of deprecated_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_frame_init_saved_regs, has predicate */
|
||||||
/* Skip verify of deprecated_init_extra_frame_info, has predicate */
|
/* Skip verify of deprecated_init_extra_frame_info, has predicate */
|
||||||
if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
|
if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
|
||||||
|
@ -807,6 +810,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: regset_from_core_section = 0x%08lx\n",
|
"gdbarch_dump: regset_from_core_section = 0x%08lx\n",
|
||||||
(long) current_gdbarch->regset_from_core_section);
|
(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,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
|
"gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
|
||||||
(long) current_gdbarch->in_function_epilogue_p);
|
(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;
|
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
|
int
|
||||||
gdbarch_deprecated_pop_frame_p (struct gdbarch *gdbarch)
|
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;
|
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
|
void
|
||||||
gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, void *valbuf)
|
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;
|
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
|
int
|
||||||
gdbarch_extract_struct_value_address_p (struct gdbarch *gdbarch)
|
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;
|
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
|
int
|
||||||
gdbarch_deprecated_frame_init_saved_regs_p (struct gdbarch *gdbarch)
|
gdbarch_deprecated_frame_init_saved_regs_p (struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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))
|
#define INTEGER_TO_ADDRESS(type, buf) (gdbarch_integer_to_address (current_gdbarch, type, buf))
|
||||||
#endif
|
#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)
|
#if defined (DEPRECATED_POP_FRAME)
|
||||||
/* Legacy for systems yet to multi-arch DEPRECATED_POP_FRAME */
|
/* Legacy for systems yet to multi-arch DEPRECATED_POP_FRAME */
|
||||||
#if !defined (DEPRECATED_POP_FRAME_P)
|
#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))
|
#define DEPRECATED_STORE_STRUCT_RETURN(addr, sp) (gdbarch_deprecated_store_struct_return (current_gdbarch, addr, sp))
|
||||||
#endif
|
#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);
|
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 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);
|
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))
|
#define DEPRECATED_STORE_RETURN_VALUE(type, valbuf) (gdbarch_deprecated_store_return_value (current_gdbarch, type, valbuf))
|
||||||
#endif
|
#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)
|
#if defined (EXTRACT_STRUCT_VALUE_ADDRESS)
|
||||||
/* Legacy for systems yet to multi-arch EXTRACT_STRUCT_VALUE_ADDRESS */
|
/* Legacy for systems yet to multi-arch EXTRACT_STRUCT_VALUE_ADDRESS */
|
||||||
#if !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P)
|
#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))
|
#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) (gdbarch_deprecated_extract_struct_value_address (current_gdbarch, regbuf))
|
||||||
#endif
|
#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)
|
#if defined (DEPRECATED_FRAME_INIT_SAVED_REGS)
|
||||||
/* Legacy for systems yet to multi-arch 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)
|
#if !defined (DEPRECATED_FRAME_INIT_SAVED_REGS_P)
|
||||||
|
|
|
@ -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: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: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:-
|
F:2:DEPRECATED_POP_FRAME:void:deprecated_pop_frame:void:-
|
||||||
# NOTE: cagney/2003-03-24: Replaced by PUSH_ARGUMENTS.
|
# 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
|
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: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: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_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: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: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: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_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
|
F:2:DEPRECATED_INIT_EXTRA_FRAME_INFO:void:deprecated_init_extra_frame_info:int fromleaf, struct frame_info *frame:fromleaf, frame
|
||||||
|
|
39
gdb/infcmd.c
39
gdb/infcmd.c
|
@ -44,6 +44,7 @@
|
||||||
#include "reggroups.h"
|
#include "reggroups.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
/* Functions exported for general use, in inferior.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_field_stream (uiout, "return-value", stb);
|
||||||
ui_out_text (uiout, "\n");
|
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)
|
||||||
/* FIXME: 2003-09-27: When returning from a nested inferior
|
to locate and return/print a "struct return" value. This is just
|
||||||
function call, it's possible (with no help from the
|
a more complicated case of what is already being done in in the
|
||||||
architecture vector) to locate and return/print a "struct
|
inferior function call code. In fact, when inferior function
|
||||||
return" value. This is just a more complicated case of what
|
calls are made async, this will likely be made the norm. */
|
||||||
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 */
|
|
||||||
#ifdef DEPRECATED_VALUE_RETURNED_FROM_STACK
|
#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_text (uiout, "Value returned has type: ");
|
||||||
ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
|
ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
|
||||||
ui_out_text (uiout, ".");
|
ui_out_text (uiout, ".");
|
||||||
ui_out_text (uiout, " Cannot determine contents\n");
|
ui_out_text (uiout, " Cannot determine contents\n");
|
||||||
#else
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (EXTRACT_STRUCT_VALUE_ADDRESS_P ())
|
if (EXTRACT_STRUCT_VALUE_ADDRESS_P ())
|
||||||
{
|
{
|
||||||
CORE_ADDR addr = EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers);
|
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);
|
value_print (value, stb->stream, 0, Val_no_prettyprint);
|
||||||
ui_out_field_stream (uiout, "return-value", stb);
|
ui_out_field_stream (uiout, "return-value", stb);
|
||||||
ui_out_text (uiout, "\n");
|
ui_out_text (uiout, "\n");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,21 +305,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
|
||||||
return sp;
|
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
|
/* Handle the return-value conventions specified by the SysV 32-bit
|
||||||
PowerPC ABI (including all the supplements):
|
PowerPC ABI (including all the supplements):
|
||||||
|
|
||||||
|
|
91
gdb/values.c
91
gdb/values.c
|
@ -1202,28 +1202,51 @@ value_from_double (struct type *type, DOUBLEST num)
|
||||||
return val;
|
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,
|
Extract the return-value (as a "struct value") that a function,
|
||||||
returning now would be returning to its caller, assuming its type
|
using register convention, has just returned to its caller. Assume
|
||||||
is VALTYPE. RETBUF is where we look for what ought to be the
|
that the type of the function is VALTYPE, and that the "just
|
||||||
contents of the registers (in raw form). This is because it is
|
returned" register state is found in RETBUF.
|
||||||
often desirable to restore old values to those registers after
|
|
||||||
saving the contents of interest, and then call this function using
|
The function has "just returned" because GDB halts a returning
|
||||||
the saved values. */
|
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 *
|
struct value *
|
||||||
register_value_being_returned (struct type *valtype, struct regcache *retbuf)
|
register_value_being_returned (struct type *valtype, struct regcache *retbuf)
|
||||||
{
|
{
|
||||||
struct value *val = allocate_value (valtype);
|
struct value *val = allocate_value (valtype);
|
||||||
CHECK_TYPEDEF (valtype);
|
|
||||||
/* If the function returns void, don't bother fetching the return
|
/* If the function returns void, don't bother fetching the return
|
||||||
value. */
|
value. */
|
||||||
if (TYPE_CODE (valtype) != TYPE_CODE_VOID)
|
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));
|
EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
|
||||||
/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
|
/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
|
||||||
EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
|
EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
|
||||||
and TYPE is the type (which is known to be struct, union or array).
|
and TYPE is the type (which is known to be struct, union or array).
|
||||||
|
@ -1262,15 +1285,27 @@ using_struct_return (struct type *value_type, int gcc_p)
|
||||||
if (code == TYPE_CODE_ERROR)
|
if (code == TYPE_CODE_ERROR)
|
||||||
error ("Function return type unknown.");
|
error ("Function return type unknown.");
|
||||||
|
|
||||||
|
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
|
if (code == TYPE_CODE_STRUCT
|
||||||
|| code == TYPE_CODE_UNION
|
|| code == TYPE_CODE_UNION
|
||||||
|| code == TYPE_CODE_ARRAY
|
|| code == TYPE_CODE_ARRAY
|
||||||
|| RETURN_VALUE_ON_STACK (value_type))
|
|| RETURN_VALUE_ON_STACK (value_type))
|
||||||
return USE_STRUCT_CONVENTION (gcc_p, 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.
|
/* Store VAL so it will be returned if a function returns now.
|
||||||
Does not verify that VAL's type matches what the current
|
Does not verify that VAL's type matches what the current
|
||||||
function wants to return. */
|
function wants to return. */
|
||||||
|
@ -1284,9 +1319,41 @@ set_return_value (struct value *val)
|
||||||
if (code == TYPE_CODE_ERROR)
|
if (code == TYPE_CODE_ERROR)
|
||||||
error ("Function return type unknown.");
|
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
|
if (code == TYPE_CODE_STRUCT
|
||||||
|| code == TYPE_CODE_UNION) /* FIXME, implement struct return. */
|
|| 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));
|
STORE_RETURN_VALUE (type, current_regcache, VALUE_CONTENTS (val));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue