GDB (API)
|
00001 /* CTF format support. 00002 00003 Copyright (C) 2012-2013 Free Software Foundation, Inc. 00004 Contributed by Hui Zhu <hui_zhu@mentor.com> 00005 Contributed by Yao Qi <yao@codesourcery.com> 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "defs.h" 00023 #include "ctf.h" 00024 #include "tracepoint.h" 00025 #include "regcache.h" 00026 #include "gdb_stat.h" 00027 #include "exec.h" 00028 #include "completer.h" 00029 00030 #include <ctype.h> 00031 00032 /* GDB saves trace buffers and other information (such as trace 00033 status) got from the remote target into Common Trace Format (CTF). 00034 The following types of information are expected to save in CTF: 00035 00036 1. The length (in bytes) of register cache. Event "register" will 00037 be defined in metadata, which includes the length. 00038 00039 2. Trace status. Event "status" is defined in metadata, which 00040 includes all aspects of trace status. 00041 00042 3. Uploaded trace variables. Event "tsv_def" is defined in 00043 metadata, which is about all aspects of a uploaded trace variable. 00044 Uploaded tracepoints. Event "tp_def" is defined in meta, which 00045 is about all aspects of an uploaded tracepoint. Note that the 00046 "sequence" (a CTF type, which is a dynamically-sized array.) is 00047 used for "actions" "step_actions" and "cmd_strings". 00048 00049 4. Trace frames. Each trace frame is composed by several blocks 00050 of different types ('R', 'M', 'V'). One trace frame is saved in 00051 one CTF packet and the blocks of this frame are saved as events. 00052 4.1: The trace frame related information (such as the number of 00053 tracepoint associated with this frame) is saved in the packet 00054 context. 00055 4.2: The block 'M', 'R' and 'V' are saved in event "memory", 00056 "register" and "tsv" respectively. 00057 4.3: When iterating over events, babeltrace can't tell iterator 00058 goes to a new packet, so we need a marker or anchor to tell GDB 00059 that iterator goes into a new packet or frame. We define event 00060 "frame". */ 00061 00062 #define CTF_MAGIC 0xC1FC1FC1 00063 #define CTF_SAVE_MAJOR 1 00064 #define CTF_SAVE_MINOR 8 00065 00066 #define CTF_METADATA_NAME "metadata" 00067 #define CTF_DATASTREAM_NAME "datastream" 00068 00069 /* Reserved event id. */ 00070 00071 #define CTF_EVENT_ID_REGISTER 0 00072 #define CTF_EVENT_ID_TSV 1 00073 #define CTF_EVENT_ID_MEMORY 2 00074 #define CTF_EVENT_ID_FRAME 3 00075 #define CTF_EVENT_ID_STATUS 4 00076 #define CTF_EVENT_ID_TSV_DEF 5 00077 #define CTF_EVENT_ID_TP_DEF 6 00078 00079 /* The state kept while writing the CTF datastream file. */ 00080 00081 struct trace_write_handler 00082 { 00083 /* File descriptor of metadata. */ 00084 FILE *metadata_fd; 00085 /* File descriptor of traceframes. */ 00086 FILE *datastream_fd; 00087 00088 /* This is the content size of the current packet. */ 00089 size_t content_size; 00090 00091 /* This is the start offset of current packet. */ 00092 long packet_start; 00093 }; 00094 00095 /* Write metadata in FORMAT. */ 00096 00097 static void 00098 ctf_save_write_metadata (struct trace_write_handler *handler, 00099 const char *format, ...) 00100 { 00101 va_list args; 00102 00103 va_start (args, format); 00104 if (vfprintf (handler->metadata_fd, format, args) < 0) 00105 error (_("Unable to write metadata file (%s)"), 00106 safe_strerror (errno)); 00107 va_end (args); 00108 } 00109 00110 /* Write BUF of length SIZE to datastream file represented by 00111 HANDLER. */ 00112 00113 static int 00114 ctf_save_write (struct trace_write_handler *handler, 00115 const gdb_byte *buf, size_t size) 00116 { 00117 if (fwrite (buf, size, 1, handler->datastream_fd) != 1) 00118 error (_("Unable to write file for saving trace data (%s)"), 00119 safe_strerror (errno)); 00120 00121 handler->content_size += size; 00122 00123 return 0; 00124 } 00125 00126 /* Write a unsigned 32-bit integer to datastream file represented by 00127 HANDLER. */ 00128 00129 #define ctf_save_write_uint32(HANDLER, U32) \ 00130 ctf_save_write (HANDLER, (gdb_byte *) &U32, 4) 00131 00132 /* Write a signed 32-bit integer to datastream file represented by 00133 HANDLER. */ 00134 00135 #define ctf_save_write_int32(HANDLER, INT32) \ 00136 ctf_save_write ((HANDLER), (gdb_byte *) &(INT32), 4) 00137 00138 /* Set datastream file position. Update HANDLER->content_size 00139 if WHENCE is SEEK_CUR. */ 00140 00141 static int 00142 ctf_save_fseek (struct trace_write_handler *handler, long offset, 00143 int whence) 00144 { 00145 gdb_assert (whence != SEEK_END); 00146 gdb_assert (whence != SEEK_SET 00147 || offset <= handler->content_size + handler->packet_start); 00148 00149 if (fseek (handler->datastream_fd, offset, whence)) 00150 error (_("Unable to seek file for saving trace data (%s)"), 00151 safe_strerror (errno)); 00152 00153 if (whence == SEEK_CUR) 00154 handler->content_size += offset; 00155 00156 return 0; 00157 } 00158 00159 /* Change the datastream file position to align on ALIGN_SIZE, 00160 and write BUF to datastream file. The size of BUF is SIZE. */ 00161 00162 static int 00163 ctf_save_align_write (struct trace_write_handler *handler, 00164 const gdb_byte *buf, 00165 size_t size, size_t align_size) 00166 { 00167 long offset 00168 = (align_up (handler->content_size, align_size) 00169 - handler->content_size); 00170 00171 if (ctf_save_fseek (handler, offset, SEEK_CUR)) 00172 return -1; 00173 00174 if (ctf_save_write (handler, buf, size)) 00175 return -1; 00176 00177 return 0; 00178 } 00179 00180 /* Write events to next new packet. */ 00181 00182 static void 00183 ctf_save_next_packet (struct trace_write_handler *handler) 00184 { 00185 handler->packet_start += (handler->content_size + 4); 00186 ctf_save_fseek (handler, handler->packet_start, SEEK_SET); 00187 handler->content_size = 0; 00188 } 00189 00190 /* Write the CTF metadata header. */ 00191 00192 static void 00193 ctf_save_metadata_header (struct trace_write_handler *handler) 00194 { 00195 const char metadata_fmt[] = 00196 "\ntrace {\n" 00197 " major = %u;\n" 00198 " minor = %u;\n" 00199 " byte_order = %s;\n" /* be or le */ 00200 " packet.header := struct {\n" 00201 " uint32_t magic;\n" 00202 " };\n" 00203 "};\n" 00204 "\n" 00205 "stream {\n" 00206 " packet.context := struct {\n" 00207 " uint32_t content_size;\n" 00208 " uint32_t packet_size;\n" 00209 " uint16_t tpnum;\n" 00210 " };\n" 00211 " event.header := struct {\n" 00212 " uint32_t id;\n" 00213 " };\n" 00214 "};\n"; 00215 00216 ctf_save_write_metadata (handler, "/* CTF %d.%d */\n", 00217 CTF_SAVE_MAJOR, CTF_SAVE_MINOR); 00218 ctf_save_write_metadata (handler, 00219 "typealias integer { size = 8; align = 8; " 00220 "signed = false; encoding = ascii;}" 00221 " := ascii;\n"); 00222 ctf_save_write_metadata (handler, 00223 "typealias integer { size = 8; align = 8; " 00224 "signed = false; }" 00225 " := uint8_t;\n"); 00226 ctf_save_write_metadata (handler, 00227 "typealias integer { size = 16; align = 16;" 00228 "signed = false; } := uint16_t;\n"); 00229 ctf_save_write_metadata (handler, 00230 "typealias integer { size = 32; align = 32;" 00231 "signed = false; } := uint32_t;\n"); 00232 ctf_save_write_metadata (handler, 00233 "typealias integer { size = 64; align = 64;" 00234 "signed = false; base = hex;}" 00235 " := uint64_t;\n"); 00236 ctf_save_write_metadata (handler, 00237 "typealias integer { size = 32; align = 32;" 00238 "signed = true; } := int32_t;\n"); 00239 ctf_save_write_metadata (handler, 00240 "typealias integer { size = 64; align = 64;" 00241 "signed = true; } := int64_t;\n"); 00242 ctf_save_write_metadata (handler, 00243 "typealias string { encoding = ascii;" 00244 " } := chars;\n"); 00245 ctf_save_write_metadata (handler, "\n"); 00246 00247 /* Get the byte order of the host and write CTF data in this byte 00248 order. */ 00249 #if WORDS_BIGENDIAN 00250 #define HOST_ENDIANNESS "be" 00251 #else 00252 #define HOST_ENDIANNESS "le" 00253 #endif 00254 00255 ctf_save_write_metadata (handler, metadata_fmt, 00256 CTF_SAVE_MAJOR, CTF_SAVE_MINOR, 00257 HOST_ENDIANNESS); 00258 ctf_save_write_metadata (handler, "\n"); 00259 } 00260 00261 /* CTF trace writer. */ 00262 00263 struct ctf_trace_file_writer 00264 { 00265 struct trace_file_writer base; 00266 00267 /* States related to writing CTF trace file. */ 00268 struct trace_write_handler tcs; 00269 }; 00270 00271 /* This is the implementation of trace_file_write_ops method 00272 dtor. */ 00273 00274 static void 00275 ctf_dtor (struct trace_file_writer *self) 00276 { 00277 struct ctf_trace_file_writer *writer 00278 = (struct ctf_trace_file_writer *) self; 00279 00280 if (writer->tcs.metadata_fd != NULL) 00281 fclose (writer->tcs.metadata_fd); 00282 00283 if (writer->tcs.datastream_fd != NULL) 00284 fclose (writer->tcs.datastream_fd); 00285 00286 } 00287 00288 /* This is the implementation of trace_file_write_ops method 00289 target_save. */ 00290 00291 static int 00292 ctf_target_save (struct trace_file_writer *self, 00293 const char *dirname) 00294 { 00295 /* Don't support save trace file to CTF format in the target. */ 00296 return 0; 00297 } 00298 00299 #ifdef USE_WIN32API 00300 #undef mkdir 00301 #define mkdir(pathname, mode) mkdir (pathname) 00302 #endif 00303 00304 /* This is the implementation of trace_file_write_ops method 00305 start. It creates the directory DIRNAME, metadata and datastream 00306 in the directory. */ 00307 00308 static void 00309 ctf_start (struct trace_file_writer *self, const char *dirname) 00310 { 00311 char *file_name; 00312 struct cleanup *old_chain; 00313 struct ctf_trace_file_writer *writer 00314 = (struct ctf_trace_file_writer *) self; 00315 int i; 00316 mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR 00317 #ifdef S_IRGRP 00318 | S_IRGRP 00319 #endif 00320 #ifdef S_IXGRP 00321 | S_IXGRP 00322 #endif 00323 | S_IROTH /* Defined in common/gdb_stat.h if not defined. */ 00324 #ifdef S_IXOTH 00325 | S_IXOTH 00326 #endif 00327 ; 00328 00329 /* Create DIRNAME. */ 00330 if (mkdir (dirname, hmode) && errno != EEXIST) 00331 error (_("Unable to open directory '%s' for saving trace data (%s)"), 00332 dirname, safe_strerror (errno)); 00333 00334 memset (&writer->tcs, '\0', sizeof (writer->tcs)); 00335 00336 file_name = xstrprintf ("%s/%s", dirname, CTF_METADATA_NAME); 00337 old_chain = make_cleanup (xfree, file_name); 00338 00339 writer->tcs.metadata_fd = fopen (file_name, "w"); 00340 if (writer->tcs.metadata_fd == NULL) 00341 error (_("Unable to open file '%s' for saving trace data (%s)"), 00342 file_name, safe_strerror (errno)); 00343 do_cleanups (old_chain); 00344 00345 ctf_save_metadata_header (&writer->tcs); 00346 00347 file_name = xstrprintf ("%s/%s", dirname, CTF_DATASTREAM_NAME); 00348 old_chain = make_cleanup (xfree, file_name); 00349 writer->tcs.datastream_fd = fopen (file_name, "w"); 00350 if (writer->tcs.datastream_fd == NULL) 00351 error (_("Unable to open file '%s' for saving trace data (%s)"), 00352 file_name, safe_strerror (errno)); 00353 do_cleanups (old_chain); 00354 } 00355 00356 /* This is the implementation of trace_file_write_ops method 00357 write_header. Write the types of events on trace variable and 00358 frame. */ 00359 00360 static void 00361 ctf_write_header (struct trace_file_writer *self) 00362 { 00363 struct ctf_trace_file_writer *writer 00364 = (struct ctf_trace_file_writer *) self; 00365 00366 00367 ctf_save_write_metadata (&writer->tcs, "\n"); 00368 ctf_save_write_metadata (&writer->tcs, 00369 "event {\n\tname = \"memory\";\n\tid = %u;\n" 00370 "\tfields := struct { \n" 00371 "\t\tuint64_t address;\n" 00372 "\t\tuint16_t length;\n" 00373 "\t\tuint8_t contents[length];\n" 00374 "\t};\n" 00375 "};\n", CTF_EVENT_ID_MEMORY); 00376 00377 ctf_save_write_metadata (&writer->tcs, "\n"); 00378 ctf_save_write_metadata (&writer->tcs, 00379 "event {\n\tname = \"tsv\";\n\tid = %u;\n" 00380 "\tfields := struct { \n" 00381 "\t\tuint64_t val;\n" 00382 "\t\tuint32_t num;\n" 00383 "\t};\n" 00384 "};\n", CTF_EVENT_ID_TSV); 00385 00386 ctf_save_write_metadata (&writer->tcs, "\n"); 00387 ctf_save_write_metadata (&writer->tcs, 00388 "event {\n\tname = \"frame\";\n\tid = %u;\n" 00389 "\tfields := struct { \n" 00390 "\t};\n" 00391 "};\n", CTF_EVENT_ID_FRAME); 00392 00393 ctf_save_write_metadata (&writer->tcs, "\n"); 00394 ctf_save_write_metadata (&writer->tcs, 00395 "event {\n\tname = \"tsv_def\";\n" 00396 "\tid = %u;\n\tfields := struct { \n" 00397 "\t\tint64_t initial_value;\n" 00398 "\t\tint32_t number;\n" 00399 "\t\tint32_t builtin;\n" 00400 "\t\tchars name;\n" 00401 "\t};\n" 00402 "};\n", CTF_EVENT_ID_TSV_DEF); 00403 00404 ctf_save_write_metadata (&writer->tcs, "\n"); 00405 ctf_save_write_metadata (&writer->tcs, 00406 "event {\n\tname = \"tp_def\";\n" 00407 "\tid = %u;\n\tfields := struct { \n" 00408 "\t\tuint64_t addr;\n" 00409 "\t\tuint64_t traceframe_usage;\n" 00410 "\t\tint32_t number;\n" 00411 "\t\tint32_t enabled;\n" 00412 "\t\tint32_t step;\n" 00413 "\t\tint32_t pass;\n" 00414 "\t\tint32_t hit_count;\n" 00415 "\t\tint32_t type;\n" 00416 "\t\tchars cond;\n" 00417 00418 "\t\tuint32_t action_num;\n" 00419 "\t\tchars actions[action_num];\n" 00420 00421 "\t\tuint32_t step_action_num;\n" 00422 "\t\tchars step_actions[step_action_num];\n" 00423 00424 "\t\tchars at_string;\n" 00425 "\t\tchars cond_string;\n" 00426 00427 "\t\tuint32_t cmd_num;\n" 00428 "\t\tchars cmd_strings[cmd_num];\n" 00429 "\t};\n" 00430 "};\n", CTF_EVENT_ID_TP_DEF); 00431 00432 gdb_assert (writer->tcs.content_size == 0); 00433 gdb_assert (writer->tcs.packet_start == 0); 00434 00435 /* Create a new packet to contain this event. */ 00436 self->ops->frame_ops->start (self, 0); 00437 } 00438 00439 /* This is the implementation of trace_file_write_ops method 00440 write_regblock_type. Write the type of register event in 00441 metadata. */ 00442 00443 static void 00444 ctf_write_regblock_type (struct trace_file_writer *self, int size) 00445 { 00446 struct ctf_trace_file_writer *writer 00447 = (struct ctf_trace_file_writer *) self; 00448 00449 ctf_save_write_metadata (&writer->tcs, "\n"); 00450 00451 ctf_save_write_metadata (&writer->tcs, 00452 "event {\n\tname = \"register\";\n\tid = %u;\n" 00453 "\tfields := struct { \n" 00454 "\t\tascii contents[%d];\n" 00455 "\t};\n" 00456 "};\n", 00457 CTF_EVENT_ID_REGISTER, size); 00458 } 00459 00460 /* This is the implementation of trace_file_write_ops method 00461 write_status. */ 00462 00463 static void 00464 ctf_write_status (struct trace_file_writer *self, 00465 struct trace_status *ts) 00466 { 00467 struct ctf_trace_file_writer *writer 00468 = (struct ctf_trace_file_writer *) self; 00469 uint32_t id; 00470 int32_t int32; 00471 00472 ctf_save_write_metadata (&writer->tcs, "\n"); 00473 ctf_save_write_metadata (&writer->tcs, 00474 "event {\n\tname = \"status\";\n\tid = %u;\n" 00475 "\tfields := struct { \n" 00476 "\t\tint32_t stop_reason;\n" 00477 "\t\tint32_t stopping_tracepoint;\n" 00478 "\t\tint32_t traceframe_count;\n" 00479 "\t\tint32_t traceframes_created;\n" 00480 "\t\tint32_t buffer_free;\n" 00481 "\t\tint32_t buffer_size;\n" 00482 "\t\tint32_t disconnected_tracing;\n" 00483 "\t\tint32_t circular_buffer;\n" 00484 "\t};\n" 00485 "};\n", 00486 CTF_EVENT_ID_STATUS); 00487 00488 id = CTF_EVENT_ID_STATUS; 00489 /* Event Id. */ 00490 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4); 00491 00492 ctf_save_write_int32 (&writer->tcs, ts->stop_reason); 00493 ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint); 00494 ctf_save_write_int32 (&writer->tcs, ts->traceframe_count); 00495 ctf_save_write_int32 (&writer->tcs, ts->traceframes_created); 00496 ctf_save_write_int32 (&writer->tcs, ts->buffer_free); 00497 ctf_save_write_int32 (&writer->tcs, ts->buffer_size); 00498 ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing); 00499 ctf_save_write_int32 (&writer->tcs, ts->circular_buffer); 00500 } 00501 00502 /* This is the implementation of trace_file_write_ops method 00503 write_uploaded_tsv. */ 00504 00505 static void 00506 ctf_write_uploaded_tsv (struct trace_file_writer *self, 00507 struct uploaded_tsv *tsv) 00508 { 00509 struct ctf_trace_file_writer *writer 00510 = (struct ctf_trace_file_writer *) self; 00511 int32_t int32; 00512 int64_t int64; 00513 unsigned int len; 00514 const gdb_byte zero = 0; 00515 00516 /* Event Id. */ 00517 int32 = CTF_EVENT_ID_TSV_DEF; 00518 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4); 00519 00520 /* initial_value */ 00521 int64 = tsv->initial_value; 00522 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8); 00523 00524 /* number */ 00525 ctf_save_write_int32 (&writer->tcs, tsv->number); 00526 00527 /* builtin */ 00528 ctf_save_write_int32 (&writer->tcs, tsv->builtin); 00529 00530 /* name */ 00531 if (tsv->name != NULL) 00532 ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name, 00533 strlen (tsv->name)); 00534 ctf_save_write (&writer->tcs, &zero, 1); 00535 } 00536 00537 /* This is the implementation of trace_file_write_ops method 00538 write_uploaded_tp. */ 00539 00540 static void 00541 ctf_write_uploaded_tp (struct trace_file_writer *self, 00542 struct uploaded_tp *tp) 00543 { 00544 struct ctf_trace_file_writer *writer 00545 = (struct ctf_trace_file_writer *) self; 00546 int32_t int32; 00547 int64_t int64; 00548 uint32_t u32; 00549 const gdb_byte zero = 0; 00550 int a; 00551 char *act; 00552 00553 /* Event Id. */ 00554 int32 = CTF_EVENT_ID_TP_DEF; 00555 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4); 00556 00557 /* address */ 00558 int64 = tp->addr; 00559 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8); 00560 00561 /* traceframe_usage */ 00562 int64 = tp->traceframe_usage; 00563 ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8); 00564 00565 /* number */ 00566 ctf_save_write_int32 (&writer->tcs, tp->number); 00567 00568 /* enabled */ 00569 ctf_save_write_int32 (&writer->tcs, tp->enabled); 00570 00571 /* step */ 00572 ctf_save_write_int32 (&writer->tcs, tp->step); 00573 00574 /* pass */ 00575 ctf_save_write_int32 (&writer->tcs, tp->pass); 00576 00577 /* hit_count */ 00578 ctf_save_write_int32 (&writer->tcs, tp->hit_count); 00579 00580 /* type */ 00581 ctf_save_write_int32 (&writer->tcs, tp->type); 00582 00583 /* condition */ 00584 if (tp->cond != NULL) 00585 ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen (tp->cond)); 00586 ctf_save_write (&writer->tcs, &zero, 1); 00587 00588 /* actions */ 00589 u32 = VEC_length (char_ptr, tp->actions); 00590 ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4); 00591 for (a = 0; VEC_iterate (char_ptr, tp->actions, a, act); ++a) 00592 ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1); 00593 00594 /* step_actions */ 00595 u32 = VEC_length (char_ptr, tp->step_actions); 00596 ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4); 00597 for (a = 0; VEC_iterate (char_ptr, tp->step_actions, a, act); ++a) 00598 ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1); 00599 00600 /* at_string */ 00601 if (tp->at_string != NULL) 00602 ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string, 00603 strlen (tp->at_string)); 00604 ctf_save_write (&writer->tcs, &zero, 1); 00605 00606 /* cond_string */ 00607 if (tp->cond_string != NULL) 00608 ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string, 00609 strlen (tp->cond_string)); 00610 ctf_save_write (&writer->tcs, &zero, 1); 00611 00612 /* cmd_strings */ 00613 u32 = VEC_length (char_ptr, tp->cmd_strings); 00614 ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4); 00615 for (a = 0; VEC_iterate (char_ptr, tp->cmd_strings, a, act); ++a) 00616 ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1); 00617 00618 } 00619 00620 /* This is the implementation of trace_file_write_ops method 00621 write_definition_end. */ 00622 00623 static void 00624 ctf_write_definition_end (struct trace_file_writer *self) 00625 { 00626 struct ctf_trace_file_writer *writer 00627 = (struct ctf_trace_file_writer *) self; 00628 00629 self->ops->frame_ops->end (self); 00630 } 00631 00632 /* The minimal file size of data stream. It is required by 00633 babeltrace. */ 00634 00635 #define CTF_FILE_MIN_SIZE 4096 00636 00637 /* This is the implementation of trace_file_write_ops method 00638 end. */ 00639 00640 static void 00641 ctf_end (struct trace_file_writer *self) 00642 { 00643 struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self; 00644 00645 gdb_assert (writer->tcs.content_size == 0); 00646 /* The babeltrace requires or assumes that the size of datastream 00647 file is greater than 4096 bytes. If we don't generate enough 00648 packets and events, create a fake packet which has zero event, 00649 to use up the space. */ 00650 if (writer->tcs.packet_start < CTF_FILE_MIN_SIZE) 00651 { 00652 uint32_t u32; 00653 00654 /* magic. */ 00655 u32 = CTF_MAGIC; 00656 ctf_save_write_uint32 (&writer->tcs, u32); 00657 00658 /* content_size. */ 00659 u32 = 0; 00660 ctf_save_write_uint32 (&writer->tcs, u32); 00661 00662 /* packet_size. */ 00663 u32 = 12; 00664 if (writer->tcs.packet_start + u32 < CTF_FILE_MIN_SIZE) 00665 u32 = CTF_FILE_MIN_SIZE - writer->tcs.packet_start; 00666 00667 u32 *= TARGET_CHAR_BIT; 00668 ctf_save_write_uint32 (&writer->tcs, u32); 00669 00670 /* tpnum. */ 00671 u32 = 0; 00672 ctf_save_write (&writer->tcs, (gdb_byte *) &u32, 2); 00673 00674 /* Enlarge the file to CTF_FILE_MIN_SIZE is it is still less 00675 than that. */ 00676 if (CTF_FILE_MIN_SIZE 00677 > (writer->tcs.packet_start + writer->tcs.content_size)) 00678 { 00679 gdb_byte b = 0; 00680 00681 /* Fake the content size to avoid assertion failure in 00682 ctf_save_fseek. */ 00683 writer->tcs.content_size = (CTF_FILE_MIN_SIZE 00684 - 1 - writer->tcs.packet_start); 00685 ctf_save_fseek (&writer->tcs, CTF_FILE_MIN_SIZE - 1, 00686 SEEK_SET); 00687 ctf_save_write (&writer->tcs, &b, 1); 00688 } 00689 } 00690 } 00691 00692 /* This is the implementation of trace_frame_write_ops method 00693 start. */ 00694 00695 static void 00696 ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum) 00697 { 00698 struct ctf_trace_file_writer *writer 00699 = (struct ctf_trace_file_writer *) self; 00700 uint32_t id = CTF_EVENT_ID_FRAME; 00701 uint32_t u32; 00702 00703 /* Step 1: Write packet context. */ 00704 /* magic. */ 00705 u32 = CTF_MAGIC; 00706 ctf_save_write_uint32 (&writer->tcs, u32); 00707 /* content_size and packet_size.. We still don't know the value, 00708 write it later. */ 00709 ctf_save_fseek (&writer->tcs, 4, SEEK_CUR); 00710 ctf_save_fseek (&writer->tcs, 4, SEEK_CUR); 00711 /* Tracepoint number. */ 00712 ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2); 00713 00714 /* Step 2: Write event "frame". */ 00715 /* Event Id. */ 00716 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4); 00717 } 00718 00719 /* This is the implementation of trace_frame_write_ops method 00720 write_r_block. */ 00721 00722 static void 00723 ctf_write_frame_r_block (struct trace_file_writer *self, 00724 gdb_byte *buf, int32_t size) 00725 { 00726 struct ctf_trace_file_writer *writer 00727 = (struct ctf_trace_file_writer *) self; 00728 uint32_t id = CTF_EVENT_ID_REGISTER; 00729 00730 /* Event Id. */ 00731 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4); 00732 00733 /* array contents. */ 00734 ctf_save_align_write (&writer->tcs, buf, size, 1); 00735 } 00736 00737 /* This is the implementation of trace_frame_write_ops method 00738 write_m_block_header. */ 00739 00740 static void 00741 ctf_write_frame_m_block_header (struct trace_file_writer *self, 00742 uint64_t addr, uint16_t length) 00743 { 00744 struct ctf_trace_file_writer *writer 00745 = (struct ctf_trace_file_writer *) self; 00746 uint32_t event_id = CTF_EVENT_ID_MEMORY; 00747 00748 /* Event Id. */ 00749 ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4); 00750 00751 /* Address. */ 00752 ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8); 00753 00754 /* Length. */ 00755 ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2); 00756 } 00757 00758 /* This is the implementation of trace_frame_write_ops method 00759 write_m_block_memory. */ 00760 00761 static void 00762 ctf_write_frame_m_block_memory (struct trace_file_writer *self, 00763 gdb_byte *buf, uint16_t length) 00764 { 00765 struct ctf_trace_file_writer *writer 00766 = (struct ctf_trace_file_writer *) self; 00767 00768 /* Contents. */ 00769 ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1); 00770 } 00771 00772 /* This is the implementation of trace_frame_write_ops method 00773 write_v_block. */ 00774 00775 static void 00776 ctf_write_frame_v_block (struct trace_file_writer *self, 00777 int32_t num, uint64_t val) 00778 { 00779 struct ctf_trace_file_writer *writer 00780 = (struct ctf_trace_file_writer *) self; 00781 uint32_t id = CTF_EVENT_ID_TSV; 00782 00783 /* Event Id. */ 00784 ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4); 00785 00786 /* val. */ 00787 ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8); 00788 /* num. */ 00789 ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4); 00790 } 00791 00792 /* This is the implementation of trace_frame_write_ops method 00793 end. */ 00794 00795 static void 00796 ctf_write_frame_end (struct trace_file_writer *self) 00797 { 00798 struct ctf_trace_file_writer *writer 00799 = (struct ctf_trace_file_writer *) self; 00800 uint32_t u32; 00801 uint32_t t; 00802 00803 /* Write the content size to packet header. */ 00804 ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4, 00805 SEEK_SET); 00806 u32 = writer->tcs.content_size * TARGET_CHAR_BIT; 00807 00808 t = writer->tcs.content_size; 00809 ctf_save_write_uint32 (&writer->tcs, u32); 00810 00811 /* Write the packet size. */ 00812 u32 += 4 * TARGET_CHAR_BIT; 00813 ctf_save_write_uint32 (&writer->tcs, u32); 00814 00815 writer->tcs.content_size = t; 00816 00817 /* Write zero at the end of the packet. */ 00818 ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t, 00819 SEEK_SET); 00820 u32 = 0; 00821 ctf_save_write_uint32 (&writer->tcs, u32); 00822 writer->tcs.content_size = t; 00823 00824 ctf_save_next_packet (&writer->tcs); 00825 } 00826 00827 /* Operations to write various types of trace frames into CTF 00828 format. */ 00829 00830 static const struct trace_frame_write_ops ctf_write_frame_ops = 00831 { 00832 ctf_write_frame_start, 00833 ctf_write_frame_r_block, 00834 ctf_write_frame_m_block_header, 00835 ctf_write_frame_m_block_memory, 00836 ctf_write_frame_v_block, 00837 ctf_write_frame_end, 00838 }; 00839 00840 /* Operations to write trace buffers into CTF format. */ 00841 00842 static const struct trace_file_write_ops ctf_write_ops = 00843 { 00844 ctf_dtor, 00845 ctf_target_save, 00846 ctf_start, 00847 ctf_write_header, 00848 ctf_write_regblock_type, 00849 ctf_write_status, 00850 ctf_write_uploaded_tsv, 00851 ctf_write_uploaded_tp, 00852 ctf_write_definition_end, 00853 NULL, 00854 &ctf_write_frame_ops, 00855 ctf_end, 00856 }; 00857 00858 /* Return a trace writer for CTF format. */ 00859 00860 struct trace_file_writer * 00861 ctf_trace_file_writer_new (void) 00862 { 00863 struct ctf_trace_file_writer *writer 00864 = xmalloc (sizeof (struct ctf_trace_file_writer)); 00865 00866 writer->base.ops = &ctf_write_ops; 00867 00868 return (struct trace_file_writer *) writer; 00869 } 00870 00871 #if HAVE_LIBBABELTRACE 00872 /* Use libbabeltrace to read CTF data. The libbabeltrace provides 00873 iterator to iterate over each event in CTF data and APIs to get 00874 details of event and packet, so it is very convenient to use 00875 libbabeltrace to access events in CTF. */ 00876 00877 #include <babeltrace/babeltrace.h> 00878 #include <babeltrace/ctf/events.h> 00879 #include <babeltrace/ctf/iterator.h> 00880 00881 /* The struct pointer for current CTF directory. */ 00882 static struct bt_context *ctx = NULL; 00883 static struct bt_ctf_iter *ctf_iter = NULL; 00884 /* The position of the first packet containing trace frame. */ 00885 static struct bt_iter_pos *start_pos; 00886 00887 /* The name of CTF directory. */ 00888 static char *trace_dirname; 00889 00890 static struct target_ops ctf_ops; 00891 00892 /* Destroy ctf iterator and context. */ 00893 00894 static void 00895 ctf_destroy (void) 00896 { 00897 if (ctf_iter != NULL) 00898 { 00899 bt_ctf_iter_destroy (ctf_iter); 00900 ctf_iter = NULL; 00901 } 00902 if (ctx != NULL) 00903 { 00904 bt_context_put (ctx); 00905 ctx = NULL; 00906 } 00907 } 00908 00909 /* Open CTF trace data in DIRNAME. */ 00910 00911 static void 00912 ctf_open_dir (char *dirname) 00913 { 00914 int ret; 00915 struct bt_iter_pos begin_pos; 00916 struct bt_iter_pos *pos; 00917 00918 ctx = bt_context_create (); 00919 if (ctx == NULL) 00920 error (_("Unable to create bt_context")); 00921 ret = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL); 00922 if (ret < 0) 00923 { 00924 ctf_destroy (); 00925 error (_("Unable to use libbabeltrace on directory \"%s\""), 00926 dirname); 00927 } 00928 00929 begin_pos.type = BT_SEEK_BEGIN; 00930 ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL); 00931 if (ctf_iter == NULL) 00932 { 00933 ctf_destroy (); 00934 error (_("Unable to create bt_iterator")); 00935 } 00936 00937 /* Iterate over events, and look for an event for register block 00938 to set trace_regblock_size. */ 00939 00940 /* Save the current position. */ 00941 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 00942 gdb_assert (pos->type == BT_SEEK_RESTORE); 00943 00944 while (1) 00945 { 00946 const char *name; 00947 struct bt_ctf_event *event; 00948 00949 event = bt_ctf_iter_read_event (ctf_iter); 00950 00951 name = bt_ctf_event_name (event); 00952 00953 if (name == NULL) 00954 break; 00955 else if (strcmp (name, "register") == 0) 00956 { 00957 const struct bt_definition *scope 00958 = bt_ctf_get_top_level_scope (event, 00959 BT_EVENT_FIELDS); 00960 const struct bt_definition *array 00961 = bt_ctf_get_field (event, scope, "contents"); 00962 00963 trace_regblock_size 00964 = bt_ctf_get_array_len (bt_ctf_get_decl_from_def (array)); 00965 } 00966 00967 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 00968 break; 00969 } 00970 00971 /* Restore the position. */ 00972 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 00973 } 00974 00975 #define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD) \ 00976 (VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \ 00977 (SCOPE), \ 00978 #FIELD)) 00979 00980 /* EVENT is the "status" event and TS is filled in. */ 00981 00982 static void 00983 ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts) 00984 { 00985 const struct bt_definition *scope 00986 = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS); 00987 00988 SET_INT32_FIELD (event, scope, ts, stop_reason); 00989 SET_INT32_FIELD (event, scope, ts, stopping_tracepoint); 00990 SET_INT32_FIELD (event, scope, ts, traceframe_count); 00991 SET_INT32_FIELD (event, scope, ts, traceframes_created); 00992 SET_INT32_FIELD (event, scope, ts, buffer_free); 00993 SET_INT32_FIELD (event, scope, ts, buffer_size); 00994 SET_INT32_FIELD (event, scope, ts, disconnected_tracing); 00995 SET_INT32_FIELD (event, scope, ts, circular_buffer); 00996 00997 bt_iter_next (bt_ctf_get_iter (ctf_iter)); 00998 } 00999 01000 /* Read the events "tsv_def" one by one, extract its contents and fill 01001 in the list UPLOADED_TSVS. */ 01002 01003 static void 01004 ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs) 01005 { 01006 gdb_assert (ctf_iter != NULL); 01007 01008 while (1) 01009 { 01010 struct bt_ctf_event *event; 01011 const struct bt_definition *scope; 01012 const struct bt_definition *def; 01013 uint32_t event_id; 01014 struct uploaded_tsv *utsv = NULL; 01015 01016 event = bt_ctf_iter_read_event (ctf_iter); 01017 scope = bt_ctf_get_top_level_scope (event, 01018 BT_STREAM_EVENT_HEADER); 01019 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, 01020 "id")); 01021 if (event_id != CTF_EVENT_ID_TSV_DEF) 01022 break; 01023 01024 scope = bt_ctf_get_top_level_scope (event, 01025 BT_EVENT_FIELDS); 01026 01027 def = bt_ctf_get_field (event, scope, "number"); 01028 utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def), 01029 uploaded_tsvs); 01030 01031 def = bt_ctf_get_field (event, scope, "builtin"); 01032 utsv->builtin = (int32_t) bt_ctf_get_int64 (def); 01033 def = bt_ctf_get_field (event, scope, "initial_value"); 01034 utsv->initial_value = bt_ctf_get_int64 (def); 01035 01036 def = bt_ctf_get_field (event, scope, "name"); 01037 utsv->name = xstrdup (bt_ctf_get_string (def)); 01038 01039 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01040 break; 01041 } 01042 01043 } 01044 01045 /* Read the value of element whose index is NUM from CTF and write it 01046 to the corresponding VAR->ARRAY. */ 01047 01048 #define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY) \ 01049 do \ 01050 { \ 01051 uint32_t u32, i; \ 01052 const struct bt_definition *def; \ 01053 \ 01054 u32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT), \ 01055 (SCOPE), \ 01056 #NUM)); \ 01057 def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY); \ 01058 for (i = 0; i < u32; i++) \ 01059 { \ 01060 const struct bt_definition *element \ 01061 = bt_ctf_get_index ((EVENT), def, i); \ 01062 \ 01063 VEC_safe_push (char_ptr, (VAR)->ARRAY, \ 01064 xstrdup (bt_ctf_get_string (element))); \ 01065 } \ 01066 } \ 01067 while (0) 01068 01069 /* Read a string from CTF and set VAR->FIELD. If the length of string 01070 is zero, set VAR->FIELD to NULL. */ 01071 01072 #define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD) \ 01073 do \ 01074 { \ 01075 const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT), \ 01076 (SCOPE), \ 01077 #FIELD)); \ 01078 \ 01079 if (strlen (p) > 0) \ 01080 (VAR)->FIELD = xstrdup (p); \ 01081 else \ 01082 (VAR)->FIELD = NULL; \ 01083 } \ 01084 while (0) 01085 01086 /* Read the events "tp_def" one by one, extract its contents and fill 01087 in the list UPLOADED_TPS. */ 01088 01089 static void 01090 ctf_read_tp (struct uploaded_tp **uploaded_tps) 01091 { 01092 gdb_assert (ctf_iter != NULL); 01093 01094 while (1) 01095 { 01096 struct bt_ctf_event *event; 01097 const struct bt_definition *scope; 01098 uint32_t u32; 01099 int32_t int32; 01100 uint64_t u64; 01101 struct uploaded_tp *utp = NULL; 01102 01103 event = bt_ctf_iter_read_event (ctf_iter); 01104 scope = bt_ctf_get_top_level_scope (event, 01105 BT_STREAM_EVENT_HEADER); 01106 u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, 01107 "id")); 01108 if (u32 != CTF_EVENT_ID_TP_DEF) 01109 break; 01110 01111 scope = bt_ctf_get_top_level_scope (event, 01112 BT_EVENT_FIELDS); 01113 int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event, 01114 scope, 01115 "number")); 01116 u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, 01117 "addr")); 01118 utp = get_uploaded_tp (int32, u64, uploaded_tps); 01119 01120 SET_INT32_FIELD (event, scope, utp, enabled); 01121 SET_INT32_FIELD (event, scope, utp, step); 01122 SET_INT32_FIELD (event, scope, utp, pass); 01123 SET_INT32_FIELD (event, scope, utp, hit_count); 01124 SET_INT32_FIELD (event, scope, utp, type); 01125 01126 /* Read 'cmd_strings'. */ 01127 SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings); 01128 /* Read 'actions'. */ 01129 SET_ARRAY_FIELD (event, scope, utp, action_num, actions); 01130 /* Read 'step_actions'. */ 01131 SET_ARRAY_FIELD (event, scope, utp, step_action_num, 01132 step_actions); 01133 01134 SET_STRING_FIELD(event, scope, utp, at_string); 01135 SET_STRING_FIELD(event, scope, utp, cond_string); 01136 01137 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01138 break; 01139 } 01140 } 01141 01142 /* This is the implementation of target_ops method to_open. Open CTF 01143 trace data, read trace status, trace state variables and tracepoint 01144 definitions from the first packet. Set the start position at the 01145 second packet which contains events on trace blocks. */ 01146 01147 static void 01148 ctf_open (char *dirname, int from_tty) 01149 { 01150 struct bt_ctf_event *event; 01151 uint32_t event_id; 01152 const struct bt_definition *scope; 01153 struct uploaded_tsv *uploaded_tsvs = NULL; 01154 struct uploaded_tp *uploaded_tps = NULL; 01155 01156 if (!dirname) 01157 error (_("No CTF directory specified.")); 01158 01159 ctf_open_dir (dirname); 01160 01161 target_preopen (from_tty); 01162 01163 /* Skip the first packet which about the trace status. The first 01164 event is "frame". */ 01165 event = bt_ctf_iter_read_event (ctf_iter); 01166 scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER); 01167 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id")); 01168 if (event_id != CTF_EVENT_ID_FRAME) 01169 error (_("Wrong event id of the first event")); 01170 /* The second event is "status". */ 01171 bt_iter_next (bt_ctf_get_iter (ctf_iter)); 01172 event = bt_ctf_iter_read_event (ctf_iter); 01173 scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER); 01174 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id")); 01175 if (event_id != CTF_EVENT_ID_STATUS) 01176 error (_("Wrong event id of the second event")); 01177 ctf_read_status (event, current_trace_status ()); 01178 01179 ctf_read_tsv (&uploaded_tsvs); 01180 01181 ctf_read_tp (&uploaded_tps); 01182 01183 event = bt_ctf_iter_read_event (ctf_iter); 01184 /* EVENT can be NULL if we've already gone to the end of stream of 01185 events. */ 01186 if (event != NULL) 01187 { 01188 scope = bt_ctf_get_top_level_scope (event, 01189 BT_STREAM_EVENT_HEADER); 01190 event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, 01191 scope, "id")); 01192 if (event_id != CTF_EVENT_ID_FRAME) 01193 error (_("Wrong event id of the first event of the second packet")); 01194 } 01195 01196 start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 01197 gdb_assert (start_pos->type == BT_SEEK_RESTORE); 01198 01199 trace_dirname = xstrdup (dirname); 01200 push_target (&ctf_ops); 01201 01202 merge_uploaded_trace_state_variables (&uploaded_tsvs); 01203 merge_uploaded_tracepoints (&uploaded_tps); 01204 } 01205 01206 /* This is the implementation of target_ops method to_close. Destroy 01207 CTF iterator and context. */ 01208 01209 static void 01210 ctf_close (void) 01211 { 01212 ctf_destroy (); 01213 xfree (trace_dirname); 01214 trace_dirname = NULL; 01215 01216 trace_reset_local_state (); 01217 } 01218 01219 /* This is the implementation of target_ops method to_files_info. 01220 Print the directory name of CTF trace data. */ 01221 01222 static void 01223 ctf_files_info (struct target_ops *t) 01224 { 01225 printf_filtered ("\t`%s'\n", trace_dirname); 01226 } 01227 01228 /* This is the implementation of target_ops method to_fetch_registers. 01229 Iterate over events whose name is "register" in current frame, 01230 extract contents from events, and set REGCACHE with the contents. 01231 If no matched events are found, mark registers unavailable. */ 01232 01233 static void 01234 ctf_fetch_registers (struct target_ops *ops, 01235 struct regcache *regcache, int regno) 01236 { 01237 struct gdbarch *gdbarch = get_regcache_arch (regcache); 01238 int offset, regn, regsize, pc_regno; 01239 gdb_byte *regs = NULL; 01240 struct bt_ctf_event *event = NULL; 01241 struct bt_iter_pos *pos; 01242 01243 /* An uninitialized reg size says we're not going to be 01244 successful at getting register blocks. */ 01245 if (trace_regblock_size == 0) 01246 return; 01247 01248 gdb_assert (ctf_iter != NULL); 01249 /* Save the current position. */ 01250 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 01251 gdb_assert (pos->type == BT_SEEK_RESTORE); 01252 01253 while (1) 01254 { 01255 const char *name; 01256 struct bt_ctf_event *event1; 01257 01258 event1 = bt_ctf_iter_read_event (ctf_iter); 01259 01260 name = bt_ctf_event_name (event1); 01261 01262 if (name == NULL || strcmp (name, "frame") == 0) 01263 break; 01264 else if (strcmp (name, "register") == 0) 01265 { 01266 event = event1; 01267 break; 01268 } 01269 01270 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01271 break; 01272 } 01273 01274 /* Restore the position. */ 01275 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 01276 01277 if (event != NULL) 01278 { 01279 const struct bt_definition *scope 01280 = bt_ctf_get_top_level_scope (event, 01281 BT_EVENT_FIELDS); 01282 const struct bt_definition *array 01283 = bt_ctf_get_field (event, scope, "contents"); 01284 01285 regs = (gdb_byte *) bt_ctf_get_char_array (array); 01286 /* Assume the block is laid out in GDB register number order, 01287 each register with the size that it has in GDB. */ 01288 offset = 0; 01289 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++) 01290 { 01291 regsize = register_size (gdbarch, regn); 01292 /* Make sure we stay within block bounds. */ 01293 if (offset + regsize >= trace_regblock_size) 01294 break; 01295 if (regcache_register_status (regcache, regn) == REG_UNKNOWN) 01296 { 01297 if (regno == regn) 01298 { 01299 regcache_raw_supply (regcache, regno, regs + offset); 01300 break; 01301 } 01302 else if (regno == -1) 01303 { 01304 regcache_raw_supply (regcache, regn, regs + offset); 01305 } 01306 } 01307 offset += regsize; 01308 } 01309 return; 01310 } 01311 01312 regs = alloca (trace_regblock_size); 01313 01314 /* We get here if no register data has been found. Mark registers 01315 as unavailable. */ 01316 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++) 01317 regcache_raw_supply (regcache, regn, NULL); 01318 01319 /* We can often usefully guess that the PC is going to be the same 01320 as the address of the tracepoint. */ 01321 pc_regno = gdbarch_pc_regnum (gdbarch); 01322 if (pc_regno >= 0 && (regno == -1 || regno == pc_regno)) 01323 { 01324 struct tracepoint *tp = get_tracepoint (get_tracepoint_number ()); 01325 01326 if (tp != NULL && tp->base.loc) 01327 { 01328 /* But don't try to guess if tracepoint is multi-location... */ 01329 if (tp->base.loc->next != NULL) 01330 { 01331 warning (_("Tracepoint %d has multiple " 01332 "locations, cannot infer $pc"), 01333 tp->base.number); 01334 return; 01335 } 01336 /* ... or does while-stepping. */ 01337 if (tp->step_count > 0) 01338 { 01339 warning (_("Tracepoint %d does while-stepping, " 01340 "cannot infer $pc"), 01341 tp->base.number); 01342 return; 01343 } 01344 01345 store_unsigned_integer (regs, register_size (gdbarch, pc_regno), 01346 gdbarch_byte_order (gdbarch), 01347 tp->base.loc->address); 01348 regcache_raw_supply (regcache, pc_regno, regs); 01349 } 01350 } 01351 } 01352 01353 /* This is the implementation of target_ops method to_xfer_partial. 01354 Iterate over events whose name is "memory" in 01355 current frame, extract the address and length from events. If 01356 OFFSET is within the range, read the contents from events to 01357 READBUF. */ 01358 01359 static LONGEST 01360 ctf_xfer_partial (struct target_ops *ops, enum target_object object, 01361 const char *annex, gdb_byte *readbuf, 01362 const gdb_byte *writebuf, ULONGEST offset, 01363 LONGEST len) 01364 { 01365 /* We're only doing regular memory for now. */ 01366 if (object != TARGET_OBJECT_MEMORY) 01367 return -1; 01368 01369 if (readbuf == NULL) 01370 error (_("ctf_xfer_partial: trace file is read-only")); 01371 01372 if (get_traceframe_number () != -1) 01373 { 01374 struct bt_iter_pos *pos; 01375 int i = 0; 01376 01377 gdb_assert (ctf_iter != NULL); 01378 /* Save the current position. */ 01379 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 01380 gdb_assert (pos->type == BT_SEEK_RESTORE); 01381 01382 /* Iterate through the traceframe's blocks, looking for 01383 memory. */ 01384 while (1) 01385 { 01386 ULONGEST amt; 01387 uint64_t maddr; 01388 uint16_t mlen; 01389 enum bfd_endian byte_order 01390 = gdbarch_byte_order (target_gdbarch ()); 01391 const struct bt_definition *scope; 01392 const struct bt_definition *def; 01393 struct bt_ctf_event *event 01394 = bt_ctf_iter_read_event (ctf_iter); 01395 const char *name = bt_ctf_event_name (event); 01396 01397 if (strcmp (name, "frame") == 0) 01398 break; 01399 else if (strcmp (name, "memory") != 0) 01400 { 01401 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01402 break; 01403 01404 continue; 01405 } 01406 01407 scope = bt_ctf_get_top_level_scope (event, 01408 BT_EVENT_FIELDS); 01409 01410 def = bt_ctf_get_field (event, scope, "address"); 01411 maddr = bt_ctf_get_uint64 (def); 01412 def = bt_ctf_get_field (event, scope, "length"); 01413 mlen = (uint16_t) bt_ctf_get_uint64 (def); 01414 01415 /* If the block includes the first part of the desired 01416 range, return as much it has; GDB will re-request the 01417 remainder, which might be in a different block of this 01418 trace frame. */ 01419 if (maddr <= offset && offset < (maddr + mlen)) 01420 { 01421 const struct bt_definition *array 01422 = bt_ctf_get_field (event, scope, "contents"); 01423 const struct bt_declaration *decl 01424 = bt_ctf_get_decl_from_def (array); 01425 gdb_byte *contents; 01426 int k; 01427 01428 contents = xmalloc (mlen); 01429 01430 for (k = 0; k < mlen; k++) 01431 { 01432 const struct bt_definition *element 01433 = bt_ctf_get_index (event, array, k); 01434 01435 contents[k] = (gdb_byte) bt_ctf_get_uint64 (element); 01436 } 01437 01438 amt = (maddr + mlen) - offset; 01439 if (amt > len) 01440 amt = len; 01441 01442 memcpy (readbuf, &contents[offset - maddr], amt); 01443 01444 xfree (contents); 01445 01446 /* Restore the position. */ 01447 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 01448 01449 return amt; 01450 } 01451 01452 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01453 break; 01454 } 01455 01456 /* Restore the position. */ 01457 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 01458 } 01459 01460 /* It's unduly pedantic to refuse to look at the executable for 01461 read-only pieces; so do the equivalent of readonly regions aka 01462 QTro packet. */ 01463 if (exec_bfd != NULL) 01464 { 01465 asection *s; 01466 bfd_size_type size; 01467 bfd_vma vma; 01468 01469 for (s = exec_bfd->sections; s; s = s->next) 01470 { 01471 if ((s->flags & SEC_LOAD) == 0 01472 || (s->flags & SEC_READONLY) == 0) 01473 continue; 01474 01475 vma = s->vma; 01476 size = bfd_get_section_size (s); 01477 if (vma <= offset && offset < (vma + size)) 01478 { 01479 ULONGEST amt; 01480 01481 amt = (vma + size) - offset; 01482 if (amt > len) 01483 amt = len; 01484 01485 amt = bfd_get_section_contents (exec_bfd, s, 01486 readbuf, offset - vma, amt); 01487 return amt; 01488 } 01489 } 01490 } 01491 01492 /* Indicate failure to find the requested memory block. */ 01493 return -1; 01494 } 01495 01496 /* This is the implementation of target_ops method 01497 to_get_trace_state_variable_value. 01498 Iterate over events whose name is "tsv" in current frame. When the 01499 trace variable is found, set the value of it to *VAL and return 01500 true, otherwise return false. */ 01501 01502 static int 01503 ctf_get_trace_state_variable_value (int tsvnum, LONGEST *val) 01504 { 01505 struct bt_iter_pos *pos; 01506 int found = 0; 01507 01508 gdb_assert (ctf_iter != NULL); 01509 /* Save the current position. */ 01510 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 01511 gdb_assert (pos->type == BT_SEEK_RESTORE); 01512 01513 /* Iterate through the traceframe's blocks, looking for 'V' 01514 block. */ 01515 while (1) 01516 { 01517 struct bt_ctf_event *event 01518 = bt_ctf_iter_read_event (ctf_iter); 01519 const char *name = bt_ctf_event_name (event); 01520 01521 if (name == NULL || strcmp (name, "frame") == 0) 01522 break; 01523 else if (strcmp (name, "tsv") == 0) 01524 { 01525 const struct bt_definition *scope; 01526 const struct bt_definition *def; 01527 01528 scope = bt_ctf_get_top_level_scope (event, 01529 BT_EVENT_FIELDS); 01530 01531 def = bt_ctf_get_field (event, scope, "num"); 01532 if (tsvnum == (int32_t) bt_ctf_get_uint64 (def)) 01533 { 01534 def = bt_ctf_get_field (event, scope, "val"); 01535 *val = bt_ctf_get_uint64 (def); 01536 01537 found = 1; 01538 } 01539 } 01540 01541 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01542 break; 01543 } 01544 01545 /* Restore the position. */ 01546 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 01547 01548 return found; 01549 } 01550 01551 /* Return the tracepoint number in "frame" event. */ 01552 01553 static int 01554 ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event) 01555 { 01556 /* The packet context of events has a field "tpnum". */ 01557 const struct bt_definition *scope 01558 = bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT); 01559 uint64_t tpnum 01560 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum")); 01561 01562 return (int) tpnum; 01563 } 01564 01565 /* Return the address at which the current frame was collected. */ 01566 01567 static CORE_ADDR 01568 ctf_get_traceframe_address (void) 01569 { 01570 struct bt_ctf_event *event = NULL; 01571 struct bt_iter_pos *pos; 01572 CORE_ADDR addr = 0; 01573 01574 gdb_assert (ctf_iter != NULL); 01575 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 01576 gdb_assert (pos->type == BT_SEEK_RESTORE); 01577 01578 while (1) 01579 { 01580 const char *name; 01581 struct bt_ctf_event *event1; 01582 01583 event1 = bt_ctf_iter_read_event (ctf_iter); 01584 01585 name = bt_ctf_event_name (event1); 01586 01587 if (name == NULL) 01588 break; 01589 else if (strcmp (name, "frame") == 0) 01590 { 01591 event = event1; 01592 break; 01593 } 01594 01595 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01596 break; 01597 } 01598 01599 if (event != NULL) 01600 { 01601 int tpnum = ctf_get_tpnum_from_frame_event (event); 01602 struct tracepoint *tp 01603 = get_tracepoint_by_number_on_target (tpnum); 01604 01605 if (tp && tp->base.loc) 01606 addr = tp->base.loc->address; 01607 } 01608 01609 /* Restore the position. */ 01610 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 01611 01612 return addr; 01613 } 01614 01615 /* This is the implementation of target_ops method to_trace_find. 01616 Iterate the events whose name is "frame", extract the tracepoint 01617 number in it. Return traceframe number when matched. */ 01618 01619 static int 01620 ctf_trace_find (enum trace_find_type type, int num, 01621 CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) 01622 { 01623 int ret = -1; 01624 int tfnum = 0; 01625 int found = 0; 01626 struct bt_iter_pos pos; 01627 01628 if (num == -1) 01629 { 01630 if (tpp != NULL) 01631 *tpp = -1; 01632 return -1; 01633 } 01634 01635 gdb_assert (ctf_iter != NULL); 01636 /* Set iterator back to the start. */ 01637 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos); 01638 01639 while (1) 01640 { 01641 int id; 01642 struct bt_ctf_event *event; 01643 const char *name; 01644 01645 event = bt_ctf_iter_read_event (ctf_iter); 01646 01647 name = bt_ctf_event_name (event); 01648 01649 if (event == NULL || name == NULL) 01650 break; 01651 01652 if (strcmp (name, "frame") == 0) 01653 { 01654 CORE_ADDR tfaddr; 01655 01656 if (type == tfind_number) 01657 { 01658 /* Looking for a specific trace frame. */ 01659 if (tfnum == num) 01660 found = 1; 01661 } 01662 else 01663 { 01664 /* Start from the _next_ trace frame. */ 01665 if (tfnum > get_traceframe_number ()) 01666 { 01667 switch (type) 01668 { 01669 case tfind_tp: 01670 { 01671 struct tracepoint *tp = get_tracepoint (num); 01672 01673 if (tp != NULL 01674 && (tp->number_on_target 01675 == ctf_get_tpnum_from_frame_event (event))) 01676 found = 1; 01677 break; 01678 } 01679 case tfind_pc: 01680 tfaddr = ctf_get_traceframe_address (); 01681 if (tfaddr == addr1) 01682 found = 1; 01683 break; 01684 case tfind_range: 01685 tfaddr = ctf_get_traceframe_address (); 01686 if (addr1 <= tfaddr && tfaddr <= addr2) 01687 found = 1; 01688 break; 01689 case tfind_outside: 01690 tfaddr = ctf_get_traceframe_address (); 01691 if (!(addr1 <= tfaddr && tfaddr <= addr2)) 01692 found = 1; 01693 break; 01694 default: 01695 internal_error (__FILE__, __LINE__, _("unknown tfind type")); 01696 } 01697 } 01698 } 01699 if (found) 01700 { 01701 if (tpp != NULL) 01702 *tpp = ctf_get_tpnum_from_frame_event (event); 01703 01704 /* Skip the event "frame". */ 01705 bt_iter_next (bt_ctf_get_iter (ctf_iter)); 01706 01707 return tfnum; 01708 } 01709 tfnum++; 01710 } 01711 01712 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01713 break; 01714 } 01715 01716 return -1; 01717 } 01718 01719 /* This is the implementation of target_ops method to_has_stack. 01720 The target has a stack when GDB has already selected one trace 01721 frame. */ 01722 01723 static int 01724 ctf_has_stack (struct target_ops *ops) 01725 { 01726 return get_traceframe_number () != -1; 01727 } 01728 01729 /* This is the implementation of target_ops method to_has_registers. 01730 The target has registers when GDB has already selected one trace 01731 frame. */ 01732 01733 static int 01734 ctf_has_registers (struct target_ops *ops) 01735 { 01736 return get_traceframe_number () != -1; 01737 } 01738 01739 /* This is the implementation of target_ops method to_traceframe_info. 01740 Iterate the events whose name is "memory", in current 01741 frame, extract memory range information, and return them in 01742 traceframe_info. */ 01743 01744 static struct traceframe_info * 01745 ctf_traceframe_info (void) 01746 { 01747 struct traceframe_info *info = XCNEW (struct traceframe_info); 01748 const char *name; 01749 struct bt_iter_pos *pos; 01750 01751 gdb_assert (ctf_iter != NULL); 01752 /* Save the current position. */ 01753 pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); 01754 gdb_assert (pos->type == BT_SEEK_RESTORE); 01755 01756 do 01757 { 01758 struct bt_ctf_event *event 01759 = bt_ctf_iter_read_event (ctf_iter); 01760 01761 name = bt_ctf_event_name (event); 01762 01763 if (name == NULL || strcmp (name, "register") == 0 01764 || strcmp (name, "frame") == 0) 01765 ; 01766 else if (strcmp (name, "memory") == 0) 01767 { 01768 const struct bt_definition *scope 01769 = bt_ctf_get_top_level_scope (event, 01770 BT_EVENT_FIELDS); 01771 const struct bt_definition *def; 01772 struct mem_range *r; 01773 01774 r = VEC_safe_push (mem_range_s, info->memory, NULL); 01775 def = bt_ctf_get_field (event, scope, "address"); 01776 r->start = bt_ctf_get_uint64 (def); 01777 01778 def = bt_ctf_get_field (event, scope, "length"); 01779 r->length = (uint16_t) bt_ctf_get_uint64 (def); 01780 } 01781 else if (strcmp (name, "tsv") == 0) 01782 { 01783 int vnum; 01784 const struct bt_definition *scope 01785 = bt_ctf_get_top_level_scope (event, 01786 BT_EVENT_FIELDS); 01787 const struct bt_definition *def; 01788 01789 def = bt_ctf_get_field (event, scope, "num"); 01790 vnum = (int) bt_ctf_get_int64 (def); 01791 VEC_safe_push (int, info->tvars, vnum); 01792 } 01793 else 01794 { 01795 warning (_("Unhandled trace block type (%s) " 01796 "while building trace frame info."), 01797 name); 01798 } 01799 01800 if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) 01801 break; 01802 } 01803 while (name != NULL && strcmp (name, "frame") != 0); 01804 01805 /* Restore the position. */ 01806 bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); 01807 01808 return info; 01809 } 01810 01811 /* This is the implementation of target_ops method to_get_trace_status. 01812 The trace status for a file is that tracing can never be run. */ 01813 01814 static int 01815 ctf_get_trace_status (struct trace_status *ts) 01816 { 01817 /* Other bits of trace status were collected as part of opening the 01818 trace files, so nothing to do here. */ 01819 01820 return -1; 01821 } 01822 01823 static void 01824 init_ctf_ops (void) 01825 { 01826 memset (&ctf_ops, 0, sizeof (ctf_ops)); 01827 01828 ctf_ops.to_shortname = "ctf"; 01829 ctf_ops.to_longname = "CTF file"; 01830 ctf_ops.to_doc = "Use a CTF directory as a target.\n\ 01831 Specify the filename of the CTF directory."; 01832 ctf_ops.to_open = ctf_open; 01833 ctf_ops.to_close = ctf_close; 01834 ctf_ops.to_fetch_registers = ctf_fetch_registers; 01835 ctf_ops.to_xfer_partial = ctf_xfer_partial; 01836 ctf_ops.to_files_info = ctf_files_info; 01837 ctf_ops.to_get_trace_status = ctf_get_trace_status; 01838 ctf_ops.to_trace_find = ctf_trace_find; 01839 ctf_ops.to_get_trace_state_variable_value 01840 = ctf_get_trace_state_variable_value; 01841 ctf_ops.to_stratum = process_stratum; 01842 ctf_ops.to_has_stack = ctf_has_stack; 01843 ctf_ops.to_has_registers = ctf_has_registers; 01844 ctf_ops.to_traceframe_info = ctf_traceframe_info; 01845 ctf_ops.to_magic = OPS_MAGIC; 01846 } 01847 01848 #endif 01849 01850 /* -Wmissing-prototypes */ 01851 01852 extern initialize_file_ftype _initialize_ctf; 01853 01854 /* module initialization */ 01855 01856 void 01857 _initialize_ctf (void) 01858 { 01859 #if HAVE_LIBBABELTRACE 01860 init_ctf_ops (); 01861 01862 add_target_with_completer (&ctf_ops, filename_completer); 01863 #endif 01864 }