From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nx207.node01.secure-mailgate.com (nx207.node01.secure-mailgate.com [89.22.108.207]) by sourceware.org (Postfix) with ESMTPS id 5CCC6393C86F for ; Fri, 26 Feb 2021 02:46:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5CCC6393C86F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=trande.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=zied.guermazi@trande.de Received: from host202.checkdomain.de ([185.137.168.148]) by node01.secure-mailgate.com with esmtps (TLSv1.2:AES128-GCM-SHA256:128) (Exim 4.92) (envelope-from ) id 1lFT99-007qpf-Op for gdb-patches@sourceware.org; Fri, 26 Feb 2021 03:46:28 +0100 X-SecureMailgate-Identity: zied.guermazi@trande.de;host202.checkdomain.de Received: from Trande0001.fritz.box (x4dbd6140.dyn.telefonica.de [77.189.97.64]) (Authenticated sender: zied.guermazi@trande.de) by host202.checkdomain.de (Postfix) with ESMTPSA id 3EBE03880D7; Fri, 26 Feb 2021 03:46:27 +0100 (CET) From: Zied Guermazi To: gdb-patches@sourceware.org Cc: Zied Guermazi Subject: [PATCH 6/8] add support for coresight btrace via remote protocol Date: Fri, 26 Feb 2021 03:46:00 +0100 Message-Id: <20210226024602.55057-7-zied.guermazi@trande.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210226024602.55057-1-zied.guermazi@trande.de> References: <20210226024602.55057-1-zied.guermazi@trande.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-PPP-Message-ID: <20210226024627.3433132.8478@host202.checkdomain.de> X-PPP-Vhost: trande.de X-Originating-IP: 185.137.168.148 X-SecureMailgate-Domain: host202.checkdomain.de X-SecureMailgate-Username: 185.137.168.148 Authentication-Results: secure-mailgate.com; auth=pass smtp.auth=185.137.168.148@host202.checkdomain.de X-SecureMailgate-Outgoing-Class: ham X-SecureMailgate-Outgoing-Evidence: SB/global_tokens (0.00316648518509) X-Recommended-Action: accept X-Filter-ID: Pt3MvcO5N4iKaDQ5O6lkdGlMVN6RH8bjRMzItlySaT8K4oqWiWOT8G9oKIDub5qFPUtbdvnXkggZ 3YnVId/Y5jcf0yeVQAvfjHznO7+bT5wgSQOko5ya3orWH1MkzQXa2oPZqVS5i0KNMNtVCi0tRw/C h5SE4jAyhe1COeASyU+qRQabvCNLmdbZ7Rtn8dw54ld5rdi2ZxohSIq+dqifZoVY3IcDeckxfee+ NDQ6wUl3g/WbBekzB3IK8RY7uNAEcY1i02TJefD768F5oV2iM8C0xB8SW32wy2mbLZXD/P/xjgGi IdaTDXlxoyUe5P+Jut5PpkrBQueV+Yg5wqLK/DPxZnad5mPqz8E0hUQw3qwLMK9HC+pUQBAyR03+ Yzd8ARsynxDH0D+SLDJWdESXziw50BoEYB44qFPH6be8XgtMhiMRK0C70oXENkWqJaNtpfX1h/uL cDQJCG2naSen4S0KEAnwyE9dte+FkDKSV99EDBffVZVjmVaNbG4ZJG7F2RgQw3d3zmVen9wp80qQ nk5/t+UnI24Hleg6UWHjmGlvyMjbyNpr4xR6RL2C9+qlIny++hg9dJLqN5zmWqF/oNe6FVV7drXD mtOldfpWzeXX3Vs0+OVZ6o01Ur0UfsSgVqahaS1Xn3nbmTfiR5jKRrn6qQ/in5NA6oG3bP7L0DnU JleWftUulkbC12DciiOUAQy3WRoWhjJ4ABRp4spTBKsH/WzE78WB+6LKJkk4wWAos7Vk+4I720v2 H9/mQnco6do4wvfNMSsfBzHuYol+AkxxORKVhc8Rtqd4GS/tmv9FXdcOXXm38/++NKnQrU/tOnYQ psOL3D4WKYPb9hiQqsMR3pimW+H6hrLs7bihM+ep7Sq+vnK5vq335GkOmYDoHPDsFqo1t5bEBI0m 4NsB3v57rn7svr0CR7c5hAqOktxJ52+eJVfFyi5Fe59LNAUy8n70AX6FTQumWXzmipp+gzwJWw42 swm4bO6gacpMpzI93NKmpOx249IDJgHZhSqYgJJFthw94zyDVRbqPxaxhXoarW2MF3gazIzgmJi5 UydShOH22SRgbHWq1uciMDoDhcd9NG1JDoOknqc6qrb4AiZPF6HXPq5gLm4Q4ElmvUALMK9HC+pU QBAyR03+Yzd87yCUgX8YuF5WBQr1Bq861zvA3BXN5HBbApl4eIrLaWewxjLyThsLecb51qdaSQev MS+4ayUpOtEhdxekWDmK9g== X-Report-Abuse-To: spam@node04.secure-mailgate.com X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP, UNWANTED_LANGUAGE_BODY autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Fri, 26 Feb 2021 02:46:34 -0000 This patch extends the remote protocol to use ARM CoreSight traces for btrace. This patch adds the capabilities enumeration as well as the required protocol extentions for configuring traces collection, starting and stopping tracing, and transferring the traces as well as the parameters needed for decoding them. gdb/ChangeLog * btrace.c (check_xml_btrace_version): add version 1.1 * btrace.c (parse_xml_btrace_etm_config_source_config_cpu_etmv4_config): New. * btrace.c (parse_xml_btrace_etm_config_source_config_cpu_etmv3_config): New. * btrace.c (parse_xml_btrace_etm_config_source_config_cpu_etm_config): New. * btrace.c (parse_xml_btrace_etm_config_source_config): New. * btrace.c (dump_config): New. * btrace.c (parse_xml_btrace_etm_config_source_config_end): New. * btrace.c (parse_xml_btrace_etm_config_sink_config): New. * btrace.c (parse_xml_btrace_etm_raw): New. * btrace.c (parse_xml_btrace_etm): New. * btrace.c (parse_xml_btrace_conf_etm): New. * btrace.dtd: add etm data and decoding parameters. * btrace-conf.dtd: add etm configuration. * remote.c (remote_target::btrace_sync_conf): add etm configuration. * remote.c(remote_target::enable_btrace): add coresight etm. * remote.c (_initialize_remote): add etm related packets. gdbserver/ChangeLog * configure.srv: add btrace for aarch64*-*-linux* and arm*-*-linux*. * linux-low.c (linux_low_encode_etm_config): New. * linux-low.c (linux_process_target::read_btrace): encode CoreSight traces and relative decoding parameters. * linux-low.c (linux_process_target::read_btrace_conf): encode CoreSight configuration. * server.cc (handle_btrace_enable_etm): New. * server.cc (handle_btrace_general_set): add etm handling. * server.cc (handle_btrace_conf_general_set): add etm handling. * server.cc (supported_btrace_packets): add etm related packets. --- gdb/ChangeLog | 22 +++ gdb/btrace.c | 360 ++++++++++++++++++++++++++++++++++- gdb/features/btrace-conf.dtd | 10 +- gdb/features/btrace.dtd | 39 +++- gdb/remote.c | 66 ++++++- gdbserver/ChangeLog | 13 ++ gdbserver/configure.srv | 4 + gdbserver/linux-low.cc | 103 +++++++++- gdbserver/server.cc | 34 +++- 9 files changed, 639 insertions(+), 12 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 15dee4eb29b..30f45a62cd5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2021-02-25 Zied Guermazi + + * btrace.c (check_xml_btrace_version): add version 1.1 + * btrace.c (parse_xml_btrace_etm_config_source_config_cpu_etmv4_config): + New. + * btrace.c (parse_xml_btrace_etm_config_source_config_cpu_etmv3_config): + New. + * btrace.c (parse_xml_btrace_etm_config_source_config_cpu_etm_config): + New. + * btrace.c (parse_xml_btrace_etm_config_source_config): New. + * btrace.c (dump_config): New. + * btrace.c (parse_xml_btrace_etm_config_source_config_end): New. + * btrace.c (parse_xml_btrace_etm_config_sink_config): New. + * btrace.c (parse_xml_btrace_etm_raw): New. + * btrace.c (parse_xml_btrace_etm): New. + * btrace.c (parse_xml_btrace_conf_etm): New. + * btrace.dtd: add etm data and decoding parameters. + * btrace-conf.dtd: add etm configuration. + * remote.c (remote_target::btrace_sync_conf): add etm configuration. + * remote.c(remote_target::enable_btrace): add coresight etm. + * remote.c (_initialize_remote): add etm related packets. + 2021-02-25 Zied Guermazi * infrun.c (set_step_over_info): add debug print. diff --git a/gdb/btrace.c b/gdb/btrace.c index dcb89964b81..ded539e94f6 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -2597,7 +2597,7 @@ check_xml_btrace_version (struct gdb_xml_parser *parser, const char *version = (const char *) xml_find_attribute (attributes, "version")->value.get (); - if (strcmp (version, "1.0") != 0) + if ((strcmp (version, "1.0") != 0) && (strcmp (version, "1.1") != 0)) gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version); } @@ -2732,6 +2732,238 @@ parse_xml_btrace_pt (struct gdb_xml_parser *parser, btrace->variant.pt.size = 0; } +/* Parse a btrace etm "cpu-etm-config-etmv4_config" xml record. */ + +static void +parse_xml_btrace_etm_config_source_config_cpu_etmv4_config ( + struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_data *btrace; + struct gdb_xml_value *reg_idr0; + struct gdb_xml_value *reg_idr1; + struct gdb_xml_value *reg_idr2; + struct gdb_xml_value *reg_idr8; + struct gdb_xml_value *reg_configr; + struct gdb_xml_value *reg_traceidr; + cs_etm_trace_params *etm_trace_params; + + DEBUG ("parse_xml_btrace_etm_config_source_config_cpu_etmv4_config"); + + btrace = (struct btrace_data *) user_data; + etm_trace_params = & (btrace->variant.etm.config.etm_trace_params->back()); + + reg_idr0 + = xml_find_attribute (attributes, "reg_idr0"); + reg_idr1 + = xml_find_attribute (attributes, "reg_idr1"); + reg_idr2 + = xml_find_attribute (attributes, "reg_idr2"); + reg_idr8 + = xml_find_attribute (attributes, "reg_idr8"); + reg_configr + = xml_find_attribute (attributes, "reg_configr"); + reg_traceidr + = xml_find_attribute (attributes, "reg_traceidr"); + + etm_trace_params->etmv4.reg_idr0 + = (unsigned int) *(ULONGEST *)reg_idr0->value.get (); + etm_trace_params->etmv4.reg_idr1 + = (unsigned int) *(ULONGEST *)reg_idr1->value.get (); + etm_trace_params->etmv4.reg_idr2 + = (unsigned int) *(ULONGEST *)reg_idr2->value.get (); + etm_trace_params->etmv4.reg_idr8 + = (unsigned int) *(ULONGEST *)reg_idr8->value.get (); + etm_trace_params->etmv4.reg_configr + = (unsigned int) *(ULONGEST *)reg_configr->value.get (); + etm_trace_params->etmv4.reg_traceidr + = (unsigned int) *(ULONGEST *)reg_traceidr->value.get (); + +} + +/* Parse a btrace etm "cpu-etm-config-etmv3_config" xml record. */ + +static void +parse_xml_btrace_etm_config_source_config_cpu_etmv3_config ( + struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_data *btrace; + struct gdb_xml_value *reg_ctrl; + struct gdb_xml_value *reg_trc_id; + struct gdb_xml_value *reg_ccer; + struct gdb_xml_value *reg_idr; + + cs_etm_trace_params *etm_trace_params; + + DEBUG ("parse_xml_btrace_etm_config_source_config_cpu_etmv3_config"); + + btrace = (struct btrace_data *) user_data; + etm_trace_params = & (btrace->variant.etm.config.etm_trace_params->back()); + + reg_ctrl + = xml_find_attribute (attributes, "reg_ctrl"); + reg_trc_id + = xml_find_attribute (attributes, "reg_trc_id"); + reg_ccer + = xml_find_attribute (attributes, "reg_ccer"); + reg_idr + = xml_find_attribute (attributes, "reg_idr"); + + etm_trace_params->etmv3.reg_ctrl + = (unsigned int) *(ULONGEST *) reg_ctrl->value.get (); + etm_trace_params->etmv3.reg_trc_id + = (unsigned int) *(ULONGEST *)reg_trc_id->value.get (); + etm_trace_params->etmv3.reg_ccer + = (unsigned int) *(ULONGEST *)reg_ccer->value.get (); + etm_trace_params->etmv3.reg_idr + = (unsigned int) *(ULONGEST *)reg_idr->value.get (); +} + + +/* Parse a btrace etm "cpu-etm-config" xml record. */ + +static void +parse_xml_btrace_etm_config_source_config_cpu_etm_config (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_data *btrace; + struct gdb_xml_value *arch_ver; + struct gdb_xml_value *core_prof; + struct gdb_xml_value *protocol; + cs_etm_trace_params etm_trace_params; + + DEBUG ("parse_xml_btrace_etm_config_source_config_cpu_etm_config"); + + btrace = (struct btrace_data *) user_data; + + arch_ver + = xml_find_attribute (attributes, "arch_ver"); + core_prof + = xml_find_attribute (attributes, "core_prof"); + protocol + = xml_find_attribute (attributes, "protocol"); + + etm_trace_params.arch_ver=(int) *(ULONGEST *) arch_ver->value.get (); + etm_trace_params.core_profile=(int) *(ULONGEST *)core_prof->value.get (); + etm_trace_params.protocol=(int) *(ULONGEST *)protocol->value.get (); + + btrace->variant.etm.config.etm_trace_params->push_back(etm_trace_params); +} + +/* Parse a btrace etm "source-config" xml record. */ + +static void +parse_xml_btrace_etm_config_source_config (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_data *btrace; + struct gdb_xml_value *trace_id; + + DEBUG ("parse_xml_btrace_etm_config_source_config"); + btrace = (struct btrace_data *) user_data; + + trace_id = xml_find_attribute (attributes, "trace_id"); + if (trace_id != NULL) + btrace->variant.etm.trace_id + = (unsigned int) *(ULONGEST *) trace_id->value.get (); + btrace->variant.etm.config.etm_trace_params + = new std::vector; +} + +/* get the number of cpus */ +static void +parse_xml_btrace_etm_config_source_config_end(struct gdb_xml_parser *, + const struct gdb_xml_element *, + void *user_data, const char *body_text) +{ + struct btrace_data *btrace; + + DEBUG ("parse_xml_btrace_etm_config_source_config_end"); + btrace = (struct btrace_data *) user_data; + + btrace->variant.etm.config.num_cpu + = btrace->variant.etm.config.etm_trace_params->size(); +} + +/* Parse a btrace etm "sink-config" xml record. */ + +static void +parse_xml_btrace_etm_config_sink_config (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_data *btrace; + //const char *sink_id; + DEBUG ("parse_xml_btrace_etm_config_sink_config"); + ULONGEST *formatted, *fsyncs, *hsyncs, *frame_aligned, *reset_on_4x_sync; + /*sink_id = + (const char *) xml_find_attribute (attributes, "sink_id")->value.get ();*/ + formatted + = (ULONGEST *) xml_find_attribute (attributes, "formatted")->value.get (); + fsyncs + = (ULONGEST *) xml_find_attribute (attributes, "fsyncs")->value.get (); + hsyncs + = (ULONGEST *) xml_find_attribute (attributes, "hsyncs")->value.get (); + frame_aligned + = (ULONGEST *) xml_find_attribute (attributes, "frame_aligned")->value.get (); + reset_on_4x_sync + = (ULONGEST *) xml_find_attribute (attributes, "reset_on_4x_sync")->value.get (); + + btrace = (struct btrace_data *) user_data; + + btrace->variant.etm.config.etm_decoder_params.formatted + = *formatted; + btrace->variant.etm.config.etm_decoder_params.fsyncs + = *fsyncs; + btrace->variant.etm.config.etm_decoder_params.hsyncs + = *hsyncs; + btrace->variant.etm.config.etm_decoder_params.frame_aligned + = *frame_aligned; + btrace->variant.etm.config.etm_decoder_params.reset_on_4x_sync + = *reset_on_4x_sync; +} + + +/* Parse a btrace etm "raw" xml record. */ + +static void +parse_xml_btrace_etm_raw (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, const char *body_text) +{ + struct btrace_data *btrace; + DEBUG ("parse_xml_btrace_etm_raw"); + btrace = (struct btrace_data *) user_data; + parse_xml_raw (parser, body_text, &btrace->variant.etm.data, + &btrace->variant.etm.size); +} + +/* Parse a btrace "etm" xml record. */ + +static void +parse_xml_btrace_etm (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_data *btrace; + DEBUG ("parse_xml_btrace_etm"); + btrace = (struct btrace_data *) user_data; + btrace->format = BTRACE_FORMAT_ETM; + btrace->variant.etm.data = NULL; + btrace->variant.etm.size = 0; +} + static const struct gdb_xml_attribute block_attributes[] = { { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, @@ -2759,6 +2991,92 @@ static const struct gdb_xml_element btrace_pt_children[] = { { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; +static const struct gdb_xml_attribute + btrace_etm_config_source_config_cpu_config_etmv3_config_attributes[] = { + { "reg_ctrl", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_trc_id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_ccer", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_idr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_attribute + btrace_etm_config_source_config_cpu_config_etmv4_config_attributes[] = { + { "reg_idr0", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_idr1", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_idr2", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_idr8", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_configr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reg_traceidr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_element + btrace_etm_config_source_config_cpu_etm_config_children[] = { + { "etmv3-config", + btrace_etm_config_source_config_cpu_config_etmv3_config_attributes, + NULL, GDB_XML_EF_OPTIONAL, + parse_xml_btrace_etm_config_source_config_cpu_etmv3_config, NULL }, + { "etmv4-config", + btrace_etm_config_source_config_cpu_config_etmv4_config_attributes, + NULL, GDB_XML_EF_OPTIONAL, + parse_xml_btrace_etm_config_source_config_cpu_etmv4_config, NULL }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_attribute + btrace_etm_config_source_config_etm_config_attributes[] = { + { "cpu_id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "arch_ver", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "core_prof", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "protocol", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_element + btrace_etm_config_source_config_children[] = { + { "cpu-etm-config", btrace_etm_config_source_config_etm_config_attributes, + btrace_etm_config_source_config_cpu_etm_config_children, + GDB_XML_EF_REPEATABLE, + parse_xml_btrace_etm_config_source_config_cpu_etm_config, NULL }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_attribute + btrace_etm_config_sink_config_attributes[] = { + { "sink_id", GDB_XML_AF_OPTIONAL, NULL, NULL }, + { "formatted", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "fsyncs", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "hsyncs", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "frame_aligned", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { "reset_on_4x_sync", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_attribute + btrace_etm_config_source_config_attributes[] = { + { "trace_id", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_element btrace_etm_config_children[] = { + { "source-config", btrace_etm_config_source_config_attributes, + btrace_etm_config_source_config_children, GDB_XML_EF_NONE, + parse_xml_btrace_etm_config_source_config, + parse_xml_btrace_etm_config_source_config_end }, + { "sink-config", btrace_etm_config_sink_config_attributes, NULL, + GDB_XML_EF_NONE, parse_xml_btrace_etm_config_sink_config, NULL }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_element btrace_etm_children[] = { + { "etm-config", NULL, btrace_etm_config_children, GDB_XML_EF_NONE, NULL, + NULL }, + { "raw", NULL, NULL, GDB_XML_EF_OPTIONAL, NULL, + parse_xml_btrace_etm_raw }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + static const struct gdb_xml_attribute btrace_attributes[] = { { "version", GDB_XML_AF_NONE, NULL, NULL }, { NULL, GDB_XML_AF_NONE, NULL, NULL } @@ -2767,8 +3085,10 @@ static const struct gdb_xml_attribute btrace_attributes[] = { static const struct gdb_xml_element btrace_children[] = { { "block", block_attributes, NULL, GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL }, - { "pt", NULL, btrace_pt_children, GDB_XML_EF_OPTIONAL, parse_xml_btrace_pt, - NULL }, + { "pt", NULL, btrace_pt_children, GDB_XML_EF_OPTIONAL, + parse_xml_btrace_pt, NULL }, + { "etm", NULL, btrace_etm_children, GDB_XML_EF_OPTIONAL, + parse_xml_btrace_etm, NULL }, { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; @@ -2849,6 +3169,32 @@ parse_xml_btrace_conf_pt (struct gdb_xml_parser *parser, conf->pt.size = (unsigned int) *(ULONGEST *) size->value.get (); } +/* Parse a btrace-conf "etm" xml record. */ + +static void +parse_xml_btrace_conf_etm (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + std::vector &attributes) +{ + struct btrace_config *conf; + struct gdb_xml_value *size; + struct gdb_xml_value *sink; + + DEBUG ("parse_xml_btrace_conf_etm"); + conf = (struct btrace_config *) user_data; + conf->format = BTRACE_FORMAT_ETM; + conf->etm.size = 0; + + size = xml_find_attribute (attributes, "size"); + if (size != NULL) + conf->etm.size = (unsigned int) *(ULONGEST *) size->value.get (); + + sink = xml_find_attribute (attributes, "sink"); + if (sink != NULL) + conf->etm.sink = (char*) sink->value.get (); +} + static const struct gdb_xml_attribute btrace_conf_pt_attributes[] = { { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, { NULL, GDB_XML_AF_NONE, NULL, NULL } @@ -2859,11 +3205,19 @@ static const struct gdb_xml_attribute btrace_conf_bts_attributes[] = { { NULL, GDB_XML_AF_NONE, NULL, NULL } }; +static const struct gdb_xml_attribute btrace_conf_etm_attributes[] = { + { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, + { "sink", GDB_XML_AF_OPTIONAL, NULL, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + static const struct gdb_xml_element btrace_conf_children[] = { { "bts", btrace_conf_bts_attributes, NULL, GDB_XML_EF_OPTIONAL, parse_xml_btrace_conf_bts, NULL }, { "pt", btrace_conf_pt_attributes, NULL, GDB_XML_EF_OPTIONAL, parse_xml_btrace_conf_pt, NULL }, + { "etm", btrace_conf_etm_attributes, NULL, GDB_XML_EF_OPTIONAL, + parse_xml_btrace_conf_etm, NULL }, { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; diff --git a/gdb/features/btrace-conf.dtd b/gdb/features/btrace-conf.dtd index 4b060bb408c..7334d035f34 100644 --- a/gdb/features/btrace-conf.dtd +++ b/gdb/features/btrace-conf.dtd @@ -4,11 +4,17 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> - - + + + + + diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd index 9bb930d7d3b..5c2bb6755ad 100644 --- a/gdb/features/btrace.dtd +++ b/gdb/features/btrace.dtd @@ -4,8 +4,8 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> - - + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/remote.c b/gdb/remote.c index 2c85bdcffbc..6e8b9bd8211 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -2167,6 +2167,15 @@ enum { /* Support TARGET_WAITKIND_NO_RESUMED. */ PACKET_no_resumed, + /* Support for the Qbtrace-etm packet. */ + PACKET_Qbtrace_etm, + + /* Support for the Qbtrace-conf:etm:size packet. */ + PACKET_Qbtrace_conf_etm_size, + + /* Support for the Qbtrace-conf:etm:sink packet. */ + PACKET_Qbtrace_conf_etm_sink, + PACKET_MAX }; @@ -5302,6 +5311,12 @@ static const struct protocol_feature remote_protocol_features[] = { { "vContSupported", PACKET_DISABLE, remote_supported_packet, PACKET_vContSupported }, { "QThreadEvents", PACKET_DISABLE, remote_supported_packet, PACKET_QThreadEvents }, { "no-resumed", PACKET_DISABLE, remote_supported_packet, PACKET_no_resumed }, + { "Qbtrace:etm", PACKET_DISABLE, remote_supported_packet, + PACKET_Qbtrace_etm }, + { "Qbtrace-conf:etm:size", PACKET_DISABLE, remote_supported_packet, + PACKET_Qbtrace_conf_etm_size }, + { "Qbtrace-conf:etm:sink", PACKET_DISABLE, remote_supported_packet, + PACKET_Qbtrace_conf_etm_sink }, }; static char *remote_support_xml; @@ -13882,6 +13897,28 @@ remote_target::btrace_sync_conf (const btrace_config *conf) rs->btrace_config.pt.size = conf->pt.size; } + + packet = &remote_protocol_packets[PACKET_Qbtrace_conf_etm_size]; + if (packet_config_support (packet) == PACKET_ENABLE + && conf->etm.size != rs->btrace_config.etm.size) + { + pos = buf; + pos += xsnprintf (pos, endbuf - pos, "%s=0x%x", packet->name, + conf->etm.size); + + putpkt (buf); + getpkt (&rs->buf, 0); + + if (packet_ok (buf, packet) == PACKET_ERROR) + { + if (buf[0] == 'E' && buf[1] == '.') + error (_("Failed to configure the trace buffer size: %s"), buf + 2); + else + error (_("Failed to configure the trace buffer size.")); + } + + rs->btrace_config.etm.size = conf->etm.size; + } } /* Read the current thread's btrace configuration from the target and @@ -13903,7 +13940,7 @@ remote_target::remote_btrace_maybe_reopen () { struct remote_state *rs = get_remote_state (); int btrace_target_pushed = 0; -#if !defined (HAVE_LIBIPT) +#if !defined (HAVE_LIBIPT) || !defined (HAVE_LIBOPENCSD_C_API) int warned = 0; #endif @@ -13938,6 +13975,20 @@ remote_target::remote_btrace_maybe_reopen () } #endif /* !defined (HAVE_LIBIPT) */ +#if !defined (HAVE_LIBOPENCSD_C_API) + if (rs->btrace_config.format == BTRACE_FORMAT_ETM) + { + if (!warned) + { + warned = 1; + warning (_("Target is recording using ARM CoreSight Processor Trace " + "but support was disabled at compile time.")); + } + + continue; + } +#endif /* !defined (HAVE_LIBOPENCSD_C_API) */ + /* Push target, once, but before anything else happens. This way our changes to the threads will be cleaned up by unpushing the target in case btrace_read_config () throws. */ @@ -13975,6 +14026,10 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf) case BTRACE_FORMAT_PT: packet = &remote_protocol_packets[PACKET_Qbtrace_pt]; break; + + case BTRACE_FORMAT_ETM: + packet = &remote_protocol_packets[PACKET_Qbtrace_etm]; + break; } if (packet == NULL || packet_config_support (packet) != PACKET_ENABLE) @@ -14883,6 +14938,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (&remote_protocol_packets[PACKET_no_resumed], "N stop reply", "no-resumed-stop-reply", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_etm], + "Qbtrace:etm", "enable-btrace-etm", 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_etm_size], + "Qbtrace-conf:etm:size", "btrace-conf-etm-size", 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_etm_sink], + "Qbtrace-conf:etm:sink", "btrace-conf-etm-sink", 0); + /* Assert that we've registered "set remote foo-packet" commands for all packet configs. */ { diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index bafdc7685c3..2c80dfbe079 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,16 @@ +2021-02-06 Zied Guermazi + + * configure.srv: add btrace for aarch64*-*-linux* and arm*-*-linux*. + * linux-low.c (linux_low_encode_etm_config): New. + * linux-low.c (linux_process_target::read_btrace): encode CoreSight + traces and relative decoding parameters. + * linux-low.c (linux_process_target::read_btrace_conf): encode + CoreSight configuration. + * server.cc (handle_btrace_enable_etm): New. + * server.cc (handle_btrace_general_set): add etm handling. + * server.cc (handle_btrace_conf_general_set): add etm handling. + * server.cc (supported_btrace_packets): add etm related packets. + 2021-02-01 Zied Guermazi * gdbserver/configure: Regenerated. diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 833ad27c4c4..5f900d80d66 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -54,12 +54,14 @@ case "${gdbserver_host}" in srv_tgtobj="$srv_tgtobj arch/aarch64.o" srv_tgtobj="$srv_tgtobj linux-aarch64-tdesc.o" srv_tgtobj="$srv_tgtobj nat/aarch64-sve-linux-ptrace.o" + srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj="${srv_tgtobj} $srv_linux_obj" srv_linux_regsets=yes srv_linux_thread_db=yes ipa_obj="linux-aarch64-ipa.o" ipa_obj="${ipa_obj} linux-aarch64-tdesc-ipa.o" ipa_obj="${ipa_obj} arch/aarch64-ipa.o" + srv_linux_btrace=yes ;; aarch64*-*-netbsd*) srv_regobj="" srv_tgtobj="netbsd-low.o netbsd-aarch64-low.o fork-child.o" @@ -82,6 +84,7 @@ case "${gdbserver_host}" in srv_tgtobj="$srv_tgtobj linux-arm-tdesc.o" srv_tgtobj="$srv_tgtobj linux-aarch32-low.o" srv_tgtobj="$srv_tgtobj linux-aarch32-tdesc.o" + srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj="${srv_tgtobj} arch/aarch32.o" srv_tgtobj="${srv_tgtobj} arch/arm.o" srv_tgtobj="${srv_tgtobj} arch/arm-linux.o" @@ -89,6 +92,7 @@ case "${gdbserver_host}" in srv_linux_usrregs=yes srv_linux_regsets=yes srv_linux_thread_db=yes + srv_linux_btrace=yes ;; i[34567]86-*-cygwin*) srv_regobj="" srv_tgtobj="x86-low.o nat/x86-dregs.o win32-low.o" diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index 0baac013129..ac5db7e8c03 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -6994,6 +6994,75 @@ linux_low_encode_pt_config (struct buffer *buffer, buffer_grow_str (buffer, "\n"); } +/* Encode ARM CoreSight Processor Trace configuration. */ + +static void +linux_low_encode_etm_config (struct buffer *buffer, + const struct btrace_data_etm_config *config) +{ + int architecture; + buffer_grow_str (buffer, "\n"); + buffer_grow_str (buffer, "\n"); + for (int i=0; i< config->num_cpu;i++) + { + if ((config->etm_trace_params->at(i).protocol == CS_ETM_PROTO_ETMV3) + ||(config->etm_trace_params->at(i).protocol == CS_ETM_PROTO_PTM)) + { + architecture = ARCHITECTURE_V7; + } + else if (config->etm_trace_params->at(i).protocol == CS_ETM_PROTO_ETMV4i) + { + architecture = ARCHITECTURE_V8; + } + else + { + architecture = ARCHITECTURE_UNKNOWN; + } + + buffer_xml_printf (buffer,"\n", + architecture, PROFILE_CORTEX_A, + i, config->etm_trace_params->at(i).protocol); + if (architecture == ARCHITECTURE_V7) + { + + buffer_xml_printf (buffer, + "\n", + config->etm_trace_params->at(i).etmv3.reg_idr, + config->etm_trace_params->at(i).etmv3.reg_ctrl, + config->etm_trace_params->at(i).etmv3.reg_ccer, + config->etm_trace_params->at(i).etmv3.reg_trc_id); + } + if (architecture == ARCHITECTURE_V8) + { + buffer_xml_printf (buffer, + "\n", + config->etm_trace_params->at(i).etmv4.reg_idr0, + config->etm_trace_params->at(i).etmv4.reg_idr1, + config->etm_trace_params->at(i).etmv4.reg_idr2, + config->etm_trace_params->at(i).etmv4.reg_idr8, + config->etm_trace_params->at(i).etmv4.reg_configr, + config->etm_trace_params->at(i).etmv4.reg_traceidr); + } + buffer_xml_printf (buffer,"\n"); + + } + buffer_grow_str (buffer,"\n"); + buffer_xml_printf (buffer, + "\n", + config->etm_decoder_params.formatted, + config->etm_decoder_params.fsyncs, + config->etm_decoder_params.hsyncs, + config->etm_decoder_params.frame_aligned, + config->etm_decoder_params.reset_on_4x_sync); + buffer_grow_str (buffer,"\n"); +} + /* Encode a raw buffer. */ static void @@ -7048,7 +7117,7 @@ linux_process_target::read_btrace (btrace_target_info *tinfo, case BTRACE_FORMAT_BTS: buffer_grow_str (buffer, "\n"); - buffer_grow_str (buffer, "\n"); + buffer_grow_str (buffer, "\n"); for (const btrace_block &block : *btrace.variant.bts.blocks) buffer_xml_printf (buffer, "\n", @@ -7059,7 +7128,7 @@ linux_process_target::read_btrace (btrace_target_info *tinfo, case BTRACE_FORMAT_PT: buffer_grow_str (buffer, "\n"); - buffer_grow_str (buffer, "\n"); + buffer_grow_str (buffer, "\n"); buffer_grow_str (buffer, "\n"); linux_low_encode_pt_config (buffer, &btrace.variant.pt.config); @@ -7071,6 +7140,20 @@ linux_process_target::read_btrace (btrace_target_info *tinfo, buffer_grow_str0 (buffer, "\n"); break; + case BTRACE_FORMAT_ETM: + buffer_grow_str (buffer, "\n"); + buffer_grow_str (buffer, "\n"); + buffer_grow_str (buffer, "\n"); + + linux_low_encode_etm_config (buffer, &btrace.variant.etm.config); + + linux_low_encode_raw (buffer, btrace.variant.etm.data, + btrace.variant.etm.size); + + buffer_grow_str (buffer, "\n"); + buffer_grow_str0 (buffer, "\n"); + break; + default: buffer_grow_str0 (buffer, "E.Unsupported Trace Format."); return -1; @@ -7088,7 +7171,7 @@ linux_process_target::read_btrace_conf (const btrace_target_info *tinfo, const struct btrace_config *conf; buffer_grow_str (buffer, "\n"); - buffer_grow_str (buffer, "\n"); + buffer_grow_str (buffer, "\n"); conf = linux_btrace_conf (tinfo); if (conf != NULL) @@ -7109,6 +7192,20 @@ linux_process_target::read_btrace_conf (const btrace_target_info *tinfo, buffer_xml_printf (buffer, " size=\"0x%x\"", conf->pt.size); buffer_xml_printf (buffer, "/>\n"); break; + + case BTRACE_FORMAT_ETM: + buffer_xml_printf (buffer, "etm.size); + if (conf->etm.sink !=NULL) + { + buffer_xml_printf (buffer, " sink=\"%s\"", conf->etm.sink); + } + else + { + buffer_xml_printf (buffer, " sink=\"default\""); + } + buffer_xml_printf (buffer, "/>\n"); + break; } } diff --git a/gdbserver/server.cc b/gdbserver/server.cc index a5497e93cee..d0c619d2178 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -424,6 +424,18 @@ handle_btrace_enable_pt (struct thread_info *thread) thread->btrace = target_enable_btrace (thread->id, ¤t_btrace_conf); } +/* Handle btrace enabling in ARM CoreSight Trace format. */ + +static void +handle_btrace_enable_etm (struct thread_info *thread) +{ + if (thread->btrace != NULL) + error (_("Btrace already enabled.")); + + current_btrace_conf.format = BTRACE_FORMAT_ETM; + thread->btrace = target_enable_btrace (thread->id, ¤t_btrace_conf); +} + /* Handle btrace disabling. */ static void @@ -473,10 +485,12 @@ handle_btrace_general_set (char *own_buf) handle_btrace_enable_bts (thread); else if (strcmp (op, "pt") == 0) handle_btrace_enable_pt (thread); + else if (strcmp (op, "etm") == 0) + handle_btrace_enable_etm (thread); else if (strcmp (op, "off") == 0) handle_btrace_disable (thread); else - error (_("Bad Qbtrace operation. Use bts, pt, or off.")); + error (_("Bad Qbtrace operation. Use bts, pt, etm, or off.")); write_ok (own_buf); } @@ -546,6 +560,21 @@ handle_btrace_conf_general_set (char *own_buf) current_btrace_conf.pt.size = (unsigned int) size; } + else if (strncmp (op, "etm:size=", strlen ("etm:size=")) == 0) + { + unsigned long size; + char *endp = NULL; + + errno = 0; + size = strtoul (op + strlen ("etm:size="), &endp, 16); + if (endp == NULL || *endp != 0 || errno != 0 || size > UINT_MAX) + { + strcpy (own_buf, "E.Bad size value."); + return -1; + } + + current_btrace_conf.etm.size = (unsigned int) size; + } else { strcpy (own_buf, "E.Bad Qbtrace configuration option."); @@ -2084,6 +2113,9 @@ supported_btrace_packets (char *buf) strcat (buf, ";Qbtrace-conf:bts:size+"); strcat (buf, ";Qbtrace:pt+"); strcat (buf, ";Qbtrace-conf:pt:size+"); + strcat (buf, ";Qbtrace:etm+"); + strcat (buf, ";Qbtrace-conf:etm:size+"); + strcat (buf, ";Qbtrace-conf:etm:sink+"); strcat (buf, ";Qbtrace:off+"); strcat (buf, ";qXfer:btrace:read+"); strcat (buf, ";qXfer:btrace-conf:read+"); -- 2.25.1