Add inclusive range support for Rust
[deliverable/binutils-gdb.git] / gdb / ctf.c
CommitLineData
d0353e76
YQ
1/* CTF format support.
2
e2882c85 3 Copyright (C) 2012-2018 Free Software Foundation, Inc.
d0353e76
YQ
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"
53ce3c39 26#include <sys/stat.h>
393fd4c3 27#include "exec.h"
da9160e4 28#include "completer.h"
de7b2893
YQ
29#include "inferior.h"
30#include "gdbthread.h"
7951c4eb 31#include "tracefile.h"
d0353e76 32#include <ctype.h>
325fac50 33#include <algorithm>
d0353e76
YQ
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
393fd4c3
YQ
42 2. Trace status. Event "status" is defined in metadata, which
43 includes all aspects of trace status.
d0353e76 44
393fd4c3
YQ
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".
d0353e76
YQ
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
393fd4c3
YQ
78#define CTF_EVENT_ID_STATUS 4
79#define CTF_EVENT_ID_TSV_DEF 5
80#define CTF_EVENT_ID_TP_DEF 6
d0353e76 81
de7b2893
YQ
82#define CTF_PID (2)
83
d0353e76
YQ
84/* The state kept while writing the CTF datastream file. */
85
86struct trace_write_handler
87{
88 /* File descriptor of metadata. */
89 FILE *metadata_fd;
90 /* File descriptor of traceframes. */
91 FILE *datastream_fd;
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. */
97 long packet_start;
98};
99
100/* Write metadata in FORMAT. */
101
77b64a49
PA
102static void
103ctf_save_write_metadata (struct trace_write_handler *handler,
104 const char *format, ...)
105 ATTRIBUTE_PRINTF (2, 3);
106
d0353e76
YQ
107static void
108ctf_save_write_metadata (struct trace_write_handler *handler,
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
123static int
124ctf_save_write (struct trace_write_handler *handler,
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
393fd4c3
YQ
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
d0353e76
YQ
148/* Set datastream file position. Update HANDLER->content_size
149 if WHENCE is SEEK_CUR. */
150
151static int
152ctf_save_fseek (struct trace_write_handler *handler, long offset,
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
172static int
173ctf_save_align_write (struct trace_write_handler *handler,
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
192static void
193ctf_save_next_packet (struct trace_write_handler *handler)
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
202static void
203ctf_save_metadata_header (struct trace_write_handler *handler)
204{
d0353e76
YQ
205 ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
206 CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
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");
393fd4c3
YQ
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");
d0353e76
YQ
234 ctf_save_write_metadata (handler, "\n");
235
8249a5a9
YQ
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
7f31862a
PA
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",
d0353e76 264 CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
8249a5a9 265 HOST_ENDIANNESS);
d0353e76
YQ
266 ctf_save_write_metadata (handler, "\n");
267}
268
269/* CTF trace writer. */
270
271struct ctf_trace_file_writer
272{
273 struct trace_file_writer base;
274
275 /* States related to writing CTF trace file. */
276 struct trace_write_handler tcs;
277};
278
279/* This is the implementation of trace_file_write_ops method
280 dtor. */
281
282static void
283ctf_dtor (struct trace_file_writer *self)
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
299static int
300ctf_target_save (struct trace_file_writer *self,
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
311static void
312ctf_start (struct trace_file_writer *self, const char *dirname)
313{
d0353e76
YQ
314 struct ctf_trace_file_writer *writer
315 = (struct ctf_trace_file_writer *) self;
840207d8 316 mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
d0353e76
YQ
317
318 /* Create DIRNAME. */
af307d6a 319 if (mkdir (dirname, hmode) && errno != EEXIST)
d0353e76
YQ
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
50feb4bd 325 std::string file_name = string_printf ("%s/%s", dirname, CTF_METADATA_NAME);
d0353e76 326
50feb4bd 327 writer->tcs.metadata_fd = fopen (file_name.c_str (), "w");
d0353e76
YQ
328 if (writer->tcs.metadata_fd == NULL)
329 error (_("Unable to open file '%s' for saving trace data (%s)"),
50feb4bd 330 file_name.c_str (), safe_strerror (errno));
d0353e76
YQ
331
332 ctf_save_metadata_header (&writer->tcs);
333
50feb4bd
TT
334 file_name = string_printf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
335 writer->tcs.datastream_fd = fopen (file_name.c_str (), "w");
d0353e76
YQ
336 if (writer->tcs.datastream_fd == NULL)
337 error (_("Unable to open file '%s' for saving trace data (%s)"),
50feb4bd 338 file_name.c_str (), safe_strerror (errno));
d0353e76
YQ
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
345static void
346ctf_write_header (struct trace_file_writer *self)
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
393fd4c3
YQ
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
d0353e76
YQ
417 gdb_assert (writer->tcs.content_size == 0);
418 gdb_assert (writer->tcs.packet_start == 0);
393fd4c3
YQ
419
420 /* Create a new packet to contain this event. */
421 self->ops->frame_ops->start (self, 0);
d0353e76
YQ
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
428static void
429ctf_write_regblock_type (struct trace_file_writer *self, int size)
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",
442 CTF_EVENT_ID_REGISTER, size);
443}
444
445/* This is the implementation of trace_file_write_ops method
446 write_status. */
447
448static void
449ctf_write_status (struct trace_file_writer *self,
450 struct trace_status *ts)
451{
393fd4c3
YQ
452 struct ctf_trace_file_writer *writer
453 = (struct ctf_trace_file_writer *) self;
454 uint32_t id;
393fd4c3
YQ
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",
470 CTF_EVENT_ID_STATUS);
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);
477 ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint);
478 ctf_save_write_int32 (&writer->tcs, ts->traceframe_count);
479 ctf_save_write_int32 (&writer->tcs, ts->traceframes_created);
480 ctf_save_write_int32 (&writer->tcs, ts->buffer_free);
481 ctf_save_write_int32 (&writer->tcs, ts->buffer_size);
482 ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing);
483 ctf_save_write_int32 (&writer->tcs, ts->circular_buffer);
d0353e76
YQ
484}
485
486/* This is the implementation of trace_file_write_ops method
487 write_uploaded_tsv. */
488
489static void
490ctf_write_uploaded_tsv (struct trace_file_writer *self,
491 struct uploaded_tsv *tsv)
492{
393fd4c3
YQ
493 struct ctf_trace_file_writer *writer
494 = (struct ctf_trace_file_writer *) self;
495 int32_t int32;
496 int64_t int64;
393fd4c3
YQ
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)
a398505b
PA
515 ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name,
516 strlen (tsv->name));
393fd4c3 517 ctf_save_write (&writer->tcs, &zero, 1);
d0353e76
YQ
518}
519
520/* This is the implementation of trace_file_write_ops method
521 write_uploaded_tp. */
522
523static void
524ctf_write_uploaded_tp (struct trace_file_writer *self,
525 struct uploaded_tp *tp)
526{
393fd4c3
YQ
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;
393fd4c3
YQ
533
534 /* Event Id. */
535 int32 = CTF_EVENT_ID_TP_DEF;
536 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
537
538 /* address */
539 int64 = tp->addr;
540 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
541
542 /* traceframe_usage */
543 int64 = tp->traceframe_usage;
544 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
545
546 /* number */
547 ctf_save_write_int32 (&writer->tcs, tp->number);
548
549 /* enabled */
550 ctf_save_write_int32 (&writer->tcs, tp->enabled);
551
552 /* step */
553 ctf_save_write_int32 (&writer->tcs, tp->step);
554
555 /* pass */
556 ctf_save_write_int32 (&writer->tcs, tp->pass);
557
558 /* hit_count */
559 ctf_save_write_int32 (&writer->tcs, tp->hit_count);
560
561 /* type */
562 ctf_save_write_int32 (&writer->tcs, tp->type);
563
564 /* condition */
565 if (tp->cond != NULL)
a398505b 566 ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen (tp->cond));
393fd4c3
YQ
567 ctf_save_write (&writer->tcs, &zero, 1);
568
569 /* actions */
a18ba4e4 570 u32 = tp->actions.size ();
393fd4c3 571 ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
a18ba4e4 572 for (char *act : tp->actions)
a398505b 573 ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
393fd4c3
YQ
574
575 /* step_actions */
a18ba4e4 576 u32 = tp->step_actions.size ();
393fd4c3 577 ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
a18ba4e4 578 for (char *act : tp->step_actions)
a398505b 579 ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
393fd4c3
YQ
580
581 /* at_string */
582 if (tp->at_string != NULL)
a398505b 583 ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string,
393fd4c3
YQ
584 strlen (tp->at_string));
585 ctf_save_write (&writer->tcs, &zero, 1);
586
587 /* cond_string */
588 if (tp->cond_string != NULL)
a398505b 589 ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string,
393fd4c3
YQ
590 strlen (tp->cond_string));
591 ctf_save_write (&writer->tcs, &zero, 1);
592
593 /* cmd_strings */
a18ba4e4 594 u32 = tp->cmd_strings.size ();
393fd4c3 595 ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
a18ba4e4 596 for (char *act : tp->cmd_strings)
a398505b 597 ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
393fd4c3 598
d0353e76
YQ
599}
600
18d3cec5
MK
601/* This is the implementation of trace_file_write_ops method
602 write_tdesc. */
603
604static void
605ctf_write_tdesc (struct trace_file_writer *self)
606{
607 /* Nothing so far. */
608}
609
d0353e76
YQ
610/* This is the implementation of trace_file_write_ops method
611 write_definition_end. */
612
613static void
614ctf_write_definition_end (struct trace_file_writer *self)
615{
393fd4c3 616 self->ops->frame_ops->end (self);
d0353e76
YQ
617}
618
d0353e76
YQ
619/* This is the implementation of trace_file_write_ops method
620 end. */
621
622static void
623ctf_end (struct trace_file_writer *self)
624{
625 struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;
626
627 gdb_assert (writer->tcs.content_size == 0);
d0353e76
YQ
628}
629
630/* This is the implementation of trace_frame_write_ops method
631 start. */
632
633static void
634ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
635{
636 struct ctf_trace_file_writer *writer
637 = (struct ctf_trace_file_writer *) self;
638 uint32_t id = CTF_EVENT_ID_FRAME;
639 uint32_t u32;
640
641 /* Step 1: Write packet context. */
642 /* magic. */
643 u32 = CTF_MAGIC;
644 ctf_save_write_uint32 (&writer->tcs, u32);
645 /* content_size and packet_size.. We still don't know the value,
646 write it later. */
647 ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
648 ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
649 /* Tracepoint number. */
650 ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);
651
652 /* Step 2: Write event "frame". */
653 /* Event Id. */
654 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
655}
656
657/* This is the implementation of trace_frame_write_ops method
658 write_r_block. */
659
660static void
661ctf_write_frame_r_block (struct trace_file_writer *self,
662 gdb_byte *buf, int32_t size)
663{
664 struct ctf_trace_file_writer *writer
665 = (struct ctf_trace_file_writer *) self;
666 uint32_t id = CTF_EVENT_ID_REGISTER;
667
668 /* Event Id. */
669 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
670
671 /* array contents. */
672 ctf_save_align_write (&writer->tcs, buf, size, 1);
673}
674
675/* This is the implementation of trace_frame_write_ops method
676 write_m_block_header. */
677
678static void
679ctf_write_frame_m_block_header (struct trace_file_writer *self,
680 uint64_t addr, uint16_t length)
681{
682 struct ctf_trace_file_writer *writer
683 = (struct ctf_trace_file_writer *) self;
684 uint32_t event_id = CTF_EVENT_ID_MEMORY;
685
686 /* Event Id. */
687 ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);
688
689 /* Address. */
690 ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);
691
692 /* Length. */
693 ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
694}
695
696/* This is the implementation of trace_frame_write_ops method
697 write_m_block_memory. */
698
699static void
700ctf_write_frame_m_block_memory (struct trace_file_writer *self,
701 gdb_byte *buf, uint16_t length)
702{
703 struct ctf_trace_file_writer *writer
704 = (struct ctf_trace_file_writer *) self;
705
706 /* Contents. */
707 ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
708}
709
710/* This is the implementation of trace_frame_write_ops method
711 write_v_block. */
712
713static void
714ctf_write_frame_v_block (struct trace_file_writer *self,
715 int32_t num, uint64_t val)
716{
717 struct ctf_trace_file_writer *writer
718 = (struct ctf_trace_file_writer *) self;
719 uint32_t id = CTF_EVENT_ID_TSV;
720
721 /* Event Id. */
722 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
723
724 /* val. */
725 ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
726 /* num. */
727 ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
728}
729
730/* This is the implementation of trace_frame_write_ops method
731 end. */
732
733static void
734ctf_write_frame_end (struct trace_file_writer *self)
735{
736 struct ctf_trace_file_writer *writer
737 = (struct ctf_trace_file_writer *) self;
738 uint32_t u32;
739 uint32_t t;
740
741 /* Write the content size to packet header. */
742 ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
743 SEEK_SET);
744 u32 = writer->tcs.content_size * TARGET_CHAR_BIT;
745
746 t = writer->tcs.content_size;
747 ctf_save_write_uint32 (&writer->tcs, u32);
748
749 /* Write the packet size. */
750 u32 += 4 * TARGET_CHAR_BIT;
751 ctf_save_write_uint32 (&writer->tcs, u32);
752
753 writer->tcs.content_size = t;
754
755 /* Write zero at the end of the packet. */
756 ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
757 SEEK_SET);
758 u32 = 0;
759 ctf_save_write_uint32 (&writer->tcs, u32);
760 writer->tcs.content_size = t;
761
762 ctf_save_next_packet (&writer->tcs);
763}
764
765/* Operations to write various types of trace frames into CTF
766 format. */
767
768static const struct trace_frame_write_ops ctf_write_frame_ops =
769{
770 ctf_write_frame_start,
771 ctf_write_frame_r_block,
772 ctf_write_frame_m_block_header,
773 ctf_write_frame_m_block_memory,
774 ctf_write_frame_v_block,
775 ctf_write_frame_end,
776};
777
778/* Operations to write trace buffers into CTF format. */
779
780static const struct trace_file_write_ops ctf_write_ops =
781{
782 ctf_dtor,
783 ctf_target_save,
784 ctf_start,
785 ctf_write_header,
786 ctf_write_regblock_type,
787 ctf_write_status,
788 ctf_write_uploaded_tsv,
789 ctf_write_uploaded_tp,
18d3cec5 790 ctf_write_tdesc,
d0353e76
YQ
791 ctf_write_definition_end,
792 NULL,
793 &ctf_write_frame_ops,
794 ctf_end,
795};
796
797/* Return a trace writer for CTF format. */
798
799struct trace_file_writer *
800ctf_trace_file_writer_new (void)
801{
8d749320 802 struct ctf_trace_file_writer *writer = XNEW (struct ctf_trace_file_writer);
d0353e76
YQ
803
804 writer->base.ops = &ctf_write_ops;
805
806 return (struct trace_file_writer *) writer;
807}
393fd4c3
YQ
808
809#if HAVE_LIBBABELTRACE
810/* Use libbabeltrace to read CTF data. The libbabeltrace provides
811 iterator to iterate over each event in CTF data and APIs to get
812 details of event and packet, so it is very convenient to use
813 libbabeltrace to access events in CTF. */
814
815#include <babeltrace/babeltrace.h>
816#include <babeltrace/ctf/events.h>
817#include <babeltrace/ctf/iterator.h>
818
819/* The struct pointer for current CTF directory. */
614d5099 820static int handle_id = -1;
393fd4c3
YQ
821static struct bt_context *ctx = NULL;
822static struct bt_ctf_iter *ctf_iter = NULL;
823/* The position of the first packet containing trace frame. */
824static struct bt_iter_pos *start_pos;
825
826/* The name of CTF directory. */
827static char *trace_dirname;
828
829static struct target_ops ctf_ops;
830
831/* Destroy ctf iterator and context. */
832
833static void
834ctf_destroy (void)
835{
836 if (ctf_iter != NULL)
837 {
838 bt_ctf_iter_destroy (ctf_iter);
839 ctf_iter = NULL;
840 }
841 if (ctx != NULL)
842 {
843 bt_context_put (ctx);
844 ctx = NULL;
845 }
846}
847
848/* Open CTF trace data in DIRNAME. */
849
850static void
014f9477 851ctf_open_dir (const char *dirname)
393fd4c3 852{
393fd4c3 853 struct bt_iter_pos begin_pos;
614d5099
YQ
854 unsigned int count, i;
855 struct bt_ctf_event_decl * const *list;
393fd4c3
YQ
856
857 ctx = bt_context_create ();
858 if (ctx == NULL)
859 error (_("Unable to create bt_context"));
614d5099
YQ
860 handle_id = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
861 if (handle_id < 0)
393fd4c3
YQ
862 {
863 ctf_destroy ();
864 error (_("Unable to use libbabeltrace on directory \"%s\""),
865 dirname);
866 }
867
868 begin_pos.type = BT_SEEK_BEGIN;
869 ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
870 if (ctf_iter == NULL)
871 {
872 ctf_destroy ();
873 error (_("Unable to create bt_iterator"));
874 }
875
614d5099
YQ
876 /* Look for the declaration of register block. Get the length of
877 array "contents" to set trace_regblock_size. */
393fd4c3 878
614d5099
YQ
879 bt_ctf_get_event_decl_list (handle_id, ctx, &list, &count);
880 for (i = 0; i < count; i++)
881 if (strcmp ("register", bt_ctf_get_decl_event_name (list[i])) == 0)
882 {
614d5099
YQ
883 const struct bt_ctf_field_decl * const *field_list;
884 const struct bt_declaration *decl;
393fd4c3 885
614d5099
YQ
886 bt_ctf_get_decl_fields (list[i], BT_EVENT_FIELDS, &field_list,
887 &count);
393fd4c3 888
614d5099
YQ
889 gdb_assert (count == 1);
890 gdb_assert (0 == strcmp ("contents",
891 bt_ctf_get_decl_field_name (field_list[0])));
892 decl = bt_ctf_get_decl_from_field_decl (field_list[0]);
893 trace_regblock_size = bt_ctf_get_array_len (decl);
393fd4c3 894
393fd4c3 895 break;
614d5099 896 }
393fd4c3
YQ
897}
898
899#define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD) \
900 (VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \
901 (SCOPE), \
902 #FIELD))
903
e0d13cbd
SM
904#define SET_ENUM_FIELD(EVENT, SCOPE, VAR, TYPE, FIELD) \
905 (VAR)->FIELD = (TYPE) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \
906 (SCOPE), \
907 #FIELD))
908
909
393fd4c3
YQ
910/* EVENT is the "status" event and TS is filled in. */
911
912static void
913ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
914{
915 const struct bt_definition *scope
916 = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS);
917
e0d13cbd 918 SET_ENUM_FIELD (event, scope, ts, enum trace_stop_reason, stop_reason);
393fd4c3
YQ
919 SET_INT32_FIELD (event, scope, ts, stopping_tracepoint);
920 SET_INT32_FIELD (event, scope, ts, traceframe_count);
921 SET_INT32_FIELD (event, scope, ts, traceframes_created);
922 SET_INT32_FIELD (event, scope, ts, buffer_free);
923 SET_INT32_FIELD (event, scope, ts, buffer_size);
924 SET_INT32_FIELD (event, scope, ts, disconnected_tracing);
925 SET_INT32_FIELD (event, scope, ts, circular_buffer);
926
927 bt_iter_next (bt_ctf_get_iter (ctf_iter));
928}
929
930/* Read the events "tsv_def" one by one, extract its contents and fill
931 in the list UPLOADED_TSVS. */
932
933static void
934ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
935{
936 gdb_assert (ctf_iter != NULL);
937
938 while (1)
939 {
940 struct bt_ctf_event *event;
941 const struct bt_definition *scope;
942 const struct bt_definition *def;
943 uint32_t event_id;
944 struct uploaded_tsv *utsv = NULL;
945
946 event = bt_ctf_iter_read_event (ctf_iter);
947 scope = bt_ctf_get_top_level_scope (event,
948 BT_STREAM_EVENT_HEADER);
949 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
950 "id"));
951 if (event_id != CTF_EVENT_ID_TSV_DEF)
952 break;
953
954 scope = bt_ctf_get_top_level_scope (event,
955 BT_EVENT_FIELDS);
956
957 def = bt_ctf_get_field (event, scope, "number");
958 utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
959 uploaded_tsvs);
960
961 def = bt_ctf_get_field (event, scope, "builtin");
962 utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
963 def = bt_ctf_get_field (event, scope, "initial_value");
964 utsv->initial_value = bt_ctf_get_int64 (def);
965
966 def = bt_ctf_get_field (event, scope, "name");
967 utsv->name = xstrdup (bt_ctf_get_string (def));
968
969 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
970 break;
971 }
972
973}
974
975/* Read the value of element whose index is NUM from CTF and write it
976 to the corresponding VAR->ARRAY. */
977
978#define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY) \
979 do \
980 { \
981 uint32_t u32, i; \
982 const struct bt_definition *def; \
983 \
984 u32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT), \
985 (SCOPE), \
986 #NUM)); \
987 def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY); \
988 for (i = 0; i < u32; i++) \
989 { \
990 const struct bt_definition *element \
991 = bt_ctf_get_index ((EVENT), def, i); \
992 \
a18ba4e4
SM
993 (VAR)->ARRAY.push_back \
994 (xstrdup (bt_ctf_get_string (element))); \
393fd4c3
YQ
995 } \
996 } \
997 while (0)
998
999/* Read a string from CTF and set VAR->FIELD. If the length of string
1000 is zero, set VAR->FIELD to NULL. */
1001
1002#define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD) \
1003 do \
1004 { \
1005 const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT), \
1006 (SCOPE), \
1007 #FIELD)); \
1008 \
1009 if (strlen (p) > 0) \
1010 (VAR)->FIELD = xstrdup (p); \
1011 else \
1012 (VAR)->FIELD = NULL; \
1013 } \
1014 while (0)
1015
1016/* Read the events "tp_def" one by one, extract its contents and fill
1017 in the list UPLOADED_TPS. */
1018
1019static void
1020ctf_read_tp (struct uploaded_tp **uploaded_tps)
1021{
1022 gdb_assert (ctf_iter != NULL);
1023
1024 while (1)
1025 {
1026 struct bt_ctf_event *event;
1027 const struct bt_definition *scope;
1028 uint32_t u32;
1029 int32_t int32;
1030 uint64_t u64;
1031 struct uploaded_tp *utp = NULL;
1032
1033 event = bt_ctf_iter_read_event (ctf_iter);
1034 scope = bt_ctf_get_top_level_scope (event,
1035 BT_STREAM_EVENT_HEADER);
1036 u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
1037 "id"));
1038 if (u32 != CTF_EVENT_ID_TP_DEF)
1039 break;
1040
1041 scope = bt_ctf_get_top_level_scope (event,
1042 BT_EVENT_FIELDS);
1043 int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event,
1044 scope,
1045 "number"));
1046 u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
1047 "addr"));
1048 utp = get_uploaded_tp (int32, u64, uploaded_tps);
1049
1050 SET_INT32_FIELD (event, scope, utp, enabled);
1051 SET_INT32_FIELD (event, scope, utp, step);
1052 SET_INT32_FIELD (event, scope, utp, pass);
1053 SET_INT32_FIELD (event, scope, utp, hit_count);
e0d13cbd 1054 SET_ENUM_FIELD (event, scope, utp, enum bptype, type);
393fd4c3
YQ
1055
1056 /* Read 'cmd_strings'. */
1057 SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings);
1058 /* Read 'actions'. */
1059 SET_ARRAY_FIELD (event, scope, utp, action_num, actions);
1060 /* Read 'step_actions'. */
1061 SET_ARRAY_FIELD (event, scope, utp, step_action_num,
1062 step_actions);
1063
1064 SET_STRING_FIELD(event, scope, utp, at_string);
1065 SET_STRING_FIELD(event, scope, utp, cond_string);
1066
1067 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1068 break;
1069 }
1070}
1071
1072/* This is the implementation of target_ops method to_open. Open CTF
1073 trace data, read trace status, trace state variables and tracepoint
1074 definitions from the first packet. Set the start position at the
1075 second packet which contains events on trace blocks. */
1076
1077static void
014f9477 1078ctf_open (const char *dirname, int from_tty)
393fd4c3
YQ
1079{
1080 struct bt_ctf_event *event;
1081 uint32_t event_id;
1082 const struct bt_definition *scope;
1083 struct uploaded_tsv *uploaded_tsvs = NULL;
1084 struct uploaded_tp *uploaded_tps = NULL;
1085
1086 if (!dirname)
1087 error (_("No CTF directory specified."));
1088
1089 ctf_open_dir (dirname);
1090
1091 target_preopen (from_tty);
1092
1093 /* Skip the first packet which about the trace status. The first
1094 event is "frame". */
1095 event = bt_ctf_iter_read_event (ctf_iter);
1096 scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
1097 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
1098 if (event_id != CTF_EVENT_ID_FRAME)
1099 error (_("Wrong event id of the first event"));
1100 /* The second event is "status". */
1101 bt_iter_next (bt_ctf_get_iter (ctf_iter));
1102 event = bt_ctf_iter_read_event (ctf_iter);
1103 scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
1104 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
1105 if (event_id != CTF_EVENT_ID_STATUS)
1106 error (_("Wrong event id of the second event"));
1107 ctf_read_status (event, current_trace_status ());
1108
1109 ctf_read_tsv (&uploaded_tsvs);
1110
1111 ctf_read_tp (&uploaded_tps);
1112
1113 event = bt_ctf_iter_read_event (ctf_iter);
1114 /* EVENT can be NULL if we've already gone to the end of stream of
1115 events. */
1116 if (event != NULL)
1117 {
1118 scope = bt_ctf_get_top_level_scope (event,
1119 BT_STREAM_EVENT_HEADER);
1120 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event,
1121 scope, "id"));
1122 if (event_id != CTF_EVENT_ID_FRAME)
1123 error (_("Wrong event id of the first event of the second packet"));
1124 }
1125
1126 start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1127 gdb_assert (start_pos->type == BT_SEEK_RESTORE);
1128
1129 trace_dirname = xstrdup (dirname);
1130 push_target (&ctf_ops);
1131
de7b2893
YQ
1132 inferior_appeared (current_inferior (), CTF_PID);
1133 inferior_ptid = pid_to_ptid (CTF_PID);
1134 add_thread_silent (inferior_ptid);
1135
393fd4c3
YQ
1136 merge_uploaded_trace_state_variables (&uploaded_tsvs);
1137 merge_uploaded_tracepoints (&uploaded_tps);
5723a6fd
YQ
1138
1139 post_create_inferior (&ctf_ops, from_tty);
393fd4c3
YQ
1140}
1141
1142/* This is the implementation of target_ops method to_close. Destroy
1143 CTF iterator and context. */
1144
1145static void
de90e03d 1146ctf_close (struct target_ops *self)
393fd4c3 1147{
de7b2893
YQ
1148 int pid;
1149
393fd4c3
YQ
1150 ctf_destroy ();
1151 xfree (trace_dirname);
1152 trace_dirname = NULL;
aef525cb 1153
de7b2893
YQ
1154 pid = ptid_get_pid (inferior_ptid);
1155 inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
1156 exit_inferior_silent (pid);
1157
aef525cb 1158 trace_reset_local_state ();
393fd4c3
YQ
1159}
1160
1161/* This is the implementation of target_ops method to_files_info.
1162 Print the directory name of CTF trace data. */
1163
1164static void
1165ctf_files_info (struct target_ops *t)
1166{
1167 printf_filtered ("\t`%s'\n", trace_dirname);
1168}
1169
1170/* This is the implementation of target_ops method to_fetch_registers.
1171 Iterate over events whose name is "register" in current frame,
1172 extract contents from events, and set REGCACHE with the contents.
1173 If no matched events are found, mark registers unavailable. */
1174
1175static void
1176ctf_fetch_registers (struct target_ops *ops,
1177 struct regcache *regcache, int regno)
1178{
ac7936df 1179 struct gdbarch *gdbarch = regcache->arch ();
393fd4c3
YQ
1180 struct bt_ctf_event *event = NULL;
1181 struct bt_iter_pos *pos;
1182
1183 /* An uninitialized reg size says we're not going to be
1184 successful at getting register blocks. */
1185 if (trace_regblock_size == 0)
1186 return;
1187
1188 gdb_assert (ctf_iter != NULL);
1189 /* Save the current position. */
1190 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1191 gdb_assert (pos->type == BT_SEEK_RESTORE);
1192
1193 while (1)
1194 {
1195 const char *name;
1196 struct bt_ctf_event *event1;
1197
1198 event1 = bt_ctf_iter_read_event (ctf_iter);
1199
1200 name = bt_ctf_event_name (event1);
1201
1202 if (name == NULL || strcmp (name, "frame") == 0)
1203 break;
1204 else if (strcmp (name, "register") == 0)
1205 {
1206 event = event1;
1207 break;
1208 }
1209
1210 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1211 break;
1212 }
1213
1214 /* Restore the position. */
1215 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1216
1217 if (event != NULL)
1218 {
48b6e87e 1219 int offset, regsize, regn;
393fd4c3
YQ
1220 const struct bt_definition *scope
1221 = bt_ctf_get_top_level_scope (event,
1222 BT_EVENT_FIELDS);
1223 const struct bt_definition *array
1224 = bt_ctf_get_field (event, scope, "contents");
48b6e87e 1225 gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);
393fd4c3 1226
393fd4c3
YQ
1227 /* Assume the block is laid out in GDB register number order,
1228 each register with the size that it has in GDB. */
1229 offset = 0;
1230 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
1231 {
1232 regsize = register_size (gdbarch, regn);
1233 /* Make sure we stay within block bounds. */
1234 if (offset + regsize >= trace_regblock_size)
1235 break;
1236 if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
1237 {
1238 if (regno == regn)
1239 {
1240 regcache_raw_supply (regcache, regno, regs + offset);
1241 break;
1242 }
1243 else if (regno == -1)
1244 {
1245 regcache_raw_supply (regcache, regn, regs + offset);
1246 }
1247 }
1248 offset += regsize;
1249 }
393fd4c3 1250 }
48b6e87e
YQ
1251 else
1252 tracefile_fetch_registers (regcache, regno);
393fd4c3
YQ
1253}
1254
1255/* This is the implementation of target_ops method to_xfer_partial.
1256 Iterate over events whose name is "memory" in
1257 current frame, extract the address and length from events. If
1258 OFFSET is within the range, read the contents from events to
1259 READBUF. */
1260
9b409511 1261static enum target_xfer_status
393fd4c3
YQ
1262ctf_xfer_partial (struct target_ops *ops, enum target_object object,
1263 const char *annex, gdb_byte *readbuf,
1264 const gdb_byte *writebuf, ULONGEST offset,
9b409511 1265 ULONGEST len, ULONGEST *xfered_len)
393fd4c3
YQ
1266{
1267 /* We're only doing regular memory for now. */
1268 if (object != TARGET_OBJECT_MEMORY)
c9244484 1269 return TARGET_XFER_E_IO;
393fd4c3
YQ
1270
1271 if (readbuf == NULL)
1272 error (_("ctf_xfer_partial: trace file is read-only"));
1273
1274 if (get_traceframe_number () != -1)
1275 {
1276 struct bt_iter_pos *pos;
8acf9577 1277 enum target_xfer_status res;
290a839c
YQ
1278 /* Records the lowest available address of all blocks that
1279 intersects the requested range. */
1280 ULONGEST low_addr_available = 0;
393fd4c3
YQ
1281
1282 gdb_assert (ctf_iter != NULL);
1283 /* Save the current position. */
1284 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1285 gdb_assert (pos->type == BT_SEEK_RESTORE);
1286
1287 /* Iterate through the traceframe's blocks, looking for
1288 memory. */
1289 while (1)
1290 {
1291 ULONGEST amt;
1292 uint64_t maddr;
1293 uint16_t mlen;
393fd4c3
YQ
1294 const struct bt_definition *scope;
1295 const struct bt_definition *def;
1296 struct bt_ctf_event *event
1297 = bt_ctf_iter_read_event (ctf_iter);
1298 const char *name = bt_ctf_event_name (event);
1299
dac3e710 1300 if (name == NULL || strcmp (name, "frame") == 0)
393fd4c3
YQ
1301 break;
1302 else if (strcmp (name, "memory") != 0)
1303 {
1304 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1305 break;
1306
1307 continue;
1308 }
1309
1310 scope = bt_ctf_get_top_level_scope (event,
1311 BT_EVENT_FIELDS);
1312
1313 def = bt_ctf_get_field (event, scope, "address");
1314 maddr = bt_ctf_get_uint64 (def);
1315 def = bt_ctf_get_field (event, scope, "length");
1316 mlen = (uint16_t) bt_ctf_get_uint64 (def);
1317
1318 /* If the block includes the first part of the desired
1319 range, return as much it has; GDB will re-request the
1320 remainder, which might be in a different block of this
1321 trace frame. */
1322 if (maddr <= offset && offset < (maddr + mlen))
1323 {
1324 const struct bt_definition *array
1325 = bt_ctf_get_field (event, scope, "contents");
393fd4c3
YQ
1326 gdb_byte *contents;
1327 int k;
1328
224c3ddb 1329 contents = (gdb_byte *) xmalloc (mlen);
393fd4c3
YQ
1330
1331 for (k = 0; k < mlen; k++)
1332 {
1333 const struct bt_definition *element
1334 = bt_ctf_get_index (event, array, k);
1335
1336 contents[k] = (gdb_byte) bt_ctf_get_uint64 (element);
1337 }
1338
1339 amt = (maddr + mlen) - offset;
1340 if (amt > len)
1341 amt = len;
1342
1343 memcpy (readbuf, &contents[offset - maddr], amt);
1344
1345 xfree (contents);
1346
1347 /* Restore the position. */
1348 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1349
9b409511
YQ
1350 if (amt == 0)
1351 return TARGET_XFER_EOF;
1352 else
1353 {
1354 *xfered_len = amt;
1355 return TARGET_XFER_OK;
1356 }
393fd4c3
YQ
1357 }
1358
290a839c
YQ
1359 if (offset < maddr && maddr < (offset + len))
1360 if (low_addr_available == 0 || low_addr_available > maddr)
1361 low_addr_available = maddr;
1362
393fd4c3
YQ
1363 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1364 break;
1365 }
1366
1367 /* Restore the position. */
1368 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
393fd4c3 1369
8acf9577
YQ
1370 /* Requested memory is unavailable in the context of traceframes,
1371 and this address falls within a read-only section, fallback
290a839c
YQ
1372 to reading from executable, up to LOW_ADDR_AVAILABLE */
1373 if (offset < low_addr_available)
325fac50 1374 len = std::min (len, low_addr_available - offset);
8acf9577
YQ
1375 res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
1376
1377 if (res == TARGET_XFER_OK)
1378 return TARGET_XFER_OK;
1379 else
1380 {
1381 /* No use trying further, we know some memory starting
1382 at MEMADDR isn't available. */
1383 *xfered_len = len;
1384 return TARGET_XFER_UNAVAILABLE;
1385 }
1ee79381
YQ
1386 }
1387 else
1388 {
1389 /* Fallback to reading from read-only sections. */
1390 return section_table_read_available_memory (readbuf, offset, len, xfered_len);
1391 }
393fd4c3
YQ
1392}
1393
1394/* This is the implementation of target_ops method
1395 to_get_trace_state_variable_value.
1396 Iterate over events whose name is "tsv" in current frame. When the
1397 trace variable is found, set the value of it to *VAL and return
1398 true, otherwise return false. */
1399
1400static int
4011015b
TT
1401ctf_get_trace_state_variable_value (struct target_ops *self,
1402 int tsvnum, LONGEST *val)
393fd4c3
YQ
1403{
1404 struct bt_iter_pos *pos;
1405 int found = 0;
1406
1407 gdb_assert (ctf_iter != NULL);
1408 /* Save the current position. */
1409 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1410 gdb_assert (pos->type == BT_SEEK_RESTORE);
1411
1412 /* Iterate through the traceframe's blocks, looking for 'V'
1413 block. */
1414 while (1)
1415 {
1416 struct bt_ctf_event *event
1417 = bt_ctf_iter_read_event (ctf_iter);
1418 const char *name = bt_ctf_event_name (event);
1419
1420 if (name == NULL || strcmp (name, "frame") == 0)
1421 break;
1422 else if (strcmp (name, "tsv") == 0)
1423 {
1424 const struct bt_definition *scope;
1425 const struct bt_definition *def;
1426
1427 scope = bt_ctf_get_top_level_scope (event,
1428 BT_EVENT_FIELDS);
1429
1430 def = bt_ctf_get_field (event, scope, "num");
1431 if (tsvnum == (int32_t) bt_ctf_get_uint64 (def))
1432 {
1433 def = bt_ctf_get_field (event, scope, "val");
1434 *val = bt_ctf_get_uint64 (def);
1435
1436 found = 1;
1437 }
1438 }
1439
1440 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1441 break;
1442 }
1443
1444 /* Restore the position. */
1445 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1446
1447 return found;
1448}
1449
1450/* Return the tracepoint number in "frame" event. */
1451
1452static int
1453ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event)
1454{
1455 /* The packet context of events has a field "tpnum". */
1456 const struct bt_definition *scope
1457 = bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT);
1458 uint64_t tpnum
1459 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum"));
1460
1461 return (int) tpnum;
1462}
1463
1464/* Return the address at which the current frame was collected. */
1465
1466static CORE_ADDR
1467ctf_get_traceframe_address (void)
1468{
1469 struct bt_ctf_event *event = NULL;
1470 struct bt_iter_pos *pos;
1471 CORE_ADDR addr = 0;
1472
1473 gdb_assert (ctf_iter != NULL);
1474 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1475 gdb_assert (pos->type == BT_SEEK_RESTORE);
1476
1477 while (1)
1478 {
1479 const char *name;
1480 struct bt_ctf_event *event1;
1481
1482 event1 = bt_ctf_iter_read_event (ctf_iter);
1483
1484 name = bt_ctf_event_name (event1);
1485
1486 if (name == NULL)
1487 break;
1488 else if (strcmp (name, "frame") == 0)
1489 {
1490 event = event1;
1491 break;
1492 }
1493
1494 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1495 break;
1496 }
1497
1498 if (event != NULL)
1499 {
1500 int tpnum = ctf_get_tpnum_from_frame_event (event);
1501 struct tracepoint *tp
1502 = get_tracepoint_by_number_on_target (tpnum);
1503
c1fc2657
SM
1504 if (tp && tp->loc)
1505 addr = tp->loc->address;
393fd4c3
YQ
1506 }
1507
1508 /* Restore the position. */
1509 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1510
1511 return addr;
1512}
1513
1514/* This is the implementation of target_ops method to_trace_find.
1515 Iterate the events whose name is "frame", extract the tracepoint
1516 number in it. Return traceframe number when matched. */
1517
1518static int
bd4c6793 1519ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
393fd4c3
YQ
1520 CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
1521{
393fd4c3
YQ
1522 int tfnum = 0;
1523 int found = 0;
393fd4c3
YQ
1524
1525 if (num == -1)
1526 {
1527 if (tpp != NULL)
1528 *tpp = -1;
1529 return -1;
1530 }
1531
1532 gdb_assert (ctf_iter != NULL);
1533 /* Set iterator back to the start. */
1534 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos);
1535
1536 while (1)
1537 {
393fd4c3
YQ
1538 struct bt_ctf_event *event;
1539 const char *name;
1540
1541 event = bt_ctf_iter_read_event (ctf_iter);
1542
1543 name = bt_ctf_event_name (event);
1544
1545 if (event == NULL || name == NULL)
1546 break;
1547
1548 if (strcmp (name, "frame") == 0)
1549 {
1550 CORE_ADDR tfaddr;
1551
1552 if (type == tfind_number)
1553 {
1554 /* Looking for a specific trace frame. */
1555 if (tfnum == num)
1556 found = 1;
1557 }
1558 else
1559 {
1560 /* Start from the _next_ trace frame. */
1561 if (tfnum > get_traceframe_number ())
1562 {
1563 switch (type)
1564 {
1565 case tfind_tp:
1566 {
1567 struct tracepoint *tp = get_tracepoint (num);
1568
1569 if (tp != NULL
1570 && (tp->number_on_target
1571 == ctf_get_tpnum_from_frame_event (event)))
1572 found = 1;
1573 break;
1574 }
1575 case tfind_pc:
1576 tfaddr = ctf_get_traceframe_address ();
1577 if (tfaddr == addr1)
1578 found = 1;
1579 break;
1580 case tfind_range:
1581 tfaddr = ctf_get_traceframe_address ();
1582 if (addr1 <= tfaddr && tfaddr <= addr2)
1583 found = 1;
1584 break;
1585 case tfind_outside:
1586 tfaddr = ctf_get_traceframe_address ();
1587 if (!(addr1 <= tfaddr && tfaddr <= addr2))
1588 found = 1;
1589 break;
1590 default:
1591 internal_error (__FILE__, __LINE__, _("unknown tfind type"));
1592 }
1593 }
1594 }
1595 if (found)
1596 {
1597 if (tpp != NULL)
1598 *tpp = ctf_get_tpnum_from_frame_event (event);
1599
1600 /* Skip the event "frame". */
1601 bt_iter_next (bt_ctf_get_iter (ctf_iter));
1602
1603 return tfnum;
1604 }
1605 tfnum++;
1606 }
1607
1608 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1609 break;
1610 }
1611
1612 return -1;
1613}
1614
393fd4c3
YQ
1615/* This is the implementation of target_ops method to_traceframe_info.
1616 Iterate the events whose name is "memory", in current
1617 frame, extract memory range information, and return them in
1618 traceframe_info. */
1619
2098b393 1620static traceframe_info_up
a893e81f 1621ctf_traceframe_info (struct target_ops *self)
393fd4c3 1622{
2098b393 1623 traceframe_info_up info (new traceframe_info);
393fd4c3
YQ
1624 const char *name;
1625 struct bt_iter_pos *pos;
1626
1627 gdb_assert (ctf_iter != NULL);
1628 /* Save the current position. */
1629 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1630 gdb_assert (pos->type == BT_SEEK_RESTORE);
1631
1632 do
1633 {
1634 struct bt_ctf_event *event
1635 = bt_ctf_iter_read_event (ctf_iter);
1636
1637 name = bt_ctf_event_name (event);
1638
1639 if (name == NULL || strcmp (name, "register") == 0
1640 || strcmp (name, "frame") == 0)
1641 ;
1642 else if (strcmp (name, "memory") == 0)
1643 {
1644 const struct bt_definition *scope
1645 = bt_ctf_get_top_level_scope (event,
1646 BT_EVENT_FIELDS);
1647 const struct bt_definition *def;
393fd4c3 1648
393fd4c3 1649 def = bt_ctf_get_field (event, scope, "address");
4cdd21a8 1650 CORE_ADDR start = bt_ctf_get_uint64 (def);
393fd4c3
YQ
1651
1652 def = bt_ctf_get_field (event, scope, "length");
4cdd21a8
SM
1653 int length = (uint16_t) bt_ctf_get_uint64 (def);
1654
1655 info->memory.emplace_back (start, length);
393fd4c3 1656 }
28a93511
YQ
1657 else if (strcmp (name, "tsv") == 0)
1658 {
1659 int vnum;
1660 const struct bt_definition *scope
1661 = bt_ctf_get_top_level_scope (event,
1662 BT_EVENT_FIELDS);
1663 const struct bt_definition *def;
1664
1665 def = bt_ctf_get_field (event, scope, "num");
eed2386e 1666 vnum = (int) bt_ctf_get_uint64 (def);
d0d292a2 1667 info->tvars.push_back (vnum);
28a93511 1668 }
393fd4c3
YQ
1669 else
1670 {
1671 warning (_("Unhandled trace block type (%s) "
1672 "while building trace frame info."),
1673 name);
1674 }
1675
1676 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1677 break;
1678 }
1679 while (name != NULL && strcmp (name, "frame") != 0);
1680
1681 /* Restore the position. */
1682 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1683
1684 return info;
1685}
1686
393fd4c3
YQ
1687static void
1688init_ctf_ops (void)
1689{
1690 memset (&ctf_ops, 0, sizeof (ctf_ops));
1691
12e03cd0 1692 init_tracefile_ops (&ctf_ops);
393fd4c3
YQ
1693 ctf_ops.to_shortname = "ctf";
1694 ctf_ops.to_longname = "CTF file";
1695 ctf_ops.to_doc = "Use a CTF directory as a target.\n\
1696Specify the filename of the CTF directory.";
1697 ctf_ops.to_open = ctf_open;
1698 ctf_ops.to_close = ctf_close;
1699 ctf_ops.to_fetch_registers = ctf_fetch_registers;
1700 ctf_ops.to_xfer_partial = ctf_xfer_partial;
1701 ctf_ops.to_files_info = ctf_files_info;
393fd4c3
YQ
1702 ctf_ops.to_trace_find = ctf_trace_find;
1703 ctf_ops.to_get_trace_state_variable_value
1704 = ctf_get_trace_state_variable_value;
393fd4c3 1705 ctf_ops.to_traceframe_info = ctf_traceframe_info;
393fd4c3
YQ
1706}
1707
1708#endif
1709
393fd4c3
YQ
1710/* module initialization */
1711
1712void
1713_initialize_ctf (void)
1714{
1715#if HAVE_LIBBABELTRACE
1716 init_ctf_ops ();
1717
da9160e4 1718 add_target_with_completer (&ctf_ops, filename_completer);
393fd4c3
YQ
1719#endif
1720}
This page took 0.435914 seconds and 4 git commands to generate.