diff options
author | Joel Brobecker <brobecker@gnat.com> | 2013-05-13 10:27:35 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2013-05-13 10:27:35 +0000 |
commit | a9fd162da6d20785d86daf2963c175d7b31b1502 (patch) | |
tree | 4fb948609aab5b4b6c1969d870b04c13aeb369be /gdb/rs6000-lynx178-tdep.c | |
parent | 81160eb832e138cbbbaefcb1a618b833e0cba067 (diff) | |
download | gdb-a9fd162da6d20785d86daf2963c175d7b31b1502.tar.gz |
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.
Diffstat (limited to 'gdb/rs6000-lynx178-tdep.c')
-rw-r--r-- | gdb/rs6000-lynx178-tdep.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/gdb/rs6000-lynx178-tdep.c b/gdb/rs6000-lynx178-tdep.c index 90730ab837c..47fcc62637f 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; } |