[v3,6/7] add support for coresight btrace via remote protocol

Message ID 20210331025234.518688-7-zied.guermazi@trande.de
State New
Headers show
Series
  • extend branch tracing to use ARM CoreSight traces
Related show

Commit Message

Zied Guermazi March 31, 2021, 2:52 a.m.
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

	* NEWS: list new remote packets for extending btrace
	to support using ARM CoreSight Traces.
	* 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.

gdb/doc/ChangeLog

	* gdb.texinfo (General Query Packets) Document extending GDB remote
	protocol packets to support using ARM CoreSight traces for btrace.

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                |  19 ++
 gdb/NEWS                     |  14 ++
 gdb/btrace.c                 | 371 ++++++++++++++++++++++++++++++++++-
 gdb/doc/gdb.texinfo          |  64 ++++++
 gdb/features/btrace-conf.dtd |  10 +-
 gdb/features/btrace.dtd      |  38 +++-
 gdb/remote.c                 |  66 ++++++-
 gdbserver/ChangeLog          |  12 ++
 gdbserver/configure.srv      |   4 +
 gdbserver/linux-low.cc       | 104 +++++++++-
 gdbserver/server.cc          |  34 +++-
 11 files changed, 724 insertions(+), 12 deletions(-)

-- 
2.25.1

Comments

Simon Marchi via Gdb-patches March 31, 2021, 6:33 a.m. | #1
> From: Zied Guermazi <zied.guermazi@trande.de>

> Date: Wed, 31 Mar 2021 04:52:33 +0200

> Cc: Zied Guermazi <zied.guermazi@trande.de>

> 

> gdb/ChangeLog

> 

> 	* NEWS: list new remote packets for extending btrace

> 	to support using ARM CoreSight Traces.

> 	* 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.

> 

> gdb/doc/ChangeLog

> 

> 	* gdb.texinfo (General Query Packets) Document extending GDB remote

> 	protocol packets to support using ARM CoreSight traces for btrace.

> 

> 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.


The documentation parts are okay, thanks.
Simon Marchi via Gdb-patches April 1, 2021, 12:45 p.m. | #2
On 3/30/21 11:52 PM, Zied Guermazi wrote:
> 

> 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

> 

> 	* NEWS: list new remote packets for extending btrace

> 	to support using ARM CoreSight Traces.

> 	* 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.


You should update the commit message to contain the fixed ChangeLog entries.

> 

> gdb/doc/ChangeLog

> 

> 	* gdb.texinfo (General Query Packets) Document extending GDB remote

> 	protocol packets to support using ARM CoreSight traces for btrace.

> 

> 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.


Same here.

> 

> ---

>   gdb/ChangeLog                |  19 ++

>   gdb/NEWS                     |  14 ++

>   gdb/btrace.c                 | 371 ++++++++++++++++++++++++++++++++++-

>   gdb/doc/gdb.texinfo          |  64 ++++++

>   gdb/features/btrace-conf.dtd |  10 +-

>   gdb/features/btrace.dtd      |  38 +++-

>   gdb/remote.c                 |  66 ++++++-

>   gdbserver/ChangeLog          |  12 ++

>   gdbserver/configure.srv      |   4 +

>   gdbserver/linux-low.cc       | 104 +++++++++-

>   gdbserver/server.cc          |  34 +++-

>   11 files changed, 724 insertions(+), 12 deletions(-)

> 

> diff --git a/gdb/ChangeLog b/gdb/ChangeLog

> index d4ed6fe0255..76b413c3857 100644

> --- a/gdb/ChangeLog

> +++ b/gdb/ChangeLog

> @@ -1,3 +1,22 @@

> +2021-02-25  Zied Guermazi  <zied.guermazi@trande.de>

> +

> +	* btrace.c (check_xml_btrace_version): add version 1.1

> +	(parse_xml_btrace_etm_config_source_config_cpu_etmv4_config): New.

> +	(parse_xml_btrace_etm_config_source_config_cpu_etmv3_config): New.

> +	(parse_xml_btrace_etm_config_source_config_cpu_etm_config): New.

> +	(parse_xml_btrace_etm_config_source_config): New.

> +	(dump_config): New.

> +	(parse_xml_btrace_etm_config_source_config_end): New.

> +	(parse_xml_btrace_etm_config_sink_config): New.

> +	(parse_xml_btrace_etm_raw): New.

> +	(parse_xml_btrace_etm): New.

> +	(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_target::enable_btrace): add coresight etm.

> +	(_initialize_remote): add etm related packets.

> +

>   2021-02-25  Zied Guermazi  <zied.guermazi@trande.de>

>   

>   	* infrun.c (set_step_over_info): add debug print.

> diff --git a/gdb/NEWS b/gdb/NEWS

> index 0dbd89eb360..0c31af6ed0b 100644

> --- a/gdb/NEWS

> +++ b/gdb/NEWS

> @@ -114,6 +114,20 @@ maintenance info sections

>   

>   ARM Symbian			arm*-*-symbianelf*

>   

> +* New remote packets

> +

> +Qbtrace:etm

> +  Enable ARM CoreSight ETM Trace-based branch tracing for the current

> +  process.  The remote stub reports support for this packet to GDB's


to -> through?

> +  qSupported query.

> +

> +Qbtrace-conf:etm:size

> +  Set the requested ring buffer size for branch tracing in

> +  ARM CoreSight ETM Trace format.

> +

> +Qbtrace-conf:etm:sink

> +  Set the trace sink for branch tracing in ARM CoreSight ETM Trace format.

> +

>   *** Changes in GDB 10

>   

>   * There are new feature names for ARC targets: "org.gnu.gdb.arc.core"

> diff --git a/gdb/btrace.c b/gdb/btrace.c

> index 1ab5a74f0b6..78feb71d243 100644

> --- a/gdb/btrace.c

> +++ b/gdb/btrace.c

> @@ -2616,7 +2616,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);

>   }

>   

> @@ -2751,6 +2751,250 @@ 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<gdb_xml_value> &attributes)

> +{

> +  struct btrace_data *btrace;

> +  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 ());

> +

> +  struct gdb_xml_value *reg_idr0;

> +  reg_idr0

> +    = xml_find_attribute (attributes, "reg_idr0");

> +

> +  struct gdb_xml_value *reg_idr1;

> +  reg_idr1

> +    = xml_find_attribute (attributes, "reg_idr1");

> +

> +  struct gdb_xml_value *reg_idr2;

> +  reg_idr2

> +    = xml_find_attribute (attributes, "reg_idr2");

> +

> +  struct gdb_xml_value *reg_idr8;

> +  reg_idr8

> +    = xml_find_attribute (attributes, "reg_idr8");

> +

> +  struct gdb_xml_value *reg_configr;

> +  reg_configr

> +    = xml_find_attribute (attributes, "reg_configr");

> +

> +  struct gdb_xml_value *reg_traceidr;

> +  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<gdb_xml_value> &attributes)

> +{

> +  struct btrace_data *btrace;

> +  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 ());

> +

> +  struct gdb_xml_value *reg_ctrl;

> +  reg_ctrl

> +    = xml_find_attribute (attributes, "reg_ctrl");

> +

> +  struct gdb_xml_value *reg_trc_id;

> +  reg_trc_id

> +    = xml_find_attribute (attributes, "reg_trc_id");

> +

> +  struct gdb_xml_value *reg_ccer;

> +  reg_ccer

> +    = xml_find_attribute (attributes, "reg_ccer");

> +

> +  struct gdb_xml_value *reg_idr;

> +  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<gdb_xml_value> &attributes)

> +{

> +  struct btrace_data *btrace;

> +  cs_etm_trace_params etm_trace_params;

> +

> +  DEBUG ("parse_xml_btrace_etm_config_source_config_cpu_etm_config");

> +

> +  btrace = (struct btrace_data *) user_data;

> +

> +  struct gdb_xml_value *arch_ver;

> +  arch_ver

> +    = xml_find_attribute (attributes, "arch_ver");

> +

> +  struct gdb_xml_value *core_prof;

> +  core_prof

> +    = xml_find_attribute (attributes, "core_prof");

> +

> +  struct gdb_xml_value *protocol;

> +  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<gdb_xml_value> &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<cs_etm_trace_params>;

> +}

> +

> +/* Get the number of cpus.  */

> +static void


Missing newline between comment and function declaration.

> +parse_xml_btrace_etm_config_source_config_end (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_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<gdb_xml_value> &attributes)

> +{

> +  struct btrace_data *btrace;

> +

> +  DEBUG ("parse_xml_btrace_etm_config_sink_config");

> +

> +  btrace = (struct btrace_data *) user_data;

> +

> +  struct gdb_xml_value *formatted;

> +  formatted = xml_find_attribute (attributes, "formatted");

> +

> +  struct gdb_xml_value *fsyncs;

> +  fsyncs = xml_find_attribute (attributes, "fsyncs");

> +

> +  struct gdb_xml_value *hsyncs;

> +  hsyncs = xml_find_attribute (attributes, "hsyncs");

> +

> +  struct gdb_xml_value *frame_aligned;

> +  frame_aligned = xml_find_attribute (attributes, "frame_aligned");

> +

> +  struct gdb_xml_value *reset_on_4x_sync;

> +  reset_on_4x_sync = xml_find_attribute (attributes, "reset_on_4x_sync");

> +

> +  btrace->variant.etm.config.etm_decoder_params.formatted

> +    = (uint8_t) *(ULONGEST *) formatted->value.get ();

> +  btrace->variant.etm.config.etm_decoder_params.fsyncs

> +    = (uint8_t) *(ULONGEST *) fsyncs->value.get ();

> +  btrace->variant.etm.config.etm_decoder_params.hsyncs

> +    = (uint8_t) *(ULONGEST *) hsyncs->value.get ();

> +  btrace->variant.etm.config.etm_decoder_params.frame_aligned

> +    = (uint8_t) *(ULONGEST *) frame_aligned->value.get ();

> +  btrace->variant.etm.config.etm_decoder_params.reset_on_4x_sync

> +    = (uint8_t) *(ULONGEST *) reset_on_4x_sync->value.get ();

> +}

> +

> +

> +/* 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<gdb_xml_value> &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 },

> @@ -2778,6 +3022,91 @@ 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[] = {

> +  { "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 }

> @@ -2786,8 +3115,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 }

>   };

>   

> @@ -2868,6 +3199,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<gdb_xml_value> &attributes)

> +{

> +  struct btrace_config *conf;

> +  struct gdb_xml_value *size;

> +

> +  DEBUG ("parse_xml_btrace_conf_etm");

> +  conf = (struct btrace_config *) user_data;


struct btrace_config *conf = (struct btrace_config *) user_data;

> +  conf->format = BTRACE_FORMAT_ETM;

> +  conf->etm.size = 0;

> +

> +  size = xml_find_attribute (attributes, "size");


struct gdb_xml_value *size = xml_find_attribute (attributes, "size");

> +  if (size != NULL)

> +    conf->etm.size = (unsigned int) *(ULONGEST *) size->value.get ();

> +

> +  struct gdb_xml_value *sink;

> +  sink = xml_find_attribute (attributes, "sink");

> +  if (sink != NULL)


Please use nullptr for all NULL pointer values. There are multiple cases 
of this throughout the code. GDB now uses C++ and NULL is no longer 
acceptable.

> +    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 }

> @@ -2878,11 +3235,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/doc/gdb.texinfo b/gdb/doc/gdb.texinfo

> index bd5b2c91869..709b4e4f09d 100644

> --- a/gdb/doc/gdb.texinfo

> +++ b/gdb/doc/gdb.texinfo

> @@ -41708,6 +41708,21 @@ These are the currently defined stub features and their properties:

>   @tab @samp{-}

>   @tab No

>   

> +@item @samp{Qbtrace:etm}

> +@tab Yes

> +@tab @samp{-}

> +@tab Yes

> +

> +@item @samp{Qbtrace-conf:etm:size}

> +@tab Yes

> +@tab @samp{-}

> +@tab Yes

> +

> +

> +@item @samp{Qbtrace-conf:etm:sink}

> +@tab Yes

> +@tab @samp{-}

> +@tab Yes

>   @end multitable

>   

>   These are the currently defined stub features, in more detail:

> @@ -41884,9 +41899,11 @@ The remote stub understands the @samp{Qbtrace:off} packet.

>   

>   @item Qbtrace:bts

>   The remote stub understands the @samp{Qbtrace:bts} packet.

> +(@pxref{bts}).

>   

>   @item Qbtrace:pt

>   The remote stub understands the @samp{Qbtrace:pt} packet.

> +(@pxref{pt}).

>   

>   @item Qbtrace-conf:bts:size

>   The remote stub understands the @samp{Qbtrace-conf:bts:size} packet.

> @@ -41922,6 +41939,16 @@ The remote stub understands the @samp{QThreadEvents} packet.

>   @item no-resumed

>   The remote stub reports the @samp{N} stop reply.

>   

> +@item Qbtrace:etm

> +The remote stub understands the @samp{Qbtrace:etm} packet.

> +(@pxref{etm}).

> +

> +@item Qbtrace-conf:etm:size

> +The remote stub understands the @samp{Qbtrace-conf:etm:size} packet.

> +

> +@item Qbtrace-conf:etm:sink

> +The remote stub understands the @samp{Qbtrace-conf:etm:sink} packet.

> +

>   @end table

>   

>   @item qSymbol::

> @@ -42328,6 +42355,7 @@ A badly formed request or an error was encountered.

>   @end table

>   

>   @item Qbtrace:bts

> +@anchor{bts}

>   Enable branch tracing for the current thread using Branch Trace Store.

>   

>   Reply:

> @@ -42339,6 +42367,7 @@ A badly formed request or an error was encountered.

>   @end table

>   

>   @item Qbtrace:pt

> +@anchor{pt}

>   Enable branch tracing for the current thread using Intel Processor Trace.

>   

>   Reply:

> @@ -42384,6 +42413,41 @@ The ring buffer size has been set.

>   A badly formed request or an error was encountered.

>   @end table

>   

> +@item Qbtrace:etm

> +@anchor{etm}

> +Enable branch tracing for the current thread using ARM CoreSight ETM Trace.

> +

> +Reply:

> +@table @samp

> +@item OK

> +Branch tracing has been enabled.

> +@item E.errtext

> +A badly formed request or an error was encountered.

> +@end table

> +

> +@item Qbtrace-conf:etm:size=@var{value}

> +Set the requested ring buffer size for new threads that use the

> +btrace recording method in etm format.

> +

> +Reply:

> +@table @samp

> +@item OK

> +The ring buffer size has been set.

> +@item E.errtext

> +A badly formed request or an error was encountered.

> +@end table

> +

> +@item Qbtrace-conf:etm:sink=@var{value}

> +Set the requested trace sink for new threads that use the

> +btrace recording method in etm format.

> +

> +Reply:

> +@table @samp

> +@item OK

> +The ring buffer size has been set.

> +@item E.errtext

> +A badly formed request or an error was encountered.

> +@end table

>   @end table

>   

>   @node Architecture-Specific Protocol Details

> 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.  -->

>   

> -<!ELEMENT btrace-conf	(bts?, pt?)>

> -<!ATTLIST btrace-conf	version	CDATA	#FIXED "1.0">

> +<!ELEMENT btrace-conf	(bts?, pt?, etm?)>

> +<!ATTLIST btrace-conf	version	(1.0|1.1) #REQUIRED>

>   

>   <!ELEMENT bts	EMPTY>

>   <!ATTLIST bts	size	CDATA	#IMPLIED>

>   

>   <!ELEMENT pt	EMPTY>

>   <!ATTLIST pt	size	CDATA	#IMPLIED>

> +

> +<!ELEMENT etm	EMPTY>

> +<!ATTLIST etm   size    CDATA   #IMPLIED

> +                sink	CDATA   #IMPLIED

> +                filter  CDATA   #IMPLIED

> +                config  CDATA   #IMPLIED>

> diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd

> index 9bb930d7d3b..001b77f35d0 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.  -->

>   

> -<!ELEMENT btrace  (block* | pt)>

> -<!ATTLIST btrace  version CDATA   #FIXED "1.0">

> +<!ELEMENT btrace  (block* | pt | etm)>

> +<!ATTLIST btrace  version (1.0|1.1) #REQUIRED>

>   

>   <!ELEMENT block        EMPTY>

>   <!ATTLIST block        begin  CDATA   #REQUIRED

> @@ -21,4 +21,38 @@

>                 model    CDATA #REQUIRED

>                 stepping CDATA #REQUIRED>

>   

> +<!ELEMENT etm (etm-config?, raw?)>

> +

> +<!ELEMENT etm-config (source-config, sink-config)>

> +

> +<!ELEMENT source-config   (cpu-etm-config+)>

> +<!ATTLIST source-config    trace_id         CDATA #IMPLIED>

> +

> +<!ELEMENT cpu-etm-config  (etmv3-config|etmv4-config)>

> +<!ATTLIST cpu-etm-config   cpu_id           CDATA #REQUIRED

> +                           arch_ver         CDATA #REQUIRED

> +                           core_prof        CDATA #REQUIRED

> +                           protocol         CDATA #REQUIRED>

> +

> +<!ELEMENT etmv3-config     EMPTY>

> +<!ATTLIST etmv3-config     reg_ctrl         CDATA #REQUIRED

> +                           reg_trc_id       CDATA #REQUIRED

> +                           reg_ccer         CDATA #REQUIRED

> +                           reg_idr          CDATA #REQUIRED>

> +

> +<!ELEMENT etmv4-config     EMPTY>

> +<!ATTLIST etmv4-config     reg_idr0         CDATA #REQUIRED

> +                           reg_idr1         CDATA #REQUIRED

> +                           reg_idr2         CDATA #REQUIRED

> +                           reg_idr8         CDATA #REQUIRED

> +                           reg_configr      CDATA #REQUIRED

> +                           reg_traceidr     CDATA #REQUIRED>

> +

> +<!ELEMENT sink-config      EMPTY>

> +<!ATTLIST sink-config      formatted         CDATA #REQUIRED

> +                           fsyncs            CDATA #REQUIRED

> +                           hsyncs            CDATA #REQUIRED

> +                           frame_aligned     CDATA #REQUIRED

> +                           reset_on_4x_sync  CDATA #REQUIRED>

> +

>   <!ELEMENT raw (#PCDATA)>

> diff --git a/gdb/remote.c b/gdb/remote.c

> index 2c85bdcffbc..e6f0aeceb11 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..8e4eebf3ac8 100644

> --- a/gdbserver/ChangeLog

> +++ b/gdbserver/ChangeLog

> @@ -1,3 +1,15 @@

> +2021-02-06  Zied Guermazi  <zied.guermazi@trande.de>

> +

> +	* configure.srv: add btrace for aarch64*-*-linux* and arm*-*-linux*.

> +	* linux-low.cc (linux_low_encode_etm_config): New.

> +	(linux_process_target::read_btrace): encode CoreSight

> +	traces and relative decoding parameters.

> +	(linux_process_target::read_btrace_conf): encode CoreSight config.

> +	* server.cc (handle_btrace_enable_etm): New.

> +	(handle_btrace_general_set): add etm handling.

> +	(handle_btrace_conf_general_set): add etm handling.

> +	(supported_btrace_packets): add etm related packets.

> +

>   2021-02-01  Zied Guermazi  <zied.guermazi@trande.de>

>   

>   	* 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..b70e9648996 100644

> --- a/gdbserver/linux-low.cc

> +++ b/gdbserver/linux-low.cc

> @@ -51,6 +51,9 @@

>   #include "gdbsupport/environ.h"

>   #include "gdbsupport/gdb-sigmask.h"

>   #include "gdbsupport/scoped_restore.h"

> +#if defined (HAVE_LIBOPENCSD_C_API)

> +#  include <opencsd/ocsd_if_types.h>

> +#endif

>   #ifndef ELFMAG0

>   /* Don't include <linux/elf.h> here.  If it got included by gdb_proc_service.h

>      then ELFMAG0 will have been defined.  If it didn't get included by

> @@ -6994,6 +6997,73 @@ linux_low_encode_pt_config (struct buffer *buffer,

>     buffer_grow_str (buffer, "</pt-config>\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, "<etm-config>\n");

> +  buffer_grow_str (buffer, "<source-config>\n");

> +  for (int i=0; i< config->num_cpu;i++)

> +  {

> +    if ((config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_ETMV3)

> +	||(config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_PTM))

> +      {

> +	architecture = ARCH_V7;

> +      }

> +    else if (config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_ETMV4I)

> +      {

> +	architecture = ARCH_V8;

> +      }

> +    else

> +      {

> +	architecture = ARCH_UNKNOWN;

> +      }

> +

> +    buffer_xml_printf (buffer,"<cpu-etm-config arch_ver=\"0x%x\" "

> +	"core_prof=\"0x%x\" cpu_id=\"0x%x\" protocol=\"0x%x\">\n",

> +			  architecture, profile_CortexA,

> +			  i, config->etm_trace_params->at (i).protocol);

> +    if (architecture == ARCH_V7)

> +    {

> +      buffer_xml_printf (buffer,

> +	"<etmv3-config reg_idr=\"0x%x\" reg_ctrl=\"0x%x\" "

> +	"reg_ccer=\"0x%x\" reg_trc_id=\"0x%x\"/>\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 == ARCH_V8)

> +    {

> +      buffer_xml_printf (buffer,

> +	"<etmv4-config reg_idr0=\"0x%x\" reg_idr1=\"0x%x\" "

> +	"reg_idr2=\"0x%x\" reg_idr8=\"0x%x\" "

> +			  "reg_configr=\"0x%x\" reg_traceidr=\"0x%x\"/>\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,"</cpu-etm-config>\n");

> +  }

> +  buffer_grow_str (buffer,"</source-config>\n");

> +  buffer_xml_printf (buffer,

> +    "<sink-config  formatted=\"0x%x\" "

> +		"fsyncs=\"0x%x\" hsyncs=\"0x%x\" "

> +		"frame_aligned=\"0x%x\" reset_on_4x_sync=\"0x%x\"/>\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,"</etm-config>\n");

> +}

> +

>   /* Encode a raw buffer.  */

>   

>   static void

> @@ -7048,7 +7118,7 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,

>   

>       case BTRACE_FORMAT_BTS:

>         buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");

> -      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");

> +      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");


If we're changing the format version to 1.1, what if we have a GDB that 
only knows about format 1.0 and connects to a gdbserver that serves 
format 1.1? Is there some backward compatibility to be supported here?

>   

>         for (const btrace_block &block : *btrace.variant.bts.blocks)

>   	buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",

> @@ -7059,7 +7129,7 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,

>   

>       case BTRACE_FORMAT_PT:

>         buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");

> -      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");

> +      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");

>         buffer_grow_str (buffer, "<pt>\n");

>   

>         linux_low_encode_pt_config (buffer, &btrace.variant.pt.config);

> @@ -7071,6 +7141,20 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,

>         buffer_grow_str0 (buffer, "</btrace>\n");

>         break;

>   

> +    case BTRACE_FORMAT_ETM:

> +      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");

> +      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");

> +      buffer_grow_str (buffer, "<etm>\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, "</etm>\n");

> +      buffer_grow_str0 (buffer, "</btrace>\n");

> +      break;

> +

>       default:

>         buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");

>         return -1;

> @@ -7088,7 +7172,7 @@ linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,

>     const struct btrace_config *conf;

>   

>     buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");

> -  buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");

> +  buffer_grow_str (buffer, "<btrace-conf version=\"1.1\">\n");

>   

>     conf = linux_btrace_conf (tinfo);

>     if (conf != NULL)

> @@ -7109,6 +7193,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");

> +	  buffer_xml_printf (buffer, " size=\"0x%x\"", conf->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..d270cf7d370 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, &current_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."));


Is this something we should merely warn and not error? What happens if 
we tell gdbserver to enable btrace again?

Doesn't GDB know that btrace is already running before sending the packet?

> +

> +  current_btrace_conf.format = BTRACE_FORMAT_ETM;

> +  thread->btrace = target_enable_btrace (thread->id, &current_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+");

>
Zied Guermazi April 1, 2021, 10:58 p.m. | #3
hi Luis

thanks for your review comments. Here is the status of the updates. The 
changes will be published in next version of the patch set.

/Zied

On 01.04.21 14:45, Luis Machado wrote:
> On 3/30/21 11:52 PM, Zied Guermazi wrote:

>>

>> 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

>>

>>     * NEWS: list new remote packets for extending btrace

>>     to support using ARM CoreSight Traces.

>>     * 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.

>

> You should update the commit message to contain the fixed ChangeLog 

> entries.

[Zied] removed duplicated filenames.
>

>>

>> gdb/doc/ChangeLog

>>

>>     * gdb.texinfo (General Query Packets) Document extending GDB remote

>>     protocol packets to support using ARM CoreSight traces for btrace.

>>

>> 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.

>

> Same here.

[Zied] removed duplicated filenames.
>

>>

>> ---

>>   gdb/ChangeLog                |  19 ++

>>   gdb/NEWS                     |  14 ++

>>   gdb/btrace.c                 | 371 ++++++++++++++++++++++++++++++++++-

>>   gdb/doc/gdb.texinfo          |  64 ++++++

>>   gdb/features/btrace-conf.dtd |  10 +-

>>   gdb/features/btrace.dtd      |  38 +++-

>>   gdb/remote.c                 |  66 ++++++-

>>   gdbserver/ChangeLog          |  12 ++

>>   gdbserver/configure.srv      |   4 +

>>   gdbserver/linux-low.cc       | 104 +++++++++-

>>   gdbserver/server.cc          |  34 +++-

>>   11 files changed, 724 insertions(+), 12 deletions(-)

>>

>> diff --git a/gdb/ChangeLog b/gdb/ChangeLog

>> index d4ed6fe0255..76b413c3857 100644

>> --- a/gdb/ChangeLog

>> +++ b/gdb/ChangeLog

>> @@ -1,3 +1,22 @@

>> +2021-02-25  Zied Guermazi  <zied.guermazi@trande.de>

>> +

>> +    * btrace.c (check_xml_btrace_version): add version 1.1

>> + (parse_xml_btrace_etm_config_source_config_cpu_etmv4_config): New.

>> + (parse_xml_btrace_etm_config_source_config_cpu_etmv3_config): New.

>> +    (parse_xml_btrace_etm_config_source_config_cpu_etm_config): New.

>> +    (parse_xml_btrace_etm_config_source_config): New.

>> +    (dump_config): New.

>> +    (parse_xml_btrace_etm_config_source_config_end): New.

>> +    (parse_xml_btrace_etm_config_sink_config): New.

>> +    (parse_xml_btrace_etm_raw): New.

>> +    (parse_xml_btrace_etm): New.

>> +    (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_target::enable_btrace): add coresight etm.

>> +    (_initialize_remote): add etm related packets.

>> +

>>   2021-02-25  Zied Guermazi  <zied.guermazi@trande.de>

>>         * infrun.c (set_step_over_info): add debug print.

>> diff --git a/gdb/NEWS b/gdb/NEWS

>> index 0dbd89eb360..0c31af6ed0b 100644

>> --- a/gdb/NEWS

>> +++ b/gdb/NEWS

>> @@ -114,6 +114,20 @@ maintenance info sections

>>     ARM Symbian            arm*-*-symbianelf*

>>   +* New remote packets

>> +

>> +Qbtrace:etm

>> +  Enable ARM CoreSight ETM Trace-based branch tracing for the current

>> +  process.  The remote stub reports support for this packet to GDB's

>

> to -> through?

[Zied] I agree it is wired. the same sentence style is used for similar 
packets. it is to be read as "the stub is reporting to the query" and 
not "the stub is reporting to GDB through the query"
>

>> +  qSupported query.

>> +

>> +Qbtrace-conf:etm:size

>> +  Set the requested ring buffer size for branch tracing in

>> +  ARM CoreSight ETM Trace format.

>> +

>> +Qbtrace-conf:etm:sink

>> +  Set the trace sink for branch tracing in ARM CoreSight ETM Trace 

>> format.

>> +

>>   *** Changes in GDB 10

>>     * There are new feature names for ARC targets: 

>> "org.gnu.gdb.arc.core"

>> diff --git a/gdb/btrace.c b/gdb/btrace.c

>> index 1ab5a74f0b6..78feb71d243 100644

>> --- a/gdb/btrace.c

>> +++ b/gdb/btrace.c

>> @@ -2616,7 +2616,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);

>>   }

>>   @@ -2751,6 +2751,250 @@ 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<gdb_xml_value> &attributes)

>> +{

>> +  struct btrace_data *btrace;

>> +  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 ());

>> +

>> +  struct gdb_xml_value *reg_idr0;

>> +  reg_idr0

>> +    = xml_find_attribute (attributes, "reg_idr0");

>> +

>> +  struct gdb_xml_value *reg_idr1;

>> +  reg_idr1

>> +    = xml_find_attribute (attributes, "reg_idr1");

>> +

>> +  struct gdb_xml_value *reg_idr2;

>> +  reg_idr2

>> +    = xml_find_attribute (attributes, "reg_idr2");

>> +

>> +  struct gdb_xml_value *reg_idr8;

>> +  reg_idr8

>> +    = xml_find_attribute (attributes, "reg_idr8");

>> +

>> +  struct gdb_xml_value *reg_configr;

>> +  reg_configr

>> +    = xml_find_attribute (attributes, "reg_configr");

>> +

>> +  struct gdb_xml_value *reg_traceidr;

>> +  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<gdb_xml_value> &attributes)

>> +{

>> +  struct btrace_data *btrace;

>> +  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 ());

>> +

>> +  struct gdb_xml_value *reg_ctrl;

>> +  reg_ctrl

>> +    = xml_find_attribute (attributes, "reg_ctrl");

>> +

>> +  struct gdb_xml_value *reg_trc_id;

>> +  reg_trc_id

>> +    = xml_find_attribute (attributes, "reg_trc_id");

>> +

>> +  struct gdb_xml_value *reg_ccer;

>> +  reg_ccer

>> +    = xml_find_attribute (attributes, "reg_ccer");

>> +

>> +  struct gdb_xml_value *reg_idr;

>> +  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<gdb_xml_value> &attributes)

>> +{

>> +  struct btrace_data *btrace;

>> +  cs_etm_trace_params etm_trace_params;

>> +

>> +  DEBUG ("parse_xml_btrace_etm_config_source_config_cpu_etm_config");

>> +

>> +  btrace = (struct btrace_data *) user_data;

>> +

>> +  struct gdb_xml_value *arch_ver;

>> +  arch_ver

>> +    = xml_find_attribute (attributes, "arch_ver");

>> +

>> +  struct gdb_xml_value *core_prof;

>> +  core_prof

>> +    = xml_find_attribute (attributes, "core_prof");

>> +

>> +  struct gdb_xml_value *protocol;

>> +  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<gdb_xml_value> &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<cs_etm_trace_params>;

>> +}

>> +

>> +/* Get the number of cpus.  */

>> +static void

>

> Missing newline between comment and function declaration.

[Zied] fixed
>

>> +parse_xml_btrace_etm_config_source_config_end (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_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<gdb_xml_value> &attributes)

>> +{

>> +  struct btrace_data *btrace;

>> +

>> +  DEBUG ("parse_xml_btrace_etm_config_sink_config");

>> +

>> +  btrace = (struct btrace_data *) user_data;

>> +

>> +  struct gdb_xml_value *formatted;

>> +  formatted = xml_find_attribute (attributes, "formatted");

>> +

>> +  struct gdb_xml_value *fsyncs;

>> +  fsyncs = xml_find_attribute (attributes, "fsyncs");

>> +

>> +  struct gdb_xml_value *hsyncs;

>> +  hsyncs = xml_find_attribute (attributes, "hsyncs");

>> +

>> +  struct gdb_xml_value *frame_aligned;

>> +  frame_aligned = xml_find_attribute (attributes, "frame_aligned");

>> +

>> +  struct gdb_xml_value *reset_on_4x_sync;

>> +  reset_on_4x_sync = xml_find_attribute (attributes, 

>> "reset_on_4x_sync");

>> +

>> +  btrace->variant.etm.config.etm_decoder_params.formatted

>> +    = (uint8_t) *(ULONGEST *) formatted->value.get ();

>> +  btrace->variant.etm.config.etm_decoder_params.fsyncs

>> +    = (uint8_t) *(ULONGEST *) fsyncs->value.get ();

>> +  btrace->variant.etm.config.etm_decoder_params.hsyncs

>> +    = (uint8_t) *(ULONGEST *) hsyncs->value.get ();

>> + btrace->variant.etm.config.etm_decoder_params.frame_aligned

>> +    = (uint8_t) *(ULONGEST *) frame_aligned->value.get ();

>> + btrace->variant.etm.config.etm_decoder_params.reset_on_4x_sync

>> +    = (uint8_t) *(ULONGEST *) reset_on_4x_sync->value.get ();

>> +}

>> +

>> +

>> +/* 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<gdb_xml_value> &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 },

>> @@ -2778,6 +3022,91 @@ 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[] = {

>> +  { "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 }

>> @@ -2786,8 +3115,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 }

>>   };

>>   @@ -2868,6 +3199,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<gdb_xml_value> &attributes)

>> +{

>> +  struct btrace_config *conf;

>> +  struct gdb_xml_value *size;

>> +

>> +  DEBUG ("parse_xml_btrace_conf_etm");

>> +  conf = (struct btrace_config *) user_data;

>

> struct btrace_config *conf = (struct btrace_config *) user_data;

[Zied] done
>

>> +  conf->format = BTRACE_FORMAT_ETM;

>> +  conf->etm.size = 0;

>> +

>> +  size = xml_find_attribute (attributes, "size");

>

> struct gdb_xml_value *size = xml_find_attribute (attributes, "size");

[Zied] done
>

>> +  if (size != NULL)

>> +    conf->etm.size = (unsigned int) *(ULONGEST *) size->value.get ();

>> +

>> +  struct gdb_xml_value *sink;

>> +  sink = xml_find_attribute (attributes, "sink");

>> +  if (sink != NULL)

>

> Please use nullptr for all NULL pointer values. There are multiple 

> cases of this throughout the code. GDB now uses C++ and NULL is no 

> longer acceptable.

[Zied] done
>

>> +    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 }

>> @@ -2878,11 +3235,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/doc/gdb.texinfo b/gdb/doc/gdb.texinfo

>> index bd5b2c91869..709b4e4f09d 100644

>> --- a/gdb/doc/gdb.texinfo

>> +++ b/gdb/doc/gdb.texinfo

>> @@ -41708,6 +41708,21 @@ These are the currently defined stub 

>> features and their properties:

>>   @tab @samp{-}

>>   @tab No

>>   +@item @samp{Qbtrace:etm}

>> +@tab Yes

>> +@tab @samp{-}

>> +@tab Yes

>> +

>> +@item @samp{Qbtrace-conf:etm:size}

>> +@tab Yes

>> +@tab @samp{-}

>> +@tab Yes

>> +

>> +

>> +@item @samp{Qbtrace-conf:etm:sink}

>> +@tab Yes

>> +@tab @samp{-}

>> +@tab Yes

>>   @end multitable

>>     These are the currently defined stub features, in more detail:

>> @@ -41884,9 +41899,11 @@ The remote stub understands the 

>> @samp{Qbtrace:off} packet.

>>     @item Qbtrace:bts

>>   The remote stub understands the @samp{Qbtrace:bts} packet.

>> +(@pxref{bts}).

>>     @item Qbtrace:pt

>>   The remote stub understands the @samp{Qbtrace:pt} packet.

>> +(@pxref{pt}).

>>     @item Qbtrace-conf:bts:size

>>   The remote stub understands the @samp{Qbtrace-conf:bts:size} packet.

>> @@ -41922,6 +41939,16 @@ The remote stub understands the 

>> @samp{QThreadEvents} packet.

>>   @item no-resumed

>>   The remote stub reports the @samp{N} stop reply.

>>   +@item Qbtrace:etm

>> +The remote stub understands the @samp{Qbtrace:etm} packet.

>> +(@pxref{etm}).

>> +

>> +@item Qbtrace-conf:etm:size

>> +The remote stub understands the @samp{Qbtrace-conf:etm:size} packet.

>> +

>> +@item Qbtrace-conf:etm:sink

>> +The remote stub understands the @samp{Qbtrace-conf:etm:sink} packet.

>> +

>>   @end table

>>     @item qSymbol::

>> @@ -42328,6 +42355,7 @@ A badly formed request or an error was 

>> encountered.

>>   @end table

>>     @item Qbtrace:bts

>> +@anchor{bts}

>>   Enable branch tracing for the current thread using Branch Trace Store.

>>     Reply:

>> @@ -42339,6 +42367,7 @@ A badly formed request or an error was 

>> encountered.

>>   @end table

>>     @item Qbtrace:pt

>> +@anchor{pt}

>>   Enable branch tracing for the current thread using Intel Processor 

>> Trace.

>>     Reply:

>> @@ -42384,6 +42413,41 @@ The ring buffer size has been set.

>>   A badly formed request or an error was encountered.

>>   @end table

>>   +@item Qbtrace:etm

>> +@anchor{etm}

>> +Enable branch tracing for the current thread using ARM CoreSight ETM 

>> Trace.

>> +

>> +Reply:

>> +@table @samp

>> +@item OK

>> +Branch tracing has been enabled.

>> +@item E.errtext

>> +A badly formed request or an error was encountered.

>> +@end table

>> +

>> +@item Qbtrace-conf:etm:size=@var{value}

>> +Set the requested ring buffer size for new threads that use the

>> +btrace recording method in etm format.

>> +

>> +Reply:

>> +@table @samp

>> +@item OK

>> +The ring buffer size has been set.

>> +@item E.errtext

>> +A badly formed request or an error was encountered.

>> +@end table

>> +

>> +@item Qbtrace-conf:etm:sink=@var{value}

>> +Set the requested trace sink for new threads that use the

>> +btrace recording method in etm format.

>> +

>> +Reply:

>> +@table @samp

>> +@item OK

>> +The ring buffer size has been set.

>> +@item E.errtext

>> +A badly formed request or an error was encountered.

>> +@end table

>>   @end table

>>     @node Architecture-Specific Protocol Details

>> 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.  -->

>>   -<!ELEMENT btrace-conf    (bts?, pt?)>

>> -<!ATTLIST btrace-conf    version    CDATA    #FIXED "1.0">

>> +<!ELEMENT btrace-conf    (bts?, pt?, etm?)>

>> +<!ATTLIST btrace-conf    version    (1.0|1.1) #REQUIRED>

>>     <!ELEMENT bts    EMPTY>

>>   <!ATTLIST bts    size    CDATA    #IMPLIED>

>>     <!ELEMENT pt    EMPTY>

>>   <!ATTLIST pt    size    CDATA    #IMPLIED>

>> +

>> +<!ELEMENT etm    EMPTY>

>> +<!ATTLIST etm   size    CDATA   #IMPLIED

>> +                sink    CDATA   #IMPLIED

>> +                filter  CDATA   #IMPLIED

>> +                config  CDATA   #IMPLIED>

>> diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd

>> index 9bb930d7d3b..001b77f35d0 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.  -->

>>   -<!ELEMENT btrace  (block* | pt)>

>> -<!ATTLIST btrace  version CDATA   #FIXED "1.0">

>> +<!ELEMENT btrace  (block* | pt | etm)>

>> +<!ATTLIST btrace  version (1.0|1.1) #REQUIRED>

>>     <!ELEMENT block        EMPTY>

>>   <!ATTLIST block        begin  CDATA   #REQUIRED

>> @@ -21,4 +21,38 @@

>>                 model    CDATA #REQUIRED

>>                 stepping CDATA #REQUIRED>

>>   +<!ELEMENT etm (etm-config?, raw?)>

>> +

>> +<!ELEMENT etm-config (source-config, sink-config)>

>> +

>> +<!ELEMENT source-config   (cpu-etm-config+)>

>> +<!ATTLIST source-config    trace_id         CDATA #IMPLIED>

>> +

>> +<!ELEMENT cpu-etm-config  (etmv3-config|etmv4-config)>

>> +<!ATTLIST cpu-etm-config   cpu_id           CDATA #REQUIRED

>> +                           arch_ver         CDATA #REQUIRED

>> +                           core_prof        CDATA #REQUIRED

>> +                           protocol         CDATA #REQUIRED>

>> +

>> +<!ELEMENT etmv3-config     EMPTY>

>> +<!ATTLIST etmv3-config     reg_ctrl         CDATA #REQUIRED

>> +                           reg_trc_id       CDATA #REQUIRED

>> +                           reg_ccer         CDATA #REQUIRED

>> +                           reg_idr          CDATA #REQUIRED>

>> +

>> +<!ELEMENT etmv4-config     EMPTY>

>> +<!ATTLIST etmv4-config     reg_idr0         CDATA #REQUIRED

>> +                           reg_idr1         CDATA #REQUIRED

>> +                           reg_idr2         CDATA #REQUIRED

>> +                           reg_idr8         CDATA #REQUIRED

>> +                           reg_configr      CDATA #REQUIRED

>> +                           reg_traceidr     CDATA #REQUIRED>

>> +

>> +<!ELEMENT sink-config      EMPTY>

>> +<!ATTLIST sink-config      formatted         CDATA #REQUIRED

>> +                           fsyncs            CDATA #REQUIRED

>> +                           hsyncs            CDATA #REQUIRED

>> +                           frame_aligned     CDATA #REQUIRED

>> +                           reset_on_4x_sync  CDATA #REQUIRED>

>> +

>>   <!ELEMENT raw (#PCDATA)>

>> diff --git a/gdb/remote.c b/gdb/remote.c

>> index 2c85bdcffbc..e6f0aeceb11 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..8e4eebf3ac8 100644

>> --- a/gdbserver/ChangeLog

>> +++ b/gdbserver/ChangeLog

>> @@ -1,3 +1,15 @@

>> +2021-02-06  Zied Guermazi  <zied.guermazi@trande.de>

>> +

>> +    * configure.srv: add btrace for aarch64*-*-linux* and 

>> arm*-*-linux*.

>> +    * linux-low.cc (linux_low_encode_etm_config): New.

>> +    (linux_process_target::read_btrace): encode CoreSight

>> +    traces and relative decoding parameters.

>> +    (linux_process_target::read_btrace_conf): encode CoreSight config.

>> +    * server.cc (handle_btrace_enable_etm): New.

>> +    (handle_btrace_general_set): add etm handling.

>> +    (handle_btrace_conf_general_set): add etm handling.

>> +    (supported_btrace_packets): add etm related packets.

>> +

>>   2021-02-01  Zied Guermazi  <zied.guermazi@trande.de>

>>         * 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..b70e9648996 100644

>> --- a/gdbserver/linux-low.cc

>> +++ b/gdbserver/linux-low.cc

>> @@ -51,6 +51,9 @@

>>   #include "gdbsupport/environ.h"

>>   #include "gdbsupport/gdb-sigmask.h"

>>   #include "gdbsupport/scoped_restore.h"

>> +#if defined (HAVE_LIBOPENCSD_C_API)

>> +#  include <opencsd/ocsd_if_types.h>

>> +#endif

>>   #ifndef ELFMAG0

>>   /* Don't include <linux/elf.h> here.  If it got included by 

>> gdb_proc_service.h

>>      then ELFMAG0 will have been defined.  If it didn't get included by

>> @@ -6994,6 +6997,73 @@ linux_low_encode_pt_config (struct buffer 

>> *buffer,

>>     buffer_grow_str (buffer, "</pt-config>\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, "<etm-config>\n");

>> +  buffer_grow_str (buffer, "<source-config>\n");

>> +  for (int i=0; i< config->num_cpu;i++)

>> +  {

>> +    if ((config->etm_trace_params->at (i).protocol == 

>> OCSD_PROTOCOL_ETMV3)

>> +    ||(config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_PTM))

>> +      {

>> +    architecture = ARCH_V7;

>> +      }

>> +    else if (config->etm_trace_params->at (i).protocol == 

>> OCSD_PROTOCOL_ETMV4I)

>> +      {

>> +    architecture = ARCH_V8;

>> +      }

>> +    else

>> +      {

>> +    architecture = ARCH_UNKNOWN;

>> +      }

>> +

>> +    buffer_xml_printf (buffer,"<cpu-etm-config arch_ver=\"0x%x\" "

>> +    "core_prof=\"0x%x\" cpu_id=\"0x%x\" protocol=\"0x%x\">\n",

>> +              architecture, profile_CortexA,

>> +              i, config->etm_trace_params->at (i).protocol);

>> +    if (architecture == ARCH_V7)

>> +    {

>> +      buffer_xml_printf (buffer,

>> +    "<etmv3-config reg_idr=\"0x%x\" reg_ctrl=\"0x%x\" "

>> +    "reg_ccer=\"0x%x\" reg_trc_id=\"0x%x\"/>\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 == ARCH_V8)

>> +    {

>> +      buffer_xml_printf (buffer,

>> +    "<etmv4-config reg_idr0=\"0x%x\" reg_idr1=\"0x%x\" "

>> +    "reg_idr2=\"0x%x\" reg_idr8=\"0x%x\" "

>> +              "reg_configr=\"0x%x\" reg_traceidr=\"0x%x\"/>\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,"</cpu-etm-config>\n");

>> +  }

>> +  buffer_grow_str (buffer,"</source-config>\n");

>> +  buffer_xml_printf (buffer,

>> +    "<sink-config  formatted=\"0x%x\" "

>> +        "fsyncs=\"0x%x\" hsyncs=\"0x%x\" "

>> +        "frame_aligned=\"0x%x\" reset_on_4x_sync=\"0x%x\"/>\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,"</etm-config>\n");

>> +}

>> +

>>   /* Encode a raw buffer.  */

>>     static void

>> @@ -7048,7 +7118,7 @@ linux_process_target::read_btrace 

>> (btrace_target_info *tinfo,

>>         case BTRACE_FORMAT_BTS:

>>         buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM 

>> \"btrace.dtd\">\n");

>> -      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");

>> +      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");

>

> If we're changing the format version to 1.1, what if we have a GDB 

> that only knows about format 1.0 and connects to a gdbserver that 

> serves format 1.1? Is there some backward compatibility to be 

> supported here?

[Zied] yes.  v1.1 extends the format without modifying existing one. It 
is backwards compatible ie. you can use an old gdbserver with new GDB. 
Using gdbserver v1.1 with GDB v1.0 will not work. I will revert it to 
v1.0 for PT and BTS for maximum possible combinaisons
>

>>           for (const btrace_block &block : *btrace.variant.bts.blocks)

>>       buffer_xml_printf (buffer, "<block begin=\"0x%s\" 

>> end=\"0x%s\"/>\n",

>> @@ -7059,7 +7129,7 @@ linux_process_target::read_btrace 

>> (btrace_target_info *tinfo,

>>         case BTRACE_FORMAT_PT:

>>         buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM 

>> \"btrace.dtd\">\n");

>> -      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");

>> +      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");

>>         buffer_grow_str (buffer, "<pt>\n");

>>           linux_low_encode_pt_config (buffer, 

>> &btrace.variant.pt.config);

>> @@ -7071,6 +7141,20 @@ linux_process_target::read_btrace 

>> (btrace_target_info *tinfo,

>>         buffer_grow_str0 (buffer, "</btrace>\n");

>>         break;

>>   +    case BTRACE_FORMAT_ETM:

>> +      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM 

>> \"btrace.dtd\">\n");

>> +      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");

>> +      buffer_grow_str (buffer, "<etm>\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, "</etm>\n");

>> +      buffer_grow_str0 (buffer, "</btrace>\n");

>> +      break;

>> +

>>       default:

>>         buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");

>>         return -1;

>> @@ -7088,7 +7172,7 @@ linux_process_target::read_btrace_conf (const 

>> btrace_target_info *tinfo,

>>     const struct btrace_config *conf;

>>       buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM 

>> \"btrace-conf.dtd\">\n");

>> -  buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");

>> +  buffer_grow_str (buffer, "<btrace-conf version=\"1.1\">\n");

>>       conf = linux_btrace_conf (tinfo);

>>     if (conf != NULL)

>> @@ -7109,6 +7193,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");

>> +      buffer_xml_printf (buffer, " size=\"0x%x\"", conf->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..d270cf7d370 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, 

>> &current_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."));

>

> Is this something we should merely warn and not error? What happens if 

> we tell gdbserver to enable btrace again?

>

> Doesn't GDB know that btrace is already running before sending the 

> packet?

[Zied] GDB handle user command by sending the packet, it does not 
maintain a cached status. If we tell GDB to enable btrace again it will 
resend the packet. GDB server knows that traces are enables 
(thread->btrace != NULL) and issue the error.
>

>> +

>> +  current_btrace_conf.format = BTRACE_FORMAT_ETM;

>> +  thread->btrace = target_enable_btrace (thread->id, 

>> &current_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+");

>>

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d4ed6fe0255..76b413c3857 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,22 @@ 
+2021-02-25  Zied Guermazi  <zied.guermazi@trande.de>
+
+	* btrace.c (check_xml_btrace_version): add version 1.1
+	(parse_xml_btrace_etm_config_source_config_cpu_etmv4_config): New.
+	(parse_xml_btrace_etm_config_source_config_cpu_etmv3_config): New.
+	(parse_xml_btrace_etm_config_source_config_cpu_etm_config): New.
+	(parse_xml_btrace_etm_config_source_config): New.
+	(dump_config): New.
+	(parse_xml_btrace_etm_config_source_config_end): New.
+	(parse_xml_btrace_etm_config_sink_config): New.
+	(parse_xml_btrace_etm_raw): New.
+	(parse_xml_btrace_etm): New.
+	(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_target::enable_btrace): add coresight etm.
+	(_initialize_remote): add etm related packets.
+
 2021-02-25  Zied Guermazi  <zied.guermazi@trande.de>
 
 	* infrun.c (set_step_over_info): add debug print.
diff --git a/gdb/NEWS b/gdb/NEWS
index 0dbd89eb360..0c31af6ed0b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -114,6 +114,20 @@  maintenance info sections
 
 ARM Symbian			arm*-*-symbianelf*
 
+* New remote packets
+
+Qbtrace:etm
+  Enable ARM CoreSight ETM Trace-based branch tracing for the current
+  process.  The remote stub reports support for this packet to GDB's
+  qSupported query.
+
+Qbtrace-conf:etm:size
+  Set the requested ring buffer size for branch tracing in
+  ARM CoreSight ETM Trace format.
+
+Qbtrace-conf:etm:sink
+  Set the trace sink for branch tracing in ARM CoreSight ETM Trace format.
+
 *** Changes in GDB 10
 
 * There are new feature names for ARC targets: "org.gnu.gdb.arc.core"
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 1ab5a74f0b6..78feb71d243 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -2616,7 +2616,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);
 }
 
@@ -2751,6 +2751,250 @@  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<gdb_xml_value> &attributes)
+{
+  struct btrace_data *btrace;
+  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 ());
+
+  struct gdb_xml_value *reg_idr0;
+  reg_idr0
+    = xml_find_attribute (attributes, "reg_idr0");
+
+  struct gdb_xml_value *reg_idr1;
+  reg_idr1
+    = xml_find_attribute (attributes, "reg_idr1");
+
+  struct gdb_xml_value *reg_idr2;
+  reg_idr2
+    = xml_find_attribute (attributes, "reg_idr2");
+
+  struct gdb_xml_value *reg_idr8;
+  reg_idr8
+    = xml_find_attribute (attributes, "reg_idr8");
+
+  struct gdb_xml_value *reg_configr;
+  reg_configr
+    = xml_find_attribute (attributes, "reg_configr");
+
+  struct gdb_xml_value *reg_traceidr;
+  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<gdb_xml_value> &attributes)
+{
+  struct btrace_data *btrace;
+  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 ());
+
+  struct gdb_xml_value *reg_ctrl;
+  reg_ctrl
+    = xml_find_attribute (attributes, "reg_ctrl");
+
+  struct gdb_xml_value *reg_trc_id;
+  reg_trc_id
+    = xml_find_attribute (attributes, "reg_trc_id");
+
+  struct gdb_xml_value *reg_ccer;
+  reg_ccer
+    = xml_find_attribute (attributes, "reg_ccer");
+
+  struct gdb_xml_value *reg_idr;
+  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<gdb_xml_value> &attributes)
+{
+  struct btrace_data *btrace;
+  cs_etm_trace_params etm_trace_params;
+
+  DEBUG ("parse_xml_btrace_etm_config_source_config_cpu_etm_config");
+
+  btrace = (struct btrace_data *) user_data;
+
+  struct gdb_xml_value *arch_ver;
+  arch_ver
+    = xml_find_attribute (attributes, "arch_ver");
+
+  struct gdb_xml_value *core_prof;
+  core_prof
+    = xml_find_attribute (attributes, "core_prof");
+
+  struct gdb_xml_value *protocol;
+  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<gdb_xml_value> &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<cs_etm_trace_params>;
+}
+
+/* Get the number of cpus.  */
+static void
+parse_xml_btrace_etm_config_source_config_end (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_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<gdb_xml_value> &attributes)
+{
+  struct btrace_data *btrace;
+
+  DEBUG ("parse_xml_btrace_etm_config_sink_config");
+
+  btrace = (struct btrace_data *) user_data;
+
+  struct gdb_xml_value *formatted;
+  formatted = xml_find_attribute (attributes, "formatted");
+
+  struct gdb_xml_value *fsyncs;
+  fsyncs = xml_find_attribute (attributes, "fsyncs");
+
+  struct gdb_xml_value *hsyncs;
+  hsyncs = xml_find_attribute (attributes, "hsyncs");
+
+  struct gdb_xml_value *frame_aligned;
+  frame_aligned = xml_find_attribute (attributes, "frame_aligned");
+
+  struct gdb_xml_value *reset_on_4x_sync;
+  reset_on_4x_sync = xml_find_attribute (attributes, "reset_on_4x_sync");
+
+  btrace->variant.etm.config.etm_decoder_params.formatted
+    = (uint8_t) *(ULONGEST *) formatted->value.get ();
+  btrace->variant.etm.config.etm_decoder_params.fsyncs
+    = (uint8_t) *(ULONGEST *) fsyncs->value.get ();
+  btrace->variant.etm.config.etm_decoder_params.hsyncs
+    = (uint8_t) *(ULONGEST *) hsyncs->value.get ();
+  btrace->variant.etm.config.etm_decoder_params.frame_aligned
+    = (uint8_t) *(ULONGEST *) frame_aligned->value.get ();
+  btrace->variant.etm.config.etm_decoder_params.reset_on_4x_sync
+    = (uint8_t) *(ULONGEST *) reset_on_4x_sync->value.get ();
+}
+
+
+/* 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<gdb_xml_value> &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 },
@@ -2778,6 +3022,91 @@  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[] = {
+  { "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 }
@@ -2786,8 +3115,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 }
 };
 
@@ -2868,6 +3199,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<gdb_xml_value> &attributes)
+{
+  struct btrace_config *conf;
+  struct gdb_xml_value *size;
+
+  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 ();
+
+  struct gdb_xml_value *sink;
+  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 }
@@ -2878,11 +3235,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/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index bd5b2c91869..709b4e4f09d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -41708,6 +41708,21 @@  These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab No
 
+@item @samp{Qbtrace:etm}
+@tab Yes
+@tab @samp{-}
+@tab Yes
+
+@item @samp{Qbtrace-conf:etm:size}
+@tab Yes
+@tab @samp{-}
+@tab Yes
+
+
+@item @samp{Qbtrace-conf:etm:sink}
+@tab Yes
+@tab @samp{-}
+@tab Yes
 @end multitable
 
 These are the currently defined stub features, in more detail:
@@ -41884,9 +41899,11 @@  The remote stub understands the @samp{Qbtrace:off} packet.
 
 @item Qbtrace:bts
 The remote stub understands the @samp{Qbtrace:bts} packet.
+(@pxref{bts}).
 
 @item Qbtrace:pt
 The remote stub understands the @samp{Qbtrace:pt} packet.
+(@pxref{pt}).
 
 @item Qbtrace-conf:bts:size
 The remote stub understands the @samp{Qbtrace-conf:bts:size} packet.
@@ -41922,6 +41939,16 @@  The remote stub understands the @samp{QThreadEvents} packet.
 @item no-resumed
 The remote stub reports the @samp{N} stop reply.
 
+@item Qbtrace:etm
+The remote stub understands the @samp{Qbtrace:etm} packet.
+(@pxref{etm}).
+
+@item Qbtrace-conf:etm:size
+The remote stub understands the @samp{Qbtrace-conf:etm:size} packet.
+
+@item Qbtrace-conf:etm:sink
+The remote stub understands the @samp{Qbtrace-conf:etm:sink} packet.
+
 @end table
 
 @item qSymbol::
@@ -42328,6 +42355,7 @@  A badly formed request or an error was encountered.
 @end table
 
 @item Qbtrace:bts
+@anchor{bts}
 Enable branch tracing for the current thread using Branch Trace Store.
 
 Reply:
@@ -42339,6 +42367,7 @@  A badly formed request or an error was encountered.
 @end table
 
 @item Qbtrace:pt
+@anchor{pt}
 Enable branch tracing for the current thread using Intel Processor Trace.
 
 Reply:
@@ -42384,6 +42413,41 @@  The ring buffer size has been set.
 A badly formed request or an error was encountered.
 @end table
 
+@item Qbtrace:etm
+@anchor{etm}
+Enable branch tracing for the current thread using ARM CoreSight ETM Trace.
+
+Reply:
+@table @samp
+@item OK
+Branch tracing has been enabled.
+@item E.errtext
+A badly formed request or an error was encountered.
+@end table
+
+@item Qbtrace-conf:etm:size=@var{value}
+Set the requested ring buffer size for new threads that use the
+btrace recording method in etm format.
+
+Reply:
+@table @samp
+@item OK
+The ring buffer size has been set.
+@item E.errtext
+A badly formed request or an error was encountered.
+@end table
+
+@item Qbtrace-conf:etm:sink=@var{value}
+Set the requested trace sink for new threads that use the
+btrace recording method in etm format.
+
+Reply:
+@table @samp
+@item OK
+The ring buffer size has been set.
+@item E.errtext
+A badly formed request or an error was encountered.
+@end table
 @end table
 
 @node Architecture-Specific Protocol Details
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.  -->
 
-<!ELEMENT btrace-conf	(bts?, pt?)>
-<!ATTLIST btrace-conf	version	CDATA	#FIXED "1.0">
+<!ELEMENT btrace-conf	(bts?, pt?, etm?)>
+<!ATTLIST btrace-conf	version	(1.0|1.1) #REQUIRED>
 
 <!ELEMENT bts	EMPTY>
 <!ATTLIST bts	size	CDATA	#IMPLIED>
 
 <!ELEMENT pt	EMPTY>
 <!ATTLIST pt	size	CDATA	#IMPLIED>
+
+<!ELEMENT etm	EMPTY>
+<!ATTLIST etm   size    CDATA   #IMPLIED
+                sink	CDATA   #IMPLIED
+                filter  CDATA   #IMPLIED
+                config  CDATA   #IMPLIED>
diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd
index 9bb930d7d3b..001b77f35d0 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.  -->
 
-<!ELEMENT btrace  (block* | pt)>
-<!ATTLIST btrace  version CDATA   #FIXED "1.0">
+<!ELEMENT btrace  (block* | pt | etm)>
+<!ATTLIST btrace  version (1.0|1.1) #REQUIRED>
 
 <!ELEMENT block        EMPTY>
 <!ATTLIST block        begin  CDATA   #REQUIRED
@@ -21,4 +21,38 @@ 
               model    CDATA #REQUIRED
               stepping CDATA #REQUIRED>
 
+<!ELEMENT etm (etm-config?, raw?)>
+
+<!ELEMENT etm-config (source-config, sink-config)>
+
+<!ELEMENT source-config   (cpu-etm-config+)>
+<!ATTLIST source-config    trace_id         CDATA #IMPLIED>
+
+<!ELEMENT cpu-etm-config  (etmv3-config|etmv4-config)>
+<!ATTLIST cpu-etm-config   cpu_id           CDATA #REQUIRED
+                           arch_ver         CDATA #REQUIRED
+                           core_prof        CDATA #REQUIRED
+                           protocol         CDATA #REQUIRED>
+
+<!ELEMENT etmv3-config     EMPTY>
+<!ATTLIST etmv3-config     reg_ctrl         CDATA #REQUIRED
+                           reg_trc_id       CDATA #REQUIRED
+                           reg_ccer         CDATA #REQUIRED
+                           reg_idr          CDATA #REQUIRED>
+
+<!ELEMENT etmv4-config     EMPTY>
+<!ATTLIST etmv4-config     reg_idr0         CDATA #REQUIRED
+                           reg_idr1         CDATA #REQUIRED
+                           reg_idr2         CDATA #REQUIRED
+                           reg_idr8         CDATA #REQUIRED
+                           reg_configr      CDATA #REQUIRED
+                           reg_traceidr     CDATA #REQUIRED>
+
+<!ELEMENT sink-config      EMPTY>
+<!ATTLIST sink-config      formatted         CDATA #REQUIRED
+                           fsyncs            CDATA #REQUIRED
+                           hsyncs            CDATA #REQUIRED
+                           frame_aligned     CDATA #REQUIRED
+                           reset_on_4x_sync  CDATA #REQUIRED>
+
 <!ELEMENT raw (#PCDATA)>
diff --git a/gdb/remote.c b/gdb/remote.c
index 2c85bdcffbc..e6f0aeceb11 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..8e4eebf3ac8 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,3 +1,15 @@ 
+2021-02-06  Zied Guermazi  <zied.guermazi@trande.de>
+
+	* configure.srv: add btrace for aarch64*-*-linux* and arm*-*-linux*.
+	* linux-low.cc (linux_low_encode_etm_config): New.
+	(linux_process_target::read_btrace): encode CoreSight
+	traces and relative decoding parameters.
+	(linux_process_target::read_btrace_conf): encode CoreSight config.
+	* server.cc (handle_btrace_enable_etm): New.
+	(handle_btrace_general_set): add etm handling.
+	(handle_btrace_conf_general_set): add etm handling.
+	(supported_btrace_packets): add etm related packets.
+
 2021-02-01  Zied Guermazi  <zied.guermazi@trande.de>
 
 	* 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..b70e9648996 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -51,6 +51,9 @@ 
 #include "gdbsupport/environ.h"
 #include "gdbsupport/gdb-sigmask.h"
 #include "gdbsupport/scoped_restore.h"
+#if defined (HAVE_LIBOPENCSD_C_API)
+#  include <opencsd/ocsd_if_types.h>
+#endif
 #ifndef ELFMAG0
 /* Don't include <linux/elf.h> here.  If it got included by gdb_proc_service.h
    then ELFMAG0 will have been defined.  If it didn't get included by
@@ -6994,6 +6997,73 @@  linux_low_encode_pt_config (struct buffer *buffer,
   buffer_grow_str (buffer, "</pt-config>\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, "<etm-config>\n");
+  buffer_grow_str (buffer, "<source-config>\n");
+  for (int i=0; i< config->num_cpu;i++)
+  {
+    if ((config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_ETMV3)
+	||(config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_PTM))
+      {
+	architecture = ARCH_V7;
+      }
+    else if (config->etm_trace_params->at (i).protocol == OCSD_PROTOCOL_ETMV4I)
+      {
+	architecture = ARCH_V8;
+      }
+    else
+      {
+	architecture = ARCH_UNKNOWN;
+      }
+
+    buffer_xml_printf (buffer,"<cpu-etm-config arch_ver=\"0x%x\" "
+	"core_prof=\"0x%x\" cpu_id=\"0x%x\" protocol=\"0x%x\">\n",
+			  architecture, profile_CortexA,
+			  i, config->etm_trace_params->at (i).protocol);
+    if (architecture == ARCH_V7)
+    {
+      buffer_xml_printf (buffer,
+	"<etmv3-config reg_idr=\"0x%x\" reg_ctrl=\"0x%x\" "
+	"reg_ccer=\"0x%x\" reg_trc_id=\"0x%x\"/>\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 == ARCH_V8)
+    {
+      buffer_xml_printf (buffer,
+	"<etmv4-config reg_idr0=\"0x%x\" reg_idr1=\"0x%x\" "
+	"reg_idr2=\"0x%x\" reg_idr8=\"0x%x\" "
+			  "reg_configr=\"0x%x\" reg_traceidr=\"0x%x\"/>\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,"</cpu-etm-config>\n");
+  }
+  buffer_grow_str (buffer,"</source-config>\n");
+  buffer_xml_printf (buffer,
+    "<sink-config  formatted=\"0x%x\" "
+		"fsyncs=\"0x%x\" hsyncs=\"0x%x\" "
+		"frame_aligned=\"0x%x\" reset_on_4x_sync=\"0x%x\"/>\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,"</etm-config>\n");
+}
+
 /* Encode a raw buffer.  */
 
 static void
@@ -7048,7 +7118,7 @@  linux_process_target::read_btrace (btrace_target_info *tinfo,
 
     case BTRACE_FORMAT_BTS:
       buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");
 
       for (const btrace_block &block : *btrace.variant.bts.blocks)
 	buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
@@ -7059,7 +7129,7 @@  linux_process_target::read_btrace (btrace_target_info *tinfo,
 
     case BTRACE_FORMAT_PT:
       buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");
       buffer_grow_str (buffer, "<pt>\n");
 
       linux_low_encode_pt_config (buffer, &btrace.variant.pt.config);
@@ -7071,6 +7141,20 @@  linux_process_target::read_btrace (btrace_target_info *tinfo,
       buffer_grow_str0 (buffer, "</btrace>\n");
       break;
 
+    case BTRACE_FORMAT_ETM:
+      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
+      buffer_grow_str (buffer, "<btrace version=\"1.1\">\n");
+      buffer_grow_str (buffer, "<etm>\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, "</etm>\n");
+      buffer_grow_str0 (buffer, "</btrace>\n");
+      break;
+
     default:
       buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");
       return -1;
@@ -7088,7 +7172,7 @@  linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
   const struct btrace_config *conf;
 
   buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");
-  buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");
+  buffer_grow_str (buffer, "<btrace-conf version=\"1.1\">\n");
 
   conf = linux_btrace_conf (tinfo);
   if (conf != NULL)
@@ -7109,6 +7193,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");
+	  buffer_xml_printf (buffer, " size=\"0x%x\"", conf->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..d270cf7d370 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, &current_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, &current_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+");