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