#include "regcache.h"
#include "block.h"
#include "dfp.h"
+#include "objfiles.h"
+#include "valprint.h"
+
+#include "python/python.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
/* Values are stored in a chain, so that they can be deleted easily
over calls to the inferior. Values assigned to internal
- variables or put into the value history are taken off this
- list. */
+ variables, put into the value history or exposed to Python are
+ taken off this list. */
struct value *next;
/* Register number if the value is from a register. */
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
/* If value is a variable, is it initialized or not. */
int initialized;
- /* Actual contents of the value. For use of this value; setting it
- uses the stuff above. Not valid if lazy is nonzero. Target
- byte-order. We force it to be aligned properly for any possible
- value. Note that a value therefore extends beyond what is
- declared here. */
- union
- {
- gdb_byte contents[1];
- DOUBLEST force_doublest_align;
- LONGEST force_longest_align;
- CORE_ADDR force_core_addr_align;
- void *force_pointer_align;
- } aligner;
- /* Do not add any new members here -- contents above will trash
- them. */
+ /* Actual contents of the value. Target byte-order. NULL or not
+ valid if lazy is nonzero. */
+ gdb_byte *contents;
};
/* Prototypes for local functions. */
static struct value *all_values;
-/* Allocate a value that has the correct length for type TYPE. */
+/* Allocate a lazy value for type TYPE. Its actual content is
+ "lazily" allocated too: the content field of the return value is
+ NULL; it will be allocated when it is fetched from the target. */
struct value *
-allocate_value (struct type *type)
+allocate_value_lazy (struct type *type)
{
struct value *val;
struct type *atype = check_typedef (type);
- val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
+ val = (struct value *) xzalloc (sizeof (struct value));
+ val->contents = NULL;
val->next = all_values;
all_values = val;
val->type = type;
val->bitpos = 0;
val->bitsize = 0;
VALUE_REGNUM (val) = -1;
- val->lazy = 0;
+ val->lazy = 1;
val->optimized_out = 0;
val->embedded_offset = 0;
val->pointed_to_offset = 0;
return val;
}
+/* Allocate the contents of VAL if it has not been allocated yet. */
+
+void
+allocate_value_contents (struct value *val)
+{
+ if (!val->contents)
+ val->contents = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
+}
+
+/* Allocate a value and its contents for type TYPE. */
+
+struct value *
+allocate_value (struct type *type)
+{
+ struct value *val = allocate_value_lazy (type);
+ allocate_value_contents (val);
+ val->lazy = 0;
+ return val;
+}
+
/* 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)
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
struct type *range_type
- = create_range_type ((struct type *) NULL, builtin_type_int,
+ = create_range_type ((struct type *) NULL, builtin_type_int32,
low_bound, count + low_bound - 1);
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
type, range_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;
+ }
+}
+
/* Accessor methods. */
struct value *
gdb_byte *
value_contents_raw (struct value *value)
{
- return value->aligner.contents + value->embedded_offset;
+ allocate_value_contents (value);
+ return value->contents + value->embedded_offset;
}
gdb_byte *
value_contents_all_raw (struct value *value)
{
- return value->aligner.contents;
+ allocate_value_contents (value);
+ return value->contents;
}
struct type *
{
if (value->lazy)
value_fetch_lazy (value);
- return value->aligner.contents;
+ return value->contents;
}
int
return all_values;
}
+void
+value_free (struct value *val)
+{
+ if (val)
+ xfree (val->contents);
+ xfree (val);
+}
+
/* Free all values allocated since MARK was obtained by value_mark
(except for those released). */
void
value_copy (struct value *arg)
{
struct type *encl_type = value_enclosing_type (arg);
- struct value *val = allocate_value (encl_type);
+ struct value *val;
+
+ if (value_lazy (arg))
+ val = allocate_value_lazy (encl_type);
+ else
+ val = allocate_value (encl_type);
val->type = arg->type;
VALUE_LVAL (val) = VALUE_LVAL (arg);
val->location = arg->location;
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;
}
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);
- value_print (val, gdb_stdout, 0, Val_pretty_default);
+ get_user_print_options (&opts);
+ value_print (val, gdb_stdout, &opts);
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] = '+';
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_value (var->value, objfile, copied_types);
+ for (val = values_in_python; val; val = val->next)
+ preserve_one_value (val, objfile, copied_types);
+
htab_delete (copied_types);
}
{
struct internalvar *var;
int varseen = 0;
+ struct value_print_options opts;
+ get_user_print_options (&opts);
for (var = internalvars; var; var = var->next)
{
if (!varseen)
}
printf_filtered (("$%s = "), var->name);
value_print (value_of_internalvar (var), gdb_stdout,
- 0, Val_pretty_default);
+ &opts);
printf_filtered (("\n"));
}
if (!varseen)
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. */
{
struct value *retval;
- if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno))
+ 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));
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
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)))
- {
- val->enclosing_type = new_encl_type;
- return val;
- }
- else
- {
- struct value *new_val;
- struct value *prev;
-
- new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (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.
- If the value has been released, this is a waste of time, but there
- is no way to tell that in advance, so... */
-
- if (val != all_values)
- {
- for (prev = all_values; prev != NULL; prev = prev->next)
- {
- if (prev->next == val)
- {
- prev->next = new_val;
- break;
- }
- }
- }
-
- return new_val;
- }
+ if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val)))
+ val->contents =
+ (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
+
+ val->enclosing_type = new_encl_type;
+ return val;
}
/* Given a value ARG1 (offset by OFFSET bytes)
/* 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));
- 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);
+ v = allocate_value_lazy (value_enclosing_type (arg1));
else
- memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
- TYPE_LENGTH (value_enclosing_type (arg1)));
+ {
+ v = allocate_value (value_enclosing_type (arg1));
+ memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
+ TYPE_LENGTH (value_enclosing_type (arg1)));
+ }
+ v->type = type;
v->offset = value_offset (arg1);
v->embedded_offset = (offset + value_embedded_offset (arg1)
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
{
/* 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);
+ v = allocate_value_lazy (type);
else
- memcpy (value_contents_raw (v),
- value_contents_raw (arg1) + offset,
- TYPE_LENGTH (type));
+ {
+ v = allocate_value (type);
+ memcpy (value_contents_raw (v),
+ value_contents_raw (arg1) + offset,
+ TYPE_LENGTH (type));
+ }
v->offset = (value_offset (arg1) + offset
+ value_embedded_offset (arg1));
}
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);
struct type *stringtype;
rangetype = create_range_type ((struct type *) NULL,
- builtin_type_int,
+ builtin_type_int32,
lowbound, len + lowbound - 1);
string_char_type = language_string_char_type (current_language,
current_gdbarch);
return val;
}
+/* Create a value of type TYPE whose contents come from VALADDR, if it
+ is non-null, and whose memory address (in the inferior) is
+ ADDRESS. */
+
+struct value *
+value_from_contents_and_address (struct type *type,
+ const gdb_byte *valaddr,
+ CORE_ADDR address)
+{
+ struct value *v = allocate_value (type);
+ if (valaddr == NULL)
+ set_value_lazy (v, 1);
+ else
+ memcpy (value_contents_raw (v), valaddr, TYPE_LENGTH (type));
+ VALUE_ADDRESS (v) = address;
+ if (address != 0)
+ VALUE_LVAL (v) = lval_memory;
+ return v;
+}
+
struct value *
value_from_double (struct type *type, DOUBLEST num)
{
}
struct value *
-value_from_decfloat (struct type *expect_type, struct type *type,
- gdb_byte decbytes[16])
+value_from_decfloat (struct type *type, const gdb_byte *dec)
{
struct value *val = allocate_value (type);
- int len = TYPE_LENGTH (type);
- if (expect_type)
- {
- int expect_len = TYPE_LENGTH (expect_type);
- char decstr[MAX_DECIMAL_STRING];
- int real_len;
-
- decimal_to_string (decbytes, len, decstr);
- decimal_from_string (decbytes, expect_len, decstr);
- }
+ memcpy (value_contents_raw (val), dec, TYPE_LENGTH (type));
- memcpy (value_contents_raw (val), decbytes, len);
return val;
}
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 type *type;
-struct value *
-coerce_number (struct value *arg)
-{
- arg = coerce_array (arg);
- arg = coerce_enum (arg);
- return arg;
-}
+ arg = coerce_ref (arg);
+ type = check_typedef (value_type (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);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (current_language->c_style_arrays)
+ arg = value_coerce_array (arg);
+ break;
+ case TYPE_CODE_FUNC:
+ arg = value_coerce_function (arg);
+ break;
+ }
return arg;
}
\f
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);
}