diff options
author | Pedro Alves <palves@redhat.com> | 2016-03-09 01:50:02 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2016-03-09 01:50:02 +0000 |
commit | aacca8a7a9c7f93955fa9dbf796b030ffce1b956 (patch) | |
tree | efe307f1ec60eabc47d31eafcbe9b924a3267b4c | |
parent | e9dba9f6c07cb60f29572ede55278b91fd6d6d7a (diff) | |
download | fsf-binutils-gdb-aacca8a7a9c7f93955fa9dbf796b030ffce1b956.zip fsf-binutils-gdb-aacca8a7a9c7f93955fa9dbf796b030ffce1b956.tar.gz fsf-binutils-gdb-aacca8a7a9c7f93955fa9dbf796b030ffce1b956.tar.bz2 |
Fix HP/PA GNU/Linux "long double" format
This:
$ ./gdb -ex "set architecture hppa1.0" -ex "set osabi GNU/Linux" -ex "ptype 1.0L"
Shows that HPPA/Linux support for long doubles is broken. It causes
GDB to access memory out of bounds. With Valgrind, we see:
The target architecture is assumed to be hppa1.0
==4371== Invalid write of size 8
==4371== at 0x4C2F21F: memset (vg_replace_strmem.c:1224)
==4371== by 0x8451C4: convert_doublest_to_floatformat (doublest.c:362)
==4371== by 0x845F86: floatformat_from_doublest (doublest.c:769)
==4371== by 0x84628E: store_typed_floating (doublest.c:873)
==4371== by 0x6A7C3D: value_from_double (value.c:3662)
==4371== by 0x6AA211: evaluate_subexp_standard (eval.c:745)
==4371== by 0x7F306D: evaluate_subexp_c (c-lang.c:716)
==4371== by 0x6A8C6A: evaluate_subexp (eval.c:79)
==4371== by 0x6A8E87: evaluate_type (eval.c:174)
==4371== by 0x817B8D: whatis_exp (typeprint.c:456)
==4371== by 0x817D68: ptype_command (typeprint.c:508)
==4371== by 0x5F2977: do_cfunc (cli-decode.c:105)
==4371== Address 0x8998d18 is 0 bytes after a block of size 8 alloc'd
==4371== at 0x4C2AA98: calloc (vg_replace_malloc.c:711)
==4371== by 0x8732B6: xcalloc (common-utils.c:83)
==4371== by 0x8732F5: xzalloc (common-utils.c:93)
==4371== by 0x6A37AF: allocate_value_contents (value.c:1036)
==4371== by 0x6A37E5: allocate_value (value.c:1047)
==4371== by 0x6A7BEE: value_from_double (value.c:3656)
==4371== by 0x6AA211: evaluate_subexp_standard (eval.c:745)
==4371== by 0x7F306D: evaluate_subexp_c (c-lang.c:716)
==4371== by 0x6A8C6A: evaluate_subexp (eval.c:79)
==4371== by 0x6A8E87: evaluate_type (eval.c:174)
==4371== by 0x817B8D: whatis_exp (typeprint.c:456)
==4371== by 0x817D68: ptype_command (typeprint.c:508)
The trouble is that hppa_linux_init_abi overrides the default
long_double_bit set by the generic hppa-tdep.c:
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
with:
/* On hppa-linux, currently, sizeof(long double) == 8. There has been
some discussions to support 128-bit long double, but it requires some
more work in gcc and glibc first. */
set_gdbarch_long_double_bit (gdbarch, 64);
which misses overriding the long_double_format, so we end with a weird
combination of:
set_gdbarch_long_double_bit (gdbarch, 64);
set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
Weird because floatformats_ia64_quad's totalsize is longer than 64-bits.
The floatformat conversion routines use the struct floatformat's
totalsize (in bits) to know how much to copy/convert, thus the buffer
overruns.
gdb/ChangeLog:
2016-03-09 Pedro Alves <palves@redhat.com>
* hppa-linux-tdep.c (hppa_linux_init_abi): Set the long double
format to floatformats_ieee_double.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/hppa-linux-tdep.c | 1 |
2 files changed, 6 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3f020ff..7303c32 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2016-03-09 Pedro Alves <palves@redhat.com> + + * hppa-linux-tdep.c (hppa_linux_init_abi): Set the long double + format to floatformats_ieee_double. + 2016-03-07 Pedro Alves <palves@redhat.com> * mips-tdep.c (mips_gdbarch_init): Check whether info.abfd is NULL diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c index 4013dfd..86b8d14 100644 --- a/gdb/hppa-linux-tdep.c +++ b/gdb/hppa-linux-tdep.c @@ -518,6 +518,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) some discussions to support 128-bit long double, but it requires some more work in gcc and glibc first. */ set_gdbarch_long_double_bit (gdbarch, 64); + set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); set_gdbarch_iterate_over_regset_sections (gdbarch, hppa_linux_iterate_over_regset_sections); |