X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fvalprint.c;h=d6ec64845f4be9bd3eb10664ac86cb623d5b3b42;hb=29ef4c0699e1b46d41ade00ae07a54f979ea21cc;hp=340a329f9d0f9af334b7619d8091d80507b6865c;hpb=8ee511afd84972c2019518725295440b3d2676bc;p=binutils-gdb.git diff --git a/gdb/valprint.c b/gdb/valprint.c index 340a329f9d0..d6ec64845f4 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1,6 +1,6 @@ /* Print values for GDB, the GNU debugger. - Copyright (C) 1986-2021 Free Software Foundation, Inc. + Copyright (C) 1986-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -30,7 +30,7 @@ #include "target-float.h" #include "extension.h" #include "ada-lang.h" -#include "gdb_obstack.h" +#include "gdbsupport/gdb_obstack.h" #include "charset.h" #include "typeprint.h" #include @@ -42,6 +42,9 @@ #include "count-one-bits.h" #include "c-lang.h" #include "cp-abi.h" +#include "inferior.h" +#include "gdbsupport/selftest.h" +#include "selftest-arch.h" /* Maximum number of wchars returned from wchar_iterate. */ #define MAX_WCHARS 4 @@ -110,6 +113,7 @@ struct value_print_options user_print_options = 10, /* repeat_count_threshold */ 0, /* output_format */ 0, /* format */ + 1, /* memory_tag_violations */ 0, /* stop_print_at_null */ 0, /* print_array_indexes */ 0, /* deref_ref */ @@ -203,6 +207,17 @@ show_repeat_count_threshold (struct ui_file *file, int from_tty, value); } +/* If nonzero, prints memory tag violations for pointers. */ + +static void +show_memory_tag_violations (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, + _("Printing of memory tag violations is %s.\n"), + value); +} + /* If nonzero, stops printing of char arrays at first null. */ static void @@ -469,7 +484,7 @@ generic_value_print_ptr (struct value *val, struct ui_file *stream, { struct type *type = check_typedef (value_type (val)); struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type)); - const gdb_byte *valaddr = value_contents_for_printing (val); + const gdb_byte *valaddr = value_contents_for_printing (val).data (); CORE_ADDR addr = unpack_pointer (type, valaddr); print_unpacked_pointer (type, elttype, addr, stream, options); @@ -505,7 +520,7 @@ get_value_addr_contents (struct value *deref_val) gdb_assert (deref_val != NULL); if (value_lval_const (deref_val) == lval_memory) - return value_contents_for_printing_const (value_addr (deref_val)); + return value_contents_for_printing_const (value_addr (deref_val)).data (); else { /* We have a non-addressable value, such as a DW_AT_const_value. */ @@ -530,7 +545,7 @@ generic_val_print_ref (struct type *type, const int must_coerce_ref = ((options->addressprint && value_is_synthetic) || options->deref_ref); const int type_is_defined = elttype->code () != TYPE_CODE_UNDEF; - const gdb_byte *valaddr = value_contents_for_printing (original_value); + const gdb_byte *valaddr = value_contents_for_printing (original_value).data (); if (must_coerce_ref && type_is_defined) { @@ -593,17 +608,17 @@ generic_val_print_enum_1 (struct type *type, LONGEST val, for (i = 0; i < len; i++) { QUIT; - if (val == TYPE_FIELD_ENUMVAL (type, i)) + if (val == type->field (i).loc_enumval ()) { break; } } if (i < len) { - fputs_styled (TYPE_FIELD_NAME (type, i), variable_name_style.style (), + fputs_styled (type->field (i).name (), variable_name_style.style (), stream); } - else if (TYPE_FLAG_ENUM (type)) + else if (type->is_flag_enum ()) { int first = 1; @@ -615,7 +630,7 @@ generic_val_print_enum_1 (struct type *type, LONGEST val, { QUIT; - ULONGEST enumval = TYPE_FIELD_ENUMVAL (type, i); + ULONGEST enumval = type->field (i).loc_enumval (); int nbits = count_one_bits_ll (enumval); gdb_assert (nbits == 0 || nbits == 1); @@ -630,8 +645,8 @@ generic_val_print_enum_1 (struct type *type, LONGEST val, else fputs_filtered (" | ", stream); - val &= ~TYPE_FIELD_ENUMVAL (type, i); - fputs_styled (TYPE_FIELD_NAME (type, i), + val &= ~type->field (i).loc_enumval (); + fputs_styled (type->field (i).name (), variable_name_style.style (), stream); } } @@ -678,7 +693,7 @@ generic_val_print_enum (struct type *type, gdb_assert (!options->format); - const gdb_byte *valaddr = value_contents_for_printing (original_value); + const gdb_byte *valaddr = value_contents_for_printing (original_value).data (); val = unpack_long (type, valaddr + embedded_offset * unit_size); @@ -725,7 +740,7 @@ generic_value_print_bool } else { - const gdb_byte *valaddr = value_contents_for_printing (value); + const gdb_byte *valaddr = value_contents_for_printing (value).data (); struct type *type = check_typedef (value_type (value)); LONGEST val = unpack_long (type, valaddr); if (val == 0) @@ -768,7 +783,7 @@ generic_value_print_char (struct value *value, struct ui_file *stream, { struct type *unresolved_type = value_type (value); struct type *type = check_typedef (unresolved_type); - const gdb_byte *valaddr = value_contents_for_printing (value); + const gdb_byte *valaddr = value_contents_for_printing (value).data (); LONGEST val = unpack_long (type, valaddr); if (type->is_unsigned ()) @@ -776,7 +791,7 @@ generic_value_print_char (struct value *value, struct ui_file *stream, else fprintf_filtered (stream, "%d", (int) val); fputs_filtered (" ", stream); - LA_PRINT_CHAR (val, unresolved_type, stream); + current_language->printchar (val, unresolved_type, stream); } } @@ -789,7 +804,7 @@ generic_val_print_float (struct type *type, struct ui_file *stream, { gdb_assert (!options->format); - const gdb_byte *valaddr = value_contents_for_printing (original_value); + const gdb_byte *valaddr = value_contents_for_printing (original_value).data (); print_floating (valaddr, type, stream); } @@ -806,7 +821,7 @@ generic_val_print_fixed_point (struct value *val, struct ui_file *stream, { struct type *type = value_type (val); - const gdb_byte *valaddr = value_contents_for_printing (val); + const gdb_byte *valaddr = value_contents_for_printing (val).data (); gdb_mpf f; f.read_fixed_point (gdb::make_array_view (valaddr, TYPE_LENGTH (type)), @@ -852,7 +867,7 @@ generic_value_print_memberptr /* Member pointers are essentially specific to C++, and so if we encounter one, we should print it according to C++ rules. */ struct type *type = check_typedef (value_type (val)); - const gdb_byte *valaddr = value_contents_for_printing (val); + const gdb_byte *valaddr = value_contents_for_printing (val).data (); cp_print_class_member (valaddr, type, stream, "&"); } else @@ -962,7 +977,7 @@ generic_value_print (struct value *val, struct ui_file *stream, int recurse, break; case TYPE_CODE_METHODPTR: - cplus_print_method_ptr (value_contents_for_printing (val), type, + cplus_print_method_ptr (value_contents_for_printing (val).data (), type, stream); break; @@ -974,16 +989,27 @@ generic_value_print (struct value *val, struct ui_file *stream, int recurse, } } -/* Helper function for val_print and common_val_print that does the - work. Arguments are as to val_print, but FULL_VALUE, if given, is - the value to be printed. */ +/* Print using the given LANGUAGE the value VAL onto stream STREAM according + to OPTIONS. -static void -do_val_print (struct value *value, struct ui_file *stream, int recurse, - const struct value_print_options *options, - const struct language_defn *language) + This is a preferable interface to val_print, above, because it uses + GDB's value mechanism. */ + +void +common_val_print (struct value *value, struct ui_file *stream, int recurse, + const struct value_print_options *options, + const struct language_defn *language) { - int ret = 0; + if (language->la_language == language_ada) + /* The value might have a dynamic type, which would cause trouble + below when trying to extract the value contents (since the value + size is determined from the type size which is unknown). So + get a fixed representation of our value. */ + value = ada_to_fixed_value (value); + + if (value_lazy (value)) + value_fetch_lazy (value); + struct value_print_options local_opts = *options; struct type *type = value_type (value); struct type *real_type = check_typedef (type); @@ -1009,9 +1035,8 @@ do_val_print (struct value *value, struct ui_file *stream, int recurse, if (!options->raw) { - ret = apply_ext_lang_val_pretty_printer (value, stream, recurse, options, - language); - if (ret) + if (apply_ext_lang_val_pretty_printer (value, stream, recurse, options, + language)) return; } @@ -1035,7 +1060,7 @@ do_val_print (struct value *value, struct ui_file *stream, int recurse, catch (const gdb_exception_error &except) { fprintf_styled (stream, metadata_style.style (), - _("")); + _(""), except.what ()); } } @@ -1112,30 +1137,6 @@ value_check_printable (struct value *val, struct ui_file *stream, return 1; } -/* Print using the given LANGUAGE the value VAL onto stream STREAM according - to OPTIONS. - - This is a preferable interface to val_print, above, because it uses - GDB's value mechanism. */ - -void -common_val_print (struct value *val, struct ui_file *stream, int recurse, - const struct value_print_options *options, - const struct language_defn *language) -{ - if (language->la_language == language_ada) - /* The value might have a dynamic type, which would cause trouble - below when trying to extract the value contents (since the value - size is determined from the type size which is unknown). So - get a fixed representation of our value. */ - val = ada_to_fixed_value (val); - - if (value_lazy (val)) - value_fetch_lazy (val); - - do_val_print (val, stream, recurse, options, language); -} - /* See valprint.h. */ void @@ -1178,7 +1179,7 @@ static void val_print_type_code_flags (struct type *type, struct value *original_value, int embedded_offset, struct ui_file *stream) { - const gdb_byte *valaddr = (value_contents_for_printing (original_value) + const gdb_byte *valaddr = (value_contents_for_printing (original_value).data () + embedded_offset); ULONGEST val = unpack_long (type, valaddr); int field, nfields = type->num_fields (); @@ -1188,7 +1189,7 @@ val_print_type_code_flags (struct type *type, struct value *original_value, fputs_filtered ("[", stream); for (field = 0; field < nfields; field++) { - if (TYPE_FIELD_NAME (type, field)[0] != '\0') + if (type->field (field).name ()[0] != '\0') { struct type *field_type = type->field (field).type (); @@ -1199,23 +1200,22 @@ val_print_type_code_flags (struct type *type, struct value *original_value, int. */ && TYPE_FIELD_BITSIZE (type, field) == 1) { - if (val & ((ULONGEST)1 << TYPE_FIELD_BITPOS (type, field))) + if (val & ((ULONGEST)1 << type->field (field).loc_bitpos ())) fprintf_filtered (stream, " %ps", styled_string (variable_name_style.style (), - TYPE_FIELD_NAME (type, field))); + type->field (field).name ())); } else { unsigned field_len = TYPE_FIELD_BITSIZE (type, field); - ULONGEST field_val - = val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1); + ULONGEST field_val = val >> type->field (field).loc_bitpos (); if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT) field_val &= ((ULONGEST) 1 << field_len) - 1; fprintf_filtered (stream, " %ps=", styled_string (variable_name_style.style (), - TYPE_FIELD_NAME (type, field))); + type->field (field).name ())); if (field_type->code () == TYPE_CODE_ENUM) generic_val_print_enum_1 (field_type, field_val, stream); else @@ -1253,7 +1253,7 @@ value_print_scalar_formatted (struct value *val, /* value_contents_for_printing fetches all VAL's contents. They are needed to check whether VAL is optimized-out or unavailable below. */ - const gdb_byte *valaddr = value_contents_for_printing (val); + const gdb_byte *valaddr = value_contents_for_printing (val).data (); /* A scalar object that does not have all bits available can't be printed, because all bits contribute to its representation. */ @@ -1836,9 +1836,8 @@ print_function_pointer_address (const struct value_print_options *options, CORE_ADDR address, struct ui_file *stream) { - CORE_ADDR func_addr - = gdbarch_convert_from_func_ptr_addr (gdbarch, address, - current_top_target ()); + CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr + (gdbarch, address, current_inferior ()->top_target ()); /* If the function pointer is represented by a description, print the address of the description. */ @@ -1933,7 +1932,7 @@ value_print_array_elements (struct value *val, struct ui_file *stream, fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } - wrap_here (n_spaces (2 + 2 * recurse)); + stream->wrap_here (2 + 2 * recurse); maybe_print_array_index (index_type, i + low_bound, stream, options); @@ -2768,10 +2767,9 @@ val_print_string (struct type *elttype, const char *encoding, But if we fetch something and then get an error, print the string and then the error message. */ if (err == 0 || bytes_read > 0) - { - LA_PRINT_STRING (stream, elttype, buffer.get (), bytes_read / width, - encoding, force_ellipsis, options); - } + current_language->printstr (stream, elttype, buffer.get (), + bytes_read / width, + encoding, force_ellipsis, options); if (err != 0) { @@ -3023,6 +3021,17 @@ will be replaced with either '{...}' or '(...)' depending on the language.\n\ Use \"unlimited\" to print the complete structure.") }, + boolean_option_def { + "memory-tag-violations", + [] (value_print_options *opt) { return &opt->memory_tag_violations; }, + show_memory_tag_violations, /* show_cmd_cb */ + N_("Set printing of memory tag violations for pointers."), + N_("Show printing of memory tag violations for pointers."), + N_("Issue a warning when the printed value is a pointer\n\ +whose logical tag doesn't match the allocation tag of the memory\n\ +location it points to."), + }, + boolean_option_def { "null-stop", [] (value_print_options *opt) { return &opt->stop_print_at_null; }, @@ -3114,37 +3123,61 @@ make_value_print_options_def_group (value_print_options *opts) return {{value_print_option_defs}, opts}; } +#if GDB_SELF_TEST + +/* Test printing of TYPE_CODE_FLAGS values. */ + +static void +test_print_flags (gdbarch *arch) +{ + type *flags_type = arch_flags_type (arch, "test_type", 32); + type *field_type = builtin_type (arch)->builtin_uint32; + + /* Value: 1010 1010 + Fields: CCCB BAAA */ + append_flags_type_field (flags_type, 0, 3, field_type, "A"); + append_flags_type_field (flags_type, 3, 2, field_type, "B"); + append_flags_type_field (flags_type, 5, 3, field_type, "C"); + + value *val = allocate_value (flags_type); + gdb_byte *contents = value_contents_writeable (val).data (); + store_unsigned_integer (contents, 4, gdbarch_byte_order (arch), 0xaa); + + string_file out; + val_print_type_code_flags (flags_type, val, 0, &out); + SELF_CHECK (out.string () == "[ A=2 B=1 C=5 ]"); +} + +#endif + void _initialize_valprint (); void _initialize_valprint () { - cmd_list_element *cmd; - - add_basic_prefix_cmd ("print", no_class, - _("Generic command for setting how things print."), - &setprintlist, "set print ", 0, &setlist); - add_alias_cmd ("p", "print", no_class, 1, &setlist); +#if GDB_SELF_TEST + selftests::register_test_foreach_arch ("print-flags", test_print_flags); +#endif + + set_show_commands setshow_print_cmds + = add_setshow_prefix_cmd ("print", no_class, + _("Generic command for setting how things print."), + _("Generic command for showing print settings."), + &setprintlist, &showprintlist, + &setlist, &showlist); + add_alias_cmd ("p", setshow_print_cmds.set, no_class, 1, &setlist); /* Prefer set print to set prompt. */ - add_alias_cmd ("pr", "print", no_class, 1, &setlist); - - add_show_prefix_cmd ("print", no_class, - _("Generic command for showing print settings."), - &showprintlist, "show print ", 0, &showlist); - add_alias_cmd ("p", "print", no_class, 1, &showlist); - add_alias_cmd ("pr", "print", no_class, 1, &showlist); - - cmd = add_basic_prefix_cmd ("raw", no_class, - _("\ -Generic command for setting what things to print in \"raw\" mode."), - &setprintrawlist, "set print raw ", 0, - &setprintlist); - deprecate_cmd (cmd, nullptr); - - cmd = add_show_prefix_cmd ("raw", no_class, - _("Generic command for showing \"print raw\" settings."), - &showprintrawlist, "show print raw ", 0, - &showprintlist); - deprecate_cmd (cmd, nullptr); + add_alias_cmd ("pr", setshow_print_cmds.set, no_class, 1, &setlist); + add_alias_cmd ("p", setshow_print_cmds.show, no_class, 1, &showlist); + add_alias_cmd ("pr", setshow_print_cmds.show, no_class, 1, &showlist); + + set_show_commands setshow_print_raw_cmds + = add_setshow_prefix_cmd + ("raw", no_class, + _("Generic command for setting what things to print in \"raw\" mode."), + _("Generic command for showing \"print raw\" settings."), + &setprintrawlist, &showprintrawlist, &setprintlist, &showprintlist); + deprecate_cmd (setshow_print_raw_cmds.set, nullptr); + deprecate_cmd (setshow_print_raw_cmds.show, nullptr); gdb::option::add_setshow_cmds_for_options (class_support, &user_print_options, value_print_option_defs,