This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Float parameter passing in funcall on ppc-aix & ppc-lynx178.


Hello,

Given the following code:

    float global_float = 0.0;

    void
    set_float (float f)
    {
      global_float = f;
    }

GDB incorrectly calls set_float if the set_float function is marked
as prototyped:

    (gdb) call set_float (5.0)
    (gdb) print global_float
    $1 = 2048

What happens, when the function is marked as prototyped, is that
GDB finds that the argument is a float, casts the value given in
the expression to a float, and then gives that float to ppc-aix/
ppc-lynx178's push_dummy_call gdbarch routine. The latter then blindly
copies it as is in the first floating-point register, instead of
making sure that it has the proper format first.

This patch fixes the problem by following the same approach as
the one used in ppc_sysv_abi_push_dummy_call, converting the FP
value to the register type before copying its contents.

This requires, but is otherwise indenpendent of:
http://www.sourceware.org/ml/gdb-patches/2013-05/msg00427.html

gdb/ChangeLog:

        * rs6000-aix-tdep.c (rs6000_push_dummy_call): Convert
        floating point registers to register type before storing
        value.
        * rs6000-lynx178-tdep.c (rs6000_lynx178_push_dummy_call):
        Likewise.

Tested on ppc-aix and ppc-lynx178.  Checked in.

---
 gdb/ChangeLog             |    8 ++++++++
 gdb/rs6000-aix-tdep.c     |   15 ++++++++++-----
 gdb/rs6000-lynx178-tdep.c |   14 ++++++++++----
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 84159e1..e3c2c4b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2013-05-13  Joel Brobecker  <brobecker@adacore.com>
+
+	* rs6000-aix-tdep.c (rs6000_push_dummy_call): Convert
+	floating point registers to register type before storing
+	value.
+	* rs6000-lynx178-tdep.c (rs6000_lynx178_push_dummy_call):
+	Likewise.
+
 2013-05-10  Joel Brobecker  <brobecker@adacore.com>
 	    Tom Tromey  <tromey@redhat.com>
 
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index 0992213..0d4fec5 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -254,16 +254,21 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
       if (TYPE_CODE (type) == TYPE_CODE_FLT)
 	{
-
 	  /* Floating point arguments are passed in fpr's, as well as gpr's.
 	     There are 13 fpr's reserved for passing parameters.  At this point
-	     there is no way we would run out of them.  */
+	     there is no way we would run out of them.
+
+	     Always store the floating point value using the register's
+	     floating-point format.  */
+	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
+	  gdb_byte reg_val[MAX_REGISTER_SIZE];
+	  struct type *reg_type = register_type (gdbarch, fp_regnum);
 
 	  gdb_assert (len <= 8);
 
-	  regcache_cooked_write (regcache,
-	                         tdep->ppc_fp0_regnum + 1 + f_argno,
-	                         value_contents (arg));
+	  convert_typed_floating (value_contents (arg), type,
+				  reg_val, reg_type);
+	  regcache_cooked_write (regcache, fp_regnum, reg_val);
 	  ++f_argno;
 	}
 
diff --git a/gdb/rs6000-lynx178-tdep.c b/gdb/rs6000-lynx178-tdep.c
index 90730ab..47fcc62 100644
--- a/gdb/rs6000-lynx178-tdep.c
+++ b/gdb/rs6000-lynx178-tdep.c
@@ -100,13 +100,19 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
 
 	  /* Floating point arguments are passed in fpr's, as well as gpr's.
 	     There are 13 fpr's reserved for passing parameters.  At this point
-	     there is no way we would run out of them.  */
+	     there is no way we would run out of them.
+
+	     Always store the floating point value using the register's
+	     floating-point format.  */
+	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
+	  gdb_byte reg_val[MAX_REGISTER_SIZE];
+	  struct type *reg_type = register_type (gdbarch, fp_regnum);
 
 	  gdb_assert (len <= 8);
 
-	  regcache_cooked_write (regcache,
-	                         tdep->ppc_fp0_regnum + 1 + f_argno,
-	                         value_contents (arg));
+	  convert_typed_floating (value_contents (arg), type,
+				  reg_val, reg_type);
+	  regcache_cooked_write (regcache, fp_regnum, reg_val);
 	  ++f_argno;
 	}
 
-- 
1.7.10.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]