/* Low level packing and unpacking of values for GDB, the GNU Debugger.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
+ 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_assert.h"
#include "regcache.h"
#include "block.h"
+#include "dfp.h"
+#include "objfiles.h"
/* Prototypes for exported functions. */
int bitsize;
/* Only used for bitfields; position of start of field. For
- BITS_BIG_ENDIAN=0 targets, it is the position of the LSB. For
- BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */
+ gdbarch_bits_big_endian=0 targets, it is the position of the LSB. For
+ gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */
int bitpos;
/* Frame register value is relative to. This will be described in
short regnum;
/* If zero, contents of this value are in the contents field. If
- nonzero, contents are in inferior memory at address in the
- location.address field plus the offset field (and the lval field
- should be lval_memory).
+ nonzero, contents are in inferior. If the lval field is lval_memory,
+ the contents are in inferior memory at location.address plus offset.
+ The lval field may also be lval_register.
WARNING: This field is used by the code which handles watchpoints
(see breakpoint.c) to decide whether a particular value can be
}
/* Allocate a value that has the correct length
- for COUNT repetitions type TYPE. */
+ for COUNT repetitions of type TYPE. */
struct value *
allocate_repeat_value (struct type *type, int count)
if (num_exp)
{
- /* "info history +" should print from the stored position.
- "info history <exp>" should print around value number <exp>. */
+ /* "show values +" should print from the stored position.
+ "show values <exp>" should print around value number <exp>. */
if (num_exp[0] != '+' || num_exp[1] != '\0')
num = parse_and_eval_long (num_exp) - 5;
}
else
{
- /* "info history" means print the last 10 values. */
+ /* "show values" means print the last 10 values. */
num = value_history_count - 9;
}
printf_filtered (("\n"));
}
- /* The next "info history +" should start after what we just printed. */
+ /* The next "show values +" should start after what we just printed. */
num += 10;
/* Hitting just return after this command should do the same thing as
- "info history +". If num_exp is null, this is unnecessary, since
- "info history +" is not useful after "info history". */
+ "show values +". If num_exp is null, this is unnecessary, since
+ "show values +" is not useful after "show values". */
if (from_tty && num_exp)
{
num_exp[0] = '+';
error (_("Invalid floating value found in program."));
return foo;
}
+
/* Extract a value as a C pointer. Does not deallocate the value.
Note that val's type may not actually be a pointer; value_as_long
handles all the cases. */
case TYPE_CODE_FLT:
return extract_typed_floating (valaddr, type);
+ case TYPE_CODE_DECFLOAT:
+ /* libdecnumber has a function to convert from decimal to integer, but
+ it doesn't work when the decimal number has a fractional part. */
+ return decimal_to_doublest (valaddr, len);
+
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
return extract_typed_floating (valaddr, type);
}
+ else if (code == TYPE_CODE_DECFLOAT)
+ return decimal_to_doublest (valaddr, len);
else if (nosign)
{
/* Unsigned -- be sure we compensate for signed LONGEST. */
else
{
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
- struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0, NULL);
+ struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
if (sym == NULL)
{
/* With some compilers, e.g. HP aCC, static data members are reported
bases, etc. */
v = allocate_value (value_enclosing_type (arg1));
v->type = type;
+
+ /* Lazy register values with offsets are not supported. */
+ if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
+ value_fetch_lazy (arg1);
+
if (value_lazy (arg1))
set_value_lazy (v, 1);
else
/* Plain old data member */
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
v = allocate_value (type);
+
+ /* Lazy register values with offsets are not supported. */
+ if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
+ value_fetch_lazy (arg1);
+
if (value_lazy (arg1))
set_value_lazy (v, 1);
else
struct symbol *sym;
struct minimal_symbol *msym;
- sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0, NULL);
+ sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0);
if (sym != NULL)
{
msym = NULL;
}
else
{
- VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
+ /* The minimal symbol might point to a function descriptor;
+ resolve it to the actual code address instead. */
+ struct objfile *objfile = msymbol_objfile (msym);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+ VALUE_ADDRESS (v)
+ = gdbarch_convert_from_func_ptr_addr
+ (gdbarch, SYMBOL_VALUE_ADDRESS (msym), ¤t_target);
}
if (arg1p)
/* Extract bits. See comment above. */
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (current_gdbarch))
lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
else
lsbcount = (bitpos % 8);
oword = extract_unsigned_integer (addr, sizeof oword);
/* Shifting for bit field depends on endianness of the target machine. */
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (current_gdbarch))
bitpos = sizeof (oword) * 8 - bitpos - bitsize;
oword &= ~(mask << bitpos);
return val;
}
+struct value *
+value_from_decfloat (struct type *type, const gdb_byte *dec)
+{
+ struct value *val = allocate_value (type);
+
+ memcpy (value_contents_raw (val), dec, TYPE_LENGTH (type));
+
+ return val;
+}
+
struct value *
coerce_ref (struct value *arg)
{
address as a hidden first parameter). */
int
-using_struct_return (struct type *value_type)
+using_struct_return (struct type *func_type, struct type *value_type)
{
enum type_code code = TYPE_CODE (value_type);
return 0;
/* Probe the architecture for the return-value convention. */
- return (gdbarch_return_value (current_gdbarch, value_type,
+ return (gdbarch_return_value (current_gdbarch, func_type, value_type,
NULL, NULL, NULL)
!= RETURN_VALUE_REGISTER_CONVENTION);
}