From b79497cb1cdc9b3053e5f0387bf3056c08c9bbdd Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 9 Mar 2016 02:29:39 +0000 Subject: Assert that a floating type's length is at least as long as its format This would have caught the HP/PA bug fixed in the previous patch: .../src/gdb/gdbtypes.c:4690: internal-error: arch_float_type: Assertion `len >= floatformat_totalsize_bytes (floatformats[0])' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) Tested on x86-64 Fedora 23, --enable-targets=all. gdb/ChangeLog: 2016-03-09 Pedro Alves * doublest.c (floatformat_totalsize_bytes): New function. (floatformat_from_type): Assert that the type's length is at least as long as the floatformat's totalsize. * doublest.h (floatformat_totalsize_bytes): New declaration. * gdbtypes.c (arch_float_type): Assert that the type's length is at least as long as the floatformat's totalsize. --- gdb/ChangeLog | 9 +++++++++ gdb/doublest.c | 17 +++++++++++++++-- gdb/doublest.h | 4 ++++ gdb/gdbtypes.c | 9 +++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7303c32..abb224d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2016-03-09 Pedro Alves + * doublest.c (floatformat_totalsize_bytes): New function. + (floatformat_from_type): Assert that the type's length is at least + as long as the floatformat's totalsize. + * doublest.h (floatformat_totalsize_bytes): New declaration. + * gdbtypes.c (arch_float_type): Assert that the type's length is + at least as long as the floatformat's totalsize. + +2016-03-09 Pedro Alves + * hppa-linux-tdep.c (hppa_linux_init_abi): Set the long double format to floatformats_ieee_double. diff --git a/gdb/doublest.c b/gdb/doublest.c index 026cf42..fe06fec 100644 --- a/gdb/doublest.c +++ b/gdb/doublest.c @@ -693,6 +693,15 @@ static const struct floatformat *host_double_format = GDB_HOST_DOUBLE_FORMAT; static const struct floatformat *host_long_double_format = GDB_HOST_LONG_DOUBLE_FORMAT; +/* See doublest.h. */ + +size_t +floatformat_totalsize_bytes (const struct floatformat *fmt) +{ + return ((fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1) + / FLOATFORMAT_CHAR_BIT); +} + void floatformat_to_doublest (const struct floatformat *fmt, const void *in, DOUBLEST *out) @@ -802,12 +811,16 @@ const struct floatformat * floatformat_from_type (const struct type *type) { struct gdbarch *gdbarch = get_type_arch (type); + const struct floatformat *fmt; gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); if (TYPE_FLOATFORMAT (type) != NULL) - return TYPE_FLOATFORMAT (type)[gdbarch_byte_order (gdbarch)]; + fmt = TYPE_FLOATFORMAT (type)[gdbarch_byte_order (gdbarch)]; else - return floatformat_from_length (gdbarch, TYPE_LENGTH (type)); + fmt = floatformat_from_length (gdbarch, TYPE_LENGTH (type)); + + gdb_assert (TYPE_LENGTH (type) >= floatformat_totalsize_bytes (fmt)); + return fmt; } /* Extract a floating-point number of type TYPE from a target-order diff --git a/gdb/doublest.h b/gdb/doublest.h index ae42bdb..9522829 100644 --- a/gdb/doublest.h +++ b/gdb/doublest.h @@ -89,6 +89,10 @@ extern const char *floatformat_mantissa (const struct floatformat *, const struct floatformat *floatformat_from_type (const struct type *type); +/* Return the floatformat's total size in host bytes. */ + +extern size_t floatformat_totalsize_bytes (const struct floatformat *fmt); + extern DOUBLEST extract_typed_floating (const void *addr, const struct type *type); extern void store_typed_floating (void *addr, const struct type *type, diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index f129b0e..1af6fff 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -4682,6 +4682,15 @@ arch_float_type (struct gdbarch *gdbarch, t = arch_type (gdbarch, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name); TYPE_FLOATFORMAT (t) = floatformats; + + if (floatformats != NULL) + { + size_t len = TYPE_LENGTH (t); + + gdb_assert (len >= floatformat_totalsize_bytes (floatformats[0])); + gdb_assert (len >= floatformat_totalsize_bytes (floatformats[1])); + } + return t; } -- cgit v1.1