X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fctf.c;h=21ed11311f5cae2df66b76acf4cd7331f52d336c;hb=2098b39391a5ade9ed308d76f2dfc7ceedd2d9a3;hp=bac7c28425cdd848828220dd8dfb1c862099d098;hpb=48b6e87ef297136a6409c2c993c4626f28bbb4d1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ctf.c b/gdb/ctf.c index bac7c28425..21ed11311f 100644 --- a/gdb/ctf.c +++ b/gdb/ctf.c @@ -1,6 +1,6 @@ /* CTF format support. - Copyright (C) 2012-2014 Free Software Foundation, Inc. + Copyright (C) 2012-2017 Free Software Foundation, Inc. Contributed by Hui Zhu Contributed by Yao Qi @@ -29,8 +29,8 @@ #include "inferior.h" #include "gdbthread.h" #include "tracefile.h" - #include +#include /* GDB saves trace buffers and other information (such as trace status) got from the remote target into Common Trace Format (CTF). @@ -99,6 +99,11 @@ struct trace_write_handler /* Write metadata in FORMAT. */ +static void +ctf_save_write_metadata (struct trace_write_handler *handler, + const char *format, ...) + ATTRIBUTE_PRINTF (2, 3); + static void ctf_save_write_metadata (struct trace_write_handler *handler, const char *format, ...) @@ -197,27 +202,6 @@ ctf_save_next_packet (struct trace_write_handler *handler) static void ctf_save_metadata_header (struct trace_write_handler *handler) { - const char metadata_fmt[] = - "\ntrace {\n" - " major = %u;\n" - " minor = %u;\n" - " byte_order = %s;\n" /* be or le */ - " packet.header := struct {\n" - " uint32_t magic;\n" - " };\n" - "};\n" - "\n" - "stream {\n" - " packet.context := struct {\n" - " uint32_t content_size;\n" - " uint32_t packet_size;\n" - " uint16_t tpnum;\n" - " };\n" - " event.header := struct {\n" - " uint32_t id;\n" - " };\n" - "};\n"; - ctf_save_write_metadata (handler, "/* CTF %d.%d */\n", CTF_SAVE_MAJOR, CTF_SAVE_MINOR); ctf_save_write_metadata (handler, @@ -257,7 +241,26 @@ ctf_save_metadata_header (struct trace_write_handler *handler) #define HOST_ENDIANNESS "le" #endif - ctf_save_write_metadata (handler, metadata_fmt, + ctf_save_write_metadata (handler, + "\ntrace {\n" + " major = %u;\n" + " minor = %u;\n" + " byte_order = %s;\n" + " packet.header := struct {\n" + " uint32_t magic;\n" + " };\n" + "};\n" + "\n" + "stream {\n" + " packet.context := struct {\n" + " uint32_t content_size;\n" + " uint32_t packet_size;\n" + " uint16_t tpnum;\n" + " };\n" + " event.header := struct {\n" + " uint32_t id;\n" + " };\n" + "};\n", CTF_SAVE_MAJOR, CTF_SAVE_MINOR, HOST_ENDIANNESS); ctf_save_write_metadata (handler, "\n"); @@ -301,11 +304,6 @@ ctf_target_save (struct trace_file_writer *self, return 0; } -#ifdef USE_WIN32API -#undef mkdir -#define mkdir(pathname, mode) mkdir (pathname) -#endif - /* This is the implementation of trace_file_write_ops method start. It creates the directory DIRNAME, metadata and datastream in the directory. */ @@ -313,8 +311,6 @@ ctf_target_save (struct trace_file_writer *self, static void ctf_start (struct trace_file_writer *self, const char *dirname) { - char *file_name; - struct cleanup *old_chain; struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self; int i; @@ -327,24 +323,20 @@ ctf_start (struct trace_file_writer *self, const char *dirname) memset (&writer->tcs, '\0', sizeof (writer->tcs)); - file_name = xstrprintf ("%s/%s", dirname, CTF_METADATA_NAME); - old_chain = make_cleanup (xfree, file_name); + std::string file_name = string_printf ("%s/%s", dirname, CTF_METADATA_NAME); - writer->tcs.metadata_fd = fopen (file_name, "w"); + writer->tcs.metadata_fd = fopen (file_name.c_str (), "w"); if (writer->tcs.metadata_fd == NULL) error (_("Unable to open file '%s' for saving trace data (%s)"), - file_name, safe_strerror (errno)); - do_cleanups (old_chain); + file_name.c_str (), safe_strerror (errno)); ctf_save_metadata_header (&writer->tcs); - file_name = xstrprintf ("%s/%s", dirname, CTF_DATASTREAM_NAME); - old_chain = make_cleanup (xfree, file_name); - writer->tcs.datastream_fd = fopen (file_name, "w"); + file_name = string_printf ("%s/%s", dirname, CTF_DATASTREAM_NAME); + writer->tcs.datastream_fd = fopen (file_name.c_str (), "w"); if (writer->tcs.datastream_fd == NULL) error (_("Unable to open file '%s' for saving trace data (%s)"), - file_name, safe_strerror (errno)); - do_cleanups (old_chain); + file_name.c_str (), safe_strerror (errno)); } /* This is the implementation of trace_file_write_ops method @@ -611,6 +603,15 @@ ctf_write_uploaded_tp (struct trace_file_writer *self, } +/* This is the implementation of trace_file_write_ops method + write_tdesc. */ + +static void +ctf_write_tdesc (struct trace_file_writer *self) +{ + /* Nothing so far. */ +} + /* This is the implementation of trace_file_write_ops method write_definition_end. */ @@ -623,11 +624,6 @@ ctf_write_definition_end (struct trace_file_writer *self) self->ops->frame_ops->end (self); } -/* The minimal file size of data stream. It is required by - babeltrace. */ - -#define CTF_FILE_MIN_SIZE 4096 - /* This is the implementation of trace_file_write_ops method end. */ @@ -637,50 +633,6 @@ ctf_end (struct trace_file_writer *self) struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self; gdb_assert (writer->tcs.content_size == 0); - /* The babeltrace requires or assumes that the size of datastream - file is greater than 4096 bytes. If we don't generate enough - packets and events, create a fake packet which has zero event, - to use up the space. */ - if (writer->tcs.packet_start < CTF_FILE_MIN_SIZE) - { - uint32_t u32; - - /* magic. */ - u32 = CTF_MAGIC; - ctf_save_write_uint32 (&writer->tcs, u32); - - /* content_size. */ - u32 = 0; - ctf_save_write_uint32 (&writer->tcs, u32); - - /* packet_size. */ - u32 = 12; - if (writer->tcs.packet_start + u32 < CTF_FILE_MIN_SIZE) - u32 = CTF_FILE_MIN_SIZE - writer->tcs.packet_start; - - u32 *= TARGET_CHAR_BIT; - ctf_save_write_uint32 (&writer->tcs, u32); - - /* tpnum. */ - u32 = 0; - ctf_save_write (&writer->tcs, (gdb_byte *) &u32, 2); - - /* Enlarge the file to CTF_FILE_MIN_SIZE is it is still less - than that. */ - if (CTF_FILE_MIN_SIZE - > (writer->tcs.packet_start + writer->tcs.content_size)) - { - gdb_byte b = 0; - - /* Fake the content size to avoid assertion failure in - ctf_save_fseek. */ - writer->tcs.content_size = (CTF_FILE_MIN_SIZE - - 1 - writer->tcs.packet_start); - ctf_save_fseek (&writer->tcs, CTF_FILE_MIN_SIZE - 1, - SEEK_SET); - ctf_save_write (&writer->tcs, &b, 1); - } - } } /* This is the implementation of trace_frame_write_ops method @@ -843,6 +795,7 @@ static const struct trace_file_write_ops ctf_write_ops = ctf_write_status, ctf_write_uploaded_tsv, ctf_write_uploaded_tp, + ctf_write_tdesc, ctf_write_definition_end, NULL, &ctf_write_frame_ops, @@ -854,8 +807,7 @@ static const struct trace_file_write_ops ctf_write_ops = struct trace_file_writer * ctf_trace_file_writer_new (void) { - struct ctf_trace_file_writer *writer - = xmalloc (sizeof (struct ctf_trace_file_writer)); + struct ctf_trace_file_writer *writer = XNEW (struct ctf_trace_file_writer); writer->base.ops = &ctf_write_ops; @@ -904,7 +856,7 @@ ctf_destroy (void) /* Open CTF trace data in DIRNAME. */ static void -ctf_open_dir (char *dirname) +ctf_open_dir (const char *dirname) { struct bt_iter_pos begin_pos; struct bt_iter_pos *pos; @@ -959,6 +911,12 @@ ctf_open_dir (char *dirname) (SCOPE), \ #FIELD)) +#define SET_ENUM_FIELD(EVENT, SCOPE, VAR, TYPE, FIELD) \ + (VAR)->FIELD = (TYPE) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \ + (SCOPE), \ + #FIELD)) + + /* EVENT is the "status" event and TS is filled in. */ static void @@ -967,7 +925,7 @@ ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts) const struct bt_definition *scope = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS); - SET_INT32_FIELD (event, scope, ts, stop_reason); + SET_ENUM_FIELD (event, scope, ts, enum trace_stop_reason, stop_reason); SET_INT32_FIELD (event, scope, ts, stopping_tracepoint); SET_INT32_FIELD (event, scope, ts, traceframe_count); SET_INT32_FIELD (event, scope, ts, traceframes_created); @@ -1103,7 +1061,7 @@ ctf_read_tp (struct uploaded_tp **uploaded_tps) SET_INT32_FIELD (event, scope, utp, step); SET_INT32_FIELD (event, scope, utp, pass); SET_INT32_FIELD (event, scope, utp, hit_count); - SET_INT32_FIELD (event, scope, utp, type); + SET_ENUM_FIELD (event, scope, utp, enum bptype, type); /* Read 'cmd_strings'. */ SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings); @@ -1127,7 +1085,7 @@ ctf_read_tp (struct uploaded_tp **uploaded_tps) second packet which contains events on trace blocks. */ static void -ctf_open (char *dirname, int from_tty) +ctf_open (const char *dirname, int from_tty) { struct bt_ctf_event *event; uint32_t event_id; @@ -1318,7 +1276,7 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, { /* We're only doing regular memory for now. */ if (object != TARGET_OBJECT_MEMORY) - return -1; + return TARGET_XFER_E_IO; if (readbuf == NULL) error (_("ctf_xfer_partial: trace file is read-only")); @@ -1328,6 +1286,9 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, struct bt_iter_pos *pos; int i = 0; enum target_xfer_status res; + /* Records the lowest available address of all blocks that + intersects the requested range. */ + ULONGEST low_addr_available = 0; gdb_assert (ctf_iter != NULL); /* Save the current position. */ @@ -1380,7 +1341,7 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, gdb_byte *contents; int k; - contents = xmalloc (mlen); + contents = (gdb_byte *) xmalloc (mlen); for (k = 0; k < mlen; k++) { @@ -1410,6 +1371,10 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, } } + if (offset < maddr && maddr < (offset + len)) + if (low_addr_available == 0 || low_addr_available > maddr) + low_addr_available = maddr; + if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) break; } @@ -1419,7 +1384,9 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, /* Requested memory is unavailable in the context of traceframes, and this address falls within a read-only section, fallback - to reading from executable. */ + to reading from executable, up to LOW_ADDR_AVAILABLE */ + if (offset < low_addr_available) + len = std::min (len, low_addr_available - offset); res = exec_read_partial_read_only (readbuf, offset, len, xfered_len); if (res == TARGET_XFER_OK) @@ -1549,8 +1516,8 @@ ctf_get_traceframe_address (void) struct tracepoint *tp = get_tracepoint_by_number_on_target (tpnum); - if (tp && tp->base.loc) - addr = tp->base.loc->address; + if (tp && tp->loc) + addr = tp->loc->address; } /* Restore the position. */ @@ -1668,10 +1635,10 @@ ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num, frame, extract memory range information, and return them in traceframe_info. */ -static struct traceframe_info * +static traceframe_info_up ctf_traceframe_info (struct target_ops *self) { - struct traceframe_info *info = XCNEW (struct traceframe_info); + traceframe_info_up info (new traceframe_info); const char *name; struct bt_iter_pos *pos; @@ -1696,14 +1663,14 @@ ctf_traceframe_info (struct target_ops *self) = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS); const struct bt_definition *def; - struct mem_range *r; - r = VEC_safe_push (mem_range_s, info->memory, NULL); def = bt_ctf_get_field (event, scope, "address"); - r->start = bt_ctf_get_uint64 (def); + CORE_ADDR start = bt_ctf_get_uint64 (def); def = bt_ctf_get_field (event, scope, "length"); - r->length = (uint16_t) bt_ctf_get_uint64 (def); + int length = (uint16_t) bt_ctf_get_uint64 (def); + + info->memory.emplace_back (start, length); } else if (strcmp (name, "tsv") == 0) { @@ -1714,8 +1681,8 @@ ctf_traceframe_info (struct target_ops *self) const struct bt_definition *def; def = bt_ctf_get_field (event, scope, "num"); - vnum = (int) bt_ctf_get_int64 (def); - VEC_safe_push (int, info->tvars, vnum); + vnum = (int) bt_ctf_get_uint64 (def); + info->tvars.push_back (vnum); } else { @@ -1758,10 +1725,6 @@ Specify the filename of the CTF directory."; #endif -/* -Wmissing-prototypes */ - -extern initialize_file_ftype _initialize_ctf; - /* module initialization */ void