X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalue.c;h=a462ee494495faa1408796591d1b73c000f536a1;hb=3c83b96e241336be0c3e26c06f2bf901d0fe8edd;hp=fffc183af07564884b291c4fb02aefc1f6c72ad3;hpb=e17a4113357102b55cfa5b80557d590a46a43300;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/value.c b/gdb/value.c index fffc183af0..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. @@ -108,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; @@ -191,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. */ @@ -238,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; @@ -259,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; } @@ -296,31 +323,6 @@ allocate_repeat_value (struct type *type, int count) 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; - } -} - struct value * allocate_computed_value (struct type *type, struct lval_funcs *funcs, @@ -387,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) { @@ -427,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) { @@ -583,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; @@ -618,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) @@ -710,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; @@ -897,8 +944,11 @@ struct internalvar /* 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, @@ -921,19 +971,22 @@ struct internalvar 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; @@ -1059,16 +1112,16 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *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: @@ -1122,14 +1175,9 @@ get_internalvar_integer (struct internalvar *var, LONGEST *result) { 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; @@ -1201,15 +1249,15 @@ set_internalvar (struct internalvar *var, struct value *val) 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: @@ -1246,9 +1294,9 @@ set_internalvar_integer (struct internalvar *var, LONGEST l) /* 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 @@ -1382,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) { @@ -1403,10 +1451,16 @@ preserve_one_internalvar (struct internalvar *var, struct objfile *objfile, { 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: @@ -1442,8 +1496,7 @@ preserve_values (struct objfile *objfile) 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); } @@ -1828,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)) { @@ -1965,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, @@ -1980,25 +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 (type)); + 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), byte_order); - 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; @@ -2021,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 @@ -2118,7 +2211,7 @@ 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; }