From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12508 invoked by alias); 23 Apr 2012 13:21:18 -0000 Received: (qmail 12475 invoked by uid 22791); 23 Apr 2012 13:21:10 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,FROM_12LTRDOM,KAM_STOCKGEN,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_BP,TW_CN,TW_EG,TW_HP X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 23 Apr 2012 13:20:49 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1SMJC7-0000Gq-JJ from Maciej_Rozycki@mentor.com for gdb-patches@sourceware.org; Mon, 23 Apr 2012 06:20:43 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 23 Apr 2012 06:20:36 -0700 Received: from [172.30.0.81] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Mon, 23 Apr 2012 14:20:32 +0100 Date: Mon, 23 Apr 2012 13:30:00 -0000 From: "Maciej W. Rozycki" To: Subject: [RFA] MIPS16 FP manual call/return fixes Message-ID: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-04/txt/msg00739.txt.bz2 Hello, Here is a change that addresses a problem that we have with MIPS16 FP manual call/return handlers. This only addresses the o32 and o64 ABIs as we currently do not support hard-float for new ABIs. As noted with the recent MIPS16 thunk fix submission, MIPS targets use a different calling convention for passing floating-point arguments and results in registers for standard ABI and MIPS16 code. We currently handle it partially for manual calls in the push_dummy_call handlers (but then do not get it right for o32) and do not handle it at all in the return_value handlers. For the push_dummy_call handlers the fix is easy -- general register arguments always follow their memory order (i.e. the order they would be pushed on the stack if they were stack arguments), that is unlike with 32-bit floating-point registers they hold opposite halves of the same FP values each for the two endiannesses possible. This is fixed with this change, rather trivially. These handlers always store arguments in floating-point and general-purpose registers both at a time -- that being safe owing to either of each being dead on function entry depending on the calling convention used. The handling of manual returns is a bit more difficult, it's not always safe to use both at a time, because the handlers are dual-purpose. They are used to either retrieve the return value of the function called, from the result register(s), such as when: (gdb) print foo() is used, or to push the return value to the intended register(s), such as with: (gdb) return foo As with arguments, either of the respective floating-point and general-purpose registers are dead on function return, which means it is safe to write both in the latter case, however to handle the former, the right register(s) need to be read. For this to work we need to know if the function called was standard ABI or MIPS16 code, something that is currently not known to the return handlers. Therefore I had to change the return handlers' internal API to take the value of the function being handled rather than its lone type, if available. This has led to adjusting the whole infrastructure. With this in place the return handler, if called to read registers, selects the appropriate set. If called to write registers, it stores the return value to both sets. The handler is called with no specific function selected in some cases -- it is assumed (and guarded by assertions) that it will never be called to read registers in this case (as presumably the function just called must have been known). I have tested it for the mips-sde-elf and mips-linux-gnu targets, o32/MIPS32, o32/MIPS16 and n64 multilibs, fixing numerous problems, like: (gdb) FAIL: gdb.base/call-sc.exp: p/c L; call call-sc-tf (gdb) FAIL: gdb.base/call-sc.exp: p/c L; call call-sc-td (gdb) FAIL: gdb.base/call-sc.exp: p/c L; call call-sc-tld The patch also fixes failures introduced by the change to return-nodebug.exp included here to cover some floating-point types that were not tested this way before -- this is an example where the value of the function returned from is not known. I have also tested it on i686-linux-gnu, powerpc-linux-gnu, and sh-linux-gnu, the former being the usual suspect and the latters being representative for some non-trival changes made to other targets here, no regressions. Finally, this change intentionally does not cover complex types which we currently do not handle at all for the MIPS target for any ABI -- one fix at a time. Is this change OK to commit? Please have a look specifically at changes I made to support the IFUNC feature (elfread.c) and updates to Python support (py-finishbreakpoint.c) as these are not my usual areas of experience. 2012-04-23 Maciej W. Rozycki Maciej W. Rozycki gdb/ * 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. * 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. * 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. * rs6000-aix-tdep.c (rs6000_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-04-23 Maciej W. Rozycki gdb/testsuite/ * gdb.base/return-nodebug.exp: Also test float and double types. Maciej Index: gdb-fsf-trunk-quilt/gdb/alpha-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/alpha-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/alpha-tdep.c 2012-04-23 14:12:54.705579723 +0100 @@ -612,7 +612,7 @@ alpha_store_return_value (struct type *v } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/amd64-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/amd64-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/amd64-tdep.c 2012-04-23 14:12:54.705579723 +0100 @@ -592,7 +592,7 @@ amd64_classify (struct type *type, enum } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/arm-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/arm-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/arm-tdep.c 2012-04-23 14:12:54.715571159 +0100 @@ -9010,11 +9010,12 @@ arm_store_return_value (struct type *typ /* Handle function return values. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { 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; int vfp_base_count; Index: gdb-fsf-trunk-quilt/gdb/cris-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/cris-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/cris-tdep.c 2012-04-23 14:12:54.735579761 +0100 @@ -1863,7 +1863,7 @@ cris_extract_return_value (struct type * /* Handle the CRIS 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/eval.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/eval.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/eval.c 2012-04-23 14:12:54.945578942 +0100 @@ -1358,8 +1358,7 @@ evaluate_subexp_standard (struct type *e val_type = expect_type; } - struct_return = using_struct_return (exp->gdbarch, - value_type (method), + struct_return = using_struct_return (exp->gdbarch, method, val_type); } else if (expect_type != NULL) Index: gdb-fsf-trunk-quilt/gdb/frv-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/frv-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/frv-tdep.c 2012-04-23 14:12:55.115577291 +0100 @@ -1351,7 +1351,7 @@ frv_store_return_value (struct type *typ } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/gdbarch.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/gdbarch.c 2012-04-23 14:12:53.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/gdbarch.c 2012-04-23 14:12:55.415581296 +0100 @@ -2477,13 +2477,13 @@ gdbarch_return_value_p (struct gdbarch * } 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->return_value != NULL); if (gdbarch_debug >= 2) 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 Index: gdb-fsf-trunk-quilt/gdb/gdbarch.h =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/gdbarch.h 2012-04-23 14:12:53.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/gdbarch.h 2012-04-23 14:12:55.675579269 +0100 @@ -448,8 +448,8 @@ extern void set_gdbarch_integer_to_addre 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); -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); +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 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); typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip); Index: gdb-fsf-trunk-quilt/gdb/gdbarch.sh =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/gdbarch.sh 2012-04-23 14:12:53.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/gdbarch.sh 2012-04-23 14:12:55.935577511 +0100 @@ -513,7 +513,7 @@ M:CORE_ADDR:integer_to_address:struct ty # stored into the appropriate register. This can be used when we want # to force the value returned by a function (see the "return" command # 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:functype, valtype, regcache, readbuf, writebuf m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip Index: gdb-fsf-trunk-quilt/gdb/h8300-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/h8300-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/h8300-tdep.c 2012-04-23 14:12:56.005575376 +0100 @@ -901,7 +901,7 @@ h8300h_store_return_value (struct type * } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -915,7 +915,7 @@ h8300_return_value (struct gdbarch *gdba } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/hppa-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/hppa-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/hppa-tdep.c 2012-04-23 14:12:56.235578496 +0100 @@ -1114,7 +1114,7 @@ hppa64_push_dummy_call (struct gdbarch * /* Handle 32/64-bit struct return conventions. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -1154,7 +1154,7 @@ hppa32_return_value (struct gdbarch *gdb } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/i386-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/i386-tdep.c 2012-04-23 14:12:41.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/i386-tdep.c 2012-04-23 14:12:56.695574486 +0100 @@ -2598,7 +2598,7 @@ i386_reg_struct_return_p (struct gdbarch from WRITEBUF into REGCACHE. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -2649,7 +2649,7 @@ i386_return_value (struct gdbarch *gdbar if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) { 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); } Index: gdb-fsf-trunk-quilt/gdb/ia64-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/ia64-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/ia64-tdep.c 2012-04-23 14:12:56.995579166 +0100 @@ -3340,7 +3340,7 @@ ia64_store_return_value (struct type *ty } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/infcall.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/infcall.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/infcall.c 2012-04-23 14:12:57.135577338 +0100 @@ -608,8 +608,7 @@ call_function_by_hand (struct value *fun } else { - struct_return = using_struct_return (gdbarch, - value_type (function), values_type); + struct_return = using_struct_return (gdbarch, function, values_type); target_values_type = values_type; } @@ -1048,13 +1047,13 @@ When the function is done executing, GDB { /* If the function returns void, don't bother fetching the return value. */ - switch (gdbarch_return_value (gdbarch, value_type (function), - target_values_type, NULL, NULL, NULL)) + switch (gdbarch_return_value (gdbarch, function, target_values_type, + NULL, NULL, NULL)) { case RETURN_VALUE_REGISTER_CONVENTION: case RETURN_VALUE_ABI_RETURNS_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); break; case RETURN_VALUE_STRUCT_CONVENTION: Index: gdb-fsf-trunk-quilt/gdb/infcmd.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/infcmd.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/infcmd.c 2012-04-23 14:12:57.395577550 +0100 @@ -75,7 +75,7 @@ void interrupt_target_command (char *arg 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); static void until_next_command (int); @@ -1416,7 +1416,7 @@ advance_command (char *arg, int from_tty command/BP. */ 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 gdbarch *gdbarch; @@ -1443,14 +1443,14 @@ get_return_value (struct type *func_type inferior function call code. In fact, when inferior function 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)) { case RETURN_VALUE_REGISTER_CONVENTION: case RETURN_VALUE_ABI_RETURNS_ADDRESS: case RETURN_VALUE_ABI_PRESERVES_ADDRESS: 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); break; case RETURN_VALUE_STRUCT_CONVENTION: @@ -1468,9 +1468,9 @@ get_return_value (struct type *func_type /* Print the result of a function at the end of a 'finish' command. */ 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; if (value) @@ -1547,14 +1547,17 @@ finish_command_continuation (void *arg, if (TYPE_CODE (value_type) != TYPE_CODE_VOID) { + CORE_ADDR faddr = BLOCK_START (SYMBOL_BLOCK_VALUE (a->function)); + struct value *func = allocate_value (SYMBOL_TYPE (a->function)); volatile struct gdb_exception ex; + set_value_address (func, faddr); TRY_CATCH (ex, RETURN_MASK_ALL) { /* print_return_value can throw an exception in some circumstances. We need to catch this so that we still delete the breakpoint. */ - print_return_value (SYMBOL_TYPE (a->function), value_type); + print_return_value (func, value_type); } if (ex.reason < 0) exception_print (gdb_stdout, ex); Index: gdb-fsf-trunk-quilt/gdb/iq2000-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/iq2000-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/iq2000-tdep.c 2012-04-23 14:12:57.545576783 +0100 @@ -583,7 +583,7 @@ iq2000_extract_return_value (struct type } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/lm32-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/lm32-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/lm32-tdep.c 2012-04-23 14:12:57.575576872 +0100 @@ -374,7 +374,7 @@ lm32_store_return_value (struct type *ty /* Determine whether a functions return value is in a register or memory. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/m32c-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/m32c-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/m32c-tdep.c 2012-04-23 14:12:58.105573784 +0100 @@ -2206,7 +2206,7 @@ m32c_return_by_passed_buf (struct type * static enum return_value_convention m32c_return_value (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, Index: gdb-fsf-trunk-quilt/gdb/m32r-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/m32r-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/m32r-tdep.c 2012-04-23 14:12:58.105573784 +0100 @@ -809,7 +809,7 @@ m32r_extract_return_value (struct type * } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/m68hc11-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/m68hc11-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/m68hc11-tdep.c 2012-04-23 14:12:58.105573784 +0100 @@ -1323,8 +1323,8 @@ m68hc11_extract_return_value (struct typ } static enum return_value_convention -m68hc11_return_value (struct gdbarch *gdbarch, struct type *func_type, - struct type *valtype, struct regcache *regcache, +m68hc11_return_value (struct gdbarch *gdbarch, struct value *function, + struct value *function, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT Index: gdb-fsf-trunk-quilt/gdb/m68k-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/m68k-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/m68k-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -403,7 +403,7 @@ m68k_reg_struct_return_p (struct gdbarch from WRITEBUF into REGCACHE. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -438,7 +438,7 @@ m68k_return_value (struct gdbarch *gdbar } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -477,7 +477,7 @@ m68k_svr4_return_value (struct gdbarch * if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) { 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); } Index: gdb-fsf-trunk-quilt/gdb/m88k-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/m88k-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/m88k-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -383,7 +383,7 @@ m88k_dummy_id (struct gdbarch *arch, str from WRITEBUF into REGCACHE. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/mep-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/mep-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/mep-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -2194,7 +2194,7 @@ Try using the 'return' command with no a } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/mips-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/mips-tdep.c 2012-04-23 14:12:54.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/mips-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -3290,7 +3290,7 @@ mips_eabi_push_dummy_call (struct gdbarc /* Determine the return value convention being used. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -3680,7 +3680,7 @@ mips_n32n64_push_dummy_call (struct gdba } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -3848,6 +3848,20 @@ mips_n32n64_return_value (struct gdbarch } } +/* 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. */ static CORE_ADDR @@ -3938,8 +3952,8 @@ mips_o32_push_dummy_call (struct gdbarch /* 32-bit ABIs always start floating point arguments in an even-numbered floating point register. Round the FP register up before the check to see if there are any FP registers - left. O32/O64 targets also pass the FP in the integer - registers so also round up normal registers. */ + left. O32 targets also pass the FP in the integer registers + so also round up normal registers. */ if (fp_register_arg_p (gdbarch, typecode, arg_type)) { if ((float_argreg & 1)) @@ -3947,46 +3961,48 @@ mips_o32_push_dummy_call (struct gdbarch } /* Floating point arguments passed in registers have to be - treated specially. On 32-bit architectures, doubles - are passed in register pairs; the even register gets - the low word, and the odd register gets the high word. - On O32/O64, the first two floating point arguments are - also copied to general registers, because MIPS16 functions - don't use float registers for arguments. This duplication of - arguments in general registers can't hurt non-MIPS16 functions - because those registers are normally skipped. */ + treated specially. On 32-bit architectures, doubles are + passed in register pairs; the even FP register gets the + low word, and the odd FP register gets the high word. + On O32, the first two floating point arguments are also + copied to general registers, following their memory order, + because MIPS16 functions don't use float registers for + arguments. This duplication of arguments in general + registers can't hurt non-MIPS16 functions, because those + registers are normally skipped. */ if (fp_register_arg_p (gdbarch, typecode, arg_type) && float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch)) { if (register_size (gdbarch, float_argreg) < 8 && len == 8) { - int low_offset = gdbarch_byte_order (gdbarch) - == BFD_ENDIAN_BIG ? 4 : 0; + int freg_offset = gdbarch_byte_order (gdbarch) + == BFD_ENDIAN_BIG ? 1 : 0; unsigned long regval; - /* Write the low word of the double to the even register(s). */ - regval = extract_unsigned_integer (val + low_offset, - 4, byte_order); + /* First word. */ + regval = extract_unsigned_integer (val, 4, byte_order); if (mips_debug) 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, - float_argreg++, regval); + float_argreg++ + freg_offset, + regval); if (mips_debug) fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", argreg, phex (regval, 4)); regcache_cooked_write_unsigned (regcache, argreg++, regval); - /* Write the high word of the double to the odd register(s). */ - regval = extract_unsigned_integer (val + 4 - low_offset, - 4, byte_order); + /* Second word. */ + regval = extract_unsigned_integer (val + 4, 4, byte_order); if (mips_debug) 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, - float_argreg++, regval); - + float_argreg++ - freg_offset, + regval); if (mips_debug) fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", argreg, phex (regval, 4)); @@ -4161,12 +4177,16 @@ mips_o32_push_dummy_call (struct gdbarch } 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, 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); + 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 || TYPE_CODE (type) == TYPE_CODE_UNION || TYPE_CODE (type) == TYPE_CODE_ARRAY) @@ -4174,54 +4194,110 @@ mips_o32_return_value (struct gdbarch *g else if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE) { - /* A single-precision floating-point value. It fits in the - least significant part of FP0. */ + /* A single-precision floating-point value. If reading in or copying, + 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) - fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); - mips_xfer_register (gdbarch, regcache, - (gdbarch_num_regs (gdbarch) - + mips_regnum (gdbarch)->fp0), - TYPE_LENGTH (type), - gdbarch_byte_order (gdbarch), - readbuf, writebuf, 0); + switch (fval_reg) + { + case mips_fval_fpr: + fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); + break; + case mips_fval_gpr: + 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; } else if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8 && tdep->mips_fpu_type != MIPS_FPU_NONE) { - /* A double-precision floating-point value. The most - significant part goes in FP1, and the least significant in - FP0. */ + /* A double-precision floating-point value. If reading in or copying, + then we get it from/put it to FP1 and FP0 for standard MIPS code or + 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) - fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n"); - switch (gdbarch_byte_order (gdbarch)) + switch (fval_reg) + { + 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: - 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: + /* 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, - (gdbarch_num_regs (gdbarch) - + mips_regnum (gdbarch)->fp0 + 1), + gdbarch_num_regs (gdbarch) + 2, 4, gdbarch_byte_order (gdbarch), readbuf, writebuf, 0); mips_xfer_register (gdbarch, regcache, - (gdbarch_num_regs (gdbarch) - + mips_regnum (gdbarch)->fp0 + 0), + gdbarch_num_regs (gdbarch) + 3, 4, gdbarch_byte_order (gdbarch), readbuf, writebuf, 4); - break; - default: - internal_error (__FILE__, __LINE__, _("bad switch")); } return RETURN_VALUE_REGISTER_CONVENTION; } @@ -4401,14 +4477,14 @@ mips_o64_push_dummy_call (struct gdbarch val = value_contents (arg); /* Floating point arguments passed in registers have to be - treated specially. On 32-bit architectures, doubles - are passed in register pairs; the even register gets - the low word, and the odd register gets the high word. - On O32/O64, the first two floating point arguments are - also copied to general registers, because MIPS16 functions - don't use float registers for arguments. This duplication of - arguments in general registers can't hurt non-MIPS16 functions - because those registers are normally skipped. */ + treated specially. On 32-bit architectures, doubles are + passed in register pairs; the even FP register gets the + low word, and the odd FP register gets the high word. + On O64, the first two floating point arguments are also + copied to general registers, because MIPS16 functions + don't use float registers for arguments. This duplication + of arguments in general registers can't hurt non-MIPS16 + functions because those registers are normally skipped. */ if (fp_register_arg_p (gdbarch, typecode, arg_type) && float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch)) @@ -4553,28 +4629,54 @@ mips_o64_push_dummy_call (struct gdbarch } 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, 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); + 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 || TYPE_CODE (type) == TYPE_CODE_UNION || TYPE_CODE (type) == TYPE_CODE_ARRAY) return RETURN_VALUE_STRUCT_CONVENTION; else if (fp_register_arg_p (gdbarch, TYPE_CODE (type), type)) { - /* A floating-point value. It fits in the least significant - part of FP0. */ + /* A floating-point value. If reading in or copying, 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) - fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); - mips_xfer_register (gdbarch, regcache, - (gdbarch_num_regs (gdbarch) - + mips_regnum (gdbarch)->fp0), - TYPE_LENGTH (type), - gdbarch_byte_order (gdbarch), - readbuf, writebuf, 0); + switch (fval_reg) + { + case mips_fval_fpr: + fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); + break; + case mips_fval_gpr: + 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; } else Index: gdb-fsf-trunk-quilt/gdb/mn10300-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/mn10300-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/mn10300-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -233,7 +233,7 @@ mn10300_extract_return_value (struct gdb from WRITEBUF into REGCACHE. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/moxie-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/moxie-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/moxie-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -341,7 +341,7 @@ moxie_extract_return_value (struct type /* Implement the "return_value" gdbarch method. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/mt-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/mt-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/mt-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -335,7 +335,7 @@ mt_register_reggroup_p (struct gdbarch * values. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/ppc-linux-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/ppc-linux-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/ppc-linux-tdep.c 2012-04-23 14:12:58.115574547 +0100 @@ -233,7 +233,7 @@ ppc_linux_memory_remove_breakpoint (stru which were added later, do get returned in a register though. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -243,7 +243,7 @@ ppc_linux_return_value (struct gdbarch * && TYPE_VECTOR (valtype))) return RETURN_VALUE_STRUCT_CONVENTION; else - return ppc_sysv_abi_return_value (gdbarch, func_type, valtype, regcache, + return ppc_sysv_abi_return_value (gdbarch, function, valtype, regcache, readbuf, writebuf); } Index: gdb-fsf-trunk-quilt/gdb/ppc-sysv-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/ppc-sysv-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/ppc-sysv-tdep.c 2012-04-23 14:12:58.125568419 +0100 @@ -1041,23 +1041,25 @@ do_ppc_sysv_return_value (struct gdbarch } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { - return do_ppc_sysv_return_value (gdbarch, func_type, valtype, regcache, - readbuf, writebuf, 0); + return do_ppc_sysv_return_value (gdbarch, + function ? value_type (function) : NULL, + valtype, regcache, readbuf, writebuf, 0); } enum return_value_convention ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - return do_ppc_sysv_return_value (gdbarch, func_type, valtype, regcache, - readbuf, writebuf, 1); + return do_ppc_sysv_return_value (gdbarch, + function ? value_type (function) : NULL, + valtype, regcache, readbuf, writebuf, 1); } /* The helper function for 64-bit SYSV push_dummy_call. Converts the @@ -1710,12 +1712,13 @@ ppc64_sysv_abi_push_dummy_call (struct g location; when READBUF is non-NULL, fill the buffer from the corresponding register return-value location. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { struct gdbarch_tdep *tdep = gdbarch_tdep (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; /* This function exists to support a calling convention that Index: gdb-fsf-trunk-quilt/gdb/ppc-tdep.h =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/ppc-tdep.h 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/ppc-tdep.h 2012-04-23 14:12:58.135579487 +0100 @@ -28,13 +28,13 @@ struct type; /* From ppc-sysv-tdep.c ... */ enum return_value_convention ppc_sysv_abi_return_value (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf); enum return_value_convention ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, @@ -54,7 +54,7 @@ CORE_ADDR ppc64_sysv_abi_push_dummy_call int struct_return, CORE_ADDR struct_addr); enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, Index: gdb-fsf-trunk-quilt/gdb/ppcnbsd-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/ppcnbsd-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/ppcnbsd-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -76,7 +76,7 @@ ppcnbsd_regset_from_core_section (struct the moment use the broken convention. Ulgh! */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -92,7 +92,7 @@ ppcnbsd_return_value (struct gdbarch *gd return RETURN_VALUE_STRUCT_CONVENTION; else #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); } Index: gdb-fsf-trunk-quilt/gdb/rs6000-aix-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/rs6000-aix-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/rs6000-aix-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -424,7 +424,7 @@ rs6000_push_dummy_call (struct gdbarch * } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/s390-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/s390-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/s390-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -2812,7 +2812,7 @@ s390_return_value_convention (struct gdb } 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, gdb_byte *out, const gdb_byte *in) { Index: gdb-fsf-trunk-quilt/gdb/score-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/score-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/score-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -450,7 +450,7 @@ score_xfer_register (struct regcache *re } 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, gdb_byte * readbuf, const gdb_byte * writebuf) { Index: gdb-fsf-trunk-quilt/gdb/sh-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/sh-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/sh-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -1398,10 +1398,12 @@ sh_store_return_value_fpu (struct type * } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { + struct type *func_type = function ? value_type (function) : NULL; + if (sh_use_struct_convention_nofpu ( sh_is_renesas_calling_convention (func_type), type)) return RETURN_VALUE_STRUCT_CONVENTION; @@ -1413,10 +1415,12 @@ sh_return_value_nofpu (struct gdbarch *g } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { + struct type *func_type = function ? value_type (function) : NULL; + if (sh_use_struct_convention ( sh_is_renesas_calling_convention (func_type), type)) return RETURN_VALUE_STRUCT_CONVENTION; Index: gdb-fsf-trunk-quilt/gdb/sh64-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/sh64-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/sh64-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -1328,7 +1328,7 @@ sh64_store_return_value (struct type *ty } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/sparc-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/sparc-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/sparc-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -1353,7 +1353,7 @@ sparc32_store_return_value (struct type } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/sparc64-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/sparc64-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/sparc64-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -1119,7 +1119,7 @@ sparc64_store_return_value (struct type } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/spu-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/spu-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/spu-tdep.c 2012-04-23 14:12:58.135579487 +0100 @@ -1450,10 +1450,11 @@ spu_dummy_id (struct gdbarch *gdbarch, s /* Function return value access. */ 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, gdb_byte *out, const gdb_byte *in) { + struct type *func_type = function ? value_type (function) : NULL; enum return_value_convention rvc; int opencl_vector = 0; Index: gdb-fsf-trunk-quilt/gdb/stack.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/stack.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/stack.c 2012-04-23 14:12:58.145564425 +0100 @@ -2238,6 +2238,7 @@ return_command (char *retval_exp, int fr struct gdbarch *gdbarch; struct symbol *thisfun; struct value *return_value = NULL; + struct value *function = NULL; const char *query_prefix = ""; thisframe = get_selected_frame ("No selected frame."); @@ -2282,6 +2283,13 @@ return_command (char *retval_exp, int fr if (value_lazy (return_value)) value_fetch_lazy (return_value); + if (thisfun != NULL) + { + function = allocate_value (SYMBOL_TYPE (thisfun)); + set_value_address (function, + BLOCK_START (SYMBOL_BLOCK_VALUE (thisfun))); + } + if (TYPE_CODE (return_type) == TYPE_CODE_VOID) /* If the return-type is "void", don't try to find the return-value's location. However, do still evaluate the @@ -2290,8 +2298,7 @@ return_command (char *retval_exp, int fr occur. */ return_value = NULL; else if (thisfun != NULL - && using_struct_return (gdbarch, - SYMBOL_TYPE (thisfun), return_type)) + && using_struct_return (gdbarch, function, return_type)) { query_prefix = "The location at which to store the " "function's return value is unknown.\n" @@ -2326,12 +2333,11 @@ return_command (char *retval_exp, int fr { struct type *return_type = value_type (return_value); 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) == RETURN_VALUE_REGISTER_CONVENTION); - gdbarch_return_value (gdbarch, func_type, return_type, + gdbarch_return_value (gdbarch, function, return_type, get_current_regcache (), NULL /*read*/, value_contents (return_value) /*write*/); } Index: gdb-fsf-trunk-quilt/gdb/v850-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/v850-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/v850-tdep.c 2012-04-23 14:12:58.145564425 +0100 @@ -933,7 +933,7 @@ v850_store_return_value (struct type *ty } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/value.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/value.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/value.c 2012-04-23 14:12:58.145564425 +0100 @@ -3269,7 +3269,7 @@ coerce_array (struct value *arg) int 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); @@ -3282,7 +3282,7 @@ using_struct_return (struct gdbarch *gdb return 0; /* 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) != RETURN_VALUE_REGISTER_CONVENTION); } Index: gdb-fsf-trunk-quilt/gdb/value.h =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/value.h 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/value.h 2012-04-23 14:12:58.145564425 +0100 @@ -698,7 +698,7 @@ extern int value_bit_index (struct type int index); extern int using_struct_return (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *value_type); extern struct value *evaluate_expression (struct expression *exp); Index: gdb-fsf-trunk-quilt/gdb/vax-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/vax-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/vax-tdep.c 2012-04-23 14:12:58.145564425 +0100 @@ -204,7 +204,7 @@ vax_dummy_id (struct gdbarch *gdbarch, s 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/xstormy16-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/xstormy16-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/xstormy16-tdep.c 2012-04-23 14:12:58.145564425 +0100 @@ -197,7 +197,7 @@ xstormy16_store_return_value (struct typ } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/xtensa-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/xtensa-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/xtensa-tdep.c 2012-04-23 14:12:58.145564425 +0100 @@ -1682,7 +1682,7 @@ xtensa_store_return_value (struct type * static enum return_value_convention xtensa_return_value (struct gdbarch *gdbarch, - struct type *func_type, + struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, Index: gdb-fsf-trunk-quilt/gdb/elfread.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/elfread.c 2012-04-23 14:12:54.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/elfread.c 2012-04-23 14:12:58.145564425 +0100 @@ -1020,21 +1020,16 @@ elf_gnu_ifunc_resolver_return_stop (stru struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func; struct type *value_type = TYPE_TARGET_TYPE (func_func_type); struct regcache *regcache = get_thread_regcache (inferior_ptid); + struct value *func_func; struct value *value; CORE_ADDR resolved_address, resolved_pc; struct symtab_and_line sal; struct symtabs_and_lines sals, sals_end; + CORE_ADDR func_func_addr; + int is_gnu_ifunc; 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, - ¤t_target); - while (b->related_breakpoint != b) { struct breakpoint *b_next = b->related_breakpoint; @@ -1055,6 +1050,21 @@ elf_gnu_ifunc_resolver_return_stop (stru b = b_next; } gdb_assert (b->type == bp_gnu_ifunc_resolver); + gdb_assert (b->loc->next == NULL); + + find_pc_partial_function_gnu_ifunc (b->loc->address, NULL, + &func_func_addr, NULL, &is_gnu_ifunc); + gdb_assert (is_gnu_ifunc); + func_func = allocate_value (func_func_type); + set_value_address (func_func, func_func_addr); + + 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, + ¤t_target); gdb_assert (current_program_space == b->pspace || b->pspace == NULL); elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc); Index: gdb-fsf-trunk-quilt/gdb/inferior.h =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/inferior.h 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/inferior.h 2012-04-23 14:12:58.145564425 +0100 @@ -266,7 +266,7 @@ extern void detach_command (char *, 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); /* Address at which inferior stopped. */ Index: gdb-fsf-trunk-quilt/gdb/python/py-finishbreakpoint.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/python/py-finishbreakpoint.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/python/py-finishbreakpoint.c 2012-04-23 14:12:58.145564425 +0100 @@ -29,6 +29,7 @@ #include "language.h" #include "observer.h" #include "inferior.h" +#include "block.h" 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 was VOID. */ 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. */ - PyObject *function_type; + PyObject *function_value; /* When stopped at this FinishBreakpoint, gdb.Value object returned by the function; Py_None if the value is not computable; NULL if GDB is not stopped at a FinishBreakpoint. */ @@ -78,7 +79,7 @@ bpfinishpy_dealloc (PyObject *self) struct finish_breakpoint_object *self_bpfinish = (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_value); } @@ -102,9 +103,11 @@ bpfinishpy_pre_stop_hook (struct breakpo TRY_CATCH (except, RETURN_MASK_ALL) { - struct value *ret = - get_return_value (type_object_to_type (self_finishbp->function_type), - type_object_to_type (self_finishbp->return_type)); + struct value *function = + value_object_to_value (self_finishbp->function_value); + struct type *value_type = + type_object_to_type (self_finishbp->return_type); + struct value *ret = get_return_value (function, value_type); if (ret) { @@ -233,7 +236,7 @@ bpfinishpy_init (PyObject *self, PyObjec /* Find the function we will return from. */ self_bpfinish->return_type = NULL; - self_bpfinish->function_type = NULL; + self_bpfinish->function_value = NULL; TRY_CATCH (except, RETURN_MASK_ALL) { @@ -248,25 +251,31 @@ bpfinishpy_init (PyObject *self, PyObjec /* Remember only non-void return types. */ if (TYPE_CODE (ret_type) != TYPE_CODE_VOID) { + struct value *func_value; + CORE_ADDR func_addr; + /* Ignore Python errors at this stage. */ self_bpfinish->return_type = type_to_type_object (ret_type); PyErr_Clear (); - self_bpfinish->function_type = - type_to_type_object (SYMBOL_TYPE (function)); + func_value = allocate_value (SYMBOL_TYPE (function)); + func_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); + set_value_address (func_value, func_addr); + self_bpfinish->function_value = + value_to_value_object (func_value); PyErr_Clear (); } } } } 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. */ 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->function_type = NULL; + self_bpfinish->function_value = NULL; } bppy_pending_object = &self_bpfinish->py_bp; Index: gdb-fsf-trunk-quilt/gdb/testsuite/gdb.base/return-nodebug.exp =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/testsuite/gdb.base/return-nodebug.exp 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/testsuite/gdb.base/return-nodebug.exp 2012-04-23 14:12:58.165575931 +0100 @@ -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 typenospace [string map {{ } -} $type] Index: gdb-fsf-trunk-quilt/gdb/amd64-windows-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/amd64-windows-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/amd64-windows-tdep.c 2012-04-23 14:12:58.175573499 +0100 @@ -73,7 +73,7 @@ amd64_windows_classify (struct type *typ /* Implement the "return_value" gdbarch method for amd64-windows. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/avr-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/avr-tdep.c 2012-04-23 14:11:35.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/avr-tdep.c 2012-04-23 14:12:58.175573499 +0100 @@ -902,7 +902,7 @@ avr_breakpoint_from_pc (struct gdbarch * from WRITEBUF into REGCACHE. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/microblaze-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/microblaze-tdep.c 2012-04-23 14:12:25.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/microblaze-tdep.c 2012-04-23 14:09:21.505559981 +0100 @@ -612,7 +612,7 @@ microblaze_store_return_value (struct ty } 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, gdb_byte *readbuf, const gdb_byte *writebuf) { Index: gdb-fsf-trunk-quilt/gdb/tic6x-tdep.c =================================================================== --- gdb-fsf-trunk-quilt.orig/gdb/tic6x-tdep.c 2012-04-23 14:12:25.000000000 +0100 +++ gdb-fsf-trunk-quilt/gdb/tic6x-tdep.c 2012-04-23 14:10:21.975575691 +0100 @@ -821,7 +821,7 @@ tic6x_store_return_value (struct type *v /* This is the implementation of gdbarch method return_value. */ 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, gdb_byte *readbuf, const gdb_byte *writebuf) {