Home | History | Annotate | Line # | Download | only in gdb
tracectf.c revision 1.1
      1  1.1  christos /* CTF format support.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2012-2020 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Hui Zhu <hui_zhu (at) mentor.com>
      5  1.1  christos    Contributed by Yao Qi <yao (at) codesourcery.com>
      6  1.1  christos 
      7  1.1  christos    This file is part of GDB.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos #include "defs.h"
     23  1.1  christos #include "tracectf.h"
     24  1.1  christos #include "tracepoint.h"
     25  1.1  christos #include "regcache.h"
     26  1.1  christos #include <sys/stat.h>
     27  1.1  christos #include "exec.h"
     28  1.1  christos #include "completer.h"
     29  1.1  christos #include "inferior.h"
     30  1.1  christos #include "gdbthread.h"
     31  1.1  christos #include "tracefile.h"
     32  1.1  christos #include <ctype.h>
     33  1.1  christos #include <algorithm>
     34  1.1  christos #include "gdbsupport/filestuff.h"
     35  1.1  christos #include "gdbarch.h"
     36  1.1  christos 
     37  1.1  christos /* The CTF target.  */
     38  1.1  christos 
     39  1.1  christos static const target_info ctf_target_info = {
     40  1.1  christos   "ctf",
     41  1.1  christos   N_("CTF file"),
     42  1.1  christos   N_("(Use a CTF directory as a target.\n\
     43  1.1  christos Specify the filename of the CTF directory.")
     44  1.1  christos };
     45  1.1  christos 
     46  1.1  christos class ctf_target final : public tracefile_target
     47  1.1  christos {
     48  1.1  christos public:
     49  1.1  christos   const target_info &info () const override
     50  1.1  christos   { return ctf_target_info; }
     51  1.1  christos 
     52  1.1  christos   void close () override;
     53  1.1  christos   void fetch_registers (struct regcache *, int) override;
     54  1.1  christos   enum target_xfer_status xfer_partial (enum target_object object,
     55  1.1  christos 						const char *annex,
     56  1.1  christos 						gdb_byte *readbuf,
     57  1.1  christos 						const gdb_byte *writebuf,
     58  1.1  christos 						ULONGEST offset, ULONGEST len,
     59  1.1  christos 						ULONGEST *xfered_len) override;
     60  1.1  christos   void files_info () override;
     61  1.1  christos   int trace_find (enum trace_find_type type, int num,
     62  1.1  christos 			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
     63  1.1  christos   bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
     64  1.1  christos   traceframe_info_up traceframe_info () override;
     65  1.1  christos };
     66  1.1  christos 
     67  1.1  christos /* GDB saves trace buffers and other information (such as trace
     68  1.1  christos    status) got from the remote target into Common Trace Format (CTF).
     69  1.1  christos    The following types of information are expected to save in CTF:
     70  1.1  christos 
     71  1.1  christos    1. The length (in bytes) of register cache.  Event "register" will
     72  1.1  christos    be defined in metadata, which includes the length.
     73  1.1  christos 
     74  1.1  christos    2. Trace status.  Event "status" is defined in metadata, which
     75  1.1  christos    includes all aspects of trace status.
     76  1.1  christos 
     77  1.1  christos    3. Uploaded trace variables.  Event "tsv_def" is defined in
     78  1.1  christos    metadata, which is about all aspects of a uploaded trace variable.
     79  1.1  christos    Uploaded tracepoints.   Event "tp_def" is defined in meta, which
     80  1.1  christos    is about all aspects of an uploaded tracepoint.  Note that the
     81  1.1  christos    "sequence" (a CTF type, which is a dynamically-sized array.) is
     82  1.1  christos    used for "actions" "step_actions" and "cmd_strings".
     83  1.1  christos 
     84  1.1  christos    4. Trace frames.  Each trace frame is composed by several blocks
     85  1.1  christos    of different types ('R', 'M', 'V').  One trace frame is saved in
     86  1.1  christos    one CTF packet and the blocks of this frame are saved as events.
     87  1.1  christos    4.1: The trace frame related information (such as the number of
     88  1.1  christos    tracepoint associated with this frame) is saved in the packet
     89  1.1  christos    context.
     90  1.1  christos    4.2: The block 'M', 'R' and 'V' are saved in event "memory",
     91  1.1  christos    "register" and "tsv" respectively.
     92  1.1  christos    4.3: When iterating over events, babeltrace can't tell iterator
     93  1.1  christos    goes to a new packet, so we need a marker or anchor to tell GDB
     94  1.1  christos    that iterator goes into a new packet or frame.  We define event
     95  1.1  christos    "frame".  */
     96  1.1  christos 
     97  1.1  christos #define CTF_MAGIC		0xC1FC1FC1
     98  1.1  christos #define CTF_SAVE_MAJOR		1
     99  1.1  christos #define CTF_SAVE_MINOR		8
    100  1.1  christos 
    101  1.1  christos #define CTF_METADATA_NAME	"metadata"
    102  1.1  christos #define CTF_DATASTREAM_NAME	"datastream"
    103  1.1  christos 
    104  1.1  christos /* Reserved event id.  */
    105  1.1  christos 
    106  1.1  christos #define CTF_EVENT_ID_REGISTER 0
    107  1.1  christos #define CTF_EVENT_ID_TSV 1
    108  1.1  christos #define CTF_EVENT_ID_MEMORY 2
    109  1.1  christos #define CTF_EVENT_ID_FRAME 3
    110  1.1  christos #define CTF_EVENT_ID_STATUS 4
    111  1.1  christos #define CTF_EVENT_ID_TSV_DEF 5
    112  1.1  christos #define CTF_EVENT_ID_TP_DEF 6
    113  1.1  christos 
    114  1.1  christos #define CTF_PID (2)
    115  1.1  christos 
    116  1.1  christos /* The state kept while writing the CTF datastream file.  */
    117  1.1  christos 
    118  1.1  christos struct trace_write_handler
    119  1.1  christos {
    120  1.1  christos   /* File descriptor of metadata.  */
    121  1.1  christos   FILE *metadata_fd;
    122  1.1  christos   /* File descriptor of traceframes.  */
    123  1.1  christos   FILE *datastream_fd;
    124  1.1  christos 
    125  1.1  christos   /* This is the content size of the current packet.  */
    126  1.1  christos   size_t content_size;
    127  1.1  christos 
    128  1.1  christos   /* This is the start offset of current packet.  */
    129  1.1  christos   long packet_start;
    130  1.1  christos };
    131  1.1  christos 
    132  1.1  christos /* Write metadata in FORMAT.  */
    133  1.1  christos 
    134  1.1  christos static void
    135  1.1  christos ctf_save_write_metadata (struct trace_write_handler *handler,
    136  1.1  christos 			 const char *format, ...)
    137  1.1  christos   ATTRIBUTE_PRINTF (2, 3);
    138  1.1  christos 
    139  1.1  christos static void
    140  1.1  christos ctf_save_write_metadata (struct trace_write_handler *handler,
    141  1.1  christos 			 const char *format, ...)
    142  1.1  christos {
    143  1.1  christos   va_list args;
    144  1.1  christos 
    145  1.1  christos   va_start (args, format);
    146  1.1  christos   if (vfprintf (handler->metadata_fd, format, args) < 0)
    147  1.1  christos     error (_("Unable to write metadata file (%s)"),
    148  1.1  christos 	     safe_strerror (errno));
    149  1.1  christos   va_end (args);
    150  1.1  christos }
    151  1.1  christos 
    152  1.1  christos /* Write BUF of length SIZE to datastream file represented by
    153  1.1  christos    HANDLER.  */
    154  1.1  christos 
    155  1.1  christos static int
    156  1.1  christos ctf_save_write (struct trace_write_handler *handler,
    157  1.1  christos 		const gdb_byte *buf, size_t size)
    158  1.1  christos {
    159  1.1  christos   if (fwrite (buf, size, 1, handler->datastream_fd) != 1)
    160  1.1  christos     error (_("Unable to write file for saving trace data (%s)"),
    161  1.1  christos 	   safe_strerror (errno));
    162  1.1  christos 
    163  1.1  christos   handler->content_size += size;
    164  1.1  christos 
    165  1.1  christos   return 0;
    166  1.1  christos }
    167  1.1  christos 
    168  1.1  christos /* Write a unsigned 32-bit integer to datastream file represented by
    169  1.1  christos    HANDLER.  */
    170  1.1  christos 
    171  1.1  christos #define ctf_save_write_uint32(HANDLER, U32) \
    172  1.1  christos   ctf_save_write (HANDLER, (gdb_byte *) &U32, 4)
    173  1.1  christos 
    174  1.1  christos /* Write a signed 32-bit integer to datastream file represented by
    175  1.1  christos    HANDLER.  */
    176  1.1  christos 
    177  1.1  christos #define ctf_save_write_int32(HANDLER, INT32) \
    178  1.1  christos   ctf_save_write ((HANDLER), (gdb_byte *) &(INT32), 4)
    179  1.1  christos 
    180  1.1  christos /* Set datastream file position.  Update HANDLER->content_size
    181  1.1  christos    if WHENCE is SEEK_CUR.  */
    182  1.1  christos 
    183  1.1  christos static int
    184  1.1  christos ctf_save_fseek (struct trace_write_handler *handler, long offset,
    185  1.1  christos 		int whence)
    186  1.1  christos {
    187  1.1  christos   gdb_assert (whence != SEEK_END);
    188  1.1  christos   gdb_assert (whence != SEEK_SET
    189  1.1  christos 	      || offset <= handler->content_size + handler->packet_start);
    190  1.1  christos 
    191  1.1  christos   if (fseek (handler->datastream_fd, offset, whence))
    192  1.1  christos     error (_("Unable to seek file for saving trace data (%s)"),
    193  1.1  christos 	   safe_strerror (errno));
    194  1.1  christos 
    195  1.1  christos   if (whence == SEEK_CUR)
    196  1.1  christos     handler->content_size += offset;
    197  1.1  christos 
    198  1.1  christos   return 0;
    199  1.1  christos }
    200  1.1  christos 
    201  1.1  christos /* Change the datastream file position to align on ALIGN_SIZE,
    202  1.1  christos    and write BUF to datastream file.  The size of BUF is SIZE.  */
    203  1.1  christos 
    204  1.1  christos static int
    205  1.1  christos ctf_save_align_write (struct trace_write_handler *handler,
    206  1.1  christos 		      const gdb_byte *buf,
    207  1.1  christos 		      size_t size, size_t align_size)
    208  1.1  christos {
    209  1.1  christos   long offset
    210  1.1  christos     = (align_up (handler->content_size, align_size)
    211  1.1  christos        - handler->content_size);
    212  1.1  christos 
    213  1.1  christos   if (ctf_save_fseek (handler, offset, SEEK_CUR))
    214  1.1  christos     return -1;
    215  1.1  christos 
    216  1.1  christos   if (ctf_save_write (handler, buf, size))
    217  1.1  christos     return -1;
    218  1.1  christos 
    219  1.1  christos   return 0;
    220  1.1  christos }
    221  1.1  christos 
    222  1.1  christos /* Write events to next new packet.  */
    223  1.1  christos 
    224  1.1  christos static void
    225  1.1  christos ctf_save_next_packet (struct trace_write_handler *handler)
    226  1.1  christos {
    227  1.1  christos   handler->packet_start += (handler->content_size + 4);
    228  1.1  christos   ctf_save_fseek (handler, handler->packet_start, SEEK_SET);
    229  1.1  christos   handler->content_size = 0;
    230  1.1  christos }
    231  1.1  christos 
    232  1.1  christos /* Write the CTF metadata header.  */
    233  1.1  christos 
    234  1.1  christos static void
    235  1.1  christos ctf_save_metadata_header (struct trace_write_handler *handler)
    236  1.1  christos {
    237  1.1  christos   ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
    238  1.1  christos 			   CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
    239  1.1  christos   ctf_save_write_metadata (handler,
    240  1.1  christos 			   "typealias integer { size = 8; align = 8; "
    241  1.1  christos 			   "signed = false; encoding = ascii;}"
    242  1.1  christos 			   " := ascii;\n");
    243  1.1  christos   ctf_save_write_metadata (handler,
    244  1.1  christos 			   "typealias integer { size = 8; align = 8; "
    245  1.1  christos 			   "signed = false; }"
    246  1.1  christos 			   " := uint8_t;\n");
    247  1.1  christos   ctf_save_write_metadata (handler,
    248  1.1  christos 			   "typealias integer { size = 16; align = 16;"
    249  1.1  christos 			   "signed = false; } := uint16_t;\n");
    250  1.1  christos   ctf_save_write_metadata (handler,
    251  1.1  christos 			   "typealias integer { size = 32; align = 32;"
    252  1.1  christos 			   "signed = false; } := uint32_t;\n");
    253  1.1  christos   ctf_save_write_metadata (handler,
    254  1.1  christos 			   "typealias integer { size = 64; align = 64;"
    255  1.1  christos 			   "signed = false; base = hex;}"
    256  1.1  christos 			   " := uint64_t;\n");
    257  1.1  christos   ctf_save_write_metadata (handler,
    258  1.1  christos 			   "typealias integer { size = 32; align = 32;"
    259  1.1  christos 			   "signed = true; } := int32_t;\n");
    260  1.1  christos   ctf_save_write_metadata (handler,
    261  1.1  christos 			   "typealias integer { size = 64; align = 64;"
    262  1.1  christos 			   "signed = true; } := int64_t;\n");
    263  1.1  christos   ctf_save_write_metadata (handler,
    264  1.1  christos 			   "typealias string { encoding = ascii;"
    265  1.1  christos 			   " } := chars;\n");
    266  1.1  christos   ctf_save_write_metadata (handler, "\n");
    267  1.1  christos 
    268  1.1  christos   /* Get the byte order of the host and write CTF data in this byte
    269  1.1  christos      order.  */
    270  1.1  christos #if WORDS_BIGENDIAN
    271  1.1  christos #define HOST_ENDIANNESS "be"
    272  1.1  christos #else
    273  1.1  christos #define HOST_ENDIANNESS "le"
    274  1.1  christos #endif
    275  1.1  christos 
    276  1.1  christos   ctf_save_write_metadata (handler,
    277  1.1  christos 			   "\ntrace {\n"
    278  1.1  christos 			   "	major = %u;\n"
    279  1.1  christos 			   "	minor = %u;\n"
    280  1.1  christos 			   "	byte_order = %s;\n"
    281  1.1  christos 			   "	packet.header := struct {\n"
    282  1.1  christos 			   "		uint32_t magic;\n"
    283  1.1  christos 			   "	};\n"
    284  1.1  christos 			   "};\n"
    285  1.1  christos 			   "\n"
    286  1.1  christos 			   "stream {\n"
    287  1.1  christos 			   "	packet.context := struct {\n"
    288  1.1  christos 			   "		uint32_t content_size;\n"
    289  1.1  christos 			   "		uint32_t packet_size;\n"
    290  1.1  christos 			   "		uint16_t tpnum;\n"
    291  1.1  christos 			   "	};\n"
    292  1.1  christos 			   "	event.header := struct {\n"
    293  1.1  christos 			   "		uint32_t id;\n"
    294  1.1  christos 			   "	};\n"
    295  1.1  christos 			   "};\n",
    296  1.1  christos 			   CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
    297  1.1  christos 			   HOST_ENDIANNESS);
    298  1.1  christos   ctf_save_write_metadata (handler, "\n");
    299  1.1  christos }
    300  1.1  christos 
    301  1.1  christos /* CTF trace writer.  */
    302  1.1  christos 
    303  1.1  christos struct ctf_trace_file_writer
    304  1.1  christos {
    305  1.1  christos   struct trace_file_writer base;
    306  1.1  christos 
    307  1.1  christos   /* States related to writing CTF trace file.  */
    308  1.1  christos   struct trace_write_handler tcs;
    309  1.1  christos };
    310  1.1  christos 
    311  1.1  christos /* This is the implementation of trace_file_write_ops method
    312  1.1  christos    dtor.  */
    313  1.1  christos 
    314  1.1  christos static void
    315  1.1  christos ctf_dtor (struct trace_file_writer *self)
    316  1.1  christos {
    317  1.1  christos   struct ctf_trace_file_writer *writer
    318  1.1  christos     = (struct ctf_trace_file_writer *) self;
    319  1.1  christos 
    320  1.1  christos   if (writer->tcs.metadata_fd != NULL)
    321  1.1  christos     fclose (writer->tcs.metadata_fd);
    322  1.1  christos 
    323  1.1  christos   if (writer->tcs.datastream_fd != NULL)
    324  1.1  christos     fclose (writer->tcs.datastream_fd);
    325  1.1  christos 
    326  1.1  christos }
    327  1.1  christos 
    328  1.1  christos /* This is the implementation of trace_file_write_ops method
    329  1.1  christos    target_save.  */
    330  1.1  christos 
    331  1.1  christos static int
    332  1.1  christos ctf_target_save (struct trace_file_writer *self,
    333  1.1  christos 		 const char *dirname)
    334  1.1  christos {
    335  1.1  christos   /* Don't support save trace file to CTF format in the target.  */
    336  1.1  christos   return 0;
    337  1.1  christos }
    338  1.1  christos 
    339  1.1  christos /* This is the implementation of trace_file_write_ops method
    340  1.1  christos    start.  It creates the directory DIRNAME, metadata and datastream
    341  1.1  christos    in the directory.  */
    342  1.1  christos 
    343  1.1  christos static void
    344  1.1  christos ctf_start (struct trace_file_writer *self, const char *dirname)
    345  1.1  christos {
    346  1.1  christos   struct ctf_trace_file_writer *writer
    347  1.1  christos     = (struct ctf_trace_file_writer *) self;
    348  1.1  christos   mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
    349  1.1  christos 
    350  1.1  christos   /* Create DIRNAME.  */
    351  1.1  christos   if (mkdir (dirname, hmode) && errno != EEXIST)
    352  1.1  christos     error (_("Unable to open directory '%s' for saving trace data (%s)"),
    353  1.1  christos 	   dirname, safe_strerror (errno));
    354  1.1  christos 
    355  1.1  christos   memset (&writer->tcs, '\0', sizeof (writer->tcs));
    356  1.1  christos 
    357  1.1  christos   std::string file_name = string_printf ("%s/%s", dirname, CTF_METADATA_NAME);
    358  1.1  christos 
    359  1.1  christos   writer->tcs.metadata_fd
    360  1.1  christos     = gdb_fopen_cloexec (file_name.c_str (), "w").release ();
    361  1.1  christos   if (writer->tcs.metadata_fd == NULL)
    362  1.1  christos     error (_("Unable to open file '%s' for saving trace data (%s)"),
    363  1.1  christos 	   file_name.c_str (), safe_strerror (errno));
    364  1.1  christos 
    365  1.1  christos   ctf_save_metadata_header (&writer->tcs);
    366  1.1  christos 
    367  1.1  christos   file_name = string_printf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
    368  1.1  christos   writer->tcs.datastream_fd
    369  1.1  christos     = gdb_fopen_cloexec (file_name.c_str (), "w").release ();
    370  1.1  christos   if (writer->tcs.datastream_fd == NULL)
    371  1.1  christos     error (_("Unable to open file '%s' for saving trace data (%s)"),
    372  1.1  christos 	   file_name.c_str (), safe_strerror (errno));
    373  1.1  christos }
    374  1.1  christos 
    375  1.1  christos /* This is the implementation of trace_file_write_ops method
    376  1.1  christos    write_header.  Write the types of events on trace variable and
    377  1.1  christos    frame.  */
    378  1.1  christos 
    379  1.1  christos static void
    380  1.1  christos ctf_write_header (struct trace_file_writer *self)
    381  1.1  christos {
    382  1.1  christos   struct ctf_trace_file_writer *writer
    383  1.1  christos     = (struct ctf_trace_file_writer *) self;
    384  1.1  christos 
    385  1.1  christos 
    386  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    387  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    388  1.1  christos 			   "event {\n\tname = \"memory\";\n\tid = %u;\n"
    389  1.1  christos 			   "\tfields := struct { \n"
    390  1.1  christos 			   "\t\tuint64_t address;\n"
    391  1.1  christos 			   "\t\tuint16_t length;\n"
    392  1.1  christos 			   "\t\tuint8_t contents[length];\n"
    393  1.1  christos 			   "\t};\n"
    394  1.1  christos 			   "};\n", CTF_EVENT_ID_MEMORY);
    395  1.1  christos 
    396  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    397  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    398  1.1  christos 			   "event {\n\tname = \"tsv\";\n\tid = %u;\n"
    399  1.1  christos 			   "\tfields := struct { \n"
    400  1.1  christos 			   "\t\tuint64_t val;\n"
    401  1.1  christos 			   "\t\tuint32_t num;\n"
    402  1.1  christos 			   "\t};\n"
    403  1.1  christos 			   "};\n", CTF_EVENT_ID_TSV);
    404  1.1  christos 
    405  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    406  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    407  1.1  christos 			   "event {\n\tname = \"frame\";\n\tid = %u;\n"
    408  1.1  christos 			   "\tfields := struct { \n"
    409  1.1  christos 			   "\t};\n"
    410  1.1  christos 			   "};\n", CTF_EVENT_ID_FRAME);
    411  1.1  christos 
    412  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    413  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    414  1.1  christos 			  "event {\n\tname = \"tsv_def\";\n"
    415  1.1  christos 			  "\tid = %u;\n\tfields := struct { \n"
    416  1.1  christos 			  "\t\tint64_t initial_value;\n"
    417  1.1  christos 			  "\t\tint32_t number;\n"
    418  1.1  christos 			  "\t\tint32_t builtin;\n"
    419  1.1  christos 			  "\t\tchars name;\n"
    420  1.1  christos 			  "\t};\n"
    421  1.1  christos 			  "};\n", CTF_EVENT_ID_TSV_DEF);
    422  1.1  christos 
    423  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    424  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    425  1.1  christos 			   "event {\n\tname = \"tp_def\";\n"
    426  1.1  christos 			   "\tid = %u;\n\tfields := struct { \n"
    427  1.1  christos 			   "\t\tuint64_t addr;\n"
    428  1.1  christos 			   "\t\tuint64_t traceframe_usage;\n"
    429  1.1  christos 			   "\t\tint32_t number;\n"
    430  1.1  christos 			   "\t\tint32_t enabled;\n"
    431  1.1  christos 			   "\t\tint32_t step;\n"
    432  1.1  christos 			   "\t\tint32_t pass;\n"
    433  1.1  christos 			   "\t\tint32_t hit_count;\n"
    434  1.1  christos 			   "\t\tint32_t type;\n"
    435  1.1  christos 			   "\t\tchars cond;\n"
    436  1.1  christos 
    437  1.1  christos 			  "\t\tuint32_t action_num;\n"
    438  1.1  christos 			  "\t\tchars actions[action_num];\n"
    439  1.1  christos 
    440  1.1  christos 			  "\t\tuint32_t step_action_num;\n"
    441  1.1  christos 			  "\t\tchars step_actions[step_action_num];\n"
    442  1.1  christos 
    443  1.1  christos 			  "\t\tchars at_string;\n"
    444  1.1  christos 			  "\t\tchars cond_string;\n"
    445  1.1  christos 
    446  1.1  christos 			  "\t\tuint32_t cmd_num;\n"
    447  1.1  christos 			  "\t\tchars cmd_strings[cmd_num];\n"
    448  1.1  christos 			  "\t};\n"
    449  1.1  christos 			  "};\n", CTF_EVENT_ID_TP_DEF);
    450  1.1  christos 
    451  1.1  christos   gdb_assert (writer->tcs.content_size == 0);
    452  1.1  christos   gdb_assert (writer->tcs.packet_start == 0);
    453  1.1  christos 
    454  1.1  christos   /* Create a new packet to contain this event.  */
    455  1.1  christos   self->ops->frame_ops->start (self, 0);
    456  1.1  christos }
    457  1.1  christos 
    458  1.1  christos /* This is the implementation of trace_file_write_ops method
    459  1.1  christos    write_regblock_type.  Write the type of register event in
    460  1.1  christos    metadata.  */
    461  1.1  christos 
    462  1.1  christos static void
    463  1.1  christos ctf_write_regblock_type (struct trace_file_writer *self, int size)
    464  1.1  christos {
    465  1.1  christos   struct ctf_trace_file_writer *writer
    466  1.1  christos     = (struct ctf_trace_file_writer *) self;
    467  1.1  christos 
    468  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    469  1.1  christos 
    470  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    471  1.1  christos 			   "event {\n\tname = \"register\";\n\tid = %u;\n"
    472  1.1  christos 			   "\tfields := struct { \n"
    473  1.1  christos 			   "\t\tascii contents[%d];\n"
    474  1.1  christos 			   "\t};\n"
    475  1.1  christos 			   "};\n",
    476  1.1  christos 			   CTF_EVENT_ID_REGISTER, size);
    477  1.1  christos }
    478  1.1  christos 
    479  1.1  christos /* This is the implementation of trace_file_write_ops method
    480  1.1  christos    write_status.  */
    481  1.1  christos 
    482  1.1  christos static void
    483  1.1  christos ctf_write_status (struct trace_file_writer *self,
    484  1.1  christos 		  struct trace_status *ts)
    485  1.1  christos {
    486  1.1  christos   struct ctf_trace_file_writer *writer
    487  1.1  christos     = (struct ctf_trace_file_writer *) self;
    488  1.1  christos   uint32_t id;
    489  1.1  christos 
    490  1.1  christos   ctf_save_write_metadata (&writer->tcs, "\n");
    491  1.1  christos   ctf_save_write_metadata (&writer->tcs,
    492  1.1  christos 			   "event {\n\tname = \"status\";\n\tid = %u;\n"
    493  1.1  christos 			   "\tfields := struct { \n"
    494  1.1  christos 			   "\t\tint32_t stop_reason;\n"
    495  1.1  christos 			   "\t\tint32_t stopping_tracepoint;\n"
    496  1.1  christos 			   "\t\tint32_t traceframe_count;\n"
    497  1.1  christos 			   "\t\tint32_t traceframes_created;\n"
    498  1.1  christos 			   "\t\tint32_t buffer_free;\n"
    499  1.1  christos 			   "\t\tint32_t buffer_size;\n"
    500  1.1  christos 			   "\t\tint32_t disconnected_tracing;\n"
    501  1.1  christos 			   "\t\tint32_t circular_buffer;\n"
    502  1.1  christos 			   "\t};\n"
    503  1.1  christos 			   "};\n",
    504  1.1  christos 			   CTF_EVENT_ID_STATUS);
    505  1.1  christos 
    506  1.1  christos   id = CTF_EVENT_ID_STATUS;
    507  1.1  christos   /* Event Id.  */
    508  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
    509  1.1  christos 
    510  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->stop_reason);
    511  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint);
    512  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->traceframe_count);
    513  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->traceframes_created);
    514  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->buffer_free);
    515  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->buffer_size);
    516  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing);
    517  1.1  christos   ctf_save_write_int32 (&writer->tcs, ts->circular_buffer);
    518  1.1  christos }
    519  1.1  christos 
    520  1.1  christos /* This is the implementation of trace_file_write_ops method
    521  1.1  christos    write_uploaded_tsv.  */
    522  1.1  christos 
    523  1.1  christos static void
    524  1.1  christos ctf_write_uploaded_tsv (struct trace_file_writer *self,
    525  1.1  christos 			struct uploaded_tsv *tsv)
    526  1.1  christos {
    527  1.1  christos   struct ctf_trace_file_writer *writer
    528  1.1  christos     = (struct ctf_trace_file_writer *) self;
    529  1.1  christos   int32_t int32;
    530  1.1  christos   int64_t int64;
    531  1.1  christos   const gdb_byte zero = 0;
    532  1.1  christos 
    533  1.1  christos   /* Event Id.  */
    534  1.1  christos   int32 = CTF_EVENT_ID_TSV_DEF;
    535  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
    536  1.1  christos 
    537  1.1  christos   /* initial_value */
    538  1.1  christos   int64 = tsv->initial_value;
    539  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
    540  1.1  christos 
    541  1.1  christos   /* number */
    542  1.1  christos   ctf_save_write_int32 (&writer->tcs, tsv->number);
    543  1.1  christos 
    544  1.1  christos   /* builtin */
    545  1.1  christos   ctf_save_write_int32 (&writer->tcs, tsv->builtin);
    546  1.1  christos 
    547  1.1  christos   /* name */
    548  1.1  christos   if (tsv->name != NULL)
    549  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name,
    550  1.1  christos 		    strlen (tsv->name));
    551  1.1  christos   ctf_save_write (&writer->tcs, &zero, 1);
    552  1.1  christos }
    553  1.1  christos 
    554  1.1  christos /* This is the implementation of trace_file_write_ops method
    555  1.1  christos    write_uploaded_tp.  */
    556  1.1  christos 
    557  1.1  christos static void
    558  1.1  christos ctf_write_uploaded_tp (struct trace_file_writer *self,
    559  1.1  christos 		       struct uploaded_tp *tp)
    560  1.1  christos {
    561  1.1  christos   struct ctf_trace_file_writer *writer
    562  1.1  christos     = (struct ctf_trace_file_writer *) self;
    563  1.1  christos   int32_t int32;
    564  1.1  christos   int64_t int64;
    565  1.1  christos   uint32_t u32;
    566  1.1  christos   const gdb_byte zero = 0;
    567  1.1  christos 
    568  1.1  christos   /* Event Id.  */
    569  1.1  christos   int32 = CTF_EVENT_ID_TP_DEF;
    570  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
    571  1.1  christos 
    572  1.1  christos   /* address */
    573  1.1  christos   int64 = tp->addr;
    574  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
    575  1.1  christos 
    576  1.1  christos   /* traceframe_usage */
    577  1.1  christos   int64 = tp->traceframe_usage;
    578  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
    579  1.1  christos 
    580  1.1  christos   /* number */
    581  1.1  christos   ctf_save_write_int32 (&writer->tcs, tp->number);
    582  1.1  christos 
    583  1.1  christos   /* enabled */
    584  1.1  christos   ctf_save_write_int32 (&writer->tcs, tp->enabled);
    585  1.1  christos 
    586  1.1  christos   /* step */
    587  1.1  christos   ctf_save_write_int32 (&writer->tcs, tp->step);
    588  1.1  christos 
    589  1.1  christos   /* pass */
    590  1.1  christos   ctf_save_write_int32 (&writer->tcs, tp->pass);
    591  1.1  christos 
    592  1.1  christos   /* hit_count */
    593  1.1  christos   ctf_save_write_int32 (&writer->tcs, tp->hit_count);
    594  1.1  christos 
    595  1.1  christos   /* type */
    596  1.1  christos   ctf_save_write_int32 (&writer->tcs, tp->type);
    597  1.1  christos 
    598  1.1  christos   /* condition  */
    599  1.1  christos   if (tp->cond != NULL)
    600  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond.get (),
    601  1.1  christos 		    strlen (tp->cond.get ()));
    602  1.1  christos   ctf_save_write (&writer->tcs, &zero, 1);
    603  1.1  christos 
    604  1.1  christos   /* actions */
    605  1.1  christos   u32 = tp->actions.size ();
    606  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
    607  1.1  christos   for (const auto &act : tp->actions)
    608  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
    609  1.1  christos 		    strlen (act.get ()) + 1);
    610  1.1  christos 
    611  1.1  christos   /* step_actions */
    612  1.1  christos   u32 = tp->step_actions.size ();
    613  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
    614  1.1  christos   for (const auto &act : tp->step_actions)
    615  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
    616  1.1  christos 		    strlen (act.get ()) + 1);
    617  1.1  christos 
    618  1.1  christos   /* at_string */
    619  1.1  christos   if (tp->at_string != NULL)
    620  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string.get (),
    621  1.1  christos 		    strlen (tp->at_string.get ()));
    622  1.1  christos   ctf_save_write (&writer->tcs, &zero, 1);
    623  1.1  christos 
    624  1.1  christos   /* cond_string */
    625  1.1  christos   if (tp->cond_string != NULL)
    626  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string.get (),
    627  1.1  christos 		    strlen (tp->cond_string.get ()));
    628  1.1  christos   ctf_save_write (&writer->tcs, &zero, 1);
    629  1.1  christos 
    630  1.1  christos   /* cmd_strings */
    631  1.1  christos   u32 = tp->cmd_strings.size ();
    632  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
    633  1.1  christos   for (const auto &act : tp->cmd_strings)
    634  1.1  christos     ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
    635  1.1  christos 		    strlen (act.get ()) + 1);
    636  1.1  christos 
    637  1.1  christos }
    638  1.1  christos 
    639  1.1  christos /* This is the implementation of trace_file_write_ops method
    640  1.1  christos    write_tdesc.  */
    641  1.1  christos 
    642  1.1  christos static void
    643  1.1  christos ctf_write_tdesc (struct trace_file_writer *self)
    644  1.1  christos {
    645  1.1  christos   /* Nothing so far. */
    646  1.1  christos }
    647  1.1  christos 
    648  1.1  christos /* This is the implementation of trace_file_write_ops method
    649  1.1  christos    write_definition_end.  */
    650  1.1  christos 
    651  1.1  christos static void
    652  1.1  christos ctf_write_definition_end (struct trace_file_writer *self)
    653  1.1  christos {
    654  1.1  christos   self->ops->frame_ops->end (self);
    655  1.1  christos }
    656  1.1  christos 
    657  1.1  christos /* This is the implementation of trace_file_write_ops method
    658  1.1  christos    end.  */
    659  1.1  christos 
    660  1.1  christos static void
    661  1.1  christos ctf_end (struct trace_file_writer *self)
    662  1.1  christos {
    663  1.1  christos   struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;
    664  1.1  christos 
    665  1.1  christos   gdb_assert (writer->tcs.content_size == 0);
    666  1.1  christos }
    667  1.1  christos 
    668  1.1  christos /* This is the implementation of trace_frame_write_ops method
    669  1.1  christos    start.  */
    670  1.1  christos 
    671  1.1  christos static void
    672  1.1  christos ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
    673  1.1  christos {
    674  1.1  christos   struct ctf_trace_file_writer *writer
    675  1.1  christos     = (struct ctf_trace_file_writer *) self;
    676  1.1  christos   uint32_t id = CTF_EVENT_ID_FRAME;
    677  1.1  christos   uint32_t u32;
    678  1.1  christos 
    679  1.1  christos   /* Step 1: Write packet context.  */
    680  1.1  christos   /* magic.  */
    681  1.1  christos   u32 = CTF_MAGIC;
    682  1.1  christos   ctf_save_write_uint32 (&writer->tcs, u32);
    683  1.1  christos   /* content_size and packet_size..  We still don't know the value,
    684  1.1  christos      write it later.  */
    685  1.1  christos   ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
    686  1.1  christos   ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
    687  1.1  christos   /* Tracepoint number.  */
    688  1.1  christos   ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);
    689  1.1  christos 
    690  1.1  christos   /* Step 2: Write event "frame".  */
    691  1.1  christos   /* Event Id.  */
    692  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
    693  1.1  christos }
    694  1.1  christos 
    695  1.1  christos /* This is the implementation of trace_frame_write_ops method
    696  1.1  christos    write_r_block.  */
    697  1.1  christos 
    698  1.1  christos static void
    699  1.1  christos ctf_write_frame_r_block (struct trace_file_writer *self,
    700  1.1  christos 			 gdb_byte *buf, int32_t size)
    701  1.1  christos {
    702  1.1  christos   struct ctf_trace_file_writer *writer
    703  1.1  christos     = (struct ctf_trace_file_writer *) self;
    704  1.1  christos   uint32_t id = CTF_EVENT_ID_REGISTER;
    705  1.1  christos 
    706  1.1  christos   /* Event Id.  */
    707  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
    708  1.1  christos 
    709  1.1  christos   /* array contents.  */
    710  1.1  christos   ctf_save_align_write (&writer->tcs, buf, size, 1);
    711  1.1  christos }
    712  1.1  christos 
    713  1.1  christos /* This is the implementation of trace_frame_write_ops method
    714  1.1  christos    write_m_block_header.  */
    715  1.1  christos 
    716  1.1  christos static void
    717  1.1  christos ctf_write_frame_m_block_header (struct trace_file_writer *self,
    718  1.1  christos 				uint64_t addr, uint16_t length)
    719  1.1  christos {
    720  1.1  christos   struct ctf_trace_file_writer *writer
    721  1.1  christos     = (struct ctf_trace_file_writer *) self;
    722  1.1  christos   uint32_t event_id = CTF_EVENT_ID_MEMORY;
    723  1.1  christos 
    724  1.1  christos   /* Event Id.  */
    725  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);
    726  1.1  christos 
    727  1.1  christos   /* Address.  */
    728  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);
    729  1.1  christos 
    730  1.1  christos   /* Length.  */
    731  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
    732  1.1  christos }
    733  1.1  christos 
    734  1.1  christos /* This is the implementation of trace_frame_write_ops method
    735  1.1  christos    write_m_block_memory.  */
    736  1.1  christos 
    737  1.1  christos static void
    738  1.1  christos ctf_write_frame_m_block_memory (struct trace_file_writer *self,
    739  1.1  christos 				gdb_byte *buf, uint16_t length)
    740  1.1  christos {
    741  1.1  christos   struct ctf_trace_file_writer *writer
    742  1.1  christos     = (struct ctf_trace_file_writer *) self;
    743  1.1  christos 
    744  1.1  christos   /* Contents.  */
    745  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
    746  1.1  christos }
    747  1.1  christos 
    748  1.1  christos /* This is the implementation of trace_frame_write_ops method
    749  1.1  christos    write_v_block.  */
    750  1.1  christos 
    751  1.1  christos static void
    752  1.1  christos ctf_write_frame_v_block (struct trace_file_writer *self,
    753  1.1  christos 			 int32_t num, uint64_t val)
    754  1.1  christos {
    755  1.1  christos   struct ctf_trace_file_writer *writer
    756  1.1  christos     = (struct ctf_trace_file_writer *) self;
    757  1.1  christos   uint32_t id = CTF_EVENT_ID_TSV;
    758  1.1  christos 
    759  1.1  christos   /* Event Id.  */
    760  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
    761  1.1  christos 
    762  1.1  christos   /* val.  */
    763  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
    764  1.1  christos   /* num.  */
    765  1.1  christos   ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
    766  1.1  christos }
    767  1.1  christos 
    768  1.1  christos /* This is the implementation of trace_frame_write_ops method
    769  1.1  christos    end.  */
    770  1.1  christos 
    771  1.1  christos static void
    772  1.1  christos ctf_write_frame_end (struct trace_file_writer *self)
    773  1.1  christos {
    774  1.1  christos   struct ctf_trace_file_writer *writer
    775  1.1  christos     = (struct ctf_trace_file_writer *) self;
    776  1.1  christos   uint32_t u32;
    777  1.1  christos   uint32_t t;
    778  1.1  christos 
    779  1.1  christos   /* Write the content size to packet header.  */
    780  1.1  christos   ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
    781  1.1  christos 		  SEEK_SET);
    782  1.1  christos   u32 = writer->tcs.content_size * TARGET_CHAR_BIT;
    783  1.1  christos 
    784  1.1  christos   t = writer->tcs.content_size;
    785  1.1  christos   ctf_save_write_uint32 (&writer->tcs, u32);
    786  1.1  christos 
    787  1.1  christos   /* Write the packet size.  */
    788  1.1  christos   u32 += 4 * TARGET_CHAR_BIT;
    789  1.1  christos   ctf_save_write_uint32 (&writer->tcs, u32);
    790  1.1  christos 
    791  1.1  christos   writer->tcs.content_size = t;
    792  1.1  christos 
    793  1.1  christos   /* Write zero at the end of the packet.  */
    794  1.1  christos   ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
    795  1.1  christos 		  SEEK_SET);
    796  1.1  christos   u32 = 0;
    797  1.1  christos   ctf_save_write_uint32 (&writer->tcs, u32);
    798  1.1  christos   writer->tcs.content_size = t;
    799  1.1  christos 
    800  1.1  christos   ctf_save_next_packet (&writer->tcs);
    801  1.1  christos }
    802  1.1  christos 
    803  1.1  christos /* Operations to write various types of trace frames into CTF
    804  1.1  christos    format.  */
    805  1.1  christos 
    806  1.1  christos static const struct trace_frame_write_ops ctf_write_frame_ops =
    807  1.1  christos {
    808  1.1  christos   ctf_write_frame_start,
    809  1.1  christos   ctf_write_frame_r_block,
    810  1.1  christos   ctf_write_frame_m_block_header,
    811  1.1  christos   ctf_write_frame_m_block_memory,
    812  1.1  christos   ctf_write_frame_v_block,
    813  1.1  christos   ctf_write_frame_end,
    814  1.1  christos };
    815  1.1  christos 
    816  1.1  christos /* Operations to write trace buffers into CTF format.  */
    817  1.1  christos 
    818  1.1  christos static const struct trace_file_write_ops ctf_write_ops =
    819  1.1  christos {
    820  1.1  christos   ctf_dtor,
    821  1.1  christos   ctf_target_save,
    822  1.1  christos   ctf_start,
    823  1.1  christos   ctf_write_header,
    824  1.1  christos   ctf_write_regblock_type,
    825  1.1  christos   ctf_write_status,
    826  1.1  christos   ctf_write_uploaded_tsv,
    827  1.1  christos   ctf_write_uploaded_tp,
    828  1.1  christos   ctf_write_tdesc,
    829  1.1  christos   ctf_write_definition_end,
    830  1.1  christos   NULL,
    831  1.1  christos   &ctf_write_frame_ops,
    832  1.1  christos   ctf_end,
    833  1.1  christos };
    834  1.1  christos 
    835  1.1  christos /* Return a trace writer for CTF format.  */
    836  1.1  christos 
    837  1.1  christos struct trace_file_writer *
    838  1.1  christos ctf_trace_file_writer_new (void)
    839  1.1  christos {
    840  1.1  christos   struct ctf_trace_file_writer *writer = XNEW (struct ctf_trace_file_writer);
    841  1.1  christos 
    842  1.1  christos   writer->base.ops = &ctf_write_ops;
    843  1.1  christos 
    844  1.1  christos   return (struct trace_file_writer *) writer;
    845  1.1  christos }
    846  1.1  christos 
    847  1.1  christos #if HAVE_LIBBABELTRACE
    848  1.1  christos /* Use libbabeltrace to read CTF data.  The libbabeltrace provides
    849  1.1  christos    iterator to iterate over each event in CTF data and APIs to get
    850  1.1  christos    details of event and packet, so it is very convenient to use
    851  1.1  christos    libbabeltrace to access events in CTF.  */
    852  1.1  christos 
    853  1.1  christos #include <babeltrace/babeltrace.h>
    854  1.1  christos #include <babeltrace/ctf/events.h>
    855  1.1  christos #include <babeltrace/ctf/iterator.h>
    856  1.1  christos 
    857  1.1  christos /* The struct pointer for current CTF directory.  */
    858  1.1  christos static int handle_id = -1;
    859  1.1  christos static struct bt_context *ctx = NULL;
    860  1.1  christos static struct bt_ctf_iter *ctf_iter = NULL;
    861  1.1  christos /* The position of the first packet containing trace frame.  */
    862  1.1  christos static struct bt_iter_pos *start_pos;
    863  1.1  christos 
    864  1.1  christos /* The name of CTF directory.  */
    865  1.1  christos static char *trace_dirname;
    866  1.1  christos 
    867  1.1  christos static ctf_target ctf_ops;
    868  1.1  christos 
    869  1.1  christos /* Destroy ctf iterator and context.  */
    870  1.1  christos 
    871  1.1  christos static void
    872  1.1  christos ctf_destroy (void)
    873  1.1  christos {
    874  1.1  christos   if (ctf_iter != NULL)
    875  1.1  christos     {
    876  1.1  christos       bt_ctf_iter_destroy (ctf_iter);
    877  1.1  christos       ctf_iter = NULL;
    878  1.1  christos     }
    879  1.1  christos   if (ctx != NULL)
    880  1.1  christos     {
    881  1.1  christos       bt_context_put (ctx);
    882  1.1  christos       ctx = NULL;
    883  1.1  christos     }
    884  1.1  christos }
    885  1.1  christos 
    886  1.1  christos /* Open CTF trace data in DIRNAME.  */
    887  1.1  christos 
    888  1.1  christos static void
    889  1.1  christos ctf_open_dir (const char *dirname)
    890  1.1  christos {
    891  1.1  christos   struct bt_iter_pos begin_pos;
    892  1.1  christos   unsigned int count, i;
    893  1.1  christos   struct bt_ctf_event_decl * const *list;
    894  1.1  christos 
    895  1.1  christos   ctx = bt_context_create ();
    896  1.1  christos   if (ctx == NULL)
    897  1.1  christos     error (_("Unable to create bt_context"));
    898  1.1  christos   handle_id = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
    899  1.1  christos   if (handle_id < 0)
    900  1.1  christos     {
    901  1.1  christos       ctf_destroy ();
    902  1.1  christos       error (_("Unable to use libbabeltrace on directory \"%s\""),
    903  1.1  christos 	     dirname);
    904  1.1  christos     }
    905  1.1  christos 
    906  1.1  christos   begin_pos.type = BT_SEEK_BEGIN;
    907  1.1  christos   ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
    908  1.1  christos   if (ctf_iter == NULL)
    909  1.1  christos     {
    910  1.1  christos       ctf_destroy ();
    911  1.1  christos       error (_("Unable to create bt_iterator"));
    912  1.1  christos     }
    913  1.1  christos 
    914  1.1  christos   /* Look for the declaration of register block.  Get the length of
    915  1.1  christos      array "contents" to set trace_regblock_size.  */
    916  1.1  christos 
    917  1.1  christos   bt_ctf_get_event_decl_list (handle_id, ctx, &list, &count);
    918  1.1  christos   for (i = 0; i < count; i++)
    919  1.1  christos     if (strcmp ("register", bt_ctf_get_decl_event_name (list[i])) == 0)
    920  1.1  christos       {
    921  1.1  christos 	const struct bt_ctf_field_decl * const *field_list;
    922  1.1  christos 	const struct bt_declaration *decl;
    923  1.1  christos 
    924  1.1  christos 	bt_ctf_get_decl_fields (list[i], BT_EVENT_FIELDS, &field_list,
    925  1.1  christos 				&count);
    926  1.1  christos 
    927  1.1  christos 	gdb_assert (count == 1);
    928  1.1  christos 	gdb_assert (0 == strcmp ("contents",
    929  1.1  christos 				 bt_ctf_get_decl_field_name (field_list[0])));
    930  1.1  christos 	decl = bt_ctf_get_decl_from_field_decl (field_list[0]);
    931  1.1  christos 	trace_regblock_size = bt_ctf_get_array_len (decl);
    932  1.1  christos 
    933  1.1  christos 	break;
    934  1.1  christos       }
    935  1.1  christos }
    936  1.1  christos 
    937  1.1  christos #define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD)			\
    938  1.1  christos   (VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT),	\
    939  1.1  christos 							   (SCOPE),	\
    940  1.1  christos 							   #FIELD))
    941  1.1  christos 
    942  1.1  christos #define SET_ENUM_FIELD(EVENT, SCOPE, VAR, TYPE, FIELD)			\
    943  1.1  christos   (VAR)->FIELD = (TYPE) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT),	\
    944  1.1  christos 							    (SCOPE),	\
    945  1.1  christos 							    #FIELD))
    946  1.1  christos 
    947  1.1  christos 
    948  1.1  christos /* EVENT is the "status" event and TS is filled in.  */
    949  1.1  christos 
    950  1.1  christos static void
    951  1.1  christos ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
    952  1.1  christos {
    953  1.1  christos   const struct bt_definition *scope
    954  1.1  christos     = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS);
    955  1.1  christos 
    956  1.1  christos   SET_ENUM_FIELD (event, scope, ts, enum trace_stop_reason, stop_reason);
    957  1.1  christos   SET_INT32_FIELD (event, scope, ts, stopping_tracepoint);
    958  1.1  christos   SET_INT32_FIELD (event, scope, ts, traceframe_count);
    959  1.1  christos   SET_INT32_FIELD (event, scope, ts, traceframes_created);
    960  1.1  christos   SET_INT32_FIELD (event, scope, ts, buffer_free);
    961  1.1  christos   SET_INT32_FIELD (event, scope, ts, buffer_size);
    962  1.1  christos   SET_INT32_FIELD (event, scope, ts, disconnected_tracing);
    963  1.1  christos   SET_INT32_FIELD (event, scope, ts, circular_buffer);
    964  1.1  christos 
    965  1.1  christos   bt_iter_next (bt_ctf_get_iter (ctf_iter));
    966  1.1  christos }
    967  1.1  christos 
    968  1.1  christos /* Read the events "tsv_def" one by one, extract its contents and fill
    969  1.1  christos    in the list UPLOADED_TSVS.  */
    970  1.1  christos 
    971  1.1  christos static void
    972  1.1  christos ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
    973  1.1  christos {
    974  1.1  christos   gdb_assert (ctf_iter != NULL);
    975  1.1  christos 
    976  1.1  christos   while (1)
    977  1.1  christos     {
    978  1.1  christos       struct bt_ctf_event *event;
    979  1.1  christos       const struct bt_definition *scope;
    980  1.1  christos       const struct bt_definition *def;
    981  1.1  christos       uint32_t event_id;
    982  1.1  christos       struct uploaded_tsv *utsv = NULL;
    983  1.1  christos 
    984  1.1  christos       event = bt_ctf_iter_read_event (ctf_iter);
    985  1.1  christos       scope = bt_ctf_get_top_level_scope (event,
    986  1.1  christos 					  BT_STREAM_EVENT_HEADER);
    987  1.1  christos       event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
    988  1.1  christos 						      "id"));
    989  1.1  christos       if (event_id != CTF_EVENT_ID_TSV_DEF)
    990  1.1  christos 	break;
    991  1.1  christos 
    992  1.1  christos       scope = bt_ctf_get_top_level_scope (event,
    993  1.1  christos 					  BT_EVENT_FIELDS);
    994  1.1  christos 
    995  1.1  christos       def = bt_ctf_get_field (event, scope, "number");
    996  1.1  christos       utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
    997  1.1  christos 			       uploaded_tsvs);
    998  1.1  christos 
    999  1.1  christos       def = bt_ctf_get_field (event, scope, "builtin");
   1000  1.1  christos       utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
   1001  1.1  christos       def = bt_ctf_get_field (event, scope, "initial_value");
   1002  1.1  christos       utsv->initial_value = bt_ctf_get_int64 (def);
   1003  1.1  christos 
   1004  1.1  christos       def = bt_ctf_get_field (event, scope, "name");
   1005  1.1  christos       utsv->name =  xstrdup (bt_ctf_get_string (def));
   1006  1.1  christos 
   1007  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1008  1.1  christos 	break;
   1009  1.1  christos     }
   1010  1.1  christos 
   1011  1.1  christos }
   1012  1.1  christos 
   1013  1.1  christos /* Read the value of element whose index is NUM from CTF and write it
   1014  1.1  christos    to the corresponding VAR->ARRAY. */
   1015  1.1  christos 
   1016  1.1  christos #define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY)	\
   1017  1.1  christos   do							\
   1018  1.1  christos     {							\
   1019  1.1  christos       uint32_t lu32, i;						\
   1020  1.1  christos       const struct bt_definition *def;				\
   1021  1.1  christos 								\
   1022  1.1  christos       lu32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT),	\
   1023  1.1  christos 							     (SCOPE),	\
   1024  1.1  christos 							     #NUM));	\
   1025  1.1  christos       def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY);		\
   1026  1.1  christos       for (i = 0; i < lu32; i++)					\
   1027  1.1  christos 	{								\
   1028  1.1  christos 	  const struct bt_definition *element				\
   1029  1.1  christos 	    = bt_ctf_get_index ((EVENT), def, i);			\
   1030  1.1  christos 									\
   1031  1.1  christos 	  (VAR)->ARRAY.emplace_back					\
   1032  1.1  christos 	    (xstrdup (bt_ctf_get_string (element)));			\
   1033  1.1  christos 	}								\
   1034  1.1  christos     }									\
   1035  1.1  christos   while (0)
   1036  1.1  christos 
   1037  1.1  christos /* Read a string from CTF and set VAR->FIELD. If the length of string
   1038  1.1  christos    is zero, set VAR->FIELD to NULL.  */
   1039  1.1  christos 
   1040  1.1  christos #define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD)			\
   1041  1.1  christos   do									\
   1042  1.1  christos     {									\
   1043  1.1  christos       const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT),	\
   1044  1.1  christos 							   (SCOPE),	\
   1045  1.1  christos 							   #FIELD));	\
   1046  1.1  christos 									\
   1047  1.1  christos       if (strlen (p) > 0)						\
   1048  1.1  christos 	(VAR)->FIELD.reset (xstrdup (p));				\
   1049  1.1  christos       else								\
   1050  1.1  christos 	(VAR)->FIELD = NULL;						\
   1051  1.1  christos     }									\
   1052  1.1  christos   while (0)
   1053  1.1  christos 
   1054  1.1  christos /* Read the events "tp_def" one by one, extract its contents and fill
   1055  1.1  christos    in the list UPLOADED_TPS.  */
   1056  1.1  christos 
   1057  1.1  christos static void
   1058  1.1  christos ctf_read_tp (struct uploaded_tp **uploaded_tps)
   1059  1.1  christos {
   1060  1.1  christos   gdb_assert (ctf_iter != NULL);
   1061  1.1  christos 
   1062  1.1  christos   while (1)
   1063  1.1  christos     {
   1064  1.1  christos       struct bt_ctf_event *event;
   1065  1.1  christos       const struct bt_definition *scope;
   1066  1.1  christos       uint32_t u32;
   1067  1.1  christos       int32_t int32;
   1068  1.1  christos       uint64_t u64;
   1069  1.1  christos       struct uploaded_tp *utp = NULL;
   1070  1.1  christos 
   1071  1.1  christos       event = bt_ctf_iter_read_event (ctf_iter);
   1072  1.1  christos       scope = bt_ctf_get_top_level_scope (event,
   1073  1.1  christos 					  BT_STREAM_EVENT_HEADER);
   1074  1.1  christos       u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
   1075  1.1  christos 						 "id"));
   1076  1.1  christos       if (u32 != CTF_EVENT_ID_TP_DEF)
   1077  1.1  christos 	break;
   1078  1.1  christos 
   1079  1.1  christos       scope = bt_ctf_get_top_level_scope (event,
   1080  1.1  christos 					  BT_EVENT_FIELDS);
   1081  1.1  christos       int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event,
   1082  1.1  christos 							    scope,
   1083  1.1  christos 							    "number"));
   1084  1.1  christos       u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
   1085  1.1  christos 						 "addr"));
   1086  1.1  christos       utp = get_uploaded_tp (int32, u64,  uploaded_tps);
   1087  1.1  christos 
   1088  1.1  christos       SET_INT32_FIELD (event, scope, utp, enabled);
   1089  1.1  christos       SET_INT32_FIELD (event, scope, utp, step);
   1090  1.1  christos       SET_INT32_FIELD (event, scope, utp, pass);
   1091  1.1  christos       SET_INT32_FIELD (event, scope, utp, hit_count);
   1092  1.1  christos       SET_ENUM_FIELD (event, scope, utp, enum bptype, type);
   1093  1.1  christos 
   1094  1.1  christos       /* Read 'cmd_strings'.  */
   1095  1.1  christos       SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings);
   1096  1.1  christos       /* Read 'actions'.  */
   1097  1.1  christos       SET_ARRAY_FIELD (event, scope, utp, action_num, actions);
   1098  1.1  christos       /* Read 'step_actions'.  */
   1099  1.1  christos       SET_ARRAY_FIELD (event, scope, utp, step_action_num,
   1100  1.1  christos 		       step_actions);
   1101  1.1  christos 
   1102  1.1  christos       SET_STRING_FIELD(event, scope, utp, at_string);
   1103  1.1  christos       SET_STRING_FIELD(event, scope, utp, cond_string);
   1104  1.1  christos 
   1105  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1106  1.1  christos 	break;
   1107  1.1  christos     }
   1108  1.1  christos }
   1109  1.1  christos 
   1110  1.1  christos /* This is the implementation of target_ops method to_open.  Open CTF
   1111  1.1  christos    trace data, read trace status, trace state variables and tracepoint
   1112  1.1  christos    definitions from the first packet.  Set the start position at the
   1113  1.1  christos    second packet which contains events on trace blocks.  */
   1114  1.1  christos 
   1115  1.1  christos static void
   1116  1.1  christos ctf_target_open (const char *dirname, int from_tty)
   1117  1.1  christos {
   1118  1.1  christos   struct bt_ctf_event *event;
   1119  1.1  christos   uint32_t event_id;
   1120  1.1  christos   const struct bt_definition *scope;
   1121  1.1  christos   struct uploaded_tsv *uploaded_tsvs = NULL;
   1122  1.1  christos   struct uploaded_tp *uploaded_tps = NULL;
   1123  1.1  christos 
   1124  1.1  christos   if (!dirname)
   1125  1.1  christos     error (_("No CTF directory specified."));
   1126  1.1  christos 
   1127  1.1  christos   ctf_open_dir (dirname);
   1128  1.1  christos 
   1129  1.1  christos   target_preopen (from_tty);
   1130  1.1  christos 
   1131  1.1  christos   /* Skip the first packet which about the trace status.  The first
   1132  1.1  christos      event is "frame".  */
   1133  1.1  christos   event = bt_ctf_iter_read_event (ctf_iter);
   1134  1.1  christos   scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
   1135  1.1  christos   event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
   1136  1.1  christos   if (event_id != CTF_EVENT_ID_FRAME)
   1137  1.1  christos     error (_("Wrong event id of the first event"));
   1138  1.1  christos   /* The second event is "status".  */
   1139  1.1  christos   bt_iter_next (bt_ctf_get_iter (ctf_iter));
   1140  1.1  christos   event = bt_ctf_iter_read_event (ctf_iter);
   1141  1.1  christos   scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
   1142  1.1  christos   event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
   1143  1.1  christos   if (event_id != CTF_EVENT_ID_STATUS)
   1144  1.1  christos     error (_("Wrong event id of the second event"));
   1145  1.1  christos   ctf_read_status (event, current_trace_status ());
   1146  1.1  christos 
   1147  1.1  christos   ctf_read_tsv (&uploaded_tsvs);
   1148  1.1  christos 
   1149  1.1  christos   ctf_read_tp (&uploaded_tps);
   1150  1.1  christos 
   1151  1.1  christos   event = bt_ctf_iter_read_event (ctf_iter);
   1152  1.1  christos   /* EVENT can be NULL if we've already gone to the end of stream of
   1153  1.1  christos      events.  */
   1154  1.1  christos   if (event != NULL)
   1155  1.1  christos     {
   1156  1.1  christos       scope = bt_ctf_get_top_level_scope (event,
   1157  1.1  christos 					  BT_STREAM_EVENT_HEADER);
   1158  1.1  christos       event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event,
   1159  1.1  christos 						      scope, "id"));
   1160  1.1  christos       if (event_id != CTF_EVENT_ID_FRAME)
   1161  1.1  christos 	error (_("Wrong event id of the first event of the second packet"));
   1162  1.1  christos     }
   1163  1.1  christos 
   1164  1.1  christos   start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
   1165  1.1  christos   gdb_assert (start_pos->type == BT_SEEK_RESTORE);
   1166  1.1  christos 
   1167  1.1  christos   trace_dirname = xstrdup (dirname);
   1168  1.1  christos   push_target (&ctf_ops);
   1169  1.1  christos 
   1170  1.1  christos   inferior_appeared (current_inferior (), CTF_PID);
   1171  1.1  christos 
   1172  1.1  christos   thread_info *thr = add_thread_silent (&ctf_ops, ptid_t (CTF_PID));
   1173  1.1  christos   switch_to_thread (thr);
   1174  1.1  christos 
   1175  1.1  christos   merge_uploaded_trace_state_variables (&uploaded_tsvs);
   1176  1.1  christos   merge_uploaded_tracepoints (&uploaded_tps);
   1177  1.1  christos 
   1178  1.1  christos   post_create_inferior (&ctf_ops, from_tty);
   1179  1.1  christos }
   1180  1.1  christos 
   1181  1.1  christos /* This is the implementation of target_ops method to_close.  Destroy
   1182  1.1  christos    CTF iterator and context.  */
   1183  1.1  christos 
   1184  1.1  christos void
   1185  1.1  christos ctf_target::close ()
   1186  1.1  christos {
   1187  1.1  christos   ctf_destroy ();
   1188  1.1  christos   xfree (trace_dirname);
   1189  1.1  christos   trace_dirname = NULL;
   1190  1.1  christos 
   1191  1.1  christos   switch_to_no_thread ();	/* Avoid confusion from thread stuff.  */
   1192  1.1  christos   exit_inferior_silent (current_inferior ());
   1193  1.1  christos 
   1194  1.1  christos   trace_reset_local_state ();
   1195  1.1  christos }
   1196  1.1  christos 
   1197  1.1  christos /* This is the implementation of target_ops method to_files_info.
   1198  1.1  christos    Print the directory name of CTF trace data.  */
   1199  1.1  christos 
   1200  1.1  christos void
   1201  1.1  christos ctf_target::files_info ()
   1202  1.1  christos {
   1203  1.1  christos   printf_filtered ("\t`%s'\n", trace_dirname);
   1204  1.1  christos }
   1205  1.1  christos 
   1206  1.1  christos /* This is the implementation of target_ops method to_fetch_registers.
   1207  1.1  christos    Iterate over events whose name is "register" in current frame,
   1208  1.1  christos    extract contents from events, and set REGCACHE with the contents.
   1209  1.1  christos    If no matched events are found, mark registers unavailable.  */
   1210  1.1  christos 
   1211  1.1  christos void
   1212  1.1  christos ctf_target::fetch_registers (struct regcache *regcache, int regno)
   1213  1.1  christos {
   1214  1.1  christos   struct gdbarch *gdbarch = regcache->arch ();
   1215  1.1  christos   struct bt_ctf_event *event = NULL;
   1216  1.1  christos   struct bt_iter_pos *pos;
   1217  1.1  christos 
   1218  1.1  christos   /* An uninitialized reg size says we're not going to be
   1219  1.1  christos      successful at getting register blocks.  */
   1220  1.1  christos   if (trace_regblock_size == 0)
   1221  1.1  christos     return;
   1222  1.1  christos 
   1223  1.1  christos   gdb_assert (ctf_iter != NULL);
   1224  1.1  christos   /* Save the current position.  */
   1225  1.1  christos   pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
   1226  1.1  christos   gdb_assert (pos->type == BT_SEEK_RESTORE);
   1227  1.1  christos 
   1228  1.1  christos   while (1)
   1229  1.1  christos     {
   1230  1.1  christos       const char *name;
   1231  1.1  christos       struct bt_ctf_event *event1;
   1232  1.1  christos 
   1233  1.1  christos       event1 = bt_ctf_iter_read_event (ctf_iter);
   1234  1.1  christos 
   1235  1.1  christos       name = bt_ctf_event_name (event1);
   1236  1.1  christos 
   1237  1.1  christos       if (name == NULL || strcmp (name, "frame") == 0)
   1238  1.1  christos 	break;
   1239  1.1  christos       else if (strcmp (name, "register") == 0)
   1240  1.1  christos 	{
   1241  1.1  christos 	  event = event1;
   1242  1.1  christos 	  break;
   1243  1.1  christos 	}
   1244  1.1  christos 
   1245  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1246  1.1  christos 	break;
   1247  1.1  christos     }
   1248  1.1  christos 
   1249  1.1  christos   /* Restore the position.  */
   1250  1.1  christos   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
   1251  1.1  christos 
   1252  1.1  christos   if (event != NULL)
   1253  1.1  christos     {
   1254  1.1  christos       int offset, regsize, regn;
   1255  1.1  christos       const struct bt_definition *scope
   1256  1.1  christos 	= bt_ctf_get_top_level_scope (event,
   1257  1.1  christos 				      BT_EVENT_FIELDS);
   1258  1.1  christos       const struct bt_definition *array
   1259  1.1  christos 	= bt_ctf_get_field (event, scope, "contents");
   1260  1.1  christos       gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);
   1261  1.1  christos 
   1262  1.1  christos       /* Assume the block is laid out in GDB register number order,
   1263  1.1  christos 	 each register with the size that it has in GDB.  */
   1264  1.1  christos       offset = 0;
   1265  1.1  christos       for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
   1266  1.1  christos 	{
   1267  1.1  christos 	  regsize = register_size (gdbarch, regn);
   1268  1.1  christos 	  /* Make sure we stay within block bounds.  */
   1269  1.1  christos 	  if (offset + regsize >= trace_regblock_size)
   1270  1.1  christos 	    break;
   1271  1.1  christos 	  if (regcache->get_register_status (regn) == REG_UNKNOWN)
   1272  1.1  christos 	    {
   1273  1.1  christos 	      if (regno == regn)
   1274  1.1  christos 		{
   1275  1.1  christos 		  regcache->raw_supply (regno, regs + offset);
   1276  1.1  christos 		  break;
   1277  1.1  christos 		}
   1278  1.1  christos 	      else if (regno == -1)
   1279  1.1  christos 		{
   1280  1.1  christos 		  regcache->raw_supply (regn, regs + offset);
   1281  1.1  christos 		}
   1282  1.1  christos 	    }
   1283  1.1  christos 	  offset += regsize;
   1284  1.1  christos 	}
   1285  1.1  christos     }
   1286  1.1  christos   else
   1287  1.1  christos     tracefile_fetch_registers (regcache, regno);
   1288  1.1  christos }
   1289  1.1  christos 
   1290  1.1  christos /* This is the implementation of target_ops method to_xfer_partial.
   1291  1.1  christos    Iterate over events whose name is "memory" in
   1292  1.1  christos    current frame, extract the address and length from events.  If
   1293  1.1  christos    OFFSET is within the range, read the contents from events to
   1294  1.1  christos    READBUF.  */
   1295  1.1  christos 
   1296  1.1  christos enum target_xfer_status
   1297  1.1  christos ctf_target::xfer_partial (enum target_object object,
   1298  1.1  christos 			  const char *annex, gdb_byte *readbuf,
   1299  1.1  christos 			  const gdb_byte *writebuf, ULONGEST offset,
   1300  1.1  christos 			  ULONGEST len, ULONGEST *xfered_len)
   1301  1.1  christos {
   1302  1.1  christos   /* We're only doing regular memory for now.  */
   1303  1.1  christos   if (object != TARGET_OBJECT_MEMORY)
   1304  1.1  christos     return TARGET_XFER_E_IO;
   1305  1.1  christos 
   1306  1.1  christos   if (readbuf == NULL)
   1307  1.1  christos     error (_("ctf_xfer_partial: trace file is read-only"));
   1308  1.1  christos 
   1309  1.1  christos   if (get_traceframe_number () != -1)
   1310  1.1  christos     {
   1311  1.1  christos       struct bt_iter_pos *pos;
   1312  1.1  christos       enum target_xfer_status res;
   1313  1.1  christos       /* Records the lowest available address of all blocks that
   1314  1.1  christos 	 intersects the requested range.  */
   1315  1.1  christos       ULONGEST low_addr_available = 0;
   1316  1.1  christos 
   1317  1.1  christos       gdb_assert (ctf_iter != NULL);
   1318  1.1  christos       /* Save the current position.  */
   1319  1.1  christos       pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
   1320  1.1  christos       gdb_assert (pos->type == BT_SEEK_RESTORE);
   1321  1.1  christos 
   1322  1.1  christos       /* Iterate through the traceframe's blocks, looking for
   1323  1.1  christos 	 memory.  */
   1324  1.1  christos       while (1)
   1325  1.1  christos 	{
   1326  1.1  christos 	  ULONGEST amt;
   1327  1.1  christos 	  uint64_t maddr;
   1328  1.1  christos 	  uint16_t mlen;
   1329  1.1  christos 	  const struct bt_definition *scope;
   1330  1.1  christos 	  const struct bt_definition *def;
   1331  1.1  christos 	  struct bt_ctf_event *event
   1332  1.1  christos 	    = bt_ctf_iter_read_event (ctf_iter);
   1333  1.1  christos 	  const char *name = bt_ctf_event_name (event);
   1334  1.1  christos 
   1335  1.1  christos 	  if (name == NULL || strcmp (name, "frame") == 0)
   1336  1.1  christos 	    break;
   1337  1.1  christos 	  else if (strcmp (name, "memory") != 0)
   1338  1.1  christos 	    {
   1339  1.1  christos 	      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1340  1.1  christos 		break;
   1341  1.1  christos 
   1342  1.1  christos 	      continue;
   1343  1.1  christos 	    }
   1344  1.1  christos 
   1345  1.1  christos 	  scope = bt_ctf_get_top_level_scope (event,
   1346  1.1  christos 					      BT_EVENT_FIELDS);
   1347  1.1  christos 
   1348  1.1  christos 	  def = bt_ctf_get_field (event, scope, "address");
   1349  1.1  christos 	  maddr = bt_ctf_get_uint64 (def);
   1350  1.1  christos 	  def = bt_ctf_get_field (event, scope, "length");
   1351  1.1  christos 	  mlen = (uint16_t) bt_ctf_get_uint64 (def);
   1352  1.1  christos 
   1353  1.1  christos 	  /* If the block includes the first part of the desired
   1354  1.1  christos 	     range, return as much it has; GDB will re-request the
   1355  1.1  christos 	     remainder, which might be in a different block of this
   1356  1.1  christos 	     trace frame.  */
   1357  1.1  christos 	  if (maddr <= offset && offset < (maddr + mlen))
   1358  1.1  christos 	    {
   1359  1.1  christos 	      const struct bt_definition *array
   1360  1.1  christos 		= bt_ctf_get_field (event, scope, "contents");
   1361  1.1  christos 	      gdb_byte *contents;
   1362  1.1  christos 	      int k;
   1363  1.1  christos 
   1364  1.1  christos 	      contents = (gdb_byte *) xmalloc (mlen);
   1365  1.1  christos 
   1366  1.1  christos 	      for (k = 0; k < mlen; k++)
   1367  1.1  christos 		{
   1368  1.1  christos 		  const struct bt_definition *element
   1369  1.1  christos 		    = bt_ctf_get_index (event, array, k);
   1370  1.1  christos 
   1371  1.1  christos 		  contents[k] = (gdb_byte) bt_ctf_get_uint64 (element);
   1372  1.1  christos 		}
   1373  1.1  christos 
   1374  1.1  christos 	      amt = (maddr + mlen) - offset;
   1375  1.1  christos 	      if (amt > len)
   1376  1.1  christos 		amt = len;
   1377  1.1  christos 
   1378  1.1  christos 	      memcpy (readbuf, &contents[offset - maddr], amt);
   1379  1.1  christos 
   1380  1.1  christos 	      xfree (contents);
   1381  1.1  christos 
   1382  1.1  christos 	      /* Restore the position.  */
   1383  1.1  christos 	      bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
   1384  1.1  christos 
   1385  1.1  christos 	      if (amt == 0)
   1386  1.1  christos 		return TARGET_XFER_EOF;
   1387  1.1  christos 	      else
   1388  1.1  christos 		{
   1389  1.1  christos 		  *xfered_len = amt;
   1390  1.1  christos 		  return TARGET_XFER_OK;
   1391  1.1  christos 		}
   1392  1.1  christos 	    }
   1393  1.1  christos 
   1394  1.1  christos 	  if (offset < maddr && maddr < (offset + len))
   1395  1.1  christos 	    if (low_addr_available == 0 || low_addr_available > maddr)
   1396  1.1  christos 	      low_addr_available = maddr;
   1397  1.1  christos 
   1398  1.1  christos 	  if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1399  1.1  christos 	    break;
   1400  1.1  christos 	}
   1401  1.1  christos 
   1402  1.1  christos       /* Restore the position.  */
   1403  1.1  christos       bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
   1404  1.1  christos 
   1405  1.1  christos       /* Requested memory is unavailable in the context of traceframes,
   1406  1.1  christos 	 and this address falls within a read-only section, fallback
   1407  1.1  christos 	 to reading from executable, up to LOW_ADDR_AVAILABLE  */
   1408  1.1  christos       if (offset < low_addr_available)
   1409  1.1  christos 	len = std::min (len, low_addr_available - offset);
   1410  1.1  christos       res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
   1411  1.1  christos 
   1412  1.1  christos       if (res == TARGET_XFER_OK)
   1413  1.1  christos 	return TARGET_XFER_OK;
   1414  1.1  christos       else
   1415  1.1  christos 	{
   1416  1.1  christos 	  /* No use trying further, we know some memory starting
   1417  1.1  christos 	     at MEMADDR isn't available.  */
   1418  1.1  christos 	  *xfered_len = len;
   1419  1.1  christos 	  return TARGET_XFER_UNAVAILABLE;
   1420  1.1  christos 	}
   1421  1.1  christos     }
   1422  1.1  christos   else
   1423  1.1  christos     {
   1424  1.1  christos       /* Fallback to reading from read-only sections.  */
   1425  1.1  christos       return section_table_read_available_memory (readbuf, offset, len, xfered_len);
   1426  1.1  christos     }
   1427  1.1  christos }
   1428  1.1  christos 
   1429  1.1  christos /* This is the implementation of target_ops method
   1430  1.1  christos    to_get_trace_state_variable_value.
   1431  1.1  christos    Iterate over events whose name is "tsv" in current frame.  When the
   1432  1.1  christos    trace variable is found, set the value of it to *VAL and return
   1433  1.1  christos    true, otherwise return false.  */
   1434  1.1  christos 
   1435  1.1  christos bool
   1436  1.1  christos ctf_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
   1437  1.1  christos {
   1438  1.1  christos   struct bt_iter_pos *pos;
   1439  1.1  christos   bool found = false;
   1440  1.1  christos 
   1441  1.1  christos   gdb_assert (ctf_iter != NULL);
   1442  1.1  christos   /* Save the current position.  */
   1443  1.1  christos   pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
   1444  1.1  christos   gdb_assert (pos->type == BT_SEEK_RESTORE);
   1445  1.1  christos 
   1446  1.1  christos   /* Iterate through the traceframe's blocks, looking for 'V'
   1447  1.1  christos      block.  */
   1448  1.1  christos   while (1)
   1449  1.1  christos     {
   1450  1.1  christos       struct bt_ctf_event *event
   1451  1.1  christos 	= bt_ctf_iter_read_event (ctf_iter);
   1452  1.1  christos       const char *name = bt_ctf_event_name (event);
   1453  1.1  christos 
   1454  1.1  christos       if (name == NULL || strcmp (name, "frame") == 0)
   1455  1.1  christos 	break;
   1456  1.1  christos       else if (strcmp (name, "tsv") == 0)
   1457  1.1  christos 	{
   1458  1.1  christos 	  const struct bt_definition *scope;
   1459  1.1  christos 	  const struct bt_definition *def;
   1460  1.1  christos 
   1461  1.1  christos 	  scope = bt_ctf_get_top_level_scope (event,
   1462  1.1  christos 					      BT_EVENT_FIELDS);
   1463  1.1  christos 
   1464  1.1  christos 	  def = bt_ctf_get_field (event, scope, "num");
   1465  1.1  christos 	  if (tsvnum == (int32_t) bt_ctf_get_uint64 (def))
   1466  1.1  christos 	    {
   1467  1.1  christos 	      def = bt_ctf_get_field (event, scope, "val");
   1468  1.1  christos 	      *val = bt_ctf_get_uint64 (def);
   1469  1.1  christos 
   1470  1.1  christos 	      found = true;
   1471  1.1  christos 	    }
   1472  1.1  christos 	}
   1473  1.1  christos 
   1474  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1475  1.1  christos 	break;
   1476  1.1  christos     }
   1477  1.1  christos 
   1478  1.1  christos   /* Restore the position.  */
   1479  1.1  christos   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
   1480  1.1  christos 
   1481  1.1  christos   return found;
   1482  1.1  christos }
   1483  1.1  christos 
   1484  1.1  christos /* Return the tracepoint number in "frame" event.  */
   1485  1.1  christos 
   1486  1.1  christos static int
   1487  1.1  christos ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event)
   1488  1.1  christos {
   1489  1.1  christos   /* The packet context of events has a field "tpnum".  */
   1490  1.1  christos   const struct bt_definition *scope
   1491  1.1  christos     = bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT);
   1492  1.1  christos   uint64_t tpnum
   1493  1.1  christos     = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum"));
   1494  1.1  christos 
   1495  1.1  christos   return (int) tpnum;
   1496  1.1  christos }
   1497  1.1  christos 
   1498  1.1  christos /* Return the address at which the current frame was collected.  */
   1499  1.1  christos 
   1500  1.1  christos static CORE_ADDR
   1501  1.1  christos ctf_get_traceframe_address (void)
   1502  1.1  christos {
   1503  1.1  christos   struct bt_ctf_event *event = NULL;
   1504  1.1  christos   struct bt_iter_pos *pos;
   1505  1.1  christos   CORE_ADDR addr = 0;
   1506  1.1  christos 
   1507  1.1  christos   gdb_assert (ctf_iter != NULL);
   1508  1.1  christos   pos  = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
   1509  1.1  christos   gdb_assert (pos->type == BT_SEEK_RESTORE);
   1510  1.1  christos 
   1511  1.1  christos   while (1)
   1512  1.1  christos     {
   1513  1.1  christos       const char *name;
   1514  1.1  christos       struct bt_ctf_event *event1;
   1515  1.1  christos 
   1516  1.1  christos       event1 = bt_ctf_iter_read_event (ctf_iter);
   1517  1.1  christos 
   1518  1.1  christos       name = bt_ctf_event_name (event1);
   1519  1.1  christos 
   1520  1.1  christos       if (name == NULL)
   1521  1.1  christos 	break;
   1522  1.1  christos       else if (strcmp (name, "frame") == 0)
   1523  1.1  christos 	{
   1524  1.1  christos 	  event = event1;
   1525  1.1  christos 	  break;
   1526  1.1  christos 	}
   1527  1.1  christos 
   1528  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1529  1.1  christos 	break;
   1530  1.1  christos     }
   1531  1.1  christos 
   1532  1.1  christos   if (event != NULL)
   1533  1.1  christos     {
   1534  1.1  christos       int tpnum = ctf_get_tpnum_from_frame_event (event);
   1535  1.1  christos       struct tracepoint *tp
   1536  1.1  christos 	= get_tracepoint_by_number_on_target (tpnum);
   1537  1.1  christos 
   1538  1.1  christos       if (tp && tp->loc)
   1539  1.1  christos 	addr = tp->loc->address;
   1540  1.1  christos     }
   1541  1.1  christos 
   1542  1.1  christos   /* Restore the position.  */
   1543  1.1  christos   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
   1544  1.1  christos 
   1545  1.1  christos   return addr;
   1546  1.1  christos }
   1547  1.1  christos 
   1548  1.1  christos /* This is the implementation of target_ops method to_trace_find.
   1549  1.1  christos    Iterate the events whose name is "frame", extract the tracepoint
   1550  1.1  christos    number in it.  Return traceframe number when matched.  */
   1551  1.1  christos 
   1552  1.1  christos int
   1553  1.1  christos ctf_target::trace_find (enum trace_find_type type, int num,
   1554  1.1  christos 			CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
   1555  1.1  christos {
   1556  1.1  christos   int tfnum = 0;
   1557  1.1  christos   int found = 0;
   1558  1.1  christos 
   1559  1.1  christos   if (num == -1)
   1560  1.1  christos     {
   1561  1.1  christos       if (tpp != NULL)
   1562  1.1  christos 	*tpp = -1;
   1563  1.1  christos       return -1;
   1564  1.1  christos     }
   1565  1.1  christos 
   1566  1.1  christos   gdb_assert (ctf_iter != NULL);
   1567  1.1  christos   /* Set iterator back to the start.  */
   1568  1.1  christos   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos);
   1569  1.1  christos 
   1570  1.1  christos   while (1)
   1571  1.1  christos     {
   1572  1.1  christos       struct bt_ctf_event *event;
   1573  1.1  christos       const char *name;
   1574  1.1  christos 
   1575  1.1  christos       event = bt_ctf_iter_read_event (ctf_iter);
   1576  1.1  christos 
   1577  1.1  christos       name = bt_ctf_event_name (event);
   1578  1.1  christos 
   1579  1.1  christos       if (event == NULL || name == NULL)
   1580  1.1  christos 	break;
   1581  1.1  christos 
   1582  1.1  christos       if (strcmp (name, "frame") == 0)
   1583  1.1  christos 	{
   1584  1.1  christos 	  CORE_ADDR tfaddr;
   1585  1.1  christos 
   1586  1.1  christos 	  if (type == tfind_number)
   1587  1.1  christos 	    {
   1588  1.1  christos 	      /* Looking for a specific trace frame.  */
   1589  1.1  christos 	      if (tfnum == num)
   1590  1.1  christos 		found = 1;
   1591  1.1  christos 	    }
   1592  1.1  christos 	  else
   1593  1.1  christos 	    {
   1594  1.1  christos 	      /* Start from the _next_ trace frame.  */
   1595  1.1  christos 	      if (tfnum > get_traceframe_number ())
   1596  1.1  christos 		{
   1597  1.1  christos 		  switch (type)
   1598  1.1  christos 		    {
   1599  1.1  christos 		    case tfind_tp:
   1600  1.1  christos 		      {
   1601  1.1  christos 			struct tracepoint *tp = get_tracepoint (num);
   1602  1.1  christos 
   1603  1.1  christos 			if (tp != NULL
   1604  1.1  christos 			    && (tp->number_on_target
   1605  1.1  christos 				== ctf_get_tpnum_from_frame_event (event)))
   1606  1.1  christos 			  found = 1;
   1607  1.1  christos 			break;
   1608  1.1  christos 		      }
   1609  1.1  christos 		    case tfind_pc:
   1610  1.1  christos 		      tfaddr = ctf_get_traceframe_address ();
   1611  1.1  christos 		      if (tfaddr == addr1)
   1612  1.1  christos 			found = 1;
   1613  1.1  christos 		      break;
   1614  1.1  christos 		    case tfind_range:
   1615  1.1  christos 		      tfaddr = ctf_get_traceframe_address ();
   1616  1.1  christos 		      if (addr1 <= tfaddr && tfaddr <= addr2)
   1617  1.1  christos 			found = 1;
   1618  1.1  christos 		      break;
   1619  1.1  christos 		    case tfind_outside:
   1620  1.1  christos 		      tfaddr = ctf_get_traceframe_address ();
   1621  1.1  christos 		      if (!(addr1 <= tfaddr && tfaddr <= addr2))
   1622  1.1  christos 			found = 1;
   1623  1.1  christos 		      break;
   1624  1.1  christos 		    default:
   1625  1.1  christos 		      internal_error (__FILE__, __LINE__, _("unknown tfind type"));
   1626  1.1  christos 		    }
   1627  1.1  christos 		}
   1628  1.1  christos 	    }
   1629  1.1  christos 	  if (found)
   1630  1.1  christos 	    {
   1631  1.1  christos 	      if (tpp != NULL)
   1632  1.1  christos 		*tpp = ctf_get_tpnum_from_frame_event (event);
   1633  1.1  christos 
   1634  1.1  christos 	      /* Skip the event "frame".  */
   1635  1.1  christos 	      bt_iter_next (bt_ctf_get_iter (ctf_iter));
   1636  1.1  christos 
   1637  1.1  christos 	      return tfnum;
   1638  1.1  christos 	    }
   1639  1.1  christos 	  tfnum++;
   1640  1.1  christos 	}
   1641  1.1  christos 
   1642  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1643  1.1  christos 	break;
   1644  1.1  christos     }
   1645  1.1  christos 
   1646  1.1  christos   return -1;
   1647  1.1  christos }
   1648  1.1  christos 
   1649  1.1  christos /* This is the implementation of target_ops method to_traceframe_info.
   1650  1.1  christos    Iterate the events whose name is "memory", in current
   1651  1.1  christos    frame, extract memory range information, and return them in
   1652  1.1  christos    traceframe_info.  */
   1653  1.1  christos 
   1654  1.1  christos traceframe_info_up
   1655  1.1  christos ctf_target::traceframe_info ()
   1656  1.1  christos {
   1657  1.1  christos   traceframe_info_up info (new struct traceframe_info);
   1658  1.1  christos   const char *name;
   1659  1.1  christos   struct bt_iter_pos *pos;
   1660  1.1  christos 
   1661  1.1  christos   gdb_assert (ctf_iter != NULL);
   1662  1.1  christos   /* Save the current position.  */
   1663  1.1  christos   pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
   1664  1.1  christos   gdb_assert (pos->type == BT_SEEK_RESTORE);
   1665  1.1  christos 
   1666  1.1  christos   do
   1667  1.1  christos     {
   1668  1.1  christos       struct bt_ctf_event *event
   1669  1.1  christos 	= bt_ctf_iter_read_event (ctf_iter);
   1670  1.1  christos 
   1671  1.1  christos       name = bt_ctf_event_name (event);
   1672  1.1  christos 
   1673  1.1  christos       if (name == NULL || strcmp (name, "register") == 0
   1674  1.1  christos 	  || strcmp (name, "frame") == 0)
   1675  1.1  christos 	;
   1676  1.1  christos       else if (strcmp (name, "memory") == 0)
   1677  1.1  christos 	{
   1678  1.1  christos 	  const struct bt_definition *scope
   1679  1.1  christos 	    = bt_ctf_get_top_level_scope (event,
   1680  1.1  christos 					  BT_EVENT_FIELDS);
   1681  1.1  christos 	  const struct bt_definition *def;
   1682  1.1  christos 
   1683  1.1  christos 	  def = bt_ctf_get_field (event, scope, "address");
   1684  1.1  christos 	  CORE_ADDR start = bt_ctf_get_uint64 (def);
   1685  1.1  christos 
   1686  1.1  christos 	  def = bt_ctf_get_field (event, scope, "length");
   1687  1.1  christos 	  int length = (uint16_t) bt_ctf_get_uint64 (def);
   1688  1.1  christos 
   1689  1.1  christos 	  info->memory.emplace_back (start, length);
   1690  1.1  christos 	}
   1691  1.1  christos       else if (strcmp (name, "tsv") == 0)
   1692  1.1  christos 	{
   1693  1.1  christos 	  int vnum;
   1694  1.1  christos 	  const struct bt_definition *scope
   1695  1.1  christos 	    = bt_ctf_get_top_level_scope (event,
   1696  1.1  christos 					  BT_EVENT_FIELDS);
   1697  1.1  christos 	  const struct bt_definition *def;
   1698  1.1  christos 
   1699  1.1  christos 	  def = bt_ctf_get_field (event, scope, "num");
   1700  1.1  christos 	  vnum = (int) bt_ctf_get_uint64 (def);
   1701  1.1  christos 	  info->tvars.push_back (vnum);
   1702  1.1  christos 	}
   1703  1.1  christos       else
   1704  1.1  christos 	{
   1705  1.1  christos 	  warning (_("Unhandled trace block type (%s) "
   1706  1.1  christos 		     "while building trace frame info."),
   1707  1.1  christos 		   name);
   1708  1.1  christos 	}
   1709  1.1  christos 
   1710  1.1  christos       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
   1711  1.1  christos 	break;
   1712  1.1  christos     }
   1713  1.1  christos   while (name != NULL && strcmp (name, "frame") != 0);
   1714  1.1  christos 
   1715  1.1  christos   /* Restore the position.  */
   1716  1.1  christos   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
   1717  1.1  christos 
   1718  1.1  christos   return info;
   1719  1.1  christos }
   1720  1.1  christos 
   1721  1.1  christos #endif
   1722  1.1  christos 
   1723  1.1  christos /* module initialization */
   1724  1.1  christos 
   1725  1.1  christos void _initialize_ctf ();
   1726  1.1  christos void
   1727  1.1  christos _initialize_ctf ()
   1728  1.1  christos {
   1729  1.1  christos #if HAVE_LIBBABELTRACE
   1730  1.1  christos   add_target (ctf_target_info, ctf_target_open, filename_completer);
   1731  1.1  christos #endif
   1732  1.1  christos }
   1733