From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 3B117388882E for ; Wed, 23 Mar 2022 22:41:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3B117388882E Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-64-qH8ePIGIOm6QraIrBS3O7Q-1; Wed, 23 Mar 2022 18:41:49 -0400 X-MC-Unique: qH8ePIGIOm6QraIrBS3O7Q-1 Received: by mail-wr1-f69.google.com with SMTP id i64-20020adf90c6000000b00203f2b5e090so989476wri.9 for ; Wed, 23 Mar 2022 15:41:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0DjyjISFs0my04AO4EIJjfN0bzozWFAl0DDnmlTLOpw=; b=ezd5cjjOAbDpUB/+cBeC22IXojIxokSWPgVTNp26dX98rIrKA3TQoU52F3+UFwZzq8 tY4Wt94VOKaTYzHxMd5b3bMUTIyZEMta1E12pEdngCWDgUOQ3dgIVO9o3ZBpal/owIeY qt782TZVCYIFoiFEQt7ah3dbq/MgG/oXS1TDi9M9ezovE9IR2JRW3aWD6gD3kG/y2Ot1 8K2edHrKOh6/GRJJ+y2oO3MAb4D72KpncUp7qzH6ZftSb60rcN5aDFTeHdXPY2IvIdak UoGUW10gqBhAmhovOwhPnxG/lydOz/QzUOQKyyBJAPtC3Zs4sPguYUW68M0yQ9M1SNs8 L4IA== X-Gm-Message-State: AOAM533ypSFtT4UJbtUf3tfbqh/24J6IyGi5aYzM8twaqdBz/w32ll/9 0teLZQ68ViredKHNtFuX9WMDbHmyFnNtPpue98V2FVujf1UCE74/ASCpWNiSSM9gwOn1kG1xLp4 7hP5AcJnwD26z7ezPnaJywyVB3rS3sJvrgFWDqjK1Bw+I9EHZSrQJVwvO278oSgh1KXk55Kspvw == X-Received: by 2002:adf:ffc9:0:b0:204:195:4ab0 with SMTP id x9-20020adfffc9000000b0020401954ab0mr1897472wrs.561.1648075308101; Wed, 23 Mar 2022 15:41:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzpZKb1UXSRV8sRQFMeS2NIndvFl13smSedSJrPLQLTwBCnPjHaUNn3WoeT9FWlLFS9wcjATA== X-Received: by 2002:adf:ffc9:0:b0:204:195:4ab0 with SMTP id x9-20020adfffc9000000b0020401954ab0mr1897453wrs.561.1648075307800; Wed, 23 Mar 2022 15:41:47 -0700 (PDT) Received: from localhost (host109-158-45-15.range109-158.btcentralplus.com. [109.158.45.15]) by smtp.gmail.com with ESMTPSA id v2-20020adf8b42000000b001edc38024c9sm1035886wra.65.2022.03.23.15.41.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Mar 2022 15:41:47 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCHv2 2/3] gdb: add extension language print_insn hook Date: Wed, 23 Mar 2022 22:41:40 +0000 Message-Id: <27bdbff53a8b28cd8c0e50af904e7c74a78ecc39.1648075231.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Mar 2022 22:41:53 -0000 From: Andrew Burgess This commit is setup for the next commit. 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. This commit does not add any new Python API. 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. 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. After this, the next commit can focus entirely on providing a Python implementation of the new print_insn callback. There should be no user visible change after this commit. --- gdb/disasm.c | 29 ++++++++++++++++++++++++++--- gdb/extension-priv.h | 15 +++++++++++++++ gdb/extension.c | 20 ++++++++++++++++++++ gdb/extension.h | 17 +++++++++++++++++ gdb/guile/guile.c | 6 +++++- gdb/python/python.c | 2 ++ 6 files changed, 85 insertions(+), 4 deletions(-) diff --git a/gdb/disasm.c b/gdb/disasm.c index 128b097a51a..76f322ad4a9 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -821,6 +821,29 @@ gdb_disassemble_info::~gdb_disassemble_info () disassemble_free_target (&m_di); } +/* 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 = 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. */ bool gdb_disassembler::use_ext_lang_colorization_p = true; @@ -834,7 +857,7 @@ gdb_disassembler::print_insn (CORE_ADDR memaddr, m_err_memaddr.reset (); m_buffer.clear (); - int length = gdbarch_print_insn (arch (), memaddr, &m_di); + int length = gdb_print_insn_1 (arch (), memaddr, &m_di); /* If we have successfully disassembled an instruction, styling is on, we think that the extension language might be able to perform styling for @@ -869,7 +892,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 = gdbarch_print_insn (arch (), memaddr, &m_di); + length = gdb_print_insn_1 (arch (), memaddr, &m_di); gdb_assert (length > 0); } } @@ -1011,7 +1034,7 @@ gdb_buffered_insn_length (struct gdbarch *gdbarch, gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr, &disassembler_options_holder); - int result = gdbarch_print_insn (gdbarch, addr, &di); + int result = 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 &content, 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); }; /* State necessary to restore a signal handler to its previous value. */ diff --git a/gdb/extension.c b/gdb/extension.c index 8f39b86e952..62f41c6445d 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; } +/* 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 == nullptr + || extlang->ops->print_insn == nullptr) + continue; + gdb::optional length + (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..f7518f91b35 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -327,6 +327,23 @@ extern gdb::optional ext_lang_colorize extern gdb::optional ext_lang_colorize_disasm (const std::string &content, gdbarch *gdbarch); +/* Try to disassemble a single instruction. ADDRESS is the address that + the instructions apparent address, though bytes for the instruction + should be read by calling INFO->read_memory_func as we might be + disassembling out of a buffer. GDBARCH is the architecture in which we + are performing the disassembly. + + The disassembled instruction should be printed by calling + INFO->fprintf_func, and the length (in octets) of the disassembled + instruction should be returned. + + If no instruction could be disassembled then an empty value is returned + and GDB will call gdbarch_print_insn to perform the disassembly + itself. */ + +extern gdb::optional ext_lang_print_insn + (struct gdbarch *gdbarch, CORE_ADDR address, struct disassemble_info *info); + #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 c040be556a6..50d43e2554b 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -130,8 +130,12 @@ static const struct extension_language_ops guile_extension_ops = gdbscm_breakpoint_has_cond, gdbscm_breakpoint_cond_says_stop, - 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 diff --git a/gdb/python/python.c b/gdb/python/python.c index f0d788bf8d5..df794dcd63a 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -166,6 +166,8 @@ static const struct extension_language_ops python_extension_ops = gdbpy_colorize, gdbpy_colorize_disasm, + + NULL, /* gdbpy_print_insn, */ }; #endif /* HAVE_PYTHON */ -- 2.25.4