X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fprocfs.c;h=ccc5e26064bf3620947219d32e166381e2c15667;hb=29298bf66f62f2f6c1efb0685623fbc29dfade90;hp=3c747cd3e21eb97ebce6585e8a226ef0cb4b09fe;hpb=70b33f195b0d76e140921db40c0bea5a7c9abc42;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/procfs.c b/gdb/procfs.c index 3c747cd3e2..ccc5e26064 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -1,6 +1,6 @@ /* Machine independent support for Solaris /proc (process file system) for GDB. - Copyright (C) 1999-2018 Free Software Foundation, Inc. + Copyright (C) 1999-2019 Free Software Foundation, Inc. Written by Michael Snyder at Cygnus Solutions. Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others. @@ -31,14 +31,14 @@ #include "regcache.h" #include "inf-child.h" #include "nat/fork-inferior.h" -#include "filestuff.h" +#include "gdbarch.h" #define _STRUCTURED_PROC 1 /* Should be done by configure script. */ #include #include #include -#include "gdb_wait.h" +#include "gdbsupport/gdb_wait.h" #include #include #include "gdb_bfd.h" @@ -46,7 +46,8 @@ #include "auxv.h" #include "procfs.h" #include "observable.h" -#include "common/scoped_fd.h" +#include "gdbsupport/scoped_fd.h" +#include "gdbsupport/pathstuff.h" /* This module provides the interface between GDB and the /proc file system, which is used on many versions of Unix @@ -86,53 +87,90 @@ /* This module defines the GDB target vector and its methods. */ -static void procfs_attach (struct target_ops *, const char *, int); -static void procfs_detach (struct target_ops *, inferior *, int); -static void procfs_resume (struct target_ops *, - ptid_t, int, enum gdb_signal); -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 (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 *, const char *, - const std::string &, char **, int); -static ptid_t procfs_wait (struct target_ops *, - ptid_t, struct target_waitstatus *, int); + 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); +class procfs_target final : public inf_child_target +{ +public: + void create_inferior (const char *, const std::string &, + char **, int) override; + + void kill () override; + + void mourn_inferior () override; + + void attach (const char *, int) override; + void detach (inferior *inf, int) override; + + void resume (ptid_t, int, enum gdb_signal) override; + ptid_t wait (ptid_t, struct target_waitstatus *, int) override; + + void fetch_registers (struct regcache *, int) override; + void store_registers (struct regcache *, int) override; + + enum target_xfer_status xfer_partial (enum target_object object, + const char *annex, + gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) override; + + void pass_signals (gdb::array_view) override; + + void files_info () override; + + void update_thread_list () override; + + bool thread_alive (ptid_t ptid) override; + + std::string pid_to_str (ptid_t) override; + + char *pid_to_exec_file (int pid) override; + + thread_control_capabilities get_thread_control_capabilities () override + { return tc_schedlock; } + + /* find_memory_regions support method for gcore */ + int find_memory_regions (find_memory_region_ftype func, void *data) + override; + + char *make_corefile_notes (bfd *, int *) override; + + bool info_proc (const char *, enum info_proc_what) override; + +#if PR_MODEL_NATIVE == PR_MODEL_LP64 + int auxv_parse (gdb_byte **readptr, + gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) + override; +#endif + + bool stopped_by_watchpoint () override; -static void procfs_update_thread_list (struct target_ops *ops); -static const char *procfs_pid_to_str (struct target_ops *, ptid_t); + int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, + struct expression *) override; -static int proc_find_memory_regions (struct target_ops *self, - find_memory_region_ftype, void *); + int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, + struct expression *) override; -static char *procfs_make_note_section (struct target_ops *self, - bfd *, int *); + int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; -static int procfs_can_use_hw_breakpoint (struct target_ops *self, - enum bptype, int, int); + int can_use_hw_breakpoint (enum bptype, int, int) override; + bool stopped_data_address (CORE_ADDR *) override; +}; -static void procfs_info_proc (struct target_ops *, const char *, - enum info_proc_what); +static procfs_target the_procfs_target; -#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64) +#if PR_MODEL_NATIVE == PR_MODEL_LP64 /* When GDB is built as 64-bit application on Solaris, the auxv data is presented in 64-bit format. We need to provide a custom parser to handle that. */ -static int -procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr, - gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) +int +procfs_target::auxv_parse (gdb_byte **readptr, + gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); gdb_byte *ptr = *readptr; @@ -155,42 +193,6 @@ procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr, } #endif -struct target_ops * -procfs_target (void) -{ - struct target_ops *t = inf_child_target (); - - t->to_create_inferior = procfs_create_inferior; - t->to_kill = procfs_kill_inferior; - t->to_mourn_inferior = procfs_mourn_inferior; - t->to_attach = procfs_attach; - t->to_detach = procfs_detach; - t->to_wait = procfs_wait; - t->to_resume = procfs_resume; - t->to_fetch_registers = procfs_fetch_registers; - t->to_store_registers = procfs_store_registers; - t->to_xfer_partial = procfs_xfer_partial; - t->to_pass_signals = procfs_pass_signals; - t->to_files_info = procfs_files_info; - - 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; - - t->to_has_thread_control = tc_schedlock; - t->to_find_memory_regions = proc_find_memory_regions; - t->to_make_corefile_notes = procfs_make_note_section; - t->to_info_proc = procfs_info_proc; - -#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64) - t->to_auxv_parse = procfs_auxv_parse; -#endif - - t->to_magic = OPS_MAGIC; - - return t; -} - /* =================== END, TARGET_OPS "MODULE" =================== */ /* World Unification: @@ -232,7 +234,7 @@ enum { READ_WATCHFLAG = WA_READ, #define AS_PROC_NAME_FMT "/proc/%d/as" #define MAP_PROC_NAME_FMT "/proc/%d/map" #define STATUS_PROC_NAME_FMT "/proc/%d/status" -#define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus") +#define MAX_PROC_NAME_SIZE sizeof("/proc/999999/lwp/0123456789/lwpstatus") typedef struct procinfo { struct procinfo *next; @@ -273,11 +275,9 @@ static procinfo *find_procinfo_or_die (int pid, int tid); static procinfo *find_procinfo (int pid, int tid); static procinfo *create_procinfo (int pid, int tid); static void destroy_procinfo (procinfo *p); -static void do_destroy_procinfo_cleanup (void *); static void dead_procinfo (procinfo *p, const char *msg, int killp); static int open_procinfo_files (procinfo *p, int which); static void close_procinfo_files (procinfo *p); -static sysset_t *sysset_t_alloc (procinfo *pi); static int iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func, void *data, @@ -385,7 +385,7 @@ open_procinfo_files (procinfo *pi, int which) several. Here is some rationale: There are several file descriptors that may need to be open - for any given process or LWP. The ones we're intereted in are: + for any given process or LWP. The ones we're interested in are: - control (ctl) write-only change the state - status (status) read-only query the state - address space (as) read/write access memory @@ -456,7 +456,8 @@ create_procinfo (int pid, int tid) { procinfo *pi, *parent = NULL; - if ((pi = find_procinfo (pid, tid))) + pi = find_procinfo (pid, tid); + if (pi != NULL) return pi; /* Already exists, nothing to do. */ /* Find parent before doing malloc, to save having to cleanup. */ @@ -470,19 +471,20 @@ create_procinfo (int pid, int tid) pi->pid = pid; pi->tid = tid; - pi->saved_entryset = sysset_t_alloc (pi); - pi->saved_exitset = sysset_t_alloc (pi); + pi->saved_entryset = XNEW (sysset_t); + pi->saved_exitset = XNEW (sysset_t); /* Chain into list. */ if (tid == 0) { - sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid); + xsnprintf (pi->pathname, sizeof (pi->pathname), MAIN_PROC_NAME_FMT, pid); pi->next = procinfo_list; procinfo_list = pi; } else { - sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid); + xsnprintf (pi->pathname, sizeof (pi->pathname), "/proc/%d/lwp/%d", + pid, tid); pi->next = parent->thread_list; parent->thread_list = pi; } @@ -550,11 +552,16 @@ destroy_procinfo (procinfo *pi) } } -static void -do_destroy_procinfo_cleanup (void *pi) +/* A deleter that calls destroy_procinfo. */ +struct procinfo_deleter { - destroy_procinfo ((procinfo *) pi); -} + void operator() (procinfo *pi) const + { + destroy_procinfo (pi); + } +}; + +typedef std::unique_ptr procinfo_up; enum { NOKILL, KILL }; @@ -568,12 +575,10 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p) char procfile[80]; if (pi->pathname) - { - print_sys_errmsg (pi->pathname, errno); - } + print_sys_errmsg (pi->pathname, errno); else { - sprintf (procfile, "process %d", pi->pid); + xsnprintf (procfile, sizeof (procfile), "process %d", pi->pid); print_sys_errmsg (procfile, errno); } if (kill_p == KILL) @@ -583,14 +588,6 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p) error ("%s", msg); } -/* Allocate and (partially) initialize a sysset_t struct. */ - -static sysset_t * -sysset_t_alloc (procinfo *pi) -{ - return (sysset_t *) xmalloc (sizeof (sysset_t)); -} - /* =================== END, STRUCT PROCINFO "MODULE" =================== */ /* =================== /proc "MODULE" =================== */ @@ -618,14 +615,16 @@ static int proc_iterate_over_threads static void proc_warn (procinfo *pi, const char *func, int line) { - sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname); + xsnprintf (errmsg, sizeof (errmsg), "procfs: %s line %d, %s", + func, line, pi->pathname); print_sys_errmsg (errmsg, errno); } static void proc_error (procinfo *pi, const char *func, int line) { - sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname); + xsnprintf (errmsg, sizeof (errmsg), "procfs: %s line %d, %s", + func, line, pi->pathname); perror_with_name (errmsg); } @@ -639,8 +638,7 @@ static int proc_get_status (procinfo *pi) { /* Status file descriptor is opened "lazily". */ - if (pi->status_fd == 0 && - open_procinfo_files (pi, FD_STATUS) == 0) + if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0) { pi->status_valid = 0; return 0; @@ -840,7 +838,7 @@ proc_unset_run_on_last_close (procinfo *pi) } /* 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 + are registered for events in the parent, then we will NOT receive events from the child. Returns non-zero for success, zero for failure. */ @@ -881,8 +879,7 @@ proc_stop_process (procinfo *pi) /* We might conceivably apply this operation to an LWP, and the LWP's ctl file descriptor might not be open. */ - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) + if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0) return 0; else { @@ -912,7 +909,12 @@ proc_wait_for_stop (procinfo *pi) procfs_ctl_t cmd = PCWSTOP; + set_sigint_trap (); + win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); + + clear_sigint_trap (); + /* We been runnin' and we stopped -- need to update status. */ pi->status_valid = 0; @@ -947,11 +949,8 @@ proc_run_process (procinfo *pi, int step, int signo) /* We will probably have to apply this operation to individual threads, so make sure the control file descriptor is open. */ - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } + if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0) + return 0; runflags = PRCFAULT; /* Always clear current fault. */ if (step) @@ -1054,20 +1053,16 @@ proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset) if (pi->tid != 0) pi = find_procinfo_or_die (pi->pid, 0); - struct gdb_proc_ctl_pcsentry { + struct { procfs_ctl_t cmd; /* Use char array to avoid alignment issues. */ char sysset[sizeof (sysset_t)]; - } *argp; - int argp_size = sizeof (struct gdb_proc_ctl_pcsentry); - - argp = (struct gdb_proc_ctl_pcsentry *) xmalloc (argp_size); + } arg; - argp->cmd = PCSENTRY; - memcpy (&argp->sysset, sysset, sizeof (sysset_t)); + arg.cmd = PCSENTRY; + memcpy (&arg.sysset, sysset, sizeof (sysset_t)); - win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size); - xfree (argp); + win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg)); /* The above operation renders the procinfo's cached pstatus obsolete. */ @@ -1096,16 +1091,12 @@ proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset) procfs_ctl_t cmd; /* Use char array to avoid alignment issues. */ char sysset[sizeof (sysset_t)]; - } *argp; - int argp_size = sizeof (struct gdb_proc_ctl_pcsexit); - - argp = (struct gdb_proc_ctl_pcsexit *) xmalloc (argp_size); + } arg; - argp->cmd = PCSEXIT; - memcpy (&argp->sysset, sysset, sizeof (sysset_t)); + arg.cmd = PCSEXIT; + memcpy (&arg.sysset, sysset, sizeof (sysset_t)); - win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size); - xfree (argp); + win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg)); /* The above operation renders the procinfo's cached pstatus obsolete. */ @@ -1337,7 +1328,7 @@ proc_set_current_signal (procinfo *pi, int signo) /* The pointer is just a type alias. */ get_last_target_status (&wait_ptid, &wait_status); - if (ptid_equal (wait_ptid, inferior_ptid) + if (wait_ptid == inferior_ptid && wait_status.kind == TARGET_WAITKIND_STOPPED && wait_status.value.sig == gdb_signal_from_host (signo) && proc_get_status (pi) @@ -1440,9 +1431,7 @@ proc_set_gregs (procinfo *pi) return 0; /* proc_get_regs has already warned. */ if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } + return 0; else { struct { @@ -1476,9 +1465,7 @@ proc_set_fpregs (procinfo *pi) return 0; /* proc_get_fpregs has already warned. */ if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } + return 0; else { struct { @@ -1508,11 +1495,8 @@ proc_kill (procinfo *pi, int signo) /* We might conceivably apply this operation to an LWP, and the LWP's ctl file descriptor might not be open. */ - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } + if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0) + return 0; else { procfs_ctl_t cmd[2]; @@ -1590,7 +1574,7 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags) matching ssh struct (LDT entry). */ static struct ssd * -proc_get_LDT_entry (procinfo *pi, int key) +proc_get_LDT_entry (procinfo *pi, int key) /* ARI: editCase function */ { static struct ssd *ldt_entry = NULL; char pathname[MAX_PROC_NAME_SIZE]; @@ -1601,7 +1585,7 @@ proc_get_LDT_entry (procinfo *pi, int key) ldt_entry = XNEW (struct ssd); /* Open the file descriptor for the LDT table. */ - sprintf (pathname, "/proc/%d/ldt", pi->pid); + xsnprintf (pathname, sizeof (pathname), "/proc/%d/ldt", pi->pid); scoped_fd fd (open_with_retry (pathname, O_RDONLY)); if (fd.get () < 0) { @@ -1613,10 +1597,10 @@ proc_get_LDT_entry (procinfo *pi, int key) while (read (fd.get (), ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd)) { - if (ldt_entry->sel == 0 && - ldt_entry->bo == 0 && - ldt_entry->acc1 == 0 && - ldt_entry->acc2 == 0) + if (ldt_entry->sel == 0 + && ldt_entry->bo == 0 + && ldt_entry->acc1 == 0 + && ldt_entry->acc2 == 0) break; /* end of table */ /* If key matches, return this entry. */ if (ldt_entry->sel == key) @@ -1629,24 +1613,26 @@ proc_get_LDT_entry (procinfo *pi, int key) /* Returns the pointer to the LDT entry of PTID. */ struct ssd * -procfs_find_LDT_entry (ptid_t ptid) +procfs_find_LDT_entry (ptid_t ptid) /* ARI: editCase function */ { gdb_gregset_t *gregs; int key; procinfo *pi; /* Find procinfo for the lwp. */ - if ((pi = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid))) == NULL) + pi = find_procinfo (ptid.pid (), ptid.lwp ()); + if (pi == NULL) { warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%ld."), - ptid_get_pid (ptid), ptid_get_lwp (ptid)); + ptid.pid (), ptid.lwp ()); return NULL; } /* get its general registers. */ - if ((gregs = proc_get_gregs (pi)) == NULL) + gregs = proc_get_gregs (pi); + if (gregs == NULL) { warning (_("procfs_find_LDT_entry: could not read gregs for %d:%ld."), - ptid_get_pid (ptid), ptid_get_lwp (ptid)); + ptid.pid (), ptid.lwp ()); return NULL; } /* Now extract the GS register's lower 16 bits. */ @@ -1723,20 +1709,13 @@ proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore) return 0; /* keep iterating */ } -static void -do_closedir_cleanup (void *dir) -{ - closedir ((DIR *) dir); -} - static int proc_update_threads (procinfo *pi) { char pathname[MAX_PROC_NAME_SIZE + 16]; struct dirent *direntry; - struct cleanup *old_chain = NULL; procinfo *thread; - DIR *dirp; + gdb_dir_up dirp; int lwpid; /* We should never have to apply this operation to any procinfo @@ -1757,19 +1736,19 @@ proc_update_threads (procinfo *pi) strcpy (pathname, pi->pathname); strcat (pathname, "/lwp"); - if ((dirp = opendir (pathname)) == NULL) + dirp.reset (opendir (pathname)); + if (dirp == NULL) proc_error (pi, "update_threads, opendir", __LINE__); - old_chain = make_cleanup (do_closedir_cleanup, dirp); - while ((direntry = readdir (dirp)) != NULL) + while ((direntry = readdir (dirp.get ())) != NULL) if (direntry->d_name[0] != '.') /* skip '.' and '..' */ { lwpid = atoi (&direntry->d_name[0]); - if ((thread = create_procinfo (pi->pid, lwpid)) == NULL) + thread = create_procinfo (pi->pid, lwpid); + if (thread == NULL) proc_error (pi, "update_threads, create_procinfo", __LINE__); } pi->threads_valid = 1; - do_cleanups (old_chain); return 1; } @@ -1805,7 +1784,8 @@ proc_iterate_over_threads (procinfo *pi, for (thread = pi->thread_list; thread != NULL; thread = next) { next = thread->next; /* In case thread is destroyed. */ - if ((retval = (*func) (pi, thread, ptr)) != 0) + retval = (*func) (pi, thread, ptr); + if (retval != 0) break; } @@ -1854,7 +1834,7 @@ procfs_debug_inferior (procinfo *pi) /* Register to trace the 'exit' system call (on entry). */ - traced_syscall_entries = sysset_t_alloc (pi); + traced_syscall_entries = XNEW (sysset_t); premptyset (traced_syscall_entries); praddset (traced_syscall_entries, SYS_exit); praddset (traced_syscall_entries, SYS_lwp_exit); @@ -1870,7 +1850,7 @@ procfs_debug_inferior (procinfo *pi) names. On the SGI, for example, there is no SYS_exec, but there *is* a SYS_execv. So, we try to account for that. */ - traced_syscall_exits = sysset_t_alloc (pi); + traced_syscall_exits = XNEW (sysset_t); premptyset (traced_syscall_exits); #ifdef SYS_exec praddset (traced_syscall_exits, SYS_exec); @@ -1887,10 +1867,9 @@ procfs_debug_inferior (procinfo *pi) return 0; } -static void -procfs_attach (struct target_ops *ops, const char *args, int from_tty) +void +procfs_target::attach (const char *args, int from_tty) { - char *exec_file; int pid; pid = parse_pid_to_attach (args); @@ -1900,26 +1879,26 @@ procfs_attach (struct target_ops *ops, const char *args, int from_tty) if (from_tty) { - exec_file = get_exec_file (0); + const char *exec_file = get_exec_file (0); if (exec_file) printf_filtered (_("Attaching to program `%s', %s\n"), - exec_file, target_pid_to_str (pid_to_ptid (pid))); + exec_file, target_pid_to_str (ptid_t (pid)).c_str ()); else printf_filtered (_("Attaching to %s\n"), - target_pid_to_str (pid_to_ptid (pid))); + target_pid_to_str (ptid_t (pid)).c_str ()); fflush (stdout); } - inferior_ptid = do_attach (pid_to_ptid (pid)); - if (!target_is_pushed (ops)) - push_target (ops); + inferior_ptid = do_attach (ptid_t (pid)); + if (!target_is_pushed (this)) + push_target (this); } -static void -procfs_detach (struct target_ops *ops, inferior *inf, int from_tty) +void +procfs_target::detach (inferior *inf, int from_tty) { - int pid = ptid_get_pid (inferior_ptid); + int pid = inferior_ptid.pid (); if (from_tty) { @@ -1930,15 +1909,14 @@ procfs_detach (struct target_ops *ops, inferior *inf, int from_tty) exec_file = ""; printf_filtered (_("Detaching from program: %s, %s\n"), exec_file, - target_pid_to_str (pid_to_ptid (pid))); - gdb_flush (gdb_stdout); + target_pid_to_str (ptid_t (pid)).c_str ()); } do_detach (); inferior_ptid = null_ptid; - detach_inferior (pid); - inf_child_maybe_unpush_target (ops); + detach_inferior (inf); + maybe_unpush_target (); } static ptid_t @@ -1949,14 +1927,16 @@ do_attach (ptid_t ptid) int fail; int lwpid; - if ((pi = create_procinfo (ptid_get_pid (ptid), 0)) == NULL) + pi = create_procinfo (ptid.pid (), 0); + if (pi == 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", - ptid_get_pid (ptid)); + xsnprintf (errmsg, sizeof (errmsg), + "do_attach: couldn't open /proc file for process %d", + ptid.pid ()); dead_procinfo (pi, errmsg, NOKILL); } @@ -1992,7 +1972,8 @@ do_attach (ptid_t ptid) if (!proc_get_held_signals (pi, &pi->saved_sighold)) dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL); - if ((fail = procfs_debug_inferior (pi)) != 0) + fail = procfs_debug_inferior (pi); + if (fail != 0) dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL); inf = current_inferior (); @@ -2005,7 +1986,7 @@ do_attach (ptid_t ptid) create_procinfo (pi->pid, lwpid); /* Add it to gdb's thread list. */ - ptid = ptid_build (pi->pid, lwpid, 0); + ptid = ptid_t (pi->pid, lwpid, 0); add_thread (ptid); return ptid; @@ -2017,7 +1998,7 @@ do_detach () procinfo *pi; /* Find procinfo for the main process. */ - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); /* FIXME: threads */ if (!proc_set_traced_signals (pi, &pi->saved_sigset)) @@ -2067,22 +2048,21 @@ do_detach () registers. So we cache the results, and mark the cache invalid when the process is resumed. */ -static void -procfs_fetch_registers (struct target_ops *ops, - struct regcache *regcache, int regnum) +void +procfs_target::fetch_registers (struct regcache *regcache, int regnum) { gdb_gregset_t *gregs; procinfo *pi; - ptid_t ptid = regcache_get_ptid (regcache); - int pid = ptid_get_pid (ptid); - int tid = ptid_get_lwp (ptid); + ptid_t ptid = regcache->ptid (); + int pid = ptid.pid (); + int tid = ptid.lwp (); struct gdbarch *gdbarch = regcache->arch (); pi = find_procinfo_or_die (pid, tid); if (pi == NULL) error (_("procfs: fetch_registers failed to find procinfo for %s"), - target_pid_to_str (ptid)); + target_pid_to_str (ptid).c_str ()); gregs = proc_get_gregs (pi); if (gregs == NULL) @@ -2117,22 +2097,21 @@ procfs_fetch_registers (struct target_ops *ops, FIXME: is that a really bad idea? Have to think about cases where writing one register might affect the value of others, etc. */ -static void -procfs_store_registers (struct target_ops *ops, - struct regcache *regcache, int regnum) +void +procfs_target::store_registers (struct regcache *regcache, int regnum) { gdb_gregset_t *gregs; procinfo *pi; - ptid_t ptid = regcache_get_ptid (regcache); - int pid = ptid_get_pid (ptid); - int tid = ptid_get_lwp (ptid); + ptid_t ptid = regcache->ptid (); + int pid = ptid.pid (); + int tid = ptid.lwp (); struct gdbarch *gdbarch = regcache->arch (); pi = find_procinfo_or_die (pid, tid); if (pi == NULL) error (_("procfs: store_registers: failed to find procinfo for %s"), - target_pid_to_str (ptid)); + target_pid_to_str (ptid).c_str ()); gregs = proc_get_gregs (pi); if (gregs == NULL) @@ -2203,9 +2182,9 @@ syscall_is_lwp_create (procinfo *pi, int scall) Returns the id of process (and possibly thread) that incurred the event. Event codes are returned through a pointer parameter. */ -static ptid_t -procfs_wait (struct target_ops *ops, - ptid_t ptid, struct target_waitstatus *status, int options) +ptid_t +procfs_target::wait (ptid_t ptid, struct target_waitstatus *status, + int options) { /* First cut: loosely based on original version 2.1. */ procinfo *pi; @@ -2219,10 +2198,10 @@ wait_again: retry++; wstat = 0; - retval = pid_to_ptid (-1); + retval = ptid_t (-1); /* Find procinfo for main process. */ - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); if (pi) { /* We must assume that the status is stale now... */ @@ -2237,8 +2216,8 @@ wait_again: pi->status_valid = 0; /* re-read again, IMMEDIATELY... */ #endif /* If child is not stopped, wait for it to stop. */ - if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) && - !proc_wait_for_stop (pi)) + if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) + && !proc_wait_for_stop (pi)) { /* wait_for_stop failed: has the child terminated? */ if (errno == ENOENT) @@ -2246,16 +2225,16 @@ wait_again: int wait_retval; /* /proc file not found; presumably child has terminated. */ - wait_retval = wait (&wstat); /* "wait" for the child's exit. */ + wait_retval = ::wait (&wstat); /* "wait" for the child's exit. */ /* Wrong child? */ - if (wait_retval != ptid_get_pid (inferior_ptid)) + if (wait_retval != inferior_ptid.pid ()) error (_("procfs: couldn't stop " "process %d: wait returned %d."), - ptid_get_pid (inferior_ptid), wait_retval); + inferior_ptid.pid (), 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); + retval = ptid_t (wait_retval); } else if (errno == EINTR) goto wait_again; @@ -2294,7 +2273,7 @@ wait_again: /* The 'pid' we will return to GDB is composed of the process ID plus the lwp ID. */ - retval = ptid_build (pi->pid, proc_get_current_thread (pi), 0); + retval = ptid_t (pi->pid, proc_get_current_thread (pi), 0); switch (why) { case PR_SIGNALLED: @@ -2305,8 +2284,8 @@ wait_again: { if (print_thread_events) printf_unfiltered (_("[%s exited]\n"), - target_pid_to_str (retval)); - delete_thread (retval); + target_pid_to_str (retval).c_str ()); + delete_thread (find_thread_ptid (retval)); status->kind = TARGET_WAITKIND_SPURIOUS; return retval; } @@ -2339,7 +2318,7 @@ wait_again: } else { - int temp = wait (&wstat); + int temp = ::wait (&wstat); /* FIXME: shouldn't I make sure I get the right event from the right process? If (for @@ -2351,7 +2330,7 @@ wait_again: /* If wait returns -1, that's what we return to GDB. */ if (temp < 0) - retval = pid_to_ptid (temp); + retval = ptid_t (temp); } } else @@ -2362,8 +2341,10 @@ wait_again: long i, nsysargs, *sysargs; - if ((nsysargs = proc_nsysarg (pi)) > 0 && - (sysargs = proc_sysargs (pi)) != NULL) + nsysargs = proc_nsysarg (pi); + sysargs = proc_sysargs (pi); + + if (nsysargs > 0 && sysargs != NULL) { printf_filtered (_("%ld syscall arguments:\n"), nsysargs); @@ -2411,7 +2392,7 @@ wait_again: if (!find_procinfo (pi->pid, temp_tid)) create_procinfo (pi->pid, temp_tid); - temp_ptid = ptid_build (pi->pid, temp_tid, 0); + temp_ptid = ptid_t (pi->pid, temp_tid, 0); /* If not in GDB's thread list, add it. */ if (!in_thread_list (temp_ptid)) add_thread (temp_ptid); @@ -2424,8 +2405,8 @@ wait_again: { if (print_thread_events) printf_unfiltered (_("[%s exited]\n"), - target_pid_to_str (retval)); - delete_thread (retval); + target_pid_to_str (retval).c_str ()); + delete_thread (find_thread_ptid (retval)); status->kind = TARGET_WAITKIND_SPURIOUS; return retval; } @@ -2446,8 +2427,10 @@ wait_again: long i, nsysargs, *sysargs; - if ((nsysargs = proc_nsysarg (pi)) > 0 && - (sysargs = proc_sysargs (pi)) != NULL) + nsysargs = proc_nsysarg (pi); + sysargs = proc_sysargs (pi); + + if (nsysargs > 0 && sysargs != NULL) { printf_filtered (_("%ld syscall arguments:\n"), nsysargs); @@ -2479,7 +2462,7 @@ wait_again: create_procinfo (pi->pid, temp_tid); /* If not in GDB's thread list, add it. */ - temp_ptid = ptid_build (pi->pid, temp_tid, 0); + temp_ptid = ptid_t (pi->pid, temp_tid, 0); if (!in_thread_list (temp_ptid)) add_thread (temp_ptid); @@ -2492,40 +2475,12 @@ wait_again: wstat = (what << 8) | 0177; break; case PR_FAULTED: - switch (what) { - case FLTWATCH: - wstat = (SIGTRAP << 8) | 0177; - break; - /* FIXME: use si_signo where possible. */ - case FLTPRIV: - case FLTILL: - wstat = (SIGILL << 8) | 0177; - break; - case FLTBPT: - case FLTTRACE: - wstat = (SIGTRAP << 8) | 0177; - break; - case FLTSTACK: - case FLTACCESS: - case FLTBOUNDS: - wstat = (SIGSEGV << 8) | 0177; - break; - case FLTIOVF: - case FLTIZDIV: - case FLTFPE: - wstat = (SIGFPE << 8) | 0177; - break; - case FLTPAGE: /* Recoverable page fault */ - default: /* FIXME: use si_signo if possible for - fault. */ - retval = pid_to_ptid (-1); - printf_filtered ("procfs:%d -- ", __LINE__); - printf_filtered (_("child stopped for unknown reason:\n")); - proc_prettyprint_why (why, what, 1); - error (_("... giving up...")); - break; + { + int signo = pi->prstatus.pr_lwp.pr_info.si_signo; + if (signo != 0) + wstat = (signo << 8) | 0177; } - break; /* case PR_FAULTED: */ + break; default: /* switch (why) unmatched */ printf_filtered ("procfs:%d -- ", __LINE__); printf_filtered (_("child stopped for unknown reason:\n")); @@ -2535,18 +2490,18 @@ wait_again: } /* Got this far without error: If retval isn't in the threads database, add it. */ - if (ptid_get_pid (retval) > 0 && - !ptid_equal (retval, inferior_ptid) && - !in_thread_list (retval)) + if (retval.pid () > 0 + && retval != inferior_ptid + && !in_thread_list (retval)) { /* We have a new thread. We need to add it both to 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 (ptid_get_pid (retval), - ptid_get_lwp (retval)) == NULL) - create_procinfo (ptid_get_pid (retval), - ptid_get_lwp (retval)); + if (find_procinfo (retval.pid (), + retval.lwp ()) == NULL) + create_procinfo (retval.pid (), + retval.lwp ()); } } else /* Flags do not indicate STOPPED. */ @@ -2569,11 +2524,11 @@ wait_again: /* Perform a partial transfer to/from the specified object. For memory transfers, fall back to the old memory xfer functions. */ -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, ULONGEST len, - ULONGEST *xfered_len) +enum target_xfer_status +procfs_target::xfer_partial (enum target_object object, + const char *annex, gdb_byte *readbuf, + const gdb_byte *writebuf, ULONGEST offset, + ULONGEST len, ULONGEST *xfered_len) { switch (object) { @@ -2581,13 +2536,13 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object, return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len); case TARGET_OBJECT_AUXV: - return memory_xfer_auxv (ops, object, annex, readbuf, writebuf, + return memory_xfer_auxv (this, object, annex, readbuf, writebuf, offset, len, xfered_len); default: - return ops->beneath->to_xfer_partial (ops->beneath, object, annex, - readbuf, writebuf, offset, len, - xfered_len); + return this->beneath ()->xfer_partial (object, annex, + readbuf, writebuf, offset, len, + xfered_len); } } @@ -2602,9 +2557,8 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf, int nbytes; /* Find procinfo for main process. */ - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); - if (pi->as_fd == 0 && - open_procinfo_files (pi, FD_AS) == 0) + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); + if (pi->as_fd == 0 && open_procinfo_files (pi, FD_AS) == 0) { proc_warn (pi, "xfer_memory, open_proc_files", __LINE__); return TARGET_XFER_E_IO; @@ -2636,7 +2590,7 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf, File descriptors are also cached. As they are a limited resource, we cannot hold onto them indefinitely. However, as they are expensive to open, we don't want to throw them away - indescriminately either. As a compromise, we will keep the file + indiscriminately either. As a compromise, we will keep the file descriptors for the parent process, but discard any file descriptors we may have accumulated for the threads. @@ -2652,15 +2606,13 @@ invalidate_cache (procinfo *parent, procinfo *pi, void *ptr) #if 0 if (pi->gregs_dirty) - if (parent == NULL || - proc_get_current_thread (parent) != pi->tid) + if (parent == NULL || proc_get_current_thread (parent) != pi->tid) if (!proc_set_gregs (pi)) /* flush gregs cache */ proc_warn (pi, "target_resume, set_gregs", __LINE__); if (gdbarch_fp0_regnum (target_gdbarch ()) >= 0) if (pi->fpregs_dirty) - if (parent == NULL || - proc_get_current_thread (parent) != pi->tid) + if (parent == NULL || proc_get_current_thread (parent) != pi->tid) if (!proc_set_fpregs (pi)) /* flush fpregs cache */ proc_warn (pi, "target_resume, set_fpregs", __LINE__); @@ -2716,9 +2668,8 @@ make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr) allow any child thread to run; if non-zero, then allow only the indicated thread to run. (not implemented yet). */ -static void -procfs_resume (struct target_ops *ops, - ptid_t ptid, int step, enum gdb_signal signo) +void +procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo) { procinfo *pi, *thread; int native_signo; @@ -2740,14 +2691,13 @@ procfs_resume (struct target_ops *ops, to proc_run_process (for use in the prrun struct by ioctl). */ /* Find procinfo for main process. */ - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); /* First cut: ignore pid argument. */ errno = 0; /* Convert signal to host numbering. */ - if (signo == 0 || - (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop)) + if (signo == 0 || (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop)) native_signo = 0; else native_signo = gdb_signal_to_host (signo); @@ -2760,11 +2710,11 @@ procfs_resume (struct target_ops *ops, /* Void the process procinfo's caches. */ invalidate_cache (NULL, pi, NULL); - if (ptid_get_pid (ptid) != -1) + if (ptid.pid () != -1) { /* Resume a specific thread, presumably suppressing the others. */ - thread = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid)); + thread = find_procinfo (ptid.pid (), ptid.lwp ()); if (thread != NULL) { if (thread->tid != 0) @@ -2796,12 +2746,11 @@ procfs_resume (struct target_ops *ops, /* Set up to trace signals in the child process. */ -static void -procfs_pass_signals (struct target_ops *self, - int numsigs, unsigned char *pass_signals) +void +procfs_target::pass_signals (gdb::array_view pass_signals) { sigset_t signals; - procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0); int signo; prfillset (&signals); @@ -2809,7 +2758,7 @@ procfs_pass_signals (struct target_ops *self, for (signo = 0; signo < NSIG; signo++) { int target_signo = gdb_signal_from_host (signo); - if (target_signo < numsigs && pass_signals[target_signo]) + if (target_signo < pass_signals.size () && pass_signals[target_signo]) prdelset (&signals, signo); } @@ -2819,14 +2768,14 @@ procfs_pass_signals (struct target_ops *self, /* Print status information about the child process. */ -static void -procfs_files_info (struct target_ops *ignore) +void +procfs_target::files_info () { struct inferior *inf = current_inferior (); printf_filtered (_("\tUsing the running image of %s %s via /proc.\n"), inf->attach_flag? "attached": "child", - target_pid_to_str (inferior_ptid)); + target_pid_to_str (inferior_ptid).c_str ()); } /* Make it die. Wait for it to die. Clean up after it. Note: this @@ -2862,13 +2811,13 @@ unconditionally_kill_inferior (procinfo *pi) /* We're done debugging it, and we want it to go away. Then we want GDB to forget all about it. */ -static void -procfs_kill_inferior (struct target_ops *ops) +void +procfs_target::kill () { - if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */ + if (inferior_ptid != null_ptid) /* ? */ { /* Find procinfo for main process. */ - procinfo *pi = find_procinfo (ptid_get_pid (inferior_ptid), 0); + procinfo *pi = find_procinfo (inferior_ptid.pid (), 0); if (pi) unconditionally_kill_inferior (pi); @@ -2878,22 +2827,22 @@ procfs_kill_inferior (struct target_ops *ops) /* Forget we ever debugged this thing! */ -static void -procfs_mourn_inferior (struct target_ops *ops) +void +procfs_target::mourn_inferior () { procinfo *pi; - if (!ptid_equal (inferior_ptid, null_ptid)) + if (inferior_ptid != null_ptid) { /* Find procinfo for main process. */ - pi = find_procinfo (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo (inferior_ptid.pid (), 0); if (pi) destroy_procinfo (pi); } generic_mourn_inferior (); - inf_child_maybe_unpush_target (ops); + maybe_unpush_target (); } /* When GDB forks to create a runnable inferior process, this function @@ -2905,7 +2854,6 @@ static void procfs_init_inferior (struct target_ops *ops, int pid) { procinfo *pi; - sigset_t signals; int fail; int lwpid; @@ -2914,7 +2862,8 @@ procfs_init_inferior (struct target_ops *ops, int pid) if (!target_is_pushed (ops)) push_target (ops); - if ((pi = create_procinfo (pid, 0)) == NULL) + pi = create_procinfo (pid, 0); + if (pi == NULL) perror (_("procfs: out of memory in 'init_inferior'")); if (!open_procinfo_files (pi, FD_CTL)) @@ -2933,8 +2882,7 @@ procfs_init_inferior (struct target_ops *ops, int pid) */ /* If not stopped yet, wait for it to stop. */ - if (!(proc_flags (pi) & PR_STOPPED) && - !(proc_wait_for_stop (pi))) + if (!(proc_flags (pi) & PR_STOPPED) && !(proc_wait_for_stop (pi))) dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL); /* Save some of the /proc state to be restored if we detach. */ @@ -2951,7 +2899,8 @@ procfs_init_inferior (struct target_ops *ops, int pid) if (!proc_get_traced_sysexit (pi, pi->saved_exitset)) proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__); - if ((fail = procfs_debug_inferior (pi)) != 0) + fail = procfs_debug_inferior (pi); + if (fail != 0) proc_error (pi, "init_inferior (procfs_debug_inferior)", fail); /* FIXME: logically, we should really be turning OFF run-on-last-close, @@ -2972,8 +2921,8 @@ procfs_init_inferior (struct target_ops *ops, int pid) /* We already have a main thread registered in the thread table at 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), - ptid_build (pid, lwpid, 0)); + thread_change_ptid (ptid_t (pid), + ptid_t (pid, lwpid, 0)); gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED); } @@ -2996,7 +2945,8 @@ procfs_set_exec_trap (void) procinfo *pi; sysset_t *exitset; - if ((pi = create_procinfo (getpid (), 0)) == NULL) + pi = create_procinfo (getpid (), 0); + if (pi == NULL) perror_with_name (_("procfs: create_procinfo failed in child.")); if (open_procinfo_files (pi, FD_CTL) == 0) @@ -3014,7 +2964,7 @@ procfs_set_exec_trap (void) names. On the SGI, for example, there is no SYS_exec, but there *is* a SYS_execv. So, we try to account for that. */ - exitset = sysset_t_alloc (pi); + exitset = XNEW (sysset_t); premptyset (exitset); #ifdef SYS_exec praddset (exitset, SYS_exec); @@ -3056,15 +3006,16 @@ procfs_set_exec_trap (void) abstracted out and shared with other unix targets such as inf-ptrace? */ -static void -procfs_create_inferior (struct target_ops *ops, const char *exec_file, - const std::string &allargs, char **env, int from_tty) +void +procfs_target::create_inferior (const char *exec_file, + const std::string &allargs, + char **env, int from_tty) { - char *shell_file = getenv ("SHELL"); + const char *shell_file = get_shell (); char *tryname; int pid; - if (shell_file != NULL && strchr (shell_file, '/') == NULL) + if (strchr (shell_file, '/') == NULL) { /* We will be looking down the PATH to find shell_file. If we @@ -3138,9 +3089,9 @@ procfs_create_inferior (struct target_ops *ops, const char *exec_file, /* We have something that executes now. We'll be running through the shell at this point (if startup-with-shell is true), but the pid shouldn't change. */ - add_thread_silent (pid_to_ptid (pid)); + add_thread_silent (ptid_t (pid)); - procfs_init_inferior (ops, pid); + procfs_init_inferior (this, pid); } /* An observer for the "inferior_created" event. */ @@ -3155,9 +3106,10 @@ procfs_inferior_created (struct target_ops *ops, int from_tty) static int procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr) { - ptid_t gdb_threadid = ptid_build (pi->pid, thread->tid, 0); + ptid_t gdb_threadid = ptid_t (pi->pid, thread->tid, 0); - if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid)) + thread_info *thr = find_thread_ptid (gdb_threadid); + if (thr == NULL || thr->state == THREAD_EXITED) add_thread (gdb_threadid); return 0; @@ -3166,15 +3118,15 @@ procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr) /* Query all the threads that the target knows about, and give them back to GDB to add to its list. */ -static void -procfs_update_thread_list (struct target_ops *ops) +void +procfs_target::update_thread_list () { procinfo *pi; prune_threads (); /* Find procinfo for main process. */ - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); proc_update_threads (pi); proc_iterate_over_threads (pi, procfs_notice_thread, NULL); } @@ -3183,42 +3135,67 @@ procfs_update_thread_list (struct target_ops *ops) really seem to be doing his job. Got to investigate how to tell when a thread is really gone. */ -static int -procfs_thread_alive (struct target_ops *ops, ptid_t ptid) +bool +procfs_target::thread_alive (ptid_t ptid) { int proc, thread; procinfo *pi; - proc = ptid_get_pid (ptid); - thread = ptid_get_lwp (ptid); + proc = ptid.pid (); + thread = ptid.lwp (); /* If I don't know it, it ain't alive! */ - if ((pi = find_procinfo (proc, thread)) == NULL) - return 0; + pi = find_procinfo (proc, thread); + if (pi == NULL) + return false; /* If I can't get its status, it ain't alive! What's more, I need to forget about it! */ if (!proc_get_status (pi)) { destroy_procinfo (pi); - return 0; + return false; } /* I couldn't have got its status if it weren't alive, so it's alive. */ - return 1; + return true; } -/* Convert PTID to a string. Returns the string in a static - buffer. */ +/* Convert PTID to a string. */ -static const char * -procfs_pid_to_str (struct target_ops *ops, ptid_t ptid) +std::string +procfs_target::pid_to_str (ptid_t ptid) { - static char buf[80]; - - if (ptid_get_lwp (ptid) == 0) - sprintf (buf, "process %d", ptid_get_pid (ptid)); + if (ptid.lwp () == 0) + return string_printf ("process %d", ptid.pid ()); else - sprintf (buf, "LWP %ld", ptid_get_lwp (ptid)); + return string_printf ("LWP %ld", ptid.lwp ()); +} + +/* Accepts an integer PID; Returns a string representing a file that + can be opened to get the symbols for the child process. */ + +char * +procfs_target::pid_to_exec_file (int pid) +{ + static char buf[PATH_MAX]; + char name[PATH_MAX]; + + /* Solaris 11 introduced /proc//execname. */ + xsnprintf (name, sizeof (name), "/proc/%d/execname", pid); + scoped_fd fd (gdb_open_cloexec (name, O_RDONLY, 0)); + if (fd.get () < 0 || read (fd.get (), buf, PATH_MAX - 1) < 0) + { + /* If that fails, fall back to /proc//path/a.out introduced in + Solaris 10. */ + ssize_t len; + + xsnprintf (name, sizeof (name), "/proc/%d/path/a.out", pid); + len = readlink (name, buf, PATH_MAX - 1); + if (len <= 0) + strcpy (buf, name); + else + buf[len] = '\0'; + } return buf; } @@ -3232,8 +3209,8 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, int pflags = 0; procinfo *pi; - pi = find_procinfo_or_die (ptid_get_pid (ptid) == -1 ? - ptid_get_pid (inferior_ptid) : ptid_get_pid (ptid), + pi = find_procinfo_or_die (ptid.pid () == -1 ? + inferior_ptid.pid () : ptid.pid (), 0); /* Translate from GDB's flags to /proc's. */ @@ -3281,10 +3258,8 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, procfs.c targets due to the fact that some of them still define target_can_use_hardware_watchpoint. */ -static int -procfs_can_use_hw_breakpoint (struct target_ops *self, - enum bptype type, - int cnt, int othertype) +int +procfs_target::can_use_hw_breakpoint (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, @@ -3307,22 +3282,18 @@ procfs_can_use_hw_breakpoint (struct target_ops *self, /* Returns non-zero if process is stopped on a hardware watchpoint fault, else returns zero. */ -static int -procfs_stopped_by_watchpoint (struct target_ops *ops) +bool +procfs_target::stopped_by_watchpoint () { procinfo *pi; - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) - { - if (proc_why (pi) == PR_FAULTED) - { - if (proc_what (pi) == FLTWATCH) - return 1; - } - } - return 0; + if (proc_why (pi) == PR_FAULTED) + if (proc_what (pi) == FLTWATCH) + return true; + return false; } /* Returns 1 if the OS knows the position of the triggered watchpoint, @@ -3331,51 +3302,44 @@ procfs_stopped_by_watchpoint (struct target_ops *ops) procfs_stopped_by_watchpoint returned 1, thus no further checks are done. The function also assumes that ADDR is not NULL. */ -static int -procfs_stopped_data_address (struct target_ops *targ, CORE_ADDR *addr) +bool +procfs_target::stopped_data_address (CORE_ADDR *addr) { procinfo *pi; - pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); return proc_watchpoint_address (pi, addr); } -static int -procfs_insert_watchpoint (struct target_ops *self, - CORE_ADDR addr, int len, - enum target_hw_bp_type type, - struct expression *cond) +int +procfs_target::insert_watchpoint (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 ())) - { - /* When a hardware watchpoint fires off the PC will be left at - the instruction following the one which caused the - watchpoint. It will *NOT* be necessary for GDB to step over - the watchpoint. */ - return procfs_set_watchpoint (inferior_ptid, addr, len, type, 1); - } + /* When a hardware watchpoint fires off the PC will be left at + the instruction following the one which caused the + watchpoint. It will *NOT* be necessary for GDB to step over + the watchpoint. */ + return procfs_set_watchpoint (inferior_ptid, addr, len, type, 1); else - { - /* When a hardware watchpoint fires off the PC will be left at - the instruction which caused the watchpoint. It will be - necessary for GDB to step over the watchpoint. */ - return procfs_set_watchpoint (inferior_ptid, addr, len, type, 0); - } + /* When a hardware watchpoint fires off the PC will be left at + the instruction which caused the watchpoint. It will be + necessary for GDB to step over the watchpoint. */ + return procfs_set_watchpoint (inferior_ptid, addr, len, type, 0); } -static int -procfs_remove_watchpoint (struct target_ops *self, - CORE_ADDR addr, int len, - enum target_hw_bp_type type, - struct expression *cond) +int +procfs_target::remove_watchpoint (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 (struct target_ops *self, - CORE_ADDR addr, int len) +int +procfs_target::region_ok_for_hw_watchpoint (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 @@ -3385,17 +3349,6 @@ procfs_region_ok_for_hw_watchpoint (struct target_ops *self, return 1; } -void -procfs_use_watchpoints (struct target_ops *t) -{ - t->to_stopped_by_watchpoint = procfs_stopped_by_watchpoint; - t->to_insert_watchpoint = procfs_insert_watchpoint; - t->to_remove_watchpoint = procfs_remove_watchpoint; - t->to_region_ok_for_hw_watchpoint = procfs_region_ok_for_hw_watchpoint; - t->to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint; - t->to_stopped_data_address = procfs_stopped_data_address; -} - /* Memory Mappings Functions: */ /* Call a callback function once for each mapping, passing it the @@ -3427,7 +3380,7 @@ iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func, /* Get the number of mappings, allocate space, and read the mappings into prmaps. */ /* Open map fd. */ - sprintf (pathname, "/proc/%d/map", pi->pid); + xsnprintf (pathname, sizeof (pathname), "/proc/%d/map", pi->pid); scoped_fd map_fd (open (pathname, O_RDONLY)); if (map_fd.get () < 0) @@ -3445,8 +3398,11 @@ iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func, proc_error (pi, "iterate_over_mappings (read)", __LINE__); for (prmap = prmaps; nmap > 0; prmap++, nmap--) - if ((funcstat = (*func) (prmap, child_func, data)) != 0) - return funcstat; + { + funcstat = (*func) (prmap, child_func, data); + if (funcstat != 0) + return funcstat; + } return 0; } @@ -3480,11 +3436,10 @@ find_memory_regions_callback (struct prmap *map, Stops iterating and returns the first non-zero value returned by the callback. */ -static int -proc_find_memory_regions (struct target_ops *self, - find_memory_region_ftype func, void *data) +int +procfs_target::find_memory_regions (find_memory_region_ftype func, void *data) { - procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0); + procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0); return iterate_over_mappings (pi, func, data, find_memory_regions_callback); @@ -3572,11 +3527,9 @@ info_proc_mappings (procinfo *pi, int summary) /* Implement the "info proc" command. */ -static void -procfs_info_proc (struct target_ops *ops, const char *args, - enum info_proc_what what) +bool +procfs_target::info_proc (const char *args, enum info_proc_what what) { - struct cleanup *old_chain; procinfo *process = NULL; procinfo *thread = NULL; char *tmp = NULL; @@ -3598,7 +3551,6 @@ procfs_info_proc (struct target_ops *ops, const char *args, error (_("Not supported on this target.")); } - old_chain = make_cleanup (null_cleanup, 0); gdb_argv built_argv (args); for (char *arg : built_argv) { @@ -3613,8 +3565,10 @@ procfs_info_proc (struct target_ops *ops, const char *args, tid = strtoul (arg + 1, NULL, 10); } } + + procinfo_up temporary_procinfo; if (pid == 0) - pid = ptid_get_pid (inferior_ptid); + pid = inferior_ptid.pid (); if (pid == 0) error (_("No current process: you must name one.")); else @@ -3627,7 +3581,7 @@ procfs_info_proc (struct target_ops *ops, const char *args, /* No. So open a procinfo for it, but remember to close it again when finished. */ process = create_procinfo (pid, 0); - make_cleanup (do_destroy_procinfo_cleanup, process); + temporary_procinfo.reset (process); if (!open_procinfo_files (process, FD_CTL)) proc_error (process, "info proc, open_procinfo_files", __LINE__); } @@ -3654,11 +3608,9 @@ procfs_info_proc (struct target_ops *ops, const char *args, } if (mappings) - { - info_proc_mappings (process, 0); - } + info_proc_mappings (process, 0); - do_cleanups (old_chain); + return true; } /* Modify the status of the system call identified by SYSCALLNUM in @@ -3706,13 +3658,13 @@ proc_trace_syscalls (const char *args, int from_tty, int entry_or_exit, int mode { procinfo *pi; - if (ptid_get_pid (inferior_ptid) <= 0) + if (inferior_ptid.pid () <= 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 (ptid_get_pid (inferior_ptid), 0); + pi = find_procinfo_or_die (inferior_ptid.pid (), 0); if (isdigit (args[0])) { const int syscallnum = atoi (args); @@ -3758,6 +3710,8 @@ _initialize_procfs (void) _("Cancel a trace of entries into the syscall.")); add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd, _("Cancel a trace of exits from the syscall.")); + + add_inf_child_target (&the_procfs_target); } /* =================== END, GDB "MODULE" =================== */ @@ -3775,7 +3729,7 @@ _initialize_procfs (void) ptid_t procfs_first_available (void) { - return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1); + return ptid_t (procinfo_list ? procinfo_list->pid : -1); } /* =================== GCORE .NOTE "MODULE" =================== */ @@ -3790,7 +3744,7 @@ procfs_do_thread_registers (bfd *obfd, ptid_t ptid, gdb_fpregset_t fpregs; unsigned long merged_pid; - merged_pid = ptid_get_lwp (ptid) << 16 | ptid_get_pid (ptid); + merged_pid = ptid.lwp () << 16 | ptid.pid (); /* This part is the old method for fetching registers. It should be replaced by the newer one using regsets @@ -3833,7 +3787,7 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data) if (pi != NULL) { - ptid_t ptid = ptid_build (pi->pid, thread->tid, 0); + ptid_t ptid = ptid_t (pi->pid, thread->tid, 0); args->note_data = procfs_do_thread_registers (args->obfd, ptid, args->note_data, @@ -3847,7 +3801,7 @@ static int find_signalled_thread (struct thread_info *info, void *data) { if (info->suspend.stop_signal != GDB_SIGNAL_0 - && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid)) + && info->ptid.pid () == inferior_ptid.pid ()) return 1; return 0; @@ -3865,20 +3819,16 @@ find_stop_signal (void) return GDB_SIGNAL_0; } -static char * -procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size) +char * +procfs_target::make_corefile_notes (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 (ptid_get_pid (inferior_ptid), 0); + procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0); char *note_data = NULL; - char *inf_args; + const char *inf_args; struct procfs_corefile_thread_data thread_args; - gdb_byte *auxv; - int auxv_len; enum gdb_signal stop_signal; if (get_exec_file (0)) @@ -3889,8 +3839,9 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size) psargs[sizeof (psargs) - 1] = 0; inf_args = get_inferior_args (); - if (inf_args && *inf_args && - strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs))) + if (inf_args && *inf_args + && (strlen (inf_args) + < ((int) sizeof (psargs) - (int) strlen (psargs)))) { strncat (psargs, " ", sizeof (psargs) - strlen (psargs)); @@ -3909,7 +3860,7 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size) fill_gregset (get_current_regcache (), &gregs, -1); note_data = elfcore_write_pstatus (obfd, note_data, note_size, - ptid_get_pid (inferior_ptid), + inferior_ptid.pid (), stop_signal, &gregs); thread_args.obfd = obfd; @@ -3920,14 +3871,12 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size) &thread_args); note_data = thread_args.note_data; - auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV, - NULL, &auxv); - if (auxv_len > 0) - { - note_data = elfcore_write_note (obfd, note_data, note_size, - "CORE", NT_AUXV, auxv, auxv_len); - xfree (auxv); - } + gdb::optional auxv = + target_read_alloc (current_top_target (), TARGET_OBJECT_AUXV, NULL); + if (auxv && !auxv->empty ()) + note_data = elfcore_write_note (obfd, note_data, note_size, + "CORE", NT_AUXV, auxv->data (), + auxv->size ()); return note_data; }