Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009 Free Software Foundation, Inc.
+ 2009, 2010 Free Software Foundation, Inc.
This file is part of GDB.
gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */
int bitpos;
+ /* Only used for bitfields; the containing value. This allows a
+ single read from the target when displaying multiple
+ bitfields. */
+ struct value *parent;
+
/* Frame register value is relative to. This will be described in
the lval enum above as "lval_register". */
struct frame_id frame_id;
/* If value is a variable, is it initialized or not. */
int initialized;
+ /* If value is from the stack. If this is set, read_stack will be
+ used instead of read_memory to enable extra caching. */
+ int stack;
+
/* Actual contents of the value. Target byte-order. NULL or not
valid if lazy is nonzero. */
gdb_byte *contents;
+
+ /* The number of references to this value. When a value is created,
+ the value chain holds a reference, so REFERENCE_COUNT is 1. If
+ release_value is called, this value is removed from the chain but
+ the caller of release_value now has a reference to this value.
+ The caller must arrange for a call to value_free later. */
+ int reference_count;
};
/* Prototypes for local functions. */
allocate_value_lazy (struct type *type)
{
struct value *val;
- struct type *atype = check_typedef (type);
+
+ /* Call check_typedef on our type to make sure that, if TYPE
+ is a TYPE_CODE_TYPEDEF, its length is set to the length
+ of the target type instead of zero. However, we do not
+ replace the typedef type by the target type, because we want
+ to keep the typedef in order to be able to set the VAL's type
+ description correctly. */
+ check_typedef (type);
val = (struct value *) xzalloc (sizeof (struct value));
val->contents = NULL;
val->pointed_to_offset = 0;
val->modifiable = 1;
val->initialized = 1; /* Default to initialized. */
+
+ /* Values start out on the all_values chain. */
+ val->reference_count = 1;
+
return val;
}
allocate_value (struct type *type)
{
struct value *val = allocate_value_lazy (type);
+
allocate_value_contents (val);
val->lazy = 0;
return val;
done with it. */
struct type *array_type
= lookup_array_range_type (type, low_bound, count + low_bound - 1);
- return allocate_value (array_type);
-}
-
-/* Needed if another module needs to maintain its on list of values. */
-void
-value_prepend_to_list (struct value **head, struct value *val)
-{
- val->next = *head;
- *head = val;
-}
-
-/* Needed if another module needs to maintain its on list of values. */
-void
-value_remove_from_list (struct value **head, struct value *val)
-{
- struct value *prev;
- if (*head == val)
- *head = (*head)->next;
- else
- for (prev = *head; prev->next; prev = prev->next)
- if (prev->next == val)
- {
- prev->next = val->next;
- break;
- }
+ return allocate_value (array_type);
}
struct value *
void *closure)
{
struct value *v = allocate_value (type);
+
VALUE_LVAL (v) = lval_computed;
v->location.computed.funcs = funcs;
v->location.computed.closure = closure;
value->bitsize = bit;
}
+struct value *
+value_parent (struct value *value)
+{
+ return value->parent;
+}
+
gdb_byte *
value_contents_raw (struct value *value)
{
value->lazy = val;
}
+int
+value_stack (struct value *value)
+{
+ return value->stack;
+}
+
+void
+set_value_stack (struct value *value, int val)
+{
+ value->stack = val;
+}
+
const gdb_byte *
value_contents (struct value *value)
{
return all_values;
}
+/* Take a reference to VAL. VAL will not be deallocated until all
+ references are released. */
+
+void
+value_incref (struct value *val)
+{
+ val->reference_count++;
+}
+
+/* Release a reference to VAL, which was acquired with value_incref.
+ This function is also called to deallocate values from the value
+ chain. */
+
void
value_free (struct value *val)
{
if (val)
{
+ gdb_assert (val->reference_count > 0);
+ val->reference_count--;
+ if (val->reference_count > 0)
+ return;
+
+ /* If there's an associated parent value, drop our reference to
+ it. */
+ if (val->parent != NULL)
+ value_free (val->parent);
+
if (VALUE_LVAL (val) == lval_computed)
{
struct lval_funcs *funcs = val->location.computed.funcs;
}
/* Free all the values that have been allocated (except for those released).
- Called after each command, successful or not. */
+ Call after each command, successful or not.
+ In practice this is called before each command, which is sufficient. */
void
free_all_values (void)
TYPE_LENGTH (value_enclosing_type (arg)));
}
+ val->parent = arg->parent;
+ if (val->parent)
+ value_incref (val->parent);
if (VALUE_LVAL (val) == lval_computed)
{
struct lval_funcs *funcs = val->location.computed.funcs;
if (i == 0)
{
struct value_history_chunk *new
- = (struct value_history_chunk *)
+ = (struct value_history_chunk *)
+
xmalloc (sizeof (struct value_history_chunk));
memset (new->values, 0, sizeof new->values);
new->next = value_history_chain;
for (i = num; i < num + 10 && i <= value_history_count; i++)
{
struct value_print_options opts;
+
val = access_value_history (i);
printf_filtered (("$%d = "), i);
get_user_print_options (&opts);
/* The internal variable holds a GDB internal convenience function. */
INTERNALVAR_FUNCTION,
- /* The variable holds a simple scalar value. */
- INTERNALVAR_SCALAR,
+ /* The variable holds an integer value. */
+ INTERNALVAR_INTEGER,
+
+ /* The variable holds a pointer value. */
+ INTERNALVAR_POINTER,
/* The variable holds a GDB-provided string. */
INTERNALVAR_STRING,
int canonical;
} fn;
- /* A scalar value used with INTERNALVAR_SCALAR. */
+ /* An integer value used with INTERNALVAR_INTEGER. */
struct
{
/* If type is non-NULL, it will be used as the type to generate
a value for this internal variable. If type is NULL, a default
integer type for the architecture is used. */
struct type *type;
- union
- {
- LONGEST l; /* Used with TYPE_CODE_INT and NULL types. */
- CORE_ADDR a; /* Used with TYPE_CODE_PTR types. */
- } val;
- } scalar;
+ LONGEST val;
+ } integer;
+
+ /* A pointer value used with INTERNALVAR_POINTER. */
+ struct
+ {
+ struct type *type;
+ CORE_ADDR val;
+ } pointer;
/* A string value used with INTERNALVAR_STRING. */
char *string;
create_internalvar (const char *name)
{
struct internalvar *var;
+
var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
var->name = concat (name, (char *)NULL);
var->kind = INTERNALVAR_VOID;
create_internalvar_type_lazy (char *name, internalvar_make_value fun)
{
struct internalvar *var = create_internalvar (name);
+
var->kind = INTERNALVAR_MAKE_VALUE;
var->u.make_value = fun;
return var;
val = allocate_value (builtin_type (gdbarch)->internal_fn);
break;
- case INTERNALVAR_SCALAR:
- if (!var->u.scalar.type)
+ case INTERNALVAR_INTEGER:
+ if (!var->u.integer.type)
val = value_from_longest (builtin_type (gdbarch)->builtin_int,
- var->u.scalar.val.l);
- else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT)
- val = value_from_longest (var->u.scalar.type, var->u.scalar.val.l);
- else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_PTR)
- val = value_from_pointer (var->u.scalar.type, var->u.scalar.val.a);
+ var->u.integer.val);
else
- internal_error (__FILE__, __LINE__, "bad type");
+ val = value_from_longest (var->u.integer.type, var->u.integer.val);
+ break;
+
+ case INTERNALVAR_POINTER:
+ val = value_from_pointer (var->u.pointer.type, var->u.pointer.val);
break;
case INTERNALVAR_STRING:
{
switch (var->kind)
{
- case INTERNALVAR_SCALAR:
- if (var->u.scalar.type == NULL
- || TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT)
- {
- *result = var->u.scalar.val.l;
- return 1;
- }
- /* Fall through. */
+ case INTERNALVAR_INTEGER:
+ *result = var->u.integer.val;
+ return 1;
default:
return 0;
break;
case TYPE_CODE_INT:
- new_kind = INTERNALVAR_SCALAR;
- new_data.scalar.type = value_type (val);
- new_data.scalar.val.l = value_as_long (val);
+ new_kind = INTERNALVAR_INTEGER;
+ new_data.integer.type = value_type (val);
+ new_data.integer.val = value_as_long (val);
break;
case TYPE_CODE_PTR:
- new_kind = INTERNALVAR_SCALAR;
- new_data.scalar.type = value_type (val);
- new_data.scalar.val.a = value_as_address (val);
+ new_kind = INTERNALVAR_POINTER;
+ new_data.pointer.type = value_type (val);
+ new_data.pointer.val = value_as_address (val);
break;
default:
/* Clean up old contents. */
clear_internalvar (var);
- var->kind = INTERNALVAR_SCALAR;
- var->u.scalar.type = NULL;
- var->u.scalar.val.l = l;
+ var->kind = INTERNALVAR_INTEGER;
+ var->u.integer.type = NULL;
+ var->u.integer.val = l;
}
void
internal_function_fn handler, void *cookie)
{
struct internal_function *ifn = XNEW (struct internal_function);
+
ifn->name = xstrdup (name);
ifn->handler = handler;
ifn->cookie = cookie;
}
struct value *
-call_internal_function (struct value *func, int argc, struct value **argv)
+call_internal_function (struct gdbarch *gdbarch,
+ const struct language_defn *language,
+ struct value *func, int argc, struct value **argv)
{
struct internal_function *ifn;
int result;
result = get_internalvar_function (VALUE_INTERNALVAR (func), &ifn);
gdb_assert (result);
- return (*ifn->handler) (ifn->cookie, argc, argv);
+ return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv);
}
/* The 'function' command. This does nothing -- it is just a
/* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to
prevent cycles / duplicates. */
-static void
+void
preserve_one_value (struct value *value, struct objfile *objfile,
htab_t copied_types)
{
{
switch (var->kind)
{
- case INTERNALVAR_SCALAR:
- if (var->u.scalar.type && TYPE_OBJFILE (var->u.scalar.type) == objfile)
- var->u.scalar.type
- = copy_type_recursive (objfile, var->u.scalar.type, copied_types);
+ case INTERNALVAR_INTEGER:
+ if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile)
+ var->u.integer.type
+ = copy_type_recursive (objfile, var->u.integer.type, copied_types);
+ break;
+
+ case INTERNALVAR_POINTER:
+ if (TYPE_OBJFILE (var->u.pointer.type) == objfile)
+ var->u.pointer.type
+ = copy_type_recursive (objfile, var->u.pointer.type, copied_types);
break;
case INTERNALVAR_VALUE:
htab_t copied_types;
struct value_history_chunk *cur;
struct internalvar *var;
- struct value *val;
int i;
/* Create the hash table. We allocate on the objfile's obstack, since
for (var = internalvars; var; var = var->next)
preserve_one_internalvar (var, objfile, copied_types);
- for (val = values_in_python; val; val = val->next)
- preserve_one_value (val, objfile, copied_types);
+ preserve_python_values (objfile, copied_types);
htab_delete (copied_types);
}
LONGEST
unpack_long (struct type *type, const gdb_byte *valaddr)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type);
int nosign = TYPE_UNSIGNED (type);
case TYPE_CODE_RANGE:
case TYPE_CODE_MEMBERPTR:
if (nosign)
- return extract_unsigned_integer (valaddr, len);
+ return extract_unsigned_integer (valaddr, len, byte_order);
else
- return extract_signed_integer (valaddr, len);
+ return extract_signed_integer (valaddr, len, byte_order);
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);
+ return decimal_to_doublest (valaddr, len, byte_order);
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
DOUBLEST
unpack_double (struct type *type, const gdb_byte *valaddr, int *invp)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
enum type_code code;
int len;
int nosign;
return extract_typed_floating (valaddr, type);
}
else if (code == TYPE_CODE_DECFLOAT)
- return decimal_to_doublest (valaddr, len);
+ return decimal_to_doublest (valaddr, len, byte_order);
else if (nosign)
{
/* Unsigned -- be sure we compensate for signed LONGEST. */
if (TYPE_FIELD_LOC_KIND (type, fieldno) == FIELD_LOC_KIND_PHYSADDR)
{
- retval = value_at (TYPE_FIELD_TYPE (type, fieldno),
- TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
+ retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno),
+ TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
}
else
{
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+ /*TYPE_FIELD_NAME (type, fieldno);*/
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
- as non-debuggable symbols */
- struct minimal_symbol *msym = lookup_minimal_symbol (phys_name, NULL, NULL);
+ /* With some compilers, e.g. HP aCC, static data members are
+ reported as non-debuggable symbols */
+ struct minimal_symbol *msym = lookup_minimal_symbol (phys_name,
+ NULL, NULL);
+
if (!msym)
return NULL;
else
{
- retval = value_at (TYPE_FIELD_TYPE (type, fieldno),
- SYMBOL_VALUE_ADDRESS (msym));
+ retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno),
+ SYMBOL_VALUE_ADDRESS (msym));
}
}
else
CHECK_TYPEDEF (arg_type);
type = TYPE_FIELD_TYPE (arg_type, fieldno);
+ /* Call check_typedef on our type to make sure that, if TYPE
+ is a TYPE_CODE_TYPEDEF, its length is set to the length
+ of the target type instead of zero. However, we do not
+ replace the typedef type by the target type, because we want
+ to keep the typedef in order to be able to print the type
+ description correctly. */
+ check_typedef (type);
+
/* Handle packed fields */
if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
{
- v = value_from_longest (type,
- unpack_field_as_long (arg_type,
- value_contents (arg1)
- + offset,
- fieldno));
- v->bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
+ /* Create a new value for the bitfield, with bitpos and bitsize
+ set. If possible, arrange offset and bitpos so that we can
+ do a single aligned read of the size of the containing type.
+ Otherwise, adjust offset to the byte containing the first
+ bit. Assume that the address, offset, and embedded offset
+ are sufficiently aligned. */
+ int bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno);
+ int container_bitsize = TYPE_LENGTH (type) * 8;
+
+ v = allocate_value_lazy (type);
v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
- v->offset = value_offset (arg1) + offset
- + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+ if ((bitpos % container_bitsize) + v->bitsize <= container_bitsize
+ && TYPE_LENGTH (type) <= (int) sizeof (LONGEST))
+ v->bitpos = bitpos % container_bitsize;
+ else
+ v->bitpos = bitpos % 8;
+ v->offset = value_embedded_offset (arg1)
+ + (bitpos - v->bitpos) / 8;
+ v->parent = arg1;
+ value_incref (v->parent);
+ if (!value_lazy (arg1))
+ value_fetch_lazy (v);
}
else if (fieldno < TYPE_N_BASECLASSES (arg_type))
{
}
\f
-/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
- VALADDR.
+/* Unpack a bitfield of the specified FIELD_TYPE, from the anonymous
+ object at VALADDR. The bitfield starts at BITPOS bits and contains
+ BITSIZE bits.
Extracting bits depends on endianness of the machine. Compute the
number of least significant bits to discard. For big endian machines,
If the field is signed, we also do sign extension. */
LONGEST
-unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
+unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
+ int bitpos, int bitsize)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (field_type));
ULONGEST val;
ULONGEST valmask;
- int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
- int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
int lsbcount;
- struct type *field_type;
+ int bytes_read;
- val = extract_unsigned_integer (valaddr + bitpos / 8, sizeof (val));
- field_type = TYPE_FIELD_TYPE (type, fieldno);
+ /* Read the minimum number of bytes required; there may not be
+ enough bytes to read an entire ULONGEST. */
CHECK_TYPEDEF (field_type);
+ if (bitsize)
+ bytes_read = ((bitpos % 8) + bitsize + 7) / 8;
+ else
+ bytes_read = TYPE_LENGTH (field_type);
+
+ val = extract_unsigned_integer (valaddr + bitpos / 8,
+ bytes_read, byte_order);
/* Extract bits. See comment above. */
- if (gdbarch_bits_big_endian (get_type_arch (type)))
- lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
+ if (gdbarch_bits_big_endian (get_type_arch (field_type)))
+ lsbcount = (bytes_read * 8 - bitpos % 8 - bitsize);
else
lsbcount = (bitpos % 8);
val >>= lsbcount;
return (val);
}
+/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
+ VALADDR. See unpack_bits_as_long for more details. */
+
+LONGEST
+unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
+{
+ int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
+ int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
+ struct type *field_type = TYPE_FIELD_TYPE (type, fieldno);
+
+ return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize);
+}
+
/* Modify the value of a bitfield. ADDR points to a block of memory in
target byte order; the bitfield starts in the byte pointed to. FIELDVAL
is the desired value of the field, in host byte order. BITPOS and BITSIZE
modify_field (struct type *type, gdb_byte *addr,
LONGEST fieldval, int bitpos, int bitsize)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
ULONGEST oword;
ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize);
fieldval &= mask;
}
- oword = extract_unsigned_integer (addr, sizeof oword);
+ oword = extract_unsigned_integer (addr, sizeof oword, byte_order);
/* Shifting for bit field depends on endianness of the target machine. */
if (gdbarch_bits_big_endian (get_type_arch (type)))
oword &= ~(mask << bitpos);
oword |= fieldval << bitpos;
- store_unsigned_integer (addr, sizeof oword, oword);
+ store_unsigned_integer (addr, sizeof oword, byte_order, oword);
}
\f
/* Pack NUM into BUF using a target format of TYPE. */
void
pack_long (gdb_byte *buf, struct type *type, LONGEST num)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
int len;
type = check_typedef (type);
case TYPE_CODE_BOOL:
case TYPE_CODE_RANGE:
case TYPE_CODE_MEMBERPTR:
- store_signed_integer (buf, len, num);
+ store_signed_integer (buf, len, byte_order, num);
break;
case TYPE_CODE_REF:
struct value *val = allocate_value (type);
pack_long (value_contents_raw (val), type, num);
-
return val;
}
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), check_typedef (type), addr);
return val;
}
CORE_ADDR address)
{
struct value *v = allocate_value (type);
+
if (valaddr == NULL)
set_value_lazy (v, 1);
else
struct value *val = allocate_value (type);
struct type *base_type = check_typedef (type);
enum type_code code = TYPE_CODE (base_type);
- int len = TYPE_LENGTH (base_type);
if (code == TYPE_CODE_FLT)
{
struct value *val = allocate_value (type);
memcpy (value_contents_raw (val), dec, TYPE_LENGTH (type));
-
return val;
}
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),