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