From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id OEtEBvjkkV9pSAAAWB0awg (envelope-from ) for ; Thu, 22 Oct 2020 16:00:56 -0400 Received: by simark.ca (Postfix, from userid 112) id 14A351EFC9; Thu, 22 Oct 2020 16:00:56 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 49DD21E552 for ; Thu, 22 Oct 2020 16:00:49 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 95B5D3987502; Thu, 22 Oct 2020 20:00:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 95B5D3987502 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1603396848; bh=imPKjXyldRMKoqEbhUQecSrotGF7rcR1oMdofLKIGkM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=clWkqs/SCaNoC6lflbH8NkkcGthnBd+9F7MfpuDz+Q2YWH7L/jVhOygnW739XC5hP xd9Hjvbnv33/6zlxF1NAFXE4ipl5xse/uU3CUaZOTW9Q4J/0xm/KTrl3zjrGpkSev4 84R/N52r+JSZ5QS80WLy90y7iw801K5dvUzQPtE8= Received: from mail-qk1-x744.google.com (mail-qk1-x744.google.com [IPv6:2607:f8b0:4864:20::744]) by sourceware.org (Postfix) with ESMTPS id 3C31F385783D for ; Thu, 22 Oct 2020 20:00:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3C31F385783D Received: by mail-qk1-x744.google.com with SMTP id b69so3070681qkg.8 for ; Thu, 22 Oct 2020 13:00:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=imPKjXyldRMKoqEbhUQecSrotGF7rcR1oMdofLKIGkM=; b=la+GMmkQIyssUpuAbNrAkhCJ0QuJ3/3uzjKu5wn6Ku68K9PUMKC7hpWWe2kYwHIelu wicoqqAfHWWF15zHXnER27anSAeaGIKTLzNycpJLCicOkej+jFsG6flKPiB1GJNuLHyD oLMsuCNDlX8BaZ4vWR/Zm3LwFrfVlLIuJVUz1qQZ0Cm1U0oXz4N9EsQxbqjQEBxvLOPz MmVSftmYXniNEaBUTTr9bYf7YS5F1aJl6xB+pjCXnRZlLcHxzOx79yZaBM76YQGSi6h2 cyZH1wusmjW6eMdBVrZMwrSfrDGueTHo+z6/YQzwCqQbQvCbAjCHmYlzdb8fVQboGVVY 606w== X-Gm-Message-State: AOAM5305O22qm4pblC2dGpJjCddafttEWLhE7nvRU93a9XKwfqCvYuT7 hPAfokaUvsMmQw/S53xj2dYIds2I9iP+1Q== X-Google-Smtp-Source: ABdhPJyp0Eh/eX68U7j1p95kPw7ixo4N4++/gmTmOKxIrlWuco+sHXDHD4uJ/K3amPybc/JUzQUUEw== X-Received: by 2002:a05:620a:144d:: with SMTP id i13mr3045419qkl.78.1603396836442; Thu, 22 Oct 2020 13:00:36 -0700 (PDT) Received: from localhost.localdomain ([2804:7f0:8284:1487:b9b1:f72a:8f1:600]) by smtp.gmail.com with ESMTPSA id a21sm1711208qkk.98.2020.10.22.13.00.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Oct 2020 13:00:35 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [PATCH v2 05/24] GDBserver remote packet support for memory tagging Date: Thu, 22 Oct 2020 16:59:55 -0300 Message-Id: <20201022200014.5189-6-luis.machado@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201022200014.5189-1-luis.machado@linaro.org> References: <20201022200014.5189-1-luis.machado@linaro.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: , From: Luis Machado via Gdb-patches Reply-To: Luis Machado Cc: david.spickett@linaro.org Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" Updates on v2: - Update target methods to contain a tag type field. - Update remote packet processing to parse the type field. -- This patch adds the generic remote bits to gdbserver so it can check for memory tagging support and handle fetch tags and store tags requests. gdbserver/ChangeLog: YYYY-MM-DD Luis Machado * remote-utils.cc (decode_m_packet_params): Renamed from ... (decode_m_packet): ... this, which now calls decode_m_packet_params. Make char * param/return const char *. (decode_M_packet): Use decode_m_packet_params and make char * param const char *. * remote-utils.h (decode_m_packet_params): New prototype. (decode_m_packet): Constify char pointers. (decode_M_packet): Likewise. * server.cc (create_fmemtags_reply, parse_smemtags_request): New functions. (handle_general_set): Handle the QMemTags packet. (parse_fmemtags_request): New function. (handle_query): Handle the qMemTags packet and advertise memory tagging support. (captured_main): Initialize memory tagging flag. * server.h (struct client_state): Initialize memory tagging flag. * target.cc (process_stratum_target::supports_memory_tagging) (process_stratum_target::fetch_memtags) (process_stratum_target::store_memtags): New methods. * target.h: Include gdbsupport/byte-vector.h. (class process_stratum_target) : New class virtual methods. (target_supports_memory_tagging): Define. --- gdbserver/remote-utils.cc | 43 ++++++----- gdbserver/remote-utils.h | 7 +- gdbserver/server.cc | 145 ++++++++++++++++++++++++++++++++++++++ gdbserver/server.h | 3 + gdbserver/target.cc | 20 ++++++ gdbserver/target.h | 17 +++++ 6 files changed, 210 insertions(+), 25 deletions(-) diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc index 5a6ceb1d9a..1774bfafc9 100644 --- a/gdbserver/remote-utils.cc +++ b/gdbserver/remote-utils.cc @@ -1304,10 +1304,14 @@ prepare_resume_reply (char *buf, ptid_t ptid, } } -void -decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr) +/* Decode ADDR and LEN from a parameter of the form "addr,len", with + being an end marker character. */ + +const char * +decode_m_packet_params (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr, const char end_marker) { - int i = 0, j = 0; + int i = 0; char ch; *mem_addr_ptr = *len_ptr = 0; @@ -1317,39 +1321,32 @@ decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr) *mem_addr_ptr |= fromhex (ch) & 0x0f; } - for (j = 0; j < 4; j++) + while ((ch = from[i++]) != end_marker) { - if ((ch = from[i++]) == 0) - break; *len_ptr = *len_ptr << 4; *len_ptr |= fromhex (ch) & 0x0f; } + + return from + i; } void -decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr, - unsigned char **to_p) +decode_m_packet (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr) { - int i = 0; - char ch; - *mem_addr_ptr = *len_ptr = 0; - - while ((ch = from[i++]) != ',') - { - *mem_addr_ptr = *mem_addr_ptr << 4; - *mem_addr_ptr |= fromhex (ch) & 0x0f; - } + decode_m_packet_params (from, mem_addr_ptr, len_ptr, '\0'); +} - while ((ch = from[i++]) != ':') - { - *len_ptr = *len_ptr << 4; - *len_ptr |= fromhex (ch) & 0x0f; - } +void +decode_M_packet (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr, unsigned char **to_p) +{ + from = decode_m_packet_params (from, mem_addr_ptr, len_ptr, ':'); if (*to_p == NULL) *to_p = (unsigned char *) xmalloc (*len_ptr); - hex2bin (&from[i++], *to_p, *len_ptr); + hex2bin (from, *to_p, *len_ptr); } int diff --git a/gdbserver/remote-utils.h b/gdbserver/remote-utils.h index 1b31456798..4d0e1cd250 100644 --- a/gdbserver/remote-utils.h +++ b/gdbserver/remote-utils.h @@ -45,9 +45,12 @@ void prepare_resume_reply (char *buf, ptid_t ptid, const char *decode_address_to_semicolon (CORE_ADDR *addrp, const char *start); void decode_address (CORE_ADDR *addrp, const char *start, int len); -void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr, +const char *decode_m_packet_params (const char *from, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr, + const char end_marker); +void decode_m_packet (const char *from, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr); -void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr, +void decode_M_packet (const char *from, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr, unsigned char **to_p); int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr, unsigned char **to_p); diff --git a/gdbserver/server.cc b/gdbserver/server.cc index 1601453922..0c845be4af 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -547,12 +547,71 @@ handle_btrace_conf_general_set (char *own_buf) return 1; } +/* Create the qMemTags packet reply given TAGS. */ + +static int +create_fmemtags_reply (char *reply, const gdb::byte_vector &tags) +{ + /* It is an error to pass a zero-sized tag vector. */ + if (tags.size () == 0) + return 1; + + std::string packet ("m"); + + /* Write the tag data. */ + packet += bin2hex (tags.data (), tags.size ()); + + /* Check if the reply is too big for the packet to handle. */ + if (PBUFSIZ < packet.size ()) + return 1; + + strcpy (reply, packet.c_str ()); + return 0; +} + +/* Parse the QMemTags request into ADDR, LEN and TAGS. + + Return 0 if successful, non-zero otherwise. */ + +static int +parse_smemtags_request (char *request, CORE_ADDR *addr, size_t *len, + gdb::byte_vector &tags, int *type) +{ + if (!startswith (request, "QMemTags:")) + return 1; + + const char *p = request + strlen ("QMemTags:"); + + /* Read address and length. */ + unsigned int length = 0; + p = decode_m_packet_params (p, addr, &length, ':'); + *len = length; + + /* Read the tag type. */ + ULONGEST tag_type = 0; + p = unpack_varlen_hex (p, &tag_type); + *type = (int) tag_type; + + /* Make sure there is a colon after the type. */ + if (*p != ':') + return 1; + + /* Skip the colon. */ + p++; + + /* Read the tag data. */ + tags = hex2bin (p); + + return 0; +} + /* Handle all of the extended 'Q' packets. */ static void handle_general_set (char *own_buf) { client_state &cs = get_client_state (); + if (startswith (own_buf, "QPassSignals:")) { int numsigs = (int) GDB_SIGNAL_LAST, i; @@ -903,6 +962,31 @@ handle_general_set (char *own_buf) return; } + + /* Handle store memory tags packets. */ + if (startswith (own_buf, "QMemTags:") + && target_supports_memory_tagging ()) + { + gdb::byte_vector tags; + CORE_ADDR addr = 0; + size_t len = 0; + int type = 0; + + require_running_or_return (own_buf); + + int ret = parse_smemtags_request (own_buf, &addr, &len, tags, &type); + + if (ret == 0) + ret = the_target->store_memtags (addr, len, tags, type); + + if (ret) + write_enn (own_buf); + else + write_ok (own_buf); + + return; + } + /* Otherwise we didn't know what packet it was. Say we didn't understand it. */ own_buf[0] = 0; @@ -2066,6 +2150,31 @@ crc32 (CORE_ADDR base, int len, unsigned int crc) return (unsigned long long) crc; } +/* Parse the qMemTags packet request into ADDR and LEN. + + Return 0 if successful, non-zero otherwise. */ + +static int +parse_fmemtags_request (char *request, CORE_ADDR *addr, size_t *len, int *type) +{ + if (!startswith (request, "qMemTags:")) + return 1; + + const char *p = request + strlen ("qMemTags:"); + + /* Read address and length. */ + unsigned int length = 0; + p = decode_m_packet_params (p, addr, &length, ':'); + *len = length; + + /* Read the tag type. */ + ULONGEST tag_type = 0; + p = unpack_varlen_hex (p, &tag_type); + *type = (int) tag_type; + + return 0; +} + /* Add supported btrace packets to BUF. */ static void @@ -2284,6 +2393,12 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) events. */ report_no_resumed = true; } + else if (feature == "memory-tagging+") + { + /* GDB supports memory tagging features. */ + if (target_supports_memory_tagging ()) + cs.memory_tagging_feature = true; + } else { /* Move the unknown features all together. */ @@ -2401,6 +2516,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) strcat (own_buf, ";no-resumed+"); + if (target_supports_memory_tagging ()) + strcat (own_buf, ";memory-tagging+"); + /* Reinitialize components as needed for the new connection. */ hostio_handle_new_gdb_connection (); target_handle_new_gdb_connection (); @@ -2593,6 +2711,32 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) if (target_supports_tracepoints () && handle_tracepoint_query (own_buf)) return; + /* Handle fetch memory tags packets. */ + if (startswith (own_buf, "qMemTags:") + && target_supports_memory_tagging ()) + { + gdb::byte_vector tags; + CORE_ADDR addr = 0; + size_t len = 0; + int type = 0; + + require_running_or_return (own_buf); + + int ret = parse_fmemtags_request (own_buf, &addr, &len, &type); + + if (ret == 0) + ret = the_target->fetch_memtags (addr, len, tags, type); + + if (ret == 0) + ret = create_fmemtags_reply (own_buf, tags); + + if (ret) + write_enn (own_buf); + + *new_packet_len_p = strlen (own_buf); + return; + } + /* Otherwise we didn't know what packet it was. Say we didn't understand it. */ own_buf[0] = 0; @@ -3810,6 +3954,7 @@ captured_main (int argc, char *argv[]) cs.swbreak_feature = 0; cs.hwbreak_feature = 0; cs.vCont_supported = 0; + cs.memory_tagging_feature = false; remote_open (port); diff --git a/gdbserver/server.h b/gdbserver/server.h index 22228050a8..3d4a086e18 100644 --- a/gdbserver/server.h +++ b/gdbserver/server.h @@ -190,6 +190,9 @@ struct client_state int current_traceframe = -1; + /* If true, memory tagging features are supported. */ + bool memory_tagging_feature = false; + }; client_state &get_client_state (); diff --git a/gdbserver/target.cc b/gdbserver/target.cc index 921d26fcf7..70df911e9f 100644 --- a/gdbserver/target.cc +++ b/gdbserver/target.cc @@ -464,6 +464,26 @@ process_stratum_target::supports_read_offsets () return false; } +bool +process_stratum_target::supports_memory_tagging () +{ + return false; +} + +int +process_stratum_target::fetch_memtags (CORE_ADDR address, size_t len, + gdb::byte_vector &tags, int type) +{ + return 0; +} + +int +process_stratum_target::store_memtags (CORE_ADDR address, size_t len, + const gdb::byte_vector &tags, int type) +{ + return 0; +} + int process_stratum_target::read_offsets (CORE_ADDR *text, CORE_ADDR *data) { diff --git a/gdbserver/target.h b/gdbserver/target.h index c2245ebfe8..e3e6b07fee 100644 --- a/gdbserver/target.h +++ b/gdbserver/target.h @@ -30,6 +30,7 @@ #include "gdbsupport/array-view.h" #include "gdbsupport/btrace-common.h" #include +#include "gdbsupport/byte-vector.h" struct emit_ops; struct buffer; @@ -499,6 +500,19 @@ class process_stratum_target /* Return tdesc index for IPA. */ virtual int get_ipa_tdesc_idx (); + + /* Returns true if the target supports memory tagging facilities. */ + virtual bool supports_memory_tagging (); + + /* Return the allocated memory tags of type TYPE associated with + [ADDRESS, ADDRESS + LEN) in TAGS. */ + virtual int fetch_memtags (CORE_ADDR address, size_t len, + gdb::byte_vector &tags, int type); + + /* Write the allocation tags of type TYPE contained in TAGS to the + memory range [ADDRESS, ADDRESS + LEN). */ + virtual int store_memtags (CORE_ADDR address, size_t len, + const gdb::byte_vector &tags, int type); }; extern process_stratum_target *the_target; @@ -525,6 +539,9 @@ int kill_inferior (process_info *proc); #define target_supports_exec_events() \ the_target->supports_exec_events () +#define target_supports_memory_tagging() \ + the_target->supports_memory_tagging () + #define target_handle_new_gdb_connection() \ the_target->handle_new_gdb_connection () -- 2.17.1