X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalue.c;h=a462ee494495faa1408796591d1b73c000f536a1;hb=3c83b96e241336be0c3e26c06f2bf901d0fe8edd;hp=aec3b4b500e7272cc8b50f184632e8c54056d49b;hpb=d80b854b33baf5ebc3940cd5928dc06c8708750d;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/value.c b/gdb/value.c
index aec3b4b500..a462ee4944 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -2,7 +2,7 @@
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.
@@ -20,6 +20,7 @@
along with this program. If not, see . */
#include "defs.h"
+#include "arch-utils.h"
#include "gdb_string.h"
#include "symtab.h"
#include "gdbtypes.h"
@@ -107,6 +108,11 @@ struct value
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;
@@ -190,9 +196,20 @@ struct value
/* 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. */
@@ -222,9 +239,6 @@ static struct value_history_chunk *value_history_chain;
static int value_history_count; /* Abs number of last entry stored */
-/* The type of internal functions. */
-
-static struct type *internal_fn_type;
/* List of all value objects currently allocated
(except for those released by calls to release_value)
@@ -240,7 +254,14 @@ struct value *
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;
@@ -261,6 +282,10 @@ allocate_value_lazy (struct type *type)
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;
}
@@ -293,38 +318,9 @@ allocate_repeat_value (struct type *type, int count)
int low_bound = current_language->string_lower_bound; /* ??? */
/* 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_int32,
- low_bound, count + low_bound - 1);
- /* FIXME-type-allocation: need a way to free this type when we are
- done with it. */
- return allocate_value (create_array_type ((struct type *) NULL,
- 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;
- }
+ struct type *array_type
+ = lookup_array_range_type (type, low_bound, count + low_bound - 1);
+ return allocate_value (array_type);
}
struct value *
@@ -393,6 +389,12 @@ set_value_bitsize (struct value *value, int bit)
value->bitsize = bit;
}
+struct value *
+value_parent (struct value *value)
+{
+ return value->parent;
+}
+
gdb_byte *
value_contents_raw (struct value *value)
{
@@ -433,6 +435,18 @@ set_value_lazy (struct value *value, int val)
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)
{
@@ -589,11 +603,34 @@ value_mark (void)
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;
@@ -624,7 +661,8 @@ value_free_to_mark (struct value *mark)
}
/* 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)
@@ -716,6 +754,9 @@ value_copy (struct value *arg)
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;
@@ -882,25 +923,73 @@ struct internalvar
{
struct internalvar *next;
char *name;
- struct type *type;
- /* True if this internalvar is the canonical name for a convenience
- function. */
- int canonical;
+ /* We support various different kinds of content of an internal variable.
+ enum internalvar_kind specifies the kind, and union internalvar_data
+ provides the data associated with this particular kind. */
+
+ enum internalvar_kind
+ {
+ /* The internal variable is empty. */
+ INTERNALVAR_VOID,
+
+ /* The value of the internal variable is provided directly as
+ a GDB value object. */
+ INTERNALVAR_VALUE,
+
+ /* A fresh value is computed via a call-back routine on every
+ access to the internal variable. */
+ INTERNALVAR_MAKE_VALUE,
+
+ /* The internal variable holds a GDB internal convenience function. */
+ INTERNALVAR_FUNCTION,
+
+ /* The variable holds an integer value. */
+ INTERNALVAR_INTEGER,
+
+ /* The variable holds a pointer value. */
+ INTERNALVAR_POINTER,
- /* If this function is non-NULL, it is used to compute a fresh value
- on every access to the internalvar. */
- internalvar_make_value make_value;
+ /* The variable holds a GDB-provided string. */
+ INTERNALVAR_STRING,
+
+ } kind;
- /* To reduce dependencies on target properties (like byte order) that
- may change during the lifetime of an internal variable, we store
- simple scalar values as host objects. */
union internalvar_data
{
- struct value *v;
- struct internal_function *f;
- LONGEST l;
- CORE_ADDR a;
+ /* A value object used with INTERNALVAR_VALUE. */
+ struct value *value;
+
+ /* The call-back routine used with INTERNALVAR_MAKE_VALUE. */
+ internalvar_make_value make_value;
+
+ /* The internal function used with INTERNALVAR_FUNCTION. */
+ struct
+ {
+ struct internal_function *function;
+ /* True if this is the canonical name for the function. */
+ int canonical;
+ } fn;
+
+ /* 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;
+ 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;
} u;
};
@@ -932,7 +1021,7 @@ init_if_undefined_command (char* args, int from_tty)
/* Only evaluate the expression if the lvalue is void.
This may still fail if the expresssion is invalid. */
- if (TYPE_CODE (intvar->type) == TYPE_CODE_VOID)
+ if (intvar->kind == INTERNALVAR_VOID)
evaluate_expression (expr);
do_cleanups (old_chain);
@@ -967,9 +1056,7 @@ create_internalvar (const char *name)
struct internalvar *var;
var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
var->name = concat (name, (char *)NULL);
- var->type = builtin_type_void;
- var->make_value = NULL;
- var->canonical = 0;
+ var->kind = INTERNALVAR_VOID;
var->next = internalvars;
internalvars = var;
return var;
@@ -984,7 +1071,8 @@ struct internalvar *
create_internalvar_type_lazy (char *name, internalvar_make_value fun)
{
struct internalvar *var = create_internalvar (name);
- var->make_value = fun;
+ var->kind = INTERNALVAR_MAKE_VALUE;
+ var->u.make_value = fun;
return var;
}
@@ -1006,53 +1094,77 @@ lookup_internalvar (const char *name)
return create_internalvar (name);
}
+/* Return current value of internal variable VAR. For variables that
+ are not inherently typed, use a value type appropriate for GDBARCH. */
+
struct value *
-value_of_internalvar (struct internalvar *var)
+value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
{
struct value *val;
- if (var->make_value != NULL)
- val = (*var->make_value) (var);
- else
+ switch (var->kind)
{
- switch (TYPE_CODE (var->type))
- {
- case TYPE_CODE_VOID:
- case TYPE_CODE_INTERNAL_FUNCTION:
- val = allocate_value (var->type);
- break;
+ case INTERNALVAR_VOID:
+ val = allocate_value (builtin_type (gdbarch)->builtin_void);
+ break;
- case TYPE_CODE_INT:
- val = value_from_longest (var->type, var->u.l);
- break;
+ case INTERNALVAR_FUNCTION:
+ val = allocate_value (builtin_type (gdbarch)->internal_fn);
+ break;
- case TYPE_CODE_PTR:
- val = value_from_pointer (var->type, var->u.a);
- break;
+ case INTERNALVAR_INTEGER:
+ if (!var->u.integer.type)
+ val = value_from_longest (builtin_type (gdbarch)->builtin_int,
+ var->u.integer.val);
+ else
+ val = value_from_longest (var->u.integer.type, var->u.integer.val);
+ break;
- default:
- val = value_copy (var->u.v);
- break;
- }
+ case INTERNALVAR_POINTER:
+ val = value_from_pointer (var->u.pointer.type, var->u.pointer.val);
+ break;
+ case INTERNALVAR_STRING:
+ val = value_cstring (var->u.string, strlen (var->u.string),
+ builtin_type (gdbarch)->builtin_char);
+ break;
+
+ case INTERNALVAR_VALUE:
+ val = value_copy (var->u.value);
if (value_lazy (val))
value_fetch_lazy (val);
+ break;
- /* If the variable's value is a computed lvalue, we want
- references to it to produce another computed lvalue, where
- referencces and assignments actually operate through the
- computed value's functions.
-
- This means that internal variables with computed values
- behave a little differently from other internal variables:
- assignments to them don't just replace the previous value
- altogether. At the moment, this seems like the behavior we
- want. */
- if (val->lval != lval_computed)
- {
- VALUE_LVAL (val) = lval_internalvar;
- VALUE_INTERNALVAR (val) = var;
- }
+ case INTERNALVAR_MAKE_VALUE:
+ val = (*var->u.make_value) (gdbarch, var);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__, "bad kind");
+ }
+
+ /* Change the VALUE_LVAL to lval_internalvar so that future operations
+ on this value go back to affect the original internal variable.
+
+ Do not do this for INTERNALVAR_MAKE_VALUE variables, as those have
+ no underlying modifyable state in the internal variable.
+
+ Likewise, if the variable's value is a computed lvalue, we want
+ references to it to produce another computed lvalue, where
+ references and assignments actually operate through the
+ computed value's functions.
+
+ This means that internal variables with computed values
+ behave a little differently from other internal variables:
+ assignments to them don't just replace the previous value
+ altogether. At the moment, this seems like the behavior we
+ want. */
+
+ if (var->kind != INTERNALVAR_MAKE_VALUE
+ && val->lval != lval_computed)
+ {
+ VALUE_LVAL (val) = lval_internalvar;
+ VALUE_INTERNALVAR (val) = var;
}
return val;
@@ -1061,10 +1173,10 @@ value_of_internalvar (struct internalvar *var)
int
get_internalvar_integer (struct internalvar *var, LONGEST *result)
{
- switch (TYPE_CODE (var->type))
+ switch (var->kind)
{
- case TYPE_CODE_INT:
- *result = var->u.l;
+ case INTERNALVAR_INTEGER:
+ *result = var->u.integer.val;
return 1;
default:
@@ -1076,10 +1188,10 @@ static int
get_internalvar_function (struct internalvar *var,
struct internal_function **result)
{
- switch (TYPE_CODE (var->type))
+ switch (var->kind)
{
- case TYPE_CODE_INTERNAL_FUNCTION:
- *result = var->u.f;
+ case INTERNALVAR_FUNCTION:
+ *result = var->u.fn.function;
return 1;
default:
@@ -1093,71 +1205,77 @@ set_internalvar_component (struct internalvar *var, int offset, int bitpos,
{
gdb_byte *addr;
- switch (TYPE_CODE (var->type))
+ switch (var->kind)
{
- case TYPE_CODE_VOID:
- case TYPE_CODE_INTERNAL_FUNCTION:
- case TYPE_CODE_INT:
- case TYPE_CODE_PTR:
- /* We can never get a component of a basic type. */
- internal_error (__FILE__, __LINE__, "set_internalvar_component");
-
- default:
- addr = value_contents_writeable (var->u.v);
+ case INTERNALVAR_VALUE:
+ addr = value_contents_writeable (var->u.value);
if (bitsize)
- modify_field (addr + offset,
+ modify_field (value_type (var->u.value), addr + offset,
value_as_long (newval), bitpos, bitsize);
else
memcpy (addr + offset, value_contents (newval),
TYPE_LENGTH (value_type (newval)));
break;
+
+ default:
+ /* We can never get a component of any other kind. */
+ internal_error (__FILE__, __LINE__, "set_internalvar_component");
}
}
void
set_internalvar (struct internalvar *var, struct value *val)
{
- struct type *new_type = check_typedef (value_type (val));
+ enum internalvar_kind new_kind;
union internalvar_data new_data = { 0 };
- if (var->canonical)
+ if (var->kind == INTERNALVAR_FUNCTION && var->u.fn.canonical)
error (_("Cannot overwrite convenience function %s"), var->name);
/* Prepare new contents. */
- switch (TYPE_CODE (new_type))
+ switch (TYPE_CODE (check_typedef (value_type (val))))
{
case TYPE_CODE_VOID:
+ new_kind = INTERNALVAR_VOID;
break;
case TYPE_CODE_INTERNAL_FUNCTION:
gdb_assert (VALUE_LVAL (val) == lval_internalvar);
- get_internalvar_function (VALUE_INTERNALVAR (val), &new_data.f);
+ new_kind = INTERNALVAR_FUNCTION;
+ get_internalvar_function (VALUE_INTERNALVAR (val),
+ &new_data.fn.function);
+ /* Copies created here are never canonical. */
break;
case TYPE_CODE_INT:
- new_data.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_data.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:
- new_data.v = value_copy (val);
- new_data.v->modifiable = 1;
+ new_kind = INTERNALVAR_VALUE;
+ new_data.value = value_copy (val);
+ new_data.value->modifiable = 1;
/* 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 (new_data.v))
- value_fetch_lazy (new_data.v);
+ if (value_lazy (new_data.value))
+ value_fetch_lazy (new_data.value);
/* Release the value from the value chain to prevent it from being
deleted by free_all_values. From here on this function should not
call error () until new_data is installed into the var->u to avoid
leaking memory. */
- release_value (new_data.v);
+ release_value (new_data.value);
break;
}
@@ -1165,7 +1283,7 @@ set_internalvar (struct internalvar *var, struct value *val)
clear_internalvar (var);
/* Switch over. */
- var->type = new_type;
+ var->kind = new_kind;
var->u = new_data;
/* End code which must not call error(). */
}
@@ -1176,9 +1294,19 @@ set_internalvar_integer (struct internalvar *var, LONGEST l)
/* Clean up old contents. */
clear_internalvar (var);
- /* Use a platform-independent 32-bit integer type. */
- var->type = builtin_type_int32;
- var->u.l = l;
+ var->kind = INTERNALVAR_INTEGER;
+ var->u.integer.type = NULL;
+ var->u.integer.val = l;
+}
+
+void
+set_internalvar_string (struct internalvar *var, const char *string)
+{
+ /* Clean up old contents. */
+ clear_internalvar (var);
+
+ var->kind = INTERNALVAR_STRING;
+ var->u.string = xstrdup (string);
}
static void
@@ -1187,29 +1315,32 @@ set_internalvar_function (struct internalvar *var, struct internal_function *f)
/* Clean up old contents. */
clear_internalvar (var);
- var->type = internal_fn_type;
- var->u.f = f;
+ var->kind = INTERNALVAR_FUNCTION;
+ var->u.fn.function = f;
+ var->u.fn.canonical = 1;
+ /* Variables installed here are always the canonical version. */
}
void
clear_internalvar (struct internalvar *var)
{
/* Clean up old contents. */
- switch (TYPE_CODE (var->type))
+ switch (var->kind)
{
- case TYPE_CODE_VOID:
- case TYPE_CODE_INTERNAL_FUNCTION:
- case TYPE_CODE_INT:
- case TYPE_CODE_PTR:
+ case INTERNALVAR_VALUE:
+ value_free (var->u.value);
+ break;
+
+ case INTERNALVAR_STRING:
+ xfree (var->u.string);
break;
default:
- value_free (var->u.v);
break;
}
- /* Set to void type. */
- var->type = builtin_type_void;
+ /* Reset to void kind. */
+ var->kind = INTERNALVAR_VOID;
}
char *
@@ -1243,7 +1374,9 @@ value_internal_function_name (struct value *val)
}
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;
@@ -1252,7 +1385,7 @@ call_internal_function (struct value *func, int argc, struct value **argv)
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
@@ -1288,7 +1421,6 @@ add_internal_function (const char *name, const char *doc,
ifn = create_internal_function (name, handler, cookie);
set_internalvar_function (var, ifn);
- var->canonical = 1;
cmd = add_cmd (xstrdup (name), no_class, function_command, (char *) doc,
&functionlist);
@@ -1298,7 +1430,7 @@ add_internal_function (const char *name, const char *doc,
/* 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)
{
@@ -1311,6 +1443,32 @@ preserve_one_value (struct value *value, struct objfile *objfile,
copied_types);
}
+/* Likewise for internal variable VAR. */
+
+static void
+preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
+ htab_t copied_types)
+{
+ switch (var->kind)
+ {
+ 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:
+ preserve_one_value (var->u.value, objfile, copied_types);
+ break;
+ }
+}
+
/* Update the internal variables and value history when OBJFILE is
discarded; we must copy the types out of the objfile. New global types
will be created for every convenience variable which currently points to
@@ -1336,26 +1494,9 @@ preserve_values (struct objfile *objfile)
preserve_one_value (cur->values[i], objfile, copied_types);
for (var = internalvars; var; var = var->next)
- {
- if (TYPE_OBJFILE (var->type) == objfile)
- var->type = copy_type_recursive (objfile, var->type, copied_types);
-
- switch (TYPE_CODE (var->type))
- {
- case TYPE_CODE_VOID:
- case TYPE_CODE_INTERNAL_FUNCTION:
- case TYPE_CODE_INT:
- case TYPE_CODE_PTR:
- break;
+ preserve_one_internalvar (var, objfile, copied_types);
- default:
- preserve_one_value (var->u.v, objfile, copied_types);
- break;
- }
- }
-
- 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);
}
@@ -1363,6 +1504,7 @@ preserve_values (struct objfile *objfile)
static void
show_convenience (char *ignore, int from_tty)
{
+ struct gdbarch *gdbarch = get_current_arch ();
struct internalvar *var;
int varseen = 0;
struct value_print_options opts;
@@ -1375,7 +1517,7 @@ show_convenience (char *ignore, int from_tty)
varseen = 1;
}
printf_filtered (("$%s = "), var->name);
- value_print (value_of_internalvar (var), gdb_stdout,
+ value_print (value_of_internalvar (gdbarch, var), gdb_stdout,
&opts);
printf_filtered (("\n"));
}
@@ -1419,13 +1561,15 @@ value_as_double (struct value *val)
CORE_ADDR
value_as_address (struct value *val)
{
+ struct gdbarch *gdbarch = get_type_arch (value_type (val));
+
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
#if 0
/* gdbarch_addr_bits_remove is wrong if we are being called for a
non-address (e.g. argument to "signal", "info break", etc.), or
for pointers to char, in which the low bits *are* significant. */
- return gdbarch_addr_bits_remove (current_gdbarch, value_as_long (val));
+ return gdbarch_addr_bits_remove (gdbarch, value_as_long (val));
#else
/* There are several targets (IA-64, PowerPC, and others) which
@@ -1510,8 +1654,8 @@ value_as_address (struct value *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),
+ && gdbarch_integer_to_address_p (gdbarch))
+ return gdbarch_integer_to_address (gdbarch, value_type (val),
value_contents (val));
return unpack_long (value_type (val), value_contents (val));
@@ -1535,6 +1679,7 @@ value_as_address (struct value *val)
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);
@@ -1551,9 +1696,9 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
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);
@@ -1561,7 +1706,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
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:
@@ -1584,6 +1729,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
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;
@@ -1621,7 +1767,7 @@ unpack_double (struct type *type, const gdb_byte *valaddr, int *invp)
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. */
@@ -1735,19 +1881,40 @@ value_primitive_field (struct value *arg1, int offset,
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))
{
@@ -1872,8 +2039,9 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
}
-/* 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,
@@ -1887,23 +2055,30 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
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 (current_gdbarch))
- 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;
@@ -1926,6 +2101,19 @@ unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
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
@@ -1934,8 +2122,10 @@ unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
0 <= BITPOS, where lbits is the size of a LONGEST in bits. */
void
-modify_field (gdb_byte *addr, LONGEST fieldval, int bitpos, int 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);
@@ -1955,16 +2145,16 @@ modify_field (gdb_byte *addr, LONGEST fieldval, int bitpos, int 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 (current_gdbarch))
+ if (gdbarch_bits_big_endian (get_type_arch (type)))
bitpos = sizeof (oword) * 8 - bitpos - bitsize;
oword &= ~(mask << bitpos);
oword |= fieldval << bitpos;
- store_unsigned_integer (addr, sizeof oword, oword);
+ store_unsigned_integer (addr, sizeof oword, byte_order, oword);
}
/* Pack NUM into BUF using a target format of TYPE. */
@@ -1972,6 +2162,7 @@ modify_field (gdb_byte *addr, LONGEST fieldval, int bitpos, int bitsize)
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);
@@ -1986,7 +2177,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
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:
@@ -2020,39 +2211,11 @@ struct value *
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;
}
-/* Create a value for a string constant to be stored locally
- (not in the inferior's memory space, but in GDB memory).
- This is analogous to value_from_longest, which also does not
- use inferior memory. String shall NOT contain embedded nulls. */
-
-struct value *
-value_from_string (char *ptr)
-{
- struct value *val;
- int len = strlen (ptr);
- int lowbound = current_language->string_lower_bound;
- struct type *string_char_type;
- struct type *rangetype;
- struct type *stringtype;
-
- rangetype = create_range_type ((struct type *) NULL,
- builtin_type_int32,
- lowbound, len + lowbound - 1);
- string_char_type = language_string_char_type (current_language,
- current_gdbarch);
- stringtype = create_array_type ((struct type *) NULL,
- string_char_type,
- rangetype);
- val = allocate_value (stringtype);
- memcpy (value_contents_raw (val), ptr, len);
- 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. */
@@ -2200,8 +2363,4 @@ VARIABLE is already initialized."));
add_prefix_cmd ("function", no_class, function_command, _("\
Placeholder command for showing help on convenience functions."),
&functionlist, "function ", 0, &cmdlist);
-
- internal_fn_type = alloc_type (NULL);
- TYPE_CODE (internal_fn_type) = TYPE_CODE_INTERNAL_FUNCTION;
- TYPE_NAME (internal_fn_type) = "";
}