diff options
Diffstat (limited to 'gdb/regcache.c')
-rw-r--r-- | gdb/regcache.c | 505 |
1 files changed, 89 insertions, 416 deletions
diff --git a/gdb/regcache.c b/gdb/regcache.c index de6dcc0..71bb788 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -25,8 +25,6 @@ #include "regcache.h" #include "reggroups.h" #include "observer.h" -#include "remote.h" -#include "valprint.h" #include "regset.h" #include <forward_list> @@ -1300,421 +1298,122 @@ reg_flush_command (const char *command, int from_tty) printf_filtered (_("Register cache flushed.\n")); } -/* An abstract base class for register dump. */ - -class register_dump +void register_dump::dump (ui_file *file) { -public: - void dump (ui_file *file) - { - auto descr = regcache_descr (m_gdbarch); - int regnum; - int footnote_nr = 0; - int footnote_register_offset = 0; - int footnote_register_type_name_null = 0; - long register_offset = 0; - - gdb_assert (descr->nr_cooked_registers - == (gdbarch_num_regs (m_gdbarch) - + gdbarch_num_pseudo_regs (m_gdbarch))); - - for (regnum = -1; regnum < descr->nr_cooked_registers; regnum++) - { - /* Name. */ - if (regnum < 0) - fprintf_unfiltered (file, " %-10s", "Name"); - else - { - const char *p = gdbarch_register_name (m_gdbarch, regnum); + auto descr = regcache_descr (m_gdbarch); + int regnum; + int footnote_nr = 0; + int footnote_register_offset = 0; + int footnote_register_type_name_null = 0; + long register_offset = 0; - if (p == NULL) - p = ""; - else if (p[0] == '\0') - p = "''"; - fprintf_unfiltered (file, " %-10s", p); - } + gdb_assert (descr->nr_cooked_registers + == (gdbarch_num_regs (m_gdbarch) + + gdbarch_num_pseudo_regs (m_gdbarch))); - /* Number. */ - if (regnum < 0) - fprintf_unfiltered (file, " %4s", "Nr"); - else - fprintf_unfiltered (file, " %4d", regnum); + for (regnum = -1; regnum < descr->nr_cooked_registers; regnum++) + { + /* Name. */ + if (regnum < 0) + fprintf_unfiltered (file, " %-10s", "Name"); + else + { + const char *p = gdbarch_register_name (m_gdbarch, regnum); - /* Relative number. */ - if (regnum < 0) - fprintf_unfiltered (file, " %4s", "Rel"); - else if (regnum < gdbarch_num_regs (m_gdbarch)) - fprintf_unfiltered (file, " %4d", regnum); - else - fprintf_unfiltered (file, " %4d", - (regnum - gdbarch_num_regs (m_gdbarch))); + if (p == NULL) + p = ""; + else if (p[0] == '\0') + p = "''"; + fprintf_unfiltered (file, " %-10s", p); + } - /* Offset. */ - if (regnum < 0) - fprintf_unfiltered (file, " %6s ", "Offset"); - else - { - fprintf_unfiltered (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; - fprintf_unfiltered (file, "*%d", footnote_register_offset); - } - else - fprintf_unfiltered (file, " "); - register_offset = (descr->register_offset[regnum] - + descr->sizeof_register[regnum]); - } + /* Number. */ + if (regnum < 0) + fprintf_unfiltered (file, " %4s", "Nr"); + else + fprintf_unfiltered (file, " %4d", regnum); - /* Size. */ - if (regnum < 0) - fprintf_unfiltered (file, " %5s ", "Size"); - else - fprintf_unfiltered (file, " %5ld", descr->sizeof_register[regnum]); + /* Relative number. */ + if (regnum < 0) + fprintf_unfiltered (file, " %4s", "Rel"); + else if (regnum < gdbarch_num_regs (m_gdbarch)) + fprintf_unfiltered (file, " %4d", regnum); + else + fprintf_unfiltered (file, " %4d", + (regnum - gdbarch_num_regs (m_gdbarch))); - /* Type. */ + /* Offset. */ + if (regnum < 0) + fprintf_unfiltered (file, " %6s ", "Offset"); + else { - const char *t; - std::string name_holder; - - if (regnum < 0) - t = "Type"; - else + fprintf_unfiltered (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]))) + ) { - static const char blt[] = "builtin_type"; - - t = TYPE_NAME (register_type (m_gdbarch, regnum)); - 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_offset) + footnote_register_offset = ++footnote_nr; + fprintf_unfiltered (file, "*%d", footnote_register_offset); } - fprintf_unfiltered (file, " %-15s", t); + else + fprintf_unfiltered (file, " "); + register_offset = (descr->register_offset[regnum] + + descr->sizeof_register[regnum]); } - /* Leading space always present. */ - fprintf_unfiltered (file, " "); - - dump_reg (file, regnum); - - fprintf_unfiltered (file, "\n"); - } - - if (footnote_register_offset) - fprintf_unfiltered (file, "*%d: Inconsistent register offsets.\n", - footnote_register_offset); - if (footnote_register_type_name_null) - fprintf_unfiltered (file, - "*%d: Register type's name NULL.\n", - footnote_register_type_name_null); - } - - virtual ~register_dump () {}; - -protected: - register_dump (gdbarch *arch) - : 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; - - gdbarch *m_gdbarch; -}; - -/* Dump registers from regcache, used for dump raw registers and - cooked registers. */ - -class register_dump_regcache : public register_dump -{ -public: - register_dump_regcache (regcache *regcache, bool dump_pseudo) - : register_dump (regcache->arch ()), m_regcache (regcache), - m_dump_pseudo (dump_pseudo) - { - } - -protected: - void dump_reg (ui_file *file, int regnum) override - { - if (regnum < 0) - { - if (m_dump_pseudo) - fprintf_unfiltered (file, "Cooked value"); - else - fprintf_unfiltered (file, "Raw value"); - } - else - { - if (regnum < gdbarch_num_regs (m_gdbarch) || m_dump_pseudo) - { - auto size = register_size (m_gdbarch, regnum); - - if (size == 0) - return; - - gdb::def_vector<gdb_byte> buf (size); - auto status = m_regcache->cooked_read (regnum, buf.data ()); - - if (status == REG_UNKNOWN) - fprintf_unfiltered (file, "<invalid>"); - else if (status == REG_UNAVAILABLE) - fprintf_unfiltered (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. */ - fprintf_unfiltered (file, "<cooked>"); - } - } - } - -private: - regcache *m_regcache; - - /* Dump pseudo registers or not. */ - const bool m_dump_pseudo; -}; - -/* Dump from reg_buffer, used when there is no thread or - registers. */ - -class register_dump_reg_buffer : public register_dump, reg_buffer -{ -public: - register_dump_reg_buffer (gdbarch *gdbarch, bool dump_pseudo) - : register_dump (gdbarch), reg_buffer (gdbarch, dump_pseudo) - { - } + /* Size. */ + if (regnum < 0) + fprintf_unfiltered (file, " %5s ", "Size"); + else + fprintf_unfiltered (file, " %5ld", descr->sizeof_register[regnum]); -protected: - void dump_reg (ui_file *file, int regnum) override - { - if (regnum < 0) - { - if (m_has_pseudo) - fprintf_unfiltered (file, "Cooked value"); - else - fprintf_unfiltered (file, "Raw value"); - } - else + /* Type. */ { - if (regnum < gdbarch_num_regs (m_gdbarch) || m_has_pseudo) - { - auto size = register_size (m_gdbarch, regnum); - - if (size == 0) - return; - - auto status = get_register_status (regnum); + const char *t; + std::string name_holder; - gdb_assert (status != REG_VALID); - - if (status == REG_UNKNOWN) - fprintf_unfiltered (file, "<invalid>"); - else - fprintf_unfiltered (file, "<unavailable>"); - } + if (regnum < 0) + t = "Type"; else { - /* Just print "<cooked>" for pseudo register when - regcache_dump_raw. */ - fprintf_unfiltered (file, "<cooked>"); - } - } - } -}; - -/* For "maint print registers". */ - -class register_dump_none : public register_dump -{ -public: - register_dump_none (gdbarch *arch) - : register_dump (arch) - {} - -protected: - void dump_reg (ui_file *file, int regnum) override - {} -}; - -/* For "maint print remote-registers". */ - -class register_dump_remote : public register_dump -{ -public: - register_dump_remote (gdbarch *arch) - : register_dump (arch) - {} + static const char blt[] = "builtin_type"; -protected: - void dump_reg (ui_file *file, int regnum) override - { - if (regnum < 0) - { - fprintf_unfiltered (file, "Rmt Nr g/G Offset"); - } - else if (regnum < gdbarch_num_regs (m_gdbarch)) - { - int pnum, poffset; - - if (remote_register_number_and_offset (m_gdbarch, regnum, - &pnum, &poffset)) - fprintf_unfiltered (file, "%7d %11d", pnum, poffset); - } - } -}; - -/* For "maint print register-groups". */ - -class register_dump_groups : public register_dump -{ -public: - register_dump_groups (gdbarch *arch) - : register_dump (arch) - {} - -protected: - void dump_reg (ui_file *file, int regnum) override - { - if (regnum < 0) - fprintf_unfiltered (file, "Groups"); - else - { - const char *sep = ""; - struct reggroup *group; - - for (group = reggroup_next (m_gdbarch, NULL); - group != NULL; - group = reggroup_next (m_gdbarch, group)) - { - if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group)) + t = TYPE_NAME (register_type (m_gdbarch, regnum)); + if (t == NULL) { - fprintf_unfiltered (file, - "%s%s", sep, reggroup_name (group)); - sep = ","; + 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); } + fprintf_unfiltered (file, " %-15s", t); } - } -}; -enum regcache_dump_what -{ - regcache_dump_none, regcache_dump_raw, - regcache_dump_cooked, regcache_dump_groups, - regcache_dump_remote -}; + /* Leading space always present. */ + fprintf_unfiltered (file, " "); -static void -regcache_print (const char *args, enum regcache_dump_what what_to_dump) -{ - /* Where to send output. */ - stdio_file file; - ui_file *out; + dump_reg (file, regnum); - if (args == NULL) - out = gdb_stdout; - else - { - if (!file.open (args, "w")) - perror_with_name (_("maintenance print architecture")); - out = &file; + fprintf_unfiltered (file, "\n"); } - std::unique_ptr<register_dump> dump; - std::unique_ptr<regcache> regs; - gdbarch *gdbarch; - - if (target_has_registers) - gdbarch = get_current_regcache ()->arch (); - else - gdbarch = target_gdbarch (); - - switch (what_to_dump) - { - case regcache_dump_none: - dump.reset (new register_dump_none (gdbarch)); - break; - case regcache_dump_remote: - dump.reset (new register_dump_remote (gdbarch)); - break; - case regcache_dump_groups: - dump.reset (new register_dump_groups (gdbarch)); - break; - case regcache_dump_raw: - case regcache_dump_cooked: - { - auto dump_pseudo = (what_to_dump == regcache_dump_cooked); - - if (target_has_registers) - dump.reset (new register_dump_regcache (get_current_regcache (), - 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 (target_gdbarch (), - dump_pseudo)); - } - } - break; - } - - dump->dump (out); -} - -static void -maintenance_print_registers (const char *args, int from_tty) -{ - regcache_print (args, regcache_dump_none); -} - -static void -maintenance_print_raw_registers (const char *args, int from_tty) -{ - regcache_print (args, regcache_dump_raw); -} - -static void -maintenance_print_cooked_registers (const char *args, int from_tty) -{ - regcache_print (args, regcache_dump_cooked); -} - -static void -maintenance_print_register_groups (const char *args, int from_tty) -{ - regcache_print (args, regcache_dump_groups); -} - -static void -maintenance_print_remote_registers (const char *args, int from_tty) -{ - regcache_print (args, regcache_dump_remote); + if (footnote_register_offset) + fprintf_unfiltered (file, "*%d: Inconsistent register offsets.\n", + footnote_register_offset); + if (footnote_register_type_name_null) + fprintf_unfiltered (file, + "*%d: Register type's name NULL.\n", + footnote_register_type_name_null); } #if GDB_SELF_TEST @@ -2175,32 +1874,6 @@ _initialize_regcache (void) add_com ("flushregs", class_maintenance, reg_flush_command, _("Force gdb to flush its register cache (maintainer command)")); - add_cmd ("registers", class_maintenance, maintenance_print_registers, - _("Print the internal register configuration.\n" - "Takes an optional file parameter."), &maintenanceprintlist); - add_cmd ("raw-registers", class_maintenance, - maintenance_print_raw_registers, - _("Print the internal register configuration " - "including raw values.\n" - "Takes an optional file parameter."), &maintenanceprintlist); - add_cmd ("cooked-registers", class_maintenance, - maintenance_print_cooked_registers, - _("Print the internal register configuration " - "including cooked values.\n" - "Takes an optional file parameter."), &maintenanceprintlist); - add_cmd ("register-groups", class_maintenance, - maintenance_print_register_groups, - _("Print the internal register configuration " - "including each register's group.\n" - "Takes an optional file parameter."), - &maintenanceprintlist); - add_cmd ("remote-registers", class_maintenance, - maintenance_print_remote_registers, _("\ -Print the internal register configuration including each register's\n\ -remote register number and buffer offset in the g/G packets.\n\ -Takes an optional file parameter."), - &maintenanceprintlist); - #if GDB_SELF_TEST selftests::register_test ("current_regcache", selftests::current_regcache_test); |