diff options
-rw-r--r-- | gdb/ChangeLog | 102 | ||||
-rw-r--r-- | gdb/ada-lang.h | 1 | ||||
-rw-r--r-- | gdb/ada-valprint.c | 101 | ||||
-rw-r--r-- | gdb/c-lang.h | 3 | ||||
-rw-r--r-- | gdb/c-valprint.c | 26 | ||||
-rw-r--r-- | gdb/cp-valprint.c | 59 | ||||
-rw-r--r-- | gdb/d-lang.h | 1 | ||||
-rw-r--r-- | gdb/d-valprint.c | 12 | ||||
-rw-r--r-- | gdb/dwarf2loc.c | 92 | ||||
-rw-r--r-- | gdb/f-lang.h | 1 | ||||
-rw-r--r-- | gdb/f-valprint.c | 22 | ||||
-rw-r--r-- | gdb/infcmd.c | 7 | ||||
-rw-r--r-- | gdb/jv-lang.h | 1 | ||||
-rw-r--r-- | gdb/jv-valprint.c | 15 | ||||
-rw-r--r-- | gdb/language.c | 1 | ||||
-rw-r--r-- | gdb/language.h | 5 | ||||
-rw-r--r-- | gdb/m2-lang.h | 1 | ||||
-rw-r--r-- | gdb/m2-valprint.c | 16 | ||||
-rw-r--r-- | gdb/mi/mi-main.c | 6 | ||||
-rw-r--r-- | gdb/mt-tdep.c | 4 | ||||
-rw-r--r-- | gdb/p-lang.h | 2 | ||||
-rw-r--r-- | gdb/p-valprint.c | 22 | ||||
-rw-r--r-- | gdb/printcmd.c | 2 | ||||
-rw-r--r-- | gdb/python/py-prettyprint.c | 12 | ||||
-rw-r--r-- | gdb/python/python.h | 1 | ||||
-rw-r--r-- | gdb/scm-lang.h | 1 | ||||
-rw-r--r-- | gdb/scm-valprint.c | 8 | ||||
-rw-r--r-- | gdb/sh64-tdep.c | 4 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/pieces.exp | 4 | ||||
-rw-r--r-- | gdb/valops.c | 9 | ||||
-rw-r--r-- | gdb/valprint.c | 64 | ||||
-rw-r--r-- | gdb/valprint.h | 1 | ||||
-rw-r--r-- | gdb/value.c | 65 | ||||
-rw-r--r-- | gdb/value.h | 39 |
35 files changed, 540 insertions, 176 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 84c7466..ba4cd27 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,107 @@ 2010-06-11 Tom Tromey <tromey@redhat.com> + PR gdb/9977, PR exp/11636: + * value.h (value_offset): Update. + (struct lval_funcs) <check_validity>: New field. + <copy_closure>: Make argument const. + (value_computed_closure): Update. + (value_contents_for_printing): Declare. + (value_bits_valid): Likewise. + (val_print): Likewise. + (set_value_component_location): Update. + (value_entirely_optimized_out): Declare. + * value.c (value_offset): Argument now const. + (require_not_optimized_out): New function. + (value_contents_for_printing): New function. + (value_contents_all): Call require_not_optimized_out. + (value_contents): Likewise. + (value_bits_valid): New function. + (value_computed_closure): Argument now const. + (set_value_component_location): Make 'whole' argument const. + (value_entirely_optimized_out): New function. + (value_bitsize): Argument now 'const'. + (value_bitpos): Likewise. + (value_type): Likewise. + * valprint.h (val_print_array_elements): Update. + * valprint.c (val_print): Add 'val' argument. Use + valprint_check_validity. + (valprint_check_validity): New function. + (value_check_printable): Use value_entirely_optimized_out. + (common_val_print): Update. + (value_print): Likewise. + (val_print_array_elements): Add 'val' argument. + * valops.c (value_fetch_lazy): Use value_contents_for_printing, + value_bits_valid. Reinit frame cache for lval_computed. + * sh64-tdep.c (sh64_do_register): Update. + * scm-valprint.c (scm_val_print): Add 'val' argument. + * scm-lang.h (scm_val_print): Update. + * python/python.h (apply_val_pretty_printer): Update. + * python/py-prettyprint.c (apply_val_pretty_printer): Add 'val' + argument. Call set_value_component_location. + * printcmd.c (print_scalar_formatted): Update. + * p-valprint.c (pascal_val_print): Add 'val' argument. + (pascal_object_print_value_fields): Likewise. + (pascal_object_print_value): Likewise. + (pascal_object_print_static_field): Update. + * p-lang.h (pascal_val_print): Update. + (pascal_object_print_value_fields): Update. + * mt-tdep.c (mt_registers_info): Update. + * mi/mi-main.c (get_register): Update. + (mi_cmd_data_evaluate_expression): Use common_val_print. + * m2-valprint.c (m2_print_array_contents): Add 'val' argument. + (m2_print_unbounded_array): Likewise. + (m2_val_print): Likewise. + * m2-lang.h (m2_val_print): Update. + * language.h (struct language_defn) <la_val_print>: Add 'val' + argument. + (LA_VAL_PRINT): Likewise. + * language.c (unk_lang_val_print): Add 'val' argument. + * jv-valprint.c (java_print_value_fields): Add 'val' argument. + (java_val_print): Likewise. + * jv-lang.h (java_val_print): Add 'val' argument. + * infcmd.c (default_print_registers_info): Update. + * f-valprint.c (f77_print_array_1): Add 'val' argument. + (f77_print_array): Likewise. + (f_val_print): Likewise. + * f-lang.h (f_val_print): Add 'val' argument. + * dwarf2loc.c (read_pieced_value): Use value_bitsize and + value_bitpos. + <DWARF_VALUE_OPTIMIZED_OUT>: Don't print warning. Call + set_value_optimized_out. + (write_pieced_value): Use value_bitsize and value_bitpos. + <default>: Don't exit loop. + (check_pieced_value_validity): New function. + (pieced_value_funcs): Reference check_pieced_value_validity, + check_pieced_value_invalid. + (copy_pieced_value_closure): Update. + (check_pieced_value_bits): New function. + (check_pieced_value_invalid): New function. + * d-valprint.c (dynamic_array_type): Add 'val' argument. + (d_val_print): Likewise. + * d-lang.h (d_val_print): Update. + * cp-valprint.c (cp_print_value_fields): Add 'val' argument. + (cp_print_value_fields_rtti): Likewise. + (cp_print_value): Likewise. + (cp_print_static_field): Update. + * c-valprint.c (c_val_print): Add 'val' argument. + (c_value_print): Update. + * c-lang.h (c_val_print): Update. + (cp_print_value_fields): Likewise. + (cp_print_value_fields_rtti): Likewise. + * ada-valprint.c (struct ada_val_print_args): Remove. + (val_print_packed_array_elements): Add 'val' argument. + (ada_val_print): Likewise. Rewrite. + (ada_val_print_stub): Remove. + (ada_val_print_array): Add 'val' argument. + (ada_val_print_1): Likewise. + (print_variant_part): Likewise. + (ada_value_print): Update. + (print_record): Add 'val' argument. + (print_field_values): Likewise. + * ada-lang.h (ada_val_print): Update. + +2010-06-11 Tom Tromey <tromey@redhat.com> + * vec.h (VEC_cleanup): New macro. (DEF_VEC_ALLOC_FUNC_I): Update. (DEF_VEC_ALLOC_FUNC_P): Likewise. diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h index f6b613f..c51964a 100644 --- a/gdb/ada-lang.h +++ b/gdb/ada-lang.h @@ -164,6 +164,7 @@ extern void ada_print_typedef (struct type *type, struct symbol *new_symbol, extern int ada_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); extern int ada_value_print (struct value *, struct ui_file *, diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c index 7e93e3a..2ab2ba2 100644 --- a/gdb/ada-valprint.c +++ b/gdb/ada-valprint.c @@ -36,33 +36,23 @@ #include "exceptions.h" #include "objfiles.h" -/* Encapsulates arguments to ada_val_print. */ -struct ada_val_print_args -{ - struct type *type; - const gdb_byte *valaddr0; - int embedded_offset; - CORE_ADDR address; - struct ui_file *stream; - int recurse; - const struct value_print_options *options; -}; - static void print_record (struct type *, const gdb_byte *, struct ui_file *, - int, const struct value_print_options *); + int, + const struct value *, + const struct value_print_options *); static int print_field_values (struct type *, const gdb_byte *, struct ui_file *, int, + const struct value *, const struct value_print_options *, int, struct type *, const gdb_byte *); static void adjust_type_signedness (struct type *); -static int ada_val_print_stub (void *args0); - static int ada_val_print_1 (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); @@ -146,6 +136,7 @@ static void val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr, int bitoffset, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { unsigned int i; @@ -217,7 +208,7 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr, opts.deref_ref = 0; val_print (elttype, value_contents (v0), 0, 0, stream, - recurse + 1, &opts, current_language); + recurse + 1, val, &opts, current_language); annotate_elt_rep (i - i0); fprintf_filtered (stream, _(" <repeats %u times>"), i - i0); annotate_elt_rep_end (); @@ -247,7 +238,7 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr, stream, options); } val_print (elttype, value_contents (v0), 0, 0, stream, - recurse + 1, &opts, current_language); + recurse + 1, val, &opts, current_language); annotate_elt (); } } @@ -581,30 +572,22 @@ int ada_val_print (struct type *type, const gdb_byte *valaddr0, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { - struct ada_val_print_args args; - args.type = type; - args.valaddr0 = valaddr0; - args.embedded_offset = embedded_offset; - args.address = address; - args.stream = stream; - args.recurse = recurse; - args.options = options; - - return catch_errors (ada_val_print_stub, &args, NULL, RETURN_MASK_ALL); -} + volatile struct gdb_exception except; + int result = 0; -/* Helper for ada_val_print; used as argument to catch_errors to - unmarshal the arguments to ada_val_print_1, which does the work. */ -static int -ada_val_print_stub (void *args0) -{ - struct ada_val_print_args *argsp = (struct ada_val_print_args *) args0; + TRY_CATCH (except, RETURN_MASK_ALL) + { + result = ada_val_print_1 (type, valaddr0, embedded_offset, address, + stream, recurse, val, options); + } - return ada_val_print_1 (argsp->type, argsp->valaddr0, - argsp->embedded_offset, argsp->address, - argsp->stream, argsp->recurse, argsp->options); + if (except.reason < 0) + result = 0; + + return result; } /* Assuming TYPE is a simple array, print the value of this array located @@ -615,6 +598,7 @@ ada_val_print_stub (void *args0) static int ada_val_print_array (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); @@ -663,10 +647,10 @@ ada_val_print_array (struct type *type, const gdb_byte *valaddr, print_optional_low_bound (stream, type, options); if (TYPE_FIELD_BITSIZE (type, 0) > 0) val_print_packed_array_elements (type, valaddr, 0, stream, - recurse, options); + recurse, val, options); else val_print_array_elements (type, valaddr, address, stream, - recurse, options, 0); + recurse, val, options, 0); fprintf_filtered (stream, ")"); } @@ -680,6 +664,7 @@ static int ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *original_value, const struct value_print_options *options) { unsigned int len; @@ -706,7 +691,8 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, } else retn = ada_val_print_1 (value_type (val), value_contents (val), 0, - value_address (val), stream, recurse, options); + value_address (val), stream, recurse, + NULL, options); value_free_to_mark (mark); return retn; } @@ -719,12 +705,12 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, { default: return c_val_print (type, valaddr0, embedded_offset, address, stream, - recurse, options); + recurse, original_value, options); case TYPE_CODE_PTR: { int ret = c_val_print (type, valaddr0, embedded_offset, address, - stream, recurse, options); + stream, recurse, original_value, options); if (ada_is_tag_type (type)) { @@ -765,12 +751,12 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, (type, valaddr, 0)); return ada_val_print_1 (target_type, value_contents (v), 0, 0, - stream, recurse + 1, options); + stream, recurse + 1, NULL, options); } else return ada_val_print_1 (TYPE_TARGET_TYPE (type), valaddr0, embedded_offset, - address, stream, recurse, options); + address, stream, recurse, original_value, options); } else { @@ -855,7 +841,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, case TYPE_CODE_FLT: if (options->format) return c_val_print (type, valaddr0, embedded_offset, address, stream, - recurse, options); + recurse, original_value, options); else ada_print_floating (valaddr0 + embedded_offset, type, stream); break; @@ -869,13 +855,14 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, } else { - print_record (type, valaddr, stream, recurse, options); + print_record (type, valaddr, stream, recurse, original_value, + options); return 0; } case TYPE_CODE_ARRAY: return ada_val_print_array (type, valaddr, address, stream, - recurse, options); + recurse, original_value, options); case TYPE_CODE_REF: /* For references, the debugger is expected to print the value as @@ -899,7 +886,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, val_print (value_type (deref_val), value_contents (deref_val), 0, value_address (deref_val), stream, recurse + 1, - options, current_language); + original_value, options, current_language); } else fputs_filtered ("(null)", stream); @@ -916,6 +903,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, static int print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, int comma_needed, struct type *outer_type, const gdb_byte *outer_valaddr) { @@ -929,7 +917,7 @@ print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr, (TYPE_FIELD_TYPE (var_type, which), valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT, - stream, recurse, options, + stream, recurse, val, options, comma_needed, outer_type, outer_valaddr); } @@ -973,19 +961,20 @@ ada_value_print (struct value *val0, struct ui_file *stream, opts = *options; opts.deref_ref = 1; return (val_print (type, value_contents (val), 0, address, - stream, 0, &opts, current_language)); + stream, 0, val, &opts, current_language)); } static void print_record (struct type *type, const gdb_byte *valaddr, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { type = ada_check_typedef (type); fprintf_filtered (stream, "("); - if (print_field_values (type, valaddr, stream, recurse, options, + if (print_field_values (type, valaddr, stream, recurse, val, options, 0, type, valaddr) != 0 && options->pretty) { fprintf_filtered (stream, "\n"); @@ -1012,6 +1001,7 @@ print_record (struct type *type, const gdb_byte *valaddr, static int print_field_values (struct type *type, const gdb_byte *valaddr, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, int comma_needed, struct type *outer_type, const gdb_byte *outer_valaddr) @@ -1031,7 +1021,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr, print_field_values (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, - stream, recurse, options, + stream, recurse, val, options, comma_needed, type, valaddr); continue; } @@ -1039,7 +1029,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr, { comma_needed = print_variant_part (type, i, valaddr, - stream, recurse, options, comma_needed, + stream, recurse, val, options, comma_needed, outer_type, outer_valaddr); continue; } @@ -1106,7 +1096,8 @@ print_field_values (struct type *type, const gdb_byte *valaddr, opts = *options; opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0, - stream, recurse + 1, &opts, current_language); + stream, recurse + 1, v, + &opts, current_language); } } else @@ -1116,7 +1107,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr, opts.deref_ref = 0; ada_val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, - 0, 0, stream, recurse + 1, &opts); + 0, 0, stream, recurse + 1, val, &opts); } annotate_field_end (); } diff --git a/gdb/c-lang.h b/gdb/c-lang.h index c2cdd56..8da1ff6 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -70,6 +70,7 @@ extern void c_print_typedef (struct type *, struct symbol *, struct ui_file *); extern int c_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); extern int c_value_print (struct value *, struct ui_file *, @@ -104,12 +105,14 @@ extern void cp_print_class_member (const gdb_byte *, struct type *, extern void cp_print_value_fields (struct type *, struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *, struct type **, int); extern void cp_print_value_fields_rtti (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *, struct type **, int); diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 9d2da35..e2a5b95 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -150,6 +150,7 @@ c_textual_element_type (struct type *type, char format) int c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); @@ -177,8 +178,12 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, print_spaces_filtered (2 + 2 * recurse, stream); } - /* Print arrays of textual chars with a string syntax. */ - if (c_textual_element_type (unresolved_elttype, options->format)) + /* Print arrays of textual chars with a string syntax, as + long as the entire array is valid. */ + if (c_textual_element_type (unresolved_elttype, options->format) + && value_bits_valid (original_value, + TARGET_CHAR_BIT * embedded_offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) { /* If requested, look for the first null char and only print elements up to it. */ @@ -217,7 +222,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, i = 0; } val_print_array_elements (type, valaddr + embedded_offset, address, stream, - recurse, options, i); + recurse, original_value, options, i); fprintf_filtered (stream, "}"); } break; @@ -394,7 +399,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, else cp_print_value_fields_rtti (type, valaddr, embedded_offset, address, stream, - recurse, options, NULL, 0); + recurse, original_value, options, NULL, 0); break; case TYPE_CODE_ENUM: @@ -695,9 +700,9 @@ c_value_print (struct value *val, struct ui_file *stream, full ? "" : _(" [incomplete object]")); /* Print out object: enclosing type is same as real_type if full */ return val_print (value_enclosing_type (val), - value_contents_all (val), 0, + value_contents_for_printing (val), 0, value_address (val), stream, 0, - &opts, current_language); + val, &opts, current_language); /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } @@ -707,15 +712,16 @@ c_value_print (struct value *val, struct ui_file *stream, fprintf_filtered (stream, "(%s ?) ", TYPE_NAME (value_enclosing_type (val))); return val_print (value_enclosing_type (val), - value_contents_all (val), 0, + value_contents_for_printing (val), 0, value_address (val), stream, 0, - &opts, current_language); + val, &opts, current_language); } /* Otherwise, we end up at the return outside this "if" */ } - return val_print (val_type, value_contents_all (val), + return val_print (val_type, value_contents_for_printing (val), value_embedded_offset (val), value_address (val), - stream, 0, &opts, current_language); + stream, 0, + val, &opts, current_language); } diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 3fbb1f1..209a752 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -81,6 +81,7 @@ static void cp_print_static_field (struct type *, struct value *, static void cp_print_value (struct type *, struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *, struct type **); @@ -151,6 +152,7 @@ void cp_print_value_fields (struct type *type, struct type *real_type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, struct type **dont_print_vb, int dont_print_statmem) { @@ -177,7 +179,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, if (n_baseclasses > 0) cp_print_value (type, real_type, valaddr, offset, address, stream, - recurse + 1, options, dont_print_vb); + recurse + 1, val, options, dont_print_vb); /* Second, print out data fields */ @@ -278,6 +280,11 @@ cp_print_value_fields (struct type *type, struct type *real_type, { fputs_filtered ("<optimized out or zero length>", stream); } + else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i), + TYPE_FIELD_BITSIZE (type, i))) + { + fputs_filtered (_("<value optimized out>"), stream); + } else { struct value_print_options opts = *options; @@ -315,7 +322,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, val_print (TYPE_FIELD_TYPE (type, i), valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, address, - stream, recurse + 1, &opts, + stream, recurse + 1, val, &opts, current_language); } } @@ -377,26 +384,35 @@ cp_print_value_fields_rtti (struct type *type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, struct type **dont_print_vb, int dont_print_statmem) { - struct value *value; - int full, top, using_enc; - struct type *real_type; - - /* Ugh, we have to convert back to a value here. */ - value = value_from_contents_and_address (type, valaddr + offset, - address + offset); - /* We don't actually care about most of the result here -- just the - type. We already have the correct offset, due to how val_print - was initially called. */ - real_type = value_rtti_type (value, &full, &top, &using_enc); + struct type *real_type = NULL; + + /* We require all bits to be valid in order to attempt a + conversion. */ + if (value_bits_valid (val, TARGET_CHAR_BIT * offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) + { + struct value *value; + int full, top, using_enc; + + /* Ugh, we have to convert back to a value here. */ + value = value_from_contents_and_address (type, valaddr + offset, + address + offset); + /* We don't actually care about most of the result here -- just the + type. We already have the correct offset, due to how val_print + was initially called. */ + real_type = value_rtti_type (value, &full, &top, &using_enc); + } + if (!real_type) real_type = type; cp_print_value_fields (type, real_type, valaddr, offset, - address, stream, recurse, options, + address, stream, recurse, val, options, dont_print_vb, dont_print_statmem); } @@ -407,6 +423,7 @@ static void cp_print_value (struct type *type, struct type *real_type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, struct type **dont_print_vb) { @@ -508,14 +525,14 @@ cp_print_value (struct type *type, struct type *real_type, result = apply_val_pretty_printer (baseclass, base_valaddr, thisoffset + boffset, address, - stream, recurse, + stream, recurse, val, options, current_language); if (!result) cp_print_value_fields (baseclass, thistype, base_valaddr, thisoffset + boffset, address, - stream, recurse, options, + stream, recurse, val, options, ((struct type **) obstack_base (&dont_print_vb_obstack)), 0); @@ -582,9 +599,10 @@ cp_print_static_field (struct type *type, sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); cp_print_value_fields (type, value_enclosing_type (val), - value_contents_all (val), + value_contents_for_printing (val), value_embedded_offset (val), addr, - stream, recurse, options, NULL, 1); + stream, recurse, + val, options, NULL, 1); return; } @@ -616,9 +634,10 @@ cp_print_static_field (struct type *type, opts = *options; opts.deref_ref = 0; - val_print (type, value_contents_all (val), + val_print (type, value_contents_for_printing (val), value_embedded_offset (val), value_address (val), - stream, recurse, &opts, current_language); + stream, recurse, + val, &opts, current_language); } diff --git a/gdb/d-lang.h b/gdb/d-lang.h index be27827..c2ec728 100644 --- a/gdb/d-lang.h +++ b/gdb/d-lang.h @@ -27,6 +27,7 @@ extern char *d_demangle (const char *mangled, int options); extern int d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options); #endif /* !defined (D_LANG_H) */ diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c index ba3f1f0..87edddb 100644 --- a/gdb/d-valprint.c +++ b/gdb/d-valprint.c @@ -31,12 +31,15 @@ static int dynamic_array_type (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { if (TYPE_NFIELDS (type) == 2 && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_INT && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0 - && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0) + && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0 + && value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) { CORE_ADDR addr; struct type *elttype; @@ -60,7 +63,7 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr, ptraddr = value_contents (val); return d_val_print (true_type, ptraddr, 0, addr, stream, recurse + 1, - options); + NULL, options); } return -1; } @@ -69,6 +72,7 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr, int d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { int ret; @@ -78,12 +82,12 @@ d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, { case TYPE_CODE_STRUCT: ret = dynamic_array_type (type, valaddr, embedded_offset, address, - stream, recurse, options); + stream, recurse, val, options); if (ret != -1) break; default: ret = c_val_print (type, valaddr, embedded_offset, address, stream, - recurse, options); + recurse, val, options); } return ret; diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index c5aa024..32d69df 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -490,7 +490,13 @@ read_pieced_value (struct value *v) contents = value_contents_raw (v); bits_to_skip = 8 * value_offset (v); - type_len = 8 * TYPE_LENGTH (value_type (v)); + if (value_bitsize (v)) + { + bits_to_skip += value_bitpos (v); + type_len = value_bitsize (v); + } + else + type_len = 8 * TYPE_LENGTH (value_type (v)); for (i = 0; i < c->n_pieces && offset < type_len; i++) { @@ -614,13 +620,7 @@ read_pieced_value (struct value *v) break; case DWARF_VALUE_OPTIMIZED_OUT: - /* We just leave the bits empty for now. This is not ideal - but gdb currently does not have a nice way to represent - optimized-out pieces. */ - warning (_("bits %ld-%ld in computed object were optimized out; " - "replacing with zeroes"), - offset, - offset + (long) this_size_bits); + set_value_optimized_out (v, 1); break; default: @@ -664,7 +664,14 @@ write_pieced_value (struct value *to, struct value *from) contents = value_contents (from); bits_to_skip = 8 * value_offset (to); - type_len = 8 * TYPE_LENGTH (value_type (to)); + if (value_bitsize (to)) + { + bits_to_skip += value_bitpos (to); + type_len = value_bitsize (to); + } + else + type_len = 8 * TYPE_LENGTH (value_type (to)); + for (i = 0; i < c->n_pieces && offset < type_len; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; @@ -767,17 +774,76 @@ write_pieced_value (struct value *to, struct value *from) break; default: set_value_optimized_out (to, 1); - goto done; + break; } offset += this_size_bits; } - done: do_cleanups (cleanup); } +static int +check_pieced_value_bits (const struct value *value, int bit_offset, + int bit_length, int validity) +{ + struct piece_closure *c + = (struct piece_closure *) value_computed_closure (value); + int i; + + bit_offset += 8 * value_offset (value); + if (value_bitsize (value)) + bit_offset += value_bitpos (value); + + for (i = 0; i < c->n_pieces && bit_length > 0; i++) + { + struct dwarf_expr_piece *p = &c->pieces[i]; + size_t this_size_bits = p->size; + + if (bit_offset > 0) + { + if (bit_offset >= this_size_bits) + { + bit_offset -= this_size_bits; + continue; + } + + bit_length -= this_size_bits - bit_offset; + bit_offset = 0; + } + else + bit_length -= this_size_bits; + + if (p->location == DWARF_VALUE_OPTIMIZED_OUT) + { + if (validity) + return 0; + } + else + { + if (!validity) + return 1; + } + } + + return validity; +} + +static int +check_pieced_value_validity (const struct value *value, int bit_offset, + int bit_length) +{ + return check_pieced_value_bits (value, bit_offset, bit_length, 1); +} + +static int +check_pieced_value_invalid (const struct value *value) +{ + return check_pieced_value_bits (value, 0, + 8 * TYPE_LENGTH (value_type (value)), 0); +} + static void * -copy_pieced_value_closure (struct value *v) +copy_pieced_value_closure (const struct value *v) { struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); @@ -802,6 +868,8 @@ free_pieced_value_closure (struct value *v) static struct lval_funcs pieced_value_funcs = { read_pieced_value, write_pieced_value, + check_pieced_value_validity, + check_pieced_value_invalid, copy_pieced_value_closure, free_pieced_value_closure }; diff --git a/gdb/f-lang.h b/gdb/f-lang.h index 094d6fa..ee3d91f 100644 --- a/gdb/f-lang.h +++ b/gdb/f-lang.h @@ -30,6 +30,7 @@ extern void f_print_type (struct type *, char *, struct ui_file *, int, extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); /* Language-specific data structures */ diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index acd6487..4db0b27 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -164,6 +164,7 @@ static void f77_print_array_1 (int nss, int ndimensions, struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, int *elts) { @@ -177,7 +178,7 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type), valaddr + i * F77_DIM_OFFSET (nss), address + i * F77_DIM_OFFSET (nss), - stream, recurse, options, elts); + stream, recurse, val, options, elts); fprintf_filtered (stream, ") "); } if (*elts >= options->print_max && i < F77_DIM_SIZE (nss)) @@ -192,7 +193,7 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, valaddr + i * F77_DIM_OFFSET (ndimensions), 0, address + i * F77_DIM_OFFSET (ndimensions), - stream, recurse, options, current_language); + stream, recurse, val, options, current_language); if (i != (F77_DIM_SIZE (nss) - 1)) fprintf_filtered (stream, ", "); @@ -210,7 +211,9 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, static void f77_print_array (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, - int recurse, const struct value_print_options *options) + int recurse, + const struct value *val, + const struct value_print_options *options) { int ndimensions; int elts = 0; @@ -228,7 +231,7 @@ f77_print_array (struct type *type, const gdb_byte *valaddr, f77_create_arrayprint_offset_tbl (type, stream); f77_print_array_1 (1, ndimensions, type, valaddr, address, stream, - recurse, options, &elts); + recurse, val, options, &elts); } @@ -242,6 +245,7 @@ f77_print_array (struct type *type, const gdb_byte *valaddr, int f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); @@ -263,7 +267,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, case TYPE_CODE_ARRAY: fprintf_filtered (stream, "("); - f77_print_array (type, valaddr, address, stream, recurse, options); + f77_print_array (type, valaddr, address, stream, recurse, original_value, options); fprintf_filtered (stream, ")"); break; @@ -424,7 +428,8 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, { /* Bash the type code temporarily. */ TYPE_CODE (type) = TYPE_CODE_INT; - f_val_print (type, valaddr, 0, address, stream, recurse, options); + val_print (type, valaddr, 0, address, stream, recurse, + original_value, options, current_language); /* Restore the type code so later uses work as intended. */ TYPE_CODE (type) = TYPE_CODE_BOOL; } @@ -456,8 +461,9 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, { int offset = TYPE_FIELD_BITPOS (type, index) / 8; - f_val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset, - embedded_offset, address, stream, recurse, options); + val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset, + embedded_offset, address, stream, recurse + 1, + original_value, options, current_language); if (index != TYPE_NFIELDS (type) - 1) fputs_filtered (", ", stream); } diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 5ada1e8..4a91a40 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1957,7 +1957,7 @@ default_print_registers_info (struct gdbarch *gdbarch, get_user_print_options (&opts); opts.deref_ref = 1; val_print (register_type (gdbarch, i), buffer, 0, 0, - file, 0, &opts, current_language); + file, 0, NULL, &opts, current_language); fprintf_filtered (file, "\t(raw 0x"); for (j = 0; j < register_size (gdbarch, i); j++) @@ -1980,8 +1980,7 @@ default_print_registers_info (struct gdbarch *gdbarch, get_formatted_print_options (&opts, 'x'); opts.deref_ref = 1; val_print (register_type (gdbarch, i), buffer, 0, 0, - file, 0, &opts, - current_language); + file, 0, NULL, &opts, current_language); /* If not a vector register, print it also according to its natural format. */ if (TYPE_VECTOR (register_type (gdbarch, i)) == 0) @@ -1990,7 +1989,7 @@ default_print_registers_info (struct gdbarch *gdbarch, opts.deref_ref = 1; fprintf_filtered (file, "\t"); val_print (register_type (gdbarch, i), buffer, 0, 0, - file, 0, &opts, current_language); + file, 0, NULL, &opts, current_language); } } diff --git a/gdb/jv-lang.h b/gdb/jv-lang.h index 95d6384..24ca61e 100644 --- a/gdb/jv-lang.h +++ b/gdb/jv-lang.h @@ -44,6 +44,7 @@ extern const struct builtin_java_type *builtin_java_type (struct gdbarch *); extern int java_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); extern int java_value_print (struct value *, struct ui_file *, diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c index 165f14e..1819b50 100644 --- a/gdb/jv-valprint.c +++ b/gdb/jv-valprint.c @@ -259,6 +259,7 @@ static void java_print_value_fields (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { int i, len, n_baseclasses; @@ -302,7 +303,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr, base_valaddr = valaddr; java_print_value_fields (baseclass, base_valaddr, address + boffset, - stream, recurse + 1, options); + stream, recurse + 1, val, options); fputs_filtered (", ", stream); } @@ -392,6 +393,11 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr, { fputs_filtered ("<optimized out or zero length>", stream); } + else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i), + TYPE_FIELD_BITSIZE (type, i))) + { + fputs_filtered (_("<value optimized out>"), stream); + } else { struct value_print_options opts; @@ -440,7 +446,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr, val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0, address + TYPE_FIELD_BITPOS (type, i) / 8, - stream, recurse + 1, &opts, + stream, recurse + 1, val, &opts, current_language); } } @@ -467,6 +473,7 @@ int java_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); @@ -543,12 +550,12 @@ java_val_print (struct type *type, const gdb_byte *valaddr, case TYPE_CODE_STRUCT: java_print_value_fields (type, valaddr, address, stream, recurse, - options); + val, options); break; default: return c_val_print (type, valaddr, embedded_offset, address, stream, - recurse, options); + recurse, val, options); } return 0; diff --git a/gdb/language.c b/gdb/language.c index c20d7c0..90bb228 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -1107,6 +1107,7 @@ static int unk_lang_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { error (_("internal error - unimplemented function unk_lang_val_print called.")); diff --git a/gdb/language.h b/gdb/language.h index 9306a82..0c04208 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -233,6 +233,7 @@ struct language_defn const gdb_byte *contents, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options); /* Print a top-level value using syntax appropriate for this language. */ @@ -401,9 +402,9 @@ extern enum language set_language (enum language); #define LA_PRINT_TYPEDEF(type,new_symbol,stream) \ (current_language->la_print_typedef(type,new_symbol,stream)) -#define LA_VAL_PRINT(type,valaddr,offset,addr,stream,recurse,options) \ +#define LA_VAL_PRINT(type,valaddr,offset,addr,stream,val,recurse,options) \ (current_language->la_val_print(type,valaddr,offset,addr,stream, \ - recurse,options)) + val,recurse,options)) #define LA_VALUE_PRINT(val,stream,options) \ (current_language->la_value_print(val,stream,options)) diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h index 75623e2..161b4b6 100644 --- a/gdb/m2-lang.h +++ b/gdb/m2-lang.h @@ -34,6 +34,7 @@ extern int m2_is_unbounded_array (struct type *type); extern int m2_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); extern int get_long_set_bounds (struct type *type, LONGEST *low, diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c index edfd324..95a7a93 100644 --- a/gdb/m2-valprint.c +++ b/gdb/m2-valprint.c @@ -38,6 +38,7 @@ static void m2_print_array_contents (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, int len); @@ -202,7 +203,7 @@ m2_print_unbounded_array (struct type *type, const gdb_byte *valaddr, fprintf_filtered (stream, "{"); m2_print_array_contents (value_type (val), value_contents(val), value_embedded_offset (val), addr, stream, - recurse, options, len); + recurse, NULL, options, len); fprintf_filtered (stream, ", HIGH = %d}", (int) len); } @@ -277,6 +278,7 @@ static void m2_print_array_contents (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, int len) { @@ -299,7 +301,8 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr, { fprintf_filtered (stream, "{"); val_print_array_elements (type, valaddr + embedded_offset, - address, stream, recurse, options, 0); + address, stream, recurse, val, + options, 0); fprintf_filtered (stream, "}"); } } @@ -316,6 +319,7 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr, int m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); @@ -367,7 +371,8 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, { fprintf_filtered (stream, "{"); val_print_array_elements (type, valaddr + embedded_offset, - address, stream, recurse, options, 0); + address, stream, recurse, original_value, + options, 0); fprintf_filtered (stream, "}"); } break; @@ -436,7 +441,8 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, address, stream, recurse, options); else cp_print_value_fields (type, type, valaddr, embedded_offset, - address, stream, recurse, options, NULL, 0); + address, stream, recurse, original_value, + options, NULL, 0); break; case TYPE_CODE_ENUM: @@ -508,7 +514,7 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) { m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset, - address, stream, recurse, options); + address, stream, recurse, original_value, options); break; } /* FIXME: create_range_type does not set the unsigned bit in a diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index ec6753d..85a3f99 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1131,7 +1131,7 @@ get_register (struct frame_info *frame, int regnum, int format) get_formatted_print_options (&opts, format); opts.deref_ref = 1; val_print (register_type (gdbarch, regnum), buffer, 0, 0, - stb->stream, 0, &opts, current_language); + stb->stream, 0, NULL, &opts, current_language); ui_out_field_stream (uiout, "value", stb); ui_out_stream_delete (stb); } @@ -1222,9 +1222,7 @@ mi_cmd_data_evaluate_expression (char *command, char **argv, int argc) /* Print the result of the expression evaluation. */ get_user_print_options (&opts); opts.deref_ref = 0; - val_print (value_type (val), value_contents (val), - value_embedded_offset (val), value_address (val), - stb->stream, 0, &opts, current_language); + common_val_print (val, stb->stream, 0, &opts, current_language); ui_out_field_stream (uiout, "value", stb); ui_out_stream_delete (stb); diff --git a/gdb/mt-tdep.c b/gdb/mt-tdep.c index 1548151..e8ea5bc 100644 --- a/gdb/mt-tdep.c +++ b/gdb/mt-tdep.c @@ -710,8 +710,8 @@ mt_registers_info (struct gdbarch *gdbarch, get_raw_print_options (&opts); opts.deref_ref = 1; val_print (register_type (gdbarch, regnum), buf, - 0, 0, file, 0, &opts, - current_language); + 0, 0, file, 0, NULL, + &opts, current_language); fputs_filtered ("\n", file); } else if (regnum == MT_MAC_REGNUM || regnum == MT_MAC_PSEUDOREG_REGNUM) diff --git a/gdb/p-lang.h b/gdb/p-lang.h index 4090caa..0ea2fc9 100644 --- a/gdb/p-lang.h +++ b/gdb/p-lang.h @@ -37,6 +37,7 @@ extern void pascal_print_typedef (struct type *, struct symbol *, extern int pascal_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); extern int pascal_value_print (struct value *, struct ui_file *, @@ -70,6 +71,7 @@ extern void extern void pascal_object_print_value_fields (struct type *, const gdb_byte *, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *, struct type **, int); diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c index e58f9d2..3d00a69 100644 --- a/gdb/p-valprint.c +++ b/gdb/p-valprint.c @@ -54,6 +54,7 @@ int pascal_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); @@ -125,7 +126,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, i = 0; } val_print_array_elements (type, valaddr + embedded_offset, address, stream, - recurse, options, i); + recurse, original_value, options, i); fprintf_filtered (stream, "}"); } break; @@ -317,7 +318,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, } else pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream, - recurse, options, NULL, 0); + recurse, original_value, options, NULL, 0); } break; @@ -611,6 +612,7 @@ static void pascal_object_print_static_field (struct value *, static void pascal_object_print_value (struct type *, const gdb_byte *, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *, struct type **); @@ -668,6 +670,7 @@ void pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, struct type **dont_print_vb, int dont_print_statmem) @@ -685,7 +688,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, duplicates of virtual baseclasses. */ if (n_baseclasses > 0) pascal_object_print_value (type, valaddr, address, stream, - recurse + 1, options, dont_print_vb); + recurse + 1, val, options, dont_print_vb); if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); @@ -774,6 +777,11 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, { fputs_filtered ("<optimized out or zero length>", stream); } + else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i), + TYPE_FIELD_BITSIZE (type, i))) + { + fputs_filtered (_("<value optimized out>"), stream); + } else { struct value_print_options opts = *options; @@ -818,7 +826,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, val_print (TYPE_FIELD_TYPE (type, i), valaddr, TYPE_FIELD_BITPOS (type, i) / 8, address + TYPE_FIELD_BITPOS (type, i) / 8, - stream, recurse + 1, &opts, + stream, recurse + 1, val, &opts, current_language); } } @@ -849,6 +857,7 @@ static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, struct type **dont_print_vb) { @@ -923,7 +932,7 @@ pascal_object_print_value (struct type *type, const gdb_byte *valaddr, fprintf_filtered (stream, "<invalid address>"); else pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset, - stream, recurse, options, + stream, recurse, val, options, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); @@ -987,7 +996,8 @@ pascal_object_print_static_field (struct value *val, CHECK_TYPEDEF (type); pascal_object_print_value_fields (type, value_contents (val), addr, - stream, recurse, options, NULL, 1); + stream, recurse, NULL, options, + NULL, 1); return; } diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 58cb1f6..42aff63 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -374,7 +374,7 @@ print_scalar_formatted (const void *valaddr, struct type *type, struct value_print_options opts = *options; opts.format = 0; opts.deref_ref = 0; - val_print (type, valaddr, 0, 0, stream, 0, &opts, + val_print (type, valaddr, 0, 0, stream, 0, NULL, &opts, current_language); return; } diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index 4d60c96..9a205b4 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -603,6 +603,7 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, const struct language_defn *language) { @@ -621,6 +622,16 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, valaddr += embedded_offset; value = value_from_contents_and_address (type, valaddr, address + embedded_offset); + if (val != NULL) + { + set_value_component_location (value, val); + /* set_value_component_location resets the address, so we may + need to set it again. */ + if (VALUE_LVAL (value) != lval_internalvar + && VALUE_LVAL (value) != lval_internalvar_component + && VALUE_LVAL (value) != lval_computed) + set_value_address (value, address + embedded_offset); + } val_obj = value_to_value_object (value); if (! val_obj) @@ -735,6 +746,7 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, const struct language_defn *language) { diff --git a/gdb/python/python.h b/gdb/python/python.h index ae808c0..affd4a4 100644 --- a/gdb/python/python.h +++ b/gdb/python/python.h @@ -31,6 +31,7 @@ void source_python_script (FILE *stream, const char *file); int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, const struct language_defn *language); diff --git a/gdb/scm-lang.h b/gdb/scm-lang.h index bcb29d8..1adeee5 100644 --- a/gdb/scm-lang.h +++ b/gdb/scm-lang.h @@ -50,6 +50,7 @@ extern int scm_value_print (struct value *, struct ui_file *, extern int scm_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *); extern LONGEST scm_get_field (LONGEST, int, int, enum bfd_endian); diff --git a/gdb/scm-valprint.c b/gdb/scm-valprint.c index 8000c78..c5e1ce1 100644 --- a/gdb/scm-valprint.c +++ b/gdb/scm-valprint.c @@ -422,9 +422,12 @@ int scm_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options) { - if (is_scmvalue_type (type)) + if (is_scmvalue_type (type) + && value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); LONGEST svalue @@ -443,7 +446,8 @@ scm_val_print (struct type *type, const gdb_byte *valaddr, } else { - return c_val_print (type, valaddr, 0, address, stream, recurse, options); + return c_val_print (type, valaddr, 0, address, stream, recurse, + val, options); } } diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c index 8d7782a..6267541 100644 --- a/gdb/sh64-tdep.c +++ b/gdb/sh64-tdep.c @@ -2121,12 +2121,12 @@ sh64_do_register (struct gdbarch *gdbarch, struct ui_file *file, get_formatted_print_options (&opts, 'x'); opts.deref_ref = 1; val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0, - file, 0, &opts, current_language); + file, 0, NULL, &opts, current_language); fprintf_filtered (file, "\t"); get_formatted_print_options (&opts, 0); opts.deref_ref = 1; val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0, - file, 0, &opts, current_language); + file, 0, NULL, &opts, current_language); fprintf_filtered (file, "\n"); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3e5e494..d239152 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-06-11 Tom Tromey <tromey@redhat.com> + + PR gdb/9977, PR exp/11636:: + * gdb.dwarf2/pieces.exp (pieces_test_f3): Remove kfail. + (pieces_test_f6): Update expected output. + 2010-06-11 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/moribund-step.exp: New. diff --git a/gdb/testsuite/gdb.dwarf2/pieces.exp b/gdb/testsuite/gdb.dwarf2/pieces.exp index 4264d69..1e3ef7f 100644 --- a/gdb/testsuite/gdb.dwarf2/pieces.exp +++ b/gdb/testsuite/gdb.dwarf2/pieces.exp @@ -76,8 +76,6 @@ proc pieces_test_f3 {} { gdb_continue_to_breakpoint "continue to f3 breakpoint for pieces" gdb_test "print a.i" " = 4" "print a.i in pieces:f3" gdb_test "print a.j" " = 14" "print a.j in pieces:f3" - # Right now gdb says "value optimized out" here, but that is wrong. - setup_kfail "exp/11636" *-*-* gdb_test "print a.i = 7" " = 7" "set a.i in pieces:f3" gdb_test "print a.i" " = 7" "print new a.i in pieces:f3" } @@ -90,7 +88,7 @@ proc pieces_test_f6 {} { "set f6 breakpoint for pieces" gdb_continue_to_breakpoint "continue to f6 breakpoint for pieces" gdb_test "print a" \ - "warning: bits .* in computed object were.* = {i = 7, j = 8, q = 0}" \ + " = {i = 7, j = 8, q = .value optimized out.}" \ "print a with optimized out piece" # Note: no warning for this case. gdb_test_multiple "print a.i" \ diff --git a/gdb/valops.c b/gdb/valops.c index 08a64ce..506d40e 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -941,11 +941,17 @@ value_fetch_lazy (struct value *val) struct value *parent = value_parent (val); LONGEST offset = value_offset (val); LONGEST num = unpack_bits_as_long (value_type (val), - value_contents (parent) + offset, + (value_contents_for_printing (parent) + + offset), value_bitpos (val), value_bitsize (val)); int length = TYPE_LENGTH (type); + if (!value_bits_valid (val, + TARGET_CHAR_BIT * offset + value_bitpos (val), + value_bitsize (val))) + error (_("value has been optimized out")); + store_signed_integer (value_contents_raw (val), length, byte_order, num); } else if (VALUE_LVAL (val) == lval_memory) @@ -1246,6 +1252,7 @@ value_assign (struct value *toval, struct value *fromval) { case lval_memory: case lval_register: + case lval_computed: reinit_frame_cache (); diff --git a/gdb/valprint.c b/gdb/valprint.c index 2b06579..ad6268e 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -245,6 +245,39 @@ scalar_type_p (struct type *type) } } +/* Helper function to check the validity of some bits of a value. + + If TYPE represents some aggregate type (e.g., a structure), return 1. + + Otherwise, any of the bytes starting at OFFSET and extending for + TYPE_LENGTH(TYPE) bytes are invalid, print a message to STREAM and + return 0. The checking is done using FUNCS. + + Otherwise, return 1. */ + +static int +valprint_check_validity (struct ui_file *stream, + struct type *type, + int offset, + const struct value *val) +{ + CHECK_TYPEDEF (type); + + if (TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_ARRAY) + { + if (! value_bits_valid (val, TARGET_CHAR_BIT * offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) + { + fprintf_filtered (stream, _("<value optimized out>")); + return 0; + } + } + + return 1; +} + /* Print using the given LANGUAGE the data of type TYPE located at VALADDR (within GDB), which came from the inferior at address ADDRESS, onto stdio stream STREAM according to OPTIONS. @@ -263,6 +296,7 @@ scalar_type_p (struct type *type) int val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, const struct language_defn *language) { @@ -283,16 +317,19 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, if (TYPE_STUB (real_type)) { - fprintf_filtered (stream, "<incomplete type>"); + fprintf_filtered (stream, _("<incomplete type>")); gdb_flush (stream); return (0); } + if (!valprint_check_validity (stream, real_type, embedded_offset, val)) + return 0; + if (!options->raw) { ret = apply_val_pretty_printer (type, valaddr, embedded_offset, - address, stream, recurse, options, - language); + address, stream, recurse, + val, options, language); if (ret) return ret; } @@ -308,7 +345,8 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, TRY_CATCH (except, RETURN_MASK_ERROR) { ret = language->la_val_print (type, valaddr, embedded_offset, address, - stream, recurse, &local_opts); + stream, recurse, val, + &local_opts); } if (except.reason < 0) fprintf_filtered (stream, _("<error reading variable>")); @@ -329,7 +367,7 @@ value_check_printable (struct value *val, struct ui_file *stream) return 0; } - if (value_optimized_out (val)) + if (value_entirely_optimized_out (val)) { fprintf_filtered (stream, _("<value optimized out>")); return 0; @@ -369,9 +407,10 @@ common_val_print (struct value *val, struct ui_file *stream, int recurse, get a fixed representation of our value. */ val = ada_to_fixed_value (val); - return val_print (value_type (val), value_contents_all (val), + return val_print (value_type (val), value_contents_for_printing (val), value_embedded_offset (val), value_address (val), - stream, recurse, options, language); + stream, recurse, + val, options, language); } /* Print on stream STREAM the value VAL according to OPTIONS. The value @@ -390,11 +429,11 @@ value_print (struct value *val, struct ui_file *stream, if (!options->raw) { int r = apply_val_pretty_printer (value_type (val), - value_contents_all (val), + value_contents_for_printing (val), value_embedded_offset (val), value_address (val), - stream, 0, options, - current_language); + stream, 0, + val, options, current_language); if (r) return r; @@ -1097,6 +1136,7 @@ void val_print_array_elements (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, unsigned int i) { @@ -1175,7 +1215,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, if (reps > options->repeat_count_threshold) { val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen, - stream, recurse + 1, options, current_language); + stream, recurse + 1, val, options, current_language); annotate_elt_rep (reps); fprintf_filtered (stream, " <repeats %u times>", reps); annotate_elt_rep_end (); @@ -1186,7 +1226,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, else { val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen, - stream, recurse + 1, options, current_language); + stream, recurse + 1, val, options, current_language); annotate_elt (); things_printed++; } diff --git a/gdb/valprint.h b/gdb/valprint.h index 070d796..6e339d1 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -118,6 +118,7 @@ extern void maybe_print_array_index (struct type *index_type, LONGEST index, extern void val_print_array_elements (struct type *, const gdb_byte *, CORE_ADDR, struct ui_file *, int, + const struct value *, const struct value_print_options *, unsigned int); diff --git a/gdb/value.c b/gdb/value.c index ec33403..5e0e8d8 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -349,7 +349,7 @@ value_next (struct value *value) } struct type * -value_type (struct value *value) +value_type (const struct value *value) { return value->type; } @@ -360,7 +360,7 @@ deprecated_set_value_type (struct value *value, struct type *type) } int -value_offset (struct value *value) +value_offset (const struct value *value) { return value->offset; } @@ -371,7 +371,7 @@ set_value_offset (struct value *value, int offset) } int -value_bitpos (struct value *value) +value_bitpos (const struct value *value) { return value->bitpos; } @@ -382,7 +382,7 @@ set_value_bitpos (struct value *value, int bit) } int -value_bitsize (struct value *value) +value_bitsize (const struct value *value) { return value->bitsize; } @@ -418,14 +418,29 @@ value_enclosing_type (struct value *value) return value->enclosing_type; } +static void +require_not_optimized_out (struct value *value) +{ + if (value->optimized_out) + error (_("value has been optimized out")); +} + const gdb_byte * -value_contents_all (struct value *value) +value_contents_for_printing (struct value *value) { if (value->lazy) value_fetch_lazy (value); return value->contents; } +const gdb_byte * +value_contents_all (struct value *value) +{ + const gdb_byte *result = value_contents_for_printing (value); + require_not_optimized_out (value); + return result; +} + int value_lazy (struct value *value) { @@ -453,7 +468,9 @@ set_value_stack (struct value *value, int val) const gdb_byte * value_contents (struct value *value) { - return value_contents_writeable (value); + const gdb_byte *result = value_contents_writeable (value); + require_not_optimized_out (value); + return result; } gdb_byte * @@ -497,6 +514,29 @@ set_value_optimized_out (struct value *value, int val) } int +value_entirely_optimized_out (const struct value *value) +{ + if (!value->optimized_out) + return 0; + if (value->lval != lval_computed + || !value->location.computed.funcs->check_validity) + return 1; + return value->location.computed.funcs->check_all_valid (value); +} + +int +value_bits_valid (const struct value *value, int offset, int length) +{ + if (value == NULL || !value->optimized_out) + return 1; + if (value->lval != lval_computed + || !value->location.computed.funcs->check_validity) + return 0; + return value->location.computed.funcs->check_validity (value, offset, + length); +} + +int value_embedded_offset (struct value *value) { return value->embedded_offset; @@ -529,9 +569,9 @@ value_computed_funcs (struct value *v) } void * -value_computed_closure (struct value *v) +value_computed_closure (const struct value *v) { - gdb_assert (VALUE_LVAL (v) == lval_computed); + gdb_assert (v->lval == lval_computed); return v->location.computed.closure; } @@ -771,15 +811,16 @@ value_copy (struct value *arg) } void -set_value_component_location (struct value *component, struct value *whole) +set_value_component_location (struct value *component, + const struct value *whole) { - if (VALUE_LVAL (whole) == lval_internalvar) + if (whole->lval == lval_internalvar) VALUE_LVAL (component) = lval_internalvar_component; else - VALUE_LVAL (component) = VALUE_LVAL (whole); + VALUE_LVAL (component) = whole->lval; component->location = whole->location; - if (VALUE_LVAL (whole) == lval_computed) + if (whole->lval == lval_computed) { struct lval_funcs *funcs = whole->location.computed.funcs; diff --git a/gdb/value.h b/gdb/value.h index 7f71dc4..c3dfb17 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -50,7 +50,7 @@ struct value *value_next (struct value *); /* Type of the value. */ -extern struct type *value_type (struct value *); +extern struct type *value_type (const struct value *); /* This is being used to change the type of an existing value, that code should instead be creating a new value with the changed type @@ -61,14 +61,14 @@ extern void deprecated_set_value_type (struct value *value, /* Only used for bitfields; number of bits contained in them. */ -extern int value_bitsize (struct value *); +extern int value_bitsize (const struct value *); extern void set_value_bitsize (struct value *, int bit); /* Only used for bitfields; position of start of field. For 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. */ -extern int value_bitpos (struct value *); +extern int value_bitpos (const struct value *); extern void set_value_bitpos (struct value *, int bit); /* Only used for bitfields; the containing value. This allows a @@ -83,7 +83,7 @@ struct value *value_parent (struct value *); within the registers structure. Note also the member embedded_offset below. */ -extern int value_offset (struct value *); +extern int value_offset (const struct value *); extern void set_value_offset (struct value *, int offset); /* The comment from "struct value" reads: ``Is it modifiable? Only @@ -164,13 +164,21 @@ struct lval_funcs should call 'error'. */ void (*write) (struct value *toval, struct value *fromval); + /* Check the validity of some bits in VALUE. This should return 1 + if all the bits starting at OFFSET and extending for LENGTH bits + are valid, or 0 if any bit is invalid. */ + int (*check_validity) (const struct value *value, int offset, int length); + + /* Return 1 if any bit in VALUE is valid, 0 if they are all invalid. */ + int (*check_all_valid) (const struct value *value); + /* Return a duplicate of VALUE's closure, for use in a new value. This may simply return the same closure, if VALUE's is reference-counted or statically allocated. This may be NULL, in which case VALUE's closure is re-used in the new value. */ - void *(*copy_closure) (struct value *v); + void *(*copy_closure) (const struct value *v); /* Drop VALUE's reference to its closure. Maybe this frees the closure; maybe this decrements a reference count; maybe the @@ -195,7 +203,7 @@ extern struct lval_funcs *value_computed_funcs (struct value *value); /* If VALUE is lval_computed, return its closure. The meaning of the returned value depends on the functions VALUE uses. */ -extern void *value_computed_closure (struct value *value); +extern void *value_computed_closure (const struct value *value); /* If zero, contents of this value are in the contents field. If nonzero, contents are in inferior. If the lval field is lval_memory, @@ -249,6 +257,11 @@ extern gdb_byte *value_contents_writeable (struct value *); extern gdb_byte *value_contents_all_raw (struct value *); extern const gdb_byte *value_contents_all (struct value *); +/* Like value_contents_all, but does not require that the returned + bits be valid. This should only be used in situations where you + plan to check the validity manually. */ +extern const gdb_byte *value_contents_for_printing (struct value *value); + extern int value_fetch_lazy (struct value *val); extern int value_contents_equal (struct value *val1, struct value *val2); @@ -257,6 +270,10 @@ extern int value_contents_equal (struct value *val1, struct value *val2); extern int value_optimized_out (struct value *value); extern void set_value_optimized_out (struct value *value, int val); +/* Like value_optimized_out, but return false if any bit in the object + is valid. */ +extern int value_entirely_optimized_out (const struct value *value); + /* Set or return field indicating whether a variable is initialized or not, based on debugging information supplied by the compiler. 1 = initialized; 0 = uninitialized. */ @@ -266,7 +283,7 @@ extern void set_value_initialized (struct value *, int); /* Set COMPONENT's location as appropriate for a component of WHOLE --- regardless of what kind of lvalue WHOLE is. */ extern void set_value_component_location (struct value *component, - struct value *whole); + const struct value *whole); /* While the following fields are per- VALUE .CONTENT .PIECE (i.e., a single value might have multiple LVALs), this hacked interface is @@ -313,6 +330,13 @@ extern struct value *coerce_ref (struct value *value); extern struct value *coerce_array (struct value *value); +/* Given a value, determine whether the bits starting at OFFSET and + extending for LENGTH bits are valid. This returns nonzero if all + bits in the given range are valid, zero if any bit is invalid. */ + +extern int value_bits_valid (const struct value *value, + int offset, int length); + #include "symtab.h" @@ -647,6 +671,7 @@ extern struct value *value_release_to_mark (struct value *mark); extern int val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, + const struct value *val, const struct value_print_options *options, const struct language_defn *language); |