/* Low-level child interface to ttrace.
- Copyright (C) 2004-2012 Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
#include <sys/mman.h>
#include <sys/ttrace.h>
#include <signal.h>
#include "inf-child.h"
#include "inf-ttrace.h"
+#include "common/filestuff.h"
\f
addr, 0, (uintptr_t)&prot) == -1)
perror_with_name (("ttrace"));
- page = XMALLOC (struct inf_ttrace_page);
+ page = XNEW (struct inf_ttrace_page);
page->addr = addr;
page->prot = prot;
page->refcount = 0;
type TYPE. */
static int
-inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type,
+inf_ttrace_insert_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len, int type,
struct expression *cond)
{
const int pagesize = inf_ttrace_page_dict.pagesize;
type TYPE. */
static int
-inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type,
+inf_ttrace_remove_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len, int type,
struct expression *cond)
{
const int pagesize = inf_ttrace_page_dict.pagesize;
}
static int
-inf_ttrace_can_use_hw_breakpoint (int type, int len, int ot)
+inf_ttrace_can_use_hw_breakpoint (struct target_ops *self,
+ int type, int len, int ot)
{
return (type == bp_hardware_watchpoint);
}
static int
-inf_ttrace_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+inf_ttrace_region_ok_for_hw_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len)
{
return 1;
}
by hitting a "hardware" watchpoint. */
static int
-inf_ttrace_stopped_by_watchpoint (void)
+inf_ttrace_stopped_by_watchpoint (struct target_ops *ops)
{
pid_t pid = ptid_get_pid (inferior_ptid);
lwpid_t lwpid = ptid_get_lwp (inferior_ptid);
static pid_t inf_ttrace_vfork_ppid = -1;
static int
-inf_ttrace_follow_fork (struct target_ops *ops, int follow_child)
+inf_ttrace_follow_fork (struct target_ops *ops, int follow_child,
+ int detach_fork)
{
pid_t pid, fpid;
lwpid_t lwpid, flwpid;
close (inf_ttrace_pfd1[1]);
close (inf_ttrace_pfd2[0]);
close (inf_ttrace_pfd2[1]);
+
+ unmark_fd_no_cloexec (inf_ttrace_pfd1[0]);
+ unmark_fd_no_cloexec (inf_ttrace_pfd1[1]);
+ unmark_fd_no_cloexec (inf_ttrace_pfd2[0]);
+ unmark_fd_no_cloexec (inf_ttrace_pfd2[1]);
}
static void
close (inf_ttrace_pfd2[0]);
perror_with_name (("pipe"));
}
+
+ mark_fd_no_cloexec (inf_ttrace_pfd1[0]);
+ mark_fd_no_cloexec (inf_ttrace_pfd1[1]);
+ mark_fd_no_cloexec (inf_ttrace_pfd2[0]);
+ mark_fd_no_cloexec (inf_ttrace_pfd2[1]);
}
/* Prepare to be traced. */
do_cleanups (old_chain);
- push_target (ops);
+ if (!target_is_pushed (ops))
+ push_target (ops);
- /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
- be 1 or 2 depending on whether we're starting without or with a
- shell. */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
/* On some targets, there must be some explicit actions taken after
}
inf_ttrace_page_dict.count = 0;
- unpush_target (ops);
- generic_mourn_inferior ();
+ inf_child_mourn_inferior (ops);
}
/* Assuming we just attached the debugger to a new inferior, create
(uintptr_t)&tte, sizeof tte, 0) == -1)
perror_with_name (("ttrace"));
- push_target (ops);
+ if (!target_is_pushed (ops))
+ push_target (ops);
inf_ttrace_create_threads_after_attach (pid);
}
static void
-inf_ttrace_detach (struct target_ops *ops, char *args, int from_tty)
+inf_ttrace_detach (struct target_ops *ops, const char *args, int from_tty)
{
pid_t pid = ptid_get_pid (inferior_ptid);
int sig = 0;
inferior_ptid = null_ptid;
detach_inferior (pid);
- unpush_target (ops);
+ inf_child_maybe_unpush_target (ops);
}
static void
return len;
}
-static LONGEST
+static enum target_xfer_status
inf_ttrace_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 offset, ULONGEST len, ULONGEST *xfered_len)
{
switch (object)
{
case TARGET_OBJECT_MEMORY:
- return inf_ttrace_xfer_memory (offset, len, readbuf, writebuf);
+ {
+ LONGEST val = inf_ttrace_xfer_memory (offset, len, readbuf, writebuf);
+
+ if (val == 0)
+ return TARGET_XFER_EOF;
+ else
+ {
+ *xfered_len = (ULONGEST) val;
+ return TARGET_XFER_OK;
+ }
+ }
case TARGET_OBJECT_UNWIND_TABLE:
- return -1;
+ return TARGET_XFER_E_IO;
case TARGET_OBJECT_AUXV:
- return -1;
+ return TARGET_XFER_E_IO;
case TARGET_OBJECT_WCOOKIE:
- return -1;
+ return TARGET_XFER_E_IO;
default:
- return -1;
+ return TARGET_XFER_E_IO;
}
}
INFO. */
static char *
-inf_ttrace_extra_thread_info (struct thread_info *info)
+inf_ttrace_extra_thread_info (struct target_ops *self,
+ struct thread_info *info)
{
struct inf_ttrace_private_thread_info* private =
(struct inf_ttrace_private_thread_info *) info->private;
/* Implement the get_ada_task_ptid target_ops method. */
static ptid_t
-inf_ttrace_get_ada_task_ptid (long lwp, long thread)
+inf_ttrace_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
{
return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
}