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) = ""; }