mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-06 07:33:08 +00:00
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.
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user