aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2012-07-25 18:27:21 +0000
committerJoel Brobecker <brobecker@gnat.com>2012-07-25 18:27:21 +0000
commit33d7655bb2b3cc12ac5401ae107a0aca33085d6e (patch)
treea45a8f48f08d796940de8a83d903bde13a7f1f12 /gdb/doublest.c
parentAdd support for --enable-lmcheck configure option. (diff)
downloadbinutils-gdb-33d7655bb2b3cc12ac5401ae107a0aca33085d6e.tar.gz
binutils-gdb-33d7655bb2b3cc12ac5401ae107a0aca33085d6e.tar.bz2
binutils-gdb-33d7655bb2b3cc12ac5401ae107a0aca33085d6e.zip
convert_doublest_to_floatformat: handle off-range values.
On x86_64-linux targetting AVR, we see the following issues: (gdb) print 1.6e+308 $1 = 0.89002949 (gdb) print 1.6e-308 $3 = 2.87630892 What happens is that GDB is trying to convert the value it read (as a host "long double") into a target "double" value. The routine performing the conversion does not realize that 1.6e+308 is just too large to fit in a double. Similarly, it does not notice that 1.6e-308 is too small to be represented. This patch enhances convert_doublest_to_floatformat to both handle floats that are too small and too large. gdb/ChangeLog: * doublest.c (convert_doublest_to_floatformat): If the exponent is too small, treat the value as zero. If the exponent is too large, treat the value as infinity.
Diffstat (limited to 'gdb/doublest.c')
-rw-r--r--gdb/doublest.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/gdb/doublest.c b/gdb/doublest.c
index c8c9e05932c..f683002020f 100644
--- a/gdb/doublest.c
+++ b/gdb/doublest.c
@@ -472,6 +472,28 @@ convert_doublest_to_floatformat (CONST struct floatformat *fmt,
mant = frexp (dfrom, &exponent);
#endif
+ if (exponent + fmt->exp_bias <= 0)
+ {
+ /* The value is too small to be expressed in the destination
+ type (not enough bits in the exponent. Treat as 0. */
+ put_field (uto, order, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, 0);
+ put_field (uto, order, fmt->totalsize, fmt->man_start,
+ fmt->man_len, 0);
+ goto finalize_byteorder;
+ }
+
+ if (exponent + fmt->exp_bias >= (1 << fmt->exp_len) - 1)
+ {
+ /* The value is too large to fit into the destination.
+ Treat as infinity. */
+ put_field (uto, order, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ put_field (uto, order, fmt->totalsize, fmt->man_start,
+ fmt->man_len, 0);
+ goto finalize_byteorder;
+ }
+
put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
exponent + fmt->exp_bias - 1);