/* Low level packing and unpacking of values for GDB, the GNU Debugger.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003 Free Software
- Foundation, Inc.
+ 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005 Free
+ Software Foundation, Inc.
This file is part of GDB.
struct value *val;
struct type *atype = check_typedef (type);
- val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (atype));
- VALUE_NEXT (val) = all_values;
+ val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
+ val->next = all_values;
all_values = val;
- VALUE_TYPE (val) = type;
- VALUE_ENCLOSING_TYPE (val) = type;
+ val->type = type;
+ val->enclosing_type = type;
VALUE_LVAL (val) = not_lval;
VALUE_ADDRESS (val) = 0;
VALUE_FRAME_ID (val) = null_frame_id;
- VALUE_OFFSET (val) = 0;
- VALUE_BITPOS (val) = 0;
- VALUE_BITSIZE (val) = 0;
- VALUE_REGNO (val) = -1;
- VALUE_LAZY (val) = 0;
- VALUE_OPTIMIZED_OUT (val) = 0;
+ val->offset = 0;
+ val->bitpos = 0;
+ val->bitsize = 0;
+ VALUE_REGNUM (val) = -1;
+ val->lazy = 0;
+ val->optimized_out = 0;
VALUE_EMBEDDED_OFFSET (val) = 0;
VALUE_POINTED_TO_OFFSET (val) = 0;
val->modifiable = 1;
type, range_type));
}
+/* Accessor methods. */
+
+struct type *
+value_type (struct value *value)
+{
+ return value->type;
+}
+
+int
+value_offset (struct value *value)
+{
+ return value->offset;
+}
+
+int
+value_bitpos (struct value *value)
+{
+ return value->bitpos;
+}
+
+int
+value_bitsize (struct value *value)
+{
+ return value->bitsize;
+}
+
+bfd_byte *
+value_contents_raw (struct value *value)
+{
+ return value->aligner.contents + value->embedded_offset;
+}
+
+bfd_byte *
+value_contents_all_raw (struct value *value)
+{
+ return value->aligner.contents;
+}
+
+struct type *
+value_enclosing_type (struct value *value)
+{
+ return value->enclosing_type;
+}
+
+const bfd_byte *
+value_contents_all (struct value *value)
+{
+ if (value->lazy)
+ value_fetch_lazy (value);
+ return value->aligner.contents;
+}
+
+int
+value_lazy (struct value *value)
+{
+ return value->lazy;
+}
+
+void
+set_value_lazy (struct value *value, int val)
+{
+ value->lazy = val;
+}
+
+const bfd_byte *
+value_contents (struct value *value)
+{
+ return value_contents_writeable (value);
+}
+
+bfd_byte *
+value_contents_writeable (struct value *value)
+{
+ if (value->lazy)
+ value_fetch_lazy (value);
+ return value->aligner.contents;
+}
+
+int
+value_optimized_out (struct value *value)
+{
+ return value->optimized_out;
+}
+
+void
+set_value_optimized_out (struct value *value, int val)
+{
+ value->optimized_out = val;
+}
+\f
/* Return a mark in the value chain. All values allocated after the
mark is obtained (except for those released) are subject to being freed
if a subsequent value_free_to_mark is passed the mark. */
for (val = all_values; val && val != mark; val = next)
{
- next = VALUE_NEXT (val);
+ next = val->next;
value_free (val);
}
all_values = val;
for (val = all_values; val; val = next)
{
- next = VALUE_NEXT (val);
+ next = val->next;
value_free (val);
}
struct value *val;
struct value *next;
- for (val = next = all_values; next; next = VALUE_NEXT (next))
- if (VALUE_NEXT (next) == mark)
+ for (val = next = all_values; next; next = next->next)
+ if (next->next == mark)
{
- all_values = VALUE_NEXT (next);
- VALUE_NEXT (next) = 0;
+ all_values = next->next;
+ next->next = NULL;
return val;
}
all_values = 0;
struct value *
value_copy (struct value *arg)
{
- struct type *encl_type = VALUE_ENCLOSING_TYPE (arg);
+ struct type *encl_type = value_enclosing_type (arg);
struct value *val = allocate_value (encl_type);
- VALUE_TYPE (val) = VALUE_TYPE (arg);
+ val->type = arg->type;
VALUE_LVAL (val) = VALUE_LVAL (arg);
VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
- VALUE_OFFSET (val) = VALUE_OFFSET (arg);
- VALUE_BITPOS (val) = VALUE_BITPOS (arg);
- VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
+ val->offset = arg->offset;
+ val->bitpos = arg->bitpos;
+ val->bitsize = arg->bitsize;
VALUE_FRAME_ID (val) = VALUE_FRAME_ID (arg);
- VALUE_REGNO (val) = VALUE_REGNO (arg);
- VALUE_LAZY (val) = VALUE_LAZY (arg);
- VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg);
+ VALUE_REGNUM (val) = VALUE_REGNUM (arg);
+ val->lazy = arg->lazy;
+ val->optimized_out = arg->optimized_out;
VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (arg);
VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (arg);
val->modifiable = arg->modifiable;
- if (!VALUE_LAZY (val))
+ if (!value_lazy (val))
{
- memcpy (VALUE_CONTENTS_ALL_RAW (val), VALUE_CONTENTS_ALL_RAW (arg),
- TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg)));
+ memcpy (value_contents_all_raw (val), value_contents_all_raw (arg),
+ TYPE_LENGTH (value_enclosing_type (arg)));
}
return val;
In particular, "set $1 = 50" should not affect the variable from which
the value was taken, and fast watchpoints should be able to assume that
a value on the value history never changes. */
- if (VALUE_LAZY (val))
+ if (value_lazy (val))
value_fetch_lazy (val);
/* We preserve VALUE_LVAL so that the user can find out where it was fetched
from. This is a bit dubious, because then *&$1 does not just return $1
struct value *val;
val = value_copy (var->value);
- if (VALUE_LAZY (val))
+ if (value_lazy (val))
value_fetch_lazy (val);
VALUE_LVAL (val) = lval_internalvar;
VALUE_INTERNALVAR (val) = var;
set_internalvar_component (struct internalvar *var, int offset, int bitpos,
int bitsize, struct value *newval)
{
- char *addr = VALUE_CONTENTS (var->value) + offset;
+ bfd_byte *addr = value_contents_writeable (var->value) + offset;
if (bitsize)
modify_field (addr, value_as_long (newval),
bitpos, bitsize);
else
- memcpy (addr, VALUE_CONTENTS (newval), TYPE_LENGTH (VALUE_TYPE (newval)));
+ memcpy (addr, value_contents (newval), TYPE_LENGTH (value_type (newval)));
}
void
/* Force the value to be fetched from the target now, to avoid problems
later when this internalvar is referenced and the target is gone or
has changed. */
- if (VALUE_LAZY (newval))
+ if (value_lazy (newval))
value_fetch_lazy (newval);
/* Begin code which must not call error(). If var->value points to
/* This coerces arrays and functions, which is necessary (e.g.
in disassemble_command). It also dereferences references, which
I suspect is the most logical thing to do. */
- COERCE_ARRAY (val);
- return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+ val = coerce_array (val);
+ return unpack_long (value_type (val), value_contents (val));
}
DOUBLEST
DOUBLEST foo;
int inv;
- foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
+ foo = unpack_double (value_type (val), value_contents (val), &inv);
if (inv)
error ("Invalid floating value found in program.");
return foo;
The following shortcut avoids this whole mess. If VAL is a
function, just return its address directly. */
- if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC
- || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_METHOD)
+ if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
+ || TYPE_CODE (value_type (val)) == TYPE_CODE_METHOD)
return VALUE_ADDRESS (val);
- COERCE_ARRAY (val);
+ val = coerce_array (val);
/* Some architectures (e.g. Harvard), map instruction and data
addresses onto a single large unified address space. For
take an address from a disassembly listing and give it to `x/i'.
This is certainly important.
- Adding an architecture method like INTEGER_TO_ADDRESS certainly
+ Adding an architecture method like integer_to_address() certainly
makes it possible for GDB to "get it right" in all circumstances
--- the target has complete control over how things get done, so
people can Do The Right Thing for their target without breaking
converted to pointers; usually, the ABI doesn't either, but
ABI-specific code is a more reasonable place to handle it. */
- if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_PTR
- && TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_REF
- && INTEGER_TO_ADDRESS_P ())
- return INTEGER_TO_ADDRESS (VALUE_TYPE (val), VALUE_CONTENTS (val));
+ if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
+ && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+ && gdbarch_integer_to_address_p (current_gdbarch))
+ return gdbarch_integer_to_address (current_gdbarch, value_type (val),
+ value_contents (val));
- return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+ return unpack_long (value_type (val), value_contents (val));
#endif
}
\f
struct value *
value_change_enclosing_type (struct value *val, struct type *new_encl_type)
{
- if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val)))
+ if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (value_enclosing_type (val)))
{
- VALUE_ENCLOSING_TYPE (val) = new_encl_type;
+ val->enclosing_type = new_encl_type;
return val;
}
else
new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
- VALUE_ENCLOSING_TYPE (new_val) = new_encl_type;
+ new_val->enclosing_type = new_encl_type;
/* We have to make sure this ends up in the same place in the value
chain as the original copy, so it's clean-up behavior is the same.
{
v = value_from_longest (type,
unpack_field_as_long (arg_type,
- VALUE_CONTENTS (arg1)
+ value_contents (arg1)
+ offset,
fieldno));
- VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
- VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
- VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ v->bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
+ v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
+ v->offset = value_offset (arg1) + offset
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
}
else if (fieldno < TYPE_N_BASECLASSES (arg_type))
/* This field is actually a base subobject, so preserve the
entire object's contents for later references to virtual
bases, etc. */
- v = allocate_value (VALUE_ENCLOSING_TYPE (arg1));
- VALUE_TYPE (v) = type;
- if (VALUE_LAZY (arg1))
- VALUE_LAZY (v) = 1;
+ v = allocate_value (value_enclosing_type (arg1));
+ v->type = type;
+ if (value_lazy (arg1))
+ set_value_lazy (v, 1);
else
- memcpy (VALUE_CONTENTS_ALL_RAW (v), VALUE_CONTENTS_ALL_RAW (arg1),
- TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg1)));
- VALUE_OFFSET (v) = VALUE_OFFSET (arg1);
+ memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
+ TYPE_LENGTH (value_enclosing_type (arg1)));
+ v->offset = value_offset (arg1);
VALUE_EMBEDDED_OFFSET (v)
= offset +
VALUE_EMBEDDED_OFFSET (arg1) +
/* Plain old data member */
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
v = allocate_value (type);
- if (VALUE_LAZY (arg1))
- VALUE_LAZY (v) = 1;
+ if (value_lazy (arg1))
+ set_value_lazy (v, 1);
else
- memcpy (VALUE_CONTENTS_RAW (v),
- VALUE_CONTENTS_RAW (arg1) + offset,
+ memcpy (value_contents_raw (v),
+ value_contents_raw (arg1) + offset,
TYPE_LENGTH (type));
- VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
- + VALUE_EMBEDDED_OFFSET (arg1);
+ v->offset = (value_offset (arg1) + offset
+ + VALUE_EMBEDDED_OFFSET (arg1));
}
VALUE_LVAL (v) = VALUE_LVAL (arg1);
if (VALUE_LVAL (arg1) == lval_internalvar)
VALUE_LVAL (v) = lval_internalvar_component;
VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
- VALUE_REGNO (v) = VALUE_REGNO (arg1);
+ VALUE_REGNUM (v) = VALUE_REGNUM (arg1);
+ VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1);
/* VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */
return v;
struct value *
value_field (struct value *arg1, int fieldno)
{
- return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1));
+ return value_primitive_field (arg1, 0, fieldno, value_type (arg1));
}
/* Return a non-virtual function as a value.
if (arg1p)
{
- if (type != VALUE_TYPE (*arg1p))
+ if (type != value_type (*arg1p))
*arg1p = value_ind (value_cast (lookup_pointer_type (type),
value_addr (*arg1p)));
case TYPE_CODE_ENUM:
case TYPE_CODE_BOOL:
case TYPE_CODE_RANGE:
- store_signed_integer (VALUE_CONTENTS_RAW (val), len, num);
+ store_signed_integer (value_contents_raw (val), len, num);
break;
case TYPE_CODE_REF:
case TYPE_CODE_PTR:
- store_typed_address (VALUE_CONTENTS_RAW (val), type, (CORE_ADDR) num);
+ store_typed_address (value_contents_raw (val), type, (CORE_ADDR) num);
break;
default:
value_from_pointer (struct type *type, CORE_ADDR addr)
{
struct value *val = allocate_value (type);
- store_typed_address (VALUE_CONTENTS_RAW (val), type, addr);
+ store_typed_address (value_contents_raw (val), type, addr);
return val;
}
string_char_type,
rangetype);
val = allocate_value (stringtype);
- memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
+ memcpy (value_contents_raw (val), ptr, len);
return val;
}
if (code == TYPE_CODE_FLT)
{
- store_typed_floating (VALUE_CONTENTS_RAW (val), base_type, num);
+ store_typed_floating (value_contents_raw (val), base_type, num);
}
else
error ("Unexpected type encountered for floating constant.");
return val;
}
+
+struct value *
+coerce_ref (struct value *arg)
+{
+ struct type *value_type_arg_tmp = check_typedef (value_type (arg));
+ if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF)
+ arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp),
+ unpack_pointer (value_type (arg),
+ value_contents (arg)));
+ return arg;
+}
+
+struct value *
+coerce_array (struct value *arg)
+{
+ arg = coerce_ref (arg);
+ if (current_language->c_style_arrays
+ && TYPE_CODE (value_type (arg)) == TYPE_CODE_ARRAY)
+ arg = value_coerce_array (arg);
+ if (TYPE_CODE (value_type (arg)) == TYPE_CODE_FUNC)
+ arg = value_coerce_function (arg);
+ return arg;
+}
+
+struct value *
+coerce_number (struct value *arg)
+{
+ arg = coerce_array (arg);
+ arg = coerce_enum (arg);
+ return arg;
+}
+
+struct value *
+coerce_enum (struct value *arg)
+{
+ if (TYPE_CODE (check_typedef (value_type (arg))) == TYPE_CODE_ENUM)
+ arg = value_cast (builtin_type_unsigned_int, arg);
+ return arg;
+}
\f
/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of