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