diff options
author | Mark Kettenis <kettenis@gnu.org> | 2001-10-28 22:06:27 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2001-10-28 22:06:27 +0000 |
commit | a8758214487b8f790087cdff5d6c8fcec112a8bd (patch) | |
tree | 138e1e621a7cf545a3193ae63e236cba9131f618 | |
parent | ca27d03581324945418e823efd525f0097db342d (diff) | |
download | gdb-a8758214487b8f790087cdff5d6c8fcec112a8bd.tar.gz |
* doublest.c: Improve comments a bit.
(floatformat_from_length): New function.
(NAN): Define to 0.0 if not already defined.
(extract_floating): Rewrite to use floatformat_from_length. Warn
instead of error if LEN doesn't match a known floating-point type,
and return NaN (or 0.0 if NaN isn't available) in that case.
(store_floating): Likewise, but zero out the target byte-stream if
LEN doesn't match a known floating-point type.
(extract_typed_floating): Reformat a bit.
(store_typed_floating): Reformat a bit. Add comment about zeroing
out padding in the target buffer.
* doublest.h (extract_floating, store_floating): Fix comment about
deprecation of these functions. Add parameter names to prototypes.
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/doublest.c | 131 | ||||
-rw-r--r-- | gdb/doublest.h | 9 |
3 files changed, 104 insertions, 52 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index fad9d4a6a4b..67e27fe4f22 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2001-10-28 Mark Kettenis <kettenis@gnu.org> + * doublest.c: Improve comments a bit. + (floatformat_from_length): New function. + (NAN): Define to 0.0 if not already defined. + (extract_floating): Rewrite to use floatformat_from_length. Warn + instead of error if LEN doesn't match a known floating-point type, + and return NaN (or 0.0 if NaN isn't available) in that case. + (store_floating): Likewise, but zero out the target byte-stream if + LEN doesn't match a known floating-point type. + (extract_typed_floating): Reformat a bit. + (store_typed_floating): Reformat a bit. Add comment about zeroing + out padding in the target buffer. + * doublest.h (extract_floating, store_floating): Fix comment about + deprecation of these functions. Add parameter names to prototypes. + +2001-10-28 Mark Kettenis <kettenis@gnu.org> + * i387-tdep.c (print_i387_value): Use extract_typed_floating to convert RAW to a DOUBLEST instead of extract_floating. diff --git a/gdb/doublest.c b/gdb/doublest.c index e2dd3e896dc..2fbf3755cbb 100644 --- a/gdb/doublest.c +++ b/gdb/doublest.c @@ -532,7 +532,6 @@ floatformat_mantissa (const struct floatformat *fmt, char *val) return res; } - /* Convert TO/FROM target to the hosts DOUBLEST floating-point format. @@ -607,84 +606,118 @@ floatformat_from_doublest (const struct floatformat *fmt, } -/* Extract/store a target floating-point number from byte-stream at - ADDR to/from a DOUBLEST. The LEN is used to select between the - pre-defined target type FLOAT, DOUBLE or LONG_DOUBLE. These - functions are used when extract/store typed floating() find that - the ``struct type'' did not include a FLOATFORMAT (e.g. some symbol - table readers and XXX-language support modules). */ +/* Return a floating-point format for a floating-point variable of + length LEN. Return NULL, if no suitable floating-point format + could be found. -DOUBLEST -extract_floating (const void *addr, int len) + We need this functionality since information about the + floating-point format of a type is not always available to GDB; the + debug information typically only tells us the size of a + floating-point type. + + FIXME: kettenis/2001-10-28: In many places, particularly in + target-dependent code, the format of floating-point types is known, + but not passed on by GDB. This should be fixed. */ + +static const struct floatformat * +floatformat_from_length (int len) { - DOUBLEST dretval; if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT) - { - floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval); - } + return TARGET_FLOAT_FORMAT; else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT) - { - floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval); - } + return TARGET_DOUBLE_FORMAT; else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT) + return TARGET_LONG_DOUBLE_FORMAT; + + return NULL; +} + +/* If the host doesn't define NAN, use zero instead. */ +#ifndef NAN +#define NAN 0.0 +#endif + +/* Extract a floating-point number of length LEN from a target-order + byte-stream at ADDR. Returns the value as type DOUBLEST. */ + +DOUBLEST +extract_floating (const void *addr, int len) +{ + const struct floatformat *fmt = floatformat_from_length (len); + DOUBLEST val; + + if (fmt == NULL) { - floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval); - } - else - { - error ("Can't deal with a floating point number of %d bytes.", len); + warning ("Can't store a floating-point number of %d bytes.", len); + return NAN; } - return dretval; + + floatformat_to_doublest (fmt, addr, &val); + return val; } +/* Store VAL as a floating-point number of length LEN to a + target-order byte-stream at ADDR. */ + void store_floating (void *addr, int len, DOUBLEST val) { - if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT) - { - floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr); - } - else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT) - { - floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr); - } - else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT) - { - floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr); - } - else + const struct floatformat *fmt = floatformat_from_length (len); + + if (fmt == NULL) { - error ("Can't deal with a floating point number of %d bytes.", len); + warning ("Can't store a floating-point number of %d bytes.", len); + memset (addr, 0, len); } + + floatformat_from_doublest (fmt, &val, addr); } -/* Extract/store a floating-point number of format TYPE from a - target-ordered byte-stream at ADDR to/from an internal DOUBLEST - accroding to its TYPE_FORMAT(). When GDB reads in debug - information, it is sometimes only provided with the type name, its - length and the fact that it is a float (TYPE_FORMAT() is not set). - For such types, the old extract/store floating() functions are - used. */ +/* Extract a floating-point number of type TYPE from a target-order + byte-stream at ADDR. Returns the value as type DOUBLEST. */ DOUBLEST extract_typed_floating (const void *addr, const struct type *type) { DOUBLEST retval; + gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + if (TYPE_FLOATFORMAT (type) == NULL) - retval = extract_floating (addr, TYPE_LENGTH (type)); - else - floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval); + return extract_floating (addr, TYPE_LENGTH (type)); + + floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval); return retval; } +/* Store VAL as a floating-point number of type TYPE to a target-order + byte-stream at ADDR. */ + void store_typed_floating (void *addr, const struct type *type, DOUBLEST val) { gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + + /* FIXME: kettenis/2001-10-28: It is debatable whether we should + zero out any remaining bytes in the target buffer when TYPE is + longer than the actual underlying floating-point format. Perhaps + we should store a fixed bitpattern in those remaining bytes, + instead of zero, or perhaps we shouldn't touch those remaining + bytes at all. + + NOTE: cagney/2001-10-28: With the way things currently work, it + isn't a good idea to leave the end bits undefined. This is + because GDB writes out the entire sizeof(<floating>) bits of the + floating-point type even though the value might only be stored + in, and the target processor may only refer to, the first N < + TYPE_LENGTH (type) bits. If the end of the buffer wasn't + initialized, GDB would write undefined data to the target. An + errant program, refering to that undefined data, would then + become non-deterministic. */ memset (addr, 0, TYPE_LENGTH (type)); + if (TYPE_FLOATFORMAT (type) == NULL) - store_floating (addr, TYPE_LENGTH (type), val); - else - floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr); + return store_floating (addr, TYPE_LENGTH (type), val); + + floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr); } diff --git a/gdb/doublest.h b/gdb/doublest.h index d3955b37955..a31d8497fd1 100644 --- a/gdb/doublest.h +++ b/gdb/doublest.h @@ -61,9 +61,12 @@ extern int floatformat_is_negative (const struct floatformat *, char *); extern int floatformat_is_nan (const struct floatformat *, char *); extern char *floatformat_mantissa (const struct floatformat *, char *); -/* Use extract_typed_float() and store_typed_float(). */ -extern DOUBLEST extract_floating (const void *in, int); /* DEPRECATED */ -extern void store_floating (void *, int, DOUBLEST); /* DEPRECATED */ +/* These two functions are deprecated in favour of + extract_typed_floating and store_typed_floating. See comments in + 'doublest.c' for details. */ + +extern DOUBLEST extract_floating (const void *addr, int len); +extern void store_floating (void *addr, int len, DOUBLEST val); extern DOUBLEST extract_typed_floating (const void *addr, const struct type *type); |