From patchwork Fri Dec 1 10:48:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 24671 Received: (qmail 75803 invoked by alias); 1 Dec 2017 10:48:46 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 74919 invoked by uid 89); 1 Dec 2017 10:48:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=chop, blt, Leading, Raw X-HELO: mail-wm0-f65.google.com Received: from mail-wm0-f65.google.com (HELO mail-wm0-f65.google.com) (74.125.82.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 01 Dec 2017 10:48:28 +0000 Received: by mail-wm0-f65.google.com with SMTP id g75so2760567wme.0 for ; Fri, 01 Dec 2017 02:48:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Yo76KdKyXbI+yN0pz9C6l3Ky59y6HtUYXs1dKKvxoFg=; b=sQf5lyAgDi1RHX1lC/Lm7j4/js/X8Jp+PS4dzNGUy9c+i2bBlS2a81OVx7FToRr35h WgEvfRvLSJ5AYER4y8QxV22mUt6DnbVbDTAPpUCZxWu4B2vWyhZwFPvEjCU9V+cUFwIf nrOnDFODBhg/6sYrPkdIRNU0gtz13/pFeRNNZsu3Wd3HdybwPfAWwR9eYB2VhetNVwey IAA2PoAcMazl4MtQ+cFSLkoaBEsqUdPyDoflxAOh83v/GqDwqtErbf6DrwWyp3C3OFra jYeCFvjGsE+jONxsQVN8BF2vAdSxfumQdbid4tWW1ujQwKex09/oQLKfJpb+zRQRdu2E +Ozg== X-Gm-Message-State: AKGB3mIbe61iZ09KPire3NGdWlEt4hLxQvC5kqOdADCSfA3fI0UAmLzf PZMTnXwNM3erwDPACilma+jPew== X-Google-Smtp-Source: AGs4zMZI/V2Bc/lgGX4Judqi2jndmSmTD4+z40Cc/fv9vtYxf037QBS/Ivk4sUrpVbsb6rlrY3/0jw== X-Received: by 10.28.125.11 with SMTP id y11mr851864wmc.115.1512125306087; Fri, 01 Dec 2017 02:48:26 -0800 (PST) Received: from E107787-LIN.cambridge.arm.com (static.42.136.251.148.clients.your-server.de. [148.251.136.42]) by smtp.gmail.com with ESMTPSA id o10sm5316833wrg.5.2017.12.01.02.48.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 01 Dec 2017 02:48:25 -0800 (PST) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 15/15] Move register_dump to regcache-dump.c Date: Fri, 1 Dec 2017 10:48:06 +0000 Message-Id: <1512125286-29788-16-git-send-email-yao.qi@linaro.org> In-Reply-To: <1512125286-29788-1-git-send-email-yao.qi@linaro.org> References: <1512125286-29788-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes gdb: 2017-11-30 Yao Qi * Makefile.in (SFILES): Add regcache-dump.c (COMMON_OBS): Add regcache-dump.o. * regcache-dump.c: New file. * regcache.c: Move register_dump to regcache-dump.c. (maintenance_print_registers): Likewise. (maintenance_print_raw_registers): Likewise. (maintenance_print_cooked_registers): Likewise. (maintenance_print_register_groups): Likewise. (maintenance_print_remote_registers): Likewise. (_initialize_regcache): Likewise. * regcache.h (register_dump): Moved from regcache.c. --- gdb/Makefile.in | 2 + gdb/regcache-dump.c | 335 ++++++++++++++++++++++++++++++++++ gdb/regcache.c | 505 +++++++++------------------------------------------- gdb/regcache.h | 20 +++ 4 files changed, 446 insertions(+), 416 deletions(-) create mode 100644 gdb/regcache-dump.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 3d90fde..1e59919 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1188,6 +1188,7 @@ SFILES = \ record-btrace.c \ record-full.c \ regcache.c \ + regcache-dump.c \ reggroups.c \ remote.c \ remote-fileio.c \ @@ -1811,6 +1812,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ record-btrace.o \ record-full.o \ regcache.o \ + regcache-dump.o \ reggroups.o \ registry.o \ reverse.o \ diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c new file mode 100644 index 0000000..4780fc4 --- /dev/null +++ b/gdb/regcache-dump.c @@ -0,0 +1,335 @@ +/* Copyright (C) 1986-2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "gdbcmd.h" +#include "regcache.h" +#include "common/def-vector.h" +#include "valprint.h" +#include "remote.h" +#include "reggroups.h" +#include "target.h" + +/* 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 buf (size); + auto status = m_regcache->cooked_read (regnum, buf.data ()); + + if (status == REG_UNKNOWN) + fprintf_unfiltered (file, ""); + else if (status == REG_UNAVAILABLE) + fprintf_unfiltered (file, ""); + else + { + print_hex_chars (file, buf.data (), size, + gdbarch_byte_order (m_gdbarch), true); + } + } + else + { + /* Just print "" for pseudo register when + regcache_dump_raw. */ + fprintf_unfiltered (file, ""); + } + } + } + +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) + { + } + +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 + { + 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); + + gdb_assert (status != REG_VALID); + + if (status == REG_UNKNOWN) + fprintf_unfiltered (file, ""); + else + fprintf_unfiltered (file, ""); + } + else + { + /* Just print "" for pseudo register when + regcache_dump_raw. */ + fprintf_unfiltered (file, ""); + } + } + } +}; + +/* 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) + {} + +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)) + { + fprintf_unfiltered (file, + "%s%s", sep, reggroup_name (group)); + sep = ","; + } + } + } + } +}; + +enum regcache_dump_what +{ + regcache_dump_none, regcache_dump_raw, + regcache_dump_cooked, regcache_dump_groups, + regcache_dump_remote +}; + +static void +regcache_print (const char *args, enum regcache_dump_what what_to_dump) +{ + /* Where to send output. */ + stdio_file file; + ui_file *out; + + if (args == NULL) + out = gdb_stdout; + else + { + if (!file.open (args, "w")) + perror_with_name (_("maintenance print architecture")); + out = &file; + } + + std::unique_ptr dump; + std::unique_ptr 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); +} + +void +_initialize_regcache_dump (void) +{ + 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); +} diff --git a/gdb/regcache.c b/gdb/regcache.c index 4ea4a5d..653c70e 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 @@ -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 buf (size); - auto status = m_regcache->cooked_read (regnum, buf.data ()); - - if (status == REG_UNKNOWN) - fprintf_unfiltered (file, ""); - else if (status == REG_UNAVAILABLE) - fprintf_unfiltered (file, ""); - else - { - print_hex_chars (file, buf.data (), size, - gdbarch_byte_order (m_gdbarch), true); - } - } - else - { - /* Just print "" for pseudo register when - regcache_dump_raw. */ - fprintf_unfiltered (file, ""); - } - } - } - -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, ""); - else - fprintf_unfiltered (file, ""); - } + if (regnum < 0) + t = "Type"; else { - /* Just print "" for pseudo register when - regcache_dump_raw. */ - fprintf_unfiltered (file, ""); - } - } - } -}; - -/* 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 dump; - std::unique_ptr 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); diff --git a/gdb/regcache.h b/gdb/regcache.h index d1e8506..ad7e0a1 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -425,4 +425,24 @@ public: extern void registers_changed (void); extern void registers_changed_ptid (ptid_t); +/* An abstract base class for register dump. */ + +class register_dump +{ +public: + void dump (ui_file *file); + 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; +}; + #endif /* REGCACHE_H */