diff options
author | Tom Tromey <tom@tromey.com> | 2024-10-09 15:25:06 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2024-12-03 18:42:57 -0700 |
commit | 17ecffd7669d605273d1f9951118b6ab1c09ed45 (patch) | |
tree | 8f4a601f743cb01767ef5ae3d3c897f8772f4b92 /gdb | |
parent | 20e8a322b1d0732ce758a106d10beee25180f9ec (diff) | |
download | gdb-17ecffd7669d605273d1f9951118b6ab1c09ed45.zip gdb-17ecffd7669d605273d1f9951118b6ab1c09ed45.tar.gz gdb-17ecffd7669d605273d1f9951118b6ab1c09ed45.tar.bz2 |
Use ui-out tables in some "maint print" commands
This changes various "maint print" register commands to use ui-out
tables rather than the current printf approach.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/regcache-dump.c | 210 | ||||
-rw-r--r-- | gdb/regcache.c | 132 | ||||
-rw-r--r-- | gdb/regcache.h | 14 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/maint.exp | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.server/server-run.exp | 2 |
5 files changed, 192 insertions, 170 deletions
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c index e25302d..9be694d 100644 --- a/gdb/regcache-dump.c +++ b/gdb/regcache-dump.c @@ -38,43 +38,45 @@ public: } protected: - void dump_reg (ui_file *file, int regnum) override + + int num_additional_headers () override + { return 1; } + + void additional_headers (ui_out *out) override { - if (regnum < 0) + out->table_header (0, ui_left, "value", + m_dump_pseudo ? "Cooked value" : "Raw value"); + } + + void dump_reg (ui_out *out, int regnum) override + { + if (regnum < gdbarch_num_regs (m_gdbarch) || m_dump_pseudo) { - if (m_dump_pseudo) - gdb_printf (file, "Cooked value"); + auto size = register_size (m_gdbarch, regnum); + + if (size == 0) + return; + + gdb::byte_vector buf (size); + auto status = m_regcache->cooked_read (regnum, buf.data ()); + + if (status == REG_UNKNOWN) + out->field_string ("value", "<invalid>"); + else if (status == REG_UNAVAILABLE) + out->field_string ("value", "<unavailable>"); else - gdb_printf (file, "Raw value"); + { + string_file str; + print_hex_chars (&str, buf.data (), size, + gdbarch_byte_order (m_gdbarch), true); + out->field_stream ("value", str); + } } else { - if (regnum < gdbarch_num_regs (m_gdbarch) || m_dump_pseudo) - { - auto size = register_size (m_gdbarch, regnum); - - if (size == 0) - return; - - gdb::byte_vector buf (size); - auto status = m_regcache->cooked_read (regnum, buf.data ()); - - if (status == REG_UNKNOWN) - gdb_printf (file, "<invalid>"); - else if (status == REG_UNAVAILABLE) - gdb_printf (file, "<unavailable>"); - else - { - print_hex_chars (file, buf.data (), size, - gdbarch_byte_order (m_gdbarch), true); - } - } - else - { - /* Just print "<cooked>" for pseudo register when - regcache_dump_raw. */ - gdb_printf (file, "<cooked>"); - } + /* Just print "<cooked>" for pseudo register when + regcache_dump_raw. */ + out->field_string ("value", "<cooked>"); } } @@ -97,39 +99,39 @@ public: } protected: - void dump_reg (ui_file *file, int regnum) override + + int num_additional_headers () override + { return 1; } + + void additional_headers (ui_out *out) override { - if (regnum < 0) - { - if (m_has_pseudo) - gdb_printf (file, "Cooked value"); - else - gdb_printf (file, "Raw value"); - } - else + out->table_header (0, ui_left, "value", + m_has_pseudo ? "Cooked value" : "Raw value"); + } + + void dump_reg (ui_out *out, int regnum) override + { + if (regnum < gdbarch_num_regs (m_gdbarch) || m_has_pseudo) { - if (regnum < gdbarch_num_regs (m_gdbarch) || m_has_pseudo) - { - auto size = register_size (m_gdbarch, regnum); + auto size = register_size (m_gdbarch, regnum); - if (size == 0) - return; + if (size == 0) + return; - auto status = get_register_status (regnum); + auto status = get_register_status (regnum); - gdb_assert (status != REG_VALID); + gdb_assert (status != REG_VALID); - if (status == REG_UNKNOWN) - gdb_printf (file, "<invalid>"); - else - gdb_printf (file, "<unavailable>"); - } + if (status == REG_UNKNOWN) + out->field_string ("value", "<invalid>"); else - { - /* Just print "<cooked>" for pseudo register when - regcache_dump_raw. */ - gdb_printf (file, "<cooked>"); - } + out->field_string ("value", "<unavailable>"); + } + else + { + /* Just print "<cooked>" for pseudo register when + regcache_dump_raw. */ + out->field_string ("value", "<cooked>"); } } }; @@ -144,7 +146,14 @@ public: {} protected: - void dump_reg (ui_file *file, int regnum) override + + int num_additional_headers () override + { return 0; } + + void additional_headers (ui_out *out) override + { } + + void dump_reg (ui_out *out, int regnum) override {} }; @@ -158,24 +167,38 @@ public: {} protected: - void dump_reg (ui_file *file, int regnum) override + + int num_additional_headers () override + { return 3; } + + void additional_headers (ui_out *out) override + { + out->table_header (7, ui_left, "remnum", "Rmt Nr"); + out->table_header (11, ui_left, "goffset", "g/G Offset"); + out->table_header (3, ui_left, "expedited", "Expedited"); + } + + void dump_reg (ui_out *out, int regnum) override { - if (regnum < 0) + int pnum, poffset; + + if (regnum < gdbarch_num_regs (m_gdbarch) + && remote_register_number_and_offset (m_gdbarch, regnum, + &pnum, &poffset)) { - gdb_printf (file, "Rmt Nr g/G Offset Expedited"); + out->field_signed ("remnum", pnum); + out->field_signed ("goffset", poffset); + + if (remote_register_is_expedited (regnum)) + out->field_string ("expedited", "yes"); + else + out->field_skip ("expedited"); } - else if (regnum < gdbarch_num_regs (m_gdbarch)) + else { - int pnum, poffset; - - if (remote_register_number_and_offset (m_gdbarch, regnum, - &pnum, &poffset)) - { - if (remote_register_is_expedited (regnum)) - gdb_printf (file, "%7d %11d yes", pnum, poffset); - else - gdb_printf (file, "%7d %11d", pnum, poffset); - } + out->field_skip ("remnum"); + out->field_skip ("goffset"); + out->field_skip ("expedited"); } } }; @@ -190,22 +213,28 @@ public: {} protected: - void dump_reg (ui_file *file, int regnum) override + + int num_additional_headers () override + { return 1; } + + void additional_headers (ui_out *out) override { - if (regnum < 0) - gdb_printf (file, "Groups"); - else + out->table_header (0, ui_left, "groups", "Groups"); + } + + void dump_reg (ui_out *out, int regnum) override + { + string_file file; + const char *sep = ""; + for (const struct reggroup *group : gdbarch_reggroups (m_gdbarch)) { - const char *sep = ""; - for (const struct reggroup *group : gdbarch_reggroups (m_gdbarch)) + if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group)) { - if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group)) - { - gdb_printf (file, "%s%s", sep, group->name ()); - sep = ","; - } + gdb_printf (&file, "%s%s", sep, group->name ()); + sep = ","; } } + out->field_stream ("groups", file); } }; @@ -221,15 +250,13 @@ regcache_print (const char *args, enum regcache_dump_what what_to_dump) { /* Where to send output. */ stdio_file file; - ui_file *out; + std::optional<ui_out_redirect_pop> redirect; - if (args == NULL) - out = gdb_stdout; - else + if (args != nullptr) { if (!file.open (args, "w")) perror_with_name (_("maintenance print architecture")); - out = &file; + redirect.emplace (current_uiout, &file); } std::unique_ptr<register_dump> dump; @@ -241,20 +268,25 @@ regcache_print (const char *args, enum regcache_dump_what what_to_dump) else gdbarch = current_inferior ()->arch (); + const char *name; switch (what_to_dump) { case regcache_dump_none: dump = std::make_unique<register_dump_none> (gdbarch); + name = "Registers"; break; case regcache_dump_remote: dump = std::make_unique<register_dump_remote> (gdbarch); + name = "RegisterRemote"; break; case regcache_dump_groups: dump = std::make_unique<register_dump_groups> (gdbarch); + name = "RegisterGroups"; break; case regcache_dump_raw: case regcache_dump_cooked: { + name = "RegisterDump"; auto dump_pseudo = (what_to_dump == regcache_dump_cooked); if (target_has_registers ()) @@ -272,7 +304,7 @@ regcache_print (const char *args, enum regcache_dump_what what_to_dump) break; } - dump->dump (out); + dump->dump (current_uiout, name); } static void diff --git a/gdb/regcache.c b/gdb/regcache.c index ab3f616..f2c403b 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1519,7 +1519,7 @@ reg_flush_command (const char *command, int from_tty) } void -register_dump::dump (ui_file *file) +register_dump::dump (ui_out *out, const char *name) { auto descr = regcache_descr (m_gdbarch); int regnum; @@ -1531,107 +1531,91 @@ register_dump::dump (ui_file *file) gdb_assert (descr->nr_cooked_registers == gdbarch_num_cooked_regs (m_gdbarch)); - for (regnum = -1; regnum < descr->nr_cooked_registers; regnum++) + ui_out_emit_table table (out, 6 + num_additional_headers (), -1, name); + out->table_header (10, ui_left, "name", "Name"); + out->table_header (4, ui_left, "num", "Nr"); + out->table_header (4, ui_left, "relnum", "Rel"); + out->table_header (8, ui_left, "offset", "Offset"); + out->table_header (5, ui_left, "size", "Size"); + out->table_header (15, ui_left, "type", "Type"); + additional_headers (out); + out->table_body (); + + for (regnum = 0; regnum < descr->nr_cooked_registers; regnum++) { - /* Name. */ - if (regnum < 0) - gdb_printf (file, " %-10s", "Name"); - else - { - const char *p = gdbarch_register_name (m_gdbarch, regnum); + ui_out_emit_tuple tuple_emitter (out, nullptr); - if (p[0] == '\0') - p = "''"; - gdb_printf (file, " %-10s", p); - } + /* Name. */ + const char *p = gdbarch_register_name (m_gdbarch, regnum); + if (p[0] == '\0') + p = "''"; + out->field_string ("name", p); /* Number. */ - if (regnum < 0) - gdb_printf (file, " %4s", "Nr"); - else - gdb_printf (file, " %4d", regnum); + out->field_signed ("num", regnum); /* Relative number. */ - if (regnum < 0) - gdb_printf (file, " %4s", "Rel"); - else if (regnum < gdbarch_num_regs (m_gdbarch)) - gdb_printf (file, " %4d", regnum); + if (regnum < gdbarch_num_regs (m_gdbarch)) + out->field_signed ("relnum", regnum); else - gdb_printf (file, " %4d", - (regnum - gdbarch_num_regs (m_gdbarch))); + out->field_signed ("relnum", (regnum - gdbarch_num_regs (m_gdbarch))); /* Offset. */ - if (regnum < 0) - gdb_printf (file, " %6s ", "Offset"); - else + if (register_offset != descr->register_offset[regnum] + || (regnum > 0 + && (descr->register_offset[regnum] + != (descr->register_offset[regnum - 1] + + descr->sizeof_register[regnum - 1])))) { - gdb_printf (file, " %6ld", - descr->register_offset[regnum]); - if (register_offset != descr->register_offset[regnum] - || (regnum > 0 - && (descr->register_offset[regnum] - != (descr->register_offset[regnum - 1] - + descr->sizeof_register[regnum - 1]))) - ) - { - if (!footnote_register_offset) - footnote_register_offset = ++footnote_nr; - gdb_printf (file, "*%d", footnote_register_offset); - } - else - gdb_printf (file, " "); - register_offset = (descr->register_offset[regnum] - + descr->sizeof_register[regnum]); + if (!footnote_register_offset) + footnote_register_offset = ++footnote_nr; + std::string val = string_printf ("%ld*%d", + descr->register_offset[regnum], + footnote_register_offset); + out->field_string ("offset", val); } + else + out->field_signed ("offset", descr->register_offset[regnum]); + register_offset = (descr->register_offset[regnum] + + descr->sizeof_register[regnum]); /* Size. */ - if (regnum < 0) - gdb_printf (file, " %5s ", "Size"); - else - gdb_printf (file, " %5ld", descr->sizeof_register[regnum]); + out->field_signed ("size", descr->sizeof_register[regnum]); /* Type. */ { const char *t; std::string name_holder; - if (regnum < 0) - t = "Type"; - else + static const char blt[] = "builtin_type"; + + t = register_type (m_gdbarch, regnum)->name (); + if (t == NULL) { - static const char blt[] = "builtin_type"; - - t = register_type (m_gdbarch, regnum)->name (); - if (t == NULL) - { - if (!footnote_register_type_name_null) - footnote_register_type_name_null = ++footnote_nr; - name_holder = string_printf ("*%d", - footnote_register_type_name_null); - t = name_holder.c_str (); - } - /* Chop a leading builtin_type. */ - if (startswith (t, blt)) - t += strlen (blt); + if (!footnote_register_type_name_null) + footnote_register_type_name_null = ++footnote_nr; + name_holder = string_printf ("*%d", + footnote_register_type_name_null); + t = name_holder.c_str (); } - gdb_printf (file, " %-15s", t); - } + /* Chop a leading builtin_type. */ + if (startswith (t, blt)) + t += strlen (blt); - /* Leading space always present. */ - gdb_printf (file, " "); + out->field_string ("type", t); + } - dump_reg (file, regnum); + dump_reg (out, regnum); - gdb_printf (file, "\n"); + out->text ("\n"); } if (footnote_register_offset) - gdb_printf (file, "*%d: Inconsistent register offsets.\n", - footnote_register_offset); + out->message ("*%d: Inconsistent register offsets.\n", + footnote_register_offset); if (footnote_register_type_name_null) - gdb_printf (file, - "*%d: Register type's name NULL.\n", - footnote_register_type_name_null); + out->message ("*%d: Register type's name NULL.\n", + footnote_register_type_name_null); } #if GDB_SELF_TEST diff --git a/gdb/regcache.h b/gdb/regcache.h index 8d026e0..7123698 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -31,6 +31,7 @@ struct gdbarch; class thread_info; struct process_stratum_target; struct inferior; +class ui_out; extern struct regcache *get_thread_regcache (process_stratum_target *target, ptid_t ptid); @@ -536,7 +537,7 @@ extern void registers_changed_thread (thread_info *thread); class register_dump { public: - void dump (ui_file *file); + void dump (ui_out *out, const char *name); virtual ~register_dump () = default; protected: @@ -544,9 +545,14 @@ protected: : m_gdbarch (arch) {} - /* Dump the register REGNUM contents. If REGNUM is -1, print the - header. */ - virtual void dump_reg (ui_file *file, int regnum) = 0; + /* Number of additional table headers. */ + virtual int num_additional_headers () = 0; + + /* Add the additional headers to OUT. */ + virtual void additional_headers (ui_out *out) = 0; + + /* Dump the register REGNUM contents. */ + virtual void dump_reg (ui_out *out, int regnum) = 0; gdbarch *m_gdbarch; }; diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp index f1e1b87..2c58ffa 100644 --- a/gdb/testsuite/gdb.base/maint.exp +++ b/gdb/testsuite/gdb.base/maint.exp @@ -70,11 +70,11 @@ set saw_registers 0 set saw_headers 0 set test "maint print registers" gdb_test_multiple $test $test { - -re "\[^\r\n\]+Name\[^\r\n\]+Nr\[^\r\n\]+Rel\[^\r\n\]+Offset\[^\r\n\]+Size\[^\r\n\]+Type\[^\r\n\]+\r\n" { + -re "Name\[^\r\n\]+Nr\[^\r\n\]+Rel\[^\r\n\]+Offset\[^\r\n\]+Size\[^\r\n\]+Type\[^\r\n\]+\r\n" { set saw_headers 1 exp_continue } - -re "^\[^\r\n\]+\[0-9\]+\[^\r\n\]+\[0-9\]+\[^\r\n\]+\[0-9\]+\[^\r\n\]+\[0-9\]+\[^\r\n\]+\r\n" { + -re "\[0-9\]+\[^\r\n\]+\[0-9\]+\[^\r\n\]+\[0-9\]+\[^\r\n\]+\[0-9\]+\[^\r\n\]+\r\n" { set saw_registers 1 exp_continue } diff --git a/gdb/testsuite/gdb.server/server-run.exp b/gdb/testsuite/gdb.server/server-run.exp index af5a5f5..e81384f 100644 --- a/gdb/testsuite/gdb.server/server-run.exp +++ b/gdb/testsuite/gdb.server/server-run.exp @@ -74,7 +74,7 @@ if { [info exists pc_regname] } { set seen_line false gdb_test_multiple "maintenance print remote-registers" \ $expedited_pc_test_name -lbl { - -re " ${pc_regname}\[\[:space:\]\]+${decimal}.*${decimal} yes" { + -re "${pc_regname}\[\[:space:\]\]+${decimal}.*${decimal}\[\[:space:\]\]+yes" { set seen_line true exp_continue } |