* breakpoint.h (bp_location): Add related_address member.
	* inferior.h (get_return_value): Take a pointer to struct value
	instead of struct type for the function requested.
	* value.h (using_struct_return): Likewise.
	* gdbarch.sh (return_value): Take a pointer to struct value
	instead of struct type for the function requested.
	* breakpoint.c (set_breakpoint_location_function): Initialize
	related_address for bp_gnu_ifunc_resolver breakpoints.
	* elfread.c (elf_gnu_ifunc_resolver_return_stop): Pass the
	requested function's address to gdbarch_return_value.
	* eval.c (evaluate_subexp_standard): Pass the requested
	function's address to using_struct_return.
	* infcall.c (call_function_by_hand): Pass the requested
	function's address to using_struct_return and
	gdbarch_return_value.
	* infcmd.c (get_return_value): Take a pointer to struct value
	instead of struct type for the function requested.
	(print_return_value): Update accordingly.
	(finish_command_continuation): Likewise.
	* stack.c (return_command): Pass the requested function's
	address to using_struct_return and gdbarch_return_value.
	* value.c (using_struct_return): Take a pointer to struct value
	instead of struct type for the function requested.  Pass the
	requested function's address to gdbarch_return_value.
	* python/py-finishbreakpoint.c (finish_breakpoint_object):
	New function_value member, replacing function_type.
	(bpfinishpy_dealloc): Update accordingly.
	(bpfinishpy_pre_stop_hook): Likewise.
	(bpfinishpy_init): Likewise.  Record the requested function's
	address.
	* mips-tdep.c (mips_fval_reg): New enum.
	(mips_o32_push_dummy_call): For MIPS16 FP doubles do not swap
	words put in GP registers.
	(mips_o64_push_dummy_call): Update a comment.
	(mips_o32_return_value): Take a pointer to struct value instead
	of struct type for the function requested and use it to check if
	using the MIPS16 calling convention.  Return the designated
	general purpose registers for floating-point values returned in
	MIPS16 mode.
	(mips_o64_return_value): Likewise.
	* ppc-tdep.h (ppc_sysv_abi_return_value): Update prototype.
	(ppc_sysv_abi_broken_return_value): Likewise.
	(ppc64_sysv_abi_return_value): Likewise.
	* alpha-tdep.c (alpha_return_value): Take a pointer to struct
	value instead of struct type for the function requested.
	* amd64-tdep.c (amd64_return_value): Likewise.
	* amd64-windows-tdep.c (amd64_windows_return_value): Likewise.
	* arm-tdep.c (arm_return_value): Likewise.
	* avr-tdep.c (avr_return_value): Likewise.
	* bfin-tdep.c (bfin_return_value): Likewise.
	* cris-tdep.c (cris_return_value): Likewise.
	* frv-tdep.c (frv_return_value): Likewise.
	* h8300-tdep.c (h8300_return_value): Likewise.
	(h8300h_return_value): Likewise.
	* hppa-tdep.c (hppa32_return_value): Likewise.
	(hppa64_return_value): Likewise.
	* i386-tdep.c (i386_return_value): Likewise.
	* ia64-tdep.c (ia64_return_value): Likewise.
	* iq2000-tdep.c (iq2000_return_value): Likewise.
	* lm32-tdep.c (lm32_return_value): Likewise.
	* m32c-tdep.c (m32c_return_value): Likewise.
	* m32r-tdep.c (m32r_return_value): Likewise.
	* m68hc11-tdep.c (m68hc11_return_value): Likewise.
	* m68k-tdep.c (m68k_return_value): Likewise.
	(m68k_svr4_return_value): Likewise.
	* m88k-tdep.c (m88k_return_value): Likewise.
	* mep-tdep.c (mep_return_value): Likewise.
	* microblaze-tdep.c (microblaze_return_value): Likewise.
	* mn10300-tdep.c (mn10300_return_value): Likewise.
	* moxie-tdep.c (moxie_return_value): Likewise.
	* mt-tdep.c (mt_return_value): Likewise.
	* ppc-linux-tdep.c (ppc_linux_return_value): Likewise.
	* ppc-sysv-tdep.c (ppc_sysv_abi_return_value): Likewise.
	(ppc_sysv_abi_broken_return_value): Likewise.
	(ppc64_sysv_abi_return_value): Likewise.
	* ppcnbsd-tdep.c (ppcnbsd_return_value): Likewise.
	* rl78-tdep.c (rl78_return_value): Likewise.
	* rs6000-aix-tdep.c (rs6000_return_value): Likewise.
	* rx-tdep.c (rx_return_value): Likewise.
	* s390-tdep.c (s390_return_value): Likewise.
	* score-tdep.c (score_return_value): Likewise.
	* sh-tdep.c (sh_return_value_nofpu): Likewise.
	(sh_return_value_fpu): Likewise.
	* sh64-tdep.c (sh64_return_value): Likewise.
	* sparc-tdep.c (sparc32_return_value): Likewise.
	* sparc64-tdep.c (sparc64_return_value): Likewise.
	* spu-tdep.c (spu_return_value): Likewise.
	* tic6x-tdep.c (tic6x_return_value): Likewise.
	* v850-tdep.c (v850_return_value): Likewise.
	* vax-tdep.c (vax_return_value): Likewise.
	* xstormy16-tdep.c (xstormy16_return_value): Likewise.
	* xtensa-tdep.c (xtensa_return_value): Likewise.
	* gdbarch.c: Regenerate.
	* gdbarch.h: Regenerate.

	gdb/testsuite/
	* gdb.base/return-nodebug.exp: Also test float and double types.
This commit is contained in:
Maciej W. Rozycki 2012-05-16 14:35:09 +00:00
parent 691bf19c4e
commit 6a3a010ba6
61 changed files with 426 additions and 191 deletions

View file

@ -1,3 +1,101 @@
2012-05-16 Maciej W. Rozycki <macro@codesourcery.com>
Maciej W. Rozycki <macro@mips.com>
* breakpoint.h (bp_location): Add related_address member.
* inferior.h (get_return_value): Take a pointer to struct value
instead of struct type for the function requested.
* value.h (using_struct_return): Likewise.
* gdbarch.sh (return_value): Take a pointer to struct value
instead of struct type for the function requested.
* breakpoint.c (set_breakpoint_location_function): Initialize
related_address for bp_gnu_ifunc_resolver breakpoints.
* elfread.c (elf_gnu_ifunc_resolver_return_stop): Pass the
requested function's address to gdbarch_return_value.
* eval.c (evaluate_subexp_standard): Pass the requested
function's address to using_struct_return.
* infcall.c (call_function_by_hand): Pass the requested
function's address to using_struct_return and
gdbarch_return_value.
* infcmd.c (get_return_value): Take a pointer to struct value
instead of struct type for the function requested.
(print_return_value): Update accordingly.
(finish_command_continuation): Likewise.
* stack.c (return_command): Pass the requested function's
address to using_struct_return and gdbarch_return_value.
* value.c (using_struct_return): Take a pointer to struct value
instead of struct type for the function requested. Pass the
requested function's address to gdbarch_return_value.
* python/py-finishbreakpoint.c (finish_breakpoint_object):
New function_value member, replacing function_type.
(bpfinishpy_dealloc): Update accordingly.
(bpfinishpy_pre_stop_hook): Likewise.
(bpfinishpy_init): Likewise. Record the requested function's
address.
* mips-tdep.c (mips_fval_reg): New enum.
(mips_o32_push_dummy_call): For MIPS16 FP doubles do not swap
words put in GP registers.
(mips_o64_push_dummy_call): Update a comment.
(mips_o32_return_value): Take a pointer to struct value instead
of struct type for the function requested and use it to check if
using the MIPS16 calling convention. Return the designated
general purpose registers for floating-point values returned in
MIPS16 mode.
(mips_o64_return_value): Likewise.
* ppc-tdep.h (ppc_sysv_abi_return_value): Update prototype.
(ppc_sysv_abi_broken_return_value): Likewise.
(ppc64_sysv_abi_return_value): Likewise.
* alpha-tdep.c (alpha_return_value): Take a pointer to struct
value instead of struct type for the function requested.
* amd64-tdep.c (amd64_return_value): Likewise.
* amd64-windows-tdep.c (amd64_windows_return_value): Likewise.
* arm-tdep.c (arm_return_value): Likewise.
* avr-tdep.c (avr_return_value): Likewise.
* bfin-tdep.c (bfin_return_value): Likewise.
* cris-tdep.c (cris_return_value): Likewise.
* frv-tdep.c (frv_return_value): Likewise.
* h8300-tdep.c (h8300_return_value): Likewise.
(h8300h_return_value): Likewise.
* hppa-tdep.c (hppa32_return_value): Likewise.
(hppa64_return_value): Likewise.
* i386-tdep.c (i386_return_value): Likewise.
* ia64-tdep.c (ia64_return_value): Likewise.
* iq2000-tdep.c (iq2000_return_value): Likewise.
* lm32-tdep.c (lm32_return_value): Likewise.
* m32c-tdep.c (m32c_return_value): Likewise.
* m32r-tdep.c (m32r_return_value): Likewise.
* m68hc11-tdep.c (m68hc11_return_value): Likewise.
* m68k-tdep.c (m68k_return_value): Likewise.
(m68k_svr4_return_value): Likewise.
* m88k-tdep.c (m88k_return_value): Likewise.
* mep-tdep.c (mep_return_value): Likewise.
* microblaze-tdep.c (microblaze_return_value): Likewise.
* mn10300-tdep.c (mn10300_return_value): Likewise.
* moxie-tdep.c (moxie_return_value): Likewise.
* mt-tdep.c (mt_return_value): Likewise.
* ppc-linux-tdep.c (ppc_linux_return_value): Likewise.
* ppc-sysv-tdep.c (ppc_sysv_abi_return_value): Likewise.
(ppc_sysv_abi_broken_return_value): Likewise.
(ppc64_sysv_abi_return_value): Likewise.
* ppcnbsd-tdep.c (ppcnbsd_return_value): Likewise.
* rl78-tdep.c (rl78_return_value): Likewise.
* rs6000-aix-tdep.c (rs6000_return_value): Likewise.
* rx-tdep.c (rx_return_value): Likewise.
* s390-tdep.c (s390_return_value): Likewise.
* score-tdep.c (score_return_value): Likewise.
* sh-tdep.c (sh_return_value_nofpu): Likewise.
(sh_return_value_fpu): Likewise.
* sh64-tdep.c (sh64_return_value): Likewise.
* sparc-tdep.c (sparc32_return_value): Likewise.
* sparc64-tdep.c (sparc64_return_value): Likewise.
* spu-tdep.c (spu_return_value): Likewise.
* tic6x-tdep.c (tic6x_return_value): Likewise.
* v850-tdep.c (v850_return_value): Likewise.
* vax-tdep.c (vax_return_value): Likewise.
* xstormy16-tdep.c (xstormy16_return_value): Likewise.
* xtensa-tdep.c (xtensa_return_value): Likewise.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
2012-05-15 Tom Tromey <tromey@redhat.com> 2012-05-15 Tom Tromey <tromey@redhat.com>
* python/python.c (gdbpy_find_pc_line): Use gdb_py_ulongest. * python/python.c (gdbpy_find_pc_line): Use gdb_py_ulongest.

View file

@ -612,7 +612,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
alpha_return_value (struct gdbarch *gdbarch, struct type *func_type, alpha_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -594,7 +594,7 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2])
} }
static enum return_value_convention static enum return_value_convention
amd64_return_value (struct gdbarch *gdbarch, struct type *func_type, amd64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -73,7 +73,7 @@ amd64_windows_classify (struct type *type, enum amd64_reg_class class[2])
/* Implement the "return_value" gdbarch method for amd64-windows. */ /* Implement the "return_value" gdbarch method for amd64-windows. */
static enum return_value_convention static enum return_value_convention
amd64_windows_return_value (struct gdbarch *gdbarch, struct type *func_type, amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -9011,11 +9011,12 @@ arm_store_return_value (struct type *type, struct regcache *regs,
/* Handle function return values. */ /* Handle function return values. */
static enum return_value_convention static enum return_value_convention
arm_return_value (struct gdbarch *gdbarch, struct type *func_type, arm_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct type *func_type = function ? value_type (function) : NULL;
enum arm_vfp_cprc_base_type vfp_base_type; enum arm_vfp_cprc_base_type vfp_base_type;
int vfp_base_count; int vfp_base_count;

View file

@ -902,7 +902,7 @@ avr_breakpoint_from_pc (struct gdbarch *gdbarch,
from WRITEBUF into REGCACHE. */ from WRITEBUF into REGCACHE. */
static enum return_value_convention static enum return_value_convention
avr_return_value (struct gdbarch *gdbarch, struct type *func_type, avr_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -663,7 +663,7 @@ bfin_store_return_value (struct type *type,
static enum return_value_convention static enum return_value_convention
bfin_return_value (struct gdbarch *gdbarch, bfin_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *type, struct type *type,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, gdb_byte *readbuf,

View file

@ -6598,9 +6598,10 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
{ {
int is_gnu_ifunc; int is_gnu_ifunc;
const char *function_name; const char *function_name;
CORE_ADDR func_addr;
find_pc_partial_function_gnu_ifunc (loc->address, &function_name, find_pc_partial_function_gnu_ifunc (loc->address, &function_name,
NULL, NULL, &is_gnu_ifunc); &func_addr, NULL, &is_gnu_ifunc);
if (is_gnu_ifunc && !explicit_loc) if (is_gnu_ifunc && !explicit_loc)
{ {
@ -6621,6 +6622,9 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
/* Create only the whole new breakpoint of this type but do not /* Create only the whole new breakpoint of this type but do not
mess more complicated breakpoints with multiple locations. */ mess more complicated breakpoints with multiple locations. */
b->type = bp_gnu_ifunc_resolver; b->type = bp_gnu_ifunc_resolver;
/* Remember the resolver's address for use by the return
breakpoint. */
loc->related_address = func_addr;
} }
} }

View file

@ -425,6 +425,11 @@ struct bp_location
processor's architectual constraints. */ processor's architectual constraints. */
CORE_ADDR requested_address; CORE_ADDR requested_address;
/* An additional address assigned with this location. This is currently
only used by STT_GNU_IFUNC resolver breakpoints to hold the address
of the resolver function. */
CORE_ADDR related_address;
/* If the location comes from a probe point, this is the probe associated /* If the location comes from a probe point, this is the probe associated
with it. */ with it. */
struct probe *probe; struct probe *probe;

View file

@ -1863,7 +1863,7 @@ cris_extract_return_value (struct type *type, struct regcache *regcache,
/* Handle the CRIS return value convention. */ /* Handle the CRIS return value convention. */
static enum return_value_convention static enum return_value_convention
cris_return_value (struct gdbarch *gdbarch, struct type *func_type, cris_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1020,6 +1020,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func; struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func;
struct type *value_type = TYPE_TARGET_TYPE (func_func_type); struct type *value_type = TYPE_TARGET_TYPE (func_func_type);
struct regcache *regcache = get_thread_regcache (inferior_ptid); struct regcache *regcache = get_thread_regcache (inferior_ptid);
struct value *func_func;
struct value *value; struct value *value;
CORE_ADDR resolved_address, resolved_pc; CORE_ADDR resolved_address, resolved_pc;
struct symtab_and_line sal; struct symtab_and_line sal;
@ -1027,14 +1028,6 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
gdb_assert (b->type == bp_gnu_ifunc_resolver_return); gdb_assert (b->type == bp_gnu_ifunc_resolver_return);
value = allocate_value (value_type);
gdbarch_return_value (gdbarch, func_func_type, value_type, regcache,
value_contents_raw (value), NULL);
resolved_address = value_as_address (value);
resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
resolved_address,
&current_target);
while (b->related_breakpoint != b) while (b->related_breakpoint != b)
{ {
struct breakpoint *b_next = b->related_breakpoint; struct breakpoint *b_next = b->related_breakpoint;
@ -1055,6 +1048,18 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
b = b_next; b = b_next;
} }
gdb_assert (b->type == bp_gnu_ifunc_resolver); gdb_assert (b->type == bp_gnu_ifunc_resolver);
gdb_assert (b->loc->next == NULL);
func_func = allocate_value (func_func_type);
set_value_address (func_func, b->loc->related_address);
value = allocate_value (value_type);
gdbarch_return_value (gdbarch, func_func, value_type, regcache,
value_contents_raw (value), NULL);
resolved_address = value_as_address (value);
resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
resolved_address,
&current_target);
gdb_assert (current_program_space == b->pspace || b->pspace == NULL); gdb_assert (current_program_space == b->pspace || b->pspace == NULL);
elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc); elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc);

View file

@ -1358,8 +1358,7 @@ evaluate_subexp_standard (struct type *expect_type,
val_type = expect_type; val_type = expect_type;
} }
struct_return = using_struct_return (exp->gdbarch, struct_return = using_struct_return (exp->gdbarch, method,
value_type (method),
val_type); val_type);
} }
else if (expect_type != NULL) else if (expect_type != NULL)

View file

@ -1351,7 +1351,7 @@ frv_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
frv_return_value (struct gdbarch *gdbarch, struct type *func_type, frv_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -2536,13 +2536,13 @@ gdbarch_return_value_p (struct gdbarch *gdbarch)
} }
enum return_value_convention enum return_value_convention
gdbarch_return_value (struct gdbarch *gdbarch, struct type *functype, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) gdbarch_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
gdb_assert (gdbarch != NULL); gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->return_value != NULL); gdb_assert (gdbarch->return_value != NULL);
if (gdbarch_debug >= 2) if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value called\n"); fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value called\n");
return gdbarch->return_value (gdbarch, functype, valtype, regcache, readbuf, writebuf); return gdbarch->return_value (gdbarch, function, valtype, regcache, readbuf, writebuf);
} }
void void

View file

@ -434,8 +434,8 @@ typedef CORE_ADDR (gdbarch_integer_to_address_ftype) (struct gdbarch *gdbarch, s
extern CORE_ADDR gdbarch_integer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf); extern CORE_ADDR gdbarch_integer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf);
extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_integer_to_address_ftype *integer_to_address); extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_integer_to_address_ftype *integer_to_address);
/* Return the return-value convention that will be used by FUNCTYPE /* Return the return-value convention that will be used by FUNCTION
to return a value of type VALTYPE. FUNCTYPE may be NULL in which to return a value of type VALTYPE. FUNCTION may be NULL in which
case the return convention is computed based only on VALTYPE. case the return convention is computed based only on VALTYPE.
If READBUF is not NULL, extract the return value and save it in this buffer. If READBUF is not NULL, extract the return value and save it in this buffer.
@ -447,8 +447,8 @@ extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_int
extern int gdbarch_return_value_p (struct gdbarch *gdbarch); extern int gdbarch_return_value_p (struct gdbarch *gdbarch);
typedef enum return_value_convention (gdbarch_return_value_ftype) (struct gdbarch *gdbarch, struct type *functype, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf); typedef enum return_value_convention (gdbarch_return_value_ftype) (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf);
extern enum return_value_convention gdbarch_return_value (struct gdbarch *gdbarch, struct type *functype, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf); extern enum return_value_convention gdbarch_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf);
extern void set_gdbarch_return_value (struct gdbarch *gdbarch, gdbarch_return_value_ftype *return_value); extern void set_gdbarch_return_value (struct gdbarch *gdbarch, gdbarch_return_value_ftype *return_value);
typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip); typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip);

View file

@ -503,8 +503,8 @@ m:CORE_ADDR:pointer_to_address:struct type *type, const gdb_byte *buf:type, buf:
m:void:address_to_pointer:struct type *type, gdb_byte *buf, CORE_ADDR addr:type, buf, addr::unsigned_address_to_pointer::0 m:void:address_to_pointer:struct type *type, gdb_byte *buf, CORE_ADDR addr:type, buf, addr::unsigned_address_to_pointer::0
M:CORE_ADDR:integer_to_address:struct type *type, const gdb_byte *buf:type, buf M:CORE_ADDR:integer_to_address:struct type *type, const gdb_byte *buf:type, buf
# Return the return-value convention that will be used by FUNCTYPE # Return the return-value convention that will be used by FUNCTION
# to return a value of type VALTYPE. FUNCTYPE may be NULL in which # to return a value of type VALTYPE. FUNCTION may be NULL in which
# case the return convention is computed based only on VALTYPE. # case the return convention is computed based only on VALTYPE.
# #
# If READBUF is not NULL, extract the return value and save it in this buffer. # If READBUF is not NULL, extract the return value and save it in this buffer.
@ -513,7 +513,7 @@ M:CORE_ADDR:integer_to_address:struct type *type, const gdb_byte *buf:type, buf
# stored into the appropriate register. This can be used when we want # stored into the appropriate register. This can be used when we want
# to force the value returned by a function (see the "return" command # to force the value returned by a function (see the "return" command
# for instance). # for instance).
M:enum return_value_convention:return_value:struct type *functype, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf:functype, valtype, regcache, readbuf, writebuf M:enum return_value_convention:return_value:struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf:function, valtype, regcache, readbuf, writebuf
m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0
M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip

View file

@ -901,7 +901,7 @@ h8300h_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
h8300_return_value (struct gdbarch *gdbarch, struct type *func_type, h8300_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -915,7 +915,7 @@ h8300_return_value (struct gdbarch *gdbarch, struct type *func_type,
} }
static enum return_value_convention static enum return_value_convention
h8300h_return_value (struct gdbarch *gdbarch, struct type *func_type, h8300h_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1114,7 +1114,7 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Handle 32/64-bit struct return conventions. */ /* Handle 32/64-bit struct return conventions. */
static enum return_value_convention static enum return_value_convention
hppa32_return_value (struct gdbarch *gdbarch, struct type *func_type, hppa32_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -1154,7 +1154,7 @@ hppa32_return_value (struct gdbarch *gdbarch, struct type *func_type,
} }
static enum return_value_convention static enum return_value_convention
hppa64_return_value (struct gdbarch *gdbarch, struct type *func_type, hppa64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -2605,7 +2605,7 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
from WRITEBUF into REGCACHE. */ from WRITEBUF into REGCACHE. */
static enum return_value_convention static enum return_value_convention
i386_return_value (struct gdbarch *gdbarch, struct type *func_type, i386_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -2656,7 +2656,7 @@ i386_return_value (struct gdbarch *gdbarch, struct type *func_type,
if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
{ {
type = check_typedef (TYPE_FIELD_TYPE (type, 0)); type = check_typedef (TYPE_FIELD_TYPE (type, 0));
return i386_return_value (gdbarch, func_type, type, regcache, return i386_return_value (gdbarch, function, type, regcache,
readbuf, writebuf); readbuf, writebuf);
} }

View file

@ -3340,7 +3340,7 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
ia64_return_value (struct gdbarch *gdbarch, struct type *func_type, ia64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -608,8 +608,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
} }
else else
{ {
struct_return = using_struct_return (gdbarch, struct_return = using_struct_return (gdbarch, function, values_type);
value_type (function), values_type);
target_values_type = values_type; target_values_type = values_type;
} }
@ -1021,13 +1020,13 @@ When the function is done executing, GDB will silently stop."),
{ {
/* If the function returns void, don't bother fetching the /* If the function returns void, don't bother fetching the
return value. */ return value. */
switch (gdbarch_return_value (gdbarch, value_type (function), switch (gdbarch_return_value (gdbarch, function, target_values_type,
target_values_type, NULL, NULL, NULL)) NULL, NULL, NULL))
{ {
case RETURN_VALUE_REGISTER_CONVENTION: case RETURN_VALUE_REGISTER_CONVENTION:
case RETURN_VALUE_ABI_RETURNS_ADDRESS: case RETURN_VALUE_ABI_RETURNS_ADDRESS:
case RETURN_VALUE_ABI_PRESERVES_ADDRESS: case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
gdbarch_return_value (gdbarch, value_type (function), values_type, gdbarch_return_value (gdbarch, function, values_type,
retbuf, value_contents_raw (retval), NULL); retbuf, value_contents_raw (retval), NULL);
break; break;
case RETURN_VALUE_STRUCT_CONVENTION: case RETURN_VALUE_STRUCT_CONVENTION:

View file

@ -75,7 +75,7 @@ void interrupt_target_command (char *args, int from_tty);
static void nofp_registers_info (char *, int); static void nofp_registers_info (char *, int);
static void print_return_value (struct type *func_type, static void print_return_value (struct value *function,
struct type *value_type); struct type *value_type);
static void until_next_command (int); static void until_next_command (int);
@ -1416,7 +1416,7 @@ advance_command (char *arg, int from_tty)
command/BP. */ command/BP. */
struct value * struct value *
get_return_value (struct type *func_type, struct type *value_type) get_return_value (struct value *function, struct type *value_type)
{ {
struct regcache *stop_regs = stop_registers; struct regcache *stop_regs = stop_registers;
struct gdbarch *gdbarch; struct gdbarch *gdbarch;
@ -1443,14 +1443,14 @@ get_return_value (struct type *func_type, struct type *value_type)
inferior function call code. In fact, when inferior function inferior function call code. In fact, when inferior function
calls are made async, this will likely be made the norm. */ calls are made async, this will likely be made the norm. */
switch (gdbarch_return_value (gdbarch, func_type, value_type, switch (gdbarch_return_value (gdbarch, function, value_type,
NULL, NULL, NULL)) NULL, NULL, NULL))
{ {
case RETURN_VALUE_REGISTER_CONVENTION: case RETURN_VALUE_REGISTER_CONVENTION:
case RETURN_VALUE_ABI_RETURNS_ADDRESS: case RETURN_VALUE_ABI_RETURNS_ADDRESS:
case RETURN_VALUE_ABI_PRESERVES_ADDRESS: case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
value = allocate_value (value_type); value = allocate_value (value_type);
gdbarch_return_value (gdbarch, func_type, value_type, stop_regs, gdbarch_return_value (gdbarch, function, value_type, stop_regs,
value_contents_raw (value), NULL); value_contents_raw (value), NULL);
break; break;
case RETURN_VALUE_STRUCT_CONVENTION: case RETURN_VALUE_STRUCT_CONVENTION:
@ -1468,9 +1468,9 @@ get_return_value (struct type *func_type, struct type *value_type)
/* Print the result of a function at the end of a 'finish' command. */ /* Print the result of a function at the end of a 'finish' command. */
static void static void
print_return_value (struct type *func_type, struct type *value_type) print_return_value (struct value *function, struct type *value_type)
{ {
struct value *value = get_return_value (func_type, value_type); struct value *value = get_return_value (function, value_type);
struct ui_out *uiout = current_uiout; struct ui_out *uiout = current_uiout;
if (value) if (value)
@ -1548,13 +1548,15 @@ finish_command_continuation (void *arg, int err)
if (TYPE_CODE (value_type) != TYPE_CODE_VOID) if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
{ {
volatile struct gdb_exception ex; volatile struct gdb_exception ex;
struct value *func;
func = read_var_value (a->function, get_current_frame ());
TRY_CATCH (ex, RETURN_MASK_ALL) TRY_CATCH (ex, RETURN_MASK_ALL)
{ {
/* print_return_value can throw an exception in some /* print_return_value can throw an exception in some
circumstances. We need to catch this so that we still circumstances. We need to catch this so that we still
delete the breakpoint. */ delete the breakpoint. */
print_return_value (SYMBOL_TYPE (a->function), value_type); print_return_value (func, value_type);
} }
if (ex.reason < 0) if (ex.reason < 0)
exception_print (gdb_stdout, ex); exception_print (gdb_stdout, ex);

View file

@ -266,7 +266,7 @@ extern void detach_command (char *, int);
extern void notice_new_inferior (ptid_t, int, int); extern void notice_new_inferior (ptid_t, int, int);
extern struct value *get_return_value (struct type *func_type, extern struct value *get_return_value (struct value *function,
struct type *value_type); struct type *value_type);
/* Address at which inferior stopped. */ /* Address at which inferior stopped. */

View file

@ -583,7 +583,7 @@ iq2000_extract_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
iq2000_return_value (struct gdbarch *gdbarch, struct type *func_type, iq2000_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -374,7 +374,7 @@ lm32_store_return_value (struct type *type, struct regcache *regcache,
/* Determine whether a functions return value is in a register or memory. */ /* Determine whether a functions return value is in a register or memory. */
static enum return_value_convention static enum return_value_convention
lm32_return_value (struct gdbarch *gdbarch, struct type *func_type, lm32_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -2206,7 +2206,7 @@ m32c_return_by_passed_buf (struct type *type)
static enum return_value_convention static enum return_value_convention
m32c_return_value (struct gdbarch *gdbarch, m32c_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, gdb_byte *readbuf,

View file

@ -809,7 +809,7 @@ m32r_extract_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
m32r_return_value (struct gdbarch *gdbarch, struct type *func_type, m32r_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1323,7 +1323,7 @@ m68hc11_extract_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
m68hc11_return_value (struct gdbarch *gdbarch, struct type *func_type, m68hc11_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -403,7 +403,7 @@ m68k_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
from WRITEBUF into REGCACHE. */ from WRITEBUF into REGCACHE. */
static enum return_value_convention static enum return_value_convention
m68k_return_value (struct gdbarch *gdbarch, struct type *func_type, m68k_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -438,7 +438,7 @@ m68k_return_value (struct gdbarch *gdbarch, struct type *func_type,
} }
static enum return_value_convention static enum return_value_convention
m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *func_type, m68k_svr4_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -477,7 +477,7 @@ m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *func_type,
if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
{ {
type = check_typedef (TYPE_FIELD_TYPE (type, 0)); type = check_typedef (TYPE_FIELD_TYPE (type, 0));
return m68k_svr4_return_value (gdbarch, func_type, type, regcache, return m68k_svr4_return_value (gdbarch, function, type, regcache,
readbuf, writebuf); readbuf, writebuf);
} }

View file

@ -383,7 +383,7 @@ m88k_dummy_id (struct gdbarch *arch, struct frame_info *this_frame)
from WRITEBUF into REGCACHE. */ from WRITEBUF into REGCACHE. */
static enum return_value_convention static enum return_value_convention
m88k_return_value (struct gdbarch *gdbarch, struct type *func_type, m88k_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -2194,7 +2194,7 @@ Try using the 'return' command with no argument."));
} }
static enum return_value_convention static enum return_value_convention
mep_return_value (struct gdbarch *gdbarch, struct type *func_type, mep_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -612,7 +612,7 @@ microblaze_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
microblaze_return_value (struct gdbarch *gdbarch, struct type *func_type, microblaze_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -3332,7 +3332,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Determine the return value convention being used. */ /* Determine the return value convention being used. */
static enum return_value_convention static enum return_value_convention
mips_eabi_return_value (struct gdbarch *gdbarch, struct type *func_type, mips_eabi_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -3722,7 +3722,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
} }
static enum return_value_convention static enum return_value_convention
mips_n32n64_return_value (struct gdbarch *gdbarch, struct type *func_type, mips_n32n64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -3890,6 +3890,20 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, struct type *func_type,
} }
} }
/* Which registers to use for passing floating-point values between
function calls, one of floating-point, general and both kinds of
registers. O32 and O64 use different register kinds for standard
MIPS and MIPS16 code; to make the handling of cases where we may
not know what kind of code is being used (e.g. no debug information)
easier we sometimes use both kinds. */
enum mips_fval_reg
{
mips_fval_fpr,
mips_fval_gpr,
mips_fval_both
};
/* O32 ABI stuff. */ /* O32 ABI stuff. */
static CORE_ADDR static CORE_ADDR
@ -3980,8 +3994,8 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* 32-bit ABIs always start floating point arguments in an /* 32-bit ABIs always start floating point arguments in an
even-numbered floating point register. Round the FP register even-numbered floating point register. Round the FP register
up before the check to see if there are any FP registers up before the check to see if there are any FP registers
left. O32/O64 targets also pass the FP in the integer left. O32 targets also pass the FP in the integer registers
registers so also round up normal registers. */ so also round up normal registers. */
if (fp_register_arg_p (gdbarch, typecode, arg_type)) if (fp_register_arg_p (gdbarch, typecode, arg_type))
{ {
if ((float_argreg & 1)) if ((float_argreg & 1))
@ -3989,46 +4003,48 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
} }
/* Floating point arguments passed in registers have to be /* Floating point arguments passed in registers have to be
treated specially. On 32-bit architectures, doubles treated specially. On 32-bit architectures, doubles are
are passed in register pairs; the even register gets passed in register pairs; the even FP register gets the
the low word, and the odd register gets the high word. low word, and the odd FP register gets the high word.
On O32/O64, the first two floating point arguments are On O32, the first two floating point arguments are also
also copied to general registers, because MIPS16 functions copied to general registers, following their memory order,
don't use float registers for arguments. This duplication of because MIPS16 functions don't use float registers for
arguments in general registers can't hurt non-MIPS16 functions arguments. This duplication of arguments in general
because those registers are normally skipped. */ registers can't hurt non-MIPS16 functions, because those
registers are normally skipped. */
if (fp_register_arg_p (gdbarch, typecode, arg_type) if (fp_register_arg_p (gdbarch, typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch)) && float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch))
{ {
if (register_size (gdbarch, float_argreg) < 8 && len == 8) if (register_size (gdbarch, float_argreg) < 8 && len == 8)
{ {
int low_offset = gdbarch_byte_order (gdbarch) int freg_offset = gdbarch_byte_order (gdbarch)
== BFD_ENDIAN_BIG ? 4 : 0; == BFD_ENDIAN_BIG ? 1 : 0;
unsigned long regval; unsigned long regval;
/* Write the low word of the double to the even register(s). */ /* First word. */
regval = extract_unsigned_integer (val + low_offset, regval = extract_unsigned_integer (val, 4, byte_order);
4, byte_order);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4)); float_argreg + freg_offset,
phex (regval, 4));
regcache_cooked_write_unsigned (regcache, regcache_cooked_write_unsigned (regcache,
float_argreg++, regval); float_argreg++ + freg_offset,
regval);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
argreg, phex (regval, 4)); argreg, phex (regval, 4));
regcache_cooked_write_unsigned (regcache, argreg++, regval); regcache_cooked_write_unsigned (regcache, argreg++, regval);
/* Write the high word of the double to the odd register(s). */ /* Second word. */
regval = extract_unsigned_integer (val + 4 - low_offset, regval = extract_unsigned_integer (val + 4, 4, byte_order);
4, byte_order);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4)); float_argreg - freg_offset,
phex (regval, 4));
regcache_cooked_write_unsigned (regcache, regcache_cooked_write_unsigned (regcache,
float_argreg++, regval); float_argreg++ - freg_offset,
regval);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
argreg, phex (regval, 4)); argreg, phex (regval, 4));
@ -4203,12 +4219,16 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
} }
static enum return_value_convention static enum return_value_convention
mips_o32_return_value (struct gdbarch *gdbarch, struct type *func_type, mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int mips16 = mips_pc_is_mips16 (func_addr);
enum mips_fval_reg fval_reg;
fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both;
if (TYPE_CODE (type) == TYPE_CODE_STRUCT if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION || TYPE_CODE (type) == TYPE_CODE_UNION
|| TYPE_CODE (type) == TYPE_CODE_ARRAY) || TYPE_CODE (type) == TYPE_CODE_ARRAY)
@ -4216,54 +4236,110 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *func_type,
else if (TYPE_CODE (type) == TYPE_CODE_FLT else if (TYPE_CODE (type) == TYPE_CODE_FLT
&& TYPE_LENGTH (type) == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE) && TYPE_LENGTH (type) == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE)
{ {
/* A single-precision floating-point value. It fits in the /* A single-precision floating-point value. If reading in or copying,
least significant part of FP0. */ then we get it from/put it to FP0 for standard MIPS code or GPR2
for MIPS16 code. If writing out only, then we put it to both FP0
and GPR2. We do not support reading in with no function known, if
this safety check ever triggers, then we'll have to try harder. */
gdb_assert (function || !readbuf);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); switch (fval_reg)
mips_xfer_register (gdbarch, regcache, {
(gdbarch_num_regs (gdbarch) case mips_fval_fpr:
+ mips_regnum (gdbarch)->fp0), fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
TYPE_LENGTH (type), break;
gdbarch_byte_order (gdbarch), case mips_fval_gpr:
readbuf, writebuf, 0); fprintf_unfiltered (gdb_stderr, "Return float in $2\n");
break;
case mips_fval_both:
fprintf_unfiltered (gdb_stderr, "Return float in $fp0 and $2\n");
break;
}
if (fval_reg != mips_fval_gpr)
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0),
TYPE_LENGTH (type),
gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
if (fval_reg != mips_fval_fpr)
mips_xfer_register (gdbarch, regcache,
gdbarch_num_regs (gdbarch) + 2,
TYPE_LENGTH (type),
gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
return RETURN_VALUE_REGISTER_CONVENTION; return RETURN_VALUE_REGISTER_CONVENTION;
} }
else if (TYPE_CODE (type) == TYPE_CODE_FLT else if (TYPE_CODE (type) == TYPE_CODE_FLT
&& TYPE_LENGTH (type) == 8 && tdep->mips_fpu_type != MIPS_FPU_NONE) && TYPE_LENGTH (type) == 8 && tdep->mips_fpu_type != MIPS_FPU_NONE)
{ {
/* A double-precision floating-point value. The most /* A double-precision floating-point value. If reading in or copying,
significant part goes in FP1, and the least significant in then we get it from/put it to FP1 and FP0 for standard MIPS code or
FP0. */ GPR2 and GPR3 for MIPS16 code. If writing out only, then we put it
to both FP1/FP0 and GPR2/GPR3. We do not support reading in with
no function known, if this safety check ever triggers, then we'll
have to try harder. */
gdb_assert (function || !readbuf);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n"); switch (fval_reg)
switch (gdbarch_byte_order (gdbarch)) {
case mips_fval_fpr:
fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n");
break;
case mips_fval_gpr:
fprintf_unfiltered (gdb_stderr, "Return float in $2/$3\n");
break;
case mips_fval_both:
fprintf_unfiltered (gdb_stderr,
"Return float in $fp1/$fp0 and $2/$3\n");
break;
}
if (fval_reg != mips_fval_gpr)
{ {
case BFD_ENDIAN_LITTLE: /* The most significant part goes in FP1, and the least significant
in FP0. */
switch (gdbarch_byte_order (gdbarch))
{
case BFD_ENDIAN_LITTLE:
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0 + 0),
4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0 + 1),
4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 4);
break;
case BFD_ENDIAN_BIG:
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0 + 1),
4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0 + 0),
4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 4);
break;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
}
if (fval_reg != mips_fval_fpr)
{
/* The two 32-bit parts are always placed in GPR2 and GPR3
following these registers' memory order. */
mips_xfer_register (gdbarch, regcache, mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch) gdbarch_num_regs (gdbarch) + 2,
+ mips_regnum (gdbarch)->fp0 + 0),
4, gdbarch_byte_order (gdbarch), 4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0); readbuf, writebuf, 0);
mips_xfer_register (gdbarch, regcache, mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch) gdbarch_num_regs (gdbarch) + 3,
+ mips_regnum (gdbarch)->fp0 + 1),
4, gdbarch_byte_order (gdbarch), 4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 4); readbuf, writebuf, 4);
break;
case BFD_ENDIAN_BIG:
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0 + 1),
4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0 + 0),
4, gdbarch_byte_order (gdbarch),
readbuf, writebuf, 4);
break;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
} }
return RETURN_VALUE_REGISTER_CONVENTION; return RETURN_VALUE_REGISTER_CONVENTION;
} }
@ -4459,14 +4535,14 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
} }
/* Floating point arguments passed in registers have to be /* Floating point arguments passed in registers have to be
treated specially. On 32-bit architectures, doubles treated specially. On 32-bit architectures, doubles are
are passed in register pairs; the even register gets passed in register pairs; the even FP register gets the
the low word, and the odd register gets the high word. low word, and the odd FP register gets the high word.
On O32/O64, the first two floating point arguments are On O64, the first two floating point arguments are also
also copied to general registers, because MIPS16 functions copied to general registers, because MIPS16 functions
don't use float registers for arguments. This duplication of don't use float registers for arguments. This duplication
arguments in general registers can't hurt non-MIPS16 functions of arguments in general registers can't hurt non-MIPS16
because those registers are normally skipped. */ functions because those registers are normally skipped. */
if (fp_register_arg_p (gdbarch, typecode, arg_type) if (fp_register_arg_p (gdbarch, typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch)) && float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch))
@ -4611,28 +4687,54 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
} }
static enum return_value_convention static enum return_value_convention
mips_o64_return_value (struct gdbarch *gdbarch, struct type *func_type, mips_o64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int mips16 = mips_pc_is_mips16 (func_addr);
enum mips_fval_reg fval_reg;
fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both;
if (TYPE_CODE (type) == TYPE_CODE_STRUCT if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION || TYPE_CODE (type) == TYPE_CODE_UNION
|| TYPE_CODE (type) == TYPE_CODE_ARRAY) || TYPE_CODE (type) == TYPE_CODE_ARRAY)
return RETURN_VALUE_STRUCT_CONVENTION; return RETURN_VALUE_STRUCT_CONVENTION;
else if (fp_register_arg_p (gdbarch, TYPE_CODE (type), type)) else if (fp_register_arg_p (gdbarch, TYPE_CODE (type), type))
{ {
/* A floating-point value. It fits in the least significant /* A floating-point value. If reading in or copying, then we get it
part of FP0. */ from/put it to FP0 for standard MIPS code or GPR2 for MIPS16 code.
If writing out only, then we put it to both FP0 and GPR2. We do
not support reading in with no function known, if this safety
check ever triggers, then we'll have to try harder. */
gdb_assert (function || !readbuf);
if (mips_debug) if (mips_debug)
fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); switch (fval_reg)
mips_xfer_register (gdbarch, regcache, {
(gdbarch_num_regs (gdbarch) case mips_fval_fpr:
+ mips_regnum (gdbarch)->fp0), fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
TYPE_LENGTH (type), break;
gdbarch_byte_order (gdbarch), case mips_fval_gpr:
readbuf, writebuf, 0); fprintf_unfiltered (gdb_stderr, "Return float in $2\n");
break;
case mips_fval_both:
fprintf_unfiltered (gdb_stderr, "Return float in $fp0 and $2\n");
break;
}
if (fval_reg != mips_fval_gpr)
mips_xfer_register (gdbarch, regcache,
(gdbarch_num_regs (gdbarch)
+ mips_regnum (gdbarch)->fp0),
TYPE_LENGTH (type),
gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
if (fval_reg != mips_fval_fpr)
mips_xfer_register (gdbarch, regcache,
gdbarch_num_regs (gdbarch) + 2,
TYPE_LENGTH (type),
gdbarch_byte_order (gdbarch),
readbuf, writebuf, 0);
return RETURN_VALUE_REGISTER_CONVENTION; return RETURN_VALUE_REGISTER_CONVENTION;
} }
else else

View file

@ -233,7 +233,7 @@ mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type,
from WRITEBUF into REGCACHE. */ from WRITEBUF into REGCACHE. */
static enum return_value_convention static enum return_value_convention
mn10300_return_value (struct gdbarch *gdbarch, struct type *func_type, mn10300_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -341,7 +341,7 @@ moxie_extract_return_value (struct type *type, struct regcache *regcache,
/* Implement the "return_value" gdbarch method. */ /* Implement the "return_value" gdbarch method. */
static enum return_value_convention static enum return_value_convention
moxie_return_value (struct gdbarch *gdbarch, struct type *func_type, moxie_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -335,7 +335,7 @@ mt_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
values. */ values. */
static enum return_value_convention static enum return_value_convention
mt_return_value (struct gdbarch *gdbarch, struct type *func_type, mt_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -241,7 +241,7 @@ ppc_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
which were added later, do get returned in a register though. */ which were added later, do get returned in a register though. */
static enum return_value_convention static enum return_value_convention
ppc_linux_return_value (struct gdbarch *gdbarch, struct type *func_type, ppc_linux_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -251,7 +251,7 @@ ppc_linux_return_value (struct gdbarch *gdbarch, struct type *func_type,
&& TYPE_VECTOR (valtype))) && TYPE_VECTOR (valtype)))
return RETURN_VALUE_STRUCT_CONVENTION; return RETURN_VALUE_STRUCT_CONVENTION;
else else
return ppc_sysv_abi_return_value (gdbarch, func_type, valtype, regcache, return ppc_sysv_abi_return_value (gdbarch, function, valtype, regcache,
readbuf, writebuf); readbuf, writebuf);
} }

View file

@ -1041,23 +1041,25 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
} }
enum return_value_convention enum return_value_convention
ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *func_type, ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
return do_ppc_sysv_return_value (gdbarch, func_type, valtype, regcache, return do_ppc_sysv_return_value (gdbarch,
readbuf, writebuf, 0); function ? value_type (function) : NULL,
valtype, regcache, readbuf, writebuf, 0);
} }
enum return_value_convention enum return_value_convention
ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
return do_ppc_sysv_return_value (gdbarch, func_type, valtype, regcache, return do_ppc_sysv_return_value (gdbarch,
readbuf, writebuf, 1); function ? value_type (function) : NULL,
valtype, regcache, readbuf, writebuf, 1);
} }
/* The helper function for 64-bit SYSV push_dummy_call. Converts the /* The helper function for 64-bit SYSV push_dummy_call. Converts the
@ -1710,12 +1712,13 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
location; when READBUF is non-NULL, fill the buffer from the location; when READBUF is non-NULL, fill the buffer from the
corresponding register return-value location. */ corresponding register return-value location. */
enum return_value_convention enum return_value_convention
ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *func_type, ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct type *func_type = function ? value_type (function) : NULL;
int opencl_abi = func_type? ppc_sysv_use_opencl_abi (func_type) : 0; int opencl_abi = func_type? ppc_sysv_use_opencl_abi (func_type) : 0;
/* This function exists to support a calling convention that /* This function exists to support a calling convention that

View file

@ -28,13 +28,13 @@ struct type;
/* From ppc-sysv-tdep.c ... */ /* From ppc-sysv-tdep.c ... */
enum return_value_convention ppc_sysv_abi_return_value (struct gdbarch *gdbarch, enum return_value_convention ppc_sysv_abi_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, gdb_byte *readbuf,
const gdb_byte *writebuf); const gdb_byte *writebuf);
enum return_value_convention ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, enum return_value_convention ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, gdb_byte *readbuf,
@ -54,7 +54,7 @@ CORE_ADDR ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
int struct_return, int struct_return,
CORE_ADDR struct_addr); CORE_ADDR struct_addr);
enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, gdb_byte *readbuf,

View file

@ -76,7 +76,7 @@ ppcnbsd_regset_from_core_section (struct gdbarch *gdbarch,
the moment use the broken convention. Ulgh! */ the moment use the broken convention. Ulgh! */
static enum return_value_convention static enum return_value_convention
ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *func_type, ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
@ -92,7 +92,7 @@ ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *func_type,
return RETURN_VALUE_STRUCT_CONVENTION; return RETURN_VALUE_STRUCT_CONVENTION;
else else
#endif #endif
return ppc_sysv_abi_broken_return_value (gdbarch, func_type, valtype, return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
regcache, readbuf, writebuf); regcache, readbuf, writebuf);
} }

View file

@ -29,6 +29,7 @@
#include "language.h" #include "language.h"
#include "observer.h" #include "observer.h"
#include "inferior.h" #include "inferior.h"
#include "block.h"
static PyTypeObject finish_breakpoint_object_type; static PyTypeObject finish_breakpoint_object_type;
@ -45,9 +46,9 @@ struct finish_breakpoint_object
May be NULL if no debug information was available or return type May be NULL if no debug information was available or return type
was VOID. */ was VOID. */
PyObject *return_type; PyObject *return_type;
/* gdb.Type object of the function finished by this breakpoint. Will be /* gdb.Value object of the function finished by this breakpoint. Will be
NULL if return_type is NULL. */ NULL if return_type is NULL. */
PyObject *function_type; PyObject *function_value;
/* When stopped at this FinishBreakpoint, gdb.Value object returned by /* When stopped at this FinishBreakpoint, gdb.Value object returned by
the function; Py_None if the value is not computable; NULL if GDB is the function; Py_None if the value is not computable; NULL if GDB is
not stopped at a FinishBreakpoint. */ not stopped at a FinishBreakpoint. */
@ -78,7 +79,7 @@ bpfinishpy_dealloc (PyObject *self)
struct finish_breakpoint_object *self_bpfinish = struct finish_breakpoint_object *self_bpfinish =
(struct finish_breakpoint_object *) self; (struct finish_breakpoint_object *) self;
Py_XDECREF (self_bpfinish->function_type); Py_XDECREF (self_bpfinish->function_value);
Py_XDECREF (self_bpfinish->return_type); Py_XDECREF (self_bpfinish->return_type);
Py_XDECREF (self_bpfinish->return_value); Py_XDECREF (self_bpfinish->return_value);
} }
@ -102,9 +103,11 @@ bpfinishpy_pre_stop_hook (struct breakpoint_object *bp_obj)
TRY_CATCH (except, RETURN_MASK_ALL) TRY_CATCH (except, RETURN_MASK_ALL)
{ {
struct value *ret = struct value *function =
get_return_value (type_object_to_type (self_finishbp->function_type), value_object_to_value (self_finishbp->function_value);
type_object_to_type (self_finishbp->return_type)); struct type *value_type =
type_object_to_type (self_finishbp->return_type);
struct value *ret = get_return_value (function, value_type);
if (ret) if (ret)
{ {
@ -233,7 +236,7 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
/* Find the function we will return from. */ /* Find the function we will return from. */
self_bpfinish->return_type = NULL; self_bpfinish->return_type = NULL;
self_bpfinish->function_type = NULL; self_bpfinish->function_value = NULL;
TRY_CATCH (except, RETURN_MASK_ALL) TRY_CATCH (except, RETURN_MASK_ALL)
{ {
@ -248,25 +251,28 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
/* Remember only non-void return types. */ /* Remember only non-void return types. */
if (TYPE_CODE (ret_type) != TYPE_CODE_VOID) if (TYPE_CODE (ret_type) != TYPE_CODE_VOID)
{ {
struct value *func_value;
/* Ignore Python errors at this stage. */ /* Ignore Python errors at this stage. */
self_bpfinish->return_type = type_to_type_object (ret_type); self_bpfinish->return_type = type_to_type_object (ret_type);
PyErr_Clear (); PyErr_Clear ();
self_bpfinish->function_type = func_value = read_var_value (function, frame);
type_to_type_object (SYMBOL_TYPE (function)); self_bpfinish->function_value =
value_to_value_object (func_value);
PyErr_Clear (); PyErr_Clear ();
} }
} }
} }
} }
if (except.reason < 0 if (except.reason < 0
|| !self_bpfinish->return_type || !self_bpfinish->function_type) || !self_bpfinish->return_type || !self_bpfinish->function_value)
{ {
/* Won't be able to compute return value. */ /* Won't be able to compute return value. */
Py_XDECREF (self_bpfinish->return_type); Py_XDECREF (self_bpfinish->return_type);
Py_XDECREF (self_bpfinish->function_type); Py_XDECREF (self_bpfinish->function_value);
self_bpfinish->return_type = NULL; self_bpfinish->return_type = NULL;
self_bpfinish->function_type = NULL; self_bpfinish->function_value = NULL;
} }
bppy_pending_object = &self_bpfinish->py_bp; bppy_pending_object = &self_bpfinish->py_bp;

View file

@ -934,7 +934,7 @@ rl78_register_sim_regno (struct gdbarch *gdbarch, int regnum)
static enum return_value_convention static enum return_value_convention
rl78_return_value (struct gdbarch *gdbarch, rl78_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)

View file

@ -424,7 +424,7 @@ ran_out_of_registers_for_arguments:
} }
static enum return_value_convention static enum return_value_convention
rs6000_return_value (struct gdbarch *gdbarch, struct type *func_type, rs6000_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache, struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -702,7 +702,7 @@ rx_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Implement the "return_value" gdbarch method. */ /* Implement the "return_value" gdbarch method. */
static enum return_value_convention static enum return_value_convention
rx_return_value (struct gdbarch *gdbarch, rx_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)

View file

@ -2818,7 +2818,7 @@ s390_return_value_convention (struct gdbarch *gdbarch, struct type *type)
} }
static enum return_value_convention static enum return_value_convention
s390_return_value (struct gdbarch *gdbarch, struct type *func_type, s390_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *out, const gdb_byte *in) gdb_byte *out, const gdb_byte *in)
{ {

View file

@ -450,7 +450,7 @@ score_xfer_register (struct regcache *regcache, int regnum, int length,
} }
static enum return_value_convention static enum return_value_convention
score_return_value (struct gdbarch *gdbarch, struct type *func_type, score_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte * readbuf, const gdb_byte * writebuf) gdb_byte * readbuf, const gdb_byte * writebuf)
{ {

View file

@ -1398,10 +1398,12 @@ sh_store_return_value_fpu (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *func_type, sh_return_value_nofpu (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
struct type *func_type = function ? value_type (function) : NULL;
if (sh_use_struct_convention_nofpu ( if (sh_use_struct_convention_nofpu (
sh_is_renesas_calling_convention (func_type), type)) sh_is_renesas_calling_convention (func_type), type))
return RETURN_VALUE_STRUCT_CONVENTION; return RETURN_VALUE_STRUCT_CONVENTION;
@ -1413,10 +1415,12 @@ sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *func_type,
} }
static enum return_value_convention static enum return_value_convention
sh_return_value_fpu (struct gdbarch *gdbarch, struct type *func_type, sh_return_value_fpu (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {
struct type *func_type = function ? value_type (function) : NULL;
if (sh_use_struct_convention ( if (sh_use_struct_convention (
sh_is_renesas_calling_convention (func_type), type)) sh_is_renesas_calling_convention (func_type), type))
return RETURN_VALUE_STRUCT_CONVENTION; return RETURN_VALUE_STRUCT_CONVENTION;

View file

@ -1328,7 +1328,7 @@ sh64_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
sh64_return_value (struct gdbarch *gdbarch, struct type *func_type, sh64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1354,7 +1354,7 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
sparc32_return_value (struct gdbarch *gdbarch, struct type *func_type, sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1119,7 +1119,7 @@ sparc64_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
sparc64_return_value (struct gdbarch *gdbarch, struct type *func_type, sparc64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1450,10 +1450,11 @@ spu_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
/* Function return value access. */ /* Function return value access. */
static enum return_value_convention static enum return_value_convention
spu_return_value (struct gdbarch *gdbarch, struct type *func_type, spu_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *out, const gdb_byte *in) gdb_byte *out, const gdb_byte *in)
{ {
struct type *func_type = function ? value_type (function) : NULL;
enum return_value_convention rvc; enum return_value_convention rvc;
int opencl_vector = 0; int opencl_vector = 0;

View file

@ -2238,6 +2238,7 @@ return_command (char *retval_exp, int from_tty)
struct gdbarch *gdbarch; struct gdbarch *gdbarch;
struct symbol *thisfun; struct symbol *thisfun;
struct value *return_value = NULL; struct value *return_value = NULL;
struct value *function = NULL;
const char *query_prefix = ""; const char *query_prefix = "";
thisframe = get_selected_frame ("No selected frame."); thisframe = get_selected_frame ("No selected frame.");
@ -2282,6 +2283,9 @@ return_command (char *retval_exp, int from_tty)
if (value_lazy (return_value)) if (value_lazy (return_value))
value_fetch_lazy (return_value); value_fetch_lazy (return_value);
if (thisfun != NULL)
function = read_var_value (thisfun, thisframe);
if (TYPE_CODE (return_type) == TYPE_CODE_VOID) if (TYPE_CODE (return_type) == TYPE_CODE_VOID)
/* If the return-type is "void", don't try to find the /* If the return-type is "void", don't try to find the
return-value's location. However, do still evaluate the return-value's location. However, do still evaluate the
@ -2290,8 +2294,7 @@ return_command (char *retval_exp, int from_tty)
occur. */ occur. */
return_value = NULL; return_value = NULL;
else if (thisfun != NULL else if (thisfun != NULL
&& using_struct_return (gdbarch, && using_struct_return (gdbarch, function, return_type))
SYMBOL_TYPE (thisfun), return_type))
{ {
query_prefix = "The location at which to store the " query_prefix = "The location at which to store the "
"function's return value is unknown.\n" "function's return value is unknown.\n"
@ -2326,12 +2329,11 @@ return_command (char *retval_exp, int from_tty)
{ {
struct type *return_type = value_type (return_value); struct type *return_type = value_type (return_value);
struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ()); struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
struct type *func_type = thisfun == NULL ? NULL : SYMBOL_TYPE (thisfun);
gdb_assert (gdbarch_return_value (gdbarch, func_type, return_type, NULL, gdb_assert (gdbarch_return_value (gdbarch, function, return_type, NULL,
NULL, NULL) NULL, NULL)
== RETURN_VALUE_REGISTER_CONVENTION); == RETURN_VALUE_REGISTER_CONVENTION);
gdbarch_return_value (gdbarch, func_type, return_type, gdbarch_return_value (gdbarch, function, return_type,
get_current_regcache (), NULL /*read*/, get_current_regcache (), NULL /*read*/,
value_contents (return_value) /*write*/); value_contents (return_value) /*write*/);
} }

View file

@ -1,3 +1,7 @@
2012-05-16 Maciej W. Rozycki <macro@codesourcery.com>
* gdb.base/return-nodebug.exp: Also test float and double types.
2012-05-15 Jan Kratochvil <jan.kratochvil@redhat.com> 2012-05-15 Jan Kratochvil <jan.kratochvil@redhat.com>
PR testsuite/12649 PR testsuite/12649

View file

@ -41,7 +41,7 @@ proc do_test {type} {
} }
} }
foreach type {{signed char} {short} {int} {long} {long long}} { foreach type {{signed char} {short} {int} {long} {long long} {float} {double}} {
set typeesc [string map {{ } {\ }} $type] set typeesc [string map {{ } {\ }} $type]
set typenospace [string map {{ } -} $type] set typenospace [string map {{ } -} $type]

View file

@ -821,7 +821,7 @@ tic6x_store_return_value (struct type *valtype, struct regcache *regcache,
/* This is the implementation of gdbarch method return_value. */ /* This is the implementation of gdbarch method return_value. */
static enum return_value_convention static enum return_value_convention
tic6x_return_value (struct gdbarch *gdbarch, struct type *func_type, tic6x_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -933,7 +933,7 @@ v850_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
v850_return_value (struct gdbarch *gdbarch, struct type *func_type, v850_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -3303,7 +3303,7 @@ coerce_array (struct value *arg)
int int
using_struct_return (struct gdbarch *gdbarch, using_struct_return (struct gdbarch *gdbarch,
struct type *func_type, struct type *value_type) struct value *function, struct type *value_type)
{ {
enum type_code code = TYPE_CODE (value_type); enum type_code code = TYPE_CODE (value_type);
@ -3316,7 +3316,7 @@ using_struct_return (struct gdbarch *gdbarch,
return 0; return 0;
/* Probe the architecture for the return-value convention. */ /* Probe the architecture for the return-value convention. */
return (gdbarch_return_value (gdbarch, func_type, value_type, return (gdbarch_return_value (gdbarch, function, value_type,
NULL, NULL, NULL) NULL, NULL, NULL)
!= RETURN_VALUE_REGISTER_CONVENTION); != RETURN_VALUE_REGISTER_CONVENTION);
} }

View file

@ -698,7 +698,7 @@ extern int value_bit_index (struct type *type, const gdb_byte *addr,
int index); int index);
extern int using_struct_return (struct gdbarch *gdbarch, extern int using_struct_return (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *value_type); struct type *value_type);
extern struct value *evaluate_expression (struct expression *exp); extern struct value *evaluate_expression (struct expression *exp);

View file

@ -204,7 +204,7 @@ vax_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
static enum return_value_convention static enum return_value_convention
vax_return_value (struct gdbarch *gdbarch, struct type *func_type, vax_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -197,7 +197,7 @@ xstormy16_store_return_value (struct type *type, struct regcache *regcache,
} }
static enum return_value_convention static enum return_value_convention
xstormy16_return_value (struct gdbarch *gdbarch, struct type *func_type, xstormy16_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache, struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf) gdb_byte *readbuf, const gdb_byte *writebuf)
{ {

View file

@ -1682,7 +1682,7 @@ xtensa_store_return_value (struct type *type,
static enum return_value_convention static enum return_value_convention
xtensa_return_value (struct gdbarch *gdbarch, xtensa_return_value (struct gdbarch *gdbarch,
struct type *func_type, struct value *function,
struct type *valtype, struct type *valtype,
struct regcache *regcache, struct regcache *regcache,
gdb_byte *readbuf, gdb_byte *readbuf,