aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2013-05-13 10:27:35 +0000
committerJoel Brobecker <brobecker@gnat.com>2013-05-13 10:27:35 +0000
commit36d1c68c70a09d38d76faa82263d16269139033c (patch)
treec49ae87ce7a151cf9e1ffaa7e04fc94ce73995cb
parent8414efeff8a66b8471e7a372fafffb9624cb499f (diff)
downloadgdb-36d1c68c70a09d38d76faa82263d16269139033c.zip
gdb-36d1c68c70a09d38d76faa82263d16269139033c.tar.gz
gdb-36d1c68c70a09d38d76faa82263d16269139033c.tar.bz2
Float parameter passing in funcall on ppc-aix & ppc-lynx178.
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. 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.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/rs6000-aix-tdep.c15
-rw-r--r--gdb/rs6000-lynx178-tdep.c14
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;
}