binutils-gdb/gdb/disasm.h

370 lines
14 KiB
C
Raw Normal View History

/* Disassemble support for GDB.
Copyright (C) 2002-2022 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 <http://www.gnu.org/licenses/>. */
#ifndef DISASM_H
#define DISASM_H
Sort includes for files gdb/[a-f]*.[chyl]. This patch sorts the include files for the files [a-f]*.[chyl]. The patch was written by a script. Tested by the buildbot. I will follow up with patches to sort the remaining files, by sorting a subset, testing them, and then checking them in. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> * ft32-tdep.c: Sort headers. * frv-tdep.c: Sort headers. * frv-linux-tdep.c: Sort headers. * frame.c: Sort headers. * frame-unwind.c: Sort headers. * frame-base.c: Sort headers. * fork-child.c: Sort headers. * findvar.c: Sort headers. * findcmd.c: Sort headers. * filesystem.c: Sort headers. * filename-seen-cache.h: Sort headers. * filename-seen-cache.c: Sort headers. * fbsd-tdep.c: Sort headers. * fbsd-nat.h: Sort headers. * fbsd-nat.c: Sort headers. * f-valprint.c: Sort headers. * f-typeprint.c: Sort headers. * f-lang.c: Sort headers. * extension.h: Sort headers. * extension.c: Sort headers. * extension-priv.h: Sort headers. * expprint.c: Sort headers. * exec.h: Sort headers. * exec.c: Sort headers. * exceptions.c: Sort headers. * event-top.c: Sort headers. * event-loop.c: Sort headers. * eval.c: Sort headers. * elfread.c: Sort headers. * dwarf2read.h: Sort headers. * dwarf2read.c: Sort headers. * dwarf2loc.c: Sort headers. * dwarf2expr.h: Sort headers. * dwarf2expr.c: Sort headers. * dwarf2-frame.c: Sort headers. * dwarf2-frame-tailcall.c: Sort headers. * dwarf-index-write.h: Sort headers. * dwarf-index-write.c: Sort headers. * dwarf-index-common.c: Sort headers. * dwarf-index-cache.h: Sort headers. * dwarf-index-cache.c: Sort headers. * dummy-frame.c: Sort headers. * dtrace-probe.c: Sort headers. * disasm.h: Sort headers. * disasm.c: Sort headers. * disasm-selftests.c: Sort headers. * dictionary.c: Sort headers. * dicos-tdep.c: Sort headers. * demangle.c: Sort headers. * dcache.h: Sort headers. * dcache.c: Sort headers. * darwin-nat.h: Sort headers. * darwin-nat.c: Sort headers. * darwin-nat-info.c: Sort headers. * d-valprint.c: Sort headers. * d-namespace.c: Sort headers. * d-lang.c: Sort headers. * ctf.c: Sort headers. * csky-tdep.c: Sort headers. * csky-linux-tdep.c: Sort headers. * cris-tdep.c: Sort headers. * cris-linux-tdep.c: Sort headers. * cp-valprint.c: Sort headers. * cp-support.c: Sort headers. * cp-namespace.c: Sort headers. * cp-abi.c: Sort headers. * corelow.c: Sort headers. * corefile.c: Sort headers. * continuations.c: Sort headers. * completer.h: Sort headers. * completer.c: Sort headers. * complaints.c: Sort headers. * coffread.c: Sort headers. * coff-pe-read.c: Sort headers. * cli-out.h: Sort headers. * cli-out.c: Sort headers. * charset.c: Sort headers. * c-varobj.c: Sort headers. * c-valprint.c: Sort headers. * c-typeprint.c: Sort headers. * c-lang.c: Sort headers. * buildsym.c: Sort headers. * buildsym-legacy.c: Sort headers. * build-id.h: Sort headers. * build-id.c: Sort headers. * btrace.c: Sort headers. * bsd-uthread.c: Sort headers. * breakpoint.h: Sort headers. * breakpoint.c: Sort headers. * break-catch-throw.c: Sort headers. * break-catch-syscall.c: Sort headers. * break-catch-sig.c: Sort headers. * blockframe.c: Sort headers. * block.c: Sort headers. * bfin-tdep.c: Sort headers. * bfin-linux-tdep.c: Sort headers. * bfd-target.c: Sort headers. * bcache.c: Sort headers. * ax-general.c: Sort headers. * ax-gdb.h: Sort headers. * ax-gdb.c: Sort headers. * avr-tdep.c: Sort headers. * auxv.c: Sort headers. * auto-load.c: Sort headers. * arm-wince-tdep.c: Sort headers. * arm-tdep.c: Sort headers. * arm-symbian-tdep.c: Sort headers. * arm-pikeos-tdep.c: Sort headers. * arm-obsd-tdep.c: Sort headers. * arm-nbsd-tdep.c: Sort headers. * arm-nbsd-nat.c: Sort headers. * arm-linux-tdep.c: Sort headers. * arm-linux-nat.c: Sort headers. * arm-fbsd-tdep.c: Sort headers. * arm-fbsd-nat.c: Sort headers. * arm-bsd-tdep.c: Sort headers. * arch-utils.c: Sort headers. * arc-tdep.c: Sort headers. * arc-newlib-tdep.c: Sort headers. * annotate.h: Sort headers. * annotate.c: Sort headers. * amd64-windows-tdep.c: Sort headers. * amd64-windows-nat.c: Sort headers. * amd64-tdep.c: Sort headers. * amd64-sol2-tdep.c: Sort headers. * amd64-obsd-tdep.c: Sort headers. * amd64-obsd-nat.c: Sort headers. * amd64-nbsd-tdep.c: Sort headers. * amd64-nbsd-nat.c: Sort headers. * amd64-nat.c: Sort headers. * amd64-linux-tdep.c: Sort headers. * amd64-linux-nat.c: Sort headers. * amd64-fbsd-tdep.c: Sort headers. * amd64-fbsd-nat.c: Sort headers. * amd64-dicos-tdep.c: Sort headers. * amd64-darwin-tdep.c: Sort headers. * amd64-bsd-nat.c: Sort headers. * alpha-tdep.c: Sort headers. * alpha-obsd-tdep.c: Sort headers. * alpha-nbsd-tdep.c: Sort headers. * alpha-mdebug-tdep.c: Sort headers. * alpha-linux-tdep.c: Sort headers. * alpha-linux-nat.c: Sort headers. * alpha-bsd-tdep.c: Sort headers. * alpha-bsd-nat.c: Sort headers. * aix-thread.c: Sort headers. * agent.c: Sort headers. * addrmap.c: Sort headers. * ada-varobj.c: Sort headers. * ada-valprint.c: Sort headers. * ada-typeprint.c: Sort headers. * ada-tasks.c: Sort headers. * ada-lang.c: Sort headers. * aarch64-tdep.c: Sort headers. * aarch64-ravenscar-thread.c: Sort headers. * aarch64-newlib-tdep.c: Sort headers. * aarch64-linux-tdep.c: Sort headers. * aarch64-linux-nat.c: Sort headers. * aarch64-fbsd-tdep.c: Sort headers. * aarch64-fbsd-nat.c: Sort headers. * aarch32-linux-nat.c: Sort headers.
2019-04-03 10:04:24 +08:00
#include "dis-asm.h"
#include "disasm-flags.h"
Add Guile as an extension language. * NEWS: Mention Guile scripting. * Makefile.in (SUBDIR_GUILE_OBS): New variable. (SUBDIR_GUILE_SRCS, SUBDIR_GUILE_DEPS): New variables (SUBDIR_GUILE_LDFLAGS, SUBDIR_GUILE_CFLAGS): New variables. (INTERNAL_CPPFLAGS): Add GUILE_CPPFLAGS. (CLIBS): Add GUILE_LIBS. (install-guile): New rule. (guile.o): New rule. (scm-arch.o, scm-auto-load.o, scm-block.o): New rules. (scm-breakpoint.o, scm-disasm.o, scm-exception.o): New rules. (scm-frame.o, scm-iterator.o, scm-lazy-string.o): New rules. (scm-math.o, scm-objfile.o, scm-ports.o): New rules. (scm-pretty-print.o, scm-safe-call.o, scm-gsmob.o): New rules. (scm-string.o, scm-symbol.o, scm-symtab.o): New rules. (scm-type.o, scm-utils.o, scm-value.o): New rules. * configure.ac: New option --with-guile. * configure: Regenerate. * config.in: Regenerate. * auto-load.c: Remove #include "python/python.h". Add #include "gdb/section-scripts.h". (source_section_scripts): Handle Guile scripts. (_initialize_auto_load): Add name of Guile objfile script to scripts-directory help text. * breakpoint.c (condition_command): Tweak comment to include Scheme. * breakpoint.h (gdbscm_breakpoint_object): Add forward decl. (struct breakpoint): New member scm_bp_object. * defs.h (enum command_control_type): New value guile_control. * cli/cli-cmds.c: Remove #include "python/python.h". Add #include "extension.h". (show_user): Update comment. (_initialize_cli_cmds): Update help text for "show user". Update help text for max-user-call-depth. * cli/cli-script.c: Remove #include "python/python.h". Add #include "extension.h". (multi_line_command_p): Add guile_control. (print_command_lines): Handle guile_control. (execute_control_command, recurse_read_control_structure): Ditto. (process_next_line): Recognize "guile" commands. * disasm.c (gdb_disassemble_info): Make non-static. * disasm.h: #include "dis-asm.h". (struct gdbarch): Add forward decl. (gdb_disassemble_info): Declare. * extension.c: #include "guile/guile.h". (extension_languages): Add guile. (get_ext_lang_defn): Handle EXT_LANG_GDB. * extension.h (enum extension_language): New value EXT_LANG_GUILE. * gdbtypes.c (get_unsigned_type_max): New function. (get_signed_type_minmax): New function. * gdbtypes.h (get_unsigned_type_max): Declare. (get_signed_type_minmax): Declare. * guile/README: New file. * guile/guile-internal.h: New file. * guile/guile.c: New file. * guile/guile.h: New file. * guile/scm-arch.c: New file. * guile/scm-auto-load.c: New file. * guile/scm-block.c: New file. * guile/scm-breakpoint.c: New file. * guile/scm-disasm.c: New file. * guile/scm-exception.c: New file. * guile/scm-frame.c: New file. * guile/scm-gsmob.c: New file. * guile/scm-iterator.c: New file. * guile/scm-lazy-string.c: New file. * guile/scm-math.c: New file. * guile/scm-objfile.c: New file. * guile/scm-ports.c: New file. * guile/scm-pretty-print.c: New file. * guile/scm-safe-call.c: New file. * guile/scm-string.c: New file. * guile/scm-symbol.c: New file. * guile/scm-symtab.c: New file. * guile/scm-type.c: New file. * guile/scm-utils.c: New file. * guile/scm-value.c: New file. * guile/lib/gdb.scm: New file. * guile/lib/gdb/boot.scm: New file. * guile/lib/gdb/experimental.scm: New file. * guile/lib/gdb/init.scm: New file. * guile/lib/gdb/iterator.scm: New file. * guile/lib/gdb/printing.scm: New file. * guile/lib/gdb/types.scm: New file. * data-directory/Makefile.in (GUILE_SRCDIR): New variable. (VPATH): Add $(GUILE_SRCDIR). (GUILE_DIR): New variable. (GUILE_INSTALL_DIR, GUILE_FILES): New variables. (all): Add stamp-guile dependency. (stamp-guile): New rule. (clean-guile, install-guile, uninstall-guile): New rules. (install-only): Add install-guile dependency. (uninstall): Add uninstall-guile dependency. (clean): Add clean-guile dependency. doc/ * Makefile.in (GDB_DOC_FILES): Add guile.texi. * gdb.texinfo (Auto-loading): Add set/show auto-load guile-scripts. (Extending GDB): New menu entries Guile, Multiple Extension Languages. (Guile docs): Include guile.texi. (objfile-gdbdotext file): Add objfile-gdb.scm. (dotdebug_gdb_scripts section): Mention Guile scripts. (Multiple Extension Languages): New node. * guile.texi: New file. testsuite/ * configure.ac (AC_OUTPUT): Add gdb.guile. * configure: Regenerate. * lib/gdb-guile.exp: New file. * lib/gdb.exp (get_target_charset): New function. * gdb.base/help.exp: Update expected output from "apropos apropos". * gdb.guile/Makefile.in: New file. * gdb.guile/guile.exp: New file. * gdb.guile/scm-arch.c: New file. * gdb.guile/scm-arch.exp: New file. * gdb.guile/scm-block.c: New file. * gdb.guile/scm-block.exp: New file. * gdb.guile/scm-breakpoint.c: New file. * gdb.guile/scm-breakpoint.exp: New file. * gdb.guile/scm-disasm.c: New file. * gdb.guile/scm-disasm.exp: New file. * gdb.guile/scm-equal.c: New file. * gdb.guile/scm-equal.exp: New file. * gdb.guile/scm-error.exp: New file. * gdb.guile/scm-error.scm: New file. * gdb.guile/scm-frame-args.c: New file. * gdb.guile/scm-frame-args.exp: New file. * gdb.guile/scm-frame-args.scm: New file. * gdb.guile/scm-frame-inline.c: New file. * gdb.guile/scm-frame-inline.exp: New file. * gdb.guile/scm-frame.c: New file. * gdb.guile/scm-frame.exp: New file. * gdb.guile/scm-generics.exp: New file. * gdb.guile/scm-gsmob.exp: New file. * gdb.guile/scm-iterator.c: New file. * gdb.guile/scm-iterator.exp: New file. * gdb.guile/scm-math.c: New file. * gdb.guile/scm-math.exp: New file. * gdb.guile/scm-objfile-script-gdb.in: New file. * gdb.guile/scm-objfile-script.c: New file. * gdb.guile/scm-objfile-script.exp: New file. * gdb.guile/scm-objfile.c: New file. * gdb.guile/scm-objfile.exp: New file. * gdb.guile/scm-ports.exp: New file. * gdb.guile/scm-pretty-print.c: New file. * gdb.guile/scm-pretty-print.exp: New file. * gdb.guile/scm-pretty-print.scm: New file. * gdb.guile/scm-section-script.c: New file. * gdb.guile/scm-section-script.exp: New file. * gdb.guile/scm-section-script.scm: New file. * gdb.guile/scm-symbol.c: New file. * gdb.guile/scm-symbol.exp: New file. * gdb.guile/scm-symtab-2.c: New file. * gdb.guile/scm-symtab.c: New file. * gdb.guile/scm-symtab.exp: New file. * gdb.guile/scm-type.c: New file. * gdb.guile/scm-type.exp: New file. * gdb.guile/scm-value-cc.cc: New file. * gdb.guile/scm-value-cc.exp: New file. * gdb.guile/scm-value.c: New file. * gdb.guile/scm-value.exp: New file. * gdb.guile/source2.scm: New file. * gdb.guile/types-module.cc: New file. * gdb.guile/types-module.exp: New file.
2014-02-10 11:40:01 +08:00
struct gdbarch;
struct ui_out;
struct ui_file;
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
/* A wrapper around a disassemble_info and a gdbarch. This is the core
set of data that all disassembler sub-classes will need. This class
doesn't actually implement the disassembling process, that is something
that sub-classes will do, with each sub-class doing things slightly
differently.
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
The constructor of this class is protected, you should not create
instances of this class directly, instead create an instance of an
appropriate sub-class. */
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
struct gdb_disassemble_info
{
DISABLE_COPY_AND_ASSIGN (gdb_disassemble_info);
Refactor disassembly code This patch addes class gdb_disassembler, and refactor code to use it. The gdb_disassembler object is saved in disassember_info.application_data. However, disassember_info.application_data is already used by gdb for arm, mips spu, and scm-disasm. In arm and mips, .application_data is gdbarch, but we can still get gdbarch from gdb_disassember. The use of application_data in spu is a little bit complicated. It creates its own disassemble_info, and save spu_dis_asm_data in .application_data. This will overwrite the pointer to gdb_disassembler, so we need to find another place to save spu_dis_asm_data. I extend disassemble_info, and put "id" there. gdb: 2017-01-26 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * arm-tdep.c: Include "disasm.h". (gdb_print_insn_arm): Update code to get gdbarch. * disasm.c (dis_asm_read_memory): Change it to gdb_disassembler::dis_asm_read_memory. (dis_asm_memory_error): Likewise. (dis_asm_print_address): Likewise. (gdb_pretty_print_insn): Change it to gdb_disassembler::pretty_print_insn. (dump_insns): Add one argument gdb_disassemlber. All callers updated. (do_mixed_source_and_assembly_deprecated): Likewise. (do_mixed_source_and_assembly): Likewise. (do_assembly_only): Likewise. (gdb_disassembler::gdb_disassembler): New. (gdb_disassembler::print_insn): New. * disasm.h (class gdb_disassembler): New. (gdb_pretty_print_insn): Remove declaration. (gdb_disassemble_info): Likewise. * guile/scm-disasm.c (class gdbscm_disassembler): New. (gdbscm_disasm_read_memory_worker): Update. (gdbscm_disasm_read_memory): Update. (gdbscm_disasm_memory_error): Remove. (gdbscm_disasm_print_address): Remove. (gdbscm_disassembler::gdbscm_disassembler): New. (gdbscm_print_insn_from_port): Update. * mips-tdep.c: Include disasm.h. (gdb_print_insn_mips): Update code to get gdbarch. * record-btrace.c (btrace_insn_history): Update. * spu-tdep.c: Include disasm.h. (struct spu_dis_asm_data): Remove. (struct spu_dis_asm_info): New. (spu_dis_asm_print_address): Use spu_dis_asm_info to get SPU id. (gdb_print_insn_spu): Cast disassemble_info to spu_dis_asm_info.
2017-01-26 22:29:19 +08:00
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
/* Return the gdbarch we are disassembling for. */
Refactor disassembly code This patch addes class gdb_disassembler, and refactor code to use it. The gdb_disassembler object is saved in disassember_info.application_data. However, disassember_info.application_data is already used by gdb for arm, mips spu, and scm-disasm. In arm and mips, .application_data is gdbarch, but we can still get gdbarch from gdb_disassember. The use of application_data in spu is a little bit complicated. It creates its own disassemble_info, and save spu_dis_asm_data in .application_data. This will overwrite the pointer to gdb_disassembler, so we need to find another place to save spu_dis_asm_data. I extend disassemble_info, and put "id" there. gdb: 2017-01-26 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * arm-tdep.c: Include "disasm.h". (gdb_print_insn_arm): Update code to get gdbarch. * disasm.c (dis_asm_read_memory): Change it to gdb_disassembler::dis_asm_read_memory. (dis_asm_memory_error): Likewise. (dis_asm_print_address): Likewise. (gdb_pretty_print_insn): Change it to gdb_disassembler::pretty_print_insn. (dump_insns): Add one argument gdb_disassemlber. All callers updated. (do_mixed_source_and_assembly_deprecated): Likewise. (do_mixed_source_and_assembly): Likewise. (do_assembly_only): Likewise. (gdb_disassembler::gdb_disassembler): New. (gdb_disassembler::print_insn): New. * disasm.h (class gdb_disassembler): New. (gdb_pretty_print_insn): Remove declaration. (gdb_disassemble_info): Likewise. * guile/scm-disasm.c (class gdbscm_disassembler): New. (gdbscm_disasm_read_memory_worker): Update. (gdbscm_disasm_read_memory): Update. (gdbscm_disasm_memory_error): Remove. (gdbscm_disasm_print_address): Remove. (gdbscm_disassembler::gdbscm_disassembler): New. (gdbscm_print_insn_from_port): Update. * mips-tdep.c: Include disasm.h. (gdb_print_insn_mips): Update code to get gdbarch. * record-btrace.c (btrace_insn_history): Update. * spu-tdep.c: Include disasm.h. (struct spu_dis_asm_data): Remove. (struct spu_dis_asm_info): New. (spu_dis_asm_print_address): Use spu_dis_asm_info to get SPU id. (gdb_print_insn_spu): Cast disassemble_info to spu_dis_asm_info.
2017-01-26 22:29:19 +08:00
struct gdbarch *arch ()
{ return m_gdbarch; }
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
/* Return a pointer to the disassemble_info, this will be needed for
passing into the libopcodes disassembler. */
struct disassemble_info *disasm_info ()
{ return &m_di; }
Refactor disassembly code This patch addes class gdb_disassembler, and refactor code to use it. The gdb_disassembler object is saved in disassember_info.application_data. However, disassember_info.application_data is already used by gdb for arm, mips spu, and scm-disasm. In arm and mips, .application_data is gdbarch, but we can still get gdbarch from gdb_disassember. The use of application_data in spu is a little bit complicated. It creates its own disassemble_info, and save spu_dis_asm_data in .application_data. This will overwrite the pointer to gdb_disassembler, so we need to find another place to save spu_dis_asm_data. I extend disassemble_info, and put "id" there. gdb: 2017-01-26 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * arm-tdep.c: Include "disasm.h". (gdb_print_insn_arm): Update code to get gdbarch. * disasm.c (dis_asm_read_memory): Change it to gdb_disassembler::dis_asm_read_memory. (dis_asm_memory_error): Likewise. (dis_asm_print_address): Likewise. (gdb_pretty_print_insn): Change it to gdb_disassembler::pretty_print_insn. (dump_insns): Add one argument gdb_disassemlber. All callers updated. (do_mixed_source_and_assembly_deprecated): Likewise. (do_mixed_source_and_assembly): Likewise. (do_assembly_only): Likewise. (gdb_disassembler::gdb_disassembler): New. (gdb_disassembler::print_insn): New. * disasm.h (class gdb_disassembler): New. (gdb_pretty_print_insn): Remove declaration. (gdb_disassemble_info): Likewise. * guile/scm-disasm.c (class gdbscm_disassembler): New. (gdbscm_disasm_read_memory_worker): Update. (gdbscm_disasm_read_memory): Update. (gdbscm_disasm_memory_error): Remove. (gdbscm_disasm_print_address): Remove. (gdbscm_disassembler::gdbscm_disassembler): New. (gdbscm_print_insn_from_port): Update. * mips-tdep.c: Include disasm.h. (gdb_print_insn_mips): Update code to get gdbarch. * record-btrace.c (btrace_insn_history): Update. * spu-tdep.c: Include disasm.h. (struct spu_dis_asm_data): Remove. (struct spu_dis_asm_info): New. (spu_dis_asm_print_address): Use spu_dis_asm_info to get SPU id. (gdb_print_insn_spu): Cast disassemble_info to spu_dis_asm_info.
2017-01-26 22:29:19 +08:00
protected:
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
/* Types for the function callbacks within m_di. */
using read_memory_ftype = decltype (disassemble_info::read_memory_func);
using memory_error_ftype = decltype (disassemble_info::memory_error_func);
using print_address_ftype = decltype (disassemble_info::print_address_func);
using fprintf_ftype = decltype (disassemble_info::fprintf_func);
using fprintf_styled_ftype = decltype (disassemble_info::fprintf_styled_func);
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
/* Constructor, many fields in m_di are initialized from GDBARCH. The
remaining arguments are function callbacks that are written into m_di.
Of these function callbacks FPRINTF_FUNC and FPRINTF_STYLED_FUNC must
not be nullptr. If READ_MEMORY_FUNC, MEMORY_ERROR_FUNC, or
PRINT_ADDRESS_FUNC are nullptr, then that field within m_di is left
with its default value (see the libopcodes function
init_disassemble_info for the defaults). */
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
gdb_disassemble_info (struct gdbarch *gdbarch,
read_memory_ftype read_memory_func,
memory_error_ftype memory_error_func,
print_address_ftype print_address_func,
fprintf_ftype fprintf_func,
fprintf_styled_ftype fprintf_styled_func);
/* Destructor. */
virtual ~gdb_disassemble_info ();
Refactor disassembly code This patch addes class gdb_disassembler, and refactor code to use it. The gdb_disassembler object is saved in disassember_info.application_data. However, disassember_info.application_data is already used by gdb for arm, mips spu, and scm-disasm. In arm and mips, .application_data is gdbarch, but we can still get gdbarch from gdb_disassember. The use of application_data in spu is a little bit complicated. It creates its own disassemble_info, and save spu_dis_asm_data in .application_data. This will overwrite the pointer to gdb_disassembler, so we need to find another place to save spu_dis_asm_data. I extend disassemble_info, and put "id" there. gdb: 2017-01-26 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * arm-tdep.c: Include "disasm.h". (gdb_print_insn_arm): Update code to get gdbarch. * disasm.c (dis_asm_read_memory): Change it to gdb_disassembler::dis_asm_read_memory. (dis_asm_memory_error): Likewise. (dis_asm_print_address): Likewise. (gdb_pretty_print_insn): Change it to gdb_disassembler::pretty_print_insn. (dump_insns): Add one argument gdb_disassemlber. All callers updated. (do_mixed_source_and_assembly_deprecated): Likewise. (do_mixed_source_and_assembly): Likewise. (do_assembly_only): Likewise. (gdb_disassembler::gdb_disassembler): New. (gdb_disassembler::print_insn): New. * disasm.h (class gdb_disassembler): New. (gdb_pretty_print_insn): Remove declaration. (gdb_disassemble_info): Likewise. * guile/scm-disasm.c (class gdbscm_disassembler): New. (gdbscm_disasm_read_memory_worker): Update. (gdbscm_disasm_read_memory): Update. (gdbscm_disasm_memory_error): Remove. (gdbscm_disasm_print_address): Remove. (gdbscm_disassembler::gdbscm_disassembler): New. (gdbscm_print_insn_from_port): Update. * mips-tdep.c: Include disasm.h. (gdb_print_insn_mips): Update code to get gdbarch. * record-btrace.c (btrace_insn_history): Update. * spu-tdep.c: Include disasm.h. (struct spu_dis_asm_data): Remove. (struct spu_dis_asm_info): New. (spu_dis_asm_print_address): Use spu_dis_asm_info to get SPU id. (gdb_print_insn_spu): Cast disassemble_info to spu_dis_asm_info.
2017-01-26 22:29:19 +08:00
/* Stores data required for disassembling instructions in
opcodes. */
struct disassemble_info m_di;
GDB PR tdep/8282: MIPS: Wire in `set disassembler-options' Implement MIPS target support for passing options to the disassembler, complementing commit 65b48a81404c ("GDB: Add support for the new set/show disassembler-options commands."). This includes options that expect an argument, so adjust the generic code and data structures used so as to handle such options. So as to give backends syntax flexibility no specific delimiter has been defined to separate options from their respective arguments, so it has to be included as the last character of the option name. Completion code however has not been adjusted and consequently option arguments cannot be completed at this time. Also the MIPS target has non-empty defaults for the options, so that ABI names for the general-purpose registers respect our `set mips abi ...' setting rather than always being determined from the ELF headers of the binary file selected. Handle these defaults as implicit options, never shown to the user and always prepended to the user-specified options, so that the latters can override the defaults. The resulting output for the MIPS target is as follows: (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: no-aliases Use canonical instruction forms. msa Recognize MSA instructions. virt Recognize the virtualization ASE instructions. xpa Recognize the eXtended Physical Address (XPA) ASE instructions. ginv Recognize the Global INValidate (GINV) ASE instructions. gpr-names=ABI Print GPR names according to specified ABI. Default: based on binary being disassembled. fpr-names=ABI Print FPR names according to specified ABI. Default: numeric. cp0-names=ARCH Print CP0 register names according to specified architecture. Default: based on binary being disassembled. hwr-names=ARCH Print HWR names according to specified architecture. Default: based on binary being disassembled. reg-names=ABI Print GPR and FPR names according to specified ABI. reg-names=ARCH Print CP0 register and HWR names according to specified architecture. For the options above, the following values are supported for "ABI": numeric 32 n32 64 For the options above, the following values are supported for "ARCH": numeric r3000 r3900 r4000 r4010 vr4100 vr4111 vr4120 r4300 r4400 r4600 r4650 r5000 vr5400 vr5500 r5900 r6000 rm7000 rm9000 r8000 r10000 r12000 r14000 r16000 mips5 mips32 mips32r2 mips32r3 mips32r5 mips32r6 mips64 mips64r2 mips64r3 mips64r5 mips64r6 interaptiv-mr2 sb1 loongson2e loongson2f loongson3a octeon octeon+ octeon2 octeon3 xlr xlp (gdb) which corresponds to what `objdump --help' used to print for the MIPS target, with minor formatting changes, most notably option argument lists being wrapped, but also the amount of white space separating options from the respective descriptions. The relevant part the new code is now also used by `objdump --help', which means these formatting changes apply to both outputs, except for argument list wrapping, which is GDB-specific. This also adds a separating new line between the heading and option lists where descriptions are provided, hence: (gdb) set architecture s390:31-bit (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: esa Disassemble in ESA architecture mode zarch Disassemble in z/Architecture mode insnlength Print unknown instructions according to length from first two bits (gdb) but: (gdb) set architecture powerpc:common (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: 403, 405, 440, 464, 476, 601, 603, 604, 620, 7400, 7410, 7450, 7455, 750cl, 821, 850, 860, a2, altivec, any, booke, booke32, cell, com, e200z4, e300, e500, e500mc, e500mc64, e5500, e6500, e500x2, efs, efs2, power4, power5, power6, power7, power8, power9, ppc, ppc32, 32, ppc64, 64, ppc64bridge, ppcps, pwr, pwr2, pwr4, pwr5, pwr5x, pwr6, pwr7, pwr8, pwr9, pwrx, raw, spe, spe2, titan, vle, vsx (gdb) Existing affected target backends have been adjusted accordingly. This has been verified manually with: (gdb) set architecture arm (gdb) set architecture powerpc:common (gdb) set architecture s390:31-bit to cause no issues with the `show disassembler-options' and `set disassembler-options' commands. A test case for the MIPS target has also been provided, covering the default settings with ABI overrides as well as disassembler option overrides. 2018-07-02 Maciej W. Rozycki <macro@mips.com> Simon Marchi <simon.marchi@polymtl.ca> include/ PR tdep/8282 * dis-asm.h (disasm_option_arg_t): New typedef. (disasm_options_and_args_t): Likewise. (disasm_options_t): Add `arg' member, document members. (disassembler_options_mips): New prototype. (disassembler_options_arm, disassembler_options_powerpc) (disassembler_options_s390): Update prototypes. opcodes/ PR tdep/8282 * mips-dis.c (mips_option_arg_t): New enumeration. (mips_options): New variable. (disassembler_options_mips): New function. (print_mips_disassembler_options): Reimplement in terms of `disassembler_options_mips'. * arm-dis.c (disassembler_options_arm): Adapt to using the `disasm_options_and_args_t' structure. * ppc-dis.c (disassembler_options_powerpc): Likewise. * s390-dis.c (disassembler_options_s390): Likewise. gdb/ PR tdep/8282 * disasm.h (gdb_disassembler): Add `m_disassembler_options_holder'. member * disasm.c (get_all_disassembler_options): New function. (gdb_disassembler::gdb_disassembler): Use it. (gdb_buffered_insn_length_init_dis): Likewise. (gdb_buffered_insn_length): Adjust accordingly. (set_disassembler_options): Handle options with arguments. (show_disassembler_options_sfunc): Likewise. Add a leading new line if showing options with descriptions. (disassembler_options_completer): Adapt to using the `disasm_options_and_args_t' structure. * mips-tdep.c (mips_disassembler_options): New variable. (mips_disassembler_options_o32): Likewise. (mips_disassembler_options_n32): Likewise. (mips_disassembler_options_n64): Likewise. (gdb_print_insn_mips): Don't set `disassembler_options'. (gdb_print_insn_mips_n32, gdb_print_insn_mips_n64): Remove functions. (mips_gdbarch_init): Always set `gdbarch_print_insn' to `gdb_print_insn_mips'. Set `gdbarch_disassembler_options', `gdbarch_disassembler_options_implicit' and `gdbarch_valid_disassembler_options'. * arm-tdep.c (_initialize_arm_tdep): Adapt to using the `disasm_options_and_args_t' structure. * gdbarch.sh (disassembler_options_implicit): New `gdbarch' method. (valid_disassembler_options): Switch from `disasm_options_t' to the `disasm_options_and_args_t' structure. * NEWS: Document `set disassembler-options' support for the MIPS target. * gdbarch.h: Regenerate. * gdbarch.c: Regenerate. gdb/doc/ PR tdep/8282 * gdb.texinfo (Source and Machine Code): Document `set disassembler-options' support for the MIPS target. gdb/testsuite/ PR tdep/8282 * gdb.arch/mips-disassembler-options.exp: New test. * gdb.arch/mips-disassembler-options.s: New test source.
2018-07-03 06:57:21 +08:00
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
private:
/* The architecture we are disassembling for. */
struct gdbarch *m_gdbarch;
GDB PR tdep/8282: MIPS: Wire in `set disassembler-options' Implement MIPS target support for passing options to the disassembler, complementing commit 65b48a81404c ("GDB: Add support for the new set/show disassembler-options commands."). This includes options that expect an argument, so adjust the generic code and data structures used so as to handle such options. So as to give backends syntax flexibility no specific delimiter has been defined to separate options from their respective arguments, so it has to be included as the last character of the option name. Completion code however has not been adjusted and consequently option arguments cannot be completed at this time. Also the MIPS target has non-empty defaults for the options, so that ABI names for the general-purpose registers respect our `set mips abi ...' setting rather than always being determined from the ELF headers of the binary file selected. Handle these defaults as implicit options, never shown to the user and always prepended to the user-specified options, so that the latters can override the defaults. The resulting output for the MIPS target is as follows: (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: no-aliases Use canonical instruction forms. msa Recognize MSA instructions. virt Recognize the virtualization ASE instructions. xpa Recognize the eXtended Physical Address (XPA) ASE instructions. ginv Recognize the Global INValidate (GINV) ASE instructions. gpr-names=ABI Print GPR names according to specified ABI. Default: based on binary being disassembled. fpr-names=ABI Print FPR names according to specified ABI. Default: numeric. cp0-names=ARCH Print CP0 register names according to specified architecture. Default: based on binary being disassembled. hwr-names=ARCH Print HWR names according to specified architecture. Default: based on binary being disassembled. reg-names=ABI Print GPR and FPR names according to specified ABI. reg-names=ARCH Print CP0 register and HWR names according to specified architecture. For the options above, the following values are supported for "ABI": numeric 32 n32 64 For the options above, the following values are supported for "ARCH": numeric r3000 r3900 r4000 r4010 vr4100 vr4111 vr4120 r4300 r4400 r4600 r4650 r5000 vr5400 vr5500 r5900 r6000 rm7000 rm9000 r8000 r10000 r12000 r14000 r16000 mips5 mips32 mips32r2 mips32r3 mips32r5 mips32r6 mips64 mips64r2 mips64r3 mips64r5 mips64r6 interaptiv-mr2 sb1 loongson2e loongson2f loongson3a octeon octeon+ octeon2 octeon3 xlr xlp (gdb) which corresponds to what `objdump --help' used to print for the MIPS target, with minor formatting changes, most notably option argument lists being wrapped, but also the amount of white space separating options from the respective descriptions. The relevant part the new code is now also used by `objdump --help', which means these formatting changes apply to both outputs, except for argument list wrapping, which is GDB-specific. This also adds a separating new line between the heading and option lists where descriptions are provided, hence: (gdb) set architecture s390:31-bit (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: esa Disassemble in ESA architecture mode zarch Disassemble in z/Architecture mode insnlength Print unknown instructions according to length from first two bits (gdb) but: (gdb) set architecture powerpc:common (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: 403, 405, 440, 464, 476, 601, 603, 604, 620, 7400, 7410, 7450, 7455, 750cl, 821, 850, 860, a2, altivec, any, booke, booke32, cell, com, e200z4, e300, e500, e500mc, e500mc64, e5500, e6500, e500x2, efs, efs2, power4, power5, power6, power7, power8, power9, ppc, ppc32, 32, ppc64, 64, ppc64bridge, ppcps, pwr, pwr2, pwr4, pwr5, pwr5x, pwr6, pwr7, pwr8, pwr9, pwrx, raw, spe, spe2, titan, vle, vsx (gdb) Existing affected target backends have been adjusted accordingly. This has been verified manually with: (gdb) set architecture arm (gdb) set architecture powerpc:common (gdb) set architecture s390:31-bit to cause no issues with the `show disassembler-options' and `set disassembler-options' commands. A test case for the MIPS target has also been provided, covering the default settings with ABI overrides as well as disassembler option overrides. 2018-07-02 Maciej W. Rozycki <macro@mips.com> Simon Marchi <simon.marchi@polymtl.ca> include/ PR tdep/8282 * dis-asm.h (disasm_option_arg_t): New typedef. (disasm_options_and_args_t): Likewise. (disasm_options_t): Add `arg' member, document members. (disassembler_options_mips): New prototype. (disassembler_options_arm, disassembler_options_powerpc) (disassembler_options_s390): Update prototypes. opcodes/ PR tdep/8282 * mips-dis.c (mips_option_arg_t): New enumeration. (mips_options): New variable. (disassembler_options_mips): New function. (print_mips_disassembler_options): Reimplement in terms of `disassembler_options_mips'. * arm-dis.c (disassembler_options_arm): Adapt to using the `disasm_options_and_args_t' structure. * ppc-dis.c (disassembler_options_powerpc): Likewise. * s390-dis.c (disassembler_options_s390): Likewise. gdb/ PR tdep/8282 * disasm.h (gdb_disassembler): Add `m_disassembler_options_holder'. member * disasm.c (get_all_disassembler_options): New function. (gdb_disassembler::gdb_disassembler): Use it. (gdb_buffered_insn_length_init_dis): Likewise. (gdb_buffered_insn_length): Adjust accordingly. (set_disassembler_options): Handle options with arguments. (show_disassembler_options_sfunc): Likewise. Add a leading new line if showing options with descriptions. (disassembler_options_completer): Adapt to using the `disasm_options_and_args_t' structure. * mips-tdep.c (mips_disassembler_options): New variable. (mips_disassembler_options_o32): Likewise. (mips_disassembler_options_n32): Likewise. (mips_disassembler_options_n64): Likewise. (gdb_print_insn_mips): Don't set `disassembler_options'. (gdb_print_insn_mips_n32, gdb_print_insn_mips_n64): Remove functions. (mips_gdbarch_init): Always set `gdbarch_print_insn' to `gdb_print_insn_mips'. Set `gdbarch_disassembler_options', `gdbarch_disassembler_options_implicit' and `gdbarch_valid_disassembler_options'. * arm-tdep.c (_initialize_arm_tdep): Adapt to using the `disasm_options_and_args_t' structure. * gdbarch.sh (disassembler_options_implicit): New `gdbarch' method. (valid_disassembler_options): Switch from `disasm_options_t' to the `disasm_options_and_args_t' structure. * NEWS: Document `set disassembler-options' support for the MIPS target. * gdbarch.h: Regenerate. * gdbarch.c: Regenerate. gdb/doc/ PR tdep/8282 * gdb.texinfo (Source and Machine Code): Document `set disassembler-options' support for the MIPS target. gdb/testsuite/ PR tdep/8282 * gdb.arch/mips-disassembler-options.exp: New test. * gdb.arch/mips-disassembler-options.s: New test source.
2018-07-03 06:57:21 +08:00
/* If we own the string in `m_di.disassembler_options', we do so
using this field. */
std::string m_disassembler_options_holder;
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
};
/* A wrapper around gdb_disassemble_info. This class adds default
print functions that are supplied to the disassemble_info within the
parent class. These default print functions write to the stream, which
is also contained in the parent class.
As with the parent class, the constructor for this class is protected,
you should not create instances of this class, but create an
appropriate sub-class instead. */
struct gdb_printing_disassembler : public gdb_disassemble_info
{
DISABLE_COPY_AND_ASSIGN (gdb_printing_disassembler);
protected:
GDB PR tdep/8282: MIPS: Wire in `set disassembler-options' Implement MIPS target support for passing options to the disassembler, complementing commit 65b48a81404c ("GDB: Add support for the new set/show disassembler-options commands."). This includes options that expect an argument, so adjust the generic code and data structures used so as to handle such options. So as to give backends syntax flexibility no specific delimiter has been defined to separate options from their respective arguments, so it has to be included as the last character of the option name. Completion code however has not been adjusted and consequently option arguments cannot be completed at this time. Also the MIPS target has non-empty defaults for the options, so that ABI names for the general-purpose registers respect our `set mips abi ...' setting rather than always being determined from the ELF headers of the binary file selected. Handle these defaults as implicit options, never shown to the user and always prepended to the user-specified options, so that the latters can override the defaults. The resulting output for the MIPS target is as follows: (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: no-aliases Use canonical instruction forms. msa Recognize MSA instructions. virt Recognize the virtualization ASE instructions. xpa Recognize the eXtended Physical Address (XPA) ASE instructions. ginv Recognize the Global INValidate (GINV) ASE instructions. gpr-names=ABI Print GPR names according to specified ABI. Default: based on binary being disassembled. fpr-names=ABI Print FPR names according to specified ABI. Default: numeric. cp0-names=ARCH Print CP0 register names according to specified architecture. Default: based on binary being disassembled. hwr-names=ARCH Print HWR names according to specified architecture. Default: based on binary being disassembled. reg-names=ABI Print GPR and FPR names according to specified ABI. reg-names=ARCH Print CP0 register and HWR names according to specified architecture. For the options above, the following values are supported for "ABI": numeric 32 n32 64 For the options above, the following values are supported for "ARCH": numeric r3000 r3900 r4000 r4010 vr4100 vr4111 vr4120 r4300 r4400 r4600 r4650 r5000 vr5400 vr5500 r5900 r6000 rm7000 rm9000 r8000 r10000 r12000 r14000 r16000 mips5 mips32 mips32r2 mips32r3 mips32r5 mips32r6 mips64 mips64r2 mips64r3 mips64r5 mips64r6 interaptiv-mr2 sb1 loongson2e loongson2f loongson3a octeon octeon+ octeon2 octeon3 xlr xlp (gdb) which corresponds to what `objdump --help' used to print for the MIPS target, with minor formatting changes, most notably option argument lists being wrapped, but also the amount of white space separating options from the respective descriptions. The relevant part the new code is now also used by `objdump --help', which means these formatting changes apply to both outputs, except for argument list wrapping, which is GDB-specific. This also adds a separating new line between the heading and option lists where descriptions are provided, hence: (gdb) set architecture s390:31-bit (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: esa Disassemble in ESA architecture mode zarch Disassemble in z/Architecture mode insnlength Print unknown instructions according to length from first two bits (gdb) but: (gdb) set architecture powerpc:common (gdb) show disassembler-options The current disassembler options are '' The following disassembler options are supported for use with the 'set disassembler-options <option>[,<option>...]' command: 403, 405, 440, 464, 476, 601, 603, 604, 620, 7400, 7410, 7450, 7455, 750cl, 821, 850, 860, a2, altivec, any, booke, booke32, cell, com, e200z4, e300, e500, e500mc, e500mc64, e5500, e6500, e500x2, efs, efs2, power4, power5, power6, power7, power8, power9, ppc, ppc32, 32, ppc64, 64, ppc64bridge, ppcps, pwr, pwr2, pwr4, pwr5, pwr5x, pwr6, pwr7, pwr8, pwr9, pwrx, raw, spe, spe2, titan, vle, vsx (gdb) Existing affected target backends have been adjusted accordingly. This has been verified manually with: (gdb) set architecture arm (gdb) set architecture powerpc:common (gdb) set architecture s390:31-bit to cause no issues with the `show disassembler-options' and `set disassembler-options' commands. A test case for the MIPS target has also been provided, covering the default settings with ABI overrides as well as disassembler option overrides. 2018-07-02 Maciej W. Rozycki <macro@mips.com> Simon Marchi <simon.marchi@polymtl.ca> include/ PR tdep/8282 * dis-asm.h (disasm_option_arg_t): New typedef. (disasm_options_and_args_t): Likewise. (disasm_options_t): Add `arg' member, document members. (disassembler_options_mips): New prototype. (disassembler_options_arm, disassembler_options_powerpc) (disassembler_options_s390): Update prototypes. opcodes/ PR tdep/8282 * mips-dis.c (mips_option_arg_t): New enumeration. (mips_options): New variable. (disassembler_options_mips): New function. (print_mips_disassembler_options): Reimplement in terms of `disassembler_options_mips'. * arm-dis.c (disassembler_options_arm): Adapt to using the `disasm_options_and_args_t' structure. * ppc-dis.c (disassembler_options_powerpc): Likewise. * s390-dis.c (disassembler_options_s390): Likewise. gdb/ PR tdep/8282 * disasm.h (gdb_disassembler): Add `m_disassembler_options_holder'. member * disasm.c (get_all_disassembler_options): New function. (gdb_disassembler::gdb_disassembler): Use it. (gdb_buffered_insn_length_init_dis): Likewise. (gdb_buffered_insn_length): Adjust accordingly. (set_disassembler_options): Handle options with arguments. (show_disassembler_options_sfunc): Likewise. Add a leading new line if showing options with descriptions. (disassembler_options_completer): Adapt to using the `disasm_options_and_args_t' structure. * mips-tdep.c (mips_disassembler_options): New variable. (mips_disassembler_options_o32): Likewise. (mips_disassembler_options_n32): Likewise. (mips_disassembler_options_n64): Likewise. (gdb_print_insn_mips): Don't set `disassembler_options'. (gdb_print_insn_mips_n32, gdb_print_insn_mips_n64): Remove functions. (mips_gdbarch_init): Always set `gdbarch_print_insn' to `gdb_print_insn_mips'. Set `gdbarch_disassembler_options', `gdbarch_disassembler_options_implicit' and `gdbarch_valid_disassembler_options'. * arm-tdep.c (_initialize_arm_tdep): Adapt to using the `disasm_options_and_args_t' structure. * gdbarch.sh (disassembler_options_implicit): New `gdbarch' method. (valid_disassembler_options): Switch from `disasm_options_t' to the `disasm_options_and_args_t' structure. * NEWS: Document `set disassembler-options' support for the MIPS target. * gdbarch.h: Regenerate. * gdbarch.c: Regenerate. gdb/doc/ PR tdep/8282 * gdb.texinfo (Source and Machine Code): Document `set disassembler-options' support for the MIPS target. gdb/testsuite/ PR tdep/8282 * gdb.arch/mips-disassembler-options.exp: New test. * gdb.arch/mips-disassembler-options.s: New test source.
2018-07-03 06:57:21 +08:00
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
/* The stream that disassembler output is being written too. */
struct ui_file *stream ()
{ return m_stream; }
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
/* Constructor. All the arguments are just passed to the parent class.
We also add the two print functions to the arguments passed to the
parent. See gdb_disassemble_info for a description of how the
arguments are handled. */
gdb_printing_disassembler (struct gdbarch *gdbarch,
struct ui_file *stream,
read_memory_ftype read_memory_func,
memory_error_ftype memory_error_func,
print_address_ftype print_address_func)
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
: gdb_disassemble_info (gdbarch, read_memory_func,
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
memory_error_func, print_address_func,
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
fprintf_func, fprintf_styled_func),
m_stream (stream)
{
gdb_assert (stream != nullptr);
}
/* Callback used as the disassemble_info's fprintf_func callback. The
DIS_INFO pointer is a pointer to a gdb_printing_disassembler object.
Content is written to the m_stream extracted from DIS_INFO. */
static int fprintf_func (void *dis_info, const char *format, ...)
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
ATTRIBUTE_PRINTF(2,3);
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
/* Callback used as the disassemble_info's fprintf_styled_func callback.
The DIS_INFO pointer is a pointer to a gdb_printing_disassembler
object. Content is written to the m_stream extracted from DIS_INFO. */
static int fprintf_styled_func (void *dis_info,
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
enum disassembler_style style,
const char *format, ...)
ATTRIBUTE_PRINTF(3,4);
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
gdb: add support for disassembler styling using libopcodes This commit extends GDB to make use of libopcodes styling support where available, currently this is just i386 based architectures, and RISC-V. For architectures that don't support styling using libopcodes GDB will fall back to using the Python Pygments package, when the package is available. The new libopcodes based styling has the disassembler identify parts of the disassembled instruction, e.g. registers, immediates, mnemonics, etc, and can style these components differently. Additionally, as the styling is now done in GDB we can add settings to allow the user to configure which colours are used right from the GDB CLI. There's some new maintenance commands: maintenance set libopcodes-styling enabled on|off maintenance show libopcodes-styling These can be used to manually disable use of libopcodes styling. This is a maintenance command as it's not anticipated that a user should need to do this. But, this could be useful for testing, or, in some rare cases, a user might want to override the Python hook used for disassembler styling, and then disable libopcode styling so that GDB falls back to using Python. Right now I would consider this second use case a rare situation, which is why I think a maintenance command is appropriate. When libopcodes is being used for styling then the user can make use of the following new styles: set/show style disassembler comment set/show style disassembler immediate set/show style disassembler mnemonic set/show style disassembler register The disassembler also makes use of the 'address' and 'function' styles to style some parts of the disassembler output. I have also added the following aliases though: set/show style disassembler address set/show style disassembler symbol these are aliases for: set/show style address set/show style function respectively, and exist to make it easier for users to discover disassembler related style settings. The 'address' style is used to style numeric addresses in the disassembler output, while the 'symbol' or 'function' style is used to style the names of symbols in disassembler output. As not every architecture supports libopcodes styling, the maintenance setting 'libopcodes-styling enabled' has an "auto-off" type behaviour. Consider this GDB session: (gdb) show architecture The target architecture is set to "auto" (currently "i386:x86-64"). (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "on". the setting defaults to "on" for architectures that support libopcodes based styling. (gdb) set architecture sparc The target architecture is set to "sparc". (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off" (not supported on architecture "sparc") the setting will show as "off" if the user switches to an architecture that doesn't support libopcodes styling. The underlying setting is still "on" at this point though, if the user switches back to i386:x86-64 then the setting would go back to being "on". (gdb) maintenance set libopcodes-styling enabled off (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off". now the setting is "off" for everyone, even if the user switches back to i386:x86-64 the setting will still show as "off". (gdb) maintenance set libopcodes-styling enabled on Use of libopcodes styling not supported on architecture "sparc". (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off". attempting to switch the setting "on" for an unsupported architecture will give an error, and the setting will remain "off". (gdb) set architecture auto The target architecture is set to "auto" (currently "i386:x86-64"). (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off". (gdb) maintenance set libopcodes-styling enabled on (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "on". the user will need to switch back to a supported architecture before they can one again turn this setting "on".
2022-02-14 22:40:52 +08:00
/* Return true if the disassembler is considered inside a comment, false
otherwise. */
bool in_comment_p () const
{ return m_in_comment; }
/* Set whether the disassembler should be considered as within comment
text or not. */
void set_in_comment (bool c)
{ m_in_comment = c; }
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
private:
/* When libopcodes calls the fprintf_func and fprintf_styled_func
callbacks, a 'void *' argument is passed. We arrange, through our
call to init_disassemble_info that this argument will be a pointer to
a gdb_disassemble_info sub-class, specifically, a
gdb_printing_disassembler pointer. This helper function casts
DIS_INFO to the correct type (with some asserts), and then returns the
m_stream member variable. */
static ui_file *stream_from_gdb_disassemble_info (void *dis_info);
/* The stream to which output should be sent. */
struct ui_file *m_stream;
gdb: add support for disassembler styling using libopcodes This commit extends GDB to make use of libopcodes styling support where available, currently this is just i386 based architectures, and RISC-V. For architectures that don't support styling using libopcodes GDB will fall back to using the Python Pygments package, when the package is available. The new libopcodes based styling has the disassembler identify parts of the disassembled instruction, e.g. registers, immediates, mnemonics, etc, and can style these components differently. Additionally, as the styling is now done in GDB we can add settings to allow the user to configure which colours are used right from the GDB CLI. There's some new maintenance commands: maintenance set libopcodes-styling enabled on|off maintenance show libopcodes-styling These can be used to manually disable use of libopcodes styling. This is a maintenance command as it's not anticipated that a user should need to do this. But, this could be useful for testing, or, in some rare cases, a user might want to override the Python hook used for disassembler styling, and then disable libopcode styling so that GDB falls back to using Python. Right now I would consider this second use case a rare situation, which is why I think a maintenance command is appropriate. When libopcodes is being used for styling then the user can make use of the following new styles: set/show style disassembler comment set/show style disassembler immediate set/show style disassembler mnemonic set/show style disassembler register The disassembler also makes use of the 'address' and 'function' styles to style some parts of the disassembler output. I have also added the following aliases though: set/show style disassembler address set/show style disassembler symbol these are aliases for: set/show style address set/show style function respectively, and exist to make it easier for users to discover disassembler related style settings. The 'address' style is used to style numeric addresses in the disassembler output, while the 'symbol' or 'function' style is used to style the names of symbols in disassembler output. As not every architecture supports libopcodes styling, the maintenance setting 'libopcodes-styling enabled' has an "auto-off" type behaviour. Consider this GDB session: (gdb) show architecture The target architecture is set to "auto" (currently "i386:x86-64"). (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "on". the setting defaults to "on" for architectures that support libopcodes based styling. (gdb) set architecture sparc The target architecture is set to "sparc". (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off" (not supported on architecture "sparc") the setting will show as "off" if the user switches to an architecture that doesn't support libopcodes styling. The underlying setting is still "on" at this point though, if the user switches back to i386:x86-64 then the setting would go back to being "on". (gdb) maintenance set libopcodes-styling enabled off (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off". now the setting is "off" for everyone, even if the user switches back to i386:x86-64 the setting will still show as "off". (gdb) maintenance set libopcodes-styling enabled on Use of libopcodes styling not supported on architecture "sparc". (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off". attempting to switch the setting "on" for an unsupported architecture will give an error, and the setting will remain "off". (gdb) set architecture auto The target architecture is set to "auto" (currently "i386:x86-64"). (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "off". (gdb) maintenance set libopcodes-styling enabled on (gdb) maintenance show libopcodes-styling enabled Use of libopcodes styling support is "on". the user will need to switch back to a supported architecture before they can one again turn this setting "on".
2022-02-14 22:40:52 +08:00
/* Are we inside a comment? This will be set true if the disassembler
uses styled output and emits a start of comment character. It is up
to the code that uses this disassembler class to reset this flag back
to false at a suitable time (e.g. at the end of every line). */
bool m_in_comment = false;
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
};
gdb: refactor the non-printing disassemblers This commit started from an observation I made while working on some other disassembler patches, that is, that the function gdb_buffered_insn_length, is broken ... sort of. I noticed that the gdb_buffered_insn_length function doesn't set up the application data field if the disassemble_info structure. Further, I noticed that some architectures, for example, ARM, require that the application_data field be set, see gdb_print_insn_arm in arm-tdep.c. And so, if we ever use gdb_buffered_insn_length for ARM, then GDB will likely crash. Which is why I said only "sort of" broken. Right now we don't use gdb_buffered_insn_length with ARM, so maybe it isn't broken yet? Anyway to prove to myself that there was a problem here I extended the disassembler self tests in disasm-selftests.c to include a test of gdb_buffered_insn_length. As I run the test for all architectures, I do indeed see GDB crash for ARM. To fix this we need gdb_buffered_insn_length to create a disassembler that inherits from gdb_disassemble_info, but we also need this new disassembler to not print anything. And so, I introduce a new gdb_non_printing_disassembler class, this is a disassembler that doesn't print anything to the output stream. I then observed that both ARC and S12Z also create non-printing disassemblers, but these are slightly different. While the disassembler in gdb_non_printing_disassembler reads the instruction from a buffer, the ARC and S12Z disassemblers read from target memory using target_read_code. And so, I further split gdb_non_printing_disassembler into two sub-classes, gdb_non_printing_memory_disassembler and gdb_non_printing_buffer_disassembler. The new selftests now pass, but otherwise, there should be no user visible changes after this commit.
2022-04-04 22:48:19 +08:00
/* A basic disassembler that doesn't actually print anything. */
struct gdb_non_printing_disassembler : public gdb_disassemble_info
{
gdb_non_printing_disassembler (struct gdbarch *gdbarch,
read_memory_ftype read_memory_func)
gdb: have gdb_disassemble_info carry 'this' in its stream pointer The gdb_disassemble_info class is a wrapper around the libopcodes disassemble_info struct. The 'stream' field of disassemble_info is passed as an argument to the fprintf_func and fprintf_styled_func callbacks when the disassembler wants to print anything. Previously, GDB would store a pointer to a ui_file object in the 'stream' field, then, when the disassembler wanted to print anything, the content would be written to the ui_file object. An example of an fprintf_func callback, from gdb/disasm.c is: int gdb_disassembler::dis_asm_fprintf (void *stream, const char *format, ...) { /* Write output to STREAM here. */ } This is fine, but has one limitation, within the print callbacks we only have access to STREAM, we can't access any additional state stored within the gdb_disassemble_info object. Right now this isn't a problem, but in a future commit this will become an issue, how we style the output being written to STREAM will depend on the state of the gdb_disassemble_info object, and this state might need to be updated, depending on what is being printed. In this commit I propose changing the 'stream' field of the disassemble_info to carry a pointer to the gdb_disassemble_info sub-class, rather than the stream itself. We then have the two sub-classes of gdb_disassemble_info to consider, the gdb_non_printing_disassembler class never cared about the stream, previously, for this class, the stream was nullptr. With the change to make stream be a gdb_disassemble_info pointer, no further updates are needed for gdb_non_printing_disassembler. The other sub-class is gdb_printing_disassembler. In this case the sub-class now carries around a pointer to the stream object. The print callbacks are updated to cast the incoming stream object back to a gdb_printing_disassembler, and then extract the stream. This is purely a refactoring commit. A later commit will add additional state to the gdb_printing_disassembler, and update the print callbacks to access this state. There should be no user visible changes after this commit.
2022-04-05 18:06:16 +08:00
: gdb_disassemble_info (gdbarch,
gdb: refactor the non-printing disassemblers This commit started from an observation I made while working on some other disassembler patches, that is, that the function gdb_buffered_insn_length, is broken ... sort of. I noticed that the gdb_buffered_insn_length function doesn't set up the application data field if the disassemble_info structure. Further, I noticed that some architectures, for example, ARM, require that the application_data field be set, see gdb_print_insn_arm in arm-tdep.c. And so, if we ever use gdb_buffered_insn_length for ARM, then GDB will likely crash. Which is why I said only "sort of" broken. Right now we don't use gdb_buffered_insn_length with ARM, so maybe it isn't broken yet? Anyway to prove to myself that there was a problem here I extended the disassembler self tests in disasm-selftests.c to include a test of gdb_buffered_insn_length. As I run the test for all architectures, I do indeed see GDB crash for ARM. To fix this we need gdb_buffered_insn_length to create a disassembler that inherits from gdb_disassemble_info, but we also need this new disassembler to not print anything. And so, I introduce a new gdb_non_printing_disassembler class, this is a disassembler that doesn't print anything to the output stream. I then observed that both ARC and S12Z also create non-printing disassemblers, but these are slightly different. While the disassembler in gdb_non_printing_disassembler reads the instruction from a buffer, the ARC and S12Z disassemblers read from target memory using target_read_code. And so, I further split gdb_non_printing_disassembler into two sub-classes, gdb_non_printing_memory_disassembler and gdb_non_printing_buffer_disassembler. The new selftests now pass, but otherwise, there should be no user visible changes after this commit.
2022-04-04 22:48:19 +08:00
read_memory_func,
nullptr /* memory_error_func */,
nullptr /* print_address_func */,
null_fprintf_func,
null_fprintf_styled_func)
{ /* Nothing. */ }
private:
/* Callback used as the disassemble_info's fprintf_func callback, this
doesn't write anything to STREAM, but just returns 0. */
static int null_fprintf_func (void *stream, const char *format, ...)
ATTRIBUTE_PRINTF(2,3);
/* Callback used as the disassemble_info's fprintf_styled_func callback,
, this doesn't write anything to STREAM, but just returns 0. */
static int null_fprintf_styled_func (void *stream,
enum disassembler_style style,
const char *format, ...)
ATTRIBUTE_PRINTF(3,4);
};
/* This is a helper class, for use as an additional base-class, by some of
the disassembler classes below. This class just defines a static method
for reading from target memory, which can then be used by the various
disassembler sub-classes. */
struct gdb_disassembler_memory_reader
{
/* Implements the read_memory_func disassemble_info callback. */
static int dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
unsigned int len,
struct disassemble_info *info);
};
gdb: refactor the non-printing disassemblers This commit started from an observation I made while working on some other disassembler patches, that is, that the function gdb_buffered_insn_length, is broken ... sort of. I noticed that the gdb_buffered_insn_length function doesn't set up the application data field if the disassemble_info structure. Further, I noticed that some architectures, for example, ARM, require that the application_data field be set, see gdb_print_insn_arm in arm-tdep.c. And so, if we ever use gdb_buffered_insn_length for ARM, then GDB will likely crash. Which is why I said only "sort of" broken. Right now we don't use gdb_buffered_insn_length with ARM, so maybe it isn't broken yet? Anyway to prove to myself that there was a problem here I extended the disassembler self tests in disasm-selftests.c to include a test of gdb_buffered_insn_length. As I run the test for all architectures, I do indeed see GDB crash for ARM. To fix this we need gdb_buffered_insn_length to create a disassembler that inherits from gdb_disassemble_info, but we also need this new disassembler to not print anything. And so, I introduce a new gdb_non_printing_disassembler class, this is a disassembler that doesn't print anything to the output stream. I then observed that both ARC and S12Z also create non-printing disassemblers, but these are slightly different. While the disassembler in gdb_non_printing_disassembler reads the instruction from a buffer, the ARC and S12Z disassemblers read from target memory using target_read_code. And so, I further split gdb_non_printing_disassembler into two sub-classes, gdb_non_printing_memory_disassembler and gdb_non_printing_buffer_disassembler. The new selftests now pass, but otherwise, there should be no user visible changes after this commit.
2022-04-04 22:48:19 +08:00
/* A non-printing disassemble_info management class. The disassemble_info
setup by this class will not print anything to the output stream (there
is no output stream), and the instruction to be disassembled will be
read from target memory. */
struct gdb_non_printing_memory_disassembler
: public gdb_non_printing_disassembler,
private gdb_disassembler_memory_reader
gdb: refactor the non-printing disassemblers This commit started from an observation I made while working on some other disassembler patches, that is, that the function gdb_buffered_insn_length, is broken ... sort of. I noticed that the gdb_buffered_insn_length function doesn't set up the application data field if the disassemble_info structure. Further, I noticed that some architectures, for example, ARM, require that the application_data field be set, see gdb_print_insn_arm in arm-tdep.c. And so, if we ever use gdb_buffered_insn_length for ARM, then GDB will likely crash. Which is why I said only "sort of" broken. Right now we don't use gdb_buffered_insn_length with ARM, so maybe it isn't broken yet? Anyway to prove to myself that there was a problem here I extended the disassembler self tests in disasm-selftests.c to include a test of gdb_buffered_insn_length. As I run the test for all architectures, I do indeed see GDB crash for ARM. To fix this we need gdb_buffered_insn_length to create a disassembler that inherits from gdb_disassemble_info, but we also need this new disassembler to not print anything. And so, I introduce a new gdb_non_printing_disassembler class, this is a disassembler that doesn't print anything to the output stream. I then observed that both ARC and S12Z also create non-printing disassemblers, but these are slightly different. While the disassembler in gdb_non_printing_disassembler reads the instruction from a buffer, the ARC and S12Z disassemblers read from target memory using target_read_code. And so, I further split gdb_non_printing_disassembler into two sub-classes, gdb_non_printing_memory_disassembler and gdb_non_printing_buffer_disassembler. The new selftests now pass, but otherwise, there should be no user visible changes after this commit.
2022-04-04 22:48:19 +08:00
{
/* Constructor. GDBARCH is the architecture to disassemble for. */
gdb_non_printing_memory_disassembler (struct gdbarch *gdbarch)
:gdb_non_printing_disassembler (gdbarch, dis_asm_read_memory)
{ /* Nothing. */ }
};
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
/* A dissassembler class that provides 'print_insn', a method for
disassembling a single instruction to the output stream. */
struct gdb_disassembler : public gdb_printing_disassembler,
private gdb_disassembler_memory_reader
gdb: add new base class to gdb_disassembler The motivation for this change is an upcoming Python disassembler API that I would like to add. As part of that change I need to create a new disassembler like class that contains a disassemble_info and a gdbarch. The management of these two objects is identical to how we manage these objects within gdb_disassembler, so it might be tempting for my new class to inherit from gdb_disassembler. The problem however, is that gdb_disassembler has a tight connection between its constructor, and its print_insn method. In the constructor the ui_file* that is passed in is replaced with a member variable string_file*, and then in print_insn, the contents of the member variable string_file are printed to the original ui_file*. What this means is that the gdb_disassembler class has a tight coupling between its constructor and print_insn; the class just isn't intended to be used in a situation where print_insn is not going to be called, which is how my (upcoming) sub-class would need to operate. My solution then, is to separate out the management of the disassemble_info and gdbarch into a new gdb_disassemble_info class, and make this class a parent of gdb_disassembler. In arm-tdep.c and mips-tdep.c, where we used to cast the disassemble_info->application_data to a gdb_disassembler, we can now cast to a gdb_disassemble_info as we only need to access the gdbarch information. Now, my new Python disassembler sub-class will still want to print things to an output stream, and so we will want access to the dis_asm_fprintf functionality for printing. However, rather than move this printing code into the gdb_disassemble_info base class, I have added yet another level of hierarchy, a gdb_printing_disassembler, thus the class structure is now: struct gdb_disassemble_info {}; struct gdb_printing_disassembler : public gdb_disassemble_info {}; struct gdb_disassembler : public gdb_printing_disassembler {}; In a later commit my new Python disassembler will inherit from gdb_printing_disassembler. The reason for adding the additional layer to the class hierarchy is that in yet another commit I intend to rewrite the function gdb_buffered_insn_length, and to do this I will be creating yet more disassembler like classes, however, these will not print anything, thus I will add a gdb_non_printing_disassembler class that also inherits from gdb_disassemble_info. Knowing that that change is coming, I've gone with the above class hierarchy now. There should be no user visible changes after this commit.
2021-10-27 17:07:56 +08:00
{
gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file)
: gdb_disassembler (gdbarch, file, dis_asm_read_memory)
{ /* Nothing. */ }
DISABLE_COPY_AND_ASSIGN (gdb_disassembler);
/* Disassemble a single instruction at MEMADDR to the ui_file* that was
passed to the constructor. If a memory error occurs while
disassembling this instruction then an error will be thrown. */
int print_insn (CORE_ADDR memaddr, int *branch_delay_insns = NULL);
protected:
gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file,
read_memory_ftype func);
private:
gdb: improve error reporting from the disassembler If the libopcodes disassembler returns a negative value then this indicates that the disassembly failed for some reason. In disas.c, in the function gdb_disassembler::print_insn we can see how this is handled; when we get a negative value back, we call the memory_error function, which throws an exception. The problem here is that the address used in the memory_error call is gdb_disassembler::m_err_memaddr, which is set in gdb_disassembler::dis_asm_memory_error, which is called from within the libopcodes disassembler through the disassembler_info::memory_error_func callback. However, for this to work correctly, every time the libopcodes disassembler returns a negative value, the libopcodes disassembler must have first called the memory_error_func callback. My first plan was to make m_err_memaddr a gdb::optional, and assert that it always had a value prior to calling memory_error, however, a quick look in opcodes/*-dis.c shows that there _are_ cases where a negative value is returned without first calling the memory_error_func callback, for example in arc-dis.c and cris-dis.c. Now, I think that a good argument can be made that these disassemblers must therefore be broken, except for the case where we can't read memory, we should always be able to disassemble the memory contents to _something_, even if it's just '.word 0x....'. However, I certainly don't plan to go and fix all of the disassemblers. What I do propose to do then, is make m_err_memaddr a gdb::optional, but now, instead of always calling memory_error, I add a new path which just calls error complaining about an unknown error. This new path is only used if m_err_memaddr doesn't have a value (indicating that the memory_error_func callback was not called). To test this I just augmented one of the disassemblers to always return -1, before this patch I see this: Dump of assembler code for function main: 0x000101aa <+0>: Cannot access memory at address 0x0 And after this commit I now see: Dump of assembler code for function main: 0x000101aa <+0>: unknown disassembler error (error = -1) This doesn't really help much, but that's because there's no way to report non memory errors out of the disasembler, because, it was not expected that the disassembler would ever report non memory errors.
2021-10-05 22:10:12 +08:00
/* This member variable is given a value by calling dis_asm_memory_error.
If after calling into the libopcodes disassembler we get back a
negative value (which indicates an error), then, if this variable has
a value, we report a memory error to the user, otherwise, we report a
non-memory error. */
gdb::optional<CORE_ADDR> m_err_memaddr;
Refactor disassembly code This patch addes class gdb_disassembler, and refactor code to use it. The gdb_disassembler object is saved in disassember_info.application_data. However, disassember_info.application_data is already used by gdb for arm, mips spu, and scm-disasm. In arm and mips, .application_data is gdbarch, but we can still get gdbarch from gdb_disassember. The use of application_data in spu is a little bit complicated. It creates its own disassemble_info, and save spu_dis_asm_data in .application_data. This will overwrite the pointer to gdb_disassembler, so we need to find another place to save spu_dis_asm_data. I extend disassemble_info, and put "id" there. gdb: 2017-01-26 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * arm-tdep.c: Include "disasm.h". (gdb_print_insn_arm): Update code to get gdbarch. * disasm.c (dis_asm_read_memory): Change it to gdb_disassembler::dis_asm_read_memory. (dis_asm_memory_error): Likewise. (dis_asm_print_address): Likewise. (gdb_pretty_print_insn): Change it to gdb_disassembler::pretty_print_insn. (dump_insns): Add one argument gdb_disassemlber. All callers updated. (do_mixed_source_and_assembly_deprecated): Likewise. (do_mixed_source_and_assembly): Likewise. (do_assembly_only): Likewise. (gdb_disassembler::gdb_disassembler): New. (gdb_disassembler::print_insn): New. * disasm.h (class gdb_disassembler): New. (gdb_pretty_print_insn): Remove declaration. (gdb_disassemble_info): Likewise. * guile/scm-disasm.c (class gdbscm_disassembler): New. (gdbscm_disasm_read_memory_worker): Update. (gdbscm_disasm_read_memory): Update. (gdbscm_disasm_memory_error): Remove. (gdbscm_disasm_print_address): Remove. (gdbscm_disassembler::gdbscm_disassembler): New. (gdbscm_print_insn_from_port): Update. * mips-tdep.c: Include disasm.h. (gdb_print_insn_mips): Update code to get gdbarch. * record-btrace.c (btrace_insn_history): Update. * spu-tdep.c: Include disasm.h. (struct spu_dis_asm_data): Remove. (struct spu_dis_asm_info): New. (spu_dis_asm_print_address): Use spu_dis_asm_info to get SPU id. (gdb_print_insn_spu): Cast disassemble_info to spu_dis_asm_info.
2017-01-26 22:29:19 +08:00
gdb: use python to colorize disassembler output This commit adds styling support to the disassembler output, as such two new commands are added to GDB: set style disassembler enabled on|off show style disassembler enabled In this commit I make use of the Python Pygments package to provide the styling. I did investigate making use of libsource-highlight, however, I found the highlighting results to be inferior to those of Pygments; only some mnemonics were highlighted, and highlighting of register names such as r9d and r8d (on x86-64) was incorrect. To enable disassembler highlighting via Pygments, I've added a new extension language hook, which is then implemented for Python. This hook is very similar to the existing hook for source code colorization. One possibly odd choice I made with the new hook is to pass a gdb.Architecture through, even though this is currently unused. The reason this argument is not used is that, currently, styling is performed identically for all architectures. However, even though the Python function used to perform styling of disassembly output is not part of any documented API, I don't want to close the door on a user overriding this function to provide architecture specific styling. To do this, the user would inevitably require access to the gdb.Architecture, and so I decided to add this field now. The styling is applied within gdb_disassembler::print_insn, to achieve this, gdb_disassembler now writes its output into a temporary buffer, styling is then applied to the contents of this buffer. Finally the gdb_disassembler buffer is copied out to its final destination stream. There's a new test to check that the disassembler output includes some escape sequences, though I don't check for specific colours; the precise colors will depend on which instructions are in the disassembler output, and, I guess, how pygments is configured. The only negative change with this commit is how we currently style addresses in GDB. Currently, when the disassembler wants to print an address, we call back into GDB, and GDB prints the address value using the `address` styling, and the symbol name using `function` styling. After this commit, if pygments is used, then all disassembler styling is done through pygments, and this include the address and symbol name parts of the disassembler output. I don't know how much of an issue this will be for people. There's already some precedent for this in GDB when we look at source styling. For example, function names in styled source listings are not styled using the `function` style, but instead, either GNU Source Highlight, or pygments gets to decide how the function name should be styled. If the Python pygments library is not present then GDB will continue to behave as it always has, the disassembler output is mostly unstyled, but the address and symbols are styled using the `address` and `function` styles, as they are today. However, if the user does `set style disassembler enabled off`, then all disassembler styling is switched off. This obviously covers the use of pygments, but also includes the minimal styling done by GDB when pygments is not available.
2021-10-26 00:26:57 +08:00
/* Disassembler output is built up into this buffer. Whether this
string_file is created with styling support or not depends on the
value of use_ext_lang_colorization_p, as well as whether disassembler
styling in general is turned on, and also, whether *m_dest supports
styling or not. */
string_file m_buffer;
/* The stream to which disassembler output will be written. */
ui_file *m_dest;
/* When true, m_buffer will be created without styling support,
otherwise, m_buffer will be created with styling support.
This field will initially be true, but will be set to false if
ext_lang_colorize_disasm fails to add styling at any time.
If the extension language is going to add the styling then m_buffer
should be created without styling support, the extension language will
then add styling at the end of the disassembly process.
If the extension language is not going to add the styling, then we
create m_buffer with styling support, and GDB will add minimal styling
(currently just to addresses and symbols) as it goes. */
static bool use_ext_lang_colorization_p;
Refactor disassembly code This patch addes class gdb_disassembler, and refactor code to use it. The gdb_disassembler object is saved in disassember_info.application_data. However, disassember_info.application_data is already used by gdb for arm, mips spu, and scm-disasm. In arm and mips, .application_data is gdbarch, but we can still get gdbarch from gdb_disassember. The use of application_data in spu is a little bit complicated. It creates its own disassemble_info, and save spu_dis_asm_data in .application_data. This will overwrite the pointer to gdb_disassembler, so we need to find another place to save spu_dis_asm_data. I extend disassemble_info, and put "id" there. gdb: 2017-01-26 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * arm-tdep.c: Include "disasm.h". (gdb_print_insn_arm): Update code to get gdbarch. * disasm.c (dis_asm_read_memory): Change it to gdb_disassembler::dis_asm_read_memory. (dis_asm_memory_error): Likewise. (dis_asm_print_address): Likewise. (gdb_pretty_print_insn): Change it to gdb_disassembler::pretty_print_insn. (dump_insns): Add one argument gdb_disassemlber. All callers updated. (do_mixed_source_and_assembly_deprecated): Likewise. (do_mixed_source_and_assembly): Likewise. (do_assembly_only): Likewise. (gdb_disassembler::gdb_disassembler): New. (gdb_disassembler::print_insn): New. * disasm.h (class gdb_disassembler): New. (gdb_pretty_print_insn): Remove declaration. (gdb_disassemble_info): Likewise. * guile/scm-disasm.c (class gdbscm_disassembler): New. (gdbscm_disasm_read_memory_worker): Update. (gdbscm_disasm_read_memory): Update. (gdbscm_disasm_memory_error): Remove. (gdbscm_disasm_print_address): Remove. (gdbscm_disassembler::gdbscm_disassembler): New. (gdbscm_print_insn_from_port): Update. * mips-tdep.c: Include disasm.h. (gdb_print_insn_mips): Update code to get gdbarch. * record-btrace.c (btrace_insn_history): Update. * spu-tdep.c: Include disasm.h. (struct spu_dis_asm_data): Remove. (struct spu_dis_asm_info): New. (spu_dis_asm_print_address): Use spu_dis_asm_info to get SPU id. (gdb_print_insn_spu): Cast disassemble_info to spu_dis_asm_info.
2017-01-26 22:29:19 +08:00
static void dis_asm_memory_error (int err, bfd_vma memaddr,
struct disassemble_info *info);
static void dis_asm_print_address (bfd_vma addr,
struct disassemble_info *info);
};
disasm: add struct disasm_insn to describe to-be-disassembled instruction The "record instruction-history" command prints for each instruction in addition to the instruction's disassembly: - the instruction number in the recorded execution trace - a '?' before the instruction if it was executed speculatively To allow the "record instruction-history" command to use GDB's disassembly infrastructure, we extend gdb_pretty_print_insn to optionally print those additional fields and export the function. Add a new struct disasm_insn to add additional fields describing the to-be-disassembled instruction. The additional fields are: number an optional instruction number, zero if omitted. is_speculative a predicate saying whether the instruction was executed speculatively. If non-zero, the instruction number is printed first. It will also appear as a new optional field "insn-number" in MI. The field will be present if insn_num is non-zero. If is_speculative is set, speculative execution will be indicated by a "?" following the new instruction number field. Unless the PC is omitted, it will overwrite the first byte of the PC prefix. It will appear as a new optional field "is-speculative" in MI. The field will contain "?" and will be present if is_speculative is set. The speculative execution indication is guarded by a new flag DISASSEMBLY_SPECULATION. Replace the PC parameter of gdb_pretty_print_insn with a pointer to the above struct. GDB's "disassemble" command does not use the new fields. gdb/ * disasm.h (DISASSEMBLY_SPECULATION): New. (struct disasm_insn): New. (gdb_pretty_print_insn): New. * disasm.c (gdb_pretty_print_insn): Replace parameter PC with INSN. Update users. Print instruction number and indicate speculative execution, if requested.
2015-09-11 20:47:08 +08:00
/* An instruction to be disassembled. */
struct disasm_insn
{
/* The address of the memory containing the instruction. */
CORE_ADDR addr;
/* An optional instruction number. If non-zero, it is printed first. */
unsigned int number;
/* True if the instruction was executed speculatively. */
unsigned int is_speculative:1;
};
* disasm.h (gdb_disassembly): Add GDBARCH parameter. (gdb_print_insn): Likewise. * disasm.c (dump_insns): Add GDBARCH parameter. Use it instead of current_gdbarch. (do_mixed_source_and_assembly): Add GDBARCH parameter. Pass to dump_insns. (do_assembly_only): Likewise. (gdb_disassembly): Add GDBARCH parameter. Use it instead of current_gdbarch. Pass to subroutines. (gdb_print_insn): Add GDBARCH parameter. Use it instead of current_gdbarch. * stack.c (struct gdb_disassembly_stub_args): Add GDBARCH member. (gdb_disassembly_stub): Pass architecture to gdb_disassembly. (do_gdb_disassembly): Add GDBARCH argument. Store into args. (print_frame_info): Pass architecture to do_gdb_disassembly. * printcmd.c (print_formatted): Pass architecture to gdb_print_insn. * mi/mi-cmd-disas.c: Include "arch-utils.h" (mi_cmd_disassemble): Pass architecture to gdb_disassembly. * cli/cli-cmds.c: Include "arch-utils.h". (print_disassembly): Add GDBARCH parameter. Pass to gdb_disassembly and tui_show_assembly. (disassemble_current_function): Pass architecture to tui_get_low_disassembly_address and print_disassembly. (disassemble_command): Pass architecture to tui_get_low_disassembly_address and print_disassembly. * tui/tui.c (tui_show_assembly): Add GDBARCH parameter. Pass to tui_update_source_windows_with_addr. * tui/tui-data.h (struct tui_locator_element): Add GDBARCH member. (struct tui_source_info): Likewise. * tui/tui-data.c (tui_clear_win_detail): Clear source_info.gdbarch. * tui/tui-disasm.c (tui_disassemble): Add GDBARCH parameter. Pass to gdb_print_insn. (tui_find_disassembly_address): Add GDBARCH parameter. Pass to tui_disassemble. (tui_set_disassem_content): Add GDBARCH parameter. Install into source_info.gdbarch. Pass to tui_disassemble. (tui_show_disassem): Add GDBARCH parameter. Pass to tui_update_source_window. (tui_show_disassem_and_update_source): Add GDBARCH parameter. Pass to tui_show_disassem and tui_update_source_window. (tui_get_begin_asm_address): Return locator architecture in addition to locator PC value. (tui_get_low_disassembly_address): Add GDBARCH parameter. Pass to tui_get_low_disassembly_address. (tui_vertical_disassem_scroll): Pass architecture to subroutines. * tui/tui-disasm.h (tui_set_disassem_content): Add GDBARCH parameter. (tui_show_disassem): Likewise. (tui_show_disassem_and_update_source): Likewise. (tui_get_begin_asm_address): Return architecture and PC value. * tui/tui.h (tui_get_low_disassembly_address): Add GDBARCH parameter. (tui_show_assembly): Add GDBARCH parameter. * tui/tui-layout.c (extract_display_start_addr): Return current window architecture in addition to current PC value. (tui_set_layout): Update calls to tui_get_low_disassembly_address and extract_display_start_addr. Pass architecture to tui_update_source_windows_with_addr. * tui/tui-source.c: Include "objfiles.h". (tui_set_source_content): Initialize window architecture. (tui_show_symtab_source): Add GDBARCH parameter. Pass to tui_update_source_window_as_is * tui/tui-source.h (tui_show_symtab_source): Add GDBARCH parameter. * tui/tui-stack.c (tui_set_locator_info): Add GDBARCH parameter. Install locator architecture. (tui_set_locator_filename): Update call. (tui_show_frame_info): Pass architecture to tui_set_locator_info and subroutines. * tui/tui-win.c (make_visible_with_new_height): Pass architecture to tui_update_source_window. * tui/tui-winsource.c: Include "objfiles.h". (tui_display_main): Update call to tui_get_begin_asm_address. Pass architecture to tui_update_source_windows_with_addr. (tui_update_source_window): Add GDBARCH parameter. Pass to tui_update_source_window_as_is. (tui_update_source_window_as_is): Add GDBARCH parameter. Pass to tui_set_disassem_content. (tui_update_source_windows_with_addr): Add GDBARCH parameter. Pass to subroutines. (tui_update_source_windows_with_line): Pass objfile architecture to subroutines. (tui_horizontal_source_scroll): Pass architecture to tui_update_source_window_as_is. * tui/tui-winsource.h (tui_update_source_window): Add GDBARCH parameter. (tui_update_source_window_as_is): Likewise. (tui_update_source_windows_with_addr): Likewise.
2009-07-03 01:17:42 +08:00
extern void gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
Introduce gdb_disassembly_flags For some reason I ended up staring at some of the "int flags" in btrace-related code, and I got confused because I had no clue what the flags where supposed to indicate. Fix that by using enum_flags, so that: #1 - it's clear from the type what the flags are about, and #2 - the compiler can catch mismatching mistakes gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * cli/cli-cmds.c (print_disassembly, disassemble_current_function) (disassemble_command): Use gdb_disassembly_flags instead of bare int. * disasm.c (gdb_pretty_print_disassembler::pretty_print_insn) (dump_insns, do_mixed_source_and_assembly_deprecated) (do_mixed_source_and_assembly, do_assembly_only, gdb_disassembly): Use gdb_disassembly_flags instead of bare int. * disasm.h (DISASSEMBLY_SOURCE_DEPRECATED, DISASSEMBLY_RAW_INSN) (DISASSEMBLY_OMIT_FNAME, DISASSEMBLY_FILENAME) (DISASSEMBLY_OMIT_PC, DISASSEMBLY_SOURCE) (DISASSEMBLY_SPECULATIVE): No longer macros. Instead they're... (enum gdb_disassembly_flag): ... values of this new enumeration. (gdb_disassembly_flags): Define. (gdb_disassembly) (gdb_pretty_print_disassembler::pretty_print_insn): Use it. * mi/mi-cmd-disas.c (mi_cmd_disassemble): Use gdb_disassembly_flags instead of bare int. * record-btrace.c (btrace_insn_history) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from): Use gdb_disassembly_flags instead of bare int. * record.c (get_insn_history_modifiers, cmd_record_insn_history): Use gdb_disassembly_flags instead of bare int. * target-debug.h (target_debug_print_gdb_disassembly_flags): Define. * target-delegates.c: Regenerate. * target.c (target_insn_history, target_insn_history_from) (target_insn_history_range): Use gdb_disassembly_flags instead of bare int. * target.h: Include "disasm.h". (struct target_ops) <to_insn_history, to_insn_history_from, to_insn_history_range>: Use gdb_disassembly_flags instead of bare int. (target_insn_history, target_insn_history_from) (target_insn_history_range): Use gdb_disassembly_flags instead of bare int.
2017-09-05 01:23:22 +08:00
gdb_disassembly_flags flags, int how_many,
CORE_ADDR low, CORE_ADDR high);
/* Print the instruction at address MEMADDR in debugged memory,
on STREAM. Returns the length of the instruction, in bytes,
and, if requested, the number of branch delay slot instructions. */
* disasm.h (gdb_disassembly): Add GDBARCH parameter. (gdb_print_insn): Likewise. * disasm.c (dump_insns): Add GDBARCH parameter. Use it instead of current_gdbarch. (do_mixed_source_and_assembly): Add GDBARCH parameter. Pass to dump_insns. (do_assembly_only): Likewise. (gdb_disassembly): Add GDBARCH parameter. Use it instead of current_gdbarch. Pass to subroutines. (gdb_print_insn): Add GDBARCH parameter. Use it instead of current_gdbarch. * stack.c (struct gdb_disassembly_stub_args): Add GDBARCH member. (gdb_disassembly_stub): Pass architecture to gdb_disassembly. (do_gdb_disassembly): Add GDBARCH argument. Store into args. (print_frame_info): Pass architecture to do_gdb_disassembly. * printcmd.c (print_formatted): Pass architecture to gdb_print_insn. * mi/mi-cmd-disas.c: Include "arch-utils.h" (mi_cmd_disassemble): Pass architecture to gdb_disassembly. * cli/cli-cmds.c: Include "arch-utils.h". (print_disassembly): Add GDBARCH parameter. Pass to gdb_disassembly and tui_show_assembly. (disassemble_current_function): Pass architecture to tui_get_low_disassembly_address and print_disassembly. (disassemble_command): Pass architecture to tui_get_low_disassembly_address and print_disassembly. * tui/tui.c (tui_show_assembly): Add GDBARCH parameter. Pass to tui_update_source_windows_with_addr. * tui/tui-data.h (struct tui_locator_element): Add GDBARCH member. (struct tui_source_info): Likewise. * tui/tui-data.c (tui_clear_win_detail): Clear source_info.gdbarch. * tui/tui-disasm.c (tui_disassemble): Add GDBARCH parameter. Pass to gdb_print_insn. (tui_find_disassembly_address): Add GDBARCH parameter. Pass to tui_disassemble. (tui_set_disassem_content): Add GDBARCH parameter. Install into source_info.gdbarch. Pass to tui_disassemble. (tui_show_disassem): Add GDBARCH parameter. Pass to tui_update_source_window. (tui_show_disassem_and_update_source): Add GDBARCH parameter. Pass to tui_show_disassem and tui_update_source_window. (tui_get_begin_asm_address): Return locator architecture in addition to locator PC value. (tui_get_low_disassembly_address): Add GDBARCH parameter. Pass to tui_get_low_disassembly_address. (tui_vertical_disassem_scroll): Pass architecture to subroutines. * tui/tui-disasm.h (tui_set_disassem_content): Add GDBARCH parameter. (tui_show_disassem): Likewise. (tui_show_disassem_and_update_source): Likewise. (tui_get_begin_asm_address): Return architecture and PC value. * tui/tui.h (tui_get_low_disassembly_address): Add GDBARCH parameter. (tui_show_assembly): Add GDBARCH parameter. * tui/tui-layout.c (extract_display_start_addr): Return current window architecture in addition to current PC value. (tui_set_layout): Update calls to tui_get_low_disassembly_address and extract_display_start_addr. Pass architecture to tui_update_source_windows_with_addr. * tui/tui-source.c: Include "objfiles.h". (tui_set_source_content): Initialize window architecture. (tui_show_symtab_source): Add GDBARCH parameter. Pass to tui_update_source_window_as_is * tui/tui-source.h (tui_show_symtab_source): Add GDBARCH parameter. * tui/tui-stack.c (tui_set_locator_info): Add GDBARCH parameter. Install locator architecture. (tui_set_locator_filename): Update call. (tui_show_frame_info): Pass architecture to tui_set_locator_info and subroutines. * tui/tui-win.c (make_visible_with_new_height): Pass architecture to tui_update_source_window. * tui/tui-winsource.c: Include "objfiles.h". (tui_display_main): Update call to tui_get_begin_asm_address. Pass architecture to tui_update_source_windows_with_addr. (tui_update_source_window): Add GDBARCH parameter. Pass to tui_update_source_window_as_is. (tui_update_source_window_as_is): Add GDBARCH parameter. Pass to tui_set_disassem_content. (tui_update_source_windows_with_addr): Add GDBARCH parameter. Pass to subroutines. (tui_update_source_windows_with_line): Pass objfile architecture to subroutines. (tui_horizontal_source_scroll): Pass architecture to tui_update_source_window_as_is. * tui/tui-winsource.h (tui_update_source_window): Add GDBARCH parameter. (tui_update_source_window_as_is): Likewise. (tui_update_source_windows_with_addr): Likewise.
2009-07-03 01:17:42 +08:00
extern int gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
struct ui_file *stream, int *branch_delay_insns);
/* Class used to pretty-print instructions. */
Add back gdb_pretty_print_insn ui_file_rewind is a ui_file method that only really works with mem buffer files, and is a nop on other ui_file types. It'd be desirable to eliminate it from the base ui_file interface, and move it to the "mem_fileopen" subclass of ui_file instead. A following patch does just that. Unfortunately, there are a couple references to ui_file_rewind inside gdb_disassembler::pretty_print_insn that were made harder to eliminate with the recent addition of the gdb_disassembler wrapper. Before the gdb_disassembler wrapper was added, in commit e47ad6c0bd7aa3 ("Refactor disassembly code"), gdb_pretty_print_insn used to be passed a ui_file pointer as argument, and it was simple to adjust that pointer be a "mem_fileopen" ui_file pointer instead, since there's only one gdb_pretty_print_insn caller. That commit made gdb_pretty_print_insn be a method of gdb_disassembler, and removed the method's ui_file parameter at the same time, replaced by referencing the gdb_disassembler's stream instead. The trouble is that a gdb_disassembler can be instantiated with a pointer any kind of ui_file. Casting the gdb_disassembler's stream to a mem_fileopen ui_file inside gdb_disassembler::pretty_print_insn in order to call the reset method would be gross hack. The fix here is to: - make gdb_disassembler::pretty_print_insn a be free function again instead of a method of gdb_disassembler. I.e., bring back gdb_pretty_print_insn. - but, don't add back the ui_file * parameter. Instead, move the mem_fileopen allocation inside. That is a better interface, given that the ui_file is only ever used as temporary scratch buffer as an implementation detail of gdb_pretty_print_insn. The function's real "where to send output" parameter is the ui_out pointer. (A following patch will add back buffer reuse across invocations differently). - don't add back a disassemble_info pointer either. That used to be necessary for this bit: err = m_di.read_memory_func (pc, &data, 1, &m_di); if (err != 0) m_di.memory_error_func (err, pc, &m_di); ... but AFAIK, it's not really necessary. We can replace those three lines with a call to read_code. This seems to fix a regression even, because before commit d8b49cf0c891d0 ("Don't throw exception in dis_asm_memory_error"), that memory_error_func call would throw an error/exception, but now it only records the error in the gdb_disassembler's m_err_memaddr field. (read_code throws on error.) With all these, gdb_pretty_print_insn is completely layered on top of gdb_disassembler only using the latter's public API. gdb/ChangeLog: 2017-02-02 Pedro Alves <palves@redhat.com> * disasm.c (gdb_disassembler::pretty_print_insn): Rename to... (gdb_pretty_print_insn): ... this. Now a free function. Add back a 'gdbarch' parameter. Allocate a mem_fileopen stream here. Adjust to call gdb_print_insn instead of gdb_disassembler::print_insn. (dump_insns, do_mixed_source_and_assembly_deprecated) (do_mixed_source_and_assembly, do_assembly_only): Add back a 'gdbarch' parameter. Remove gdb_disassembler parameter. (gdb_disassembly): Don't allocate a gdb_disassembler here. * disasm.h (gdb_disassembler::pretty_print_insn): Delete declaration. (gdb_pretty_print_insn): Re-add declaration. * record-btrace.c (btrace_insn_history): Don't allocate a gdb_disassembler here. Adjust to call gdb_pretty_print_insn.
2017-02-02 19:11:47 +08:00
class gdb_pretty_print_disassembler
{
public:
explicit gdb_pretty_print_disassembler (struct gdbarch *gdbarch,
struct ui_out *uiout)
: m_uiout (uiout),
m_insn_stb (uiout->can_emit_style_escape ()),
m_di (gdbarch, &m_insn_stb)
{}
/* Prints the instruction INSN into the saved ui_out and returns the
length of the printed instruction in bytes. */
int pretty_print_insn (const struct disasm_insn *insn,
Introduce gdb_disassembly_flags For some reason I ended up staring at some of the "int flags" in btrace-related code, and I got confused because I had no clue what the flags where supposed to indicate. Fix that by using enum_flags, so that: #1 - it's clear from the type what the flags are about, and #2 - the compiler can catch mismatching mistakes gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * cli/cli-cmds.c (print_disassembly, disassemble_current_function) (disassemble_command): Use gdb_disassembly_flags instead of bare int. * disasm.c (gdb_pretty_print_disassembler::pretty_print_insn) (dump_insns, do_mixed_source_and_assembly_deprecated) (do_mixed_source_and_assembly, do_assembly_only, gdb_disassembly): Use gdb_disassembly_flags instead of bare int. * disasm.h (DISASSEMBLY_SOURCE_DEPRECATED, DISASSEMBLY_RAW_INSN) (DISASSEMBLY_OMIT_FNAME, DISASSEMBLY_FILENAME) (DISASSEMBLY_OMIT_PC, DISASSEMBLY_SOURCE) (DISASSEMBLY_SPECULATIVE): No longer macros. Instead they're... (enum gdb_disassembly_flag): ... values of this new enumeration. (gdb_disassembly_flags): Define. (gdb_disassembly) (gdb_pretty_print_disassembler::pretty_print_insn): Use it. * mi/mi-cmd-disas.c (mi_cmd_disassemble): Use gdb_disassembly_flags instead of bare int. * record-btrace.c (btrace_insn_history) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from): Use gdb_disassembly_flags instead of bare int. * record.c (get_insn_history_modifiers, cmd_record_insn_history): Use gdb_disassembly_flags instead of bare int. * target-debug.h (target_debug_print_gdb_disassembly_flags): Define. * target-delegates.c: Regenerate. * target.c (target_insn_history, target_insn_history_from) (target_insn_history_range): Use gdb_disassembly_flags instead of bare int. * target.h: Include "disasm.h". (struct target_ops) <to_insn_history, to_insn_history_from, to_insn_history_range>: Use gdb_disassembly_flags instead of bare int. (target_insn_history, target_insn_history_from) (target_insn_history_range): Use gdb_disassembly_flags instead of bare int.
2017-09-05 01:23:22 +08:00
gdb_disassembly_flags flags);
private:
/* Returns the architecture used for disassembling. */
struct gdbarch *arch () { return m_di.arch (); }
/* The ui_out that is used by pretty_print_insn. */
struct ui_out *m_uiout;
/* The buffer used to build the instruction string. The
disassembler is initialized with this stream. */
string_file m_insn_stb;
/* The disassembler used for instruction printing. */
gdb_disassembler m_di;
/* The buffer used to build the raw opcodes string. */
string_file m_opcode_stb;
};
Add back gdb_pretty_print_insn ui_file_rewind is a ui_file method that only really works with mem buffer files, and is a nop on other ui_file types. It'd be desirable to eliminate it from the base ui_file interface, and move it to the "mem_fileopen" subclass of ui_file instead. A following patch does just that. Unfortunately, there are a couple references to ui_file_rewind inside gdb_disassembler::pretty_print_insn that were made harder to eliminate with the recent addition of the gdb_disassembler wrapper. Before the gdb_disassembler wrapper was added, in commit e47ad6c0bd7aa3 ("Refactor disassembly code"), gdb_pretty_print_insn used to be passed a ui_file pointer as argument, and it was simple to adjust that pointer be a "mem_fileopen" ui_file pointer instead, since there's only one gdb_pretty_print_insn caller. That commit made gdb_pretty_print_insn be a method of gdb_disassembler, and removed the method's ui_file parameter at the same time, replaced by referencing the gdb_disassembler's stream instead. The trouble is that a gdb_disassembler can be instantiated with a pointer any kind of ui_file. Casting the gdb_disassembler's stream to a mem_fileopen ui_file inside gdb_disassembler::pretty_print_insn in order to call the reset method would be gross hack. The fix here is to: - make gdb_disassembler::pretty_print_insn a be free function again instead of a method of gdb_disassembler. I.e., bring back gdb_pretty_print_insn. - but, don't add back the ui_file * parameter. Instead, move the mem_fileopen allocation inside. That is a better interface, given that the ui_file is only ever used as temporary scratch buffer as an implementation detail of gdb_pretty_print_insn. The function's real "where to send output" parameter is the ui_out pointer. (A following patch will add back buffer reuse across invocations differently). - don't add back a disassemble_info pointer either. That used to be necessary for this bit: err = m_di.read_memory_func (pc, &data, 1, &m_di); if (err != 0) m_di.memory_error_func (err, pc, &m_di); ... but AFAIK, it's not really necessary. We can replace those three lines with a call to read_code. This seems to fix a regression even, because before commit d8b49cf0c891d0 ("Don't throw exception in dis_asm_memory_error"), that memory_error_func call would throw an error/exception, but now it only records the error in the gdb_disassembler's m_err_memaddr field. (read_code throws on error.) With all these, gdb_pretty_print_insn is completely layered on top of gdb_disassembler only using the latter's public API. gdb/ChangeLog: 2017-02-02 Pedro Alves <palves@redhat.com> * disasm.c (gdb_disassembler::pretty_print_insn): Rename to... (gdb_pretty_print_insn): ... this. Now a free function. Add back a 'gdbarch' parameter. Allocate a mem_fileopen stream here. Adjust to call gdb_print_insn instead of gdb_disassembler::print_insn. (dump_insns, do_mixed_source_and_assembly_deprecated) (do_mixed_source_and_assembly, do_assembly_only): Add back a 'gdbarch' parameter. Remove gdb_disassembler parameter. (gdb_disassembly): Don't allocate a gdb_disassembler here. * disasm.h (gdb_disassembler::pretty_print_insn): Delete declaration. (gdb_pretty_print_insn): Re-add declaration. * record-btrace.c (btrace_insn_history): Don't allocate a gdb_disassembler here. Adjust to call gdb_pretty_print_insn.
2017-02-02 19:11:47 +08:00
/* Return the length in bytes of the instruction at address MEMADDR in
debugged memory. */
extern int gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR memaddr);
/* Return the length in bytes of INSN, originally at MEMADDR. MAX_LEN
is the size of the buffer containing INSN. */
extern int gdb_buffered_insn_length (struct gdbarch *gdbarch,
const gdb_byte *insn, int max_len,
CORE_ADDR memaddr);
GDB: Add support for the new set/show disassembler-options commands. This commit adds support to GDB so that it can modify the disassembler-options value that is passed to the disassembler, similar to objdump's -M option. Currently, the only supported targets are ARM, PowerPC and S/390, but adding support for a new target(s) is not difficult. include/ * dis-asm.h (disasm_options_t): New typedef. (parse_arm_disassembler_option): Remove prototype. (set_arm_regname_option): Likewise. (get_arm_regnames): Likewise. (get_arm_regname_num_options): Likewise. (disassemble_init_s390): New prototype. (disassembler_options_powerpc): Likewise. (disassembler_options_arm): Likewise. (disassembler_options_s390): Likewise. (remove_whitespace_and_extra_commas): Likewise. (disassembler_options_cmp): Likewise. (next_disassembler_option): New inline function. (FOR_EACH_DISASSEMBLER_OPTION): New macro. opcodes/ * disassemble.c Include "safe-ctype.h". (disassemble_init_for_target): Handle s390 init. (remove_whitespace_and_extra_commas): New function. (disassembler_options_cmp): Likewise. * arm-dis.c: Include "libiberty.h". (NUM_ELEM): Delete. (regnames): Use long disassembler style names. Add force-thumb and no-force-thumb options. (NUM_ARM_REGNAMES): Rename from this... (NUM_ARM_OPTIONS): ...to this. Use ARRAY_SIZE. (get_arm_regname_num_options): Delete. (set_arm_regname_option): Likewise. (get_arm_regnames): Likewise. (parse_disassembler_options): Likewise. (parse_arm_disassembler_option): Rename from this... (parse_arm_disassembler_options): ...to this. Make static. Use new FOR_EACH_DISASSEMBLER_OPTION macro to scan over options. (print_insn): Use parse_arm_disassembler_options. (disassembler_options_arm): New function. (print_arm_disassembler_options): Handle updated regnames. * ppc-dis.c: Include "libiberty.h". (ppc_opts): Add "32" and "64" entries. (ppc_parse_cpu): Use ARRAY_SIZE and disassembler_options_cmp. (powerpc_init_dialect): Add break to switch statement. Use new FOR_EACH_DISASSEMBLER_OPTION macro. (disassembler_options_powerpc): New function. (print_ppc_disassembler_options): Use ARRAY_SIZE. Remove printing of "32" and "64". * s390-dis.c: Include "libiberty.h". (init_flag): Remove unneeded variable. (struct s390_options_t): New structure type. (options): New structure. (init_disasm): Rename from this... (disassemble_init_s390): ...to this. Add initializations for current_arch_mask and option_use_insn_len_bits_p. Remove init_flag. (print_insn_s390): Delete call to init_disasm. (disassembler_options_s390): New function. (print_s390_disassembler_options): Print using information from struct 'options'. * po/opcodes.pot: Regenerate. binutils/ * objdump.c (main): Use remove_whitespace_and_extra_commas. gdb/ * NEWS: Mention new set/show disassembler-options commands. * doc/gdb.texinfo: Document new set/show disassembler-options commands. * disasm.c: Include "arch-utils.h", "gdbcmd.h" and "safe-ctype.h". (prospective_options): New static variable. (gdb_disassembler::gdb_disassembler): Initialize m_di.disassembler_options. (gdb_buffered_insn_length_init_dis): Initilize di->disassembler_options. (get_disassembler_options): New function. (set_disassembler_options): Likewise. (set_disassembler_options_sfunc): Likewise. (show_disassembler_options_sfunc): Likewise. (disassembler_options_completer): Likewise. (_initialize_disasm): Likewise. * disasm.h (get_disassembler_options): New prototype. (set_disassembler_options): Likewise. * gdbarch.sh (gdbarch_disassembler_options): New variable. (gdbarch_verify_disassembler_options): Likewise. * gdbarch.c: Regenerate. * gdbarch.h: Likewise. * arm-tdep.c (num_disassembly_options): Delete. (set_disassembly_style): Likewise. (arm_disassembler_options): New static variable. (set_disassembly_style_sfunc): Convert short style name into long option name. Call set_disassembler_options. (show_disassembly_style_sfunc): New function. (arm_gdbarch_init): Call set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. (_initialize_arm_tdep): Delete regnames variable and update callers. (arm_disassembler_options): Initialize. (disasm_options): New variable. (num_disassembly_options): Rename from this... (num_disassembly_styles): ...to this. Compute by scanning through disasm_options. (valid_disassembly_styles): Initialize using disasm_options. Remove calls to parse_arm_disassembler_option, get_arm_regnames and set_arm_regname_option. Pass show_disassembly_style_sfunc to the "disassembler" setshow command. * rs6000-tdep.c (powerpc_disassembler_options): New static variable. (rs6000_gdbarch_init): Call set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. * s390-tdep.c (s390_disassembler_options): New static variable. (s390_gdbarch_init):all set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. gdb/testsuite/ * gdb.arch/powerpc-power.exp: Delete test. * gdb.arch/powerpc-power.s: Likewise. * gdb.disasm/disassembler-options.exp: New test. * gdb.arch/powerpc-altivec.exp: Likewise. * gdb.arch/powerpc-altivec.s: Likewise. * gdb.arch/powerpc-altivec2.exp: Likewise. * gdb.arch/powerpc-altivec2.s: Likewise. * gdb.arch/powerpc-altivec3.exp: Likewise. * gdb.arch/powerpc-altivec3.s: Likewise. * gdb.arch/powerpc-power7.exp: Likewise. * gdb.arch/powerpc-power7.s: Likewise. * gdb.arch/powerpc-power8.exp: Likewise. * gdb.arch/powerpc-power8.s: Likewise. * gdb.arch/powerpc-power9.exp: Likewise. * gdb.arch/powerpc-power9.s: Likewise. * gdb.arch/powerpc-vsx.exp: Likewise. * gdb.arch/powerpc-vsx.s: Likewise. * gdb.arch/powerpc-vsx2.exp: Likewise. * gdb.arch/powerpc-vsx2.s: Likewise. * gdb.arch/powerpc-vsx3.exp: Likewise. * gdb.arch/powerpc-vsx3.s: Likewise. * gdb.arch/arm-disassembler-options.exp: Likewise. * gdb.arch/powerpc-disassembler-options.exp: Likewise. * gdb.arch/s390-disassembler-options.exp: Likewise.
2017-03-01 02:32:07 +08:00
/* Returns GDBARCH's disassembler options. */
extern char *get_disassembler_options (struct gdbarch *gdbarch);
/* Sets the active gdbarch's disassembler options to OPTIONS. */
gdb: make string-like set show commands use std::string variable String-like settings (var_string, var_filename, var_optional_filename, var_string_noescape) currently take a pointer to a `char *` storage variable (typically global) that holds the setting's value. I'd like to "mordernize" this by changing them to use an std::string for storage. An obvious reason is that string operations on std::string are often easier to write than with C strings. And they avoid having to do any manual memory management. Another interesting reason is that, with `char *`, nullptr and an empty string often both have the same meaning of "no value". String settings are initially nullptr (unless initialized otherwise). But when doing "set foo" (where `foo` is a string setting), the setting now points to an empty string. For example, solib_search_path is nullptr at startup, but points to an empty string after doing "set solib-search-path". This leads to some code that needs to check for both to check for "no value". Or some code that converts back and forth between NULL and "" when getting or setting the value. I find this very error-prone, because it is very easy to forget one or the other. With std::string, we at least know that the variable is not "NULL". There is only one way of representing an empty string setting, that is with an empty string. I was wondering whether the distinction between NULL and "" would be important for some setting, but it doesn't seem so. If that ever happens, it would be more C++-y and self-descriptive to use optional<string> anyway. Actually, there's one spot where this distinction mattered, it's in init_history, for the test gdb.base/gdbinit-history.exp. init_history sets the history filename to the default ".gdb_history" if it sees that the setting was never set - if history_filename is nullptr. If history_filename is an empty string, it means the setting was explicitly cleared, so it leaves it as-is. With the change to std::string, this distinction doesn't exist anymore. This can be fixed by moving the code that chooses a good default value for history_filename to _initialize_top. This is ran before -ex commands are processed, so an -ex command can then clear that value if needed (what gdb.base/gdbinit-history.exp tests). Another small improvement, in my opinion is that we can now easily give string parameters initial values, by simply initializing the global variables, instead of xstrdup-ing it in the _initialize function. In Python and Guile, when registering a string-like parameter, we allocate (with new) an std::string that is owned by the param_smob (in Guile) and the parmpy_object (in Python) objects. This patch started by changing all relevant add_setshow_* commands to take an `std::string *` instead of a `char **` and fixing everything that failed to build. That includes of course all string setting variable and their uses. string_option_def now uses an std::string also, because there's a connection between options and settings (see add_setshow_cmds_for_options). The add_path function in source.c is really complex and twisted, I'd rather not try to change it to work on an std::string right now. Instead, I added an overload that copies the std:string to a `char *` and back. This means more copying, but this is not used in a hot path at all, so I think it is acceptable. Change-Id: I92c50a1bdd8307141cdbacb388248e4e4fc08c93 Co-authored-by: Lancelot SIX <lsix@lancelotsix.com>
2021-09-11 05:10:13 +08:00
extern void set_disassembler_options (const char *options);
GDB: Add support for the new set/show disassembler-options commands. This commit adds support to GDB so that it can modify the disassembler-options value that is passed to the disassembler, similar to objdump's -M option. Currently, the only supported targets are ARM, PowerPC and S/390, but adding support for a new target(s) is not difficult. include/ * dis-asm.h (disasm_options_t): New typedef. (parse_arm_disassembler_option): Remove prototype. (set_arm_regname_option): Likewise. (get_arm_regnames): Likewise. (get_arm_regname_num_options): Likewise. (disassemble_init_s390): New prototype. (disassembler_options_powerpc): Likewise. (disassembler_options_arm): Likewise. (disassembler_options_s390): Likewise. (remove_whitespace_and_extra_commas): Likewise. (disassembler_options_cmp): Likewise. (next_disassembler_option): New inline function. (FOR_EACH_DISASSEMBLER_OPTION): New macro. opcodes/ * disassemble.c Include "safe-ctype.h". (disassemble_init_for_target): Handle s390 init. (remove_whitespace_and_extra_commas): New function. (disassembler_options_cmp): Likewise. * arm-dis.c: Include "libiberty.h". (NUM_ELEM): Delete. (regnames): Use long disassembler style names. Add force-thumb and no-force-thumb options. (NUM_ARM_REGNAMES): Rename from this... (NUM_ARM_OPTIONS): ...to this. Use ARRAY_SIZE. (get_arm_regname_num_options): Delete. (set_arm_regname_option): Likewise. (get_arm_regnames): Likewise. (parse_disassembler_options): Likewise. (parse_arm_disassembler_option): Rename from this... (parse_arm_disassembler_options): ...to this. Make static. Use new FOR_EACH_DISASSEMBLER_OPTION macro to scan over options. (print_insn): Use parse_arm_disassembler_options. (disassembler_options_arm): New function. (print_arm_disassembler_options): Handle updated regnames. * ppc-dis.c: Include "libiberty.h". (ppc_opts): Add "32" and "64" entries. (ppc_parse_cpu): Use ARRAY_SIZE and disassembler_options_cmp. (powerpc_init_dialect): Add break to switch statement. Use new FOR_EACH_DISASSEMBLER_OPTION macro. (disassembler_options_powerpc): New function. (print_ppc_disassembler_options): Use ARRAY_SIZE. Remove printing of "32" and "64". * s390-dis.c: Include "libiberty.h". (init_flag): Remove unneeded variable. (struct s390_options_t): New structure type. (options): New structure. (init_disasm): Rename from this... (disassemble_init_s390): ...to this. Add initializations for current_arch_mask and option_use_insn_len_bits_p. Remove init_flag. (print_insn_s390): Delete call to init_disasm. (disassembler_options_s390): New function. (print_s390_disassembler_options): Print using information from struct 'options'. * po/opcodes.pot: Regenerate. binutils/ * objdump.c (main): Use remove_whitespace_and_extra_commas. gdb/ * NEWS: Mention new set/show disassembler-options commands. * doc/gdb.texinfo: Document new set/show disassembler-options commands. * disasm.c: Include "arch-utils.h", "gdbcmd.h" and "safe-ctype.h". (prospective_options): New static variable. (gdb_disassembler::gdb_disassembler): Initialize m_di.disassembler_options. (gdb_buffered_insn_length_init_dis): Initilize di->disassembler_options. (get_disassembler_options): New function. (set_disassembler_options): Likewise. (set_disassembler_options_sfunc): Likewise. (show_disassembler_options_sfunc): Likewise. (disassembler_options_completer): Likewise. (_initialize_disasm): Likewise. * disasm.h (get_disassembler_options): New prototype. (set_disassembler_options): Likewise. * gdbarch.sh (gdbarch_disassembler_options): New variable. (gdbarch_verify_disassembler_options): Likewise. * gdbarch.c: Regenerate. * gdbarch.h: Likewise. * arm-tdep.c (num_disassembly_options): Delete. (set_disassembly_style): Likewise. (arm_disassembler_options): New static variable. (set_disassembly_style_sfunc): Convert short style name into long option name. Call set_disassembler_options. (show_disassembly_style_sfunc): New function. (arm_gdbarch_init): Call set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. (_initialize_arm_tdep): Delete regnames variable and update callers. (arm_disassembler_options): Initialize. (disasm_options): New variable. (num_disassembly_options): Rename from this... (num_disassembly_styles): ...to this. Compute by scanning through disasm_options. (valid_disassembly_styles): Initialize using disasm_options. Remove calls to parse_arm_disassembler_option, get_arm_regnames and set_arm_regname_option. Pass show_disassembly_style_sfunc to the "disassembler" setshow command. * rs6000-tdep.c (powerpc_disassembler_options): New static variable. (rs6000_gdbarch_init): Call set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. * s390-tdep.c (s390_disassembler_options): New static variable. (s390_gdbarch_init):all set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. gdb/testsuite/ * gdb.arch/powerpc-power.exp: Delete test. * gdb.arch/powerpc-power.s: Likewise. * gdb.disasm/disassembler-options.exp: New test. * gdb.arch/powerpc-altivec.exp: Likewise. * gdb.arch/powerpc-altivec.s: Likewise. * gdb.arch/powerpc-altivec2.exp: Likewise. * gdb.arch/powerpc-altivec2.s: Likewise. * gdb.arch/powerpc-altivec3.exp: Likewise. * gdb.arch/powerpc-altivec3.s: Likewise. * gdb.arch/powerpc-power7.exp: Likewise. * gdb.arch/powerpc-power7.s: Likewise. * gdb.arch/powerpc-power8.exp: Likewise. * gdb.arch/powerpc-power8.s: Likewise. * gdb.arch/powerpc-power9.exp: Likewise. * gdb.arch/powerpc-power9.s: Likewise. * gdb.arch/powerpc-vsx.exp: Likewise. * gdb.arch/powerpc-vsx.s: Likewise. * gdb.arch/powerpc-vsx2.exp: Likewise. * gdb.arch/powerpc-vsx2.s: Likewise. * gdb.arch/powerpc-vsx3.exp: Likewise. * gdb.arch/powerpc-vsx3.s: Likewise. * gdb.arch/arm-disassembler-options.exp: Likewise. * gdb.arch/powerpc-disassembler-options.exp: Likewise. * gdb.arch/s390-disassembler-options.exp: Likewise.
2017-03-01 02:32:07 +08:00
#endif