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