/* CTF format support.

   Copyright (C) 2012-2018 Free Software Foundation, Inc.
   Contributed by Hui Zhu <hui_zhu@mentor.com>
   Contributed by Yao Qi <yao@codesourcery.com>

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "ctf.h"
#include "tracepoint.h"
#include "regcache.h"
#include <sys/stat.h>
#include "exec.h"
#include "completer.h"
#include "inferior.h"
#include "gdbthread.h"
#include "tracefile.h"
#include <ctype.h>
#include <algorithm>

/* GDB saves trace buffers and other information (such as trace
   status) got from the remote target into Common Trace Format (CTF).
   The following types of information are expected to save in CTF:

   1. The length (in bytes) of register cache.  Event "register" will
   be defined in metadata, which includes the length.

   2. Trace status.  Event "status" is defined in metadata, which
   includes all aspects of trace status.

   3. Uploaded trace variables.  Event "tsv_def" is defined in
   metadata, which is about all aspects of a uploaded trace variable.
   Uploaded tracepoints.   Event "tp_def" is defined in meta, which
   is about all aspects of an uploaded tracepoint.  Note that the
   "sequence" (a CTF type, which is a dynamically-sized array.) is
   used for "actions" "step_actions" and "cmd_strings".

   4. Trace frames.  Each trace frame is composed by several blocks
   of different types ('R', 'M', 'V').  One trace frame is saved in
   one CTF packet and the blocks of this frame are saved as events.
   4.1: The trace frame related information (such as the number of
   tracepoint associated with this frame) is saved in the packet
   context.
   4.2: The block 'M', 'R' and 'V' are saved in event "memory",
   "register" and "tsv" respectively.
   4.3: When iterating over events, babeltrace can't tell iterator
   goes to a new packet, so we need a marker or anchor to tell GDB
   that iterator goes into a new packet or frame.  We define event
   "frame".  */

#define CTF_MAGIC		0xC1FC1FC1
#define CTF_SAVE_MAJOR		1
#define CTF_SAVE_MINOR		8

#define CTF_METADATA_NAME	"metadata"
#define CTF_DATASTREAM_NAME	"datastream"

/* Reserved event id.  */

#define CTF_EVENT_ID_REGISTER 0
#define CTF_EVENT_ID_TSV 1
#define CTF_EVENT_ID_MEMORY 2
#define CTF_EVENT_ID_FRAME 3
#define CTF_EVENT_ID_STATUS 4
#define CTF_EVENT_ID_TSV_DEF 5
#define CTF_EVENT_ID_TP_DEF 6

#define CTF_PID (2)

/* The state kept while writing the CTF datastream file.  */

struct trace_write_handler
{
  /* File descriptor of metadata.  */
  FILE *metadata_fd;
  /* File descriptor of traceframes.  */
  FILE *datastream_fd;

  /* This is the content size of the current packet.  */
  size_t content_size;

  /* This is the start offset of current packet.  */
  long packet_start;
};

/* Write metadata in FORMAT.  */

static void
ctf_save_write_metadata (struct trace_write_handler *handler,
			 const char *format, ...)
  ATTRIBUTE_PRINTF (2, 3);

static void
ctf_save_write_metadata (struct trace_write_handler *handler,
			 const char *format, ...)
{
  va_list args;

  va_start (args, format);
  if (vfprintf (handler->metadata_fd, format, args) < 0)
    error (_("Unable to write metadata file (%s)"),
	     safe_strerror (errno));
  va_end (args);
}

/* Write BUF of length SIZE to datastream file represented by
   HANDLER.  */

static int
ctf_save_write (struct trace_write_handler *handler,
		const gdb_byte *buf, size_t size)
{
  if (fwrite (buf, size, 1, handler->datastream_fd) != 1)
    error (_("Unable to write file for saving trace data (%s)"),
	   safe_strerror (errno));

  handler->content_size += size;

  return 0;
}

/* Write a unsigned 32-bit integer to datastream file represented by
   HANDLER.  */

#define ctf_save_write_uint32(HANDLER, U32) \
  ctf_save_write (HANDLER, (gdb_byte *) &U32, 4)

/* Write a signed 32-bit integer to datastream file represented by
   HANDLER.  */

#define ctf_save_write_int32(HANDLER, INT32) \
  ctf_save_write ((HANDLER), (gdb_byte *) &(INT32), 4)

/* Set datastream file position.  Update HANDLER->content_size
   if WHENCE is SEEK_CUR.  */

static int
ctf_save_fseek (struct trace_write_handler *handler, long offset,
		int whence)
{
  gdb_assert (whence != SEEK_END);
  gdb_assert (whence != SEEK_SET
	      || offset <= handler->content_size + handler->packet_start);

  if (fseek (handler->datastream_fd, offset, whence))
    error (_("Unable to seek file for saving trace data (%s)"),
	   safe_strerror (errno));

  if (whence == SEEK_CUR)
    handler->content_size += offset;

  return 0;
}

/* Change the datastream file position to align on ALIGN_SIZE,
   and write BUF to datastream file.  The size of BUF is SIZE.  */

static int
ctf_save_align_write (struct trace_write_handler *handler,
		      const gdb_byte *buf,
		      size_t size, size_t align_size)
{
  long offset
    = (align_up (handler->content_size, align_size)
       - handler->content_size);

  if (ctf_save_fseek (handler, offset, SEEK_CUR))
    return -1;

  if (ctf_save_write (handler, buf, size))
    return -1;

  return 0;
}

/* Write events to next new packet.  */

static void
ctf_save_next_packet (struct trace_write_handler *handler)
{
  handler->packet_start += (handler->content_size + 4);
  ctf_save_fseek (handler, handler->packet_start, SEEK_SET);
  handler->content_size = 0;
}

/* Write the CTF metadata header.  */

static void
ctf_save_metadata_header (struct trace_write_handler *handler)
{
  ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
			   CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 8; align = 8; "
			   "signed = false; encoding = ascii;}"
			   " := ascii;\n");
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 8; align = 8; "
			   "signed = false; }"
			   " := uint8_t;\n");
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 16; align = 16;"
			   "signed = false; } := uint16_t;\n");
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 32; align = 32;"
			   "signed = false; } := uint32_t;\n");
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 64; align = 64;"
			   "signed = false; base = hex;}"
			   " := uint64_t;\n");
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 32; align = 32;"
			   "signed = true; } := int32_t;\n");
  ctf_save_write_metadata (handler,
			   "typealias integer { size = 64; align = 64;"
			   "signed = true; } := int64_t;\n");
  ctf_save_write_metadata (handler,
			   "typealias string { encoding = ascii;"
			   " } := chars;\n");
  ctf_save_write_metadata (handler, "\n");

  /* Get the byte order of the host and write CTF data in this byte
     order.  */
#if WORDS_BIGENDIAN
#define HOST_ENDIANNESS "be"
#else
#define HOST_ENDIANNESS "le"
#endif

  ctf_save_write_metadata (handler,
			   "\ntrace {\n"
			   "	major = %u;\n"
			   "	minor = %u;\n"
			   "	byte_order = %s;\n"
			   "	packet.header := struct {\n"
			   "		uint32_t magic;\n"
			   "	};\n"
			   "};\n"
			   "\n"
			   "stream {\n"
			   "	packet.context := struct {\n"
			   "		uint32_t content_size;\n"
			   "		uint32_t packet_size;\n"
			   "		uint16_t tpnum;\n"
			   "	};\n"
			   "	event.header := struct {\n"
			   "		uint32_t id;\n"
			   "	};\n"
			   "};\n",
			   CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
			   HOST_ENDIANNESS);
  ctf_save_write_metadata (handler, "\n");
}

/* CTF trace writer.  */

struct ctf_trace_file_writer
{
  struct trace_file_writer base;

  /* States related to writing CTF trace file.  */
  struct trace_write_handler tcs;
};

/* This is the implementation of trace_file_write_ops method
   dtor.  */

static void
ctf_dtor (struct trace_file_writer *self)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;

  if (writer->tcs.metadata_fd != NULL)
    fclose (writer->tcs.metadata_fd);

  if (writer->tcs.datastream_fd != NULL)
    fclose (writer->tcs.datastream_fd);

}

/* This is the implementation of trace_file_write_ops method
   target_save.  */

static int
ctf_target_save (struct trace_file_writer *self,
		 const char *dirname)
{
  /* Don't support save trace file to CTF format in the target.  */
  return 0;
}

/* This is the implementation of trace_file_write_ops method
   start.  It creates the directory DIRNAME, metadata and datastream
   in the directory.  */

static void
ctf_start (struct trace_file_writer *self, const char *dirname)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;

  /* Create DIRNAME.  */
  if (mkdir (dirname, hmode) && errno != EEXIST)
    error (_("Unable to open directory '%s' for saving trace data (%s)"),
	   dirname, safe_strerror (errno));

  memset (&writer->tcs, '\0', sizeof (writer->tcs));

  std::string file_name = string_printf ("%s/%s", dirname, CTF_METADATA_NAME);

  writer->tcs.metadata_fd = fopen (file_name.c_str (), "w");
  if (writer->tcs.metadata_fd == NULL)
    error (_("Unable to open file '%s' for saving trace data (%s)"),
	   file_name.c_str (), safe_strerror (errno));

  ctf_save_metadata_header (&writer->tcs);

  file_name = string_printf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
  writer->tcs.datastream_fd = fopen (file_name.c_str (), "w");
  if (writer->tcs.datastream_fd == NULL)
    error (_("Unable to open file '%s' for saving trace data (%s)"),
	   file_name.c_str (), safe_strerror (errno));
}

/* This is the implementation of trace_file_write_ops method
   write_header.  Write the types of events on trace variable and
   frame.  */

static void
ctf_write_header (struct trace_file_writer *self)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;


  ctf_save_write_metadata (&writer->tcs, "\n");
  ctf_save_write_metadata (&writer->tcs,
			   "event {\n\tname = \"memory\";\n\tid = %u;\n"
			   "\tfields := struct { \n"
			   "\t\tuint64_t address;\n"
			   "\t\tuint16_t length;\n"
			   "\t\tuint8_t contents[length];\n"
			   "\t};\n"
			   "};\n", CTF_EVENT_ID_MEMORY);

  ctf_save_write_metadata (&writer->tcs, "\n");
  ctf_save_write_metadata (&writer->tcs,
			   "event {\n\tname = \"tsv\";\n\tid = %u;\n"
			   "\tfields := struct { \n"
			   "\t\tuint64_t val;\n"
			   "\t\tuint32_t num;\n"
			   "\t};\n"
			   "};\n", CTF_EVENT_ID_TSV);

  ctf_save_write_metadata (&writer->tcs, "\n");
  ctf_save_write_metadata (&writer->tcs,
			   "event {\n\tname = \"frame\";\n\tid = %u;\n"
			   "\tfields := struct { \n"
			   "\t};\n"
			   "};\n", CTF_EVENT_ID_FRAME);

  ctf_save_write_metadata (&writer->tcs, "\n");
  ctf_save_write_metadata (&writer->tcs,
			  "event {\n\tname = \"tsv_def\";\n"
			  "\tid = %u;\n\tfields := struct { \n"
			  "\t\tint64_t initial_value;\n"
			  "\t\tint32_t number;\n"
			  "\t\tint32_t builtin;\n"
			  "\t\tchars name;\n"
			  "\t};\n"
			  "};\n", CTF_EVENT_ID_TSV_DEF);

  ctf_save_write_metadata (&writer->tcs, "\n");
  ctf_save_write_metadata (&writer->tcs,
			   "event {\n\tname = \"tp_def\";\n"
			   "\tid = %u;\n\tfields := struct { \n"
			   "\t\tuint64_t addr;\n"
			   "\t\tuint64_t traceframe_usage;\n"
			   "\t\tint32_t number;\n"
			   "\t\tint32_t enabled;\n"
			   "\t\tint32_t step;\n"
			   "\t\tint32_t pass;\n"
			   "\t\tint32_t hit_count;\n"
			   "\t\tint32_t type;\n"
			   "\t\tchars cond;\n"

			  "\t\tuint32_t action_num;\n"
			  "\t\tchars actions[action_num];\n"

			  "\t\tuint32_t step_action_num;\n"
			  "\t\tchars step_actions[step_action_num];\n"

			  "\t\tchars at_string;\n"
			  "\t\tchars cond_string;\n"

			  "\t\tuint32_t cmd_num;\n"
			  "\t\tchars cmd_strings[cmd_num];\n"
			  "\t};\n"
			  "};\n", CTF_EVENT_ID_TP_DEF);

  gdb_assert (writer->tcs.content_size == 0);
  gdb_assert (writer->tcs.packet_start == 0);

  /* Create a new packet to contain this event.  */
  self->ops->frame_ops->start (self, 0);
}

/* This is the implementation of trace_file_write_ops method
   write_regblock_type.  Write the type of register event in
   metadata.  */

static void
ctf_write_regblock_type (struct trace_file_writer *self, int size)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;

  ctf_save_write_metadata (&writer->tcs, "\n");

  ctf_save_write_metadata (&writer->tcs,
			   "event {\n\tname = \"register\";\n\tid = %u;\n"
			   "\tfields := struct { \n"
			   "\t\tascii contents[%d];\n"
			   "\t};\n"
			   "};\n",
			   CTF_EVENT_ID_REGISTER, size);
}

/* This is the implementation of trace_file_write_ops method
   write_status.  */

static void
ctf_write_status (struct trace_file_writer *self,
		  struct trace_status *ts)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  uint32_t id;

  ctf_save_write_metadata (&writer->tcs, "\n");
  ctf_save_write_metadata (&writer->tcs,
			   "event {\n\tname = \"status\";\n\tid = %u;\n"
			   "\tfields := struct { \n"
			   "\t\tint32_t stop_reason;\n"
			   "\t\tint32_t stopping_tracepoint;\n"
			   "\t\tint32_t traceframe_count;\n"
			   "\t\tint32_t traceframes_created;\n"
			   "\t\tint32_t buffer_free;\n"
			   "\t\tint32_t buffer_size;\n"
			   "\t\tint32_t disconnected_tracing;\n"
			   "\t\tint32_t circular_buffer;\n"
			   "\t};\n"
			   "};\n",
			   CTF_EVENT_ID_STATUS);

  id = CTF_EVENT_ID_STATUS;
  /* Event Id.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);

  ctf_save_write_int32 (&writer->tcs, ts->stop_reason);
  ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint);
  ctf_save_write_int32 (&writer->tcs, ts->traceframe_count);
  ctf_save_write_int32 (&writer->tcs, ts->traceframes_created);
  ctf_save_write_int32 (&writer->tcs, ts->buffer_free);
  ctf_save_write_int32 (&writer->tcs, ts->buffer_size);
  ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing);
  ctf_save_write_int32 (&writer->tcs, ts->circular_buffer);
}

/* This is the implementation of trace_file_write_ops method
   write_uploaded_tsv.  */

static void
ctf_write_uploaded_tsv (struct trace_file_writer *self,
			struct uploaded_tsv *tsv)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  int32_t int32;
  int64_t int64;
  const gdb_byte zero = 0;

  /* Event Id.  */
  int32 = CTF_EVENT_ID_TSV_DEF;
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);

  /* initial_value */
  int64 = tsv->initial_value;
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);

  /* number */
  ctf_save_write_int32 (&writer->tcs, tsv->number);

  /* builtin */
  ctf_save_write_int32 (&writer->tcs, tsv->builtin);

  /* name */
  if (tsv->name != NULL)
    ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name,
		    strlen (tsv->name));
  ctf_save_write (&writer->tcs, &zero, 1);
}

/* This is the implementation of trace_file_write_ops method
   write_uploaded_tp.  */

static void
ctf_write_uploaded_tp (struct trace_file_writer *self,
		       struct uploaded_tp *tp)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  int32_t int32;
  int64_t int64;
  uint32_t u32;
  const gdb_byte zero = 0;
  int a;
  char *act;

  /* Event Id.  */
  int32 = CTF_EVENT_ID_TP_DEF;
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);

  /* address */
  int64 = tp->addr;
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);

  /* traceframe_usage */
  int64 = tp->traceframe_usage;
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);

  /* number */
  ctf_save_write_int32 (&writer->tcs, tp->number);

  /* enabled */
  ctf_save_write_int32 (&writer->tcs, tp->enabled);

  /* step */
  ctf_save_write_int32 (&writer->tcs, tp->step);

  /* pass */
  ctf_save_write_int32 (&writer->tcs, tp->pass);

  /* hit_count */
  ctf_save_write_int32 (&writer->tcs, tp->hit_count);

  /* type */
  ctf_save_write_int32 (&writer->tcs, tp->type);

  /* condition  */
  if (tp->cond != NULL)
    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen (tp->cond));
  ctf_save_write (&writer->tcs, &zero, 1);

  /* actions */
  u32 = VEC_length (char_ptr, tp->actions);
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
  for (a = 0; VEC_iterate (char_ptr, tp->actions, a, act); ++a)
    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);

  /* step_actions */
  u32 = VEC_length (char_ptr, tp->step_actions);
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
  for (a = 0; VEC_iterate (char_ptr, tp->step_actions, a, act); ++a)
    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);

  /* at_string */
  if (tp->at_string != NULL)
    ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string,
		    strlen (tp->at_string));
  ctf_save_write (&writer->tcs, &zero, 1);

  /* cond_string */
  if (tp->cond_string != NULL)
    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string,
		    strlen (tp->cond_string));
  ctf_save_write (&writer->tcs, &zero, 1);

  /* cmd_strings */
  u32 = VEC_length (char_ptr, tp->cmd_strings);
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
  for (a = 0; VEC_iterate (char_ptr, tp->cmd_strings, a, act); ++a)
    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);

}

/* This is the implementation of trace_file_write_ops method
   write_tdesc.  */

static void
ctf_write_tdesc (struct trace_file_writer *self)
{
  /* Nothing so far. */
}

/* This is the implementation of trace_file_write_ops method
   write_definition_end.  */

static void
ctf_write_definition_end (struct trace_file_writer *self)
{
  self->ops->frame_ops->end (self);
}

/* This is the implementation of trace_file_write_ops method
   end.  */

static void
ctf_end (struct trace_file_writer *self)
{
  struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;

  gdb_assert (writer->tcs.content_size == 0);
}

/* This is the implementation of trace_frame_write_ops method
   start.  */

static void
ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  uint32_t id = CTF_EVENT_ID_FRAME;
  uint32_t u32;

  /* Step 1: Write packet context.  */
  /* magic.  */
  u32 = CTF_MAGIC;
  ctf_save_write_uint32 (&writer->tcs, u32);
  /* content_size and packet_size..  We still don't know the value,
     write it later.  */
  ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
  ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
  /* Tracepoint number.  */
  ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);

  /* Step 2: Write event "frame".  */
  /* Event Id.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
}

/* This is the implementation of trace_frame_write_ops method
   write_r_block.  */

static void
ctf_write_frame_r_block (struct trace_file_writer *self,
			 gdb_byte *buf, int32_t size)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  uint32_t id = CTF_EVENT_ID_REGISTER;

  /* Event Id.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);

  /* array contents.  */
  ctf_save_align_write (&writer->tcs, buf, size, 1);
}

/* This is the implementation of trace_frame_write_ops method
   write_m_block_header.  */

static void
ctf_write_frame_m_block_header (struct trace_file_writer *self,
				uint64_t addr, uint16_t length)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  uint32_t event_id = CTF_EVENT_ID_MEMORY;

  /* Event Id.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);

  /* Address.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);

  /* Length.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
}

/* This is the implementation of trace_frame_write_ops method
   write_m_block_memory.  */

static void
ctf_write_frame_m_block_memory (struct trace_file_writer *self,
				gdb_byte *buf, uint16_t length)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;

  /* Contents.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
}

/* This is the implementation of trace_frame_write_ops method
   write_v_block.  */

static void
ctf_write_frame_v_block (struct trace_file_writer *self,
			 int32_t num, uint64_t val)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  uint32_t id = CTF_EVENT_ID_TSV;

  /* Event Id.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);

  /* val.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
  /* num.  */
  ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
}

/* This is the implementation of trace_frame_write_ops method
   end.  */

static void
ctf_write_frame_end (struct trace_file_writer *self)
{
  struct ctf_trace_file_writer *writer
    = (struct ctf_trace_file_writer *) self;
  uint32_t u32;
  uint32_t t;

  /* Write the content size to packet header.  */
  ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
		  SEEK_SET);
  u32 = writer->tcs.content_size * TARGET_CHAR_BIT;

  t = writer->tcs.content_size;
  ctf_save_write_uint32 (&writer->tcs, u32);

  /* Write the packet size.  */
  u32 += 4 * TARGET_CHAR_BIT;
  ctf_save_write_uint32 (&writer->tcs, u32);

  writer->tcs.content_size = t;

  /* Write zero at the end of the packet.  */
  ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
		  SEEK_SET);
  u32 = 0;
  ctf_save_write_uint32 (&writer->tcs, u32);
  writer->tcs.content_size = t;

  ctf_save_next_packet (&writer->tcs);
}

/* Operations to write various types of trace frames into CTF
   format.  */

static const struct trace_frame_write_ops ctf_write_frame_ops =
{
  ctf_write_frame_start,
  ctf_write_frame_r_block,
  ctf_write_frame_m_block_header,
  ctf_write_frame_m_block_memory,
  ctf_write_frame_v_block,
  ctf_write_frame_end,
};

/* Operations to write trace buffers into CTF format.  */

static const struct trace_file_write_ops ctf_write_ops =
{
  ctf_dtor,
  ctf_target_save,
  ctf_start,
  ctf_write_header,
  ctf_write_regblock_type,
  ctf_write_status,
  ctf_write_uploaded_tsv,
  ctf_write_uploaded_tp,
  ctf_write_tdesc,
  ctf_write_definition_end,
  NULL,
  &ctf_write_frame_ops,
  ctf_end,
};

/* Return a trace writer for CTF format.  */

struct trace_file_writer *
ctf_trace_file_writer_new (void)
{
  struct ctf_trace_file_writer *writer = XNEW (struct ctf_trace_file_writer);

  writer->base.ops = &ctf_write_ops;

  return (struct trace_file_writer *) writer;
}

#if HAVE_LIBBABELTRACE
/* Use libbabeltrace to read CTF data.  The libbabeltrace provides
   iterator to iterate over each event in CTF data and APIs to get
   details of event and packet, so it is very convenient to use
   libbabeltrace to access events in CTF.  */

#include <babeltrace/babeltrace.h>
#include <babeltrace/ctf/events.h>
#include <babeltrace/ctf/iterator.h>

/* The struct pointer for current CTF directory.  */
static int handle_id = -1;
static struct bt_context *ctx = NULL;
static struct bt_ctf_iter *ctf_iter = NULL;
/* The position of the first packet containing trace frame.  */
static struct bt_iter_pos *start_pos;

/* The name of CTF directory.  */
static char *trace_dirname;

static struct target_ops ctf_ops;

/* Destroy ctf iterator and context.  */

static void
ctf_destroy (void)
{
  if (ctf_iter != NULL)
    {
      bt_ctf_iter_destroy (ctf_iter);
      ctf_iter = NULL;
    }
  if (ctx != NULL)
    {
      bt_context_put (ctx);
      ctx = NULL;
    }
}

/* Open CTF trace data in DIRNAME.  */

static void
ctf_open_dir (const char *dirname)
{
  struct bt_iter_pos begin_pos;
  unsigned int count, i;
  struct bt_ctf_event_decl * const *list;

  ctx = bt_context_create ();
  if (ctx == NULL)
    error (_("Unable to create bt_context"));
  handle_id = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
  if (handle_id < 0)
    {
      ctf_destroy ();
      error (_("Unable to use libbabeltrace on directory \"%s\""),
	     dirname);
    }

  begin_pos.type = BT_SEEK_BEGIN;
  ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
  if (ctf_iter == NULL)
    {
      ctf_destroy ();
      error (_("Unable to create bt_iterator"));
    }

  /* Look for the declaration of register block.  Get the length of
     array "contents" to set trace_regblock_size.  */

  bt_ctf_get_event_decl_list (handle_id, ctx, &list, &count);
  for (i = 0; i < count; i++)
    if (strcmp ("register", bt_ctf_get_decl_event_name (list[i])) == 0)
      {
	const struct bt_ctf_field_decl * const *field_list;
	const struct bt_declaration *decl;

	bt_ctf_get_decl_fields (list[i], BT_EVENT_FIELDS, &field_list,
				&count);

	gdb_assert (count == 1);
	gdb_assert (0 == strcmp ("contents",
				 bt_ctf_get_decl_field_name (field_list[0])));
	decl = bt_ctf_get_decl_from_field_decl (field_list[0]);
	trace_regblock_size = bt_ctf_get_array_len (decl);

	break;
      }
}

#define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD)			\
  (VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT),	\
							   (SCOPE),	\
							   #FIELD))

#define SET_ENUM_FIELD(EVENT, SCOPE, VAR, TYPE, FIELD)			\
  (VAR)->FIELD = (TYPE) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT),	\
							    (SCOPE),	\
							    #FIELD))


/* EVENT is the "status" event and TS is filled in.  */

static void
ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
{
  const struct bt_definition *scope
    = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS);

  SET_ENUM_FIELD (event, scope, ts, enum trace_stop_reason, stop_reason);
  SET_INT32_FIELD (event, scope, ts, stopping_tracepoint);
  SET_INT32_FIELD (event, scope, ts, traceframe_count);
  SET_INT32_FIELD (event, scope, ts, traceframes_created);
  SET_INT32_FIELD (event, scope, ts, buffer_free);
  SET_INT32_FIELD (event, scope, ts, buffer_size);
  SET_INT32_FIELD (event, scope, ts, disconnected_tracing);
  SET_INT32_FIELD (event, scope, ts, circular_buffer);

  bt_iter_next (bt_ctf_get_iter (ctf_iter));
}

/* Read the events "tsv_def" one by one, extract its contents and fill
   in the list UPLOADED_TSVS.  */

static void
ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
{
  gdb_assert (ctf_iter != NULL);

  while (1)
    {
      struct bt_ctf_event *event;
      const struct bt_definition *scope;
      const struct bt_definition *def;
      uint32_t event_id;
      struct uploaded_tsv *utsv = NULL;

      event = bt_ctf_iter_read_event (ctf_iter);
      scope = bt_ctf_get_top_level_scope (event,
					  BT_STREAM_EVENT_HEADER);
      event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
						      "id"));
      if (event_id != CTF_EVENT_ID_TSV_DEF)
	break;

      scope = bt_ctf_get_top_level_scope (event,
					  BT_EVENT_FIELDS);

      def = bt_ctf_get_field (event, scope, "number");
      utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
			       uploaded_tsvs);

      def = bt_ctf_get_field (event, scope, "builtin");
      utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
      def = bt_ctf_get_field (event, scope, "initial_value");
      utsv->initial_value = bt_ctf_get_int64 (def);

      def = bt_ctf_get_field (event, scope, "name");
      utsv->name =  xstrdup (bt_ctf_get_string (def));

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }

}

/* Read the value of element whose index is NUM from CTF and write it
   to the corresponding VAR->ARRAY. */

#define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY)	\
  do							\
    {							\
      uint32_t u32, i;						\
      const struct bt_definition *def;				\
								\
      u32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT),	\
							    (SCOPE),	\
							    #NUM));	\
      def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY);		\
      for (i = 0; i < u32; i++)					\
	{								\
	  const struct bt_definition *element				\
	    = bt_ctf_get_index ((EVENT), def, i);			\
									\
	  VEC_safe_push (char_ptr, (VAR)->ARRAY,			\
			 xstrdup (bt_ctf_get_string (element)));	\
	}								\
    }									\
  while (0)

/* Read a string from CTF and set VAR->FIELD. If the length of string
   is zero, set VAR->FIELD to NULL.  */

#define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD)			\
  do									\
    {									\
      const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT),	\
							   (SCOPE),	\
							   #FIELD));	\
									\
      if (strlen (p) > 0)						\
	(VAR)->FIELD = xstrdup (p);					\
      else								\
	(VAR)->FIELD = NULL;						\
    }									\
  while (0)

/* Read the events "tp_def" one by one, extract its contents and fill
   in the list UPLOADED_TPS.  */

static void
ctf_read_tp (struct uploaded_tp **uploaded_tps)
{
  gdb_assert (ctf_iter != NULL);

  while (1)
    {
      struct bt_ctf_event *event;
      const struct bt_definition *scope;
      uint32_t u32;
      int32_t int32;
      uint64_t u64;
      struct uploaded_tp *utp = NULL;

      event = bt_ctf_iter_read_event (ctf_iter);
      scope = bt_ctf_get_top_level_scope (event,
					  BT_STREAM_EVENT_HEADER);
      u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
						 "id"));
      if (u32 != CTF_EVENT_ID_TP_DEF)
	break;

      scope = bt_ctf_get_top_level_scope (event,
					  BT_EVENT_FIELDS);
      int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event,
							    scope,
							    "number"));
      u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
						 "addr"));
      utp = get_uploaded_tp (int32, u64,  uploaded_tps);

      SET_INT32_FIELD (event, scope, utp, enabled);
      SET_INT32_FIELD (event, scope, utp, step);
      SET_INT32_FIELD (event, scope, utp, pass);
      SET_INT32_FIELD (event, scope, utp, hit_count);
      SET_ENUM_FIELD (event, scope, utp, enum bptype, type);

      /* Read 'cmd_strings'.  */
      SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings);
      /* Read 'actions'.  */
      SET_ARRAY_FIELD (event, scope, utp, action_num, actions);
      /* Read 'step_actions'.  */
      SET_ARRAY_FIELD (event, scope, utp, step_action_num,
		       step_actions);

      SET_STRING_FIELD(event, scope, utp, at_string);
      SET_STRING_FIELD(event, scope, utp, cond_string);

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }
}

/* This is the implementation of target_ops method to_open.  Open CTF
   trace data, read trace status, trace state variables and tracepoint
   definitions from the first packet.  Set the start position at the
   second packet which contains events on trace blocks.  */

static void
ctf_open (const char *dirname, int from_tty)
{
  struct bt_ctf_event *event;
  uint32_t event_id;
  const struct bt_definition *scope;
  struct uploaded_tsv *uploaded_tsvs = NULL;
  struct uploaded_tp *uploaded_tps = NULL;

  if (!dirname)
    error (_("No CTF directory specified."));

  ctf_open_dir (dirname);

  target_preopen (from_tty);

  /* Skip the first packet which about the trace status.  The first
     event is "frame".  */
  event = bt_ctf_iter_read_event (ctf_iter);
  scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
  event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
  if (event_id != CTF_EVENT_ID_FRAME)
    error (_("Wrong event id of the first event"));
  /* The second event is "status".  */
  bt_iter_next (bt_ctf_get_iter (ctf_iter));
  event = bt_ctf_iter_read_event (ctf_iter);
  scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
  event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
  if (event_id != CTF_EVENT_ID_STATUS)
    error (_("Wrong event id of the second event"));
  ctf_read_status (event, current_trace_status ());

  ctf_read_tsv (&uploaded_tsvs);

  ctf_read_tp (&uploaded_tps);

  event = bt_ctf_iter_read_event (ctf_iter);
  /* EVENT can be NULL if we've already gone to the end of stream of
     events.  */
  if (event != NULL)
    {
      scope = bt_ctf_get_top_level_scope (event,
					  BT_STREAM_EVENT_HEADER);
      event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event,
						      scope, "id"));
      if (event_id != CTF_EVENT_ID_FRAME)
	error (_("Wrong event id of the first event of the second packet"));
    }

  start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
  gdb_assert (start_pos->type == BT_SEEK_RESTORE);

  trace_dirname = xstrdup (dirname);
  push_target (&ctf_ops);

  inferior_appeared (current_inferior (), CTF_PID);
  inferior_ptid = pid_to_ptid (CTF_PID);
  add_thread_silent (inferior_ptid);

  merge_uploaded_trace_state_variables (&uploaded_tsvs);
  merge_uploaded_tracepoints (&uploaded_tps);

  post_create_inferior (&ctf_ops, from_tty);
}

/* This is the implementation of target_ops method to_close.  Destroy
   CTF iterator and context.  */

static void
ctf_close (struct target_ops *self)
{
  int pid;

  ctf_destroy ();
  xfree (trace_dirname);
  trace_dirname = NULL;

  pid = ptid_get_pid (inferior_ptid);
  inferior_ptid = null_ptid;	/* Avoid confusion from thread stuff.  */
  exit_inferior_silent (pid);

  trace_reset_local_state ();
}

/* This is the implementation of target_ops method to_files_info.
   Print the directory name of CTF trace data.  */

static void
ctf_files_info (struct target_ops *t)
{
  printf_filtered ("\t`%s'\n", trace_dirname);
}

/* This is the implementation of target_ops method to_fetch_registers.
   Iterate over events whose name is "register" in current frame,
   extract contents from events, and set REGCACHE with the contents.
   If no matched events are found, mark registers unavailable.  */

static void
ctf_fetch_registers (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct bt_ctf_event *event = NULL;
  struct bt_iter_pos *pos;

  /* An uninitialized reg size says we're not going to be
     successful at getting register blocks.  */
  if (trace_regblock_size == 0)
    return;

  gdb_assert (ctf_iter != NULL);
  /* Save the current position.  */
  pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
  gdb_assert (pos->type == BT_SEEK_RESTORE);

  while (1)
    {
      const char *name;
      struct bt_ctf_event *event1;

      event1 = bt_ctf_iter_read_event (ctf_iter);

      name = bt_ctf_event_name (event1);

      if (name == NULL || strcmp (name, "frame") == 0)
	break;
      else if (strcmp (name, "register") == 0)
	{
	  event = event1;
	  break;
	}

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }

  /* Restore the position.  */
  bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

  if (event != NULL)
    {
      int offset, regsize, regn;
      const struct bt_definition *scope
	= bt_ctf_get_top_level_scope (event,
				      BT_EVENT_FIELDS);
      const struct bt_definition *array
	= bt_ctf_get_field (event, scope, "contents");
      gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);

      /* Assume the block is laid out in GDB register number order,
	 each register with the size that it has in GDB.  */
      offset = 0;
      for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
	{
	  regsize = register_size (gdbarch, regn);
	  /* Make sure we stay within block bounds.  */
	  if (offset + regsize >= trace_regblock_size)
	    break;
	  if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
	    {
	      if (regno == regn)
		{
		  regcache_raw_supply (regcache, regno, regs + offset);
		  break;
		}
	      else if (regno == -1)
		{
		  regcache_raw_supply (regcache, regn, regs + offset);
		}
	    }
	  offset += regsize;
	}
    }
  else
    tracefile_fetch_registers (regcache, regno);
}

/* This is the implementation of target_ops method to_xfer_partial.
   Iterate over events whose name is "memory" in
   current frame, extract the address and length from events.  If
   OFFSET is within the range, read the contents from events to
   READBUF.  */

static enum target_xfer_status
ctf_xfer_partial (struct target_ops *ops, enum target_object object,
		  const char *annex, gdb_byte *readbuf,
		  const gdb_byte *writebuf, ULONGEST offset,
		  ULONGEST len, ULONGEST *xfered_len)
{
  /* We're only doing regular memory for now.  */
  if (object != TARGET_OBJECT_MEMORY)
    return TARGET_XFER_E_IO;

  if (readbuf == NULL)
    error (_("ctf_xfer_partial: trace file is read-only"));

  if (get_traceframe_number () != -1)
    {
      struct bt_iter_pos *pos;
      enum target_xfer_status res;
      /* Records the lowest available address of all blocks that
	 intersects the requested range.  */
      ULONGEST low_addr_available = 0;

      gdb_assert (ctf_iter != NULL);
      /* Save the current position.  */
      pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
      gdb_assert (pos->type == BT_SEEK_RESTORE);

      /* Iterate through the traceframe's blocks, looking for
	 memory.  */
      while (1)
	{
	  ULONGEST amt;
	  uint64_t maddr;
	  uint16_t mlen;
	  const struct bt_definition *scope;
	  const struct bt_definition *def;
	  struct bt_ctf_event *event
	    = bt_ctf_iter_read_event (ctf_iter);
	  const char *name = bt_ctf_event_name (event);

	  if (name == NULL || strcmp (name, "frame") == 0)
	    break;
	  else if (strcmp (name, "memory") != 0)
	    {
	      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
		break;

	      continue;
	    }

	  scope = bt_ctf_get_top_level_scope (event,
					      BT_EVENT_FIELDS);

	  def = bt_ctf_get_field (event, scope, "address");
	  maddr = bt_ctf_get_uint64 (def);
	  def = bt_ctf_get_field (event, scope, "length");
	  mlen = (uint16_t) bt_ctf_get_uint64 (def);

	  /* If the block includes the first part of the desired
	     range, return as much it has; GDB will re-request the
	     remainder, which might be in a different block of this
	     trace frame.  */
	  if (maddr <= offset && offset < (maddr + mlen))
	    {
	      const struct bt_definition *array
		= bt_ctf_get_field (event, scope, "contents");
	      gdb_byte *contents;
	      int k;

	      contents = (gdb_byte *) xmalloc (mlen);

	      for (k = 0; k < mlen; k++)
		{
		  const struct bt_definition *element
		    = bt_ctf_get_index (event, array, k);

		  contents[k] = (gdb_byte) bt_ctf_get_uint64 (element);
		}

	      amt = (maddr + mlen) - offset;
	      if (amt > len)
		amt = len;

	      memcpy (readbuf, &contents[offset - maddr], amt);

	      xfree (contents);

	      /* Restore the position.  */
	      bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

	      if (amt == 0)
		return TARGET_XFER_EOF;
	      else
		{
		  *xfered_len = amt;
		  return TARGET_XFER_OK;
		}
	    }

	  if (offset < maddr && maddr < (offset + len))
	    if (low_addr_available == 0 || low_addr_available > maddr)
	      low_addr_available = maddr;

	  if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	    break;
	}

      /* Restore the position.  */
      bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

      /* Requested memory is unavailable in the context of traceframes,
	 and this address falls within a read-only section, fallback
	 to reading from executable, up to LOW_ADDR_AVAILABLE  */
      if (offset < low_addr_available)
	len = std::min (len, low_addr_available - offset);
      res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);

      if (res == TARGET_XFER_OK)
	return TARGET_XFER_OK;
      else
	{
	  /* No use trying further, we know some memory starting
	     at MEMADDR isn't available.  */
	  *xfered_len = len;
	  return TARGET_XFER_UNAVAILABLE;
	}
    }
  else
    {
      /* Fallback to reading from read-only sections.  */
      return section_table_read_available_memory (readbuf, offset, len, xfered_len);
    }
}

/* This is the implementation of target_ops method
   to_get_trace_state_variable_value.
   Iterate over events whose name is "tsv" in current frame.  When the
   trace variable is found, set the value of it to *VAL and return
   true, otherwise return false.  */

static int
ctf_get_trace_state_variable_value (struct target_ops *self,
				    int tsvnum, LONGEST *val)
{
  struct bt_iter_pos *pos;
  int found = 0;

  gdb_assert (ctf_iter != NULL);
  /* Save the current position.  */
  pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
  gdb_assert (pos->type == BT_SEEK_RESTORE);

  /* Iterate through the traceframe's blocks, looking for 'V'
     block.  */
  while (1)
    {
      struct bt_ctf_event *event
	= bt_ctf_iter_read_event (ctf_iter);
      const char *name = bt_ctf_event_name (event);

      if (name == NULL || strcmp (name, "frame") == 0)
	break;
      else if (strcmp (name, "tsv") == 0)
	{
	  const struct bt_definition *scope;
	  const struct bt_definition *def;

	  scope = bt_ctf_get_top_level_scope (event,
					      BT_EVENT_FIELDS);

	  def = bt_ctf_get_field (event, scope, "num");
	  if (tsvnum == (int32_t) bt_ctf_get_uint64 (def))
	    {
	      def = bt_ctf_get_field (event, scope, "val");
	      *val = bt_ctf_get_uint64 (def);

	      found = 1;
	    }
	}

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }

  /* Restore the position.  */
  bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

  return found;
}

/* Return the tracepoint number in "frame" event.  */

static int
ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event)
{
  /* The packet context of events has a field "tpnum".  */
  const struct bt_definition *scope
    = bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT);
  uint64_t tpnum
    = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum"));

  return (int) tpnum;
}

/* Return the address at which the current frame was collected.  */

static CORE_ADDR
ctf_get_traceframe_address (void)
{
  struct bt_ctf_event *event = NULL;
  struct bt_iter_pos *pos;
  CORE_ADDR addr = 0;

  gdb_assert (ctf_iter != NULL);
  pos  = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
  gdb_assert (pos->type == BT_SEEK_RESTORE);

  while (1)
    {
      const char *name;
      struct bt_ctf_event *event1;

      event1 = bt_ctf_iter_read_event (ctf_iter);

      name = bt_ctf_event_name (event1);

      if (name == NULL)
	break;
      else if (strcmp (name, "frame") == 0)
	{
	  event = event1;
	  break;
	}

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }

  if (event != NULL)
    {
      int tpnum = ctf_get_tpnum_from_frame_event (event);
      struct tracepoint *tp
	= get_tracepoint_by_number_on_target (tpnum);

      if (tp && tp->loc)
	addr = tp->loc->address;
    }

  /* Restore the position.  */
  bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

  return addr;
}

/* This is the implementation of target_ops method to_trace_find.
   Iterate the events whose name is "frame", extract the tracepoint
   number in it.  Return traceframe number when matched.  */

static int
ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
		CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
{
  int tfnum = 0;
  int found = 0;

  if (num == -1)
    {
      if (tpp != NULL)
	*tpp = -1;
      return -1;
    }

  gdb_assert (ctf_iter != NULL);
  /* Set iterator back to the start.  */
  bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos);

  while (1)
    {
      struct bt_ctf_event *event;
      const char *name;

      event = bt_ctf_iter_read_event (ctf_iter);

      name = bt_ctf_event_name (event);

      if (event == NULL || name == NULL)
	break;

      if (strcmp (name, "frame") == 0)
	{
	  CORE_ADDR tfaddr;

	  if (type == tfind_number)
	    {
	      /* Looking for a specific trace frame.  */
	      if (tfnum == num)
		found = 1;
	    }
	  else
	    {
	      /* Start from the _next_ trace frame.  */
	      if (tfnum > get_traceframe_number ())
		{
		  switch (type)
		    {
		    case tfind_tp:
		      {
			struct tracepoint *tp = get_tracepoint (num);

			if (tp != NULL
			    && (tp->number_on_target
				== ctf_get_tpnum_from_frame_event (event)))
			  found = 1;
			break;
		      }
		    case tfind_pc:
		      tfaddr = ctf_get_traceframe_address ();
		      if (tfaddr == addr1)
			found = 1;
		      break;
		    case tfind_range:
		      tfaddr = ctf_get_traceframe_address ();
		      if (addr1 <= tfaddr && tfaddr <= addr2)
			found = 1;
		      break;
		    case tfind_outside:
		      tfaddr = ctf_get_traceframe_address ();
		      if (!(addr1 <= tfaddr && tfaddr <= addr2))
			found = 1;
		      break;
		    default:
		      internal_error (__FILE__, __LINE__, _("unknown tfind type"));
		    }
		}
	    }
	  if (found)
	    {
	      if (tpp != NULL)
		*tpp = ctf_get_tpnum_from_frame_event (event);

	      /* Skip the event "frame".  */
	      bt_iter_next (bt_ctf_get_iter (ctf_iter));

	      return tfnum;
	    }
	  tfnum++;
	}

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }

  return -1;
}

/* This is the implementation of target_ops method to_traceframe_info.
   Iterate the events whose name is "memory", in current
   frame, extract memory range information, and return them in
   traceframe_info.  */

static traceframe_info_up
ctf_traceframe_info (struct target_ops *self)
{
  traceframe_info_up info (new traceframe_info);
  const char *name;
  struct bt_iter_pos *pos;

  gdb_assert (ctf_iter != NULL);
  /* Save the current position.  */
  pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
  gdb_assert (pos->type == BT_SEEK_RESTORE);

  do
    {
      struct bt_ctf_event *event
	= bt_ctf_iter_read_event (ctf_iter);

      name = bt_ctf_event_name (event);

      if (name == NULL || strcmp (name, "register") == 0
	  || strcmp (name, "frame") == 0)
	;
      else if (strcmp (name, "memory") == 0)
	{
	  const struct bt_definition *scope
	    = bt_ctf_get_top_level_scope (event,
					  BT_EVENT_FIELDS);
	  const struct bt_definition *def;

	  def = bt_ctf_get_field (event, scope, "address");
	  CORE_ADDR start = bt_ctf_get_uint64 (def);

	  def = bt_ctf_get_field (event, scope, "length");
	  int length = (uint16_t) bt_ctf_get_uint64 (def);

	  info->memory.emplace_back (start, length);
	}
      else if (strcmp (name, "tsv") == 0)
	{
	  int vnum;
	  const struct bt_definition *scope
	    = bt_ctf_get_top_level_scope (event,
					  BT_EVENT_FIELDS);
	  const struct bt_definition *def;

	  def = bt_ctf_get_field (event, scope, "num");
	  vnum = (int) bt_ctf_get_uint64 (def);
	  info->tvars.push_back (vnum);
	}
      else
	{
	  warning (_("Unhandled trace block type (%s) "
		     "while building trace frame info."),
		   name);
	}

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }
  while (name != NULL && strcmp (name, "frame") != 0);

  /* Restore the position.  */
  bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

  return info;
}

static void
init_ctf_ops (void)
{
  memset (&ctf_ops, 0, sizeof (ctf_ops));

  init_tracefile_ops (&ctf_ops);
  ctf_ops.to_shortname = "ctf";
  ctf_ops.to_longname = "CTF file";
  ctf_ops.to_doc = "Use a CTF directory as a target.\n\
Specify the filename of the CTF directory.";
  ctf_ops.to_open = ctf_open;
  ctf_ops.to_close = ctf_close;
  ctf_ops.to_fetch_registers = ctf_fetch_registers;
  ctf_ops.to_xfer_partial = ctf_xfer_partial;
  ctf_ops.to_files_info = ctf_files_info;
  ctf_ops.to_trace_find = ctf_trace_find;
  ctf_ops.to_get_trace_state_variable_value
    = ctf_get_trace_state_variable_value;
  ctf_ops.to_traceframe_info = ctf_traceframe_info;
}

#endif

/* module initialization */

void
_initialize_ctf (void)
{
#if HAVE_LIBBABELTRACE
  init_ctf_ops ();

  add_target_with_completer (&ctf_ops, filename_completer);
#endif
}
