From mboxrd@z Thu Jan 1 00:00:00 1970 Received: by 2002:a17:906:fcb7:b0:974:3dd3:6e73 with SMTP id qw23csp3487715ejb; Tue, 6 Jun 2023 06:28:02 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4ANH9zi2xz9se6Cs7VBHSzmYaYR//EWLH0xdRQ7KSqy74o0+c5DE1W7NgzgKD2TZmYYo09 X-Received: by 2002:a92:cb88:0:b0:33a:5bb5:f8f6 with SMTP id z8-20020a92cb88000000b0033a5bb5f8f6mr1448416ilo.18.1686058081858; Tue, 06 Jun 2023 06:28:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686058081; cv=none; d=google.com; s=arc-20160816; b=PJ8dUZlRdzEwNo6dLnTboaAvPPg/rwWQbGclcsksK0xH/z0um22fXHEvLEW9cTVmnC Yp+AqIBklHOJvcQOmuJJWqgtArKMgRrJXrckFnS9pd04ZBoI1h4wgfBv723viTSfyCv4 1wrO1shv14C0LFqWdvuADeii76GrrWiBjexJ3x10yFyaWdX0FprCBCbXgqD1qTKXvRHC ksA21LKaHLyWIhoNQK8xdxfdUJg+6g6AiigKE4dlVhadkUsTvzfGvfRycWhhtDYYeAML E983lafSUAbGCXfeqok3oB3SYOwtSPInd4hhGMTO+lGvPhr/fCZ/cjUfqkPbbgeooE/N Q5OA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:content-transfer-encoding:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=h4Eo/WE6PD7DH+aUp8YME6oujn0fEcEMUOitRx5EvTk=; b=jT0okajTvmAimRQ5yj3WXiqYk1VJI/CZV/n1GCFTWlbLfllzRbnGPIoLGG/CUjI8OX KSjvPIUJDTAQ99eJrgqIp6I87wDMhQne4QlGbs4bK2b3LdU5NoP334zKwu7yxYsHGGt9 oScKcas6vpS0UT8UpphRUrdO7bVBoeqmOgl5qTdEkNwd+vc/nvgOWpGkpawsxyQ1YdrY W+CMmWTvGfKtBylXS5lgZNHzA4hK5nZHIKR/xZsN1JyTKwzMa1pprE8cNHDFK5oKikYI aeZEbr4jQ/6LiX/qhVt54XxH5eYVBx9Xcnn3IXdisAdKfBc4gxlHKIlzFHtD0TNZINqF 8LTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b=RhrkpmOl; spf=pass (google.com: domain of iii@linux.ibm.com designates 148.163.156.1 as permitted sender) smtp.mailfrom=iii@linux.ibm.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com. [148.163.156.1]) by mx.google.com with ESMTPS id t17-20020a026411000000b00416481a3d2dsi3751203jac.195.2023.06.06.06.28.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Jun 2023 06:28:01 -0700 (PDT) Received-SPF: pass (google.com: domain of iii@linux.ibm.com designates 148.163.156.1 as permitted sender) client-ip=148.163.156.1; Authentication-Results: mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b=RhrkpmOl; spf=pass (google.com: domain of iii@linux.ibm.com designates 148.163.156.1 as permitted sender) smtp.mailfrom=iii@linux.ibm.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 356DKXiM007226; Tue, 6 Jun 2023 13:28:01 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-transfer-encoding : mime-version; s=pp1; bh=h4Eo/WE6PD7DH+aUp8YME6oujn0fEcEMUOitRx5EvTk=; b=RhrkpmOlsnpKRYSXQbsZlrU01LfGIoGARAxnvhpC/mnxcK8sJTw9Yp/+2JHkle6pocYh 7frp7uj1bU1O3dwlI0nOKnGCowKyh7sNhQO1GeSEfaMg113TR14YyPZd03ytgvuzP20i Icn5kb81c5onqs0yrVqOH8KVy7rUXLnv0A/z6PpVRr7DQ06pIBwX0DqhisljRg3jil7k ai/oUvmBTfBgh2pTs++4m+mUsoLNxrF5UOIMKnGyR8ZuDdyw2G/S4NvwOfpLL6Iwmhv7 lDk++QOoSyxnz9oG7rdu9jk+qgjv+FzYsTTnn+S4h24lpedYWwvSpnXgo7haTYZspZxe 0A== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3r25kfr690-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 06 Jun 2023 13:28:00 +0000 Received: from m0360083.ppops.net (m0360083.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 356DLsUU011617; Tue, 6 Jun 2023 13:28:00 GMT Received: from ppma06fra.de.ibm.com (48.49.7a9f.ip4.static.sl-reverse.com [159.122.73.72]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3r25kfr67n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 06 Jun 2023 13:28:00 +0000 Received: from pps.filterd (ppma06fra.de.ibm.com [127.0.0.1]) by ppma06fra.de.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 3562qbuD019031; Tue, 6 Jun 2023 13:27:57 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma06fra.de.ibm.com (PPS) with ESMTPS id 3qyx5q9hue-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 06 Jun 2023 13:27:57 +0000 Received: from smtpav02.fra02v.mail.ibm.com (smtpav02.fra02v.mail.ibm.com [10.20.54.101]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 356DRtvR44695950 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 6 Jun 2023 13:27:55 GMT Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E32C62004E; Tue, 6 Jun 2023 13:27:54 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 95B0120040; Tue, 6 Jun 2023 13:27:54 +0000 (GMT) Received: from heavy.boeblingen.de.ibm.com (unknown [9.155.209.184]) by smtpav02.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 6 Jun 2023 13:27:54 +0000 (GMT) From: Ilya Leoshkevich To: =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , Peter Maydell , Richard Henderson , David Hildenbrand Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org, qemu-arm@nongnu.org, qemu-s390x@nongnu.org, Ilya Leoshkevich , "Dominik 'Disconnect3d' Czarnota" Subject: [PATCH v3 6/8] gdbstub: Add support for info proc mappings Date: Tue, 6 Jun 2023 15:27:41 +0200 Message-Id: <20230606132743.1386003-7-iii@linux.ibm.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230606132743.1386003-1-iii@linux.ibm.com> References: <20230606132743.1386003-1-iii@linux.ibm.com> X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 0rWctmoq-iAySEH-ExEPBFnm5M6QAo5z X-Proofpoint-ORIG-GUID: 7zq34fMoVoxme9o8LNHH2XHvQQ99w-An Content-Transfer-Encoding: 8bit X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.573,FMLib:17.11.176.26 definitions=2023-06-06_08,2023-06-06_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 lowpriorityscore=0 impostorscore=0 mlxscore=0 adultscore=0 priorityscore=1501 clxscore=1015 malwarescore=0 mlxlogscore=999 bulkscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2304280000 definitions=main-2306060110 X-TUID: xiYvd2Phz43+ 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 Signed-off-by: Ilya Leoshkevich --- gdbstub/gdbstub.c | 45 +++++++++++++- gdbstub/internals.h | 5 ++ gdbstub/user-target.c | 139 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 2 deletions(-) diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index c7e3ee71f2f..d2efefd3528 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -1337,6 +1337,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) @@ -1482,11 +1512,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+")) { @@ -1625,13 +1658,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/internals.h b/gdbstub/internals.h index 25e4d5eeaa6..f2b46cce412 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/user-target.c b/gdbstub/user-target.c index fa0e59ec9a5..aa64a8b9440 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,138 @@ 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%lx;", 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"); +} + +#define BUFSIZ 8192 + +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.40.1