/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright (C) 1999-2003, 2006-2012 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 Free Software Foundation, Inc.
Written by Michael Snyder at Cygnus Solutions.
Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
#include "defs.h"
#include "inferior.h"
+#include "infrun.h"
#include "target.h"
#include "gdbcore.h"
#include "elf-bfd.h" /* for elfcore_write_* */
#include "gdbthread.h"
#include "regcache.h"
#include "inf-child.h"
+#include "filestuff.h"
#if defined (NEW_PROC_API)
#define _STRUCTURED_PROC 1 /* Should be done by configure script. */
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
-#include <sys/errno.h>
#include "gdb_wait.h"
#include <signal.h>
#include <ctype.h>
-#include "gdb_string.h"
-#include "gdb_assert.h"
+#include "gdb_bfd.h"
#include "inflow.h"
#include "auxv.h"
#include "procfs.h"
Irix
Solaris
OSF
- Unixware
AIX5
/proc works by imitating a file system: you open a simulated file
#ifdef NEW_PROC_API
#include <sys/types.h>
-#include "gdb_dirent.h" /* opendir/readdir, for listing the LWP's */
+#include <dirent.h> /* opendir/readdir, for listing the LWP's */
#endif
#include <fcntl.h> /* for O_RDONLY */
#include <unistd.h> /* for "X_OK" */
-#include "gdb_stat.h" /* for struct stat */
+#include <sys/stat.h> /* for struct stat */
/* Note: procfs-utils.h must be included after the above system header
files, because it redefines various system calls using macros.
/* This module defines the GDB target vector and its methods. */
-static void procfs_attach (struct target_ops *, char *, int);
-static void procfs_detach (struct target_ops *, char *, int);
+static void procfs_attach (struct target_ops *, const char *, int);
+static void procfs_detach (struct target_ops *, const char *, int);
static void procfs_resume (struct target_ops *,
- ptid_t, int, enum target_signal);
-static void procfs_stop (ptid_t);
+ ptid_t, int, enum gdb_signal);
+static void procfs_interrupt (struct target_ops *self, ptid_t);
static void procfs_files_info (struct target_ops *);
static void procfs_fetch_registers (struct target_ops *,
struct regcache *, int);
static void procfs_store_registers (struct target_ops *,
struct regcache *, int);
-static void procfs_pass_signals (int, unsigned char *);
+static void procfs_pass_signals (struct target_ops *self,
+ int, unsigned char *);
static void procfs_kill_inferior (struct target_ops *ops);
static void procfs_mourn_inferior (struct target_ops *ops);
static void procfs_create_inferior (struct target_ops *, char *,
char *, char **, int);
static ptid_t procfs_wait (struct target_ops *,
ptid_t, struct target_waitstatus *, int);
-static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
- struct mem_attrib *attrib,
- struct target_ops *);
-static LONGEST procfs_xfer_partial (struct target_ops *ops,
- enum target_object object,
- const char *annex,
- gdb_byte *readbuf,
- const gdb_byte *writebuf,
- ULONGEST offset, LONGEST len);
+static enum target_xfer_status procfs_xfer_memory (gdb_byte *,
+ const gdb_byte *,
+ ULONGEST, ULONGEST,
+ ULONGEST *);
+static target_xfer_partial_ftype procfs_xfer_partial;
static int procfs_thread_alive (struct target_ops *ops, ptid_t);
-void procfs_find_new_threads (struct target_ops *ops);
-char *procfs_pid_to_str (struct target_ops *, ptid_t);
+static void procfs_update_thread_list (struct target_ops *ops);
+static char *procfs_pid_to_str (struct target_ops *, ptid_t);
-static int proc_find_memory_regions (int (*) (CORE_ADDR,
- unsigned long,
- int, int, int,
- void *),
- void *);
+static int proc_find_memory_regions (struct target_ops *self,
+ find_memory_region_ftype, void *);
-static char * procfs_make_note_section (bfd *, int *);
+static char * procfs_make_note_section (struct target_ops *self,
+ bfd *, int *);
-static int procfs_can_use_hw_breakpoint (int, int, int);
+static int procfs_can_use_hw_breakpoint (struct target_ops *self,
+ enum bptype, int, int);
-static void procfs_info_proc (struct target_ops *, char *,
+static void procfs_info_proc (struct target_ops *, const char *,
enum info_proc_what);
#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
gdb_byte *ptr = *readptr;
if (endptr == ptr)
{
struct target_ops *t = inf_child_target ();
- t->to_shortname = "procfs";
- t->to_longname = "Unix /proc child process";
- t->to_doc =
- "Unix /proc child process (started by the \"run\" command).";
t->to_create_inferior = procfs_create_inferior;
t->to_kill = procfs_kill_inferior;
t->to_mourn_inferior = procfs_mourn_inferior;
t->to_fetch_registers = procfs_fetch_registers;
t->to_store_registers = procfs_store_registers;
t->to_xfer_partial = procfs_xfer_partial;
- t->deprecated_xfer_memory = procfs_xfer_memory;
t->to_pass_signals = procfs_pass_signals;
t->to_files_info = procfs_files_info;
- t->to_stop = procfs_stop;
+ t->to_interrupt = procfs_interrupt;
- t->to_find_new_threads = procfs_find_new_threads;
+ t->to_update_thread_list = procfs_update_thread_list;
t->to_thread_alive = procfs_thread_alive;
t->to_pid_to_str = procfs_pid_to_str;
#ifdef HAVE_PR_SIGINFO64_T
typedef pr_siginfo64_t gdb_siginfo_t;
#else
-typedef struct siginfo gdb_siginfo_t;
+typedef siginfo_t gdb_siginfo_t;
#endif
/* On mips-irix, praddset and prdelset are defined in such a way that
/* This function is getting ALMOST long enough to break up into
several. Here is some rationale:
- NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware):
+ NEW_PROC_API (Solaris 2.6, Solaris 2.7):
There are several file descriptors that may need to be open
for any given process or LWP. The ones we're intereted in are:
- control (ctl) write-only change the state
create it if it
doesn't exist yet? */
- pi = (procinfo *) xmalloc (sizeof (procinfo));
+ pi = XNEW (procinfo);
memset (pi, 0, sizeof (procinfo));
pi->pid = pid;
pi->tid = tid;
maxcall = syscalls[i].pr_number;
pi->num_syscalls = maxcall+1;
- pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *));
+ pi->syscall_names = XNEWVEC (char *, pi->num_syscalls);
for (i = 0; i < pi->num_syscalls; i++)
pi->syscall_names[i] = NULL;
than have a bunch of #ifdefs all thru the gdb target vector
functions, we do our best to hide them all in here. */
-int proc_get_status (procinfo * pi);
-long proc_flags (procinfo * pi);
-int proc_why (procinfo * pi);
-int proc_what (procinfo * pi);
-int proc_set_run_on_last_close (procinfo * pi);
-int proc_unset_run_on_last_close (procinfo * pi);
-int proc_set_inherit_on_fork (procinfo * pi);
-int proc_unset_inherit_on_fork (procinfo * pi);
-int proc_set_async (procinfo * pi);
-int proc_unset_async (procinfo * pi);
-int proc_stop_process (procinfo * pi);
-int proc_trace_signal (procinfo * pi, int signo);
-int proc_ignore_signal (procinfo * pi, int signo);
-int proc_clear_current_fault (procinfo * pi);
-int proc_set_current_signal (procinfo * pi, int signo);
-int proc_clear_current_signal (procinfo * pi);
-int proc_set_gregs (procinfo * pi);
-int proc_set_fpregs (procinfo * pi);
-int proc_wait_for_stop (procinfo * pi);
-int proc_run_process (procinfo * pi, int step, int signo);
-int proc_kill (procinfo * pi, int signo);
-int proc_parent_pid (procinfo * pi);
-int proc_get_nthreads (procinfo * pi);
-int proc_get_current_thread (procinfo * pi);
-int proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold);
-int proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset);
-int proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset);
-int proc_set_traced_faults (procinfo * pi, fltset_t * fltset);
-int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset);
-
-int proc_update_threads (procinfo * pi);
-int proc_iterate_over_threads (procinfo * pi,
- int (*func) (procinfo *, procinfo *, void *),
- void *ptr);
-
-gdb_gregset_t *proc_get_gregs (procinfo * pi);
-gdb_fpregset_t *proc_get_fpregs (procinfo * pi);
-sysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save);
-sysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save);
-fltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save);
-gdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save);
-gdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save);
-gdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save);
-gdb_sigaction_t *proc_get_signal_actions (procinfo * pi,
- gdb_sigaction_t *save);
-
-void proc_warn (procinfo * pi, char *func, int line);
-void proc_error (procinfo * pi, char *func, int line);
+static long proc_flags (procinfo * pi);
+static int proc_why (procinfo * pi);
+static int proc_what (procinfo * pi);
+static int proc_set_current_signal (procinfo * pi, int signo);
+static int proc_get_current_thread (procinfo * pi);
+static int proc_iterate_over_threads
+ (procinfo * pi,
+ int (*func) (procinfo *, procinfo *, void *),
+ void *ptr);
-void
+static void
proc_warn (procinfo *pi, char *func, int line)
{
sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
print_sys_errmsg (errmsg, errno);
}
-void
+static void
proc_error (procinfo *pi, char *func, int line)
{
sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
file descriptor is also only opened when it is needed. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_get_status (procinfo *pi)
{
/* Status file descriptor is opened "lazily". */
(char *) &pi->prstatus,
sizeof (gdb_prstatus_t))
== sizeof (gdb_prstatus_t));
-#if 0 /*def UNIXWARE*/
- if (pi->status_valid &&
- (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) &&
- pi->prstatus.pr_lwp.pr_why == PR_REQUESTED)
- /* Unixware peculiarity -- read the damn thing again! */
- pi->status_valid = (read (pi->status_fd,
- (char *) &pi->prstatus,
- sizeof (gdb_prstatus_t))
- == sizeof (gdb_prstatus_t));
-#endif /* UNIXWARE */
}
}
#else /* ioctl method */
/* Returns the process flags (pr_flags field). */
-long
+static long
proc_flags (procinfo *pi)
{
if (!pi->status_valid)
return 0; /* FIXME: not a good failure value (but what is?) */
#ifdef NEW_PROC_API
-# ifdef UNIXWARE
- /* UnixWare 7.1 puts process status flags, e.g. PR_ASYNC, in
- pstatus_t and LWP status flags, e.g. PR_STOPPED, in lwpstatus_t.
- The two sets of flags don't overlap. */
- return pi->prstatus.pr_flags | pi->prstatus.pr_lwp.pr_flags;
-# else
return pi->prstatus.pr_lwp.pr_flags;
-# endif
#else
return pi->prstatus.pr_flags;
#endif
/* Returns the pr_why field (why the process stopped). */
-int
+static int
proc_why (procinfo *pi)
{
if (!pi->status_valid)
/* Returns the pr_what field (details of why the process stopped). */
-int
+static int
proc_what (procinfo *pi)
{
if (!pi->status_valid)
return 0;
#ifdef NEW_PROC_API
- *addr = (CORE_ADDR) gdbarch_pointer_to_address (target_gdbarch,
- builtin_type (target_gdbarch)->builtin_data_ptr,
+ *addr = (CORE_ADDR) gdbarch_pointer_to_address (target_gdbarch (),
+ builtin_type (target_gdbarch ())->builtin_data_ptr,
(gdb_byte *) &pi->prstatus.pr_lwp.pr_info.si_addr);
#else
- *addr = (CORE_ADDR) gdbarch_pointer_to_address (target_gdbarch,
- builtin_type (target_gdbarch)->builtin_data_ptr,
+ *addr = (CORE_ADDR) gdbarch_pointer_to_address (target_gdbarch (),
+ builtin_type (target_gdbarch ())->builtin_data_ptr,
(gdb_byte *) &pi->prstatus.pr_info.si_addr);
#endif
return 1;
/* Returns the pr_nsysarg field (number of args to the current
syscall). */
-int
+static int
proc_nsysarg (procinfo *pi)
{
if (!pi->status_valid)
/* Returns the pr_sysarg field (pointer to the arguments of current
syscall). */
-long *
+static long *
proc_sysargs (procinfo *pi)
{
if (!pi->status_valid)
return (long *) &pi->prstatus.pr_sysarg;
#endif
}
-
-/* Returns the pr_syscall field (id of current syscall if we are in
- one). */
-
-int
-proc_syscall (procinfo *pi)
-{
- if (!pi->status_valid)
- if (!proc_get_status (pi))
- return 0;
-
-#ifdef NEW_PROC_API
- return pi->prstatus.pr_lwp.pr_syscall;
-#else
- return pi->prstatus.pr_syscall;
-#endif
-}
#endif /* PIOCSSPCACT */
+#ifdef PROCFS_DONT_PIOCSSIG_CURSIG
/* Returns the pr_cursig field (current signal). */
-long
+static long
proc_cursig (struct procinfo *pi)
{
if (!pi->status_valid)
return pi->prstatus.pr_cursig;
#endif
}
+#endif /* PROCFS_DONT_PIOCSSIG_CURSIG */
/* === I appologize for the messiness of this function.
=== This is an area where the different versions of
if (pi->pid != 0)
pi = find_procinfo_or_die (pi->pid, 0);
-#ifdef NEW_PROC_API /* Newest method: UnixWare and newer Solarii. */
+#ifdef NEW_PROC_API /* Newest method: Newer Solarii. */
/* First normalize the PCUNSET/PCRESET command opcode
(which for no obvious reason has a different definition
from one operating system to the next...) */
become runnable when debugger closes all /proc fds. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_set_run_on_last_close (procinfo *pi)
{
return proc_modify_flag (pi, PR_RLC, FLAG_SET);
runnable when debugger closes its file handles. Returns non-zero
for success, zero for failure. */
-int
+static int
proc_unset_run_on_last_close (procinfo *pi)
{
return proc_modify_flag (pi, PR_RLC, FLAG_RESET);
}
-#ifdef PR_KLC
-/* Set the kill_on_last_close flag. Process with all threads will be
- killed when debugger closes all /proc fds (or debugger exits or
- dies). Returns non-zero for success, zero for failure. */
-
-int
-proc_set_kill_on_last_close (procinfo *pi)
-{
- return proc_modify_flag (pi, PR_KLC, FLAG_SET);
-}
-
-/* Reset the kill_on_last_close flag. Process will NOT be killed when
- debugger closes its file handles (or exits or dies). Returns
- non-zero for success, zero for failure. */
-
-int
-proc_unset_kill_on_last_close (procinfo *pi)
-{
- return proc_modify_flag (pi, PR_KLC, FLAG_RESET);
-}
-#endif /* PR_KLC */
-
-/* Set inherit_on_fork flag. If the process forks a child while we
- are registered for events in the parent, then we will also recieve
- events from the child. Returns non-zero for success, zero for
- failure. */
-
-int
-proc_set_inherit_on_fork (procinfo *pi)
-{
- return proc_modify_flag (pi, PR_FORK, FLAG_SET);
-}
-
/* Reset inherit_on_fork flag. If the process forks a child while we
are registered for events in the parent, then we will NOT recieve
events from the child. Returns non-zero for success, zero for
failure. */
-int
+static int
proc_unset_inherit_on_fork (procinfo *pi)
{
return proc_modify_flag (pi, PR_FORK, FLAG_RESET);
(signal etc.), the remaining LWPs will continue to run. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_set_async (procinfo *pi)
{
return proc_modify_flag (pi, PR_ASYNC, FLAG_SET);
(signal etc.), then all other LWPs will stop as well. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_unset_async (procinfo *pi)
{
return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET);
/* Request the process/LWP to stop. Does not wait. Returns non-zero
for success, zero for failure. */
-int
+static int
proc_stop_process (procinfo *pi)
{
int win;
/* Wait for the process or LWP to stop (block until it does). Returns
non-zero for success, zero for failure. */
-int
+static int
proc_wait_for_stop (procinfo *pi)
{
int win;
any; if non-zero, set the current signal to this one. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_run_process (procinfo *pi, int step, int signo)
{
int win;
/* Register to trace signals in the process or LWP. Returns non-zero
for success, zero for failure. */
-int
+static int
proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
{
int win;
/* Register to trace hardware faults in the process or LWP. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_set_traced_faults (procinfo *pi, fltset_t *fltset)
{
int win;
/* Register to trace entry to system calls in the process or LWP.
Returns non-zero for success, zero for failure. */
-int
+static int
proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
{
int win;
/* Register to trace exit from system calls in the process or LWP.
Returns non-zero for success, zero for failure. */
-int
+static int
proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
{
int win;
/* Specify the set of blocked / held signals in the process or LWP.
Returns non-zero for success, zero for failure. */
-int
+static int
proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
{
int win;
return win;
}
-/* Returns the set of signals that are pending in the process or LWP.
- Will also copy the sigset if SAVE is non-zero. */
-
-gdb_sigset_t *
-proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save)
-{
- gdb_sigset_t *ret = NULL;
-
- /* We should never have to apply this operation to any procinfo
- except the one for the main process. If that ever changes for
- any reason, then take out the following clause and replace it
- with one that makes sure the ctl_fd is open. */
-
- if (pi->tid != 0)
- pi = find_procinfo_or_die (pi->pid, 0);
-
- if (!pi->status_valid)
- if (!proc_get_status (pi))
- return NULL;
-
-#ifdef NEW_PROC_API
- ret = &pi->prstatus.pr_lwp.pr_lwppend;
-#else
- ret = &pi->prstatus.pr_sigpend;
-#endif
- if (save && ret)
- memcpy (save, ret, sizeof (gdb_sigset_t));
-
- return ret;
-}
-
-/* Returns the set of signal actions. Will also copy the sigactionset
- if SAVE is non-zero. */
-
-gdb_sigaction_t *
-proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save)
-{
- gdb_sigaction_t *ret = NULL;
-
- /* We should never have to apply this operation to any procinfo
- except the one for the main process. If that ever changes for
- any reason, then take out the following clause and replace it
- with one that makes sure the ctl_fd is open. */
-
- if (pi->tid != 0)
- pi = find_procinfo_or_die (pi->pid, 0);
-
- if (!pi->status_valid)
- if (!proc_get_status (pi))
- return NULL;
-
-#ifdef NEW_PROC_API
- ret = &pi->prstatus.pr_lwp.pr_action;
-#else
- ret = &pi->prstatus.pr_action;
-#endif
- if (save && ret)
- memcpy (save, ret, sizeof (gdb_sigaction_t));
-
- return ret;
-}
-
/* Returns the set of signals that are held / blocked. Will also copy
the sigset if SAVE is non-zero. */
-gdb_sigset_t *
+static gdb_sigset_t *
proc_get_held_signals (procinfo *pi, gdb_sigset_t *save)
{
gdb_sigset_t *ret = NULL;
if (!proc_get_status (pi))
return NULL;
-#ifdef UNIXWARE
- ret = &pi->prstatus.pr_lwp.pr_context.uc_sigmask;
-#else
ret = &pi->prstatus.pr_lwp.pr_lwphold;
-#endif /* UNIXWARE */
#else /* not NEW_PROC_API */
{
static gdb_sigset_t sigheld;
/* Returns the set of signals that are traced / debugged. Will also
copy the sigset if SAVE is non-zero. */
-gdb_sigset_t *
+static gdb_sigset_t *
proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save)
{
gdb_sigset_t *ret = NULL;
return ret;
}
-/* Add SIGNO to the set of signals that are traced. Returns non-zero
- for success, zero for failure. */
-
-int
-proc_trace_signal (procinfo *pi, int signo)
-{
- gdb_sigset_t temp;
-
- /* We should never have to apply this operation to any procinfo
- except the one for the main process. If that ever changes for
- any reason, then take out the following clause and replace it
- with one that makes sure the ctl_fd is open. */
-
- if (pi->tid != 0)
- pi = find_procinfo_or_die (pi->pid, 0);
-
- if (pi)
- {
- if (proc_get_traced_signals (pi, &temp))
- {
- gdb_praddset (&temp, signo);
- return proc_set_traced_signals (pi, &temp);
- }
- }
-
- return 0; /* failure */
-}
-
-/* Remove SIGNO from the set of signals that are traced. Returns
- non-zero for success, zero for failure. */
-
-int
-proc_ignore_signal (procinfo *pi, int signo)
-{
- gdb_sigset_t temp;
-
- /* We should never have to apply this operation to any procinfo
- except the one for the main process. If that ever changes for
- any reason, then take out the following clause and replace it
- with one that makes sure the ctl_fd is open. */
-
- if (pi->tid != 0)
- pi = find_procinfo_or_die (pi->pid, 0);
-
- if (pi)
- {
- if (proc_get_traced_signals (pi, &temp))
- {
- gdb_prdelset (&temp, signo);
- return proc_set_traced_signals (pi, &temp);
- }
- }
-
- return 0; /* failure */
-}
-
/* Returns the set of hardware faults that are traced /debugged. Will
also copy the faultset if SAVE is non-zero. */
-fltset_t *
+static fltset_t *
proc_get_traced_faults (procinfo *pi, fltset_t *save)
{
fltset_t *ret = NULL;
/* Returns the set of syscalls that are traced /debugged on entry.
Will also copy the syscall set if SAVE is non-zero. */
-sysset_t *
+static sysset_t *
proc_get_traced_sysentry (procinfo *pi, sysset_t *save)
{
sysset_t *ret = NULL;
/* Returns the set of syscalls that are traced /debugged on exit.
Will also copy the syscall set if SAVE is non-zero. */
-sysset_t *
+static sysset_t *
proc_get_traced_sysexit (procinfo *pi, sysset_t *save)
{
sysset_t * ret = NULL;
not be sent to the process or LWP when it resumes. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_clear_current_fault (procinfo *pi)
{
int win;
trap back to the debugger. Returns non-zero for success, zero for
failure. */
-int
+static int
proc_set_current_signal (procinfo *pi, int signo)
{
int win;
get_last_target_status (&wait_ptid, &wait_status);
if (ptid_equal (wait_ptid, inferior_ptid)
&& wait_status.kind == TARGET_WAITKIND_STOPPED
- && wait_status.value.sig == target_signal_from_host (signo)
+ && wait_status.value.sig == gdb_signal_from_host (signo)
&& proc_get_status (pi)
#ifdef NEW_PROC_API
&& pi->prstatus.pr_lwp.pr_info.si_signo == signo
process or LWP when it resumes. Returns non-zero for success, zero
for failure. */
-int
+static int
proc_clear_current_signal (procinfo *pi)
{
int win;
/* Return the general-purpose registers for the process or LWP
corresponding to PI. Upon failure, return NULL. */
-gdb_gregset_t *
+static gdb_gregset_t *
proc_get_gregs (procinfo *pi)
{
if (!pi->status_valid || !pi->gregs_valid)
if (!proc_get_status (pi))
return NULL;
- /* OK, sorry about the ifdef's. There's three cases instead of two,
- because in this case Unixware and Solaris/RW differ. */
-
#ifdef NEW_PROC_API
-# ifdef UNIXWARE /* FIXME: Should be autoconfigured. */
- return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs;
-# else
return &pi->prstatus.pr_lwp.pr_reg;
-# endif
#else
return &pi->prstatus.pr_reg;
#endif
/* Return the general-purpose registers for the process or LWP
corresponding to PI. Upon failure, return NULL. */
-gdb_fpregset_t *
+static gdb_fpregset_t *
proc_get_fpregs (procinfo *pi)
{
#ifdef NEW_PROC_API
if (!proc_get_status (pi))
return NULL;
-# ifdef UNIXWARE /* FIXME: Should be autoconfigured. */
- return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs;
-# else
return &pi->prstatus.pr_lwp.pr_fpreg;
-# endif
#else /* not NEW_PROC_API */
if (pi->fpregs_valid)
corresponding to PI. Return non-zero for success, zero for
failure. */
-int
+static int
proc_set_gregs (procinfo *pi)
{
gdb_gregset_t *gregs;
corresponding to PI. Return non-zero for success, zero for
failure. */
-int
+static int
proc_set_fpregs (procinfo *pi)
{
gdb_fpregset_t *fpregs;
/* Send a signal to the proc or lwp with the semantics of "kill()".
Returns non-zero for success, zero for failure. */
-int
+static int
proc_kill (procinfo *pi, int signo)
{
int win;
/* Find the pid of the process that started this one. Returns the
parent process pid, or zero. */
-int
+static int
proc_parent_pid (procinfo *pi)
{
/* We should never have to apply this operation to any procinfo
(a.k.a void pointer)! */
#if (defined (PCWATCH) || defined (PIOCSWATCH)) \
- && !(defined (PIOCOPENLWP) || defined (UNIXWARE))
+ && !(defined (PIOCOPENLWP))
static void *
procfs_address_to_host_pointer (CORE_ADDR addr)
{
- struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+ struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
void *ptr;
gdb_assert (sizeof (ptr) == TYPE_LENGTH (ptr_type));
- gdbarch_address_to_pointer (target_gdbarch, ptr_type,
+ gdbarch_address_to_pointer (target_gdbarch (), ptr_type,
(gdb_byte *) &ptr, addr);
return ptr;
}
#endif
-int
+static int
proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
{
#if !defined (PCWATCH) && !defined (PIOCSWATCH)
return 0;
#else
/* Horrible hack! Detect Solaris 2.5, because this doesn't work on 2.5. */
-#if defined (PIOCOPENLWP) || defined (UNIXWARE) /* Solaris 2.5: bail out. */
+#if defined (PIOCOPENLWP) /* Solaris 2.5: bail out. */
return 0;
#else
struct {
register for the LWP that we're interested in. Returns the
matching ssh struct (LDT entry). */
-struct ssd *
+static struct ssd *
proc_get_LDT_entry (procinfo *pi, int key)
{
static struct ssd *ldt_entry = NULL;
/* Allocate space for one LDT entry.
This alloc must persist, because we return a pointer to it. */
if (ldt_entry == NULL)
- ldt_entry = (struct ssd *) xmalloc (sizeof (struct ssd));
+ ldt_entry = XNEW (struct ssd);
/* Open the file descriptor for the LDT table. */
sprintf (pathname, "/proc/%d/ldt", pi->pid);
procinfo *pi;
/* Find procinfo for the lwp. */
- if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
+ if ((pi = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid))) == NULL)
{
warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%ld."),
- PIDGET (ptid), TIDGET (ptid));
+ ptid_get_pid (ptid), ptid_get_lwp (ptid));
return NULL;
}
/* get its general registers. */
if ((gregs = proc_get_gregs (pi)) == NULL)
{
warning (_("procfs_find_LDT_entry: could not read gregs for %d:%ld."),
- PIDGET (ptid), TIDGET (ptid));
+ ptid_get_pid (ptid), ptid_get_lwp (ptid));
return NULL;
}
/* Now extract the GS register's lower 16 bits. */
#if defined (PIOCNTHR) && defined (PIOCTLIST)
/* OSF version */
-int
+static int
proc_get_nthreads (procinfo *pi)
{
int nthreads = 0;
#else
#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
-/* Solaris and Unixware version */
-int
+/* Solaris version */
+static int
proc_get_nthreads (procinfo *pi)
{
if (!pi->status_valid)
#else
/* Default version */
-int
+static int
proc_get_nthreads (procinfo *pi)
{
return 0;
currently executing. */
#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
-/* Solaris and Unixware version */
-int
+/* Solaris version */
+static int
proc_get_current_thread (procinfo *pi)
{
/* Note: this should be applied to the root procinfo for the
#else
#if defined (PIOCNTHR) && defined (PIOCTLIST)
/* OSF version */
-int
+static int
proc_get_current_thread (procinfo *pi)
{
#if 0 /* FIXME: not ready for prime time? */
#else
/* Default version */
-int
+static int
proc_get_current_thread (procinfo *pi)
{
return 0;
unfortunately requires a different method on every OS. Returns
non-zero for success, zero for failure. */
-int
+static int
proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore)
{
if (thread && parent) /* sanity */
#if defined (PIOCLSTATUS)
/* Solaris 2.5 (ioctl) version */
-int
+static int
proc_update_threads (procinfo *pi)
{
gdb_prstatus_t *prstatus;
if ((nlwp = proc_get_nthreads (pi)) <= 1)
return 1; /* Process is not multi-threaded; nothing to do. */
- prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1));
+ prstatus = XNEWVEC (gdb_prstatus_t, nlwp + 1);
old_chain = make_cleanup (xfree, prstatus);
if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0)
}
#else
#ifdef NEW_PROC_API
-/* Unixware and Solaris 6 (and later) version. */
+/* Solaris 6 (and later) version. */
static void
do_closedir_cleanup (void *dir)
{
closedir (dir);
}
-int
+static int
proc_update_threads (procinfo *pi)
{
char pathname[MAX_PROC_NAME_SIZE + 16];
proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
- /* Unixware
-
- Note: this brute-force method is the only way I know of to
- accomplish this task on Unixware. This method will also work on
- Solaris 2.6 and 2.7. There is a much simpler and more elegant
- way to do this on Solaris, but the margins of this manuscript are
- too small to write it here... ;-) */
+ /* Note: this brute-force method was originally devised for Unixware
+ (support removed since), and will also work on Solaris 2.6 and
+ 2.7. The original comment mentioned the existence of a much
+ simpler and more elegant way to do this on Solaris, but didn't
+ point out what that was. */
strcpy (pathname, pi->pathname);
strcat (pathname, "/lwp");
#else
#ifdef PIOCTLIST
/* OSF version */
-int
+static int
proc_update_threads (procinfo *pi)
{
int nthreads, i;
if (nthreads < 2)
return 0; /* Nothing to do for 1 or fewer threads. */
- threads = xmalloc (nthreads * sizeof (tid_t));
+ threads = XNEWVEC (tid_t, nthreads);
if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0)
proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__);
}
#else
/* Default version */
-int
+static int
proc_update_threads (procinfo *pi)
{
return 0;
function. PTR is an opaque parameter for function. Returns the
first non-zero return value from the callee, or zero. */
-int
+static int
proc_iterate_over_threads (procinfo *pi,
int (*func) (procinfo *, procinfo *, void *),
void *ptr)
static void proc_trace_syscalls_1 (procinfo *pi, int syscallnum,
int entry_or_exit, int mode, int from_tty);
-/* On mips-irix, we need to insert a breakpoint at __dbx_link during
- the startup phase. The following two variables are used to record
- the address of the breakpoint, and the code that was replaced by
- a breakpoint. */
-static int dbx_link_bpt_addr = 0;
-static void *dbx_link_bpt;
-
/* Sets up the inferior to be debugged. Registers to trace signals,
hardware faults, and syscalls. Note: does not set RLC flag: caller
may want to customize that. Returns zero for success (note!
sysset_t *traced_syscall_exits;
int status;
-#ifdef PROCFS_DONT_TRACE_FAULTS
- /* On some systems (OSF), we don't trace hardware faults.
- Apparently it's enough that we catch them as signals.
- Wonder why we don't just do that in general? */
- premptyset (&traced_faults); /* don't trace faults. */
-#else
/* Register to trace hardware faults in the child. */
prfillset (&traced_faults); /* trace all faults... */
gdb_prdelset (&traced_faults, FLTPAGE); /* except page fault. */
-#endif
if (!proc_set_traced_faults (pi, &traced_faults))
return __LINE__;
}
static void
-procfs_attach (struct target_ops *ops, char *args, int from_tty)
+procfs_attach (struct target_ops *ops, const char *args, int from_tty)
{
char *exec_file;
int pid;
fflush (stdout);
}
inferior_ptid = do_attach (pid_to_ptid (pid));
- push_target (ops);
+ if (!target_is_pushed (ops))
+ push_target (ops);
}
static void
-procfs_detach (struct target_ops *ops, char *args, int from_tty)
+procfs_detach (struct target_ops *ops, const char *args, int from_tty)
{
int sig = 0;
- int pid = PIDGET (inferior_ptid);
+ int pid = ptid_get_pid (inferior_ptid);
if (args)
sig = atoi (args);
inferior_ptid = null_ptid;
detach_inferior (pid);
- unpush_target (ops);
+ inf_child_maybe_unpush_target (ops);
}
static ptid_t
int fail;
int lwpid;
- if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
+ if ((pi = create_procinfo (ptid_get_pid (ptid), 0)) == NULL)
perror (_("procfs: out of memory in 'attach'"));
if (!open_procinfo_files (pi, FD_CTL))
{
fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
- PIDGET (ptid));
+ ptid_get_pid (ptid));
dead_procinfo (pi, errmsg, NOKILL);
}
create_procinfo (pi->pid, lwpid);
/* Add it to gdb's thread list. */
- ptid = MERGEPID (pi->pid, lwpid);
+ ptid = ptid_build (pi->pid, lwpid, 0);
add_thread (ptid);
return ptid;
procinfo *pi;
/* Find procinfo for the main process. */
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid),
+ 0); /* FIXME: threads */
if (signo)
if (!proc_set_current_signal (pi, signo))
proc_warn (pi, "do_detach, set_current_signal", __LINE__);
{
gdb_gregset_t *gregs;
procinfo *pi;
- int pid = PIDGET (inferior_ptid);
- int tid = TIDGET (inferior_ptid);
+ int pid = ptid_get_pid (inferior_ptid);
+ int tid = ptid_get_lwp (inferior_ptid);
struct gdbarch *gdbarch = get_regcache_arch (regcache);
pi = find_procinfo_or_die (pid, tid);
{
gdb_gregset_t *gregs;
procinfo *pi;
- int pid = PIDGET (inferior_ptid);
- int tid = TIDGET (inferior_ptid);
+ int pid = ptid_get_pid (inferior_ptid);
+ int tid = ptid_get_lwp (inferior_ptid);
struct gdbarch *gdbarch = get_regcache_arch (regcache);
pi = find_procinfo_or_die (pid, tid);
return 0;
}
-/* Remove the breakpoint that we inserted in __dbx_link().
- Does nothing if the breakpoint hasn't been inserted or has already
- been removed. */
-
-static void
-remove_dbx_link_breakpoint (void)
-{
- if (dbx_link_bpt_addr == 0)
- return;
-
- if (deprecated_remove_raw_breakpoint (target_gdbarch, dbx_link_bpt) != 0)
- warning (_("Unable to remove __dbx_link breakpoint."));
-
- dbx_link_bpt_addr = 0;
- dbx_link_bpt = NULL;
-}
-
#ifdef SYS_syssgi
/* Return the address of the __dbx_link() function in the file
refernced by ABFD by scanning its symbol table. Return 0 if
long storage_needed;
CORE_ADDR sym_addr;
- abfd = bfd_fdopenr ("unamed", 0, fd);
+ abfd = gdb_bfd_fdopenr ("unamed", 0, fd);
if (abfd == NULL)
{
warning (_("Failed to create a bfd: %s."), bfd_errmsg (bfd_get_error ()));
{
/* Not the correct format, so we can not possibly find the dbx_link
symbol in it. */
- bfd_close (abfd);
+ gdb_bfd_unref (abfd);
return 0;
}
sym_addr = dbx_link_addr (abfd);
if (sym_addr != 0)
{
+ struct breakpoint *dbx_link_bpt;
+
/* Insert the breakpoint. */
- dbx_link_bpt_addr = sym_addr;
- dbx_link_bpt = deprecated_insert_raw_breakpoint (target_gdbarch, NULL,
- sym_addr);
+ dbx_link_bpt
+ = create_and_insert_solib_event_breakpoint (target_gdbarch (),
+ sym_addr);
if (dbx_link_bpt == NULL)
{
warning (_("Failed to insert dbx_link breakpoint."));
- bfd_close (abfd);
+ gdb_bfd_unref (abfd);
return 0;
}
- bfd_close (abfd);
+ gdb_bfd_unref (abfd);
return 1;
}
- bfd_close (abfd);
+ gdb_bfd_unref (abfd);
return 0;
}
retval = pid_to_ptid (-1);
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
if (pi)
{
/* We must assume that the status is stale now... */
/* /proc file not found; presumably child has terminated. */
wait_retval = wait (&wstat); /* "wait" for the child's exit. */
- if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
+ /* Wrong child? */
+ if (wait_retval != ptid_get_pid (inferior_ptid))
error (_("procfs: couldn't stop "
"process %d: wait returned %d."),
- PIDGET (inferior_ptid), wait_retval);
+ ptid_get_pid (inferior_ptid), wait_retval);
/* FIXME: might I not just use waitpid?
Or try find_procinfo to see if I know about this child? */
retval = pid_to_ptid (wait_retval);
/* The 'pid' we will return to GDB is composed of
the process ID plus the lwp ID. */
- retval = MERGEPID (pi->pid, proc_get_current_thread (pi));
+ retval = ptid_build (pi->pid, proc_get_current_thread (pi), 0);
switch (why) {
case PR_SIGNALLED:
else
{
/* How to keep going without returning to wfi: */
- target_resume (ptid, 0, TARGET_SIGNAL_0);
+ target_resume (ptid, 0, GDB_SIGNAL_0);
goto wait_again;
}
}
/* This is an internal event and should be transparent
to wfi, so resume the execution and wait again. See
comment in procfs_init_inferior() for more details. */
- target_resume (ptid, 0, TARGET_SIGNAL_0);
+ target_resume (ptid, 0, GDB_SIGNAL_0);
goto wait_again;
}
#endif
if (!find_procinfo (pi->pid, temp_tid))
create_procinfo (pi->pid, temp_tid);
- temp_ptid = MERGEPID (pi->pid, temp_tid);
+ temp_ptid = ptid_build (pi->pid, temp_tid, 0);
/* If not in GDB's thread list, add it. */
if (!in_thread_list (temp_ptid))
add_thread (temp_ptid);
create_procinfo (pi->pid, temp_tid);
/* If not in GDB's thread list, add it. */
- temp_ptid = MERGEPID (pi->pid, temp_tid);
+ temp_ptid = ptid_build (pi->pid, temp_tid, 0);
if (!in_thread_list (temp_ptid))
add_thread (temp_ptid);
#if (FLTTRACE != FLTBPT) /* Avoid "duplicate case" error. */
case FLTTRACE:
#endif
- /* If we hit our __dbx_link() internal breakpoint,
- then remove it. See comments in procfs_init_inferior()
- for more details. */
- if (dbx_link_bpt_addr != 0
- && dbx_link_bpt_addr
- == regcache_read_pc (get_current_regcache ()))
- remove_dbx_link_breakpoint ();
-
wstat = (SIGTRAP << 8) | 0177;
break;
case FLTSTACK:
}
/* Got this far without error: If retval isn't in the
threads database, add it. */
- if (PIDGET (retval) > 0 &&
+ if (ptid_get_pid (retval) > 0 &&
!ptid_equal (retval, inferior_ptid) &&
!in_thread_list (retval))
{
GDB's list and to our own. If we don't create a
procinfo, resume may be unhappy later. */
add_thread (retval);
- if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
- create_procinfo (PIDGET (retval), TIDGET (retval));
+ if (find_procinfo (ptid_get_pid (retval),
+ ptid_get_lwp (retval)) == NULL)
+ create_procinfo (ptid_get_pid (retval),
+ ptid_get_lwp (retval));
}
}
else /* Flags do not indicate STOPPED. */
/* Perform a partial transfer to/from the specified object. For
memory transfers, fall back to the old memory xfer functions. */
-static LONGEST
+static enum target_xfer_status
procfs_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+ const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
{
switch (object)
{
case TARGET_OBJECT_MEMORY:
- if (readbuf)
- return (*ops->deprecated_xfer_memory) (offset, readbuf,
- len, 0/*read*/, NULL, ops);
- if (writebuf)
- return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
- len, 1/*write*/, NULL, ops);
- return -1;
+ return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
#ifdef NEW_PROC_API
case TARGET_OBJECT_AUXV:
return memory_xfer_auxv (ops, object, annex, readbuf, writebuf,
- offset, len);
+ offset, len, xfered_len);
#endif
default:
- if (ops->beneath != NULL)
- return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
- readbuf, writebuf, offset, len);
- return -1;
+ return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+ readbuf, writebuf, offset, len,
+ xfered_len);
}
}
+/* Helper for procfs_xfer_partial that handles memory transfers.
+ Arguments are like target_xfer_partial. */
-/* Transfer LEN bytes between GDB address MYADDR and target address
- MEMADDR. If DOWRITE is non-zero, transfer them to the target,
- otherwise transfer them from the target. TARGET is unused.
-
- The return value is 0 if an error occurred or no bytes were
- transferred. Otherwise, it will be a positive value which
- indicates the number of bytes transferred between gdb and the
- target. (Note that the interface also makes provisions for
- negative values, but this capability isn't implemented here.) */
-
-static int
-procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
- struct mem_attrib *attrib, struct target_ops *target)
+static enum target_xfer_status
+procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
{
procinfo *pi;
- int nbytes = 0;
+ int nbytes;
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
if (pi->as_fd == 0 &&
open_procinfo_files (pi, FD_AS) == 0)
{
proc_warn (pi, "xfer_memory, open_proc_files", __LINE__);
- return 0;
+ return TARGET_XFER_E_IO;
}
- if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
+ if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) != (off_t) memaddr)
+ return TARGET_XFER_E_IO;
+
+ if (writebuf != NULL)
{
- if (dowrite)
- {
-#ifdef NEW_PROC_API
- PROCFS_NOTE ("write memory:\n");
-#else
- PROCFS_NOTE ("write memory:\n");
-#endif
- nbytes = write (pi->as_fd, myaddr, len);
- }
- else
- {
- PROCFS_NOTE ("read memory:\n");
- nbytes = read (pi->as_fd, myaddr, len);
- }
- if (nbytes < 0)
- {
- nbytes = 0;
- }
+ PROCFS_NOTE ("write memory:\n");
+ nbytes = write (pi->as_fd, writebuf, len);
+ }
+ else
+ {
+ PROCFS_NOTE ("read memory:\n");
+ nbytes = read (pi->as_fd, readbuf, len);
}
- return nbytes;
+ if (nbytes <= 0)
+ return TARGET_XFER_E_IO;
+ *xfered_len = nbytes;
+ return TARGET_XFER_OK;
}
/* Called by target_resume before making child runnable. Mark cached
if (!proc_set_gregs (pi)) /* flush gregs cache */
proc_warn (pi, "target_resume, set_gregs",
__LINE__);
- if (gdbarch_fp0_regnum (target_gdbarch) >= 0)
+ if (gdbarch_fp0_regnum (target_gdbarch ()) >= 0)
if (pi->fpregs_dirty)
if (parent == NULL ||
proc_get_current_thread (parent) != pi->tid)
static void
procfs_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum target_signal signo)
+ ptid_t ptid, int step, enum gdb_signal signo)
{
procinfo *pi, *thread;
int native_signo;
to proc_run_process (for use in the prrun struct by ioctl). */
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
/* First cut: ignore pid argument. */
errno = 0;
/* Convert signal to host numbering. */
if (signo == 0 ||
- (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop))
+ (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop))
native_signo = 0;
else
- native_signo = target_signal_to_host (signo);
+ native_signo = gdb_signal_to_host (signo);
pi->ignore_next_sigstop = 0;
/* Void the process procinfo's caches. */
invalidate_cache (NULL, pi, NULL);
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
{
/* Resume a specific thread, presumably suppressing the
others. */
- thread = find_procinfo (PIDGET (ptid), TIDGET (ptid));
+ thread = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid));
if (thread != NULL)
{
if (thread->tid != 0)
/* Set up to trace signals in the child process. */
static void
-procfs_pass_signals (int numsigs, unsigned char *pass_signals)
+procfs_pass_signals (struct target_ops *self,
+ int numsigs, unsigned char *pass_signals)
{
gdb_sigset_t signals;
- procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
int signo;
prfillset (&signals);
for (signo = 0; signo < NSIG; signo++)
{
- int target_signo = target_signal_from_host (signo);
+ int target_signo = gdb_signal_from_host (signo);
if (target_signo < numsigs && pass_signals[target_signo])
gdb_prdelset (&signals, signo);
}
kill(SIGINT) to the child's process group. */
static void
-procfs_stop (ptid_t ptid)
+procfs_interrupt (struct target_ops *self, ptid_t ptid)
{
kill (-inferior_process_group (), SIGINT);
}
int parent_pid;
parent_pid = proc_parent_pid (pi);
-#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
- /* FIXME: use access functions. */
- /* Alpha OSF/1-3.x procfs needs a clear of the current signal
- before the PIOCKILL, otherwise it might generate a corrupted core
- file for the inferior. */
- if (ioctl (pi->ctl_fd, PIOCSSIG, NULL) < 0)
- {
- printf_filtered ("unconditionally_kill: SSIG failed!\n");
- }
-#endif
#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL
/* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal
to kill the inferior, otherwise it might remain stopped with a
if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
{
/* Find procinfo for main process. */
- procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0);
+ procinfo *pi = find_procinfo (ptid_get_pid (inferior_ptid), 0);
if (pi)
unconditionally_kill_inferior (pi);
if (!ptid_equal (inferior_ptid, null_ptid))
{
/* Find procinfo for main process. */
- pi = find_procinfo (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo (ptid_get_pid (inferior_ptid), 0);
if (pi)
destroy_procinfo (pi);
}
- unpush_target (ops);
-
- if (dbx_link_bpt != NULL)
- {
- deprecated_remove_raw_breakpoint (target_gdbarch, dbx_link_bpt);
- dbx_link_bpt_addr = 0;
- dbx_link_bpt = NULL;
- }
generic_mourn_inferior ();
+
+ inf_child_maybe_unpush_target (ops);
}
/* When GDB forks to create a runnable inferior process, this function
/* This routine called on the parent side (GDB side)
after GDB forks the inferior. */
- push_target (ops);
+ if (!target_is_pushed (ops))
+ push_target (ops);
if ((pi = create_procinfo (pid, 0)) == NULL)
perror (_("procfs: out of memory in 'init_inferior'"));
this point, but it didn't have any lwp info yet. Notify the core
about it. This changes inferior_ptid as well. */
thread_change_ptid (pid_to_ptid (pid),
- MERGEPID (pid, lwpid));
+ ptid_build (pid, lwpid, 0));
- /* Typically two, one trap to exec the shell, one to exec the
- program being debugged. Defined by "inferior.h". */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
#ifdef SYS_syssgi
if (current_inferior ()->attach_flag || !target_can_run (¤t_target))
return;
- proc_trace_syscalls_1 (find_procinfo_or_die (PIDGET (inferior_ptid), 0),
- SYS_syssgi, PR_SYSEXIT, FLAG_RESET, 0);
+ proc_trace_syscalls_1 (find_procinfo_or_die (ptid_get_pid (inferior_ptid),
+ 0), SYS_syssgi, PR_SYSEXIT, FLAG_RESET, 0);
#endif
}
-/* Callback for find_new_threads. Calls "add_thread". */
+/* Callback for update_thread_list. Calls "add_thread". */
static int
procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
{
- ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
+ ptid_t gdb_threadid = ptid_build (pi->pid, thread->tid, 0);
if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid))
add_thread (gdb_threadid);
/* Query all the threads that the target knows about, and give them
back to GDB to add to its list. */
-void
-procfs_find_new_threads (struct target_ops *ops)
+static void
+procfs_update_thread_list (struct target_ops *ops)
{
procinfo *pi;
+ prune_threads ();
+
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
proc_update_threads (pi);
proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
}
int proc, thread;
procinfo *pi;
- proc = PIDGET (ptid);
- thread = TIDGET (ptid);
+ proc = ptid_get_pid (ptid);
+ thread = ptid_get_lwp (ptid);
/* If I don't know it, it ain't alive! */
if ((pi = find_procinfo (proc, thread)) == NULL)
return 0;
/* Convert PTID to a string. Returns the string in a static
buffer. */
-char *
+static char *
procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static char buf[80];
- if (TIDGET (ptid) == 0)
- sprintf (buf, "process %d", PIDGET (ptid));
+ if (ptid_get_lwp (ptid) == 0)
+ sprintf (buf, "process %d", ptid_get_pid (ptid));
else
- sprintf (buf, "LWP %ld", TIDGET (ptid));
+ sprintf (buf, "LWP %ld", ptid_get_lwp (ptid));
return buf;
}
/* Insert a watchpoint. */
-int
+static int
procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
int after)
{
-#ifndef UNIXWARE
#ifndef AIX5
int pflags = 0;
procinfo *pi;
- pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
- PIDGET (inferior_ptid) : PIDGET (ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (ptid) == -1 ?
+ ptid_get_pid (inferior_ptid) : ptid_get_pid (ptid),
+ 0);
/* Translate from GDB's flags to /proc's. */
if (len > 0) /* len == 0 means delete watchpoint. */
proc_error (pi, "set_watchpoint", __LINE__);
}
#endif /* AIX5 */
-#endif /* UNIXWARE */
return 0;
}
target_can_use_hardware_watchpoint. */
static int
-procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
+procfs_can_use_hw_breakpoint (struct target_ops *self,
+ enum bptype type,
+ int cnt, int othertype)
{
/* Due to the way that proc_set_watchpoint() is implemented, host
and target pointers must be of the same size. If they are not,
procfs_address_to_host_pointer will reveal that an internal error
will be generated when the host and target pointer sizes are
different. */
- struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+ struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
if (sizeof (void *) != TYPE_LENGTH (ptr_type))
return 0;
fault, else returns zero. */
static int
-procfs_stopped_by_watchpoint (void)
+procfs_stopped_by_watchpoint (struct target_ops *ops)
{
procinfo *pi;
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
{
{
procinfo *pi;
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
return proc_watchpoint_address (pi, addr);
}
static int
-procfs_insert_watchpoint (CORE_ADDR addr, int len, int type,
+procfs_insert_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len,
+ enum target_hw_bp_type type,
struct expression *cond)
{
if (!target_have_steppable_watchpoint
- && !gdbarch_have_nonsteppable_watchpoint (target_gdbarch))
+ && !gdbarch_have_nonsteppable_watchpoint (target_gdbarch ()))
{
/* When a hardware watchpoint fires off the PC will be left at
the instruction following the one which caused the
}
static int
-procfs_remove_watchpoint (CORE_ADDR addr, int len, int type,
+procfs_remove_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len,
+ enum target_hw_bp_type type,
struct expression *cond)
{
return procfs_set_watchpoint (inferior_ptid, addr, 0, 0, 0);
}
static int
-procfs_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+procfs_region_ok_for_hw_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len)
{
/* The man page for proc(4) on Solaris 2.6 and up says that the
system can support "thousands" of hardware watchpoints, but gives
(map->pr_mflags & MA_READ) != 0,
(map->pr_mflags & MA_WRITE) != 0,
(map->pr_mflags & MA_EXEC) != 0,
+ 1, /* MODIFIED is unknown, pass it as true. */
data);
}
the callback. */
static int
-proc_find_memory_regions (find_memory_region_ftype func, void *data)
+proc_find_memory_regions (struct target_ops *self,
+ find_memory_region_ftype func, void *data)
{
- procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
return iterate_over_mappings (pi, func, data,
find_memory_regions_callback);
pr_off = map->pr_off;
#endif
- if (gdbarch_addr_bit (target_gdbarch) == 32)
+ if (gdbarch_addr_bit (target_gdbarch ()) == 32)
printf_filtered ("\t%#10lx %#10lx %#10lx %#10x %7s\n",
(unsigned long) map->pr_vaddr,
(unsigned long) map->pr_vaddr + map->pr_size - 1,
return; /* No output for summary mode. */
printf_filtered (_("Mapped address spaces:\n\n"));
- if (gdbarch_ptr_bit (target_gdbarch) == 32)
+ if (gdbarch_ptr_bit (target_gdbarch ()) == 32)
printf_filtered ("\t%10s %10s %10s %10s %7s\n",
"Start Addr",
" End Addr",
/* Implement the "info proc" command. */
static void
-procfs_info_proc (struct target_ops *ops, char *args,
+procfs_info_proc (struct target_ops *ops, const char *args,
enum info_proc_what what)
{
struct cleanup *old_chain;
argv++;
}
if (pid == 0)
- pid = PIDGET (inferior_ptid);
+ pid = ptid_get_pid (inferior_ptid);
if (pid == 0)
error (_("No current process: you must name one."));
else
{
procinfo *pi;
- if (PIDGET (inferior_ptid) <= 0)
+ if (ptid_get_pid (inferior_ptid) <= 0)
error (_("you must be debugging a process to use this command."));
if (args == NULL || args[0] == 0)
error_no_arg (_("system call to trace"));
- pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
if (isdigit (args[0]))
{
const int syscallnum = atoi (args);
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern void _initialize_procfs (void);
+
void
_initialize_procfs (void)
{
}
/* =================== GCORE .NOTE "MODULE" =================== */
-#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
-/* gcore only implemented on solaris and unixware (so far) */
+#if defined (PIOCOPENLWP) || defined (PCAGENT)
+/* gcore only implemented on solaris (so far) */
static char *
procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
char *note_data, int *note_size,
- enum target_signal stop_signal)
+ enum gdb_signal stop_signal)
{
struct regcache *regcache = get_thread_regcache (ptid);
gdb_gregset_t gregs;
unsigned long merged_pid;
struct cleanup *old_chain;
- merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
+ merged_pid = ptid_get_lwp (ptid) << 16 | ptid_get_pid (ptid);
/* This part is the old method for fetching registers.
It should be replaced by the newer one using regsets
once it is implemented in this platform:
- gdbarch_regset_from_core_section() and regset->collect_regset(). */
+ gdbarch_iterate_over_regset_sections(). */
old_chain = save_inferior_ptid ();
inferior_ptid = ptid;
bfd *obfd;
char *note_data;
int *note_size;
- enum target_signal stop_signal;
+ enum gdb_signal stop_signal;
};
static int
if (pi != NULL)
{
- ptid_t ptid = MERGEPID (pi->pid, thread->tid);
+ ptid_t ptid = ptid_build (pi->pid, thread->tid, 0);
args->note_data = procfs_do_thread_registers (args->obfd, ptid,
args->note_data,
static int
find_signalled_thread (struct thread_info *info, void *data)
{
- if (info->suspend.stop_signal != TARGET_SIGNAL_0
+ if (info->suspend.stop_signal != GDB_SIGNAL_0
&& ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
return 1;
return 0;
}
-static enum target_signal
+static enum gdb_signal
find_stop_signal (void)
{
struct thread_info *info =
if (info)
return info->suspend.stop_signal;
else
- return TARGET_SIGNAL_0;
+ return GDB_SIGNAL_0;
}
static char *
-procfs_make_note_section (bfd *obfd, int *note_size)
+procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
{
struct cleanup *old_chain;
gdb_gregset_t gregs;
gdb_fpregset_t fpregs;
char fname[16] = {'\0'};
char psargs[80] = {'\0'};
- procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
char *note_data = NULL;
char *inf_args;
struct procfs_corefile_thread_data thread_args;
gdb_byte *auxv;
int auxv_len;
- enum target_signal stop_signal;
+ enum gdb_signal stop_signal;
if (get_exec_file (0))
{
strncpy (fname, lbasename (get_exec_file (0)), sizeof (fname));
- strncpy (psargs, get_exec_file (0),
- sizeof (psargs));
+ fname[sizeof (fname) - 1] = 0;
+ strncpy (psargs, get_exec_file (0), sizeof (psargs));
+ psargs[sizeof (psargs) - 1] = 0;
inf_args = get_inferior_args ();
if (inf_args && *inf_args &&
stop_signal = find_stop_signal ();
-#ifdef UNIXWARE
+#ifdef NEW_PROC_API
fill_gregset (get_current_regcache (), &gregs, -1);
note_data = elfcore_write_pstatus (obfd, note_data, note_size,
- PIDGET (inferior_ptid),
+ ptid_get_pid (inferior_ptid),
stop_signal, &gregs);
#endif
thread_args.stop_signal = stop_signal;
proc_iterate_over_threads (pi, procfs_corefile_thread_callback,
&thread_args);
-
- /* There should be always at least one thread. */
- gdb_assert (thread_args.note_data != note_data);
note_data = thread_args.note_data;
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
xfree (auxv);
}
- make_cleanup (xfree, note_data);
return note_data;
}
-#else /* !(Solaris or Unixware) */
+#else /* !Solaris */
static char *
-procfs_make_note_section (bfd *obfd, int *note_size)
+procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
{
error (_("gcore not implemented for this host."));
return NULL; /* lint */
}
-#endif /* Solaris or Unixware */
+#endif /* Solaris */
/* =================== END GCORE .NOTE "MODULE" =================== */