From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Daniel P. Berrangé" <berrange@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Leonardo Bras" <leobras@redhat.com>,
"Laurent Vivier" <laurent@vivier.eu>,
"Peter Xu" <peterx@redhat.com>,
"Juan Quintela" <quintela@redhat.com>,
"Beraldo Leal" <bleal@redhat.com>,
"Radoslaw Biernacki" <rad@semihalf.com>,
"Qiuhao Li" <Qiuhao.Li@outlook.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Yanan Wang" <wangyanan55@huawei.com>,
"Riku Voipio" <riku.voipio@iki.fi>,
"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
"Mahmoud Mandour" <ma.mandourr@gmail.com>,
"Alexandre Iooss" <erdnaxe@crans.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Eduardo Habkost" <eduardo@habkost.net>,
"Thomas Huth" <thuth@redhat.com>,
"Laurent Vivier" <lvivier@redhat.com>,
"Bin Meng" <bmeng.cn@gmail.com>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Bandan Das" <bsd@redhat.com>, "Cleber Rosa" <crosa@redhat.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Leif Lindholm" <quic_llindhol@quicinc.com>,
"Marcin Juszkiewicz" <marcin.juszkiewicz@linaro.org>,
qemu-arm@nongnu.org, "Darren Kenny" <darren.kenny@oracle.com>,
"Alexander Bulekov" <alxndr@bu.edu>,
"Ilya Leoshkevich" <iii@linux.ibm.com>,
"Dominik 'Disconnect3d' Czarnota" <dominik.b.czarnota@gmail.com>
Subject: [PATCH v4 36/38] gdbstub: Add support for info proc mappings
Date: Fri, 30 Jun 2023 19:04:21 +0100 [thread overview]
Message-ID: <20230630180423.558337-37-alex.bennee@linaro.org> (raw)
In-Reply-To: <20230630180423.558337-1-alex.bennee@linaro.org>
From: Ilya Leoshkevich <iii@linux.ibm.com>
Currently the GDB's generate-core-file command doesn't work well with
qemu-user: the resulting dumps are huge [1] and at the same time
incomplete (argv and envp are missing). The reason is that GDB has no
access to proc mappings and therefore has to fall back to using
heuristics for discovering them. This is, in turn, because qemu-user
does not implement the Host I/O feature of the GDB Remote Serial
Protocol.
Implement vFile:{open,close,pread,readlink} and also
qXfer:exec-file:read+. With that, generate-core-file begins to work on
aarch64 and s390x.
[1] https://sourceware.org/pipermail/gdb-patches/2023-May/199432.html
Co-developed-by: Dominik 'Disconnect3d' Czarnota <dominik.b.czarnota@gmail.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230621203627.1808446-7-iii@linux.ibm.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
v3
- remove #define BUFSIZ (both linux and BSD define it but BSD complains if
you redefine it)
---
gdbstub/internals.h | 5 ++
gdbstub/gdbstub.c | 45 +++++++++++++-
gdbstub/user-target.c | 137 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 185 insertions(+), 2 deletions(-)
diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 25e4d5eeaa..f2b46cce41 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -189,6 +189,11 @@ typedef union GdbCmdVariant {
void gdb_handle_query_rcmd(GArray *params, void *user_ctx); /* softmmu */
void gdb_handle_query_offsets(GArray *params, void *user_ctx); /* user */
void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx); /*user */
+void gdb_handle_v_file_open(GArray *params, void *user_ctx); /* user */
+void gdb_handle_v_file_close(GArray *params, void *user_ctx); /* user */
+void gdb_handle_v_file_pread(GArray *params, void *user_ctx); /* user */
+void gdb_handle_v_file_readlink(GArray *params, void *user_ctx); /* user */
+void gdb_handle_query_xfer_exec_file(GArray *params, void *user_ctx); /* user */
void gdb_handle_query_attached(GArray *params, void *user_ctx); /* both */
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 697dd4bbad..6911b73c07 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -1327,6 +1327,36 @@ static const GdbCmdParseEntry gdb_v_commands_table[] = {
.cmd = "Kill;",
.cmd_startswith = 1
},
+#ifdef CONFIG_USER_ONLY
+ /*
+ * Host I/O Packets. See [1] for details.
+ * [1] https://sourceware.org/gdb/onlinedocs/gdb/Host-I_002fO-Packets.html
+ */
+ {
+ .handler = gdb_handle_v_file_open,
+ .cmd = "File:open:",
+ .cmd_startswith = 1,
+ .schema = "s,L,L0"
+ },
+ {
+ .handler = gdb_handle_v_file_close,
+ .cmd = "File:close:",
+ .cmd_startswith = 1,
+ .schema = "l0"
+ },
+ {
+ .handler = gdb_handle_v_file_pread,
+ .cmd = "File:pread:",
+ .cmd_startswith = 1,
+ .schema = "l,L,L0"
+ },
+ {
+ .handler = gdb_handle_v_file_readlink,
+ .cmd = "File:readlink:",
+ .cmd_startswith = 1,
+ .schema = "s0"
+ },
+#endif
};
static void handle_v_commands(GArray *params, void *user_ctx)
@@ -1472,11 +1502,14 @@ static void handle_query_supported(GArray *params, void *user_ctx)
";ReverseStep+;ReverseContinue+");
}
-#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX)
+#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_LINUX)
if (gdbserver_state.c_cpu->opaque) {
g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
}
#endif
+ g_string_append(gdbserver_state.str_buf, ";qXfer:exec-file:read+");
+#endif
if (params->len &&
strstr(get_param(params, 0)->data, "multiprocess+")) {
@@ -1615,13 +1648,21 @@ static const GdbCmdParseEntry gdb_gen_query_table[] = {
.cmd_startswith = 1,
.schema = "s:l,l0"
},
-#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX)
+#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_LINUX)
{
.handler = gdb_handle_query_xfer_auxv,
.cmd = "Xfer:auxv:read::",
.cmd_startswith = 1,
.schema = "l,l0"
},
+#endif
+ {
+ .handler = gdb_handle_query_xfer_exec_file,
+ .cmd = "Xfer:exec-file:read:",
+ .cmd_startswith = 1,
+ .schema = "l:l,l0"
+ },
#endif
{
.handler = gdb_handle_query_attached,
diff --git a/gdbstub/user-target.c b/gdbstub/user-target.c
index fa0e59ec9a..6e21c3161c 100644
--- a/gdbstub/user-target.c
+++ b/gdbstub/user-target.c
@@ -11,6 +11,10 @@
#include "exec/gdbstub.h"
#include "qemu.h"
#include "internals.h"
+#ifdef CONFIG_LINUX
+#include "linux-user/loader.h"
+#include "linux-user/qemu.h"
+#endif
/*
* Map target signal numbers to GDB protocol signal numbers and vice
@@ -281,3 +285,136 @@ void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
gdbserver_state.str_buf->len, true);
}
#endif
+
+static const char *get_filename_param(GArray *params, int i)
+{
+ const char *hex_filename = get_param(params, i)->data;
+ gdb_hextomem(gdbserver_state.mem_buf, hex_filename,
+ strlen(hex_filename) / 2);
+ g_byte_array_append(gdbserver_state.mem_buf, (const guint8 *)"", 1);
+ return (const char *)gdbserver_state.mem_buf->data;
+}
+
+static void hostio_reply_with_data(const void *buf, size_t n)
+{
+ g_string_printf(gdbserver_state.str_buf, "F%zx;", n);
+ gdb_memtox(gdbserver_state.str_buf, buf, n);
+ gdb_put_packet_binary(gdbserver_state.str_buf->str,
+ gdbserver_state.str_buf->len, true);
+}
+
+void gdb_handle_v_file_open(GArray *params, void *user_ctx)
+{
+ const char *filename = get_filename_param(params, 0);
+ uint64_t flags = get_param(params, 1)->val_ull;
+ uint64_t mode = get_param(params, 2)->val_ull;
+
+#ifdef CONFIG_LINUX
+ int fd = do_guest_openat(gdbserver_state.g_cpu->env_ptr, 0, filename,
+ flags, mode, false);
+#else
+ int fd = open(filename, flags, mode);
+#endif
+ if (fd < 0) {
+ g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
+ } else {
+ g_string_printf(gdbserver_state.str_buf, "F%d", fd);
+ }
+ gdb_put_strbuf();
+}
+
+void gdb_handle_v_file_close(GArray *params, void *user_ctx)
+{
+ int fd = get_param(params, 0)->val_ul;
+
+ if (close(fd) == -1) {
+ g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
+ gdb_put_strbuf();
+ return;
+ }
+
+ gdb_put_packet("F00");
+}
+
+void gdb_handle_v_file_pread(GArray *params, void *user_ctx)
+{
+ int fd = get_param(params, 0)->val_ul;
+ size_t count = get_param(params, 1)->val_ull;
+ off_t offset = get_param(params, 2)->val_ull;
+
+ size_t bufsiz = MIN(count, BUFSIZ);
+ g_autofree char *buf = g_try_malloc(bufsiz);
+ if (buf == NULL) {
+ gdb_put_packet("E12");
+ return;
+ }
+
+ ssize_t n = pread(fd, buf, bufsiz, offset);
+ if (n < 0) {
+ g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
+ gdb_put_strbuf();
+ return;
+ }
+ hostio_reply_with_data(buf, n);
+}
+
+void gdb_handle_v_file_readlink(GArray *params, void *user_ctx)
+{
+ const char *filename = get_filename_param(params, 0);
+
+ g_autofree char *buf = g_try_malloc(BUFSIZ);
+ if (buf == NULL) {
+ gdb_put_packet("E12");
+ return;
+ }
+
+#ifdef CONFIG_LINUX
+ ssize_t n = do_guest_readlink(filename, buf, BUFSIZ);
+#else
+ ssize_t n = readlink(filename, buf, BUFSIZ);
+#endif
+ if (n < 0) {
+ g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
+ gdb_put_strbuf();
+ return;
+ }
+ hostio_reply_with_data(buf, n);
+}
+
+void gdb_handle_query_xfer_exec_file(GArray *params, void *user_ctx)
+{
+ uint32_t pid = get_param(params, 0)->val_ul;
+ uint32_t offset = get_param(params, 1)->val_ul;
+ uint32_t length = get_param(params, 2)->val_ul;
+
+ GDBProcess *process = gdb_get_process(pid);
+ if (!process) {
+ gdb_put_packet("E00");
+ return;
+ }
+
+ CPUState *cpu = gdb_get_first_cpu_in_process(process);
+ if (!cpu) {
+ gdb_put_packet("E00");
+ return;
+ }
+
+ TaskState *ts = cpu->opaque;
+ if (!ts || !ts->bprm || !ts->bprm->filename) {
+ gdb_put_packet("E00");
+ return;
+ }
+
+ size_t total_length = strlen(ts->bprm->filename);
+ if (offset > total_length) {
+ gdb_put_packet("E00");
+ return;
+ }
+ if (offset + length > total_length) {
+ length = total_length - offset;
+ }
+
+ g_string_printf(gdbserver_state.str_buf, "l%.*s", length,
+ ts->bprm->filename + offset);
+ gdb_put_strbuf();
+}
--
2.39.2
next prev parent reply other threads:[~2023-06-30 18:14 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-30 18:03 [PATCH v4 00/38] maintainer omnibus: testing, fuzz, plugins, documentation, gdbstub (pre-PR) Alex Bennée
2023-06-30 18:03 ` [PATCH v4 01/38] gitlab: explicit set artifacts publishing criteria Alex Bennée
2023-06-30 18:03 ` [PATCH v4 02/38] gitlab: ensure coverage job also publishes meson log Alex Bennée
2023-06-30 18:03 ` [PATCH v4 03/38] gitlab: reduce testing scope of check-gcov Alex Bennée
2023-06-30 18:03 ` [PATCH v4 04/38] docs/devel: remind developers to run CI container pipeline when updating images Alex Bennée
2023-06-30 18:03 ` [PATCH v4 05/38] tests/tcg: add mechanism to handle plugin arguments Alex Bennée
2023-06-30 18:03 ` [PATCH v4 06/38] qemu-keymap: properly check return from xkb_keymap_mod_get_index Alex Bennée
2023-06-30 18:03 ` [PATCH v4 07/38] scripts/oss-fuzz: add a suppression for keymap Alex Bennée
2023-06-30 18:03 ` [PATCH v4 08/38] tests/qtests: clean-up and fix leak in generic_fuzz Alex Bennée
2023-07-03 8:00 ` Richard Henderson
2023-06-30 18:03 ` [PATCH v4 09/38] tests/docker: add test-fuzz Alex Bennée
2023-06-30 18:03 ` [PATCH v4 10/38] Makefile: add lcitool-refresh to UNCHECKED_GOALS Alex Bennée
2023-06-30 18:03 ` [PATCH v4 11/38] tests/lcitool: update to latest version Alex Bennée
2023-06-30 18:03 ` [PATCH v4 12/38] tests/lcitool: Bump fedora container versions Alex Bennée
2023-06-30 18:03 ` [PATCH v4 13/38] tests/lcitool: add an explicit gcc-native package Alex Bennée
2023-06-30 18:03 ` [PATCH v4 14/38] tests/lcitool: introduce qemu-minimal Alex Bennée
2023-07-03 7:59 ` Richard Henderson
2023-06-30 18:04 ` [PATCH v4 15/38] tests/docker: convert riscv64-cross to lcitool Alex Bennée
2023-07-03 7:59 ` Richard Henderson
2023-06-30 18:04 ` [PATCH v4 16/38] tests/avocado: update firmware to enable sbsa-ref/max Alex Bennée
2023-06-30 18:04 ` [PATCH v4 17/38] tests/avocado: Make the test_arm_bpim2u_gmac test more reliable Alex Bennée
2023-06-30 18:04 ` [PATCH v4 18/38] target/arm: make arm_casq_ptw CONFIG_TCG only Alex Bennée
2023-06-30 18:04 ` [PATCH v4 19/38] plugins: force slow path when plugins instrument memory ops Alex Bennée
2023-06-30 18:04 ` [PATCH v4 20/38] plugins: fix memory leak while parsing options Alex Bennée
2023-06-30 18:04 ` [PATCH v4 21/38] plugins: update lockstep to use g_memdup2 Alex Bennée
2023-06-30 18:04 ` [PATCH v4 22/38] docs/devel: add some front matter to the devel index Alex Bennée
2023-06-30 18:04 ` [PATCH v4 23/38] include/migration: mark vmstate_register() as a legacy function Alex Bennée
2023-06-30 18:04 ` [PATCH v4 24/38] include/hw/qdev-core: fixup kerneldoc annotations Alex Bennée
2023-06-30 18:04 ` [PATCH v4 25/38] docs/devel/qom.rst: Correct code style Alex Bennée
2023-06-30 18:04 ` [PATCH v4 26/38] docs/devel: split qom-api reference into new file Alex Bennée
2023-06-30 18:04 ` [PATCH v4 27/38] docs/devel: introduce some key concepts for QOM development Alex Bennée
2023-06-30 18:04 ` [PATCH v4 28/38] gdbstub: lightly refactor connection to avoid snprintf Alex Bennée
2023-07-03 7:57 ` Richard Henderson
2023-06-30 18:04 ` [PATCH v4 29/38] gdbstub: Permit reverse step/break to provide stop response Alex Bennée
2023-06-30 18:04 ` [PATCH v4 30/38] gdbstub: clean-up vcont handling to avoid goto Alex Bennée
2023-06-30 18:04 ` [PATCH v4 31/38] linux-user: Expose do_guest_openat() and do_guest_readlink() Alex Bennée
2023-06-30 18:04 ` [PATCH v4 32/38] linux-user: Add "safe" parameter to do_guest_openat() Alex Bennée
2023-06-30 18:04 ` [PATCH v4 33/38] linux-user: Emulate /proc/self/smaps Alex Bennée
2023-06-30 18:04 ` [PATCH v4 34/38] gdbstub: Expose gdb_get_process() and gdb_get_first_cpu_in_process() Alex Bennée
2023-06-30 18:04 ` [PATCH v4 35/38] gdbstub: Report the actual qemu-user pid Alex Bennée
2023-06-30 18:04 ` Alex Bennée [this message]
2023-06-30 18:04 ` [PATCH v4 37/38] docs: Document security implications of debugging Alex Bennée
2023-06-30 18:04 ` [PATCH v4 38/38] tests/tcg: Add a test for info proc mappings Alex Bennée
2023-08-08 22:45 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230630180423.558337-37-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=Qiuhao.Li@outlook.com \
--cc=alxndr@bu.edu \
--cc=berrange@redhat.com \
--cc=bleal@redhat.com \
--cc=bmeng.cn@gmail.com \
--cc=bsd@redhat.com \
--cc=crosa@redhat.com \
--cc=darren.kenny@oracle.com \
--cc=dominik.b.czarnota@gmail.com \
--cc=eduardo@habkost.net \
--cc=erdnaxe@crans.org \
--cc=iii@linux.ibm.com \
--cc=laurent@vivier.eu \
--cc=leobras@redhat.com \
--cc=lvivier@redhat.com \
--cc=ma.mandourr@gmail.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=marcin.juszkiewicz@linaro.org \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=quic_llindhol@quicinc.com \
--cc=quintela@redhat.com \
--cc=rad@semihalf.com \
--cc=richard.henderson@linaro.org \
--cc=riku.voipio@iki.fi \
--cc=stefanha@redhat.com \
--cc=thuth@redhat.com \
--cc=wainersm@redhat.com \
--cc=wangyanan55@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).