/* CTF format support.
- Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
Contributed by Hui Zhu <hui_zhu@mentor.com>
Contributed by Yao Qi <yao@codesourcery.com>
#include "ctf.h"
#include "tracepoint.h"
#include "regcache.h"
-#include "gdb_stat.h"
+#include <sys/stat.h>
#include "exec.h"
#include "completer.h"
+#include "inferior.h"
+#include "gdbthread.h"
#include <ctype.h>
#define CTF_EVENT_ID_TSV_DEF 5
#define CTF_EVENT_ID_TP_DEF 6
+#define CTF_PID (2)
+
/* The state kept while writing the CTF datastream file. */
struct trace_write_handler
struct ctf_trace_file_writer *writer
= (struct ctf_trace_file_writer *) self;
int i;
- mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR
-#ifdef S_IRGRP
- | S_IRGRP
-#endif
-#ifdef S_IXGRP
- | S_IXGRP
-#endif
- | S_IROTH /* Defined in common/gdb_stat.h if not defined. */
-#ifdef S_IXOTH
- | S_IXOTH
-#endif
- ;
+ mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
/* Create DIRNAME. */
if (mkdir (dirname, hmode) && errno != EEXIST)
trace_dirname = xstrdup (dirname);
push_target (&ctf_ops);
+ inferior_appeared (current_inferior (), CTF_PID);
+ inferior_ptid = pid_to_ptid (CTF_PID);
+ add_thread_silent (inferior_ptid);
+
merge_uploaded_trace_state_variables (&uploaded_tsvs);
merge_uploaded_tracepoints (&uploaded_tps);
}
CTF iterator and context. */
static void
-ctf_close (void)
+ctf_close (struct target_ops *self)
{
+ int pid;
+
ctf_destroy ();
xfree (trace_dirname);
trace_dirname = NULL;
+ pid = ptid_get_pid (inferior_ptid);
+ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
+ exit_inferior_silent (pid);
+
trace_reset_local_state ();
}
OFFSET is within the range, read the contents from events to
READBUF. */
-static LONGEST
+static enum target_xfer_status
ctf_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf, ULONGEST offset,
- LONGEST len)
+ ULONGEST len, ULONGEST *xfered_len)
{
/* We're only doing regular memory for now. */
if (object != TARGET_OBJECT_MEMORY)
/* Restore the position. */
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- return amt;
+ if (amt == 0)
+ return TARGET_XFER_EOF;
+ else
+ {
+ *xfered_len = amt;
+ return TARGET_XFER_OK;
+ }
}
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
amt = bfd_get_section_contents (exec_bfd, s,
readbuf, offset - vma, amt);
- return amt;
+
+ if (amt == 0)
+ return TARGET_XFER_EOF;
+ else
+ {
+ *xfered_len = amt;
+ return TARGET_XFER_OK;
+ }
}
}
}
/* Indicate failure to find the requested memory block. */
- return -1;
+ return TARGET_XFER_E_IO;
}
/* This is the implementation of target_ops method
true, otherwise return false. */
static int
-ctf_get_trace_state_variable_value (int tsvnum, LONGEST *val)
+ctf_get_trace_state_variable_value (struct target_ops *self,
+ int tsvnum, LONGEST *val)
{
struct bt_iter_pos *pos;
int found = 0;
number in it. Return traceframe number when matched. */
static int
-ctf_trace_find (enum trace_find_type type, int num,
+ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
{
int ret = -1;
return get_traceframe_number () != -1;
}
+/* This is the implementation of target_ops method to_thread_alive.
+ CTF trace data has one thread faked by GDB. */
+
+static int
+ctf_thread_alive (struct target_ops *ops, ptid_t ptid)
+{
+ return 1;
+}
+
/* This is the implementation of target_ops method to_traceframe_info.
Iterate the events whose name is "memory", in current
frame, extract memory range information, and return them in
traceframe_info. */
static struct traceframe_info *
-ctf_traceframe_info (void)
+ctf_traceframe_info (struct target_ops *self)
{
struct traceframe_info *info = XCNEW (struct traceframe_info);
const char *name;
def = bt_ctf_get_field (event, scope, "length");
r->length = (uint16_t) bt_ctf_get_uint64 (def);
}
+ else if (strcmp (name, "tsv") == 0)
+ {
+ int vnum;
+ const struct bt_definition *scope
+ = bt_ctf_get_top_level_scope (event,
+ BT_EVENT_FIELDS);
+ 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);
+ }
else
{
warning (_("Unhandled trace block type (%s) "
The trace status for a file is that tracing can never be run. */
static int
-ctf_get_trace_status (struct trace_status *ts)
+ctf_get_trace_status (struct target_ops *self, struct trace_status *ts)
{
/* Other bits of trace status were collected as part of opening the
trace files, so nothing to do here. */
ctf_ops.to_has_stack = ctf_has_stack;
ctf_ops.to_has_registers = ctf_has_registers;
ctf_ops.to_traceframe_info = ctf_traceframe_info;
+ ctf_ops.to_thread_alive = ctf_thread_alive;
ctf_ops.to_magic = OPS_MAGIC;
}