From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1726) id B2120384D1AD; Wed, 15 Jun 2022 09:03:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B2120384D1AD Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Andrew Burgess To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb: add extension language print_insn hook X-Act-Checkin: binutils-gdb X-Git-Author: Andrew Burgess X-Git-Refname: refs/heads/master X-Git-Oldrev: f0c2e3e020d350b410e1bbe4ed636f2ea228d555 X-Git-Newrev: e4ae302562aba1bd166919d76341fb631e2d470a Message-Id: <20220615090342.B2120384D1AD@sourceware.org> Date: Wed, 15 Jun 2022 09:03:42 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Jun 2022 09:03:42 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3De4ae302562ab= a1bd166919d76341fb631e2d470a commit e4ae302562aba1bd166919d76341fb631e2d470a Author: Andrew Burgess Date: Fri Sep 17 18:11:40 2021 +0100 gdb: add extension language print_insn hook =20 This commit is setup for the next commit. =20 In the next commit I will add a Python API to intercept the print_insn calls within GDB, each print_insn call is responsible for disassembling, and printing one instruction. After the next commit it will be possible for a user to write Python code that either wraps around the existing disassembler, or even, in extreme situations, entirely replaces the existing disassembler. =20 This commit does not add any new Python API. =20 What this commit does is put the extension language framework in place for a print_insn hook. There's a new callback added to 'struct extension_language_ops', which is then filled in with nullptr for Python and Guile. =20 Finally, in the disassembler, the code is restructured so that the new extension language function ext_lang_print_insn is called before we delegate to gdbarch_print_insn. =20 After this, the next commit can focus entirely on providing a Python implementation of the new print_insn callback. =20 There should be no user visible change after this commit. Diff: --- gdb/disasm.c | 29 ++++++++++++++++++++++++++--- gdb/extension-priv.h | 15 +++++++++++++++ gdb/extension.c | 20 ++++++++++++++++++++ gdb/extension.h | 10 ++++++++++ gdb/guile/guile.c | 6 +++++- gdb/python/python.c | 2 ++ 6 files changed, 78 insertions(+), 4 deletions(-) diff --git a/gdb/disasm.c b/gdb/disasm.c index 6ac84388cc3..4af40c916b2 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -851,6 +851,29 @@ gdb_disassemble_info::~gdb_disassemble_info () disassemble_free_target (&m_di); } =20 +/* Wrapper around calling gdbarch_print_insn. This function takes care of + first calling the extension language hooks for print_insn, and, if none + of the extension languages can print this instruction, calls + gdbarch_print_insn to do the work. + + GDBARCH is the architecture to disassemble in, VMA is the address of the + instruction being disassembled, and INFO is the libopcodes disassembler + related information. */ + +static int +gdb_print_insn_1 (struct gdbarch *gdbarch, CORE_ADDR vma, + struct disassemble_info *info) +{ + /* Call into the extension languages to do the disassembly. */ + gdb::optional length =3D ext_lang_print_insn (gdbarch, vma, info); + if (length.has_value ()) + return *length; + + /* No extension language wanted to do the disassembly, so do it + manually. */ + return gdbarch_print_insn (gdbarch, vma, info); +} + /* See disasm.h. */ =20 bool gdb_disassembler::use_ext_lang_colorization_p =3D true; @@ -864,7 +887,7 @@ gdb_disassembler::print_insn (CORE_ADDR memaddr, m_err_memaddr.reset (); m_buffer.clear (); =20 - int length =3D gdbarch_print_insn (arch (), memaddr, &m_di); + int length =3D gdb_print_insn_1 (arch (), memaddr, &m_di); =20 /* If we have successfully disassembled an instruction, styling is on, we think that the extension language might be able to perform styling for @@ -899,7 +922,7 @@ gdb_disassembler::print_insn (CORE_ADDR memaddr, gdb_assert (!m_buffer.term_out ()); m_buffer.~string_file (); new (&m_buffer) string_file (true); - length =3D gdbarch_print_insn (arch (), memaddr, &m_di); + length =3D gdb_print_insn_1 (arch (), memaddr, &m_di); gdb_assert (length > 0); } } @@ -1054,7 +1077,7 @@ gdb_buffered_insn_length (struct gdbarch *gdbarch, gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr, &disassembler_options_holder); =20 - int result =3D gdbarch_print_insn (gdbarch, addr, &di); + int result =3D gdb_print_insn_1 (gdbarch, addr, &di); disassemble_free_target (&di); return result; } diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h index d9450b51231..7c74e721c57 100644 --- a/gdb/extension-priv.h +++ b/gdb/extension-priv.h @@ -263,6 +263,21 @@ struct extension_language_ops contents, or an empty optional. */ gdb::optional (*colorize_disasm) (const std::string &conten= t, gdbarch *gdbarch); + + /* Print a single instruction from ADDRESS in architecture GDBARCH. INFO + is the standard libopcodes disassembler_info structure. Bytes for the + instruction being printed should be read using INFO->read_memory_func + as the actual instruction bytes might be in a buffer. + + Use INFO->fprintf_func to print the results of the disassembly, and + return the length of the instruction. + + If no instruction can be disassembled then return an empty value and + other extension languages will get a chance to perform the + disassembly. */ + gdb::optional (*print_insn) (struct gdbarch *gdbarch, + CORE_ADDR address, + struct disassemble_info *info); }; =20 /* State necessary to restore a signal handler to its previous value. */ diff --git a/gdb/extension.c b/gdb/extension.c index 8f39b86e952..5a805bea00e 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -924,6 +924,26 @@ ext_lang_colorize_disasm (const std::string &content, = gdbarch *gdbarch) return result; } =20 +/* See extension.h. */ + +gdb::optional +ext_lang_print_insn (struct gdbarch *gdbarch, CORE_ADDR address, + struct disassemble_info *info) +{ + for (const struct extension_language_defn *extlang : extension_languages) + { + if (extlang->ops =3D=3D nullptr + || extlang->ops->print_insn =3D=3D nullptr) + continue; + gdb::optional length + =3D extlang->ops->print_insn (gdbarch, address, info); + if (length.has_value ()) + return length; + } + + return {}; +} + /* Called via an observer before gdb prints its prompt. Iterate over the extension languages giving them a chance to change the prompt. The first one to change the prompt wins, diff --git a/gdb/extension.h b/gdb/extension.h index 7eb89530c44..47839ea50be 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -327,6 +327,16 @@ extern gdb::optional ext_lang_colorize extern gdb::optional ext_lang_colorize_disasm (const std::string &content, gdbarch *gdbarch); =20 +/* Calls extension_language_ops::print_insn for each extension language, + returning the result from the first extension language that returns a + non-empty result (any further extension languages are not then called). + + All arguments are forwarded to extension_language_ops::print_insn, see + that function for a full description. */ + +extern gdb::optional ext_lang_print_insn + (struct gdbarch *gdbarch, CORE_ADDR address, struct disassemble_info *in= fo); + #if GDB_SELF_TEST namespace selftests { extern void (*hook_set_active_ext_lang) (); diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c index c7be48fb739..14b191ded62 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -130,8 +130,12 @@ static const struct extension_language_ops guile_exten= sion_ops =3D gdbscm_breakpoint_has_cond, gdbscm_breakpoint_cond_says_stop, =20 - NULL, /* gdbscm_check_quit_flag, */ NULL, /* gdbscm_set_quit_flag, */ + NULL, /* gdbscm_check_quit_flag, */ + NULL, /* gdbscm_before_prompt, */ + NULL, /* gdbscm_get_matching_xmethod_workers */ + NULL, /* gdbscm_colorize */ + NULL, /* gdbscm_print_insn */ }; #endif =20 diff --git a/gdb/python/python.c b/gdb/python/python.c index 9bef2252e88..97de5f5cee5 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -166,6 +166,8 @@ static const struct extension_language_ops python_exten= sion_ops =3D gdbpy_colorize, =20 gdbpy_colorize_disasm, + + NULL, /* gdbpy_print_insn, */ }; =20 #endif /* HAVE_PYTHON */