/* Find a variable's value in memory, for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "symtab.h"
#include "inferior.h"
#include "target.h"
#include "gdb_string.h"
+#include "floatformat.h"
+
+/* This is used to indicate that we don't know the format of the floating point
+ number. Typically, this is useful for native ports, where the actual format
+ is irrelevant, since no conversions will be taking place. */
+
+const struct floatformat floatformat_unknown;
/* Registers we shouldn't try to store. */
#if !defined (CANNOT_STORE_REGISTER)
unsigned char *startaddr = (unsigned char *)addr;
unsigned char *endaddr = startaddr + len;
- if (len > sizeof (LONGEST))
+ if (len > (int) sizeof (LONGEST))
error ("\
That operation is not available on integers of more than %d bytes.",
sizeof (LONGEST));
unsigned char *startaddr = (unsigned char *)addr;
unsigned char *endaddr = startaddr + len;
- if (len > sizeof (unsigned LONGEST))
+ if (len > (int) sizeof (unsigned LONGEST))
error ("\
That operation is not available on integers of more than %d bytes.",
sizeof (unsigned LONGEST));
return retval;
}
+/* Sometimes a long long unsigned integer can be extracted as a
+ LONGEST value. This is done so that we can print these values
+ better. If this integer can be converted to a LONGEST, this
+ function returns 1 and sets *PVAL. Otherwise it returns 0. */
+
+int
+extract_long_unsigned_integer (addr, orig_len, pval)
+ PTR addr;
+ int orig_len;
+ LONGEST *pval;
+{
+ char *p, *first_addr;
+ int len;
+
+ len = orig_len;
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ {
+ for (p = (char *) addr;
+ len > (int) sizeof (LONGEST) && p < (char *) addr + orig_len;
+ p++)
+ {
+ if (*p == 0)
+ len--;
+ else
+ break;
+ }
+ first_addr = p;
+ }
+ else
+ {
+ first_addr = (char *) addr;
+ for (p = (char *) addr + orig_len - 1;
+ len > (int) sizeof (LONGEST) && p >= (char *) addr;
+ p--)
+ {
+ if (*p == 0)
+ len--;
+ else
+ break;
+ }
+ }
+
+ if (len <= (int) sizeof (LONGEST))
+ {
+ *pval = (LONGEST) extract_unsigned_integer (first_addr,
+ sizeof (LONGEST));
+ return 1;
+ }
+
+ return 0;
+}
+
CORE_ADDR
extract_address (addr, len)
PTR addr;
3. We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever
we want to call it which is long double where available. */
-double
+DOUBLEST
extract_floating (addr, len)
PTR addr;
int len;
{
+ DOUBLEST dretval;
+
if (len == sizeof (float))
{
- float retval;
- memcpy (&retval, addr, sizeof (retval));
- SWAP_FLOATING (&retval, sizeof (retval));
- return retval;
+ if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
+ {
+ float retval;
+
+ memcpy (&retval, addr, sizeof (retval));
+ return retval;
+ }
+ else
+ FLOATFORMAT_TO_DOUBLEST (TARGET_FLOAT_FORMAT, addr, &dretval);
}
else if (len == sizeof (double))
{
- double retval;
- memcpy (&retval, addr, sizeof (retval));
- SWAP_FLOATING (&retval, sizeof (retval));
- return retval;
+ if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
+ {
+ double retval;
+
+ memcpy (&retval, addr, sizeof (retval));
+ return retval;
+ }
+ else
+ FLOATFORMAT_TO_DOUBLEST (TARGET_DOUBLE_FORMAT, addr, &dretval);
+ }
+ else if (len == sizeof (DOUBLEST))
+ {
+ if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
+ {
+ DOUBLEST retval;
+
+ memcpy (&retval, addr, sizeof (retval));
+ return retval;
+ }
+ else
+ FLOATFORMAT_TO_DOUBLEST (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
+
+ return dretval;
}
void
store_floating (addr, len, val)
PTR addr;
int len;
- double val;
+ DOUBLEST val;
{
if (len == sizeof (float))
{
- float floatval = val;
- SWAP_FLOATING (&floatval, sizeof (floatval));
- memcpy (addr, &floatval, sizeof (floatval));
+ if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
+ {
+ float floatval = val;
+
+ memcpy (addr, &floatval, sizeof (floatval));
+ }
+ else
+ FLOATFORMAT_FROM_DOUBLEST (TARGET_FLOAT_FORMAT, &val, addr);
}
else if (len == sizeof (double))
{
- SWAP_FLOATING (&val, sizeof (val));
- memcpy (addr, &val, sizeof (val));
+ if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
+ {
+ double doubleval = val;
+
+ memcpy (addr, &doubleval, sizeof (doubleval));
+ }
+ else
+ FLOATFORMAT_FROM_DOUBLEST (TARGET_DOUBLE_FORMAT, &val, addr);
+ }
+ else if (len == sizeof (DOUBLEST))
+ {
+ if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
+ memcpy (addr, &val, sizeof (val));
+ else
+ FLOATFORMAT_FROM_DOUBLEST (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
}
else
{
case LOC_BLOCK:
case LOC_CONST_BYTES:
+ case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT:
return 0;
}
}
break;
+ case LOC_UNRESOLVED:
+ {
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+ if (msym == NULL)
+ return 0;
+ addr = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ break;
+
case LOC_OPTIMIZED_OUT:
VALUE_LVAL (v) = not_lval;
VALUE_OPTIMIZED_OUT (v) = 1;
CORE_ADDR addr;
int optim;
value_ptr v = allocate_value (type);
- int len = TYPE_LENGTH (type);
char *value_bytes = 0;
int value_bytes_copied = 0;
int num_storage_locs;
enum lval_type lval;
+ int len;
+
+ CHECK_TYPEDEF (type);
+ len = TYPE_LENGTH (type);
VALUE_REGNO (v) = regnum;