X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalprint.c;h=720942b85e74d55561c98dba0ed344d5f26e57f4;hb=73e6209faecc21516a981ed86a27b259f506098c;hp=ecc3411b6e7dc6447fd8d12de391f098ac47e09a;hpb=f380848e84613364a17008f04e91bfef09eaf158;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valprint.c b/gdb/valprint.c index ecc3411b6e..720942b85e 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1,6 +1,6 @@ /* Print values for GDB, the GNU debugger. - Copyright (C) 1986-2013 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -18,7 +18,6 @@ along with this program. If not, see . */ #include "defs.h" -#include #include "symtab.h" #include "gdbtypes.h" #include "value.h" @@ -30,16 +29,14 @@ #include "valprint.h" #include "floatformat.h" #include "doublest.h" -#include "exceptions.h" #include "dfp.h" -#include "python/python.h" +#include "extension.h" #include "ada-lang.h" #include "gdb_obstack.h" #include "charset.h" +#include "typeprint.h" #include -#include - /* Maximum number of wchars returned from wchar_iterate. */ #define MAX_WCHARS 4 @@ -101,6 +98,10 @@ static void set_output_radix (char *, int, struct cmd_list_element *); static void set_output_radix_1 (int, unsigned); +static void val_print_type_code_flags (struct type *type, + const gdb_byte *valaddr, + struct ui_file *stream); + void _initialize_valprint (void); #define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */ @@ -278,11 +279,11 @@ show_symbol_print (struct ui_file *file, int from_tty, int val_print_scalar_type_p (struct type *type) { - CHECK_TYPEDEF (type); + type = check_typedef (type); while (TYPE_CODE (type) == TYPE_CODE_REF) { type = TYPE_TARGET_TYPE (type); - CHECK_TYPEDEF (type); + type = check_typedef (type); } switch (TYPE_CODE (type)) { @@ -305,14 +306,27 @@ valprint_check_validity (struct ui_file *stream, int embedded_offset, const struct value *val) { - CHECK_TYPEDEF (type); + type = check_typedef (type); + + if (type_not_associated (type)) + { + val_print_not_associated (stream); + return 0; + } + + if (type_not_allocated (type)) + { + val_print_not_allocated (stream); + return 0; + } 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 * embedded_offset, - TARGET_CHAR_BIT * TYPE_LENGTH (type))) + if (value_bits_any_optimized_out (val, + TARGET_CHAR_BIT * embedded_offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) { val_print_optimized_out (val, stream); return 0; @@ -339,11 +353,17 @@ void val_print_optimized_out (const struct value *val, struct ui_file *stream) { if (val != NULL && value_lval_const (val) == lval_register) - fprintf_filtered (stream, _("")); + val_print_not_saved (stream); else fprintf_filtered (stream, _("")); } +void +val_print_not_saved (struct ui_file *stream) +{ + fprintf_filtered (stream, _("")); +} + void val_print_unavailable (struct ui_file *stream) { @@ -356,209 +376,277 @@ val_print_invalid_address (struct ui_file *stream) fprintf_filtered (stream, _("")); } -/* A generic val_print that is suitable for use by language - implementations of the la_val_print method. This function can - handle most type codes, though not all, notably exception - TYPE_CODE_UNION and TYPE_CODE_STRUCT, which must be implemented by - the caller. - - Most arguments are as to val_print. - - The additional DECORATIONS argument can be used to customize the - output in some small, language-specific ways. */ +/* Print a pointer based on the type of its target. -void -generic_val_print (struct type *type, const gdb_byte *valaddr, + Arguments to this functions are roughly the same as those in + generic_val_print. A difference is that ADDRESS is the address to print, + with embedded_offset already added. ELTTYPE represents + the pointed type after check_typedef. */ + +static void +print_unpacked_pointer (struct type *type, struct type *elttype, + CORE_ADDR address, struct ui_file *stream, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + + if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) + { + /* Try to print what function it points to. */ + print_function_pointer_address (options, gdbarch, address, stream); + return; + } + + if (options->symbol_print) + print_address_demangle (options, gdbarch, address, stream, demangle); + else if (options->addressprint) + fputs_filtered (paddress (gdbarch, address), stream); +} + +/* generic_val_print helper for TYPE_CODE_ARRAY. */ + +static void +generic_val_print_array (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, - const struct generic_val_print_decorations *decorations) + const struct value_print_options *options) { - struct gdbarch *gdbarch = get_type_arch (type); - unsigned int i = 0; /* Number of characters printed. */ - unsigned len; - struct type *elttype, *unresolved_elttype; - struct type *unresolved_type = type; - LONGEST val; - CORE_ADDR addr; + struct type *unresolved_elttype = TYPE_TARGET_TYPE (type); + struct type *elttype = check_typedef (unresolved_elttype); - CHECK_TYPEDEF (type); - switch (TYPE_CODE (type)) + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) { - case TYPE_CODE_ARRAY: - unresolved_elttype = TYPE_TARGET_TYPE (type); - elttype = check_typedef (unresolved_elttype); - if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) + LONGEST low_bound, high_bound; + + if (!get_array_bounds (type, &low_bound, &high_bound)) + error (_("Could not determine the array high bound")); + + if (options->prettyformat_arrays) { - LONGEST low_bound, high_bound; + print_spaces_filtered (2 + 2 * recurse, stream); + } - if (!get_array_bounds (type, &low_bound, &high_bound)) - error (_("Could not determine the array high bound")); + fprintf_filtered (stream, "{"); + val_print_array_elements (type, valaddr, embedded_offset, + address, stream, + recurse, original_value, options, 0); + fprintf_filtered (stream, "}"); + } + else + { + /* Array of unspecified length: treat like pointer to first elt. */ + print_unpacked_pointer (type, elttype, address + embedded_offset, stream, + options); + } - if (options->prettyformat_arrays) - { - print_spaces_filtered (2 + 2 * recurse, stream); - } +} - fprintf_filtered (stream, "{"); - val_print_array_elements (type, valaddr, embedded_offset, - address, stream, - recurse, original_value, options, 0); - fprintf_filtered (stream, "}"); - break; - } - /* Array of unspecified length: treat like pointer to first - elt. */ - addr = address + embedded_offset; - goto print_unpacked_pointer; +/* generic_val_print helper for TYPE_CODE_PTR. */ - case TYPE_CODE_MEMBERPTR: +static void +generic_val_print_ptr (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format && options->format != 's') + { val_print_scalar_formatted (type, valaddr, embedded_offset, original_value, options, 0, stream); - break; + } + else + { + struct type *unresolved_elttype = TYPE_TARGET_TYPE(type); + struct type *elttype = check_typedef (unresolved_elttype); + CORE_ADDR addr = unpack_pointer (type, + valaddr + embedded_offset * unit_size); - case TYPE_CODE_PTR: - if (options->format && options->format != 's') - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - unresolved_elttype = TYPE_TARGET_TYPE (type); - elttype = check_typedef (unresolved_elttype); - { - addr = unpack_pointer (type, valaddr + embedded_offset); - print_unpacked_pointer: + print_unpacked_pointer (type, elttype, addr, stream, options); + } +} - if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) - { - /* Try to print what function it points to. */ - print_function_pointer_address (options, gdbarch, addr, stream); - return; - } - if (options->symbol_print) - print_address_demangle (options, gdbarch, addr, stream, demangle); - else if (options->addressprint) - fputs_filtered (paddress (gdbarch, addr), stream); - } - break; +/* generic_val_print helper for TYPE_CODE_MEMBERPTR. */ - case TYPE_CODE_REF: - elttype = check_typedef (TYPE_TARGET_TYPE (type)); - if (options->addressprint) - { - CORE_ADDR addr - = extract_typed_address (valaddr + embedded_offset, type); +static void +generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); +} - fprintf_filtered (stream, "@"); - fputs_filtered (paddress (gdbarch, addr), stream); - if (options->deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ +/* generic_val_print helper for TYPE_CODE_REF. */ + +static void +generic_val_print_ref (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, int recurse, + const struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type)); + + if (options->addressprint) + { + CORE_ADDR addr + = extract_typed_address (valaddr + embedded_offset, type); + + fprintf_filtered (stream, "@"); + fputs_filtered (paddress (gdbarch, addr), stream); if (options->deref_ref) + fputs_filtered (": ", stream); + } + /* De-reference the reference. */ + if (options->deref_ref) + { + if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { - if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) - { - struct value *deref_val; + struct value *deref_val; - deref_val = coerce_ref_if_computed (original_value); - if (deref_val != NULL) - { - /* More complicated computed references are not supported. */ - gdb_assert (embedded_offset == 0); - } - else - deref_val = value_at (TYPE_TARGET_TYPE (type), - unpack_pointer (type, - (valaddr - + embedded_offset))); - - common_val_print (deref_val, stream, recurse, options, - current_language); + deref_val = coerce_ref_if_computed (original_value); + if (deref_val != NULL) + { + /* More complicated computed references are not supported. */ + gdb_assert (embedded_offset == 0); } else - fputs_filtered ("???", stream); + deref_val = value_at (TYPE_TARGET_TYPE (type), + unpack_pointer (type, + (valaddr + + embedded_offset))); + + common_val_print (deref_val, stream, recurse, options, + current_language); } - break; + else + fputs_filtered ("???", stream); + } +} - case TYPE_CODE_ENUM: - if (options->format) +/* Helper function for generic_val_print_enum. + This is also used to print enums in TYPE_CODE_FLAGS values. */ + +static void +generic_val_print_enum_1 (struct type *type, LONGEST val, + struct ui_file *stream) +{ + unsigned int i; + unsigned int len; + + len = TYPE_NFIELDS (type); + for (i = 0; i < len; i++) + { + QUIT; + if (val == TYPE_FIELD_ENUMVAL (type, i)) { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); break; } - len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr + embedded_offset); - for (i = 0; i < len; i++) + } + if (i < len) + { + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + } + else if (TYPE_FLAG_ENUM (type)) + { + int first = 1; + + /* We have a "flag" enum, so we try to decompose it into + pieces as appropriate. A flag enum has disjoint + constants by definition. */ + fputs_filtered ("(", stream); + for (i = 0; i < len; ++i) { QUIT; - if (val == TYPE_FIELD_ENUMVAL (type, i)) + + if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0) { - break; + if (!first) + fputs_filtered (" | ", stream); + first = 0; + + val &= ~TYPE_FIELD_ENUMVAL (type, i); + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); } } - if (i < len) + + if (first || val != 0) { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + if (!first) + fputs_filtered (" | ", stream); + fputs_filtered ("unknown: ", stream); + print_longest (stream, 'd', 0, val); } - else if (TYPE_FLAG_ENUM (type)) - { - int first = 1; - /* We have a "flag" enum, so we try to decompose it into - pieces as appropriate. A flag enum has disjoint - constants by definition. */ - fputs_filtered ("(", stream); - for (i = 0; i < len; ++i) - { - QUIT; + fputs_filtered (")", stream); + } + else + print_longest (stream, 'd', 0, val); +} - if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0) - { - if (!first) - fputs_filtered (" | ", stream); - first = 0; +/* generic_val_print helper for TYPE_CODE_ENUM. */ - val &= ~TYPE_FIELD_ENUMVAL (type, i); - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - } +static void +generic_val_print_enum (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + LONGEST val; + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); - if (first || val != 0) - { - if (!first) - fputs_filtered (" | ", stream); - fputs_filtered ("unknown: ", stream); - print_longest (stream, 'd', 0, val); - } + if (options->format) + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + return; + } + val = unpack_long (type, valaddr + embedded_offset * unit_size); - fputs_filtered (")", stream); - } - else - print_longest (stream, 'd', 0, val); - break; + generic_val_print_enum_1 (type, val, stream); +} - case TYPE_CODE_FLAGS: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - val_print_type_code_flags (type, valaddr + embedded_offset, - stream); - break; +/* generic_val_print helper for TYPE_CODE_FLAGS. */ - case TYPE_CODE_FUNC: - case TYPE_CODE_METHOD: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } +static void +generic_val_print_flags (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) + +{ + if (options->format) + val_print_scalar_formatted (type, valaddr, embedded_offset, original_value, + options, 0, stream); + else + val_print_type_code_flags (type, valaddr + embedded_offset, stream); +} + +/* generic_val_print helper for TYPE_CODE_FUNC and TYPE_CODE_METHOD. */ + +static void +generic_val_print_func (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + + if (options->format) + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + } + else + { /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ @@ -567,31 +655,243 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (options, gdbarch, address, stream, demangle); + } +} + +/* generic_val_print helper for TYPE_CODE_BOOL. */ + +static void +generic_val_print_bool (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options, + const struct generic_val_print_decorations *decorations) +{ + LONGEST val; + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, &opts, 0, stream); + } + else + { + val = unpack_long (type, valaddr + embedded_offset * unit_size); + if (val == 0) + fputs_filtered (decorations->false_name, stream); + else if (val == 1) + fputs_filtered (decorations->true_name, stream); + else + print_longest (stream, 'd', 0, val); + } +} + +/* generic_val_print helper for TYPE_CODE_INT. */ + +static void +generic_val_print_int (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, &opts, 0, stream); + } + else + val_print_type_code_int (type, valaddr + embedded_offset * unit_size, + stream); +} + +/* generic_val_print helper for TYPE_CODE_CHAR. */ + +static void +generic_val_print_char (struct type *type, struct type *unresolved_type, + const gdb_byte *valaddr, int embedded_offset, + struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + LONGEST val; + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, &opts, 0, stream); + } + else + { + val = unpack_long (type, valaddr + embedded_offset * unit_size); + if (TYPE_UNSIGNED (type)) + fprintf_filtered (stream, "%u", (unsigned int) val); + else + fprintf_filtered (stream, "%d", (int) val); + fputs_filtered (" ", stream); + LA_PRINT_CHAR (val, unresolved_type, stream); + } +} + +/* generic_val_print helper for TYPE_CODE_FLT. */ + +static void +generic_val_print_float (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format) + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + } + else + { + print_floating (valaddr + embedded_offset * unit_size, type, stream); + } +} + +/* generic_val_print helper for TYPE_CODE_DECFLOAT. */ + +static void +generic_val_print_decfloat (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format) + val_print_scalar_formatted (type, valaddr, embedded_offset, original_value, + options, 0, stream); + else + print_decimal_floating (valaddr + embedded_offset * unit_size, type, + stream); +} + +/* generic_val_print helper for TYPE_CODE_COMPLEX. */ + +static void +generic_val_print_complex (struct type *type, const gdb_byte *valaddr, + int embedded_offset, struct ui_file *stream, + const struct value *original_value, + const struct value_print_options *options, + const struct generic_val_print_decorations + *decorations) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + fprintf_filtered (stream, "%s", decorations->complex_prefix); + if (options->format) + val_print_scalar_formatted (TYPE_TARGET_TYPE (type), valaddr, + embedded_offset, original_value, options, 0, + stream); + else + print_floating (valaddr + embedded_offset * unit_size, + TYPE_TARGET_TYPE (type), stream); + fprintf_filtered (stream, "%s", decorations->complex_infix); + if (options->format) + val_print_scalar_formatted (TYPE_TARGET_TYPE (type), valaddr, + embedded_offset + + type_length_units (TYPE_TARGET_TYPE (type)), + original_value, options, 0, stream); + else + print_floating (valaddr + embedded_offset * unit_size + + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), + TYPE_TARGET_TYPE (type), stream); + fprintf_filtered (stream, "%s", decorations->complex_suffix); +} + +/* A generic val_print that is suitable for use by language + implementations of the la_val_print method. This function can + handle most type codes, though not all, notably exception + TYPE_CODE_UNION and TYPE_CODE_STRUCT, which must be implemented by + the caller. + + Most arguments are as to val_print. + + The additional DECORATIONS argument can be used to customize the + output in some small, language-specific ways. */ + +void +generic_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, + const struct generic_val_print_decorations *decorations) +{ + struct type *unresolved_type = type; + + type = check_typedef (type); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + generic_val_print_array (type, valaddr, embedded_offset, address, stream, + recurse, original_value, options); + break; + + case TYPE_CODE_MEMBERPTR: + generic_val_print_memberptr (type, valaddr, embedded_offset, stream, + original_value, options); + break; + + case TYPE_CODE_PTR: + generic_val_print_ptr (type, valaddr, embedded_offset, stream, + original_value, options); + break; + + case TYPE_CODE_REF: + generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse, + original_value, options); + break; + + case TYPE_CODE_ENUM: + generic_val_print_enum (type, valaddr, embedded_offset, stream, + original_value, options); + break; + + case TYPE_CODE_FLAGS: + generic_val_print_flags (type, valaddr, embedded_offset, stream, + original_value, options); + break; + + case TYPE_CODE_FUNC: + case TYPE_CODE_METHOD: + generic_val_print_func (type, valaddr, embedded_offset, address, stream, + original_value, options); break; case TYPE_CODE_BOOL: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (val == 0) - fputs_filtered (decorations->false_name, stream); - else if (val == 1) - fputs_filtered (decorations->true_name, stream); - else - print_longest (stream, 'd', 0, val); - } + generic_val_print_bool (type, valaddr, embedded_offset, stream, + original_value, options, decorations); break; case TYPE_CODE_RANGE: - /* FIXME: create_range_type does not set the unsigned bit in a + /* FIXME: create_static_range_type does not set the unsigned bit in a range type (I think it probably should copy it from the target type), so we won't print values which are too large to fit in a signed integer correctly. */ @@ -602,60 +902,23 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, /* FALLTHROUGH */ case TYPE_CODE_INT: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - val_print_type_code_int (type, valaddr + embedded_offset, stream); + generic_val_print_int (type, valaddr, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_CHAR: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (TYPE_UNSIGNED (type)) - fprintf_filtered (stream, "%u", (unsigned int) val); - else - fprintf_filtered (stream, "%d", (int) val); - fputs_filtered (" ", stream); - LA_PRINT_CHAR (val, unresolved_type, stream); - } + generic_val_print_char (type, unresolved_type, valaddr, embedded_offset, + stream, original_value, options); break; case TYPE_CODE_FLT: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - } - else - { - print_floating (valaddr + embedded_offset, type, stream); - } + generic_val_print_float (type, valaddr, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_DECFLOAT: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_decimal_floating (valaddr + embedded_offset, - type, stream); + generic_val_print_decfloat (type, valaddr, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_VOID: @@ -675,29 +938,8 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, break; case TYPE_CODE_COMPLEX: - fprintf_filtered (stream, "%s", decorations->complex_prefix); - if (options->format) - val_print_scalar_formatted (TYPE_TARGET_TYPE (type), - valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_floating (valaddr + embedded_offset, - TYPE_TARGET_TYPE (type), - stream); - fprintf_filtered (stream, "%s", decorations->complex_infix); - if (options->format) - val_print_scalar_formatted (TYPE_TARGET_TYPE (type), - valaddr, - embedded_offset - + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), - original_value, - options, 0, stream); - else - print_floating (valaddr + embedded_offset - + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), - TYPE_TARGET_TYPE (type), - stream); - fprintf_filtered (stream, "%s", decorations->complex_suffix); + generic_val_print_complex (type, valaddr, embedded_offset, stream, + original_value, options, decorations); break; case TYPE_CODE_UNION: @@ -737,7 +979,6 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, const struct value_print_options *options, const struct language_defn *language) { - volatile struct gdb_exception except; int ret = 0; struct value_print_options local_opts = *options; struct type *real_type = check_typedef (type); @@ -764,9 +1005,9 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, if (!options->raw) { - ret = apply_val_pretty_printer (type, valaddr, embedded_offset, - address, stream, recurse, - val, options, language); + ret = apply_ext_lang_val_pretty_printer (type, valaddr, embedded_offset, + address, stream, recurse, + val, options, language); if (ret) return; } @@ -779,14 +1020,17 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, return; } - TRY_CATCH (except, RETURN_MASK_ERROR) + TRY { language->la_val_print (type, valaddr, embedded_offset, address, stream, recurse, val, &local_opts); } - if (except.reason < 0) - fprintf_filtered (stream, _("")); + CATCH (except, RETURN_MASK_ERROR) + { + fprintf_filtered (stream, _("")); + } + END_CATCH } /* Check whether the value VAL is printable. Return 1 if it is; @@ -812,6 +1056,15 @@ value_check_printable (struct value *val, struct ui_file *stream, return 0; } + if (value_entirely_unavailable (val)) + { + if (options->summary && !val_print_scalar_type_p (value_type (val))) + fprintf_filtered (stream, "..."); + else + val_print_unavailable (stream); + return 0; + } + if (TYPE_CODE (value_type (val)) == TYPE_CODE_INTERNAL_FUNCTION) { fprintf_filtered (stream, _(""), @@ -819,6 +1072,18 @@ value_check_printable (struct value *val, struct ui_file *stream, return 0; } + if (type_not_associated (value_type (val))) + { + val_print_not_associated (stream); + return 0; + } + + if (type_not_allocated (value_type (val))) + { + val_print_not_allocated (stream); + return 0; + } + return 1; } @@ -861,12 +1126,13 @@ value_print (struct value *val, struct ui_file *stream, if (!options->raw) { - int r = apply_val_pretty_printer (value_type (val), - value_contents_for_printing (val), - value_embedded_offset (val), - value_address (val), - stream, 0, - val, options, current_language); + int r + = apply_ext_lang_val_pretty_printer (value_type (val), + value_contents_for_printing (val), + value_embedded_offset (val), + value_address (val), + stream, 0, + val, options, current_language); if (r) return; @@ -912,26 +1178,51 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr, } } -void +static void val_print_type_code_flags (struct type *type, const gdb_byte *valaddr, struct ui_file *stream) { ULONGEST val = unpack_long (type, valaddr); - int bitpos, nfields = TYPE_NFIELDS (type); + int field, nfields = TYPE_NFIELDS (type); + struct gdbarch *gdbarch = get_type_arch (type); + struct type *bool_type = builtin_type (gdbarch)->builtin_bool; - fputs_filtered ("[ ", stream); - for (bitpos = 0; bitpos < nfields; bitpos++) + fputs_filtered ("[", stream); + for (field = 0; field < nfields; field++) { - if (TYPE_FIELD_BITPOS (type, bitpos) != -1 - && (val & ((ULONGEST)1 << bitpos))) + if (TYPE_FIELD_NAME (type, field)[0] != '\0') { - if (TYPE_FIELD_NAME (type, bitpos)) - fprintf_filtered (stream, "%s ", TYPE_FIELD_NAME (type, bitpos)); + struct type *field_type = TYPE_FIELD_TYPE (type, field); + + if (field_type == bool_type + /* We require boolean types here to be one bit wide. This is a + problematic place to notify the user of an internal error + though. Instead just fall through and print the field as an + int. */ + && TYPE_FIELD_BITSIZE (type, field) == 1) + { + if (val & ((ULONGEST)1 << TYPE_FIELD_BITPOS (type, field))) + fprintf_filtered (stream, " %s", + TYPE_FIELD_NAME (type, field)); + } else - fprintf_filtered (stream, "#%d ", bitpos); + { + unsigned field_len = TYPE_FIELD_BITSIZE (type, field); + ULONGEST field_val + = val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1); + + if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT) + field_val &= ((ULONGEST) 1 << field_len) - 1; + fprintf_filtered (stream, " %s=", + TYPE_FIELD_NAME (type, field)); + if (TYPE_CODE (field_type) == TYPE_CODE_ENUM) + generic_val_print_enum_1 (field_type, field_val, stream); + else + print_longest (stream, 'd', 0, field_val); + } } } - fputs_filtered ("]", stream); + fputs_filtered (" ]", stream); } /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR, @@ -949,6 +1240,9 @@ val_print_scalar_formatted (struct type *type, int size, struct ui_file *stream) { + struct gdbarch *arch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (arch); + gdb_assert (val != NULL); gdb_assert (valaddr == value_contents_for_printing_const (val)); @@ -967,13 +1261,14 @@ val_print_scalar_formatted (struct type *type, /* A scalar object that does not have all bits available can't be printed, because all bits contribute to its representation. */ - if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset, - TARGET_CHAR_BIT * TYPE_LENGTH (type))) + if (value_bits_any_optimized_out (val, + TARGET_CHAR_BIT * embedded_offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type))) val_print_optimized_out (val, stream); else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) val_print_unavailable (stream); else - print_scalar_formatted (valaddr + embedded_offset, type, + print_scalar_formatted (valaddr + embedded_offset * unit_size, type, options, size, stream); } @@ -1374,7 +1669,7 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, as the base 16 number, which is 2 digits per byte. */ decimal_len = len * 2 * 2; - digits = xmalloc (decimal_len); + digits = (unsigned char *) xmalloc (decimal_len); for (i = 0; i < decimal_len; i++) { @@ -1610,7 +1905,7 @@ val_print_array_elements (struct type *type, { unsigned int things_printed = 0; unsigned len; - struct type *elttype, *index_type; + struct type *elttype, *index_type, *base_index_type; unsigned eltlen; /* Position of the array element we are examining to see whether it is repeated. */ @@ -1618,22 +1913,41 @@ val_print_array_elements (struct type *type, /* Number of repetitions we have detected so far. */ unsigned int reps; LONGEST low_bound, high_bound; + LONGEST low_pos, high_pos; elttype = TYPE_TARGET_TYPE (type); - eltlen = TYPE_LENGTH (check_typedef (elttype)); + eltlen = type_length_units (check_typedef (elttype)); index_type = TYPE_INDEX_TYPE (type); if (get_array_bounds (type, &low_bound, &high_bound)) { - /* The array length should normally be HIGH_BOUND - LOW_BOUND + 1. + if (TYPE_CODE (index_type) == TYPE_CODE_RANGE) + base_index_type = TYPE_TARGET_TYPE (index_type); + else + base_index_type = index_type; + + /* Non-contiguous enumerations types can by used as index types + in some languages (e.g. Ada). In this case, the array length + shall be computed from the positions of the first and last + literal in the enumeration type, and not from the values + of these literals. */ + if (!discrete_position (base_index_type, low_bound, &low_pos) + || !discrete_position (base_index_type, high_bound, &high_pos)) + { + warning (_("unable to get positions in array, use bounds instead")); + low_pos = low_bound; + high_pos = high_bound; + } + + /* The array length should normally be HIGH_POS - LOW_POS + 1. But we have to be a little extra careful, because some languages - such as Ada allow LOW_BOUND to be greater than HIGH_BOUND for + such as Ada allow LOW_POS to be greater than HIGH_POS for empty arrays. In that situation, the array length is just zero, not negative! */ - if (low_bound > high_bound) + if (low_pos > high_pos) len = 0; else - len = high_bound - low_bound + 1; + len = high_pos - low_pos + 1; } else { @@ -1669,12 +1983,12 @@ val_print_array_elements (struct type *type, if (options->repeat_count_threshold < UINT_MAX) { while (rep1 < len - && value_available_contents_eq (val, - embedded_offset + i * eltlen, - val, - (embedded_offset - + rep1 * eltlen), - eltlen)) + && value_contents_eq (val, + embedded_offset + i * eltlen, + val, + (embedded_offset + + rep1 * eltlen), + eltlen)) { ++reps; ++rep1; @@ -1711,7 +2025,7 @@ val_print_array_elements (struct type *type, /* Read LEN bytes of target memory at address MEMADDR, placing the results in GDB's memory at MYADDR. Returns a count of the bytes - actually read, and optionally a target_xfer_error value in the + actually read, and optionally a target_xfer_status value in the location pointed to by ERRPTR if ERRPTR is non-null. */ /* FIXME: cagney/1999-10-14: Only used by val_print_string. Can this @@ -1755,7 +2069,7 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr, each. Fetch at most FETCHLIMIT characters. BUFFER will be set to a newly allocated buffer containing the string, which the caller is responsible to free, and BYTES_READ will be set to the number of bytes read. Returns 0 on - success, or a target_xfer_error on failure. + success, or a target_xfer_status on failure. If LEN > 0, reads the lesser of LEN or FETCHLIMIT characters (including eventual NULs in the middle or end of the string). @@ -1779,36 +2093,23 @@ int read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read) { - int found_nul; /* Non-zero if we found the nul char. */ int errcode; /* Errno returned from bad reads. */ unsigned int nfetch; /* Chars to fetch / chars fetched. */ - unsigned int chunksize; /* Size of each fetch, in chars. */ gdb_byte *bufptr; /* Pointer to next available byte in buffer. */ - gdb_byte *limit; /* First location past end of fetch buffer. */ struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */ - /* Decide how large of chunks to try to read in one operation. This - is also pretty simple. If LEN >= zero, then we want fetchlimit chars, - so we might as well read them all in one operation. If LEN is -1, we - are looking for a NUL terminator to end the fetching, so we might as - well read in blocks that are large enough to be efficient, but not so - large as to be slow if fetchlimit happens to be large. So we choose the - minimum of 8 and fetchlimit. We used to use 200 instead of 8 but - 200 is way too big for remote debugging over a serial line. */ - - chunksize = (len == -1 ? min (8, fetchlimit) : fetchlimit); - /* Loop until we either have all the characters, or we encounter some error, such as bumping into the end of the address space. */ - found_nul = 0; *buffer = NULL; old_chain = make_cleanup (free_current_contents, buffer); if (len > 0) { + /* We want fetchlimit chars, so we might as well read them all in + one operation. */ unsigned int fetchlen = min (len, fetchlimit); *buffer = (gdb_byte *) xmalloc (fetchlen * width); @@ -1822,6 +2123,18 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, else if (len == -1) { unsigned long bufsize = 0; + unsigned int chunksize; /* Size of each fetch, in chars. */ + int found_nul; /* Non-zero if we found the nul char. */ + gdb_byte *limit; /* First location past end of fetch buffer. */ + + found_nul = 0; + /* We are looking for a NUL terminator to end the fetching, so we + might as well read in blocks that are large enough to be efficient, + but not so large as to be slow if fetchlimit happens to be large. + So we choose the minimum of 8 and fetchlimit. We used to use 200 + instead of 8 but 200 is way too big for remote debugging over a + serial line. */ + chunksize = min (8, fetchlimit); do { @@ -1872,7 +2185,7 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, else { /* Length of string is really 0! */ /* We always allocate *buffer. */ - *buffer = bufptr = xmalloc (1); + *buffer = bufptr = (gdb_byte *) xmalloc (1); errcode = 0; } @@ -1933,73 +2246,77 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig, int need_escape = *need_escapep; *need_escapep = 0; - if (gdb_iswprint (w) && (!need_escape || (!gdb_iswdigit (w) - && w != LCST ('8') - && w != LCST ('9')))) - { - gdb_wchar_t wchar = w; - if (w == gdb_btowc (quoter) || w == LCST ('\\')) - obstack_grow_wstr (output, LCST ("\\")); - obstack_grow (output, &wchar, sizeof (gdb_wchar_t)); - } - else + /* iswprint implementation on Windows returns 1 for tab character. + In order to avoid different printout on this host, we explicitly + use wchar_printable function. */ + switch (w) { - switch (w) + case LCST ('\a'): + obstack_grow_wstr (output, LCST ("\\a")); + break; + case LCST ('\b'): + obstack_grow_wstr (output, LCST ("\\b")); + break; + case LCST ('\f'): + obstack_grow_wstr (output, LCST ("\\f")); + break; + case LCST ('\n'): + obstack_grow_wstr (output, LCST ("\\n")); + break; + case LCST ('\r'): + obstack_grow_wstr (output, LCST ("\\r")); + break; + case LCST ('\t'): + obstack_grow_wstr (output, LCST ("\\t")); + break; + case LCST ('\v'): + obstack_grow_wstr (output, LCST ("\\v")); + break; + default: { - case LCST ('\a'): - obstack_grow_wstr (output, LCST ("\\a")); - break; - case LCST ('\b'): - obstack_grow_wstr (output, LCST ("\\b")); - break; - case LCST ('\f'): - obstack_grow_wstr (output, LCST ("\\f")); - break; - case LCST ('\n'): - obstack_grow_wstr (output, LCST ("\\n")); - break; - case LCST ('\r'): - obstack_grow_wstr (output, LCST ("\\r")); - break; - case LCST ('\t'): - obstack_grow_wstr (output, LCST ("\\t")); - break; - case LCST ('\v'): - obstack_grow_wstr (output, LCST ("\\v")); - break; - default: - { - int i; + if (wchar_printable (w) && (!need_escape || (!gdb_iswdigit (w) + && w != LCST ('8') + && w != LCST ('9')))) + { + gdb_wchar_t wchar = w; - for (i = 0; i + width <= orig_len; i += width) - { - char octal[30]; - ULONGEST value; + if (w == gdb_btowc (quoter) || w == LCST ('\\')) + obstack_grow_wstr (output, LCST ("\\")); + obstack_grow (output, &wchar, sizeof (gdb_wchar_t)); + } + else + { + int i; - value = extract_unsigned_integer (&orig[i], width, + for (i = 0; i + width <= orig_len; i += width) + { + char octal[30]; + ULONGEST value; + + value = extract_unsigned_integer (&orig[i], width, byte_order); - /* If the value fits in 3 octal digits, print it that - way. Otherwise, print it as a hex escape. */ - if (value <= 0777) - xsnprintf (octal, sizeof (octal), "\\%.3o", - (int) (value & 0777)); - else - xsnprintf (octal, sizeof (octal), "\\x%lx", (long) value); - append_string_as_wide (octal, output); - } - /* If we somehow have extra bytes, print them now. */ - while (i < orig_len) - { - char octal[5]; + /* If the value fits in 3 octal digits, print it that + way. Otherwise, print it as a hex escape. */ + if (value <= 0777) + xsnprintf (octal, sizeof (octal), "\\%.3o", + (int) (value & 0777)); + else + xsnprintf (octal, sizeof (octal), "\\x%lx", (long) value); + append_string_as_wide (octal, output); + } + /* If we somehow have extra bytes, print them now. */ + while (i < orig_len) + { + char octal[5]; - xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff); - append_string_as_wide (octal, output); - ++i; - } + xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff); + append_string_as_wide (octal, output); + ++i; + } - *need_escapep = 1; - } + *need_escapep = 1; + } break; } } @@ -2021,7 +2338,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, struct wchar_iterator *iter; int need_escape = 0; - buf = alloca (TYPE_LENGTH (type)); + buf = (gdb_byte *) alloca (TYPE_LENGTH (type)); pack_long (buf, type, c); iter = make_wchar_iterator (buf, TYPE_LENGTH (type), @@ -2086,7 +2403,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, sizeof (gdb_wchar_t), &output, translit_char); obstack_1grow (&output, '\0'); - fputs_filtered (obstack_base (&output), stream); + fputs_filtered ((const char *) obstack_base (&output), stream); do_cleanups (cleanups); } @@ -2441,7 +2758,7 @@ generic_printstr (struct ui_file *stream, struct type *type, sizeof (gdb_wchar_t), &output, translit_char); obstack_1grow (&output, '\0'); - fputs_filtered (obstack_base (&output), stream); + fputs_filtered ((const char *) obstack_base (&output), stream); do_cleanups (cleanup); } @@ -2461,7 +2778,7 @@ val_print_string (struct type *elttype, const char *encoding, const struct value_print_options *options) { int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero. */ - int errcode; /* Errno returned from bad reads. */ + int err; /* Non-zero if we got a bad read. */ int found_nul; /* Non-zero if we found the nul char. */ unsigned int fetchlimit; /* Maximum number of chars to print. */ int bytes_read; @@ -2482,8 +2799,8 @@ val_print_string (struct type *elttype, const char *encoding, fetchlimit = (len == -1 ? options->print_max : min (len, options->print_max)); - errcode = read_string (addr, len, width, fetchlimit, byte_order, - &buffer, &bytes_read); + err = read_string (addr, len, width, fetchlimit, byte_order, + &buffer, &bytes_read); old_chain = make_cleanup (xfree, buffer); addr += bytes_read; @@ -2493,8 +2810,10 @@ val_print_string (struct type *elttype, const char *encoding, LEN is -1. */ /* Determine found_nul by looking at the last character read. */ - found_nul = extract_unsigned_integer (buffer + bytes_read - width, width, - byte_order) == 0; + found_nul = 0; + if (bytes_read >= width) + found_nul = extract_unsigned_integer (buffer + bytes_read - width, width, + byte_order) == 0; if (len == -1 && !found_nul) { gdb_byte *peekbuf; @@ -2509,7 +2828,7 @@ val_print_string (struct type *elttype, const char *encoding, && extract_unsigned_integer (peekbuf, width, byte_order) != 0) force_ellipsis = 1; } - else if ((len >= 0 && errcode != 0) || (len > bytes_read / width)) + else if ((len >= 0 && err != 0) || (len > bytes_read / width)) { /* Getting an error when we have a requested length, or fetching less than the number of characters actually requested, always make us @@ -2520,17 +2839,17 @@ val_print_string (struct type *elttype, const char *encoding, /* If we get an error before fetching anything, don't print a string. But if we fetch something and then get an error, print the string and then the error message. */ - if (errcode == 0 || bytes_read > 0) + if (err == 0 || bytes_read > 0) { LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width, encoding, force_ellipsis, options); } - if (errcode != 0) + if (err != 0) { char *str; - str = memory_error_message (errcode, gdbarch, addr); + str = memory_error_message (TARGET_XFER_E_IO, gdbarch, addr); make_cleanup (xfree, str); fprintf_filtered (stream, "