gdb/
authorMaciej W. Rozycki <macro@linux-mips.org>
Wed, 16 May 2012 14:35:09 +0000 (14:35 +0000)
committerMaciej W. Rozycki <macro@linux-mips.org>
Wed, 16 May 2012 14:35:09 +0000 (14:35 +0000)
* 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.

61 files changed:
gdb/ChangeLog
gdb/alpha-tdep.c
gdb/amd64-tdep.c
gdb/amd64-windows-tdep.c
gdb/arm-tdep.c
gdb/avr-tdep.c
gdb/bfin-tdep.c
gdb/breakpoint.c
gdb/breakpoint.h
gdb/cris-tdep.c
gdb/elfread.c
gdb/eval.c
gdb/frv-tdep.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/h8300-tdep.c
gdb/hppa-tdep.c
gdb/i386-tdep.c
gdb/ia64-tdep.c
gdb/infcall.c
gdb/infcmd.c
gdb/inferior.h
gdb/iq2000-tdep.c
gdb/lm32-tdep.c
gdb/m32c-tdep.c
gdb/m32r-tdep.c
gdb/m68hc11-tdep.c
gdb/m68k-tdep.c
gdb/m88k-tdep.c
gdb/mep-tdep.c
gdb/microblaze-tdep.c
gdb/mips-tdep.c
gdb/mn10300-tdep.c
gdb/moxie-tdep.c
gdb/mt-tdep.c
gdb/ppc-linux-tdep.c
gdb/ppc-sysv-tdep.c
gdb/ppc-tdep.h
gdb/ppcnbsd-tdep.c
gdb/python/py-finishbreakpoint.c
gdb/rl78-tdep.c
gdb/rs6000-aix-tdep.c
gdb/rx-tdep.c
gdb/s390-tdep.c
gdb/score-tdep.c
gdb/sh-tdep.c
gdb/sh64-tdep.c
gdb/sparc-tdep.c
gdb/sparc64-tdep.c
gdb/spu-tdep.c
gdb/stack.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/return-nodebug.exp
gdb/tic6x-tdep.c
gdb/v850-tdep.c
gdb/value.c
gdb/value.h
gdb/vax-tdep.c
gdb/xstormy16-tdep.c
gdb/xtensa-tdep.c

index d6af2ce7090c322ab52b5a03becdce5df18daf13..0a3557265610422f79a8b6e0c10db1981abc17bc 100644 (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>
 
        * python/python.c (gdbpy_find_pc_line): Use gdb_py_ulongest.
index 856aa0d17c6ba2266c87d623dc02f6226a6d6311..5d3affa86d1871094869c90755cdb5a5610ae7f1 100644 (file)
@@ -612,7 +612,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
 }
 
 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 35d849bfd3a97f52571121bb20c506206b4968e7..df91a519a858b7f5c88de496f067e5e08bc72df6 100644 (file)
@@ -594,7 +594,7 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2])
 }
 
 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 2b94eca9d9f45c76a690235835f2bada93172519..4a40f4799b0f5e2abf144595409fd328a5f34038 100644 (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.  */
 
 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 f83dc0e6c484dc44a313ccfa4bcd3a057165e0f7..7ebd8b701624193eb6ceab2c4d08e5ca7219c77d 100644 (file)
@@ -9011,11 +9011,12 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 /* 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 34b0bafc856fa43d8fc9c69fde37b115e585a841..6901fc906f8d486eb37fb8d097d61a704ea9ea1a 100644 (file)
@@ -902,7 +902,7 @@ avr_breakpoint_from_pc (struct gdbarch *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 a48758dd8e96aac3cdeadc305236adc57f4bf0ca..fb2ead05212ecdc8ab03e69a382e97221e8a9073 100644 (file)
@@ -663,7 +663,7 @@ bfin_store_return_value (struct type *type,
 
 static enum return_value_convention
 bfin_return_value (struct gdbarch *gdbarch,
-                  struct type *func_type,
+                  struct value *function,
                   struct type *type,
                   struct regcache *regcache,
                   gdb_byte *readbuf,
index 1a76754be51456da9fca3c5a1baed64c68d04b89..333c54fd022d612af08580190cb0607534b4507c 100644 (file)
@@ -6598,9 +6598,10 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
     {
       int is_gnu_ifunc;
       const char *function_name;
+      CORE_ADDR func_addr;
 
       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)
        {
@@ -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
                 mess more complicated breakpoints with multiple locations.  */
              b->type = bp_gnu_ifunc_resolver;
+             /* Remember the resolver's address for use by the return
+                breakpoint.  */
+             loc->related_address = func_addr;
            }
        }
 
index c81c0802120366e00837266328257829eb8712fa..a957b6f3cd5baaffc940b87027ff327209f9b1e7 100644 (file)
@@ -425,6 +425,11 @@ struct bp_location
      processor's architectual constraints.  */
   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
      with it.  */
   struct probe *probe;
index 34a25944239149ea4a1224a9f1487e44715bc142..91eefb479abcd008838fe06fc9a64dc972be9fb1 100644 (file)
@@ -1863,7 +1863,7 @@ cris_extract_return_value (struct type *type, struct regcache *regcache,
 /* 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 d8dec38b4b321cbde0aa13e46464db4226f52e6a..8e642472cf1d6afbda72ee7aafc178d30b76693c 100644 (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 *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;
@@ -1027,14 +1028,6 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
 
   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)
     {
       struct breakpoint *b_next = b->related_breakpoint;
@@ -1055,6 +1048,18 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
       b = b_next;
     }
   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);
   elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc);
index de1c4bdc713b9948595feda5aad02c0e7df34da5..dba174d3563ca59a5d6b11c8a53289e0a38a7f0c 100644 (file)
@@ -1358,8 +1358,7 @@ evaluate_subexp_standard (struct type *expect_type,
                  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 1f2400aec8557411f0dfcaaf1d656ce7df178ea5..9e884a473b339827ce723ec5dea74a70186ce30b 100644 (file)
@@ -1351,7 +1351,7 @@ frv_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 056dd5ab1ca12f0e0d299f19be32e37169ba48b1..af2033b7e5edc69a6fb27ea95174a9239eeb79e4 100644 (file)
@@ -2536,13 +2536,13 @@ gdbarch_return_value_p (struct gdbarch *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 2d832aaa603099f49732707b2830c5b67b119b7d..5bc4f4d8c118856dca729502cb2d136632d8b276 100644 (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 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
-   to return a value of type VALTYPE.  FUNCTYPE may be NULL in which
+/* Return the return-value convention that will be used by FUNCTION
+   to return a value of type VALTYPE.  FUNCTION may be NULL in which
    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.
@@ -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);
 
-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 956734abacbea0d10c6f6210a2895be78f7f78a5..3e3b126c2151e5b0cad4f89ef775cb2003a476cc 100755 (executable)
@@ -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: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
-# to return a value of type VALTYPE.  FUNCTYPE may be NULL in which
+# Return the return-value convention that will be used by FUNCTION
+# to return a value of type VALTYPE.  FUNCTION may be NULL in which
 # 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.
@@ -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
 # 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:function, 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 aa056f9548c8f56481d750ddc8ed41967515a951..7ec50b3513eaf60e4188a3d506d14c02b7161081 100644 (file)
@@ -901,7 +901,7 @@ h8300h_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 *gdbarch, struct type *func_type,
 }
 
 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 7f7fb8ed8ed55048649633ab3684143c70bc42d0..07b8015580771e940ee937f044e1247369e84fd9 100644 (file)
@@ -1114,7 +1114,7 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 /* 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 *gdbarch, struct type *func_type,
 }
 
 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 6858b5ab183224a691eb66acafbefe6c58c4bfdb..b3abba2f53b952fc0b770cb037fea80f4034d1d1 100644 (file)
@@ -2605,7 +2605,7 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
    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)
 {
@@ -2656,7 +2656,7 @@ i386_return_value (struct gdbarch *gdbarch, struct type *func_type,
   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 460345bc96a476c58a55d97df75f624ae5ba724b..27a4938d3420f391933a4cff8a931067f2e87ab4 100644 (file)
@@ -3340,7 +3340,7 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
 }
   
 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 fa498f60ee9cb29f5f099d3732c813a738fdbb3a..4ace08b7a7aa4ee1c8937e42bd7f8d04f2c98cf2 100644 (file)
@@ -608,8 +608,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
     }
   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;
     }
 
@@ -1021,13 +1020,13 @@ When the function is done executing, GDB will silently stop."),
       {
        /* 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 6a841e549acecc9530882427a83c85af96c65de7..1f7564aefb773875f3ccdc1930276d6d56899015 100644 (file)
@@ -75,7 +75,7 @@ void interrupt_target_command (char *args, int from_tty);
 
 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, struct type *value_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, struct type *value_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)
@@ -1548,13 +1548,15 @@ finish_command_continuation (void *arg, int err)
          if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
            {
              volatile struct gdb_exception ex;
+             struct value *func;
 
+             func = read_var_value (a->function, get_current_frame ());
              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 8c90f96d865e004712332b357827917eaf69ac83..24916f590858fa16c9459554151031f01196dba2 100644 (file)
@@ -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 dd8ad619bb9aa7ec93d87f39625122165f55b26f..6ecc671e593c00cf57b54e7baf269df8057cf425 100644 (file)
@@ -583,7 +583,7 @@ iq2000_extract_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 4f67542f9f4d073c8b813fa5eace815bb3fad569..09c2cc02f6abeda14356d14a5a6d66720fb8adb3 100644 (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.  */
 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 1211624e5ea82826b9b3486b0d6a8aadd35ae540..3957f8c9033206964ccb696f44fef8b9dabdaa06 100644 (file)
@@ -2206,7 +2206,7 @@ m32c_return_by_passed_buf (struct type *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 d504eb38359ddf748f00491c98b7c9053cbe8610..720e8b6a5d8a2a7f62268b0adb244d4108587bdc 100644 (file)
@@ -809,7 +809,7 @@ m32r_extract_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 1215de8d365bfd249aa49cd5a69b7a4315c6d574..79629ef897bfb22815a0032e9cb7b9555d01a557 100644 (file)
@@ -1323,7 +1323,7 @@ m68hc11_extract_return_value (struct type *type, struct regcache *regcache,
 }
 
 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,
                      gdb_byte *readbuf, const gdb_byte *writebuf)
 {
index ee72026e479c21ecde52c46ff9827fb8924781c1..90feaaf8dc65f70ec85d91659c37eebe8614ddcf 100644 (file)
@@ -403,7 +403,7 @@ m68k_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
    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 *gdbarch, struct type *func_type,
 }
 
 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 *gdbarch, struct type *func_type,
   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 1fda594e41b545b7e9a464a3952ea50d6f810bdc..c4c3266914d2c9b8af0dc95e3c1a374cfb993dea 100644 (file)
@@ -383,7 +383,7 @@ m88k_dummy_id (struct gdbarch *arch, struct frame_info *this_frame)
    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 fea14bf0f7c865ccf87e9b1c56b8df449b36ee7a..960500c167e58bcc0a1c76d7d083a7bea0992527 100644 (file)
@@ -2194,7 +2194,7 @@ Try using the 'return' command with no argument."));
 }
 
 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 3ce3d1cd6d87789942643d9cd17b21de2d89cafd..d3e2cae4a87b973771c0dc8ac7c453a5cd067e98 100644 (file)
@@ -612,7 +612,7 @@ microblaze_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 d68782ca6977035fbc73ef2d9948c262947fc901..28fec270b56c590d099a84660bf78adb1fcd8788 100644 (file)
@@ -3332,7 +3332,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 /* 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)
 {
@@ -3722,7 +3722,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 }
 
 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)
 {
@@ -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.  */
 
 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
          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))
@@ -3989,46 +4003,48 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        }
 
       /* 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));
@@ -4203,12 +4219,16 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 }
 
 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)
@@ -4216,54 +4236,110 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *func_type,
   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;
     }
@@ -4459,14 +4535,14 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        }
 
       /* 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))
@@ -4611,28 +4687,54 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 }
 
 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 116a03e7d071f573948ecd6b928b2325f4266c5f..33fa227c70eb317b9ceb243967e9c55271853b38 100644 (file)
@@ -233,7 +233,7 @@ mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type,
    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 1f5f33f2428bfc90d948f920fd5aad545aa74b30..3e08d6011026c06ccb094c19ca081172c05fde56 100644 (file)
@@ -341,7 +341,7 @@ moxie_extract_return_value (struct type *type, struct regcache *regcache,
 /* 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 268be867bd77a62d3e71dc6fd7ff541cc370095b..ee4b6eb5d4b6b78b927663022f76dba001000995 100644 (file)
@@ -335,7 +335,7 @@ mt_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
    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 3392e6799f063f7426c39890e8246adcfd591ed4..878d3f8fdd140f2b2fba5c8e38bda4454a243023 100644 (file)
@@ -241,7 +241,7 @@ ppc_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
    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)
 {  
@@ -251,7 +251,7 @@ ppc_linux_return_value (struct gdbarch *gdbarch, struct type *func_type,
           && 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 20598d0e028fee4404cb4da7c045e3553f217fdf..a4521abb265e699a532975aba8a9d2434f283dc4 100644 (file)
@@ -1041,23 +1041,25 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 }
 
 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 gdbarch *gdbarch,
    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 ce43e797c1b8267be5fd47428478fb762063e34a..7ab639d7e3f4cc7911ae31378510556f66cad14a 100644 (file)
@@ -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 (struct gdbarch *gdbarch,
                                          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 c94774addb3ceed6cf35e72406aae7ca3d75efc8..d18636f2e18269a3a864b32cf47584bb0e403a4a 100644 (file)
@@ -76,7 +76,7 @@ ppcnbsd_regset_from_core_section (struct gdbarch *gdbarch,
    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 *gdbarch, struct type *func_type,
     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);
 }
 \f
index 3d598d71c7aed3f43ff9c97420408cd4ac67f522..761ad327212c803877ace476762ab29d4f9e81f0 100644 (file)
@@ -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 breakpoint_object *bp_obj)
 
   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, PyObject *args, PyObject *kwargs)
 
   /* 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,28 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
               /* Remember only non-void return types.  */
               if (TYPE_CODE (ret_type) != TYPE_CODE_VOID)
                 {
+                  struct value *func_value;
+
                   /* 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 = read_var_value (function, frame);
+                  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 7a847692382db8b2b5d8198b256d9eb874f0b06e..d178a1fecfe073202f4a83e74d89387a2d293f2b 100644 (file)
@@ -934,7 +934,7 @@ rl78_register_sim_regno (struct gdbarch *gdbarch, int regnum)
 
 static enum return_value_convention
 rl78_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)
index 55313262094d594d79ea935d650d952d6aaece49..c99273e3c70cdd59c70fe759a98b3d682f20ebf9 100644 (file)
@@ -424,7 +424,7 @@ ran_out_of_registers_for_arguments:
 }
 
 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 95d9e3d9145b3021cd594cf0690b5592142ff777..8637c0c31b1a747c41fd9a731385609ac24a2429 100644 (file)
@@ -702,7 +702,7 @@ rx_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 /* Implement the "return_value" gdbarch method.  */
 static enum return_value_convention
 rx_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)
index 038a3ce8f699fe83eae20323bda0d4876b77f14a..f03c13ae292ebacd40eb1fb93624427096f88910 100644 (file)
@@ -2818,7 +2818,7 @@ s390_return_value_convention (struct gdbarch *gdbarch, struct type *type)
 }
 
 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 90ef610bb7ee6bd6012bdf2a71f1efe4b85a7424..daaa51820628be13ac0a021ec46e697ba991593c 100644 (file)
@@ -450,7 +450,7 @@ score_xfer_register (struct regcache *regcache, int regnum, int length,
 }
 
 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 7f1519158a55ca2bc63a32cb71cb4cc15ee2f85a..ec1151b5e62480558a53117d36a0ca9d2645b05b 100644 (file)
@@ -1398,10 +1398,12 @@ sh_store_return_value_fpu (struct type *type, struct regcache *regcache,
 }
 
 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 *gdbarch, struct type *func_type,
 }
 
 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 2e5d8bdb5ee968bf4ca1703e1a6d0d52dd6840c5..66b57e336252551b54dc6426794e901b0a910c01 100644 (file)
@@ -1328,7 +1328,7 @@ sh64_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 00bca01b915b10c230b1e0756c441dd65a7d111a..f185d41bcf800de73cd64123e048d7cd4f8444ba 100644 (file)
@@ -1354,7 +1354,7 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 f30022ecf9011df9822346a32108b94f90541c14..28c9ca4fec8b057b22c21aee9a21122e8d3b9188 100644 (file)
@@ -1119,7 +1119,7 @@ sparc64_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 efc6e1672bf3a64abfff743b83aea2ec90ae7f71..9bc9522c036845c2adde88f09b94c88744e797d5 100644 (file)
@@ -1450,10 +1450,11 @@ spu_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 /* 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 2c2797e81b420d6b5a670af89c7cadd6a425bf9f..3c983ff8fbaf1dcd037477e29808507e17841f7d 100644 (file)
@@ -2238,6 +2238,7 @@ return_command (char *retval_exp, int from_tty)
   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,9 @@ return_command (char *retval_exp, int from_tty)
       if (value_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 the return-type is "void", don't try to find the
            return-value's location.  However, do still evaluate the
@@ -2290,8 +2294,7 @@ return_command (char *retval_exp, int from_tty)
            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 +2329,11 @@ return_command (char *retval_exp, int from_tty)
     {
       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 076d751e4a65fda7b0fbf209e63e9f695209894b..52f44a916bd6d711dc0b105044325ae765b8d639 100644 (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>
 
        PR testsuite/12649
index aa9389f10cdef181c134dcabe6f96e828338e5a3..1802862c3b46a117256190a4a2fc4477b5324300 100644 (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 typenospace [string map {{ } -} $type]
 
index 2dce8da072394004afe0a09cbcafaacb738dac0e..ca959475f53ee4fa2a4335e4f3597a47e4d7ddfd 100644 (file)
@@ -821,7 +821,7 @@ tic6x_store_return_value (struct type *valtype, struct regcache *regcache,
 /* 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)
 {
index 240a15435d94d64eb2330ede233f2cd5631ea634..c0d2281c71691dfd51908dfea606231725913b2b 100644 (file)
@@ -933,7 +933,7 @@ v850_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 d49828913f90ccf85b09a1cb90d89731a950f91d..c5b50c2ec59b8a8717b010a8958ed6a6634d243c 100644 (file)
@@ -3303,7 +3303,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);
 
@@ -3316,7 +3316,7 @@ using_struct_return (struct gdbarch *gdbarch,
     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 76c8e85d43b94e15e07d58c0af7711c3454d01e6..055b69eb203f3b1c0f47eca409b9c3d4b0c9447d 100644 (file)
@@ -698,7 +698,7 @@ extern int value_bit_index (struct type *type, const gdb_byte *addr,
                            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 0dcca75d241ae332337feca43b853a9b63b54523..550b56b37881b38d300707a441d9dd5c79a1555b 100644 (file)
@@ -204,7 +204,7 @@ vax_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 \f
 
 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 cfef755a9f8d30ae2368c335c4ef75f9613ee973..47fc86b22597c0bfbf2c84f1597539c47344faff 100644 (file)
@@ -197,7 +197,7 @@ xstormy16_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 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 78d888806ff023a9db67b4a21d704633d773b5b5..13397f249c9a566519526aaa9f665aa4b34a6ee2 100644 (file)
@@ -1682,7 +1682,7 @@ xtensa_store_return_value (struct type *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,