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