binutils-gdb/gdb/disasm.h

410 lines
15 KiB
C
Raw Normal View History

/* Disassemble support for GDB.
Copyright (C) 2002-2023 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-02 20:04:24 -06: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-09 19:40:01 -08:00
struct gdbarch;
struct ui_out;
struct ui_file;
gdb: mark disassembler function callback types as noexcept In disasm.h we define a set of types that are used by the various disassembler classes to hold callback functions before passing the callbacks into libopcodes. Because libopcodes is C code, and on some (many?) targets, C code is compiled without exception support, it is important that GDB not try to throw an exception over libopcode code. In the previous commit all the existing callbacks were marked as noexcept, however, this doesn't protect us from a future change to GDB either adding a new callback that is not noexcept, or removing the noexcept keyword from an existing callback. In this commit I mark all the callback types as noexcept. This means that GDB's disassembler classes will no longer compile if we try to pass a callback that is not marked as noexcept. At least, that's the idea. Unfortunately, it's not that easy. Before C++17, the noexcept keyword on a function typedef would be ignored, thus: using func_type = void (*) (void) noexcept; void a_func () { throw 123; } void some_func (func_type f) { f (); } int main () { some_func (a_func); return 0; } Will compile just fine for C++11 and C++14 with GCC. Clang on the other hand complains that 'noexcept' should not appear on function types, but then does appear to correctly complain that passing a_func is a mismatch in the set of exceptions that could be thrown. Switching to C++17 and both GCC and Clang correctly point out that passing a_func is an invalid conversion relating to the noexcept keyword. Changing a_func to: void a_func () noexcept { /* Nothing. */ } And for C++17 both GCC and Clang compile this just fine. My conclusion then is that adding the noexcept keyword to the function types is pointless while GDB is not compiled as C++17, and silencing the warnings would require us to jump through a bunch of hoops. And so, in this commit, I define a macro LIBOPCODE_CALLBACK_NOEXCEPT, this macro expands to noexcept when compiling for C++17, but otherwise expands to nothing. I then add this macro to the function types. I've compiled GDB as the default C++11 and also forced the compile to C++17. When compiling as C++17 I spotted a few additional places where callbacks needed to be marked noexcept (these fixes were merged into the previous commit, but this confirmed to be that the macro is working as expected).
2022-10-27 15:20:10 +01:00
#if __cplusplus >= 201703L
#define LIBOPCODE_CALLBACK_NOEXCEPT noexcept
#else
#define LIBOPCODE_CALLBACK_NOEXCEPT
#endif
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 10:07:56 +01: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 10:07:56 +01: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 10:07:56 +01: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 14:29:19 +00: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 10:07:56 +01: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 14:29:19 +00: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 10:07:56 +01: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 14:29:19 +00:00
protected:
gdb: mark disassembler function callback types as noexcept In disasm.h we define a set of types that are used by the various disassembler classes to hold callback functions before passing the callbacks into libopcodes. Because libopcodes is C code, and on some (many?) targets, C code is compiled without exception support, it is important that GDB not try to throw an exception over libopcode code. In the previous commit all the existing callbacks were marked as noexcept, however, this doesn't protect us from a future change to GDB either adding a new callback that is not noexcept, or removing the noexcept keyword from an existing callback. In this commit I mark all the callback types as noexcept. This means that GDB's disassembler classes will no longer compile if we try to pass a callback that is not marked as noexcept. At least, that's the idea. Unfortunately, it's not that easy. Before C++17, the noexcept keyword on a function typedef would be ignored, thus: using func_type = void (*) (void) noexcept; void a_func () { throw 123; } void some_func (func_type f) { f (); } int main () { some_func (a_func); return 0; } Will compile just fine for C++11 and C++14 with GCC. Clang on the other hand complains that 'noexcept' should not appear on function types, but then does appear to correctly complain that passing a_func is a mismatch in the set of exceptions that could be thrown. Switching to C++17 and both GCC and Clang correctly point out that passing a_func is an invalid conversion relating to the noexcept keyword. Changing a_func to: void a_func () noexcept { /* Nothing. */ } And for C++17 both GCC and Clang compile this just fine. My conclusion then is that adding the noexcept keyword to the function types is pointless while GDB is not compiled as C++17, and silencing the warnings would require us to jump through a bunch of hoops. And so, in this commit, I define a macro LIBOPCODE_CALLBACK_NOEXCEPT, this macro expands to noexcept when compiling for C++17, but otherwise expands to nothing. I then add this macro to the function types. I've compiled GDB as the default C++11 and also forced the compile to C++17. When compiling as C++17 I spotted a few additional places where callbacks needed to be marked noexcept (these fixes were merged into the previous commit, but this confirmed to be that the macro is working as expected).
2022-10-27 15:20:10 +01:00
/* Types for the function callbacks within m_di. The actual function
signatures here are taken from include/dis-asm.h. The noexcept macro
expands to 'noexcept' for C++17 and later, otherwise, it expands to
nothing. This is because including noexcept was ignored for function
types before C++17, but both GCC and Clang warn that the noexcept
will become relevant when you switch to C++17, and this warning
causes the build to fail. */
using read_memory_ftype
= int (*) (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *)
LIBOPCODE_CALLBACK_NOEXCEPT;
using memory_error_ftype
= void (*) (int, bfd_vma, struct disassemble_info *)
LIBOPCODE_CALLBACK_NOEXCEPT;
using print_address_ftype
= void (*) (bfd_vma, struct disassemble_info *)
LIBOPCODE_CALLBACK_NOEXCEPT;
using fprintf_ftype
= int (*) (void *, const char *, ...)
LIBOPCODE_CALLBACK_NOEXCEPT;
using fprintf_styled_ftype
= int (*) (void *, enum disassembler_style, const char *, ...)
LIBOPCODE_CALLBACK_NOEXCEPT;
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 10:07:56 +01: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 11:06:16 +01: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 10:07:56 +01: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 14:29:19 +00: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-02 23:57:21 +01: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 10:07:56 +01: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-02 23:57:21 +01: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 10:07:56 +01: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);
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 11:06:16 +01:00
/* The stream that disassembler output is being written too. */
struct ui_file *stream ()
{ return m_stream; }
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 10:07:56 +01: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 11:06:16 +01: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 10:07:56 +01: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 11:06:16 +01: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. */
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
static int fprintf_func (void *dis_info, const char *format, ...) noexcept
gdb: style filenames in separate debug file warnings After the commit: commit 6647f05df023b63bbe056e9167e9e234172fa2ca Date: Tue Jan 24 18:13:38 2023 +0100 gdb: defer warnings when loading separate debug files It was pointed out[1] that the warnings being deferred and then later emitted lacked styling. The warnings lacked styling before the above commit, but it was suggested that the filenames in these warnings should be styled, and this commit does this. There were a couple of previous attempts[2][3][4] to solve this problem, but these all tried to extend the mechanism introduced in the above commit, the deferred warnings were placed directly into a std::vector, but now we tried to, when appropriate, style these warnings. The review feedback that this approach looked too complex. So instead, this revision adds a new helper class 'deferred_warnings' which can be used to collect a set of deferred warnings, and then emit these deferred warnings later, if needed. This helper class hides the complexity, so at the point the deferred warning is created no extra logic is required. The deferred_warnings class will style the deferred warnings only if gdb_stderr supports styling. GDB's warnings are sent to gdb_stderr, so this should ensure we only style when expected. There was also review feedback[5] that all of the warnings should be bundled into a single string_file, this has not been done. I feel pretty strongly that separate warnings should be emitted using separate "warning" calls. If we do end up with multiple warnings in this case they aren't really related, one will be about looking up debug via .gnu_debuglink, while the other will be about build-id based lookup. So I'd really rather keep the warnings separate. [1] https://inbox.sourceware.org/gdb-patches/87edr9pcku.fsf@tromey.com/ [2] https://inbox.sourceware.org/gdb-patches/20230216195604.2685177-1-ahajkova@redhat.com/ [3] https://inbox.sourceware.org/gdb-patches/20230217123547.2737612-1-ahajkova@redhat.com/ [4] https://inbox.sourceware.org/gdb-patches/20230320145638.1202335-1-ahajkova@redhat.com/ [5] https://inbox.sourceware.org/gdb-patches/87o7nh1g8h.fsf@tromey.com/ Co-Authored-By: Alexandra Hájková <ahajkova@redhat.com> Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-05-05 14:22:38 +01:00
ATTRIBUTE_PRINTF (2, 3);
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 10:07:56 +01: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 11:06:16 +01: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 10:07:56 +01:00
enum disassembler_style style,
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
const char *format, ...) noexcept
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 10:07:56 +01:00
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 11:06:16 +01: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 14:40:52 +00: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 11:06:16 +01: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 14:40:52 +00: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 10:07:56 +01: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 15:48:19 +01: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 11:06:16 +01: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 15:48:19 +01: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. */
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
static int null_fprintf_func (void *stream, const char *format, ...) noexcept
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 15:48:19 +01:00
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,
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
const char *format, ...) noexcept
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 15:48:19 +01:00
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,
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
struct disassemble_info *info) noexcept;
};
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 15:48:19 +01: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 15:48:19 +01: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. */ }
};
/* A disassembler class that provides 'print_insn', a method for
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 10:07:56 +01:00
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 10:07:56 +01: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 15:10:12 +01: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 14:29:19 +00:00
gdb: improve disassembler styling when Pygments raises an exception While working on another issue relating to GDB's use of the Python Pygments package for disassembly styling I noticed an issue in the case where the Pygments package raises an exception. The intention of the current code is that, should the Pygments package raise an exception, GDB will disable future attempts to call into the Pygments code. This was intended to prevent repeated errors during disassembly if, for some reason, the Pygments code isn't working. Since the Pygments based styling was added, GDB now supports disassembly styling using libopcodes, but this is only available for some architectures. For architectures not covered by libopcodes Pygments is still the only option. What I observed is that, if I disable the libopcodes styling, then setup GDB so that the Pygments based styling code will indicate an error (by returning None), GDB does, as expected, stop using the Pygments based styling. However, the libopcodes based styling will instead be used, despite this feature having been disabled. The problem is that the disassembler output is produced into a string_file buffer. When we are using Pygments, this buffer is created without styling support. However, when Pygments fails, we recreate the buffer with styling support. The problem is that we should only recreate the buffer with styling support only if libopcodes styling is enabled. This was an oversight in commit: commit 4cbe4ca5da5cd7e1e6331ce11f024bf3c07b9744 Date: Mon Feb 14 14:40:52 2022 +0000 gdb: add support for disassembler styling using libopcodes This commit: 1. Factors out some of the condition checking logic into two new helper functions use_ext_lang_for_styling and use_libopcodes_for_styling, 2. Reorders gdb_disassembler::m_buffer and gdb_disassembler::m_dest, this allows these fields to be initialised m_dest first, which means that the new condition checking functions can rely on m_dest being set, even when called from the gdb_disassembler constructor, 3. Make use of the new condition checking functions each time m_buffer is initialised, 4. Add a new test that forces the Python disassembler styling function to return None, this will cause GDB to disable use of Pygments for styling, and 5. When we reinitialise m_buffer, and re-disassemble the instruction, call reset the in-comment flag. If the instruction being disassembler ends in a comment then the first disassembly pass will have set the in-comment flag to true. This shouldn't be a problem as we will only be using Pygments, and thus performing a re-disassembly pass, if libopcodes is disabled, so the in-comment flag will never be checked, even if it is set incorrectly. However, I think that having the flag set correctly is a good thing, even if we don't check it (you never know what future uses might come up).
2022-08-26 21:19:14 +01:00
/* The stream to which disassembler output will be written. */
ui_file *m_dest;
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-25 17:26:57 +01: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;
/* 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 14:29:19 +00:00
static void dis_asm_memory_error (int err, bfd_vma memaddr,
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
struct disassemble_info *info) noexcept;
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 14:29:19 +00:00
static void dis_asm_print_address (bfd_vma addr,
gdb/disasm: mark functions passed to the disassembler noexcept While working on another patch, Simon pointed out that GDB could be improved by marking the functions passed to the disassembler as noexcept. https://sourceware.org/pipermail/gdb-patches/2022-October/193084.html The reason this is important is the on some hosts, libopcodes, being C code, will not be compiled with support for handling exceptions. As such, an attempt to throw an exception over libopcodes code will cause GDB to terminate. See bug gdb/29712 for an example of when this happened. In this commit all the functions that are passed to the disassembler, and which might be used as callbacks by libopcodes are marked noexcept. Ideally, I would have liked to change these typedefs: 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); which are declared in disasm.h, as including the noexcept keyword. However, when I tried this, I ran into this warning/error: In file included from ../../src/gdb/disasm.c:25: ../../src/gdb/disasm.h: In constructor ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’: ../../src/gdb/disasm.h:116:3: error: mangled name for ‘gdb_printing_disassembler::gdb_printing_disassembler(gdbarch*, ui_file*, gdb_disassemble_info::read_memory_ftype, gdb_disassemble_info::memory_error_ftype, gdb_disassemble_info::print_address_ftype)’ will change in C++17 because the exception specification is part of a function type [-Werror=noexcept-type] 116 | gdb_printing_disassembler (struct gdbarch *gdbarch, | ^~~~~~~~~~~~~~~~~~~~~~~~~ So I've left that change out. This does mean that if somebody adds a new use of the disassembler classes in the future, and forgets to mark the callbacks as noexcept, this will compile fine. We'll just have to manually check for that during review.
2022-10-24 18:35:41 +01:00
struct disassemble_info *info) noexcept;
gdb: improve disassembler styling when Pygments raises an exception While working on another issue relating to GDB's use of the Python Pygments package for disassembly styling I noticed an issue in the case where the Pygments package raises an exception. The intention of the current code is that, should the Pygments package raise an exception, GDB will disable future attempts to call into the Pygments code. This was intended to prevent repeated errors during disassembly if, for some reason, the Pygments code isn't working. Since the Pygments based styling was added, GDB now supports disassembly styling using libopcodes, but this is only available for some architectures. For architectures not covered by libopcodes Pygments is still the only option. What I observed is that, if I disable the libopcodes styling, then setup GDB so that the Pygments based styling code will indicate an error (by returning None), GDB does, as expected, stop using the Pygments based styling. However, the libopcodes based styling will instead be used, despite this feature having been disabled. The problem is that the disassembler output is produced into a string_file buffer. When we are using Pygments, this buffer is created without styling support. However, when Pygments fails, we recreate the buffer with styling support. The problem is that we should only recreate the buffer with styling support only if libopcodes styling is enabled. This was an oversight in commit: commit 4cbe4ca5da5cd7e1e6331ce11f024bf3c07b9744 Date: Mon Feb 14 14:40:52 2022 +0000 gdb: add support for disassembler styling using libopcodes This commit: 1. Factors out some of the condition checking logic into two new helper functions use_ext_lang_for_styling and use_libopcodes_for_styling, 2. Reorders gdb_disassembler::m_buffer and gdb_disassembler::m_dest, this allows these fields to be initialised m_dest first, which means that the new condition checking functions can rely on m_dest being set, even when called from the gdb_disassembler constructor, 3. Make use of the new condition checking functions each time m_buffer is initialised, 4. Add a new test that forces the Python disassembler styling function to return None, this will cause GDB to disable use of Pygments for styling, and 5. When we reinitialise m_buffer, and re-disassemble the instruction, call reset the in-comment flag. If the instruction being disassembler ends in a comment then the first disassembly pass will have set the in-comment flag to true. This shouldn't be a problem as we will only be using Pygments, and thus performing a re-disassembly pass, if libopcodes is disabled, so the in-comment flag will never be checked, even if it is set incorrectly. However, I think that having the flag set correctly is a good thing, even if we don't check it (you never know what future uses might come up).
2022-08-26 21:19:14 +01:00
/* Return true if we should use the extension language to apply
disassembler styling. This requires disassembler styling to be on
(i.e. 'set style disassembler enabled on'), the output stream needs to
support styling, and libopcode styling needs to be either off, or not
supported for the current architecture (libopcodes is used in
preference to the extension language method). */
bool use_ext_lang_for_styling () const;
/* Return true if we should use libopcodes to apply disassembler styling.
This requires disassembler styling to be on (i.e. 'set style
disassembler enabled on'), the output stream needs to support styling,
and libopcodes styling needs to be supported for the current
architecture, and not disabled by the user. */
bool use_libopcodes_for_styling () const;
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 14:29:19 +00:00
};
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 14:47:08 +02: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-02 17:17:42 +00: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-04 18:23:22 +01: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-02 17:17:42 +00: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 11:11:47 +00: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-04 18:23:22 +01: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;
/* The buffer used to hold the opcode bytes (if required). */
gdb::byte_vector m_opcode_data;
};
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 11:11:47 +00: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-02-28 12:32:07 -06: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-10 17:10:13 -04: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-02-28 12:32:07 -06:00
#endif