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