aboutsummaryrefslogtreecommitdiff
path: root/gdb/regcache-dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/regcache-dump.c')
-rw-r--r--gdb/regcache-dump.c256
1 files changed, 151 insertions, 105 deletions
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c
index bc665dc..c6ef552 100644
--- a/gdb/regcache-dump.c
+++ b/gdb/regcache-dump.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1986-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1986-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -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 (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,19 +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");
+ 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))
- gdb_printf (file, "%7d %11d", pnum, poffset);
+ out->field_skip ("remnum");
+ out->field_skip ("goffset");
+ out->field_skip ("expedited");
}
}
};
@@ -185,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);
}
};
@@ -211,20 +245,24 @@ enum regcache_dump_what
regcache_dump_remote
};
+/* Helper for the various maint commands that print registers. ARGS
+ is the arguments passed to the command. WHAT_TO_DUMP indicates
+ exactly which registers to display. COMMAND is the command name,
+ used in error messages. */
+
static void
-regcache_print (const char *args, enum regcache_dump_what what_to_dump)
+regcache_print (const char *args, enum regcache_dump_what what_to_dump,
+ const char *command)
{
/* 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;
+ perror_with_name (command);
+ redirect.emplace (current_uiout, &file);
}
std::unique_ptr<register_dump> dump;
@@ -236,73 +274,79 @@ 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.reset (new register_dump_none (gdbarch));
+ dump = std::make_unique<register_dump_none> (gdbarch);
+ name = "Registers";
break;
case regcache_dump_remote:
- dump.reset (new register_dump_remote (gdbarch));
+ dump = std::make_unique<register_dump_remote> (gdbarch);
+ name = "RegisterRemote";
break;
case regcache_dump_groups:
- dump.reset (new register_dump_groups (gdbarch));
+ 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 ())
- dump.reset (new register_dump_regcache (get_thread_regcache
- (inferior_thread ()),
- dump_pseudo));
+ dump = (std::make_unique<register_dump_regcache>
+ (get_thread_regcache (inferior_thread ()), dump_pseudo));
else
{
/* For the benefit of "maint print registers" & co when
debugging an executable, allow dumping a regcache even when
there is no thread selected / no registers. */
- dump.reset (new register_dump_reg_buffer (gdbarch, dump_pseudo));
+ dump = std::make_unique<register_dump_reg_buffer> (gdbarch,
+ dump_pseudo);
}
}
break;
}
- dump->dump (out);
+ dump->dump (current_uiout, name);
}
static void
maintenance_print_registers (const char *args, int from_tty)
{
- regcache_print (args, regcache_dump_none);
+ regcache_print (args, regcache_dump_none, "maintenance print registers");
}
static void
maintenance_print_raw_registers (const char *args, int from_tty)
{
- regcache_print (args, regcache_dump_raw);
+ regcache_print (args, regcache_dump_raw, "maintenance print raw-registers");
}
static void
maintenance_print_cooked_registers (const char *args, int from_tty)
{
- regcache_print (args, regcache_dump_cooked);
+ regcache_print (args, regcache_dump_cooked,
+ "maintenance print cooked-registers");
}
static void
maintenance_print_register_groups (const char *args, int from_tty)
{
- regcache_print (args, regcache_dump_groups);
+ regcache_print (args, regcache_dump_groups,
+ "maintenance print register-groups");
}
static void
maintenance_print_remote_registers (const char *args, int from_tty)
{
- regcache_print (args, regcache_dump_remote);
+ regcache_print (args, regcache_dump_remote,
+ "maintenance print remote-registers");
}
-void _initialize_regcache_dump ();
-void
-_initialize_regcache_dump ()
+INIT_GDB_FILE (regcache_dump)
{
add_cmd ("registers", class_maintenance, maintenance_print_registers,
_("Print the internal register configuration.\n"
@@ -325,8 +369,10 @@ _initialize_regcache_dump ()
&maintenanceprintlist);
add_cmd ("remote-registers", class_maintenance,
maintenance_print_remote_registers, _("\
-Print the internal register configuration including remote register number "
-"and g/G packets offset.\n\
-Takes an optional file parameter."),
+Print the internal register configuration.\n\
+Usage: maintenance print remote-registers [FILE]\n\
+The remote register number and g/G packets offset are included,\n\
+as well as which registers were sent in the last stop reply packet\n\
+(i.e., expedited)."),
&maintenanceprintlist);
}