|  | /* Low level interface to ptrace, for the remote server for GDB. | 
|  | Copyright (C) 1995-2025 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GDB. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #include "linux-low.h" | 
|  | #include "nat/linux-osdata.h" | 
|  | #include "gdbsupport/agent.h" | 
|  | #include "tdesc.h" | 
|  | #include "gdbsupport/event-loop.h" | 
|  | #include "gdbsupport/event-pipe.h" | 
|  | #include "gdbsupport/rsp-low.h" | 
|  | #include "gdbsupport/signals-state-save-restore.h" | 
|  | #include "nat/linux-nat.h" | 
|  | #include "nat/linux-waitpid.h" | 
|  | #include "gdbsupport/gdb_wait.h" | 
|  | #include "nat/gdb_ptrace.h" | 
|  | #include "nat/linux-ptrace.h" | 
|  | #include "nat/linux-procfs.h" | 
|  | #include "nat/linux-personality.h" | 
|  | #include <signal.h> | 
|  | #include <sys/ioctl.h> | 
|  | #include <fcntl.h> | 
|  | #include <unistd.h> | 
|  | #include <sys/syscall.h> | 
|  | #include <sched.h> | 
|  | #include <pwd.h> | 
|  | #include <sys/types.h> | 
|  | #include <dirent.h> | 
|  | #include <sys/stat.h> | 
|  | #include <sys/vfs.h> | 
|  | #include <sys/uio.h> | 
|  | #include <langinfo.h> | 
|  | #include <iconv.h> | 
|  | #include "gdbsupport/filestuff.h" | 
|  | #include "gdbsupport/gdb-safe-ctype.h" | 
|  | #include "tracepoint.h" | 
|  | #include <inttypes.h> | 
|  | #include "gdbsupport/common-inferior.h" | 
|  | #include "nat/fork-inferior.h" | 
|  | #include "gdbsupport/environ.h" | 
|  | #include "gdbsupport/gdb-sigmask.h" | 
|  | #include "gdbsupport/scoped_restore.h" | 
|  | #ifndef ELFMAG0 | 
|  | /* Don't include <linux/elf.h> here.  If it got included by gdb_proc_service.h | 
|  | then ELFMAG0 will have been defined.  If it didn't get included by | 
|  | gdb_proc_service.h then including it will likely introduce a duplicate | 
|  | definition of elf_fpregset_t.  */ | 
|  | #include <elf.h> | 
|  | #endif | 
|  | #include "nat/linux-namespaces.h" | 
|  |  | 
|  | #ifndef O_LARGEFILE | 
|  | #define O_LARGEFILE 0 | 
|  | #endif | 
|  |  | 
|  | #ifndef AT_HWCAP2 | 
|  | #define AT_HWCAP2 26 | 
|  | #endif | 
|  |  | 
|  | /* Some targets did not define these ptrace constants from the start, | 
|  | so gdbserver defines them locally here.  In the future, these may | 
|  | be removed after they are added to asm/ptrace.h.  */ | 
|  | #if !(defined(PT_TEXT_ADDR) \ | 
|  | || defined(PT_DATA_ADDR) \ | 
|  | || defined(PT_TEXT_END_ADDR)) | 
|  | #if defined(__mcoldfire__) | 
|  | /* These are still undefined in 3.10 kernels.  */ | 
|  | #define PT_TEXT_ADDR 49*4 | 
|  | #define PT_DATA_ADDR 50*4 | 
|  | #define PT_TEXT_END_ADDR  51*4 | 
|  | /* These are still undefined in 3.10 kernels.  */ | 
|  | #elif defined(__TMS320C6X__) | 
|  | #define PT_TEXT_ADDR     (0x10000*4) | 
|  | #define PT_DATA_ADDR     (0x10004*4) | 
|  | #define PT_TEXT_END_ADDR (0x10008*4) | 
|  | #endif | 
|  | #endif | 
|  |  | 
|  | #if (defined(__UCLIBC__)		\ | 
|  | && defined(HAS_NOMMU)		\ | 
|  | && defined(PT_TEXT_ADDR)		\ | 
|  | && defined(PT_DATA_ADDR)		\ | 
|  | && defined(PT_TEXT_END_ADDR)) | 
|  | #define SUPPORTS_READ_OFFSETS | 
|  | #endif | 
|  |  | 
|  | #ifdef HAVE_LINUX_BTRACE | 
|  | # include "nat/linux-btrace.h" | 
|  | # include "gdbsupport/btrace-common.h" | 
|  | #endif | 
|  |  | 
|  | #ifndef HAVE_ELF32_AUXV_T | 
|  | /* Copied from glibc's elf.h.  */ | 
|  | typedef struct | 
|  | { | 
|  | uint32_t a_type;		/* Entry type */ | 
|  | union | 
|  | { | 
|  | uint32_t a_val;		/* Integer value */ | 
|  | /* We use to have pointer elements added here.  We cannot do that, | 
|  | though, since it does not work when using 32-bit definitions | 
|  | on 64-bit platforms and vice versa.  */ | 
|  | } a_un; | 
|  | } Elf32_auxv_t; | 
|  | #endif | 
|  |  | 
|  | #ifndef HAVE_ELF64_AUXV_T | 
|  | /* Copied from glibc's elf.h.  */ | 
|  | typedef struct | 
|  | { | 
|  | uint64_t a_type;		/* Entry type */ | 
|  | union | 
|  | { | 
|  | uint64_t a_val;		/* Integer value */ | 
|  | /* We use to have pointer elements added here.  We cannot do that, | 
|  | though, since it does not work when using 32-bit definitions | 
|  | on 64-bit platforms and vice versa.  */ | 
|  | } a_un; | 
|  | } Elf64_auxv_t; | 
|  | #endif | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  | enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN; | 
|  |  | 
|  | /* Return TRUE if THREAD is the leader thread of the process.  */ | 
|  |  | 
|  | static bool | 
|  | is_leader (thread_info *thread) | 
|  | { | 
|  | return thread->id.pid () == thread->id.lwp (); | 
|  | } | 
|  |  | 
|  | /* Return true if we should report thread exit events to GDB, for | 
|  | THR.  */ | 
|  |  | 
|  | static bool | 
|  | report_exit_events_for (thread_info *thr) | 
|  | { | 
|  | client_state &cs = get_client_state (); | 
|  |  | 
|  | return (cs.report_thread_events | 
|  | || (thr->thread_options & GDB_THREAD_OPTION_EXIT) != 0); | 
|  | } | 
|  |  | 
|  | /* LWP accessors.  */ | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | ptid_t | 
|  | ptid_of_lwp (struct lwp_info *lwp) | 
|  | { | 
|  | return lwp->thread->id; | 
|  | } | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | void | 
|  | lwp_set_arch_private_info (struct lwp_info *lwp, | 
|  | struct arch_lwp_info *info) | 
|  | { | 
|  | lwp->arch_private = info; | 
|  | } | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | struct arch_lwp_info * | 
|  | lwp_arch_private_info (struct lwp_info *lwp) | 
|  | { | 
|  | return lwp->arch_private; | 
|  | } | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | int | 
|  | lwp_is_stopped (struct lwp_info *lwp) | 
|  | { | 
|  | return lwp->stopped; | 
|  | } | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | enum target_stop_reason | 
|  | lwp_stop_reason (struct lwp_info *lwp) | 
|  | { | 
|  | return lwp->stop_reason; | 
|  | } | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | int | 
|  | lwp_is_stepping (struct lwp_info *lwp) | 
|  | { | 
|  | return lwp->stepping; | 
|  | } | 
|  |  | 
|  | /* A list of all unknown processes which receive stop signals.  Some | 
|  | other process will presumably claim each of these as forked | 
|  | children momentarily.  */ | 
|  |  | 
|  | struct simple_pid_list | 
|  | { | 
|  | /* The process ID.  */ | 
|  | int pid; | 
|  |  | 
|  | /* The status as reported by waitpid.  */ | 
|  | int status; | 
|  |  | 
|  | /* Next in chain.  */ | 
|  | struct simple_pid_list *next; | 
|  | }; | 
|  | static struct simple_pid_list *stopped_pids; | 
|  |  | 
|  | /* Trivial list manipulation functions to keep track of a list of new | 
|  | stopped processes.  */ | 
|  |  | 
|  | static void | 
|  | add_to_pid_list (struct simple_pid_list **listp, int pid, int status) | 
|  | { | 
|  | struct simple_pid_list *new_pid = XNEW (struct simple_pid_list); | 
|  |  | 
|  | new_pid->pid = pid; | 
|  | new_pid->status = status; | 
|  | new_pid->next = *listp; | 
|  | *listp = new_pid; | 
|  | } | 
|  |  | 
|  | static int | 
|  | pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp) | 
|  | { | 
|  | struct simple_pid_list **p; | 
|  |  | 
|  | for (p = listp; *p != NULL; p = &(*p)->next) | 
|  | if ((*p)->pid == pid) | 
|  | { | 
|  | struct simple_pid_list *next = (*p)->next; | 
|  |  | 
|  | *statusp = (*p)->status; | 
|  | xfree (*p); | 
|  | *p = next; | 
|  | return 1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | enum stopping_threads_kind | 
|  | { | 
|  | /* Not stopping threads presently.  */ | 
|  | NOT_STOPPING_THREADS, | 
|  |  | 
|  | /* Stopping threads.  */ | 
|  | STOPPING_THREADS, | 
|  |  | 
|  | /* Stopping and suspending threads.  */ | 
|  | STOPPING_AND_SUSPENDING_THREADS | 
|  | }; | 
|  |  | 
|  | /* This is set while stop_all_lwps is in effect.  */ | 
|  | static stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS; | 
|  |  | 
|  | /* FIXME make into a target method?  */ | 
|  | int using_threads = 1; | 
|  |  | 
|  | /* True if we're presently stabilizing threads (moving them out of | 
|  | jump pads).  */ | 
|  | static int stabilizing_threads; | 
|  |  | 
|  | static void unsuspend_all_lwps (struct lwp_info *except); | 
|  | static void mark_lwp_dead (struct lwp_info *lwp, int wstat, | 
|  | bool thread_event); | 
|  | static int lwp_is_marked_dead (struct lwp_info *lwp); | 
|  | static int kill_lwp (unsigned long lwpid, int signo); | 
|  | static void enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info); | 
|  | static int linux_low_ptrace_options (int attached); | 
|  | static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp); | 
|  |  | 
|  | /* When the event-loop is doing a step-over, this points at the thread | 
|  | being stepped.  */ | 
|  | static ptid_t step_over_bkpt; | 
|  |  | 
|  | bool | 
|  | linux_process_target::low_supports_breakpoints () | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_process_target::low_get_pc (regcache *regcache) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_set_pc (regcache *regcache, CORE_ADDR newpc) | 
|  | { | 
|  | gdb_assert_not_reached ("linux target op low_set_pc is not implemented"); | 
|  | } | 
|  |  | 
|  | std::vector<CORE_ADDR> | 
|  | linux_process_target::low_get_next_pcs (regcache *regcache) | 
|  | { | 
|  | gdb_assert_not_reached ("linux target op low_get_next_pcs is not " | 
|  | "implemented"); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::low_decr_pc_after_break () | 
|  | { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* True if LWP is stopped in its stepping range.  */ | 
|  |  | 
|  | static int | 
|  | lwp_in_step_range (struct lwp_info *lwp) | 
|  | { | 
|  | CORE_ADDR pc = lwp->stop_pc; | 
|  |  | 
|  | return (pc >= lwp->step_range_start && pc < lwp->step_range_end); | 
|  | } | 
|  |  | 
|  | /* The event pipe registered as a waitable file in the event loop.  */ | 
|  | static event_pipe linux_event_pipe; | 
|  |  | 
|  | /* True if we're currently in async mode.  */ | 
|  | #define target_is_async_p() (linux_event_pipe.is_open ()) | 
|  |  | 
|  | static void send_sigstop (struct lwp_info *lwp); | 
|  |  | 
|  | /* Return non-zero if HEADER is a 64-bit ELF file.  */ | 
|  |  | 
|  | static int | 
|  | elf_64_header_p (const Elf64_Ehdr *header, unsigned int *machine) | 
|  | { | 
|  | if (header->e_ident[EI_MAG0] == ELFMAG0 | 
|  | && header->e_ident[EI_MAG1] == ELFMAG1 | 
|  | && header->e_ident[EI_MAG2] == ELFMAG2 | 
|  | && header->e_ident[EI_MAG3] == ELFMAG3) | 
|  | { | 
|  | *machine = header->e_machine; | 
|  | return header->e_ident[EI_CLASS] == ELFCLASS64; | 
|  |  | 
|  | } | 
|  | *machine = EM_NONE; | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | /* Return non-zero if FILE is a 64-bit ELF file, | 
|  | zero if the file is not a 64-bit ELF file, | 
|  | and -1 if the file is not accessible or doesn't exist.  */ | 
|  |  | 
|  | static int | 
|  | elf_64_file_p (const char *file, unsigned int *machine) | 
|  | { | 
|  | Elf64_Ehdr header; | 
|  | int fd; | 
|  |  | 
|  | fd = open (file, O_RDONLY); | 
|  | if (fd < 0) | 
|  | return -1; | 
|  |  | 
|  | if (read (fd, &header, sizeof (header)) != sizeof (header)) | 
|  | { | 
|  | close (fd); | 
|  | return 0; | 
|  | } | 
|  | close (fd); | 
|  |  | 
|  | return elf_64_header_p (&header, machine); | 
|  | } | 
|  |  | 
|  | /* Accepts an integer PID; Returns true if the executable PID is | 
|  | running is a 64-bit ELF file..  */ | 
|  |  | 
|  | int | 
|  | linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine) | 
|  | { | 
|  | char file[PATH_MAX]; | 
|  |  | 
|  | sprintf (file, "/proc/%d/exe", pid); | 
|  | return elf_64_file_p (file, machine); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::delete_lwp (lwp_info *lwp) | 
|  | { | 
|  | thread_info *thr = lwp->thread; | 
|  |  | 
|  | threads_debug_printf ("deleting %ld", thr->id.lwp ()); | 
|  |  | 
|  | thr->process ()->remove_thread (thr); | 
|  |  | 
|  | low_delete_thread (lwp->arch_private); | 
|  |  | 
|  | delete lwp; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_delete_thread (arch_lwp_info *info) | 
|  | { | 
|  | /* Default implementation should be overridden if architecture-specific | 
|  | info is being used.  */ | 
|  | gdb_assert (info == nullptr); | 
|  | } | 
|  |  | 
|  | /* Open the /proc/PID/mem file for PROC.  */ | 
|  |  | 
|  | static void | 
|  | open_proc_mem_file (process_info *proc) | 
|  | { | 
|  | gdb_assert (proc->priv->mem_fd == -1); | 
|  |  | 
|  | char filename[64]; | 
|  | xsnprintf (filename, sizeof filename, "/proc/%d/mem", proc->pid); | 
|  |  | 
|  | proc->priv->mem_fd | 
|  | = gdb_open_cloexec (filename, O_RDWR | O_LARGEFILE, 0).release (); | 
|  | } | 
|  |  | 
|  | process_info * | 
|  | linux_process_target::add_linux_process_no_mem_file (int pid, int attached) | 
|  | { | 
|  | struct process_info *proc; | 
|  |  | 
|  | proc = add_process (pid, attached); | 
|  | proc->priv = XCNEW (struct process_info_private); | 
|  |  | 
|  | proc->priv->arch_private = low_new_process (); | 
|  | proc->priv->mem_fd = -1; | 
|  |  | 
|  | return proc; | 
|  | } | 
|  |  | 
|  |  | 
|  | process_info * | 
|  | linux_process_target::add_linux_process (int pid, int attached) | 
|  | { | 
|  | process_info *proc = add_linux_process_no_mem_file (pid, attached); | 
|  | open_proc_mem_file (proc); | 
|  | return proc; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::remove_linux_process (process_info *proc) | 
|  | { | 
|  | if (proc->priv->mem_fd >= 0) | 
|  | close (proc->priv->mem_fd); | 
|  |  | 
|  | this->low_delete_process (proc->priv->arch_private); | 
|  |  | 
|  | xfree (proc->priv); | 
|  | proc->priv = nullptr; | 
|  |  | 
|  | remove_process (proc); | 
|  | } | 
|  |  | 
|  | arch_process_info * | 
|  | linux_process_target::low_new_process () | 
|  | { | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_delete_process (arch_process_info *info) | 
|  | { | 
|  | /* Default implementation must be overridden if architecture-specific | 
|  | info exists.  */ | 
|  | gdb_assert (info == nullptr); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_new_fork (process_info *parent, process_info *child) | 
|  | { | 
|  | /* Nop.  */ | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::arch_setup_thread (thread_info *thread) | 
|  | { | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (thread); | 
|  |  | 
|  | low_arch_setup (); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, | 
|  | int wstat) | 
|  | { | 
|  | client_state &cs = get_client_state (); | 
|  | struct lwp_info *event_lwp = *orig_event_lwp; | 
|  | int event = linux_ptrace_get_extended_event (wstat); | 
|  | thread_info *event_thr = event_lwp->thread; | 
|  |  | 
|  | gdb_assert (event_lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE); | 
|  |  | 
|  | /* All extended events we currently use are mid-syscall.  Only | 
|  | PTRACE_EVENT_STOP is delivered more like a signal-stop, but | 
|  | you have to be using PTRACE_SEIZE to get that.  */ | 
|  | event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY; | 
|  |  | 
|  | if ((event == PTRACE_EVENT_FORK) || (event == PTRACE_EVENT_VFORK) | 
|  | || (event == PTRACE_EVENT_CLONE)) | 
|  | { | 
|  | unsigned long new_pid; | 
|  | int ret, status; | 
|  |  | 
|  | /* Get the pid of the new lwp.  */ | 
|  | ptrace (PTRACE_GETEVENTMSG, event_thr->id.lwp (), (PTRACE_TYPE_ARG3) 0, | 
|  | &new_pid); | 
|  |  | 
|  | /* If we haven't already seen the new PID stop, wait for it now.  */ | 
|  | if (!pull_pid_from_list (&stopped_pids, new_pid, &status)) | 
|  | { | 
|  | /* The new child has a pending SIGSTOP.  We can't affect it until it | 
|  | hits the SIGSTOP, but we're already attached.  */ | 
|  |  | 
|  | ret = my_waitpid (new_pid, &status, __WALL); | 
|  |  | 
|  | if (ret == -1) | 
|  | perror_with_name ("waiting for new child"); | 
|  | else if (ret != new_pid) | 
|  | warning ("wait returned unexpected PID %d", ret); | 
|  | else if (!WIFSTOPPED (status)) | 
|  | warning ("wait returned unexpected status 0x%x", status); | 
|  | } | 
|  |  | 
|  | if (debug_threads) | 
|  | { | 
|  | debug_printf ("HEW: Got %s event from LWP %ld, new child is %ld\n", | 
|  | (event == PTRACE_EVENT_FORK ? "fork" | 
|  | : event == PTRACE_EVENT_VFORK ? "vfork" | 
|  | : event == PTRACE_EVENT_CLONE ? "clone" | 
|  | : "???"), | 
|  | event_thr->id.lwp (), | 
|  | new_pid); | 
|  | } | 
|  |  | 
|  | ptid_t child_ptid = (event != PTRACE_EVENT_CLONE | 
|  | ? ptid_t (new_pid, new_pid) | 
|  | : ptid_t (event_thr->id.pid (), new_pid)); | 
|  |  | 
|  | process_info *child_proc = nullptr; | 
|  |  | 
|  | if (event != PTRACE_EVENT_CLONE) | 
|  | { | 
|  | /* Add the new process to the tables before we add the LWP. | 
|  | We need to do this even if the new process will be | 
|  | detached.  See breakpoint cloning code further below.  */ | 
|  | child_proc = add_linux_process (new_pid, 0); | 
|  | } | 
|  |  | 
|  | lwp_info *child_lwp = add_lwp (child_ptid); | 
|  | gdb_assert (child_lwp != NULL); | 
|  | child_lwp->stopped = 1; | 
|  | if (event != PTRACE_EVENT_CLONE) | 
|  | child_lwp->must_set_ptrace_flags = 1; | 
|  | child_lwp->status_pending_p = 0; | 
|  |  | 
|  | thread_info *child_thr = child_lwp->thread; | 
|  |  | 
|  | /* If we're suspending all threads, leave this one suspended | 
|  | too.  If the fork/clone parent is stepping over a breakpoint, | 
|  | all other threads have been suspended already.  Leave the | 
|  | child suspended too.  */ | 
|  | if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS | 
|  | || event_lwp->bp_reinsert != 0) | 
|  | { | 
|  | threads_debug_printf ("leaving child suspended"); | 
|  | child_lwp->suspended = 1; | 
|  | } | 
|  |  | 
|  | if (event_lwp->bp_reinsert != 0 | 
|  | && supports_software_single_step () | 
|  | && event == PTRACE_EVENT_VFORK) | 
|  | { | 
|  | /* If we leave single-step breakpoints there, child will | 
|  | hit it, so uninsert single-step breakpoints from parent | 
|  | (and child).  Once vfork child is done, reinsert | 
|  | them back to parent.  */ | 
|  | uninsert_single_step_breakpoints (event_thr); | 
|  | } | 
|  |  | 
|  | if (event != PTRACE_EVENT_CLONE) | 
|  | { | 
|  | /* Clone the breakpoint lists of the parent.  We need to do | 
|  | this even if the new process will be detached, since we | 
|  | will need the process object and the breakpoints to | 
|  | remove any breakpoints from memory when we detach, and | 
|  | the client side will access registers.  */ | 
|  | gdb_assert (child_proc != NULL); | 
|  |  | 
|  | process_info *parent_proc = event_thr->process (); | 
|  | child_proc->attached = parent_proc->attached; | 
|  |  | 
|  | clone_all_breakpoints (child_thr, event_thr); | 
|  |  | 
|  | target_desc_up tdesc = allocate_target_description (); | 
|  | copy_target_description (tdesc.get (), parent_proc->tdesc); | 
|  | child_proc->tdesc = tdesc.release (); | 
|  |  | 
|  | /* Clone arch-specific process data.  */ | 
|  | low_new_fork (parent_proc, child_proc); | 
|  | } | 
|  |  | 
|  | /* Save fork/clone info in the parent thread.  */ | 
|  | if (event == PTRACE_EVENT_FORK) | 
|  | event_lwp->waitstatus.set_forked (child_ptid); | 
|  | else if (event == PTRACE_EVENT_VFORK) | 
|  | event_lwp->waitstatus.set_vforked (child_ptid); | 
|  | else if (event == PTRACE_EVENT_CLONE | 
|  | && (event_thr->thread_options & GDB_THREAD_OPTION_CLONE) != 0) | 
|  | event_lwp->waitstatus.set_thread_cloned (child_ptid); | 
|  |  | 
|  | if (event != PTRACE_EVENT_CLONE | 
|  | || (event_thr->thread_options & GDB_THREAD_OPTION_CLONE) != 0) | 
|  | { | 
|  | /* The status_pending field contains bits denoting the | 
|  | extended event, so when the pending event is handled, the | 
|  | handler will look at lwp->waitstatus.  */ | 
|  | event_lwp->status_pending_p = 1; | 
|  | event_lwp->status_pending = wstat; | 
|  |  | 
|  | /* Link the threads until the parent's event is passed on to | 
|  | GDB.  */ | 
|  | event_lwp->relative = child_lwp; | 
|  | child_lwp->relative = event_lwp; | 
|  | } | 
|  |  | 
|  | /* If the parent thread is doing step-over with single-step | 
|  | breakpoints, the list of single-step breakpoints are cloned | 
|  | from the parent's.  Remove them from the child process. | 
|  | In case of vfork, we'll reinsert them back once vforked | 
|  | child is done.  */ | 
|  | if (event_lwp->bp_reinsert != 0 | 
|  | && supports_software_single_step ()) | 
|  | { | 
|  | /* The child process is forked and stopped, so it is safe | 
|  | to access its memory without stopping all other threads | 
|  | from other processes.  */ | 
|  | delete_single_step_breakpoints (child_thr); | 
|  |  | 
|  | gdb_assert (has_single_step_breakpoints (event_thr)); | 
|  | gdb_assert (!has_single_step_breakpoints (child_thr)); | 
|  | } | 
|  |  | 
|  | /* Normally we will get the pending SIGSTOP.  But in some cases | 
|  | we might get another signal delivered to the group first. | 
|  | If we do get another signal, be sure not to lose it.  */ | 
|  | if (WSTOPSIG (status) != SIGSTOP) | 
|  | { | 
|  | child_lwp->stop_expected = 1; | 
|  | child_lwp->status_pending_p = 1; | 
|  | child_lwp->status_pending = status; | 
|  | } | 
|  | else if (event == PTRACE_EVENT_CLONE && cs.report_thread_events) | 
|  | { | 
|  | child_lwp->waitstatus.set_thread_created (); | 
|  | child_lwp->status_pending_p = 1; | 
|  | child_lwp->status_pending = status; | 
|  | } | 
|  |  | 
|  | if (event == PTRACE_EVENT_CLONE) | 
|  | { | 
|  | #ifdef USE_THREAD_DB | 
|  | thread_db_notice_clone (event_thr, child_ptid); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | if (event == PTRACE_EVENT_CLONE | 
|  | && (event_thr->thread_options & GDB_THREAD_OPTION_CLONE) == 0) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("not reporting clone event from LWP %ld, new child is %ld\n", | 
|  | event_thr->id.lwp (), | 
|  | new_pid); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | /* Leave the child stopped until GDB processes the parent | 
|  | event.  */ | 
|  | child_thr->last_resume_kind = resume_stop; | 
|  | child_thr->last_status.set_stopped (GDB_SIGNAL_0); | 
|  |  | 
|  | /* Report the event.  */ | 
|  | threads_debug_printf | 
|  | ("reporting %s event from LWP %ld, new child is %ld\n", | 
|  | (event == PTRACE_EVENT_FORK ? "fork" | 
|  | : event == PTRACE_EVENT_VFORK ? "vfork" | 
|  | : event == PTRACE_EVENT_CLONE ? "clone" | 
|  | : "???"), | 
|  | event_thr->id.lwp (), | 
|  | new_pid); | 
|  | return 0; | 
|  | } | 
|  | else if (event == PTRACE_EVENT_VFORK_DONE) | 
|  | { | 
|  | event_lwp->waitstatus.set_vfork_done (); | 
|  |  | 
|  | if (event_lwp->bp_reinsert != 0 && supports_software_single_step ()) | 
|  | { | 
|  | reinsert_single_step_breakpoints (event_thr); | 
|  |  | 
|  | gdb_assert (has_single_step_breakpoints (event_thr)); | 
|  | } | 
|  |  | 
|  | /* Report the event.  */ | 
|  | return 0; | 
|  | } | 
|  | else if (event == PTRACE_EVENT_EXEC && cs.report_exec_events) | 
|  | { | 
|  | std::vector<int> syscalls_to_catch; | 
|  | ptid_t event_ptid; | 
|  | pid_t event_pid; | 
|  |  | 
|  | threads_debug_printf ("Got exec event from LWP %ld", | 
|  | event_thr->id.lwp ()); | 
|  |  | 
|  | /* Get the event ptid.  */ | 
|  | event_ptid = event_thr->id; | 
|  | event_pid = event_ptid.pid (); | 
|  |  | 
|  | /* Save the syscall list from the execing process.  */ | 
|  | process_info *proc = event_thr->process (); | 
|  | syscalls_to_catch = std::move (proc->syscalls_to_catch); | 
|  |  | 
|  | /* Delete the execing process and all its threads.  */ | 
|  | mourn (proc); | 
|  | switch_to_thread (nullptr); | 
|  |  | 
|  | /* Create a new process/lwp/thread.  */ | 
|  | proc = add_linux_process (event_pid, 0); | 
|  | event_lwp = add_lwp (event_ptid); | 
|  | event_thr = event_lwp->thread; | 
|  | gdb_assert (current_thread == event_thr); | 
|  | arch_setup_thread (event_thr); | 
|  |  | 
|  | /* Set the event status.  */ | 
|  | event_lwp->waitstatus.set_execd | 
|  | (make_unique_xstrdup | 
|  | (pid_to_exec_file (event_thr->id.lwp ()))); | 
|  |  | 
|  | /* Mark the exec status as pending.  */ | 
|  | event_lwp->stopped = 1; | 
|  | event_lwp->status_pending_p = 1; | 
|  | event_lwp->status_pending = wstat; | 
|  | event_thr->last_resume_kind = resume_continue; | 
|  | event_thr->last_status.set_ignore (); | 
|  |  | 
|  | /* Update syscall state in the new lwp, effectively mid-syscall too.  */ | 
|  | event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY; | 
|  |  | 
|  | /* Restore the list to catch.  Don't rely on the client, which is free | 
|  | to avoid sending a new list when the architecture doesn't change. | 
|  | Also, for ANY_SYSCALL, the architecture doesn't really matter.  */ | 
|  | proc->syscalls_to_catch = std::move (syscalls_to_catch); | 
|  |  | 
|  | /* Report the event.  */ | 
|  | *orig_event_lwp = event_lwp; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | internal_error (_("unknown ptrace event %d"), event); | 
|  | } | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_process_target::get_pc (lwp_info *lwp) | 
|  | { | 
|  | process_info *proc = lwp->thread->process (); | 
|  | gdb_assert (!proc->starting_up); | 
|  |  | 
|  | if (!low_supports_breakpoints ()) | 
|  | return 0; | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (lwp->thread); | 
|  |  | 
|  | regcache *regcache = get_thread_regcache (current_thread); | 
|  | CORE_ADDR pc = low_get_pc (regcache); | 
|  |  | 
|  | threads_debug_printf ("pc is 0x%lx", (long) pc); | 
|  |  | 
|  | return pc; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::get_syscall_trapinfo (lwp_info *lwp, int *sysno) | 
|  | { | 
|  | struct regcache *regcache; | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (lwp->thread); | 
|  |  | 
|  | regcache = get_thread_regcache (current_thread); | 
|  | low_get_syscall_trapinfo (regcache, sysno); | 
|  |  | 
|  | threads_debug_printf ("get_syscall_trapinfo sysno %d", *sysno); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_get_syscall_trapinfo (regcache *regcache, int *sysno) | 
|  | { | 
|  | /* By default, report an unknown system call number.  */ | 
|  | *sysno = UNKNOWN_SYSCALL; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::save_stop_reason (lwp_info *lwp) | 
|  | { | 
|  | CORE_ADDR pc; | 
|  | CORE_ADDR sw_breakpoint_pc; | 
|  | siginfo_t siginfo; | 
|  |  | 
|  | if (!low_supports_breakpoints ()) | 
|  | return false; | 
|  |  | 
|  | process_info *proc = lwp->thread->process (); | 
|  | if (proc->starting_up) | 
|  | { | 
|  | /* Claim we have the stop PC so that the caller doesn't try to | 
|  | fetch it itself.  */ | 
|  | return true; | 
|  | } | 
|  |  | 
|  | pc = get_pc (lwp); | 
|  | sw_breakpoint_pc = pc - low_decr_pc_after_break (); | 
|  |  | 
|  | /* breakpoint_at reads from the current thread.  */ | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (lwp->thread); | 
|  |  | 
|  | if (ptrace (PTRACE_GETSIGINFO, current_thread->id.lwp (), | 
|  | (PTRACE_TYPE_ARG3) 0, &siginfo) == 0) | 
|  | { | 
|  | if (siginfo.si_signo == SIGTRAP) | 
|  | { | 
|  | if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code) | 
|  | && GDB_ARCH_IS_TRAP_HWBKPT (siginfo.si_code)) | 
|  | { | 
|  | /* The si_code is ambiguous on this arch -- check debug | 
|  | registers.  */ | 
|  | if (!check_stopped_by_watchpoint (lwp)) | 
|  | lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT; | 
|  | } | 
|  | else if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code)) | 
|  | { | 
|  | /* If we determine the LWP stopped for a SW breakpoint, | 
|  | trust it.  Particularly don't check watchpoint | 
|  | registers, because at least on s390, we'd find | 
|  | stopped-by-watchpoint as long as there's a watchpoint | 
|  | set.  */ | 
|  | lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT; | 
|  | } | 
|  | else if (GDB_ARCH_IS_TRAP_HWBKPT (siginfo.si_code)) | 
|  | { | 
|  | /* This can indicate either a hardware breakpoint or | 
|  | hardware watchpoint.  Check debug registers.  */ | 
|  | if (!check_stopped_by_watchpoint (lwp)) | 
|  | lwp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT; | 
|  | } | 
|  | else if (siginfo.si_code == TRAP_TRACE) | 
|  | { | 
|  | /* We may have single stepped an instruction that | 
|  | triggered a watchpoint.  In that case, on some | 
|  | architectures (such as x86), instead of TRAP_HWBKPT, | 
|  | si_code indicates TRAP_TRACE, and we need to check | 
|  | the debug registers separately.  */ | 
|  | if (!check_stopped_by_watchpoint (lwp)) | 
|  | lwp->stop_reason = TARGET_STOPPED_BY_SINGLE_STEP; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (lwp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("%s stopped by software breakpoint", | 
|  | target_pid_to_str (lwp->thread->id).c_str ()); | 
|  |  | 
|  | /* Back up the PC if necessary.  */ | 
|  | if (pc != sw_breakpoint_pc) | 
|  | { | 
|  | struct regcache *regcache | 
|  | = get_thread_regcache (current_thread); | 
|  | low_set_pc (regcache, sw_breakpoint_pc); | 
|  | } | 
|  |  | 
|  | /* Update this so we record the correct stop PC below.  */ | 
|  | pc = sw_breakpoint_pc; | 
|  | } | 
|  | else if (lwp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT) | 
|  | threads_debug_printf | 
|  | ("%s stopped by hardware breakpoint", | 
|  | target_pid_to_str (lwp->thread->id).c_str ()); | 
|  | else if (lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT) | 
|  | threads_debug_printf | 
|  | ("%s stopped by hardware watchpoint", | 
|  | target_pid_to_str (lwp->thread->id).c_str ()); | 
|  | else if (lwp->stop_reason == TARGET_STOPPED_BY_SINGLE_STEP) | 
|  | threads_debug_printf | 
|  | ("%s stopped by trace", | 
|  | target_pid_to_str (lwp->thread->id).c_str ()); | 
|  |  | 
|  | lwp->stop_pc = pc; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | lwp_info * | 
|  | linux_process_target::add_lwp (ptid_t ptid) | 
|  | { | 
|  | lwp_info *lwp = new lwp_info; | 
|  |  | 
|  | lwp->thread = find_process_pid (ptid.pid ())->add_thread (ptid, lwp); | 
|  |  | 
|  | low_new_thread (lwp); | 
|  |  | 
|  | return lwp; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_new_thread (lwp_info *info) | 
|  | { | 
|  | /* Nop.  */ | 
|  | } | 
|  |  | 
|  | /* Callback to be used when calling fork_inferior, responsible for | 
|  | actually initiating the tracing of the inferior.  */ | 
|  |  | 
|  | static void | 
|  | linux_ptrace_fun () | 
|  | { | 
|  | if (ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, | 
|  | (PTRACE_TYPE_ARG4) 0) < 0) | 
|  | trace_start_error_with_name ("ptrace"); | 
|  |  | 
|  | if (setpgid (0, 0) < 0) | 
|  | trace_start_error_with_name ("setpgid"); | 
|  |  | 
|  | /* If GDBserver is connected to gdb via stdio, redirect the inferior's | 
|  | stdout to stderr so that inferior i/o doesn't corrupt the connection. | 
|  | Also, redirect stdin to /dev/null.  */ | 
|  | if (remote_connection_is_stdio ()) | 
|  | { | 
|  | if (close (0) < 0) | 
|  | trace_start_error_with_name ("close"); | 
|  | if (open ("/dev/null", O_RDONLY) < 0) | 
|  | trace_start_error_with_name ("open"); | 
|  | if (dup2 (2, 1) < 0) | 
|  | trace_start_error_with_name ("dup2"); | 
|  | if (write (2, "stdin/stdout redirected\n", | 
|  | sizeof ("stdin/stdout redirected\n") - 1) < 0) | 
|  | { | 
|  | /* Errors ignored.  */; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Start an inferior process and returns its pid. | 
|  | PROGRAM is the name of the program to be started, and PROGRAM_ARGS | 
|  | are its arguments.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::create_inferior (const char *program, | 
|  | const std::string &program_args) | 
|  | { | 
|  | client_state &cs = get_client_state (); | 
|  | struct lwp_info *new_lwp; | 
|  | int pid; | 
|  | ptid_t ptid; | 
|  |  | 
|  | { | 
|  | maybe_disable_address_space_randomization restore_personality | 
|  | (cs.disable_randomization); | 
|  |  | 
|  | pid = fork_inferior (program, | 
|  | program_args.c_str (), | 
|  | get_environ ()->envp (), linux_ptrace_fun, | 
|  | NULL, NULL, NULL, NULL); | 
|  | } | 
|  |  | 
|  | /* When spawning a new process, we can't open the mem file yet.  We | 
|  | still have to nurse the process through the shell, and that execs | 
|  | a couple times.  The address space a /proc/PID/mem file is | 
|  | accessing is destroyed on exec.  */ | 
|  | process_info *proc = add_linux_process_no_mem_file (pid, 0); | 
|  |  | 
|  | ptid = ptid_t (pid, pid); | 
|  | new_lwp = add_lwp (ptid); | 
|  | new_lwp->must_set_ptrace_flags = 1; | 
|  |  | 
|  | post_fork_inferior (pid, program); | 
|  |  | 
|  | /* PROC is now past the shell running the program we want, so we can | 
|  | open the /proc/PID/mem file.  */ | 
|  | open_proc_mem_file (proc); | 
|  |  | 
|  | return pid; | 
|  | } | 
|  |  | 
|  | /* Implement the post_create_inferior target_ops method.  */ | 
|  |  | 
|  | void | 
|  | linux_process_target::post_create_inferior () | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (current_thread); | 
|  |  | 
|  | low_arch_setup (); | 
|  |  | 
|  | if (lwp->must_set_ptrace_flags) | 
|  | { | 
|  | struct process_info *proc = current_process (); | 
|  | int options = linux_low_ptrace_options (proc->attached); | 
|  |  | 
|  | linux_enable_event_reporting (current_thread->id.lwp (), options); | 
|  | lwp->must_set_ptrace_flags = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::attach_lwp (ptid_t ptid) | 
|  | { | 
|  | struct lwp_info *new_lwp; | 
|  | int lwpid = ptid.lwp (); | 
|  |  | 
|  | if (ptrace (PTRACE_ATTACH, lwpid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0) | 
|  | != 0) | 
|  | return errno; | 
|  |  | 
|  | new_lwp = add_lwp (ptid); | 
|  |  | 
|  | /* We need to wait for SIGSTOP before being able to make the next | 
|  | ptrace call on this LWP.  */ | 
|  | new_lwp->must_set_ptrace_flags = 1; | 
|  |  | 
|  | if (linux_proc_pid_is_stopped (lwpid)) | 
|  | { | 
|  | threads_debug_printf ("Attached to a stopped process"); | 
|  |  | 
|  | /* The process is definitely stopped.  It is in a job control | 
|  | stop, unless the kernel predates the TASK_STOPPED / | 
|  | TASK_TRACED distinction, in which case it might be in a | 
|  | ptrace stop.  Make sure it is in a ptrace stop; from there we | 
|  | can kill it, signal it, et cetera. | 
|  |  | 
|  | First make sure there is a pending SIGSTOP.  Since we are | 
|  | already attached, the process can not transition from stopped | 
|  | to running without a PTRACE_CONT; so we know this signal will | 
|  | go into the queue.  The SIGSTOP generated by PTRACE_ATTACH is | 
|  | probably already in the queue (unless this kernel is old | 
|  | enough to use TASK_STOPPED for ptrace stops); but since | 
|  | SIGSTOP is not an RT signal, it can only be queued once.  */ | 
|  | kill_lwp (lwpid, SIGSTOP); | 
|  |  | 
|  | /* Finally, resume the stopped process.  This will deliver the | 
|  | SIGSTOP (or a higher priority signal, just like normal | 
|  | PTRACE_ATTACH), which we'll catch later on.  */ | 
|  | ptrace (PTRACE_CONT, lwpid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0); | 
|  | } | 
|  |  | 
|  | /* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH | 
|  | brings it to a halt. | 
|  |  | 
|  | There are several cases to consider here: | 
|  |  | 
|  | 1) gdbserver has already attached to the process and is being notified | 
|  | of a new thread that is being created. | 
|  | In this case we should ignore that SIGSTOP and resume the | 
|  | process.  This is handled below by setting stop_expected = 1, | 
|  | and the fact that add_thread sets last_resume_kind == | 
|  | resume_continue. | 
|  |  | 
|  | 2) This is the first thread (the process thread), and we're attaching | 
|  | to it via attach_inferior. | 
|  | In this case we want the process thread to stop. | 
|  | This is handled by having linux_attach set last_resume_kind == | 
|  | resume_stop after we return. | 
|  |  | 
|  | If the pid we are attaching to is also the tgid, we attach to and | 
|  | stop all the existing threads.  Otherwise, we attach to pid and | 
|  | ignore any other threads in the same group as this pid. | 
|  |  | 
|  | 3) GDB is connecting to gdbserver and is requesting an enumeration of all | 
|  | existing threads. | 
|  | In this case we want the thread to stop. | 
|  | FIXME: This case is currently not properly handled. | 
|  | We should wait for the SIGSTOP but don't.  Things work apparently | 
|  | because enough time passes between when we ptrace (ATTACH) and when | 
|  | gdb makes the next ptrace call on the thread. | 
|  |  | 
|  | On the other hand, if we are currently trying to stop all threads, we | 
|  | should treat the new thread as if we had sent it a SIGSTOP.  This works | 
|  | because we are guaranteed that the add_lwp call above added us to the | 
|  | end of the list, and so the new thread has not yet reached | 
|  | wait_for_sigstop (but will).  */ | 
|  | new_lwp->stop_expected = 1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Callback for linux_proc_attach_tgid_threads.  Attach to PTID if not | 
|  | already attached.  Returns true if a new LWP is found, false | 
|  | otherwise.  */ | 
|  |  | 
|  | static int | 
|  | attach_proc_task_lwp_callback (ptid_t ptid) | 
|  | { | 
|  | /* Is this a new thread?  */ | 
|  | if (find_thread_ptid (ptid) == NULL) | 
|  | { | 
|  | int lwpid = ptid.lwp (); | 
|  | int err; | 
|  |  | 
|  | threads_debug_printf ("Found new lwp %d", lwpid); | 
|  |  | 
|  | err = the_linux_target->attach_lwp (ptid); | 
|  |  | 
|  | /* Be quiet if we simply raced with the thread exiting.  EPERM | 
|  | is returned if the thread's task still exists, and is marked | 
|  | as exited or zombie, as well as other conditions, so in that | 
|  | case, confirm the status in /proc/PID/status.  */ | 
|  | if (err == ESRCH | 
|  | || (err == EPERM && linux_proc_pid_is_gone (lwpid))) | 
|  | threads_debug_printf | 
|  | ("Cannot attach to lwp %d: thread is gone (%d: %s)", | 
|  | lwpid, err, safe_strerror (err)); | 
|  | else if (err != 0) | 
|  | { | 
|  | std::string reason | 
|  | = linux_ptrace_attach_fail_reason_string (ptid, err); | 
|  |  | 
|  | error (_("Cannot attach to lwp %d: %s"), lwpid, reason.c_str ()); | 
|  | } | 
|  |  | 
|  | return 1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void async_file_mark (void); | 
|  |  | 
|  | /* Attach to PID.  If PID is the tgid, attach to it and all | 
|  | of its threads.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::attach (unsigned long pid) | 
|  | { | 
|  | struct process_info *proc; | 
|  | thread_info *initial_thread; | 
|  | ptid_t ptid = ptid_t (pid, pid); | 
|  | int err; | 
|  |  | 
|  | /* Delay opening the /proc/PID/mem file until we've successfully | 
|  | attached.  */ | 
|  | proc = add_linux_process_no_mem_file (pid, 1); | 
|  |  | 
|  | /* Attach to PID.  We will check for other threads | 
|  | soon.  */ | 
|  | err = attach_lwp (ptid); | 
|  | if (err != 0) | 
|  | { | 
|  | this->remove_linux_process (proc); | 
|  |  | 
|  | std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err); | 
|  | error ("Cannot attach to process %ld: %s", pid, reason.c_str ()); | 
|  | } | 
|  |  | 
|  | open_proc_mem_file (proc); | 
|  |  | 
|  | /* Don't ignore the initial SIGSTOP if we just attached to this | 
|  | process.  It will be collected by wait shortly.  */ | 
|  | initial_thread = find_thread_ptid (ptid_t (pid, pid)); | 
|  | gdb_assert (initial_thread != nullptr); | 
|  | initial_thread->last_resume_kind = resume_stop; | 
|  |  | 
|  | /* We must attach to every LWP.  If /proc is mounted, use that to | 
|  | find them now.  On the one hand, the inferior may be using raw | 
|  | clone instead of using pthreads.  On the other hand, even if it | 
|  | is using pthreads, GDB may not be connected yet (thread_db needs | 
|  | to do symbol lookups, through qSymbol).  Also, thread_db walks | 
|  | structures in the inferior's address space to find the list of | 
|  | threads/LWPs, and those structures may well be corrupted.  Note | 
|  | that once thread_db is loaded, we'll still use it to list threads | 
|  | and associate pthread info with each LWP.  */ | 
|  | try | 
|  | { | 
|  | linux_proc_attach_tgid_threads (pid, attach_proc_task_lwp_callback); | 
|  | } | 
|  | catch (const gdb_exception_error &) | 
|  | { | 
|  | /* Make sure we do not deliver the SIGSTOP to the process.  */ | 
|  | initial_thread->last_resume_kind = resume_continue; | 
|  |  | 
|  | this->detach (proc); | 
|  | throw; | 
|  | } | 
|  |  | 
|  | /* GDB will shortly read the xml target description for this | 
|  | process, to figure out the process' architecture.  But the target | 
|  | description is only filled in when the first process/thread in | 
|  | the thread group reports its initial PTRACE_ATTACH SIGSTOP.  Do | 
|  | that now, otherwise, if GDB is fast enough, it could read the | 
|  | target description _before_ that initial stop.  */ | 
|  | if (non_stop) | 
|  | { | 
|  | struct lwp_info *lwp; | 
|  | int wstat, lwpid; | 
|  | ptid_t pid_ptid = ptid_t (pid); | 
|  |  | 
|  | lwpid = wait_for_event_filtered (pid_ptid, pid_ptid, &wstat, __WALL); | 
|  | gdb_assert (lwpid > 0); | 
|  |  | 
|  | lwp = find_lwp_pid (ptid_t (lwpid)); | 
|  | gdb_assert (lwp != nullptr); | 
|  |  | 
|  | if (!WIFSTOPPED (wstat) || WSTOPSIG (wstat) != SIGSTOP) | 
|  | { | 
|  | lwp->status_pending_p = 1; | 
|  | lwp->status_pending = wstat; | 
|  | } | 
|  |  | 
|  | initial_thread->last_resume_kind = resume_continue; | 
|  |  | 
|  | async_file_mark (); | 
|  |  | 
|  | gdb_assert (proc->tdesc != NULL); | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | last_thread_of_process_p (int pid) | 
|  | { | 
|  | bool seen_one = false; | 
|  |  | 
|  | thread_info *thread = find_thread (pid, [&] (thread_info *thr_arg) | 
|  | { | 
|  | if (!seen_one) | 
|  | { | 
|  | /* This is the first thread of this process we see.  */ | 
|  | seen_one = true; | 
|  | return false; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* This is the second thread of this process we see.  */ | 
|  | return true; | 
|  | } | 
|  | }); | 
|  |  | 
|  | return thread == NULL; | 
|  | } | 
|  |  | 
|  | /* Kill LWP.  */ | 
|  |  | 
|  | static void | 
|  | linux_kill_one_lwp (struct lwp_info *lwp) | 
|  | { | 
|  | thread_info *thr = lwp->thread; | 
|  | int pid = thr->id.lwp (); | 
|  |  | 
|  | /* PTRACE_KILL is unreliable.  After stepping into a signal handler, | 
|  | there is no signal context, and ptrace(PTRACE_KILL) (or | 
|  | ptrace(PTRACE_CONT, SIGKILL), pretty much the same) acts like | 
|  | ptrace(CONT, pid, 0,0) and just resumes the tracee.  A better | 
|  | alternative is to kill with SIGKILL.  We only need one SIGKILL | 
|  | per process, not one for each thread.  But since we still support | 
|  | support debugging programs using raw clone without CLONE_THREAD, | 
|  | we send one for each thread.  For years, we used PTRACE_KILL | 
|  | only, so we're being a bit paranoid about some old kernels where | 
|  | PTRACE_KILL might work better (dubious if there are any such, but | 
|  | that's why it's paranoia), so we try SIGKILL first, PTRACE_KILL | 
|  | second, and so we're fine everywhere.  */ | 
|  |  | 
|  | errno = 0; | 
|  | kill_lwp (pid, SIGKILL); | 
|  | if (debug_threads) | 
|  | { | 
|  | int save_errno = errno; | 
|  |  | 
|  | threads_debug_printf ("kill_lwp (SIGKILL) %s, 0, 0 (%s)", | 
|  | target_pid_to_str (thr->id).c_str (), | 
|  | save_errno ? safe_strerror (save_errno) : "OK"); | 
|  | } | 
|  |  | 
|  | errno = 0; | 
|  | ptrace (PTRACE_KILL, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0); | 
|  | if (debug_threads) | 
|  | { | 
|  | int save_errno = errno; | 
|  |  | 
|  | threads_debug_printf ("PTRACE_KILL %s, 0, 0 (%s)", | 
|  | target_pid_to_str (thr->id).c_str (), | 
|  | save_errno ? safe_strerror (save_errno) : "OK"); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Kill LWP and wait for it to die.  */ | 
|  |  | 
|  | static void | 
|  | kill_wait_lwp (struct lwp_info *lwp) | 
|  | { | 
|  | thread_info *thr = lwp->thread; | 
|  | int pid = thr->id.pid (); | 
|  | int lwpid = thr->id.lwp (); | 
|  | int wstat; | 
|  | int res; | 
|  |  | 
|  | threads_debug_printf ("killing lwp %d, for pid: %d", lwpid, pid); | 
|  |  | 
|  | do | 
|  | { | 
|  | linux_kill_one_lwp (lwp); | 
|  |  | 
|  | /* Make sure it died.  Notes: | 
|  |  | 
|  | - The loop is most likely unnecessary. | 
|  |  | 
|  | - We don't use wait_for_event as that could delete lwps | 
|  | while we're iterating over them.  We're not interested in | 
|  | any pending status at this point, only in making sure all | 
|  | wait status on the kernel side are collected until the | 
|  | process is reaped. | 
|  |  | 
|  | - We don't use __WALL here as the __WALL emulation relies on | 
|  | SIGCHLD, and killing a stopped process doesn't generate | 
|  | one, nor an exit status. | 
|  | */ | 
|  | res = my_waitpid (lwpid, &wstat, 0); | 
|  | if (res == -1 && errno == ECHILD) | 
|  | res = my_waitpid (lwpid, &wstat, __WCLONE); | 
|  | } while (res > 0 && WIFSTOPPED (wstat)); | 
|  |  | 
|  | /* Even if it was stopped, the child may have already disappeared. | 
|  | E.g., if it was killed by SIGKILL.  */ | 
|  | if (res < 0 && errno != ECHILD) | 
|  | perror_with_name ("kill_wait_lwp"); | 
|  | } | 
|  |  | 
|  | /* Callback for `for_each_thread'.  Kills an lwp of a given process, | 
|  | except the leader.  */ | 
|  |  | 
|  | static void | 
|  | kill_one_lwp_callback (thread_info *thread, int pid) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | /* We avoid killing the first thread here, because of a Linux kernel (at | 
|  | least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before | 
|  | the children get a chance to be reaped, it will remain a zombie | 
|  | forever.  */ | 
|  |  | 
|  | if (thread->id.lwp () == pid) | 
|  | { | 
|  | threads_debug_printf ("is last of process %s", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | kill_wait_lwp (lwp); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::kill (process_info *process) | 
|  | { | 
|  | int pid = process->pid; | 
|  |  | 
|  | /* If we're killing a running inferior, make sure it is stopped | 
|  | first, as PTRACE_KILL will not work otherwise.  */ | 
|  | stop_all_lwps (0, NULL); | 
|  |  | 
|  | process->for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | kill_one_lwp_callback (thread, pid); | 
|  | }); | 
|  |  | 
|  | /* See the comment in linux_kill_one_lwp.  We did not kill the first | 
|  | thread in the list, so do so now.  */ | 
|  | lwp_info *lwp = find_lwp_pid (ptid_t (pid)); | 
|  |  | 
|  | if (lwp == NULL) | 
|  | threads_debug_printf ("cannot find lwp for pid: %d", pid); | 
|  | else | 
|  | kill_wait_lwp (lwp); | 
|  |  | 
|  | mourn (process); | 
|  |  | 
|  | /* Since we presently can only stop all lwps of all processes, we | 
|  | need to unstop lwps of other processes.  */ | 
|  | unstop_all_lwps (0, NULL); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Get pending signal of THREAD, for detaching purposes.  This is the | 
|  | signal the thread last stopped for, which we need to deliver to the | 
|  | thread when detaching, otherwise, it'd be suppressed/lost.  */ | 
|  |  | 
|  | static int | 
|  | get_detach_signal (thread_info *thread) | 
|  | { | 
|  | client_state &cs = get_client_state (); | 
|  | enum gdb_signal signo = GDB_SIGNAL_0; | 
|  | int status; | 
|  | struct lwp_info *lp = get_thread_lwp (thread); | 
|  |  | 
|  | if (lp->status_pending_p) | 
|  | status = lp->status_pending; | 
|  | else | 
|  | { | 
|  | /* If the thread had been suspended by gdbserver, and it stopped | 
|  | cleanly, then it'll have stopped with SIGSTOP.  But we don't | 
|  | want to deliver that SIGSTOP.  */ | 
|  | if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED | 
|  | || thread->last_status.sig () == GDB_SIGNAL_0) | 
|  | return 0; | 
|  |  | 
|  | /* Otherwise, we may need to deliver the signal we | 
|  | intercepted.  */ | 
|  | status = lp->last_status; | 
|  | } | 
|  |  | 
|  | if (!WIFSTOPPED (status)) | 
|  | { | 
|  | threads_debug_printf ("lwp %s hasn't stopped: no pending signal", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Extended wait statuses aren't real SIGTRAPs.  */ | 
|  | if (WSTOPSIG (status) == SIGTRAP && linux_is_extended_waitstatus (status)) | 
|  | { | 
|  | threads_debug_printf ("lwp %s had stopped with extended " | 
|  | "status: no pending signal", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | signo = gdb_signal_from_host (WSTOPSIG (status)); | 
|  |  | 
|  | if (cs.program_signals_p && !cs.program_signals[signo]) | 
|  | { | 
|  | threads_debug_printf ("lwp %s had signal %s, but it is in nopass state", | 
|  | target_pid_to_str (thread->id).c_str (), | 
|  | gdb_signal_to_string (signo)); | 
|  | return 0; | 
|  | } | 
|  | else if (!cs.program_signals_p | 
|  | /* If we have no way to know which signals GDB does not | 
|  | want to have passed to the program, assume | 
|  | SIGTRAP/SIGINT, which is GDB's default.  */ | 
|  | && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT)) | 
|  | { | 
|  | threads_debug_printf ("lwp %s had signal %s, " | 
|  | "but we don't know if we should pass it. " | 
|  | "Default to not.", | 
|  | target_pid_to_str (thread->id).c_str (), | 
|  | gdb_signal_to_string (signo)); | 
|  | return 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | threads_debug_printf ("lwp %s has pending signal %s: delivering it", | 
|  | target_pid_to_str (thread->id).c_str (), | 
|  | gdb_signal_to_string (signo)); | 
|  |  | 
|  | return WSTOPSIG (status); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::detach_one_lwp (lwp_info *lwp) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  | int sig; | 
|  |  | 
|  | /* If there is a pending SIGSTOP, get rid of it.  */ | 
|  | if (lwp->stop_expected) | 
|  | { | 
|  | threads_debug_printf ("Sending SIGCONT to %s", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  |  | 
|  | kill_lwp (thread->id.lwp (), SIGCONT); | 
|  | lwp->stop_expected = 0; | 
|  | } | 
|  |  | 
|  | /* Pass on any pending signal for this thread.  */ | 
|  | sig = get_detach_signal (thread); | 
|  |  | 
|  | /* Preparing to resume may try to write registers, and fail if the | 
|  | lwp is zombie.  If that happens, ignore the error.  We'll handle | 
|  | it below, when detach fails with ESRCH.  */ | 
|  | try | 
|  | { | 
|  | /* Flush any pending changes to the process's registers.  */ | 
|  | regcache_invalidate_thread (thread); | 
|  |  | 
|  | /* Finally, let it resume.  */ | 
|  | low_prepare_to_resume (lwp); | 
|  | } | 
|  | catch (const gdb_exception_error &ex) | 
|  | { | 
|  | if (!check_ptrace_stopped_lwp_gone (lwp)) | 
|  | throw; | 
|  | } | 
|  |  | 
|  | int lwpid = thread->id.lwp (); | 
|  | if (ptrace (PTRACE_DETACH, lwpid, (PTRACE_TYPE_ARG3) 0, | 
|  | (PTRACE_TYPE_ARG4) (long) sig) < 0) | 
|  | { | 
|  | int save_errno = errno; | 
|  |  | 
|  | /* We know the thread exists, so ESRCH must mean the lwp is | 
|  | zombie.  This can happen if one of the already-detached | 
|  | threads exits the whole thread group.  In that case we're | 
|  | still attached, and must reap the lwp.  */ | 
|  | if (save_errno == ESRCH) | 
|  | { | 
|  | int ret, status; | 
|  |  | 
|  | ret = my_waitpid (lwpid, &status, __WALL); | 
|  | if (ret == -1) | 
|  | { | 
|  | warning (_("Couldn't reap LWP %d while detaching: %s"), | 
|  | lwpid, safe_strerror (errno)); | 
|  | } | 
|  | else if (!WIFEXITED (status) && !WIFSIGNALED (status)) | 
|  | { | 
|  | warning (_("Reaping LWP %d while detaching " | 
|  | "returned unexpected status 0x%x"), | 
|  | lwpid, status); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error (_("Can't detach %s: %s"), | 
|  | target_pid_to_str (thread->id).c_str (), | 
|  | safe_strerror (save_errno)); | 
|  | } | 
|  | } | 
|  | else | 
|  | threads_debug_printf ("PTRACE_DETACH (%s, %s, 0) (OK)", | 
|  | target_pid_to_str (thread->id).c_str (), | 
|  | strsignal (sig)); | 
|  |  | 
|  | delete_lwp (lwp); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::detach (process_info *process) | 
|  | { | 
|  | struct lwp_info *main_lwp; | 
|  |  | 
|  | /* As there's a step over already in progress, let it finish first, | 
|  | otherwise nesting a stabilize_threads operation on top gets real | 
|  | messy.  */ | 
|  | complete_ongoing_step_over (); | 
|  |  | 
|  | /* Stop all threads before detaching.  First, ptrace requires that | 
|  | the thread is stopped to successfully detach.  Second, thread_db | 
|  | may need to uninstall thread event breakpoints from memory, which | 
|  | only works with a stopped process anyway.  */ | 
|  | stop_all_lwps (0, NULL); | 
|  |  | 
|  | #ifdef USE_THREAD_DB | 
|  | thread_db_detach (process); | 
|  | #endif | 
|  |  | 
|  | /* Stabilize threads (move out of jump pads).  */ | 
|  | target_stabilize_threads (); | 
|  |  | 
|  | /* Detach from the clone lwps first.  If the thread group exits just | 
|  | while we're detaching, we must reap the clone lwps before we're | 
|  | able to reap the leader.  */ | 
|  | process->for_each_thread ([this] (thread_info *thread) | 
|  | { | 
|  | /* We don't actually detach from the thread group leader just yet. | 
|  | If the thread group exits, we must reap the zombie clone lwps | 
|  | before we're able to reap the leader.  */ | 
|  | if (thread->id.pid () == thread->id.lwp ()) | 
|  | return; | 
|  |  | 
|  | lwp_info *lwp = get_thread_lwp (thread); | 
|  | detach_one_lwp (lwp); | 
|  | }); | 
|  |  | 
|  | main_lwp = find_lwp_pid (ptid_t (process->pid)); | 
|  | gdb_assert (main_lwp != nullptr); | 
|  | detach_one_lwp (main_lwp); | 
|  |  | 
|  | mourn (process); | 
|  |  | 
|  | /* Since we presently can only stop all lwps of all processes, we | 
|  | need to unstop lwps of other processes.  */ | 
|  | unstop_all_lwps (0, NULL); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Remove all LWPs that belong to process PROC from the lwp list.  */ | 
|  |  | 
|  | void | 
|  | linux_process_target::mourn (process_info *process) | 
|  | { | 
|  | #ifdef USE_THREAD_DB | 
|  | thread_db_mourn (process); | 
|  | #endif | 
|  |  | 
|  | process->for_each_thread ([this] (thread_info *thread) | 
|  | { | 
|  | delete_lwp (get_thread_lwp (thread)); | 
|  | }); | 
|  |  | 
|  | this->remove_linux_process (process); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::join (int pid) | 
|  | { | 
|  | int status, ret; | 
|  |  | 
|  | do { | 
|  | ret = my_waitpid (pid, &status, 0); | 
|  | if (WIFEXITED (status) || WIFSIGNALED (status)) | 
|  | break; | 
|  | } while (ret != -1 || errno != ECHILD); | 
|  | } | 
|  |  | 
|  | /* Return true if the given thread is still alive.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::thread_alive (ptid_t ptid) | 
|  | { | 
|  | struct lwp_info *lwp = find_lwp_pid (ptid); | 
|  |  | 
|  | /* We assume we always know if a thread exits.  If a whole process | 
|  | exited but we still haven't been able to report it to GDB, we'll | 
|  | hold on to the last lwp of the dead process.  */ | 
|  | if (lwp != NULL) | 
|  | return !lwp_is_marked_dead (lwp); | 
|  | else | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::thread_still_has_status_pending (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lp = get_thread_lwp (thread); | 
|  |  | 
|  | if (!lp->status_pending_p) | 
|  | return 0; | 
|  |  | 
|  | if (thread->last_resume_kind != resume_stop | 
|  | && (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT | 
|  | || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)) | 
|  | { | 
|  | CORE_ADDR pc; | 
|  | int discard = 0; | 
|  |  | 
|  | gdb_assert (lp->last_status != 0); | 
|  |  | 
|  | pc = get_pc (lp); | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (thread); | 
|  |  | 
|  | if (pc != lp->stop_pc) | 
|  | { | 
|  | threads_debug_printf ("PC of %ld changed", | 
|  | thread->id.lwp ()); | 
|  | discard = 1; | 
|  | } | 
|  |  | 
|  | if (discard) | 
|  | { | 
|  | threads_debug_printf ("discarding pending breakpoint status"); | 
|  | lp->status_pending_p = 0; | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | /* Returns true if LWP is resumed from the client's perspective.  */ | 
|  |  | 
|  | static int | 
|  | lwp_resumed (struct lwp_info *lwp) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  |  | 
|  | if (thread->last_resume_kind != resume_stop) | 
|  | return 1; | 
|  |  | 
|  | /* Did gdb send us a `vCont;t', but we haven't reported the | 
|  | corresponding stop to gdb yet?  If so, the thread is still | 
|  | resumed/running from gdb's perspective.  */ | 
|  | if (thread->last_resume_kind == resume_stop | 
|  | && thread->last_status.kind () == TARGET_WAITKIND_IGNORE) | 
|  | return 1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::status_pending_p_callback (thread_info *thread, | 
|  | ptid_t ptid) | 
|  | { | 
|  | struct lwp_info *lp = get_thread_lwp (thread); | 
|  |  | 
|  | /* Check if we're only interested in events from a specific process | 
|  | or a specific LWP.  */ | 
|  | if (!thread->id.matches (ptid)) | 
|  | return 0; | 
|  |  | 
|  | if (!lwp_resumed (lp)) | 
|  | return 0; | 
|  |  | 
|  | if (lp->status_pending_p | 
|  | && !thread_still_has_status_pending (thread)) | 
|  | { | 
|  | resume_one_lwp (lp, lp->stepping, GDB_SIGNAL_0, NULL); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | return lp->status_pending_p; | 
|  | } | 
|  |  | 
|  | struct lwp_info * | 
|  | find_lwp_pid (ptid_t ptid) | 
|  | { | 
|  | long lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid (); | 
|  | thread_info *thread = find_thread ([lwp] (thread_info *thr_arg) | 
|  | { | 
|  | return thr_arg->id.lwp () == lwp; | 
|  | }); | 
|  |  | 
|  | if (thread == NULL) | 
|  | return NULL; | 
|  |  | 
|  | return get_thread_lwp (thread); | 
|  | } | 
|  |  | 
|  | /* Return the number of known LWPs in PROCESS.  */ | 
|  |  | 
|  | static int | 
|  | num_lwps (process_info *process) | 
|  | { | 
|  | int count = 0; | 
|  |  | 
|  | process->for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | count++; | 
|  | }); | 
|  |  | 
|  | return count; | 
|  | } | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | struct lwp_info * | 
|  | iterate_over_lwps (ptid_t filter, | 
|  | gdb::function_view<iterate_over_lwps_ftype> callback) | 
|  | { | 
|  | thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg) | 
|  | { | 
|  | lwp_info *lwp = get_thread_lwp (thr_arg); | 
|  |  | 
|  | return callback (lwp); | 
|  | }); | 
|  |  | 
|  | if (thread == NULL) | 
|  | return NULL; | 
|  |  | 
|  | return get_thread_lwp (thread); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::check_zombie_leaders () | 
|  | { | 
|  | bool new_pending_event = false; | 
|  |  | 
|  | for_each_process ([&] (process_info *proc) | 
|  | { | 
|  | pid_t leader_pid = proc->pid; | 
|  | lwp_info *leader_lp = find_lwp_pid (ptid_t (leader_pid)); | 
|  |  | 
|  | threads_debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, " | 
|  | "num_lwps=%d, zombie=%d", | 
|  | leader_pid, leader_lp!= NULL, num_lwps (proc), | 
|  | linux_proc_pid_is_zombie (leader_pid)); | 
|  |  | 
|  | if (leader_lp != NULL && !leader_lp->stopped | 
|  | /* Check if there are other threads in the group, as we may | 
|  | have raced with the inferior simply exiting.  Note this | 
|  | isn't a watertight check.  If the inferior is | 
|  | multi-threaded and is exiting, it may be we see the | 
|  | leader as zombie before we reap all the non-leader | 
|  | threads.  See comments below.  */ | 
|  | && !last_thread_of_process_p (leader_pid) | 
|  | && linux_proc_pid_is_zombie (leader_pid)) | 
|  | { | 
|  | /* A zombie leader in a multi-threaded program can mean one | 
|  | of three things: | 
|  |  | 
|  | #1 - Only the leader exited, not the whole program, e.g., | 
|  | with pthread_exit.  Since we can't reap the leader's exit | 
|  | status until all other threads are gone and reaped too, | 
|  | we want to delete the zombie leader right away, as it | 
|  | can't be debugged, we can't read its registers, etc. | 
|  | This is the main reason we check for zombie leaders | 
|  | disappearing. | 
|  |  | 
|  | #2 - The whole thread-group/process exited (a group exit, | 
|  | via e.g. exit(3), and there is (or will be shortly) an | 
|  | exit reported for each thread in the process, and then | 
|  | finally an exit for the leader once the non-leaders are | 
|  | reaped. | 
|  |  | 
|  | #3 - There are 3 or more threads in the group, and a | 
|  | thread other than the leader exec'd.  See comments on | 
|  | exec events at the top of the file. | 
|  |  | 
|  | Ideally we would never delete the leader for case #2. | 
|  | Instead, we want to collect the exit status of each | 
|  | non-leader thread, and then finally collect the exit | 
|  | status of the leader as normal and use its exit code as | 
|  | whole-process exit code.  Unfortunately, there's no | 
|  | race-free way to distinguish cases #1 and #2.  We can't | 
|  | assume the exit events for the non-leaders threads are | 
|  | already pending in the kernel, nor can we assume the | 
|  | non-leader threads are in zombie state already.  Between | 
|  | the leader becoming zombie and the non-leaders exiting | 
|  | and becoming zombie themselves, there's a small time | 
|  | window, so such a check would be racy.  Temporarily | 
|  | pausing all threads and checking to see if all threads | 
|  | exit or not before re-resuming them would work in the | 
|  | case that all threads are running right now, but it | 
|  | wouldn't work if some thread is currently already | 
|  | ptrace-stopped, e.g., due to scheduler-locking. | 
|  |  | 
|  | So what we do is we delete the leader anyhow, and then | 
|  | later on when we see its exit status, we re-add it back. | 
|  | We also make sure that we only report a whole-process | 
|  | exit when we see the leader exiting, as opposed to when | 
|  | the last LWP in the LWP list exits, which can be a | 
|  | non-leader if we deleted the leader here.  */ | 
|  | threads_debug_printf ("Thread group leader %d zombie " | 
|  | "(it exited, or another thread execd), " | 
|  | "deleting it.", | 
|  | leader_pid); | 
|  |  | 
|  | thread_info *leader_thread = leader_lp->thread; | 
|  | if (report_exit_events_for (leader_thread)) | 
|  | { | 
|  | mark_lwp_dead (leader_lp, W_EXITCODE (0, 0), true); | 
|  | new_pending_event = true; | 
|  | } | 
|  | else | 
|  | delete_lwp (leader_lp); | 
|  | } | 
|  | }); | 
|  |  | 
|  | return new_pending_event; | 
|  | } | 
|  |  | 
|  | /* Callback for `find_thread'.  Returns the first LWP that is not | 
|  | stopped.  */ | 
|  |  | 
|  | static bool | 
|  | not_stopped_callback (thread_info *thread, ptid_t filter) | 
|  | { | 
|  | if (!thread->id.matches (filter)) | 
|  | return false; | 
|  |  | 
|  | lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | return !lwp->stopped; | 
|  | } | 
|  |  | 
|  | /* Increment LWP's suspend count.  */ | 
|  |  | 
|  | static void | 
|  | lwp_suspended_inc (struct lwp_info *lwp) | 
|  | { | 
|  | lwp->suspended++; | 
|  |  | 
|  | if (lwp->suspended > 4) | 
|  | threads_debug_printf | 
|  | ("LWP %ld has a suspiciously high suspend count, suspended=%d", | 
|  | lwp->thread->id.lwp (), lwp->suspended); | 
|  | } | 
|  |  | 
|  | /* Decrement LWP's suspend count.  */ | 
|  |  | 
|  | static void | 
|  | lwp_suspended_decr (struct lwp_info *lwp) | 
|  | { | 
|  | lwp->suspended--; | 
|  |  | 
|  | if (lwp->suspended < 0) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  |  | 
|  | internal_error ("unsuspend LWP %ld, suspended=%d\n", thread->id.lwp (), | 
|  | lwp->suspended); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* This function should only be called if the LWP got a SIGTRAP. | 
|  |  | 
|  | Handle any tracepoint steps or hits.  Return true if a tracepoint | 
|  | event was handled, 0 otherwise.  */ | 
|  |  | 
|  | static int | 
|  | handle_tracepoints (struct lwp_info *lwp) | 
|  | { | 
|  | thread_info *tinfo = lwp->thread; | 
|  | int tpoint_related_event = 0; | 
|  |  | 
|  | gdb_assert (lwp->suspended == 0); | 
|  |  | 
|  | /* If this tracepoint hit causes a tracing stop, we'll immediately | 
|  | uninsert tracepoints.  To do this, we temporarily pause all | 
|  | threads, unpatch away, and then unpause threads.  We need to make | 
|  | sure the unpausing doesn't resume LWP too.  */ | 
|  | lwp_suspended_inc (lwp); | 
|  |  | 
|  | /* And we need to be sure that any all-threads-stopping doesn't try | 
|  | to move threads out of the jump pads, as it could deadlock the | 
|  | inferior (LWP could be in the jump pad, maybe even holding the | 
|  | lock.)  */ | 
|  |  | 
|  | /* Do any necessary step collect actions.  */ | 
|  | tpoint_related_event |= tracepoint_finished_step (tinfo, lwp->stop_pc); | 
|  |  | 
|  | tpoint_related_event |= handle_tracepoint_bkpts (tinfo, lwp->stop_pc); | 
|  |  | 
|  | /* See if we just hit a tracepoint and do its main collect | 
|  | actions.  */ | 
|  | tpoint_related_event |= tracepoint_was_hit (tinfo, lwp->stop_pc); | 
|  |  | 
|  | lwp_suspended_decr (lwp); | 
|  |  | 
|  | gdb_assert (lwp->suspended == 0); | 
|  | gdb_assert (!stabilizing_threads | 
|  | || (lwp->collecting_fast_tracepoint | 
|  | != fast_tpoint_collect_result::not_collecting)); | 
|  |  | 
|  | if (tpoint_related_event) | 
|  | { | 
|  | threads_debug_printf ("got a tracepoint event"); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | fast_tpoint_collect_result | 
|  | linux_process_target::linux_fast_tracepoint_collecting | 
|  | (lwp_info *lwp, fast_tpoint_collect_status *status) | 
|  | { | 
|  | CORE_ADDR thread_area; | 
|  | thread_info *thread = lwp->thread; | 
|  |  | 
|  | /* Get the thread area address.  This is used to recognize which | 
|  | thread is which when tracing with the in-process agent library. | 
|  | We don't read anything from the address, and treat it as opaque; | 
|  | it's the address itself that we assume is unique per-thread.  */ | 
|  | if (low_get_thread_area (thread->id.lwp (), &thread_area) == -1) | 
|  | return fast_tpoint_collect_result::not_collecting; | 
|  |  | 
|  | return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp) | 
|  | { | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat) | 
|  | { | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (lwp->thread); | 
|  |  | 
|  | if ((wstat == NULL | 
|  | || (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP)) | 
|  | && supports_fast_tracepoints () | 
|  | && agent_loaded_p ()) | 
|  | { | 
|  | struct fast_tpoint_collect_status status; | 
|  |  | 
|  | threads_debug_printf | 
|  | ("Checking whether LWP %ld needs to move out of the jump pad.", | 
|  | current_thread->id.lwp ()); | 
|  |  | 
|  | fast_tpoint_collect_result r | 
|  | = linux_fast_tracepoint_collecting (lwp, &status); | 
|  |  | 
|  | if (wstat == NULL | 
|  | || (WSTOPSIG (*wstat) != SIGILL | 
|  | && WSTOPSIG (*wstat) != SIGFPE | 
|  | && WSTOPSIG (*wstat) != SIGSEGV | 
|  | && WSTOPSIG (*wstat) != SIGBUS)) | 
|  | { | 
|  | lwp->collecting_fast_tracepoint = r; | 
|  |  | 
|  | if (r != fast_tpoint_collect_result::not_collecting) | 
|  | { | 
|  | if (r == fast_tpoint_collect_result::before_insn | 
|  | && lwp->exit_jump_pad_bkpt == NULL) | 
|  | { | 
|  | /* Haven't executed the original instruction yet. | 
|  | Set breakpoint there, and wait till it's hit, | 
|  | then single-step until exiting the jump pad.  */ | 
|  | lwp->exit_jump_pad_bkpt | 
|  | = set_breakpoint_at (status.adjusted_insn_addr, NULL); | 
|  | } | 
|  |  | 
|  | threads_debug_printf | 
|  | ("Checking whether LWP %ld needs to move out of the jump pad..." | 
|  | " it does", current_thread->id.lwp ()); | 
|  |  | 
|  | return true; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* If we get a synchronous signal while collecting, *and* | 
|  | while executing the (relocated) original instruction, | 
|  | reset the PC to point at the tpoint address, before | 
|  | reporting to GDB.  Otherwise, it's an IPA lib bug: just | 
|  | report the signal to GDB, and pray for the best.  */ | 
|  |  | 
|  | lwp->collecting_fast_tracepoint | 
|  | = fast_tpoint_collect_result::not_collecting; | 
|  |  | 
|  | if (r != fast_tpoint_collect_result::not_collecting | 
|  | && (status.adjusted_insn_addr <= lwp->stop_pc | 
|  | && lwp->stop_pc < status.adjusted_insn_addr_end)) | 
|  | { | 
|  | siginfo_t info; | 
|  | struct regcache *regcache; | 
|  |  | 
|  | /* The si_addr on a few signals references the address | 
|  | of the faulting instruction.  Adjust that as | 
|  | well.  */ | 
|  | if ((WSTOPSIG (*wstat) == SIGILL | 
|  | || WSTOPSIG (*wstat) == SIGFPE | 
|  | || WSTOPSIG (*wstat) == SIGBUS | 
|  | || WSTOPSIG (*wstat) == SIGSEGV) | 
|  | && ptrace (PTRACE_GETSIGINFO, current_thread->id.lwp (), | 
|  | (PTRACE_TYPE_ARG3) 0, &info) == 0 | 
|  | /* Final check just to make sure we don't clobber | 
|  | the siginfo of non-kernel-sent signals.  */ | 
|  | && (uintptr_t) info.si_addr == lwp->stop_pc) | 
|  | { | 
|  | info.si_addr = (void *) (uintptr_t) status.tpoint_addr; | 
|  | ptrace (PTRACE_SETSIGINFO, current_thread->id.lwp (), | 
|  | (PTRACE_TYPE_ARG3) 0, &info); | 
|  | } | 
|  |  | 
|  | regcache = get_thread_regcache (current_thread); | 
|  | low_set_pc (regcache, status.tpoint_addr); | 
|  | lwp->stop_pc = status.tpoint_addr; | 
|  |  | 
|  | /* Cancel any fast tracepoint lock this thread was | 
|  | holding.  */ | 
|  | force_unlock_trace_buffer (); | 
|  | } | 
|  |  | 
|  | if (lwp->exit_jump_pad_bkpt != NULL) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Cancelling fast exit-jump-pad: removing bkpt." | 
|  | "stopping all threads momentarily."); | 
|  |  | 
|  | stop_all_lwps (1, lwp); | 
|  |  | 
|  | delete_breakpoint (lwp->exit_jump_pad_bkpt); | 
|  | lwp->exit_jump_pad_bkpt = NULL; | 
|  |  | 
|  | unstop_all_lwps (1, lwp); | 
|  |  | 
|  | gdb_assert (lwp->suspended >= 0); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | threads_debug_printf | 
|  | ("Checking whether LWP %ld needs to move out of the jump pad... no", | 
|  | current_thread->id.lwp ()); | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* Enqueue one signal in the "signals to report later when out of the | 
|  | jump pad" list.  */ | 
|  |  | 
|  | static void | 
|  | enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  |  | 
|  | threads_debug_printf ("Deferring signal %d for LWP %ld.", | 
|  | WSTOPSIG (*wstat), thread->id.lwp ()); | 
|  |  | 
|  | if (debug_threads) | 
|  | { | 
|  | for (const auto &sig : lwp->pending_signals_to_report) | 
|  | threads_debug_printf ("   Already queued %d", sig.signal); | 
|  |  | 
|  | threads_debug_printf ("   (no more currently queued signals)"); | 
|  | } | 
|  |  | 
|  | /* Don't enqueue non-RT signals if they are already in the deferred | 
|  | queue.  (SIGSTOP being the easiest signal to see ending up here | 
|  | twice)  */ | 
|  | if (WSTOPSIG (*wstat) < __SIGRTMIN) | 
|  | { | 
|  | for (const auto &sig : lwp->pending_signals_to_report) | 
|  | { | 
|  | if (sig.signal == WSTOPSIG (*wstat)) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Not requeuing already queued non-RT signal %d for LWP %ld", | 
|  | sig.signal, thread->id.lwp ()); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | lwp->pending_signals_to_report.emplace_back (WSTOPSIG (*wstat)); | 
|  |  | 
|  | ptrace (PTRACE_GETSIGINFO, thread->id.lwp (), (PTRACE_TYPE_ARG3) 0, | 
|  | &lwp->pending_signals_to_report.back ().info); | 
|  | } | 
|  |  | 
|  | /* Dequeue one signal from the "signals to report later when out of | 
|  | the jump pad" list.  */ | 
|  |  | 
|  | static int | 
|  | dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  |  | 
|  | if (!lwp->pending_signals_to_report.empty ()) | 
|  | { | 
|  | const pending_signal &p_sig = lwp->pending_signals_to_report.front (); | 
|  |  | 
|  | *wstat = W_STOPCODE (p_sig.signal); | 
|  | if (p_sig.info.si_signo != 0) | 
|  | ptrace (PTRACE_SETSIGINFO, thread->id.lwp (), (PTRACE_TYPE_ARG3) 0, | 
|  | &p_sig.info); | 
|  |  | 
|  | lwp->pending_signals_to_report.pop_front (); | 
|  |  | 
|  | threads_debug_printf ("Reporting deferred signal %d for LWP %ld.", | 
|  | WSTOPSIG (*wstat), thread->id.lwp ()); | 
|  |  | 
|  | if (debug_threads) | 
|  | { | 
|  | for (const auto &sig : lwp->pending_signals_to_report) | 
|  | threads_debug_printf ("   Still queued %d", sig.signal); | 
|  |  | 
|  | threads_debug_printf ("   (no more queued signals)"); | 
|  | } | 
|  |  | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::check_stopped_by_watchpoint (lwp_info *child) | 
|  | { | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (child->thread); | 
|  |  | 
|  | if (low_stopped_by_watchpoint ()) | 
|  | { | 
|  | child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT; | 
|  | child->stopped_data_address = low_stopped_data_address (); | 
|  | } | 
|  |  | 
|  | return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::low_stopped_by_watchpoint () | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_process_target::low_stopped_data_address () | 
|  | { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Return the ptrace options that we want to try to enable.  */ | 
|  |  | 
|  | static int | 
|  | linux_low_ptrace_options (int attached) | 
|  | { | 
|  | client_state &cs = get_client_state (); | 
|  | int options = 0; | 
|  |  | 
|  | if (!attached) | 
|  | options |= PTRACE_O_EXITKILL; | 
|  |  | 
|  | if (cs.report_fork_events) | 
|  | options |= PTRACE_O_TRACEFORK; | 
|  |  | 
|  | if (cs.report_vfork_events) | 
|  | options |= (PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE); | 
|  |  | 
|  | if (cs.report_exec_events) | 
|  | options |= PTRACE_O_TRACEEXEC; | 
|  |  | 
|  | options |= PTRACE_O_TRACESYSGOOD; | 
|  |  | 
|  | return options; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::filter_event (int lwpid, int wstat) | 
|  | { | 
|  | struct lwp_info *child; | 
|  | thread_info *thread; | 
|  | int have_stop_pc = 0; | 
|  |  | 
|  | child = find_lwp_pid (ptid_t (lwpid)); | 
|  |  | 
|  | /* Check for events reported by anything not in our LWP list.  */ | 
|  | if (child == nullptr) | 
|  | { | 
|  | if (WIFSTOPPED (wstat)) | 
|  | { | 
|  | if (WSTOPSIG (wstat) == SIGTRAP | 
|  | && linux_ptrace_get_extended_event (wstat) == PTRACE_EVENT_EXEC) | 
|  | { | 
|  | /* A non-leader thread exec'ed after we've seen the | 
|  | leader zombie, and removed it from our lists (in | 
|  | check_zombie_leaders).  The non-leader thread changes | 
|  | its tid to the tgid.  */ | 
|  | threads_debug_printf | 
|  | ("Re-adding thread group leader LWP %d after exec.", | 
|  | lwpid); | 
|  |  | 
|  | child = add_lwp (ptid_t (lwpid, lwpid)); | 
|  | child->stopped = 1; | 
|  | switch_to_thread (child->thread); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* A process we are controlling has forked and the new | 
|  | child's stop was reported to us by the kernel.  Save | 
|  | its PID and go back to waiting for the fork event to | 
|  | be reported - the stopped process might be returned | 
|  | from waitpid before or after the fork event is.  */ | 
|  | threads_debug_printf | 
|  | ("Saving LWP %d status %s in stopped_pids list", | 
|  | lwpid, status_to_str (wstat).c_str ()); | 
|  | add_to_pid_list (&stopped_pids, lwpid, wstat); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Don't report an event for the exit of an LWP not in our | 
|  | list, i.e. not part of any inferior we're debugging. | 
|  | This can happen if we detach from a program we originally | 
|  | forked and then it exits.  However, note that we may have | 
|  | earlier deleted a leader of an inferior we're debugging, | 
|  | in check_zombie_leaders.  Re-add it back here if so.  */ | 
|  | find_process ([&] (process_info *proc) | 
|  | { | 
|  | if (proc->pid == lwpid) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Re-adding thread group leader LWP %d after exit.", | 
|  | lwpid); | 
|  |  | 
|  | child = add_lwp (ptid_t (lwpid, lwpid)); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | }); | 
|  | } | 
|  |  | 
|  | if (child == nullptr) | 
|  | return; | 
|  | } | 
|  |  | 
|  | thread = child->thread; | 
|  |  | 
|  | child->stopped = 1; | 
|  |  | 
|  | child->last_status = wstat; | 
|  |  | 
|  | /* Check if the thread has exited.  */ | 
|  | if ((WIFEXITED (wstat) || WIFSIGNALED (wstat))) | 
|  | { | 
|  | threads_debug_printf ("%d exited", lwpid); | 
|  |  | 
|  | if (finish_step_over (child)) | 
|  | { | 
|  | /* Unsuspend all other LWPs, and set them back running again.  */ | 
|  | unsuspend_all_lwps (child); | 
|  | } | 
|  |  | 
|  | /* If this is not the leader LWP, then the exit signal was not | 
|  | the end of the debugged application and should be ignored, | 
|  | unless GDB wants to hear about thread exits.  */ | 
|  | if (report_exit_events_for (thread) || is_leader (thread)) | 
|  | { | 
|  | /* Since events are serialized to GDB core, and we can't | 
|  | report this one right now.  Leave the status pending for | 
|  | the next time we're able to report it.  */ | 
|  | mark_lwp_dead (child, wstat, false); | 
|  | return; | 
|  | } | 
|  | else | 
|  | { | 
|  | delete_lwp (child); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | gdb_assert (WIFSTOPPED (wstat)); | 
|  |  | 
|  | if (WIFSTOPPED (wstat)) | 
|  | { | 
|  | /* Architecture-specific setup after inferior is running.  */ | 
|  | process_info *proc = find_process_pid (thread->id.pid ()); | 
|  |  | 
|  | if (proc->tdesc == NULL) | 
|  | { | 
|  | if (proc->attached) | 
|  | { | 
|  | /* This needs to happen after we have attached to the | 
|  | inferior and it is stopped for the first time, but | 
|  | before we access any inferior registers.  */ | 
|  | arch_setup_thread (thread); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* The process is started, but GDBserver will do | 
|  | architecture-specific setup after the program stops at | 
|  | the first instruction.  */ | 
|  | child->status_pending_p = 1; | 
|  | child->status_pending = wstat; | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (WIFSTOPPED (wstat) && child->must_set_ptrace_flags) | 
|  | { | 
|  | process_info *proc = find_process_pid (thread->id.pid ()); | 
|  | int options = linux_low_ptrace_options (proc->attached); | 
|  |  | 
|  | linux_enable_event_reporting (lwpid, options); | 
|  | child->must_set_ptrace_flags = 0; | 
|  | } | 
|  |  | 
|  | /* Always update syscall_state, even if it will be filtered later.  */ | 
|  | if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SYSCALL_SIGTRAP) | 
|  | { | 
|  | child->syscall_state | 
|  | = (child->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY | 
|  | ? TARGET_WAITKIND_SYSCALL_RETURN | 
|  | : TARGET_WAITKIND_SYSCALL_ENTRY); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Almost all other ptrace-stops are known to be outside of system | 
|  | calls, with further exceptions in handle_extended_wait.  */ | 
|  | child->syscall_state = TARGET_WAITKIND_IGNORE; | 
|  | } | 
|  |  | 
|  | /* Be careful to not overwrite stop_pc until save_stop_reason is | 
|  | called.  */ | 
|  | if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP | 
|  | && linux_is_extended_waitstatus (wstat)) | 
|  | { | 
|  | child->stop_pc = get_pc (child); | 
|  | if (handle_extended_wait (&child, wstat)) | 
|  | { | 
|  | /* The event has been handled, so just return without | 
|  | reporting it.  */ | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (linux_wstatus_maybe_breakpoint (wstat)) | 
|  | { | 
|  | if (save_stop_reason (child)) | 
|  | have_stop_pc = 1; | 
|  | } | 
|  |  | 
|  | if (!have_stop_pc) | 
|  | child->stop_pc = get_pc (child); | 
|  |  | 
|  | if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGSTOP | 
|  | && child->stop_expected) | 
|  | { | 
|  | threads_debug_printf ("Expected stop."); | 
|  |  | 
|  | child->stop_expected = 0; | 
|  |  | 
|  | if (thread->last_resume_kind == resume_stop) | 
|  | { | 
|  | /* We want to report the stop to the core.  Treat the | 
|  | SIGSTOP as a normal event.  */ | 
|  | threads_debug_printf ("resume_stop SIGSTOP caught for %s.", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  | } | 
|  | else if (stopping_threads != NOT_STOPPING_THREADS) | 
|  | { | 
|  | /* Stopping threads.  We don't want this SIGSTOP to end up | 
|  | pending.  */ | 
|  | threads_debug_printf ("SIGSTOP caught for %s while stopping threads.", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  | return; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* This is a delayed SIGSTOP.  Filter out the event.  */ | 
|  | threads_debug_printf ("%s %s, 0, 0 (discard delayed SIGSTOP)", | 
|  | child->stepping ? "step" : "continue", | 
|  | target_pid_to_str (thread->id).c_str ()); | 
|  |  | 
|  | resume_one_lwp (child, child->stepping, 0, NULL); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | child->status_pending_p = 1; | 
|  | child->status_pending = wstat; | 
|  | return; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::maybe_hw_step (thread_info *thread) | 
|  | { | 
|  | if (supports_hardware_single_step ()) | 
|  | return true; | 
|  | else | 
|  | { | 
|  | /* GDBserver must insert single-step breakpoint for software | 
|  | single step.  */ | 
|  | gdb_assert (has_single_step_breakpoints (thread)); | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::resume_stopped_resumed_lwps (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lp = get_thread_lwp (thread); | 
|  |  | 
|  | if (lp->stopped | 
|  | && !lp->suspended | 
|  | && !lp->status_pending_p | 
|  | && thread->last_status.kind () == TARGET_WAITKIND_IGNORE) | 
|  | { | 
|  | int step = 0; | 
|  |  | 
|  | if (thread->last_resume_kind == resume_step) | 
|  | { | 
|  | if (supports_software_single_step ()) | 
|  | install_software_single_step_breakpoints (lp); | 
|  |  | 
|  | step = maybe_hw_step (thread); | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("resuming stopped-resumed LWP %s at %s: step=%d", | 
|  | target_pid_to_str (thread->id).c_str (), | 
|  | paddress (lp->stop_pc), step); | 
|  |  | 
|  | resume_one_lwp (lp, step, GDB_SIGNAL_0, NULL); | 
|  | } | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::wait_for_event_filtered (ptid_t wait_ptid, | 
|  | ptid_t filter_ptid, | 
|  | int *wstatp, int options) | 
|  | { | 
|  | thread_info *event_thread; | 
|  | struct lwp_info *event_child, *requested_child; | 
|  | sigset_t block_mask, prev_mask; | 
|  |  | 
|  | retry: | 
|  | /* N.B. event_thread points to the thread_info struct that contains | 
|  | event_child.  Keep them in sync.  */ | 
|  | event_thread = NULL; | 
|  | event_child = NULL; | 
|  | requested_child = NULL; | 
|  |  | 
|  | /* Check for a lwp with a pending status.  */ | 
|  |  | 
|  | if (filter_ptid == minus_one_ptid || filter_ptid.is_pid ()) | 
|  | { | 
|  | event_thread = find_thread_in_random ([&] (thread_info *thread) | 
|  | { | 
|  | return status_pending_p_callback (thread, filter_ptid); | 
|  | }); | 
|  |  | 
|  | if (event_thread != NULL) | 
|  | { | 
|  | event_child = get_thread_lwp (event_thread); | 
|  | threads_debug_printf ("Got a pending child %ld", event_thread->id.lwp ()); | 
|  | } | 
|  | } | 
|  | else if (filter_ptid != null_ptid) | 
|  | { | 
|  | requested_child = find_lwp_pid (filter_ptid); | 
|  | gdb_assert (requested_child != nullptr); | 
|  |  | 
|  | if (stopping_threads == NOT_STOPPING_THREADS | 
|  | && requested_child->status_pending_p | 
|  | && (requested_child->collecting_fast_tracepoint | 
|  | != fast_tpoint_collect_result::not_collecting)) | 
|  | { | 
|  | enqueue_one_deferred_signal (requested_child, | 
|  | &requested_child->status_pending); | 
|  | requested_child->status_pending_p = 0; | 
|  | requested_child->status_pending = 0; | 
|  | resume_one_lwp (requested_child, 0, 0, NULL); | 
|  | } | 
|  |  | 
|  | if (requested_child->suspended | 
|  | && requested_child->status_pending_p) | 
|  | { | 
|  | internal_error ("requesting an event out of a" | 
|  | " suspended child?"); | 
|  | } | 
|  |  | 
|  | if (requested_child->status_pending_p) | 
|  | { | 
|  | event_child = requested_child; | 
|  | event_thread = event_child->thread; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (event_child != NULL) | 
|  | { | 
|  | threads_debug_printf ("Got an event from pending child %ld (%04x)", | 
|  | event_thread->id.lwp (), | 
|  | event_child->status_pending); | 
|  |  | 
|  | *wstatp = event_child->status_pending; | 
|  | event_child->status_pending_p = 0; | 
|  | event_child->status_pending = 0; | 
|  | switch_to_thread (event_thread); | 
|  | return event_thread->id.lwp (); | 
|  | } | 
|  |  | 
|  | /* But if we don't find a pending event, we'll have to wait. | 
|  |  | 
|  | We only enter this loop if no process has a pending wait status. | 
|  | Thus any action taken in response to a wait status inside this | 
|  | loop is responding as soon as we detect the status, not after any | 
|  | pending events.  */ | 
|  |  | 
|  | /* Make sure SIGCHLD is blocked until the sigsuspend below.  Block | 
|  | all signals while here.  */ | 
|  | sigfillset (&block_mask); | 
|  | gdb_sigmask (SIG_BLOCK, &block_mask, &prev_mask); | 
|  |  | 
|  | /* Always pull all events out of the kernel.  We'll randomly select | 
|  | an event LWP out of all that have events, to prevent | 
|  | starvation.  */ | 
|  | while (event_child == NULL) | 
|  | { | 
|  | pid_t ret = 0; | 
|  |  | 
|  | /* Always use -1 and WNOHANG, due to couple of a kernel/ptrace | 
|  | quirks: | 
|  |  | 
|  | - If the thread group leader exits while other threads in the | 
|  | thread group still exist, waitpid(TGID, ...) hangs.  That | 
|  | waitpid won't return an exit status until the other threads | 
|  | in the group are reaped. | 
|  |  | 
|  | - When a non-leader thread execs, that thread just vanishes | 
|  | without reporting an exit (so we'd hang if we waited for it | 
|  | explicitly in that case).  The exec event is reported to | 
|  | the TGID pid.  */ | 
|  | errno = 0; | 
|  | ret = my_waitpid (-1, wstatp, options | WNOHANG); | 
|  |  | 
|  | threads_debug_printf ("waitpid(-1, ...) returned %d, %s", | 
|  | ret, errno ? safe_strerror (errno) : "ERRNO-OK"); | 
|  |  | 
|  | if (ret > 0) | 
|  | { | 
|  | threads_debug_printf ("waitpid %ld received %s", | 
|  | (long) ret, status_to_str (*wstatp).c_str ()); | 
|  |  | 
|  | /* Filter all events.  IOW, leave all events pending.  We'll | 
|  | randomly select an event LWP out of all that have events | 
|  | below.  */ | 
|  | filter_event (ret, *wstatp); | 
|  | /* Retry until nothing comes out of waitpid.  A single | 
|  | SIGCHLD can indicate more than one child stopped.  */ | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* Now that we've pulled all events out of the kernel, resume | 
|  | LWPs that don't have an interesting event to report.  */ | 
|  | if (stopping_threads == NOT_STOPPING_THREADS) | 
|  | for_each_thread ([this] (thread_info *thread) | 
|  | { | 
|  | resume_stopped_resumed_lwps (thread); | 
|  | }); | 
|  |  | 
|  | /* ... and find an LWP with a status to report to the core, if | 
|  | any.  */ | 
|  | event_thread = find_thread_in_random ([&] (thread_info *thread) | 
|  | { | 
|  | return status_pending_p_callback (thread, filter_ptid); | 
|  | }); | 
|  |  | 
|  | if (event_thread != NULL) | 
|  | { | 
|  | event_child = get_thread_lwp (event_thread); | 
|  | *wstatp = event_child->status_pending; | 
|  | event_child->status_pending_p = 0; | 
|  | event_child->status_pending = 0; | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* Check for zombie thread group leaders.  Those can't be reaped | 
|  | until all other threads in the thread group are.  */ | 
|  | if (check_zombie_leaders ()) | 
|  | goto retry; | 
|  |  | 
|  | auto not_stopped = [&] (thread_info *thread) | 
|  | { | 
|  | return not_stopped_callback (thread, wait_ptid); | 
|  | }; | 
|  |  | 
|  | /* If there are no resumed children left in the set of LWPs we | 
|  | want to wait for, bail.  We can't just block in | 
|  | waitpid/sigsuspend, because lwps might have been left stopped | 
|  | in trace-stop state, and we'd be stuck forever waiting for | 
|  | their status to change (which would only happen if we resumed | 
|  | them).  Even if WNOHANG is set, this return code is preferred | 
|  | over 0 (below), as it is more detailed.  */ | 
|  | if (find_thread (not_stopped) == NULL) | 
|  | { | 
|  | threads_debug_printf ("exit (no unwaited-for LWP)"); | 
|  |  | 
|  | gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | /* No interesting event to report to the caller.  */ | 
|  | if ((options & WNOHANG)) | 
|  | { | 
|  | threads_debug_printf ("WNOHANG set, no event found"); | 
|  |  | 
|  | gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Block until we get an event reported with SIGCHLD.  */ | 
|  | threads_debug_printf ("sigsuspend'ing"); | 
|  |  | 
|  | sigsuspend (&prev_mask); | 
|  | gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); | 
|  | goto retry; | 
|  | } | 
|  |  | 
|  | gdb_sigmask (SIG_SETMASK, &prev_mask, NULL); | 
|  |  | 
|  | switch_to_thread (event_thread); | 
|  |  | 
|  | return event_thread->id.lwp (); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::wait_for_event (ptid_t ptid, int *wstatp, int options) | 
|  | { | 
|  | return wait_for_event_filtered (ptid, ptid, wstatp, options); | 
|  | } | 
|  |  | 
|  | /* Select one LWP out of those that have events pending.  */ | 
|  |  | 
|  | static void | 
|  | select_event_lwp (struct lwp_info **orig_lp) | 
|  | { | 
|  | thread_info *event_thread = NULL; | 
|  |  | 
|  | /* In all-stop, give preference to the LWP that is being | 
|  | single-stepped.  There will be at most one, and it's the LWP that | 
|  | the core is most interested in.  If we didn't do this, then we'd | 
|  | have to handle pending step SIGTRAPs somehow in case the core | 
|  | later continues the previously-stepped thread, otherwise we'd | 
|  | report the pending SIGTRAP, and the core, not having stepped the | 
|  | thread, wouldn't understand what the trap was for, and therefore | 
|  | would report it to the user as a random signal.  */ | 
|  | if (!non_stop) | 
|  | { | 
|  | event_thread = find_thread ([] (thread_info *thread) | 
|  | { | 
|  | lwp_info *lp = get_thread_lwp (thread); | 
|  |  | 
|  | return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE | 
|  | && thread->last_resume_kind == resume_step | 
|  | && lp->status_pending_p); | 
|  | }); | 
|  |  | 
|  | if (event_thread != NULL) | 
|  | threads_debug_printf | 
|  | ("Select single-step %s", | 
|  | target_pid_to_str (event_thread->id).c_str ()); | 
|  | } | 
|  | if (event_thread == NULL) | 
|  | { | 
|  | /* No single-stepping LWP.  Select one at random, out of those | 
|  | which have had events.  */ | 
|  |  | 
|  | event_thread = find_thread_in_random ([&] (thread_info *thread) | 
|  | { | 
|  | lwp_info *lp = get_thread_lwp (thread); | 
|  |  | 
|  | /* Only resumed LWPs that have an event pending. */ | 
|  | return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE | 
|  | && lp->status_pending_p); | 
|  | }); | 
|  | } | 
|  |  | 
|  | if (event_thread != NULL) | 
|  | { | 
|  | struct lwp_info *event_lp = get_thread_lwp (event_thread); | 
|  |  | 
|  | /* Switch the event LWP.  */ | 
|  | *orig_lp = event_lp; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Decrement the suspend count of all LWPs, except EXCEPT, if non | 
|  | NULL.  */ | 
|  |  | 
|  | static void | 
|  | unsuspend_all_lwps (struct lwp_info *except) | 
|  | { | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | if (lwp != except) | 
|  | lwp_suspended_decr (lwp); | 
|  | }); | 
|  | } | 
|  |  | 
|  | static bool lwp_running (thread_info *thread); | 
|  |  | 
|  | /* Stabilize threads (move out of jump pads). | 
|  |  | 
|  | If a thread is midway collecting a fast tracepoint, we need to | 
|  | finish the collection and move it out of the jump pad before | 
|  | reporting the signal. | 
|  |  | 
|  | This avoids recursion while collecting (when a signal arrives | 
|  | midway, and the signal handler itself collects), which would trash | 
|  | the trace buffer.  In case the user set a breakpoint in a signal | 
|  | handler, this avoids the backtrace showing the jump pad, etc.. | 
|  | Most importantly, there are certain things we can't do safely if | 
|  | threads are stopped in a jump pad (or in its callee's).  For | 
|  | example: | 
|  |  | 
|  | - starting a new trace run.  A thread still collecting the | 
|  | previous run, could trash the trace buffer when resumed.  The trace | 
|  | buffer control structures would have been reset but the thread had | 
|  | no way to tell.  The thread could even midway memcpy'ing to the | 
|  | buffer, which would mean that when resumed, it would clobber the | 
|  | trace buffer that had been set for a new run. | 
|  |  | 
|  | - we can't rewrite/reuse the jump pads for new tracepoints | 
|  | safely.  Say you do tstart while a thread is stopped midway while | 
|  | collecting.  When the thread is later resumed, it finishes the | 
|  | collection, and returns to the jump pad, to execute the original | 
|  | instruction that was under the tracepoint jump at the time the | 
|  | older run had been started.  If the jump pad had been rewritten | 
|  | since for something else in the new run, the thread would now | 
|  | execute the wrong / random instructions.  */ | 
|  |  | 
|  | void | 
|  | linux_process_target::stabilize_threads () | 
|  | { | 
|  | thread_info *thread_stuck = find_thread ([this] (thread_info *thread) | 
|  | { | 
|  | return stuck_in_jump_pad (thread); | 
|  | }); | 
|  |  | 
|  | if (thread_stuck != NULL) | 
|  | { | 
|  | threads_debug_printf ("can't stabilize, LWP %ld is stuck in jump pad", | 
|  | thread_stuck->id.lwp ()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  |  | 
|  | stabilizing_threads = 1; | 
|  |  | 
|  | /* Kick 'em all.  */ | 
|  | for_each_thread ([this] (thread_info *thread) | 
|  | { | 
|  | move_out_of_jump_pad (thread); | 
|  | }); | 
|  |  | 
|  | /* Loop until all are stopped out of the jump pads.  */ | 
|  | while (find_thread (lwp_running) != NULL) | 
|  | { | 
|  | struct target_waitstatus ourstatus; | 
|  | struct lwp_info *lwp; | 
|  | int wstat; | 
|  |  | 
|  | /* Note that we go through the full wait even loop.  While | 
|  | moving threads out of jump pad, we need to be able to step | 
|  | over internal breakpoints and such.  */ | 
|  | wait_1 (minus_one_ptid, &ourstatus, 0); | 
|  |  | 
|  | if (ourstatus.kind () == TARGET_WAITKIND_STOPPED) | 
|  | { | 
|  | lwp = get_thread_lwp (current_thread); | 
|  |  | 
|  | /* Lock it.  */ | 
|  | lwp_suspended_inc (lwp); | 
|  |  | 
|  | if (ourstatus.sig () != GDB_SIGNAL_0 | 
|  | || current_thread->last_resume_kind == resume_stop) | 
|  | { | 
|  | wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.sig ())); | 
|  | enqueue_one_deferred_signal (lwp, &wstat); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | unsuspend_all_lwps (NULL); | 
|  |  | 
|  | stabilizing_threads = 0; | 
|  |  | 
|  | if (debug_threads) | 
|  | { | 
|  | thread_stuck = find_thread ([this] (thread_info *thread) | 
|  | { | 
|  | return stuck_in_jump_pad (thread); | 
|  | }); | 
|  |  | 
|  | if (thread_stuck != NULL) | 
|  | threads_debug_printf | 
|  | ("couldn't stabilize, LWP %ld got stuck in jump pad", | 
|  | thread_stuck->id.lwp ()); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Convenience function that is called when the kernel reports an | 
|  | event that is not passed out to GDB.  */ | 
|  |  | 
|  | static ptid_t | 
|  | ignore_event (struct target_waitstatus *ourstatus) | 
|  | { | 
|  | /* If we got an event, there may still be others, as a single | 
|  | SIGCHLD can indicate more than one child stopped.  This forces | 
|  | another target_wait call.  */ | 
|  | async_file_mark (); | 
|  |  | 
|  | ourstatus->set_ignore (); | 
|  | return null_ptid; | 
|  | } | 
|  |  | 
|  | ptid_t | 
|  | linux_process_target::filter_exit_event (lwp_info *event_child, | 
|  | target_waitstatus *ourstatus) | 
|  | { | 
|  | thread_info *thread = event_child->thread; | 
|  | ptid_t ptid = thread->id; | 
|  |  | 
|  | if (ourstatus->kind () == TARGET_WAITKIND_THREAD_EXITED) | 
|  | { | 
|  | /* We're reporting a thread exit for the leader.  The exit was | 
|  | detected by check_zombie_leaders.  */ | 
|  | gdb_assert (is_leader (thread)); | 
|  | gdb_assert (report_exit_events_for (thread)); | 
|  |  | 
|  | delete_lwp (event_child); | 
|  | return ptid; | 
|  | } | 
|  |  | 
|  | /* Note we must filter TARGET_WAITKIND_SIGNALLED as well, otherwise | 
|  | if a non-leader thread exits with a signal, we'd report it to the | 
|  | core which would interpret it as the whole-process exiting. | 
|  | There is no TARGET_WAITKIND_THREAD_SIGNALLED event kind.  */ | 
|  | if (ourstatus->kind () != TARGET_WAITKIND_EXITED | 
|  | && ourstatus->kind () != TARGET_WAITKIND_SIGNALLED) | 
|  | return ptid; | 
|  |  | 
|  | if (!is_leader (thread)) | 
|  | { | 
|  | if (report_exit_events_for (thread)) | 
|  | ourstatus->set_thread_exited (0); | 
|  | else | 
|  | ourstatus->set_ignore (); | 
|  |  | 
|  | delete_lwp (event_child); | 
|  | } | 
|  | return ptid; | 
|  | } | 
|  |  | 
|  | /* Returns 1 if GDB is interested in any event_child syscalls.  */ | 
|  |  | 
|  | static int | 
|  | gdb_catching_syscalls_p (struct lwp_info *event_child) | 
|  | { | 
|  | return !event_child->thread->process ()->syscalls_to_catch.empty (); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::gdb_catch_this_syscall (lwp_info *event_child) | 
|  | { | 
|  | int sysno; | 
|  | thread_info *thread = event_child->thread; | 
|  | process_info *proc = thread->process (); | 
|  |  | 
|  | if (proc->syscalls_to_catch.empty ()) | 
|  | return false; | 
|  |  | 
|  | if (proc->syscalls_to_catch[0] == ANY_SYSCALL) | 
|  | return true; | 
|  |  | 
|  | get_syscall_trapinfo (event_child, &sysno); | 
|  |  | 
|  | for (int iter : proc->syscalls_to_catch) | 
|  | if (iter == sysno) | 
|  | return true; | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ptid_t | 
|  | linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, | 
|  | target_wait_flags target_options) | 
|  | { | 
|  | THREADS_SCOPED_DEBUG_ENTER_EXIT; | 
|  |  | 
|  | client_state &cs = get_client_state (); | 
|  | int w; | 
|  | struct lwp_info *event_child; | 
|  | int options; | 
|  | int pid; | 
|  | int step_over_finished; | 
|  | int bp_explains_trap; | 
|  | int maybe_internal_trap; | 
|  | int report_to_gdb; | 
|  | int trace_event; | 
|  | int in_step_range; | 
|  |  | 
|  | threads_debug_printf ("[%s]", target_pid_to_str (ptid).c_str ()); | 
|  |  | 
|  | /* Translate generic target options into linux options.  */ | 
|  | options = __WALL; | 
|  | if (target_options & TARGET_WNOHANG) | 
|  | options |= WNOHANG; | 
|  |  | 
|  | bp_explains_trap = 0; | 
|  | trace_event = 0; | 
|  | in_step_range = 0; | 
|  | ourstatus->set_ignore (); | 
|  |  | 
|  | bool was_any_resumed = any_resumed (); | 
|  |  | 
|  | if (step_over_bkpt == null_ptid) | 
|  | pid = wait_for_event (ptid, &w, options); | 
|  | else | 
|  | { | 
|  | threads_debug_printf ("step_over_bkpt set [%s], doing a blocking wait", | 
|  | target_pid_to_str (step_over_bkpt).c_str ()); | 
|  | pid = wait_for_event (step_over_bkpt, &w, options & ~WNOHANG); | 
|  | } | 
|  |  | 
|  | if (pid == 0 || (pid == -1 && !was_any_resumed)) | 
|  | { | 
|  | gdb_assert (target_options & TARGET_WNOHANG); | 
|  |  | 
|  | threads_debug_printf ("ret = null_ptid, TARGET_WAITKIND_IGNORE"); | 
|  |  | 
|  | ourstatus->set_ignore (); | 
|  | return null_ptid; | 
|  | } | 
|  | else if (pid == -1) | 
|  | { | 
|  | threads_debug_printf ("ret = null_ptid, TARGET_WAITKIND_NO_RESUMED"); | 
|  |  | 
|  | ourstatus->set_no_resumed (); | 
|  | return null_ptid; | 
|  | } | 
|  |  | 
|  | event_child = get_thread_lwp (current_thread); | 
|  |  | 
|  | /* wait_for_event only returns an exit status for the last | 
|  | child of a process.  Report it.  */ | 
|  | if (WIFEXITED (w) || WIFSIGNALED (w)) | 
|  | { | 
|  | if (WIFEXITED (w)) | 
|  | { | 
|  | /* If we already have the exit recorded in waitstatus, use | 
|  | it.  This will happen when we detect a zombie leader, | 
|  | when we had GDB_THREAD_OPTION_EXIT enabled for it.  We | 
|  | want to report its exit as TARGET_WAITKIND_THREAD_EXITED, | 
|  | as the whole process hasn't exited yet.  */ | 
|  | const target_waitstatus &ws = event_child->waitstatus; | 
|  | if (ws.kind () != TARGET_WAITKIND_IGNORE) | 
|  | { | 
|  | gdb_assert (ws.kind () == TARGET_WAITKIND_EXITED | 
|  | || ws.kind () == TARGET_WAITKIND_THREAD_EXITED); | 
|  | *ourstatus = ws; | 
|  | } | 
|  | else | 
|  | ourstatus->set_exited (WEXITSTATUS (w)); | 
|  |  | 
|  | threads_debug_printf | 
|  | ("ret = %s, exited with retcode %d", | 
|  | target_pid_to_str (current_thread->id).c_str (), | 
|  | WEXITSTATUS (w)); | 
|  | } | 
|  | else | 
|  | { | 
|  | ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (w))); | 
|  |  | 
|  | threads_debug_printf | 
|  | ("ret = %s, terminated with signal %d", | 
|  | target_pid_to_str (current_thread->id).c_str (), | 
|  | WTERMSIG (w)); | 
|  | } | 
|  |  | 
|  | return filter_exit_event (event_child, ourstatus); | 
|  | } | 
|  |  | 
|  | /* If step-over executes a breakpoint instruction, in the case of a | 
|  | hardware single step it means a gdb/gdbserver breakpoint had been | 
|  | planted on top of a permanent breakpoint, in the case of a software | 
|  | single step it may just mean that gdbserver hit the reinsert breakpoint. | 
|  | The PC has been adjusted by save_stop_reason to point at | 
|  | the breakpoint address. | 
|  | So in the case of the hardware single step advance the PC manually | 
|  | past the breakpoint and in the case of software single step advance only | 
|  | if it's not the single_step_breakpoint we are hitting. | 
|  | This avoids that a program would keep trapping a permanent breakpoint | 
|  | forever.  */ | 
|  | if (step_over_bkpt != null_ptid | 
|  | && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT | 
|  | && (event_child->stepping | 
|  | || !single_step_breakpoint_inserted_here (event_child->stop_pc))) | 
|  | { | 
|  | int increment_pc = 0; | 
|  | int breakpoint_kind = 0; | 
|  | CORE_ADDR stop_pc = event_child->stop_pc; | 
|  |  | 
|  | breakpoint_kind = breakpoint_kind_from_current_state (&stop_pc); | 
|  | sw_breakpoint_from_kind (breakpoint_kind, &increment_pc); | 
|  |  | 
|  | threads_debug_printf | 
|  | ("step-over for %s executed software breakpoint", | 
|  | target_pid_to_str (current_thread->id).c_str ()); | 
|  |  | 
|  | if (increment_pc != 0) | 
|  | { | 
|  | struct regcache *regcache | 
|  | = get_thread_regcache (current_thread); | 
|  |  | 
|  | event_child->stop_pc += increment_pc; | 
|  | low_set_pc (regcache, event_child->stop_pc); | 
|  |  | 
|  | if (!low_breakpoint_at (event_child->stop_pc)) | 
|  | event_child->stop_reason = TARGET_STOPPED_BY_NO_REASON; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If this event was not handled before, and is not a SIGTRAP, we | 
|  | report it.  SIGILL and SIGSEGV are also treated as traps in case | 
|  | a breakpoint is inserted at the current PC.  If this target does | 
|  | not support internal breakpoints at all, we also report the | 
|  | SIGTRAP without further processing; it's of no concern to us.  */ | 
|  | maybe_internal_trap | 
|  | = (low_supports_breakpoints () | 
|  | && (WSTOPSIG (w) == SIGTRAP | 
|  | || ((WSTOPSIG (w) == SIGILL | 
|  | || WSTOPSIG (w) == SIGSEGV) | 
|  | && low_breakpoint_at (event_child->stop_pc)))); | 
|  |  | 
|  | if (maybe_internal_trap) | 
|  | { | 
|  | /* Handle anything that requires bookkeeping before deciding to | 
|  | report the event or continue waiting.  */ | 
|  |  | 
|  | /* First check if we can explain the SIGTRAP with an internal | 
|  | breakpoint, or if we should possibly report the event to GDB. | 
|  | Do this before anything that may remove or insert a | 
|  | breakpoint.  */ | 
|  | bp_explains_trap = breakpoint_inserted_here (event_child->stop_pc); | 
|  |  | 
|  | /* We have a SIGTRAP, possibly a step-over dance has just | 
|  | finished.  If so, tweak the state machine accordingly, | 
|  | reinsert breakpoints and delete any single-step | 
|  | breakpoints.  */ | 
|  | step_over_finished = finish_step_over (event_child); | 
|  |  | 
|  | /* Now invoke the callbacks of any internal breakpoints there.  */ | 
|  | check_breakpoints (event_child->stop_pc); | 
|  |  | 
|  | /* Handle tracepoint data collecting.  This may overflow the | 
|  | trace buffer, and cause a tracing stop, removing | 
|  | breakpoints.  */ | 
|  | trace_event = handle_tracepoints (event_child); | 
|  |  | 
|  | if (bp_explains_trap) | 
|  | threads_debug_printf ("Hit a gdbserver breakpoint."); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* We have some other signal, possibly a step-over dance was in | 
|  | progress, and it should be cancelled too.  */ | 
|  | step_over_finished = finish_step_over (event_child); | 
|  | } | 
|  |  | 
|  | /* We have all the data we need.  Either report the event to GDB, or | 
|  | resume threads and keep waiting for more.  */ | 
|  |  | 
|  | /* If we're collecting a fast tracepoint, finish the collection and | 
|  | move out of the jump pad before delivering a signal.  See | 
|  | linux_stabilize_threads.  */ | 
|  |  | 
|  | if (WIFSTOPPED (w) | 
|  | && WSTOPSIG (w) != SIGTRAP | 
|  | && supports_fast_tracepoints () | 
|  | && agent_loaded_p ()) | 
|  | { | 
|  | threads_debug_printf ("Got signal %d for LWP %ld.  Check if we need " | 
|  | "to defer or adjust it.", | 
|  | WSTOPSIG (w), current_thread->id.lwp ()); | 
|  |  | 
|  | /* Allow debugging the jump pad itself.  */ | 
|  | if (current_thread->last_resume_kind != resume_step | 
|  | && maybe_move_out_of_jump_pad (event_child, &w)) | 
|  | { | 
|  | enqueue_one_deferred_signal (event_child, &w); | 
|  |  | 
|  | threads_debug_printf ("Signal %d for LWP %ld deferred (in jump pad)", | 
|  | WSTOPSIG (w), current_thread->id.lwp ()); | 
|  |  | 
|  | resume_one_lwp (event_child, 0, 0, NULL); | 
|  |  | 
|  | return ignore_event (ourstatus); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (event_child->collecting_fast_tracepoint | 
|  | != fast_tpoint_collect_result::not_collecting) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("LWP %ld was trying to move out of the jump pad (%d). " | 
|  | "Check if we're already there.", | 
|  | current_thread->id.lwp (), | 
|  | (int) event_child->collecting_fast_tracepoint); | 
|  |  | 
|  | trace_event = 1; | 
|  |  | 
|  | event_child->collecting_fast_tracepoint | 
|  | = linux_fast_tracepoint_collecting (event_child, NULL); | 
|  |  | 
|  | if (event_child->collecting_fast_tracepoint | 
|  | != fast_tpoint_collect_result::before_insn) | 
|  | { | 
|  | /* No longer need this breakpoint.  */ | 
|  | if (event_child->exit_jump_pad_bkpt != NULL) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("No longer need exit-jump-pad bkpt; removing it." | 
|  | "stopping all threads momentarily."); | 
|  |  | 
|  | /* Other running threads could hit this breakpoint. | 
|  | We don't handle moribund locations like GDB does, | 
|  | instead we always pause all threads when removing | 
|  | breakpoints, so that any step-over or | 
|  | decr_pc_after_break adjustment is always taken | 
|  | care of while the breakpoint is still | 
|  | inserted.  */ | 
|  | stop_all_lwps (1, event_child); | 
|  |  | 
|  | delete_breakpoint (event_child->exit_jump_pad_bkpt); | 
|  | event_child->exit_jump_pad_bkpt = NULL; | 
|  |  | 
|  | unstop_all_lwps (1, event_child); | 
|  |  | 
|  | gdb_assert (event_child->suspended >= 0); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (event_child->collecting_fast_tracepoint | 
|  | == fast_tpoint_collect_result::not_collecting) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("fast tracepoint finished collecting successfully."); | 
|  |  | 
|  | /* We may have a deferred signal to report.  */ | 
|  | if (dequeue_one_deferred_signal (event_child, &w)) | 
|  | threads_debug_printf ("dequeued one signal."); | 
|  | else | 
|  | { | 
|  | threads_debug_printf ("no deferred signals."); | 
|  |  | 
|  | if (stabilizing_threads) | 
|  | { | 
|  | ourstatus->set_stopped (GDB_SIGNAL_0); | 
|  |  | 
|  | threads_debug_printf | 
|  | ("ret = %s, stopped while stabilizing threads", | 
|  | target_pid_to_str (current_thread->id).c_str ()); | 
|  |  | 
|  | return current_thread->id; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Check whether GDB would be interested in this event.  */ | 
|  |  | 
|  | /* Check if GDB is interested in this syscall.  */ | 
|  | if (WIFSTOPPED (w) | 
|  | && WSTOPSIG (w) == SYSCALL_SIGTRAP | 
|  | && !gdb_catch_this_syscall (event_child)) | 
|  | { | 
|  | threads_debug_printf ("Ignored syscall for LWP %ld.", | 
|  | current_thread->id.lwp ()); | 
|  |  | 
|  | resume_one_lwp (event_child, event_child->stepping, 0, NULL); | 
|  |  | 
|  | return ignore_event (ourstatus); | 
|  | } | 
|  |  | 
|  | /* If GDB is not interested in this signal, don't stop other | 
|  | threads, and don't report it to GDB.  Just resume the inferior | 
|  | right away.  We do this for threading-related signals as well as | 
|  | any that GDB specifically requested we ignore.  But never ignore | 
|  | SIGSTOP if we sent it ourselves, and do not ignore signals when | 
|  | stepping - they may require special handling to skip the signal | 
|  | handler. Also never ignore signals that could be caused by a | 
|  | breakpoint.  */ | 
|  | if (WIFSTOPPED (w) | 
|  | && current_thread->last_resume_kind != resume_step | 
|  | && ( | 
|  | #if defined (USE_THREAD_DB) && !defined (__ANDROID__) | 
|  | (current_process ()->priv->thread_db != NULL | 
|  | && (WSTOPSIG (w) == __SIGRTMIN | 
|  | || WSTOPSIG (w) == __SIGRTMIN + 1)) | 
|  | || | 
|  | #endif | 
|  | (cs.pass_signals[gdb_signal_from_host (WSTOPSIG (w))] | 
|  | && !(WSTOPSIG (w) == SIGSTOP | 
|  | && current_thread->last_resume_kind == resume_stop) | 
|  | && !linux_wstatus_maybe_breakpoint (w)))) | 
|  | { | 
|  | siginfo_t info, *info_p; | 
|  |  | 
|  | threads_debug_printf ("Ignored signal %d for LWP %ld.", | 
|  | WSTOPSIG (w), current_thread->id.lwp ()); | 
|  |  | 
|  | if (ptrace (PTRACE_GETSIGINFO, current_thread->id.lwp (), | 
|  | (PTRACE_TYPE_ARG3) 0, &info) == 0) | 
|  | info_p = &info; | 
|  | else | 
|  | info_p = NULL; | 
|  |  | 
|  | if (step_over_finished) | 
|  | { | 
|  | /* We cancelled this thread's step-over above.  We still | 
|  | need to unsuspend all other LWPs, and set them back | 
|  | running again while the signal handler runs.  */ | 
|  | unsuspend_all_lwps (event_child); | 
|  |  | 
|  | /* Enqueue the pending signal info so that proceed_all_lwps | 
|  | doesn't lose it.  */ | 
|  | enqueue_pending_signal (event_child, WSTOPSIG (w), info_p); | 
|  |  | 
|  | proceed_all_lwps (); | 
|  | } | 
|  | else | 
|  | { | 
|  | resume_one_lwp (event_child, event_child->stepping, | 
|  | WSTOPSIG (w), info_p); | 
|  | } | 
|  |  | 
|  | return ignore_event (ourstatus); | 
|  | } | 
|  |  | 
|  | /* Note that all addresses are always "out of the step range" when | 
|  | there's no range to begin with.  */ | 
|  | in_step_range = lwp_in_step_range (event_child); | 
|  |  | 
|  | /* If GDB wanted this thread to single step, and the thread is out | 
|  | of the step range, we always want to report the SIGTRAP, and let | 
|  | GDB handle it.  Watchpoints should always be reported.  So should | 
|  | signals we can't explain.  A SIGTRAP we can't explain could be a | 
|  | GDB breakpoint --- we may or not support Z0 breakpoints.  If we | 
|  | do, we're be able to handle GDB breakpoints on top of internal | 
|  | breakpoints, by handling the internal breakpoint and still | 
|  | reporting the event to GDB.  If we don't, we're out of luck, GDB | 
|  | won't see the breakpoint hit.  If we see a single-step event but | 
|  | the thread should be continuing, don't pass the trap to gdb. | 
|  | That indicates that we had previously finished a single-step but | 
|  | left the single-step pending -- see | 
|  | complete_ongoing_step_over.  */ | 
|  | report_to_gdb = (!maybe_internal_trap | 
|  | || (current_thread->last_resume_kind == resume_step | 
|  | && !in_step_range) | 
|  | || event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT | 
|  | || (!in_step_range | 
|  | && !bp_explains_trap | 
|  | && !trace_event | 
|  | && !step_over_finished | 
|  | && !(current_thread->last_resume_kind == resume_continue | 
|  | && event_child->stop_reason == TARGET_STOPPED_BY_SINGLE_STEP)) | 
|  | || (gdb_breakpoint_here (event_child->stop_pc) | 
|  | && gdb_condition_true_at_breakpoint (event_child->stop_pc) | 
|  | && gdb_no_commands_at_breakpoint (event_child->stop_pc)) | 
|  | || event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE); | 
|  |  | 
|  | run_breakpoint_commands (event_child->stop_pc); | 
|  |  | 
|  | /* We found no reason GDB would want us to stop.  We either hit one | 
|  | of our own breakpoints, or finished an internal step GDB | 
|  | shouldn't know about.  */ | 
|  | if (!report_to_gdb) | 
|  | { | 
|  | if (bp_explains_trap) | 
|  | threads_debug_printf ("Hit a gdbserver breakpoint."); | 
|  |  | 
|  | if (step_over_finished) | 
|  | threads_debug_printf ("Step-over finished."); | 
|  |  | 
|  | if (trace_event) | 
|  | threads_debug_printf ("Tracepoint event."); | 
|  |  | 
|  | if (lwp_in_step_range (event_child)) | 
|  | threads_debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).", | 
|  | paddress (event_child->stop_pc), | 
|  | paddress (event_child->step_range_start), | 
|  | paddress (event_child->step_range_end)); | 
|  |  | 
|  | /* We're not reporting this breakpoint to GDB, so apply the | 
|  | decr_pc_after_break adjustment to the inferior's regcache | 
|  | ourselves.  */ | 
|  |  | 
|  | if (low_supports_breakpoints ()) | 
|  | { | 
|  | struct regcache *regcache | 
|  | = get_thread_regcache (current_thread); | 
|  | low_set_pc (regcache, event_child->stop_pc); | 
|  | } | 
|  |  | 
|  | if (step_over_finished) | 
|  | { | 
|  | /* If we have finished stepping over a breakpoint, we've | 
|  | stopped and suspended all LWPs momentarily except the | 
|  | stepping one.  This is where we resume them all again. | 
|  | We're going to keep waiting, so use proceed, which | 
|  | handles stepping over the next breakpoint.  */ | 
|  | unsuspend_all_lwps (event_child); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Remove the single-step breakpoints if any.  Note that | 
|  | there isn't single-step breakpoint if we finished stepping | 
|  | over.  */ | 
|  | if (supports_software_single_step () | 
|  | && has_single_step_breakpoints (current_thread)) | 
|  | { | 
|  | stop_all_lwps (0, event_child); | 
|  | delete_single_step_breakpoints (current_thread); | 
|  | unstop_all_lwps (0, event_child); | 
|  | } | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("proceeding all threads."); | 
|  |  | 
|  | proceed_all_lwps (); | 
|  |  | 
|  | return ignore_event (ourstatus); | 
|  | } | 
|  |  | 
|  | if (debug_threads) | 
|  | { | 
|  | if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE) | 
|  | threads_debug_printf ("LWP %ld: extended event with waitstatus %s", | 
|  | event_child->thread->id.lwp (), | 
|  | event_child->waitstatus.to_string ().c_str ()); | 
|  |  | 
|  | if (current_thread->last_resume_kind == resume_step) | 
|  | { | 
|  | if (event_child->step_range_start == event_child->step_range_end) | 
|  | threads_debug_printf | 
|  | ("GDB wanted to single-step, reporting event."); | 
|  | else if (!lwp_in_step_range (event_child)) | 
|  | threads_debug_printf ("Out of step range, reporting event."); | 
|  | } | 
|  |  | 
|  | if (event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT) | 
|  | threads_debug_printf ("Stopped by watchpoint."); | 
|  | else if (gdb_breakpoint_here (event_child->stop_pc)) | 
|  | threads_debug_printf ("Stopped by GDB breakpoint."); | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("Hit a non-gdbserver trap event."); | 
|  |  | 
|  | /* Alright, we're going to report a stop.  */ | 
|  |  | 
|  | /* Remove single-step breakpoints.  */ | 
|  | if (supports_software_single_step ()) | 
|  | { | 
|  | /* Remove single-step breakpoints or not.  It it is true, stop all | 
|  | lwps, so that other threads won't hit the breakpoint in the | 
|  | staled memory.  */ | 
|  | int remove_single_step_breakpoints_p = 0; | 
|  |  | 
|  | if (non_stop) | 
|  | { | 
|  | remove_single_step_breakpoints_p | 
|  | = has_single_step_breakpoints (current_thread); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* In all-stop, a stop reply cancels all previous resume | 
|  | requests.  Delete all single-step breakpoints.  */ | 
|  |  | 
|  | find_thread ([&] (thread_info *thread) { | 
|  | if (has_single_step_breakpoints (thread)) | 
|  | { | 
|  | remove_single_step_breakpoints_p = 1; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | return false; | 
|  | }); | 
|  | } | 
|  |  | 
|  | if (remove_single_step_breakpoints_p) | 
|  | { | 
|  | /* If we remove single-step breakpoints from memory, stop all lwps, | 
|  | so that other threads won't hit the breakpoint in the staled | 
|  | memory.  */ | 
|  | stop_all_lwps (0, event_child); | 
|  |  | 
|  | if (non_stop) | 
|  | { | 
|  | gdb_assert (has_single_step_breakpoints (current_thread)); | 
|  | delete_single_step_breakpoints (current_thread); | 
|  | } | 
|  | else | 
|  | { | 
|  | for_each_thread ([] (thread_info *thread){ | 
|  | if (has_single_step_breakpoints (thread)) | 
|  | delete_single_step_breakpoints (thread); | 
|  | }); | 
|  | } | 
|  |  | 
|  | unstop_all_lwps (0, event_child); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!stabilizing_threads) | 
|  | { | 
|  | /* In all-stop, stop all threads.  */ | 
|  | if (!non_stop) | 
|  | stop_all_lwps (0, NULL); | 
|  |  | 
|  | if (step_over_finished) | 
|  | { | 
|  | if (!non_stop) | 
|  | { | 
|  | /* If we were doing a step-over, all other threads but | 
|  | the stepping one had been paused in start_step_over, | 
|  | with their suspend counts incremented.  We don't want | 
|  | to do a full unstop/unpause, because we're in | 
|  | all-stop mode (so we want threads stopped), but we | 
|  | still need to unsuspend the other threads, to | 
|  | decrement their `suspended' count back.  */ | 
|  | unsuspend_all_lwps (event_child); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* If we just finished a step-over, then all threads had | 
|  | been momentarily paused.  In all-stop, that's fine, | 
|  | we want threads stopped by now anyway.  In non-stop, | 
|  | we need to re-resume threads that GDB wanted to be | 
|  | running.  */ | 
|  | unstop_all_lwps (1, event_child); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If we're not waiting for a specific LWP, choose an event LWP | 
|  | from among those that have had events.  Giving equal priority | 
|  | to all LWPs that have had events helps prevent | 
|  | starvation.  */ | 
|  | if (ptid == minus_one_ptid) | 
|  | { | 
|  | event_child->status_pending_p = 1; | 
|  | event_child->status_pending = w; | 
|  |  | 
|  | select_event_lwp (&event_child); | 
|  |  | 
|  | /* current_thread and event_child must stay in sync.  */ | 
|  | switch_to_thread (event_child->thread); | 
|  |  | 
|  | event_child->status_pending_p = 0; | 
|  | w = event_child->status_pending; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Stabilize threads (move out of jump pads).  */ | 
|  | if (!non_stop) | 
|  | target_stabilize_threads (); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* If we just finished a step-over, then all threads had been | 
|  | momentarily paused.  In all-stop, that's fine, we want | 
|  | threads stopped by now anyway.  In non-stop, we need to | 
|  | re-resume threads that GDB wanted to be running.  */ | 
|  | if (step_over_finished) | 
|  | unstop_all_lwps (1, event_child); | 
|  | } | 
|  |  | 
|  | /* At this point, we haven't set OURSTATUS.  This is where we do it.  */ | 
|  | gdb_assert (ourstatus->kind () == TARGET_WAITKIND_IGNORE); | 
|  |  | 
|  | if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE) | 
|  | { | 
|  | /* If the reported event is an exit, fork, vfork, clone or exec, | 
|  | let GDB know.  */ | 
|  |  | 
|  | /* Break the unreported fork/vfork/clone relationship chain.  */ | 
|  | if (is_new_child_status (event_child->waitstatus.kind ())) | 
|  | { | 
|  | event_child->relative->relative = NULL; | 
|  | event_child->relative = NULL; | 
|  | } | 
|  |  | 
|  | *ourstatus = event_child->waitstatus; | 
|  | /* Clear the event lwp's waitstatus since we handled it already.  */ | 
|  | event_child->waitstatus.set_ignore (); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* The LWP stopped due to a plain signal or a syscall signal.  Either way, | 
|  | event_child->waitstatus wasn't filled in with the details, so look at | 
|  | the wait status W.  */ | 
|  | if (WSTOPSIG (w) == SYSCALL_SIGTRAP) | 
|  | { | 
|  | int syscall_number; | 
|  |  | 
|  | get_syscall_trapinfo (event_child, &syscall_number); | 
|  | if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY) | 
|  | ourstatus->set_syscall_entry (syscall_number); | 
|  | else if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN) | 
|  | ourstatus->set_syscall_return (syscall_number); | 
|  | else | 
|  | gdb_assert_not_reached ("unexpected syscall state"); | 
|  | } | 
|  | else if (current_thread->last_resume_kind == resume_stop | 
|  | && WSTOPSIG (w) == SIGSTOP) | 
|  | { | 
|  | /* A thread that has been requested to stop by GDB with vCont;t, | 
|  | and it stopped cleanly, so report as SIG0.  The use of | 
|  | SIGSTOP is an implementation detail.  */ | 
|  | ourstatus->set_stopped (GDB_SIGNAL_0); | 
|  | } | 
|  | else | 
|  | ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w))); | 
|  | } | 
|  |  | 
|  | /* Now that we've selected our final event LWP, un-adjust its PC if | 
|  | it was a software breakpoint, and the client doesn't know we can | 
|  | adjust the breakpoint ourselves.  */ | 
|  | if (event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT | 
|  | && !cs.swbreak_feature) | 
|  | { | 
|  | int decr_pc = low_decr_pc_after_break (); | 
|  |  | 
|  | if (decr_pc != 0) | 
|  | { | 
|  | struct regcache *regcache | 
|  | = get_thread_regcache (current_thread); | 
|  | low_set_pc (regcache, event_child->stop_pc + decr_pc); | 
|  | } | 
|  | } | 
|  |  | 
|  | gdb_assert (step_over_bkpt == null_ptid); | 
|  |  | 
|  | threads_debug_printf ("ret = %s, %s", | 
|  | target_pid_to_str (current_thread->id).c_str (), | 
|  | ourstatus->to_string ().c_str ()); | 
|  |  | 
|  | return filter_exit_event (event_child, ourstatus); | 
|  | } | 
|  |  | 
|  | /* Get rid of any pending event in the pipe.  */ | 
|  | static void | 
|  | async_file_flush (void) | 
|  | { | 
|  | linux_event_pipe.flush (); | 
|  | } | 
|  |  | 
|  | /* Put something in the pipe, so the event loop wakes up.  */ | 
|  | static void | 
|  | async_file_mark (void) | 
|  | { | 
|  | linux_event_pipe.mark (); | 
|  | } | 
|  |  | 
|  | ptid_t | 
|  | linux_process_target::wait (ptid_t ptid, | 
|  | target_waitstatus *ourstatus, | 
|  | target_wait_flags target_options) | 
|  | { | 
|  | ptid_t event_ptid; | 
|  |  | 
|  | /* Flush the async file first.  */ | 
|  | if (target_is_async_p ()) | 
|  | async_file_flush (); | 
|  |  | 
|  | do | 
|  | { | 
|  | event_ptid = wait_1 (ptid, ourstatus, target_options); | 
|  | } | 
|  | while ((target_options & TARGET_WNOHANG) == 0 | 
|  | && ourstatus->kind () == TARGET_WAITKIND_IGNORE); | 
|  |  | 
|  | /* If at least one stop was reported, there may be more.  A single | 
|  | SIGCHLD can signal more than one child stop.  */ | 
|  | if (target_is_async_p () | 
|  | && (target_options & TARGET_WNOHANG) != 0 | 
|  | && event_ptid != null_ptid) | 
|  | async_file_mark (); | 
|  |  | 
|  | return event_ptid; | 
|  | } | 
|  |  | 
|  | /* Send a signal to an LWP.  */ | 
|  |  | 
|  | static int | 
|  | kill_lwp (unsigned long lwpid, int signo) | 
|  | { | 
|  | int ret; | 
|  |  | 
|  | errno = 0; | 
|  | ret = syscall (__NR_tkill, lwpid, signo); | 
|  | if (errno == ENOSYS) | 
|  | { | 
|  | /* If tkill fails, then we are not using nptl threads, a | 
|  | configuration we no longer support.  */ | 
|  | perror_with_name (("tkill")); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_stop_lwp (struct lwp_info *lwp) | 
|  | { | 
|  | send_sigstop (lwp); | 
|  | } | 
|  |  | 
|  | static void | 
|  | send_sigstop (struct lwp_info *lwp) | 
|  | { | 
|  | int pid = lwp->thread->id.lwp (); | 
|  |  | 
|  | /* If we already have a pending stop signal for this process, don't | 
|  | send another.  */ | 
|  | if (lwp->stop_expected) | 
|  | { | 
|  | threads_debug_printf ("Have pending sigstop for lwp %d", pid); | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("Sending sigstop to lwp %d", pid); | 
|  |  | 
|  | lwp->stop_expected = 1; | 
|  | kill_lwp (pid, SIGSTOP); | 
|  | } | 
|  |  | 
|  | static void | 
|  | send_sigstop (thread_info *thread, lwp_info *except) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | /* Ignore EXCEPT.  */ | 
|  | if (lwp == except) | 
|  | return; | 
|  |  | 
|  | if (lwp->stopped) | 
|  | return; | 
|  |  | 
|  | send_sigstop (lwp); | 
|  | } | 
|  |  | 
|  | /* Increment the suspend count of an LWP, and stop it, if not stopped | 
|  | yet.  */ | 
|  | static void | 
|  | suspend_and_send_sigstop (thread_info *thread, lwp_info *except) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | /* Ignore EXCEPT.  */ | 
|  | if (lwp == except) | 
|  | return; | 
|  |  | 
|  | lwp_suspended_inc (lwp); | 
|  |  | 
|  | send_sigstop (thread, except); | 
|  | } | 
|  |  | 
|  | /* Mark LWP dead, with WSTAT as exit status pending to report later. | 
|  | If THREAD_EVENT is true, interpret WSTAT as a thread exit event | 
|  | instead of a process exit event.  This is meaningful for the leader | 
|  | thread, as we normally report a process-wide exit event when we see | 
|  | the leader exit, and a thread exit event when we see any other | 
|  | thread exit.  */ | 
|  |  | 
|  | static void | 
|  | mark_lwp_dead (struct lwp_info *lwp, int wstat, bool thread_event) | 
|  | { | 
|  | /* Store the exit status for later.  */ | 
|  | lwp->status_pending_p = 1; | 
|  | lwp->status_pending = wstat; | 
|  |  | 
|  | /* Store in waitstatus as well, as there's nothing else to process | 
|  | for this event.  */ | 
|  | if (WIFEXITED (wstat)) | 
|  | { | 
|  | if (thread_event) | 
|  | lwp->waitstatus.set_thread_exited (WEXITSTATUS (wstat)); | 
|  | else | 
|  | lwp->waitstatus.set_exited (WEXITSTATUS (wstat)); | 
|  | } | 
|  | else if (WIFSIGNALED (wstat)) | 
|  | { | 
|  | gdb_assert (!thread_event); | 
|  | lwp->waitstatus.set_signalled (gdb_signal_from_host (WTERMSIG (wstat))); | 
|  | } | 
|  | else | 
|  | gdb_assert_not_reached ("unknown status kind"); | 
|  |  | 
|  | /* Prevent trying to stop it.  */ | 
|  | lwp->stopped = 1; | 
|  |  | 
|  | /* No further stops are expected from a dead lwp.  */ | 
|  | lwp->stop_expected = 0; | 
|  | } | 
|  |  | 
|  | /* Return true if LWP has exited already, and has a pending exit event | 
|  | to report to GDB.  */ | 
|  |  | 
|  | static int | 
|  | lwp_is_marked_dead (struct lwp_info *lwp) | 
|  | { | 
|  | return (lwp->status_pending_p | 
|  | && (WIFEXITED (lwp->status_pending) | 
|  | || WIFSIGNALED (lwp->status_pending))); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::wait_for_sigstop () | 
|  | { | 
|  | thread_info *saved_thread; | 
|  | ptid_t saved_tid; | 
|  | int wstat; | 
|  | int ret; | 
|  |  | 
|  | saved_thread = current_thread; | 
|  | if (saved_thread != NULL) | 
|  | saved_tid = saved_thread->id; | 
|  | else | 
|  | saved_tid = null_ptid; /* avoid bogus unused warning */ | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  |  | 
|  | threads_debug_printf ("pulling events"); | 
|  |  | 
|  | /* Passing NULL_PTID as filter indicates we want all events to be | 
|  | left pending.  Eventually this returns when there are no | 
|  | unwaited-for children left.  */ | 
|  | ret = wait_for_event_filtered (minus_one_ptid, null_ptid, &wstat, __WALL); | 
|  | gdb_assert (ret == -1); | 
|  |  | 
|  | if (saved_thread == NULL || mythread_alive (saved_tid)) | 
|  | return; | 
|  | else | 
|  | { | 
|  | threads_debug_printf ("Previously current thread died."); | 
|  |  | 
|  | /* We can't change the current inferior behind GDB's back, | 
|  | otherwise, a subsequent command may apply to the wrong | 
|  | process.  */ | 
|  | restore_thread.dont_restore (); | 
|  | switch_to_thread (nullptr); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::stuck_in_jump_pad (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | if (lwp->suspended != 0) | 
|  | { | 
|  | internal_error ("LWP %ld is suspended, suspended=%d\n", | 
|  | thread->id.lwp (), lwp->suspended); | 
|  | } | 
|  | gdb_assert (lwp->stopped); | 
|  |  | 
|  | /* Allow debugging the jump pad, gdb_collect, etc..  */ | 
|  | return (supports_fast_tracepoints () | 
|  | && agent_loaded_p () | 
|  | && (gdb_breakpoint_here (lwp->stop_pc) | 
|  | || lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT | 
|  | || thread->last_resume_kind == resume_step) | 
|  | && (linux_fast_tracepoint_collecting (lwp, NULL) | 
|  | != fast_tpoint_collect_result::not_collecting)); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::move_out_of_jump_pad (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  | int *wstat; | 
|  |  | 
|  | if (lwp->suspended != 0) | 
|  | { | 
|  | internal_error ("LWP %ld is suspended, suspended=%d\n", | 
|  | thread->id.lwp (), lwp->suspended); | 
|  | } | 
|  | gdb_assert (lwp->stopped); | 
|  |  | 
|  | /* For gdb_breakpoint_here.  */ | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (thread); | 
|  |  | 
|  | wstat = lwp->status_pending_p ? &lwp->status_pending : NULL; | 
|  |  | 
|  | /* Allow debugging the jump pad, gdb_collect, etc.  */ | 
|  | if (!gdb_breakpoint_here (lwp->stop_pc) | 
|  | && lwp->stop_reason != TARGET_STOPPED_BY_WATCHPOINT | 
|  | && thread->last_resume_kind != resume_step | 
|  | && maybe_move_out_of_jump_pad (lwp, wstat)) | 
|  | { | 
|  | threads_debug_printf ("LWP %ld needs stabilizing (in jump pad)", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | if (wstat) | 
|  | { | 
|  | lwp->status_pending_p = 0; | 
|  | enqueue_one_deferred_signal (lwp, wstat); | 
|  |  | 
|  | threads_debug_printf ("Signal %d for LWP %ld deferred (in jump pad", | 
|  | WSTOPSIG (*wstat), thread->id.lwp ()); | 
|  | } | 
|  |  | 
|  | resume_one_lwp (lwp, 0, 0, NULL); | 
|  | } | 
|  | else | 
|  | lwp_suspended_inc (lwp); | 
|  | } | 
|  |  | 
|  | static bool | 
|  | lwp_running (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | if (lwp_is_marked_dead (lwp)) | 
|  | return false; | 
|  |  | 
|  | return !lwp->stopped; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::stop_all_lwps (int suspend, lwp_info *except) | 
|  | { | 
|  | /* Should not be called recursively.  */ | 
|  | gdb_assert (stopping_threads == NOT_STOPPING_THREADS); | 
|  |  | 
|  | THREADS_SCOPED_DEBUG_ENTER_EXIT; | 
|  |  | 
|  | threads_debug_printf | 
|  | ("%s, except=%s", suspend ? "stop-and-suspend" : "stop", | 
|  | (except != NULL | 
|  | ? target_pid_to_str (except->thread->id).c_str () | 
|  | : "none")); | 
|  |  | 
|  | stopping_threads = (suspend | 
|  | ? STOPPING_AND_SUSPENDING_THREADS | 
|  | : STOPPING_THREADS); | 
|  |  | 
|  | if (suspend) | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | suspend_and_send_sigstop (thread, except); | 
|  | }); | 
|  | else | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | send_sigstop (thread, except); | 
|  | }); | 
|  |  | 
|  | wait_for_sigstop (); | 
|  | stopping_threads = NOT_STOPPING_THREADS; | 
|  |  | 
|  | threads_debug_printf ("setting stopping_threads back to !stopping"); | 
|  | } | 
|  |  | 
|  | /* Enqueue one signal in the chain of signals which need to be | 
|  | delivered to this process on next resume.  */ | 
|  |  | 
|  | static void | 
|  | enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info) | 
|  | { | 
|  | lwp->pending_signals.emplace_back (signal); | 
|  | if (info == nullptr) | 
|  | memset (&lwp->pending_signals.back ().info, 0, sizeof (siginfo_t)); | 
|  | else | 
|  | lwp->pending_signals.back ().info = *info; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::install_software_single_step_breakpoints (lwp_info *lwp) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  | regcache *regcache = get_thread_regcache (thread); | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  |  | 
|  | switch_to_thread (thread); | 
|  | std::vector<CORE_ADDR> next_pcs = low_get_next_pcs (regcache); | 
|  |  | 
|  | for (CORE_ADDR pc : next_pcs) | 
|  | set_single_step_breakpoint (pc, current_thread->id); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::single_step (lwp_info* lwp) | 
|  | { | 
|  | int step = 0; | 
|  |  | 
|  | if (supports_hardware_single_step ()) | 
|  | { | 
|  | step = 1; | 
|  | } | 
|  | else if (supports_software_single_step ()) | 
|  | { | 
|  | install_software_single_step_breakpoints (lwp); | 
|  | step = 0; | 
|  | } | 
|  | else | 
|  | threads_debug_printf ("stepping is not implemented on this target"); | 
|  |  | 
|  | return step; | 
|  | } | 
|  |  | 
|  | /* The signal can be delivered to the inferior if we are not trying to | 
|  | finish a fast tracepoint collect.  Since signal can be delivered in | 
|  | the step-over, the program may go to signal handler and trap again | 
|  | after return from the signal handler.  We can live with the spurious | 
|  | double traps.  */ | 
|  |  | 
|  | static int | 
|  | lwp_signal_can_be_delivered (struct lwp_info *lwp) | 
|  | { | 
|  | return (lwp->collecting_fast_tracepoint | 
|  | == fast_tpoint_collect_result::not_collecting); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step, | 
|  | int signal, siginfo_t *info) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  | int ptrace_request; | 
|  |  | 
|  | /* Note that target description may not be initialised | 
|  | (proc->tdesc == NULL) at this point because the program hasn't | 
|  | stopped at the first instruction yet.  It means GDBserver skips | 
|  | the extra traps from the wrapper program (see option --wrapper). | 
|  | Code in this function that requires register access should be | 
|  | guarded by proc->tdesc == NULL or something else.  */ | 
|  |  | 
|  | if (lwp->stopped == 0) | 
|  | return; | 
|  |  | 
|  | gdb_assert (lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE); | 
|  |  | 
|  | fast_tpoint_collect_result fast_tp_collecting | 
|  | = lwp->collecting_fast_tracepoint; | 
|  |  | 
|  | gdb_assert (!stabilizing_threads | 
|  | || (fast_tp_collecting | 
|  | != fast_tpoint_collect_result::not_collecting)); | 
|  |  | 
|  | /* Cancel actions that rely on GDB not changing the PC (e.g., the | 
|  | user used the "jump" command, or "set $pc = foo").  */ | 
|  | if (thread->while_stepping != NULL && lwp->stop_pc != get_pc (lwp)) | 
|  | { | 
|  | /* Collecting 'while-stepping' actions doesn't make sense | 
|  | anymore.  */ | 
|  | release_while_stepping_state_list (thread); | 
|  | } | 
|  |  | 
|  | /* If we have pending signals or status, and a new signal, enqueue the | 
|  | signal.  Also enqueue the signal if it can't be delivered to the | 
|  | inferior right now.  */ | 
|  | if (signal != 0 | 
|  | && (lwp->status_pending_p | 
|  | || !lwp->pending_signals.empty () | 
|  | || !lwp_signal_can_be_delivered (lwp))) | 
|  | { | 
|  | enqueue_pending_signal (lwp, signal, info); | 
|  |  | 
|  | /* Postpone any pending signal.  It was enqueued above.  */ | 
|  | signal = 0; | 
|  | } | 
|  |  | 
|  | if (lwp->status_pending_p) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Not resuming lwp %ld (%s, stop %s); has pending status", | 
|  | thread->id.lwp (), step ? "step" : "continue", | 
|  | lwp->stop_expected ? "expected" : "not expected"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (thread); | 
|  |  | 
|  | /* This bit needs some thinking about.  If we get a signal that | 
|  | we must report while a single-step reinsert is still pending, | 
|  | we often end up resuming the thread.  It might be better to | 
|  | (ew) allow a stack of pending events; then we could be sure that | 
|  | the reinsert happened right away and not lose any signals. | 
|  |  | 
|  | Making this stack would also shrink the window in which breakpoints are | 
|  | uninserted (see comment in linux_wait_for_lwp) but not enough for | 
|  | complete correctness, so it won't solve that problem.  It may be | 
|  | worthwhile just to solve this one, however.  */ | 
|  | if (lwp->bp_reinsert != 0) | 
|  | { | 
|  | threads_debug_printf ("  pending reinsert at 0x%s", | 
|  | paddress (lwp->bp_reinsert)); | 
|  |  | 
|  | if (supports_hardware_single_step ()) | 
|  | { | 
|  | if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting) | 
|  | { | 
|  | if (step == 0) | 
|  | warning ("BAD - reinserting but not stepping."); | 
|  | if (lwp->suspended) | 
|  | warning ("BAD - reinserting and suspended(%d).", | 
|  | lwp->suspended); | 
|  | } | 
|  | } | 
|  |  | 
|  | step = maybe_hw_step (thread); | 
|  | } | 
|  |  | 
|  | if (fast_tp_collecting == fast_tpoint_collect_result::before_insn) | 
|  | threads_debug_printf | 
|  | ("lwp %ld wants to get out of fast tracepoint jump pad " | 
|  | "(exit-jump-pad-bkpt)", thread->id.lwp ()); | 
|  |  | 
|  | else if (fast_tp_collecting == fast_tpoint_collect_result::at_insn) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("lwp %ld wants to get out of fast tracepoint jump pad single-stepping", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | if (supports_hardware_single_step ()) | 
|  | step = 1; | 
|  | else | 
|  | { | 
|  | internal_error ("moving out of jump pad single-stepping" | 
|  | " not implemented on this target"); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If we have while-stepping actions in this thread set it stepping. | 
|  | If we have a signal to deliver, it may or may not be set to | 
|  | SIG_IGN, we don't know.  Assume so, and allow collecting | 
|  | while-stepping into a signal handler.  A possible smart thing to | 
|  | do would be to set an internal breakpoint at the signal return | 
|  | address, continue, and carry on catching this while-stepping | 
|  | action only when that breakpoint is hit.  A future | 
|  | enhancement.  */ | 
|  | if (thread->while_stepping != NULL) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("lwp %ld has a while-stepping action -> forcing step.", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | step = single_step (lwp); | 
|  | } | 
|  |  | 
|  | if (thread->process ()->tdesc != nullptr && low_supports_breakpoints ()) | 
|  | { | 
|  | regcache *regcache = get_thread_regcache (current_thread); | 
|  |  | 
|  | lwp->stop_pc = low_get_pc (regcache); | 
|  |  | 
|  | threads_debug_printf ("  %s from pc 0x%lx", step ? "step" : "continue", | 
|  | (long) lwp->stop_pc); | 
|  | } | 
|  |  | 
|  | /* If we have pending signals, consume one if it can be delivered to | 
|  | the inferior.  */ | 
|  | if (!lwp->pending_signals.empty () && lwp_signal_can_be_delivered (lwp)) | 
|  | { | 
|  | const pending_signal &p_sig = lwp->pending_signals.front (); | 
|  |  | 
|  | signal = p_sig.signal; | 
|  | if (p_sig.info.si_signo != 0) | 
|  | ptrace (PTRACE_SETSIGINFO, thread->id.lwp (), (PTRACE_TYPE_ARG3) 0, | 
|  | &p_sig.info); | 
|  |  | 
|  | lwp->pending_signals.pop_front (); | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)", | 
|  | thread->id.lwp (), step ? "step" : "continue", signal, | 
|  | lwp->stop_expected ? "expected" : "not expected"); | 
|  |  | 
|  | low_prepare_to_resume (lwp); | 
|  |  | 
|  | regcache_invalidate_thread (thread); | 
|  | errno = 0; | 
|  | lwp->stepping = step; | 
|  | if (step) | 
|  | ptrace_request = PTRACE_SINGLESTEP; | 
|  | else if (gdb_catching_syscalls_p (lwp)) | 
|  | ptrace_request = PTRACE_SYSCALL; | 
|  | else | 
|  | ptrace_request = PTRACE_CONT; | 
|  | ptrace (ptrace_request, | 
|  | thread->id.lwp (), | 
|  | (PTRACE_TYPE_ARG3) 0, | 
|  | /* Coerce to a uintptr_t first to avoid potential gcc warning | 
|  | of coercing an 8 byte integer to a 4 byte pointer.  */ | 
|  | (PTRACE_TYPE_ARG4) (uintptr_t) signal); | 
|  |  | 
|  | if (errno) | 
|  | { | 
|  | int saved_errno = errno; | 
|  |  | 
|  | threads_debug_printf ("ptrace errno = %d (%s)", | 
|  | saved_errno, strerror (saved_errno)); | 
|  |  | 
|  | errno = saved_errno; | 
|  | perror_with_name ("resuming thread"); | 
|  | } | 
|  |  | 
|  | /* Successfully resumed.  Clear state that no longer makes sense, | 
|  | and mark the LWP as running.  Must not do this before resuming | 
|  | otherwise if that fails other code will be confused.  E.g., we'd | 
|  | later try to stop the LWP and hang forever waiting for a stop | 
|  | status.  Note that we must not throw after this is cleared, | 
|  | otherwise handle_zombie_lwp_error would get confused.  */ | 
|  | lwp->stopped = 0; | 
|  | lwp->stop_reason = TARGET_STOPPED_BY_NO_REASON; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_prepare_to_resume (lwp_info *lwp) | 
|  | { | 
|  | /* Nop.  */ | 
|  | } | 
|  |  | 
|  | /* Called when we try to resume a stopped LWP and that errors out.  If | 
|  | the LWP is no longer in ptrace-stopped state (meaning it's zombie, | 
|  | or about to become), discard the error, clear any pending status | 
|  | the LWP may have, and return true (we'll collect the exit status | 
|  | soon enough).  Otherwise, return false.  */ | 
|  |  | 
|  | static int | 
|  | check_ptrace_stopped_lwp_gone (struct lwp_info *lp) | 
|  | { | 
|  | thread_info *thread = lp->thread; | 
|  |  | 
|  | /* If we get an error after resuming the LWP successfully, we'd | 
|  | confuse !T state for the LWP being gone.  */ | 
|  | gdb_assert (lp->stopped); | 
|  |  | 
|  | /* We can't just check whether the LWP is in 'Z (Zombie)' state, | 
|  | because even if ptrace failed with ESRCH, the tracee may be "not | 
|  | yet fully dead", but already refusing ptrace requests.  In that | 
|  | case the tracee has 'R (Running)' state for a little bit | 
|  | (observed in Linux 3.18).  See also the note on ESRCH in the | 
|  | ptrace(2) man page.  Instead, check whether the LWP has any state | 
|  | other than ptrace-stopped.  */ | 
|  |  | 
|  | /* Don't assume anything if /proc/PID/status can't be read.  */ | 
|  | if (linux_proc_pid_is_trace_stopped_nowarn (thread->id.lwp ()) == 0) | 
|  | { | 
|  | lp->stop_reason = TARGET_STOPPED_BY_NO_REASON; | 
|  | lp->status_pending_p = 0; | 
|  | return 1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::resume_one_lwp (lwp_info *lwp, int step, int signal, | 
|  | siginfo_t *info) | 
|  | { | 
|  | try | 
|  | { | 
|  | resume_one_lwp_throw (lwp, step, signal, info); | 
|  | } | 
|  | catch (const gdb_exception_error &ex) | 
|  | { | 
|  | if (check_ptrace_stopped_lwp_gone (lwp)) | 
|  | { | 
|  | /* This could because we tried to resume an LWP after its leader | 
|  | exited.  Mark it as resumed, so we can collect an exit event | 
|  | from it.  */ | 
|  | lwp->stopped = 0; | 
|  | lwp->stop_reason = TARGET_STOPPED_BY_NO_REASON; | 
|  | } | 
|  | else | 
|  | throw; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* This function is called once per thread via for_each_thread. | 
|  | We look up which resume request applies to THREAD and mark it with a | 
|  | pointer to the appropriate resume request. | 
|  |  | 
|  | This algorithm is O(threads * resume elements), but resume elements | 
|  | is small (and will remain small at least until GDB supports thread | 
|  | suspension).  */ | 
|  |  | 
|  | static void | 
|  | linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | for (int ndx = 0; ndx < n; ndx++) | 
|  | { | 
|  | ptid_t ptid = resume[ndx].thread; | 
|  | if (ptid == minus_one_ptid | 
|  | || ptid == thread->id | 
|  | /* Handle both 'pPID' and 'pPID.-1' as meaning 'all threads | 
|  | of PID'.  */ | 
|  | || (ptid.pid () == thread->id.pid () | 
|  | && (ptid.is_pid () | 
|  | || ptid.lwp () == -1))) | 
|  | { | 
|  | if (resume[ndx].kind == resume_stop | 
|  | && thread->last_resume_kind == resume_stop) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("already %s LWP %ld at GDB's request", | 
|  | (thread->last_status.kind () == TARGET_WAITKIND_STOPPED | 
|  | ? "stopped" : "stopping"), | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* Ignore (wildcard) resume requests for already-resumed | 
|  | threads.  */ | 
|  | if (resume[ndx].kind != resume_stop | 
|  | && thread->last_resume_kind != resume_stop) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("already %s LWP %ld at GDB's request", | 
|  | (thread->last_resume_kind == resume_step | 
|  | ? "stepping" : "continuing"), | 
|  | thread->id.lwp ()); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* Don't let wildcard resumes resume fork/vfork/clone | 
|  | children that GDB does not yet know are new children.  */ | 
|  | if (lwp->relative != NULL) | 
|  | { | 
|  | struct lwp_info *rel = lwp->relative; | 
|  |  | 
|  | if (rel->status_pending_p | 
|  | && is_new_child_status (rel->waitstatus.kind ())) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("not resuming LWP %ld: has queued stop reply", | 
|  | thread->id.lwp ()); | 
|  | continue; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If the thread has a pending event that has already been | 
|  | reported to GDBserver core, but GDB has not pulled the | 
|  | event out of the vStopped queue yet, likewise, ignore the | 
|  | (wildcard) resume request.  */ | 
|  | if (in_queued_stop_replies (thread->id)) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("not resuming LWP %ld: has queued stop reply", | 
|  | thread->id.lwp ()); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | lwp->resume = &resume[ndx]; | 
|  | thread->last_resume_kind = lwp->resume->kind; | 
|  |  | 
|  | lwp->step_range_start = lwp->resume->step_range_start; | 
|  | lwp->step_range_end = lwp->resume->step_range_end; | 
|  |  | 
|  | /* If we had a deferred signal to report, dequeue one now. | 
|  | This can happen if LWP gets more than one signal while | 
|  | trying to get out of a jump pad.  */ | 
|  | if (lwp->stopped | 
|  | && !lwp->status_pending_p | 
|  | && dequeue_one_deferred_signal (lwp, &lwp->status_pending)) | 
|  | { | 
|  | lwp->status_pending_p = 1; | 
|  |  | 
|  | threads_debug_printf | 
|  | ("Dequeueing deferred signal %d for LWP %ld, " | 
|  | "leaving status pending.", | 
|  | WSTOPSIG (lwp->status_pending), | 
|  | thread->id.lwp ()); | 
|  | } | 
|  |  | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* No resume action for this thread.  */ | 
|  | lwp->resume = NULL; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::resume_status_pending (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | /* LWPs which will not be resumed are not interesting, because | 
|  | we might not wait for them next time through linux_wait.  */ | 
|  | if (lwp->resume == NULL) | 
|  | return false; | 
|  |  | 
|  | return thread_still_has_status_pending (thread); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::thread_needs_step_over (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  | CORE_ADDR pc; | 
|  |  | 
|  | /* GDBserver is skipping the extra traps from the wrapper program, | 
|  | don't have to do step over.  */ | 
|  | if (thread->process ()->tdesc == nullptr) | 
|  | return false; | 
|  |  | 
|  | /* LWPs which will not be resumed are not interesting, because we | 
|  | might not wait for them next time through linux_wait.  */ | 
|  |  | 
|  | if (!lwp->stopped) | 
|  | { | 
|  | threads_debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped", | 
|  | thread->id.lwp ()); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | if (thread->last_resume_kind == resume_stop) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Need step over [LWP %ld]? Ignoring, should remain stopped", | 
|  | thread->id.lwp ()); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | gdb_assert (lwp->suspended >= 0); | 
|  |  | 
|  | if (lwp->suspended) | 
|  | { | 
|  | threads_debug_printf ("Need step over [LWP %ld]? Ignoring, suspended", | 
|  | thread->id.lwp ()); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | if (lwp->status_pending_p) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Need step over [LWP %ld]? Ignoring, has pending status.", | 
|  | thread->id.lwp ()); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* Note: PC, not STOP_PC.  Either GDB has adjusted the PC already, | 
|  | or we have.  */ | 
|  | pc = get_pc (lwp); | 
|  |  | 
|  | /* If the PC has changed since we stopped, then don't do anything, | 
|  | and let the breakpoint/tracepoint be hit.  This happens if, for | 
|  | instance, GDB handled the decr_pc_after_break subtraction itself, | 
|  | GDB is OOL stepping this thread, or the user has issued a "jump" | 
|  | command, or poked thread's registers herself.  */ | 
|  | if (pc != lwp->stop_pc) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Need step over [LWP %ld]? Cancelling, PC was changed. " | 
|  | "Old stop_pc was 0x%s, PC is now 0x%s", thread->id.lwp (), | 
|  | paddress (lwp->stop_pc), paddress (pc)); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* On software single step target, resume the inferior with signal | 
|  | rather than stepping over.  */ | 
|  | if (supports_software_single_step () | 
|  | && !lwp->pending_signals.empty () | 
|  | && lwp_signal_can_be_delivered (lwp)) | 
|  | { | 
|  | threads_debug_printf | 
|  | ("Need step over [LWP %ld]? Ignoring, has pending signals.", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (thread); | 
|  |  | 
|  | /* We can only step over breakpoints we know about.  */ | 
|  | if (breakpoint_here (pc) || fast_tracepoint_jump_here (pc)) | 
|  | { | 
|  | /* Don't step over a breakpoint that GDB expects to hit | 
|  | though.  If the condition is being evaluated on the target's side | 
|  | and it evaluate to false, step over this breakpoint as well.  */ | 
|  | if (gdb_breakpoint_here (pc) | 
|  | && gdb_condition_true_at_breakpoint (pc) | 
|  | && gdb_no_commands_at_breakpoint (pc)) | 
|  | { | 
|  | threads_debug_printf ("Need step over [LWP %ld]? yes, but found" | 
|  | " GDB breakpoint at 0x%s; skipping step over", | 
|  | thread->id.lwp (), paddress (pc)); | 
|  |  | 
|  | return false; | 
|  | } | 
|  | else | 
|  | { | 
|  | threads_debug_printf ("Need step over [LWP %ld]? yes, " | 
|  | "found breakpoint at 0x%s", | 
|  | thread->id.lwp (), paddress (pc)); | 
|  |  | 
|  | /* We've found an lwp that needs stepping over --- return 1 so | 
|  | that find_thread stops looking.  */ | 
|  | return true; | 
|  | } | 
|  | } | 
|  |  | 
|  | threads_debug_printf | 
|  | ("Need step over [LWP %ld]? No, no breakpoint found at 0x%s", | 
|  | thread->id.lwp (), paddress (pc)); | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::start_step_over (lwp_info *lwp) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  | CORE_ADDR pc; | 
|  |  | 
|  | threads_debug_printf ("Starting step-over on LWP %ld.  Stopping all threads", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | stop_all_lwps (1, lwp); | 
|  |  | 
|  | if (lwp->suspended != 0) | 
|  | { | 
|  | internal_error ("LWP %ld suspended=%d\n", thread->id.lwp (), | 
|  | lwp->suspended); | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("Done stopping all threads for step-over."); | 
|  |  | 
|  | /* Note, we should always reach here with an already adjusted PC, | 
|  | either by GDB (if we're resuming due to GDB's request), or by our | 
|  | caller, if we just finished handling an internal breakpoint GDB | 
|  | shouldn't care about.  */ | 
|  | pc = get_pc (lwp); | 
|  |  | 
|  | bool step = false; | 
|  | { | 
|  | scoped_restore_current_thread restore_thread; | 
|  | switch_to_thread (thread); | 
|  |  | 
|  | lwp->bp_reinsert = pc; | 
|  | uninsert_breakpoints_at (pc); | 
|  | uninsert_fast_tracepoint_jumps_at (pc); | 
|  |  | 
|  | step = single_step (lwp); | 
|  | } | 
|  |  | 
|  | resume_one_lwp (lwp, step, 0, NULL); | 
|  |  | 
|  | /* Require next event from this LWP.  */ | 
|  | step_over_bkpt = thread->id; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::finish_step_over (lwp_info *lwp) | 
|  | { | 
|  | if (lwp->bp_reinsert != 0) | 
|  | { | 
|  | scoped_restore_current_thread restore_thread; | 
|  |  | 
|  | threads_debug_printf ("Finished step over."); | 
|  |  | 
|  | switch_to_thread (lwp->thread); | 
|  |  | 
|  | /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there | 
|  | may be no breakpoint to reinsert there by now.  */ | 
|  | reinsert_breakpoints_at (lwp->bp_reinsert); | 
|  | reinsert_fast_tracepoint_jumps_at (lwp->bp_reinsert); | 
|  |  | 
|  | lwp->bp_reinsert = 0; | 
|  |  | 
|  | /* Delete any single-step breakpoints.  No longer needed.  We | 
|  | don't have to worry about other threads hitting this trap, | 
|  | and later not being able to explain it, because we were | 
|  | stepping over a breakpoint, and we hold all threads but | 
|  | LWP stopped while doing that.  */ | 
|  | if (!supports_hardware_single_step ()) | 
|  | { | 
|  | gdb_assert (has_single_step_breakpoints (current_thread)); | 
|  | delete_single_step_breakpoints (current_thread); | 
|  | } | 
|  |  | 
|  | step_over_bkpt = null_ptid; | 
|  | return true; | 
|  | } | 
|  | else | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::complete_ongoing_step_over () | 
|  | { | 
|  | if (step_over_bkpt != null_ptid) | 
|  | { | 
|  | struct lwp_info *lwp; | 
|  | int wstat; | 
|  | int ret; | 
|  |  | 
|  | threads_debug_printf ("detach: step over in progress, finish it first"); | 
|  |  | 
|  | /* Passing NULL_PTID as filter indicates we want all events to | 
|  | be left pending.  Eventually this returns when there are no | 
|  | unwaited-for children left.  */ | 
|  | ret = wait_for_event_filtered (minus_one_ptid, null_ptid, &wstat, | 
|  | __WALL); | 
|  | gdb_assert (ret == -1); | 
|  |  | 
|  | lwp = find_lwp_pid (step_over_bkpt); | 
|  | if (lwp != NULL) | 
|  | { | 
|  | finish_step_over (lwp); | 
|  |  | 
|  | /* If we got our step SIGTRAP, don't leave it pending, | 
|  | otherwise we would report it to GDB as a spurious | 
|  | SIGTRAP.  */ | 
|  | gdb_assert (lwp->status_pending_p); | 
|  | if (WIFSTOPPED (lwp->status_pending) | 
|  | && WSTOPSIG (lwp->status_pending) == SIGTRAP) | 
|  | { | 
|  | thread_info *thread = lwp->thread; | 
|  | if (thread->last_resume_kind != resume_step) | 
|  | { | 
|  | threads_debug_printf ("detach: discard step-over SIGTRAP"); | 
|  |  | 
|  | lwp->status_pending_p = 0; | 
|  | lwp->status_pending = 0; | 
|  | resume_one_lwp (lwp, lwp->stepping, 0, NULL); | 
|  | } | 
|  | else | 
|  | threads_debug_printf | 
|  | ("detach: resume_step, not discarding step-over SIGTRAP"); | 
|  | } | 
|  | } | 
|  | step_over_bkpt = null_ptid; | 
|  | unsuspend_all_lwps (lwp); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::resume_one_thread (thread_info *thread, | 
|  | bool leave_all_stopped) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  | int leave_pending; | 
|  |  | 
|  | if (lwp->resume == NULL) | 
|  | return; | 
|  |  | 
|  | if (lwp->resume->kind == resume_stop) | 
|  | { | 
|  | threads_debug_printf ("resume_stop request for LWP %ld", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | if (!lwp->stopped) | 
|  | { | 
|  | threads_debug_printf ("stopping LWP %ld", thread->id.lwp ()); | 
|  |  | 
|  | /* Stop the thread, and wait for the event asynchronously, | 
|  | through the event loop.  */ | 
|  | send_sigstop (lwp); | 
|  | } | 
|  | else | 
|  | { | 
|  | threads_debug_printf ("already stopped LWP %ld", thread->id.lwp ()); | 
|  |  | 
|  | /* The LWP may have been stopped in an internal event that | 
|  | was not meant to be notified back to GDB (e.g., gdbserver | 
|  | breakpoint), so we should be reporting a stop event in | 
|  | this case too.  */ | 
|  |  | 
|  | /* If the thread already has a pending SIGSTOP, this is a | 
|  | no-op.  Otherwise, something later will presumably resume | 
|  | the thread and this will cause it to cancel any pending | 
|  | operation, due to last_resume_kind == resume_stop.  If | 
|  | the thread already has a pending status to report, we | 
|  | will still report it the next time we wait - see | 
|  | status_pending_p_callback.  */ | 
|  |  | 
|  | /* If we already have a pending signal to report, then | 
|  | there's no need to queue a SIGSTOP, as this means we're | 
|  | midway through moving the LWP out of the jumppad, and we | 
|  | will report the pending signal as soon as that is | 
|  | finished.  */ | 
|  | if (lwp->pending_signals_to_report.empty ()) | 
|  | send_sigstop (lwp); | 
|  | } | 
|  |  | 
|  | /* For stop requests, we're done.  */ | 
|  | lwp->resume = NULL; | 
|  | thread->last_status.set_ignore (); | 
|  | return; | 
|  | } | 
|  |  | 
|  | /* If this thread which is about to be resumed has a pending status, | 
|  | then don't resume it - we can just report the pending status. | 
|  | Likewise if it is suspended, because e.g., another thread is | 
|  | stepping past a breakpoint.  Make sure to queue any signals that | 
|  | would otherwise be sent.  In all-stop mode, we do this decision | 
|  | based on if *any* thread has a pending status.  If there's a | 
|  | thread that needs the step-over-breakpoint dance, then don't | 
|  | resume any other thread but that particular one.  */ | 
|  | leave_pending = (lwp->suspended | 
|  | || lwp->status_pending_p | 
|  | || leave_all_stopped); | 
|  |  | 
|  | /* If we have a new signal, enqueue the signal.  */ | 
|  | if (lwp->resume->sig != 0) | 
|  | { | 
|  | siginfo_t info, *info_p; | 
|  |  | 
|  | /* If this is the same signal we were previously stopped by, | 
|  | make sure to queue its siginfo.  */ | 
|  | if (WIFSTOPPED (lwp->last_status) | 
|  | && WSTOPSIG (lwp->last_status) == lwp->resume->sig | 
|  | && ptrace (PTRACE_GETSIGINFO, thread->id.lwp (), | 
|  | (PTRACE_TYPE_ARG3) 0, &info) == 0) | 
|  | info_p = &info; | 
|  | else | 
|  | info_p = NULL; | 
|  |  | 
|  | enqueue_pending_signal (lwp, lwp->resume->sig, info_p); | 
|  | } | 
|  |  | 
|  | if (!leave_pending) | 
|  | { | 
|  | threads_debug_printf ("resuming LWP %ld", thread->id.lwp ()); | 
|  |  | 
|  | proceed_one_lwp (thread, NULL); | 
|  | } | 
|  | else | 
|  | threads_debug_printf ("leaving LWP %ld stopped", thread->id.lwp ()); | 
|  |  | 
|  | thread->last_status.set_ignore (); | 
|  | lwp->resume = NULL; | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::resume (thread_resume *resume_info, size_t n) | 
|  | { | 
|  | thread_info *need_step_over = NULL; | 
|  |  | 
|  | THREADS_SCOPED_DEBUG_ENTER_EXIT; | 
|  |  | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | linux_set_resume_request (thread, resume_info, n); | 
|  | }); | 
|  |  | 
|  | /* If there is a thread which would otherwise be resumed, which has | 
|  | a pending status, then don't resume any threads - we can just | 
|  | report the pending status.  Make sure to queue any signals that | 
|  | would otherwise be sent.  In non-stop mode, we'll apply this | 
|  | logic to each thread individually.  We consume all pending events | 
|  | before considering to start a step-over (in all-stop).  */ | 
|  | bool any_pending = false; | 
|  | if (!non_stop) | 
|  | any_pending = find_thread ([this] (thread_info *thread) | 
|  | { | 
|  | return resume_status_pending (thread); | 
|  | }) != nullptr; | 
|  |  | 
|  | /* If there is a thread which would otherwise be resumed, which is | 
|  | stopped at a breakpoint that needs stepping over, then don't | 
|  | resume any threads - have it step over the breakpoint with all | 
|  | other threads stopped, then resume all threads again.  Make sure | 
|  | to queue any signals that would otherwise be delivered or | 
|  | queued.  */ | 
|  | if (!any_pending && low_supports_breakpoints ()) | 
|  | need_step_over = find_thread ([this] (thread_info *thread) | 
|  | { | 
|  | return thread_needs_step_over (thread); | 
|  | }); | 
|  |  | 
|  | bool leave_all_stopped = (need_step_over != NULL || any_pending); | 
|  |  | 
|  | if (need_step_over != NULL) | 
|  | threads_debug_printf ("Not resuming all, need step over"); | 
|  | else if (any_pending) | 
|  | threads_debug_printf ("Not resuming, all-stop and found " | 
|  | "an LWP with pending status"); | 
|  | else | 
|  | threads_debug_printf ("Resuming, no pending status or step over needed"); | 
|  |  | 
|  | /* Even if we're leaving threads stopped, queue all signals we'd | 
|  | otherwise deliver.  */ | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | resume_one_thread (thread, leave_all_stopped); | 
|  | }); | 
|  |  | 
|  | if (need_step_over) | 
|  | start_step_over (get_thread_lwp (need_step_over)); | 
|  |  | 
|  | /* We may have events that were pending that can/should be sent to | 
|  | the client now.  Trigger a linux_wait call.  */ | 
|  | if (target_is_async_p ()) | 
|  | async_file_mark (); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  | int step; | 
|  |  | 
|  | if (lwp == except) | 
|  | return; | 
|  |  | 
|  | threads_debug_printf ("lwp %ld", thread->id.lwp ()); | 
|  |  | 
|  | if (!lwp->stopped) | 
|  | { | 
|  | threads_debug_printf ("   LWP %ld already running", thread->id.lwp ()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (thread->last_resume_kind == resume_stop | 
|  | && thread->last_status.kind () != TARGET_WAITKIND_IGNORE) | 
|  | { | 
|  | threads_debug_printf ("   client wants LWP to remain %ld stopped", | 
|  | thread->id.lwp ()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (lwp->status_pending_p) | 
|  | { | 
|  | threads_debug_printf ("   LWP %ld has pending status, leaving stopped", | 
|  | thread->id.lwp ()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | gdb_assert (lwp->suspended >= 0); | 
|  |  | 
|  | if (lwp->suspended) | 
|  | { | 
|  | threads_debug_printf ("   LWP %ld is suspended", thread->id.lwp ()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (thread->last_resume_kind == resume_stop | 
|  | && lwp->pending_signals_to_report.empty () | 
|  | && (lwp->collecting_fast_tracepoint | 
|  | == fast_tpoint_collect_result::not_collecting)) | 
|  | { | 
|  | /* We haven't reported this LWP as stopped yet (otherwise, the | 
|  | last_status.kind check above would catch it, and we wouldn't | 
|  | reach here.  This LWP may have been momentarily paused by a | 
|  | stop_all_lwps call while handling for example, another LWP's | 
|  | step-over.  In that case, the pending expected SIGSTOP signal | 
|  | that was queued at vCont;t handling time will have already | 
|  | been consumed by wait_for_sigstop, and so we need to requeue | 
|  | another one here.  Note that if the LWP already has a SIGSTOP | 
|  | pending, this is a no-op.  */ | 
|  |  | 
|  | threads_debug_printf | 
|  | ("Client wants LWP %ld to stop.  Making sure it has a SIGSTOP pending", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | send_sigstop (lwp); | 
|  | } | 
|  |  | 
|  | if (thread->last_resume_kind == resume_step) | 
|  | { | 
|  | threads_debug_printf ("   stepping LWP %ld, client wants it stepping", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | /* If resume_step is requested by GDB, install single-step | 
|  | breakpoints when the thread is about to be actually resumed if | 
|  | the single-step breakpoints weren't removed.  */ | 
|  | if (supports_software_single_step () | 
|  | && !has_single_step_breakpoints (thread)) | 
|  | install_software_single_step_breakpoints (lwp); | 
|  |  | 
|  | step = maybe_hw_step (thread); | 
|  | } | 
|  | else if (lwp->bp_reinsert != 0) | 
|  | { | 
|  | threads_debug_printf ("   stepping LWP %ld, reinsert set", | 
|  | thread->id.lwp ()); | 
|  |  | 
|  | step = maybe_hw_step (thread); | 
|  | } | 
|  | else | 
|  | step = 0; | 
|  |  | 
|  | resume_one_lwp (lwp, step, 0, NULL); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::unsuspend_and_proceed_one_lwp (thread_info *thread, | 
|  | lwp_info *except) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | if (lwp == except) | 
|  | return; | 
|  |  | 
|  | lwp_suspended_decr (lwp); | 
|  |  | 
|  | proceed_one_lwp (thread, except); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::proceed_all_lwps () | 
|  | { | 
|  | thread_info *need_step_over; | 
|  |  | 
|  | /* If there is a thread which would otherwise be resumed, which is | 
|  | stopped at a breakpoint that needs stepping over, then don't | 
|  | resume any threads - have it step over the breakpoint with all | 
|  | other threads stopped, then resume all threads again.  */ | 
|  |  | 
|  | if (low_supports_breakpoints ()) | 
|  | { | 
|  | need_step_over = find_thread ([this] (thread_info *thread) | 
|  | { | 
|  | return thread_needs_step_over (thread); | 
|  | }); | 
|  |  | 
|  | if (need_step_over != NULL) | 
|  | { | 
|  | threads_debug_printf ("found thread %ld needing a step-over", | 
|  | need_step_over->id.lwp ()); | 
|  |  | 
|  | start_step_over (get_thread_lwp (need_step_over)); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | threads_debug_printf ("Proceeding, no step-over needed"); | 
|  |  | 
|  | for_each_thread ([this] (thread_info *thread) | 
|  | { | 
|  | proceed_one_lwp (thread, NULL); | 
|  | }); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::unstop_all_lwps (int unsuspend, lwp_info *except) | 
|  | { | 
|  | THREADS_SCOPED_DEBUG_ENTER_EXIT; | 
|  |  | 
|  | if (except) | 
|  | threads_debug_printf ("except=(LWP %ld)", except->thread->id.lwp ()); | 
|  | else | 
|  | threads_debug_printf ("except=nullptr"); | 
|  |  | 
|  | if (unsuspend) | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | unsuspend_and_proceed_one_lwp (thread, except); | 
|  | }); | 
|  | else | 
|  | for_each_thread ([&] (thread_info *thread) | 
|  | { | 
|  | proceed_one_lwp (thread, except); | 
|  | }); | 
|  | } | 
|  |  | 
|  |  | 
|  | #ifdef HAVE_LINUX_REGSETS | 
|  |  | 
|  | #define use_linux_regsets 1 | 
|  |  | 
|  | /* Returns true if REGSET has been disabled.  */ | 
|  |  | 
|  | static int | 
|  | regset_disabled (struct regsets_info *info, struct regset_info *regset) | 
|  | { | 
|  | return (info->disabled_regsets != NULL | 
|  | && info->disabled_regsets[regset - info->regsets]); | 
|  | } | 
|  |  | 
|  | /* Disable REGSET.  */ | 
|  |  | 
|  | static void | 
|  | disable_regset (struct regsets_info *info, struct regset_info *regset) | 
|  | { | 
|  | int dr_offset; | 
|  |  | 
|  | dr_offset = regset - info->regsets; | 
|  | if (info->disabled_regsets == NULL) | 
|  | info->disabled_regsets = (char *) xcalloc (1, info->num_regsets); | 
|  | info->disabled_regsets[dr_offset] = 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | regsets_fetch_inferior_registers (struct regsets_info *regsets_info, | 
|  | struct regcache *regcache) | 
|  | { | 
|  | struct regset_info *regset; | 
|  | int saw_general_regs = 0; | 
|  | int pid = current_thread->id.lwp (); | 
|  | struct iovec iov; | 
|  |  | 
|  | for (regset = regsets_info->regsets; regset->size >= 0; regset++) | 
|  | { | 
|  | void *buf, *data; | 
|  | int nt_type, res; | 
|  |  | 
|  | if (regset->size == 0 || regset_disabled (regsets_info, regset)) | 
|  | continue; | 
|  |  | 
|  | buf = xmalloc (regset->size); | 
|  |  | 
|  | nt_type = regset->nt_type; | 
|  | if (nt_type) | 
|  | { | 
|  | iov.iov_base = buf; | 
|  | iov.iov_len = regset->size; | 
|  | data = (void *) &iov; | 
|  | } | 
|  | else | 
|  | data = buf; | 
|  |  | 
|  | #ifndef __sparc__ | 
|  | res = ptrace (regset->get_request, pid, | 
|  | (PTRACE_TYPE_ARG3) (long) nt_type, data); | 
|  | #else | 
|  | res = ptrace (regset->get_request, pid, data, nt_type); | 
|  | #endif | 
|  | if (res < 0) | 
|  | { | 
|  | if (errno == EIO | 
|  | || (errno == EINVAL && regset->type == OPTIONAL_REGS)) | 
|  | { | 
|  | /* If we get EIO on a regset, or an EINVAL and the regset is | 
|  | optional, do not try it again for this process mode.  */ | 
|  | disable_regset (regsets_info, regset); | 
|  | } | 
|  | else if (errno == ENODATA) | 
|  | { | 
|  | /* ENODATA may be returned if the regset is currently | 
|  | not "active".  This can happen in normal operation, | 
|  | so suppress the warning in this case.  */ | 
|  | } | 
|  | else if (errno == ESRCH) | 
|  | { | 
|  | /* At this point, ESRCH should mean the process is | 
|  | already gone, in which case we simply ignore attempts | 
|  | to read its registers.  */ | 
|  | } | 
|  | else | 
|  | { | 
|  | char s[256]; | 
|  | sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%d", | 
|  | pid); | 
|  | perror (s); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (regset->type == GENERAL_REGS) | 
|  | saw_general_regs = 1; | 
|  | regset->store_function (regcache, buf); | 
|  | } | 
|  | free (buf); | 
|  | } | 
|  | if (saw_general_regs) | 
|  | return 0; | 
|  | else | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | regsets_store_inferior_registers (struct regsets_info *regsets_info, | 
|  | struct regcache *regcache) | 
|  | { | 
|  | struct regset_info *regset; | 
|  | int saw_general_regs = 0; | 
|  | int pid = current_thread->id.lwp (); | 
|  | struct iovec iov; | 
|  |  | 
|  | for (regset = regsets_info->regsets; regset->size >= 0; regset++) | 
|  | { | 
|  | void *buf, *data; | 
|  | int nt_type, res; | 
|  |  | 
|  | if (regset->size == 0 || regset_disabled (regsets_info, regset) | 
|  | || regset->fill_function == NULL) | 
|  | continue; | 
|  |  | 
|  | buf = xmalloc (regset->size); | 
|  |  | 
|  | /* First fill the buffer with the current register set contents, | 
|  | in case there are any items in the kernel's regset that are | 
|  | not in gdbserver's regcache.  */ | 
|  |  | 
|  | nt_type = regset->nt_type; | 
|  | if (nt_type) | 
|  | { | 
|  | iov.iov_base = buf; | 
|  | iov.iov_len = regset->size; | 
|  | data = (void *) &iov; | 
|  | } | 
|  | else | 
|  | data = buf; | 
|  |  | 
|  | #ifndef __sparc__ | 
|  | res = ptrace (regset->get_request, pid, | 
|  | (PTRACE_TYPE_ARG3) (long) nt_type, data); | 
|  | #else | 
|  | res = ptrace (regset->get_request, pid, data, nt_type); | 
|  | #endif | 
|  |  | 
|  | if (res == 0) | 
|  | { | 
|  | /* Then overlay our cached registers on that.  */ | 
|  | regset->fill_function (regcache, buf); | 
|  |  | 
|  | /* Only now do we write the register set.  */ | 
|  | #ifndef __sparc__ | 
|  | res = ptrace (regset->set_request, pid, | 
|  | (PTRACE_TYPE_ARG3) (long) nt_type, data); | 
|  | #else | 
|  | res = ptrace (regset->set_request, pid, data, nt_type); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | if (res < 0) | 
|  | { | 
|  | if (errno == EIO | 
|  | || (errno == EINVAL && regset->type == OPTIONAL_REGS)) | 
|  | { | 
|  | /* If we get EIO on a regset, or an EINVAL and the regset is | 
|  | optional, do not try it again for this process mode.  */ | 
|  | disable_regset (regsets_info, regset); | 
|  | } | 
|  | else if (errno == ESRCH) | 
|  | { | 
|  | /* At this point, ESRCH should mean the process is | 
|  | already gone, in which case we simply ignore attempts | 
|  | to change its registers.  See also the related | 
|  | comment in resume_one_lwp.  */ | 
|  | free (buf); | 
|  | return 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | perror ("Warning: ptrace(regsets_store_inferior_registers)"); | 
|  | } | 
|  | } | 
|  | else if (regset->type == GENERAL_REGS) | 
|  | saw_general_regs = 1; | 
|  | free (buf); | 
|  | } | 
|  | if (saw_general_regs) | 
|  | return 0; | 
|  | else | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | #else /* !HAVE_LINUX_REGSETS */ | 
|  |  | 
|  | #define use_linux_regsets 0 | 
|  | #define regsets_fetch_inferior_registers(regsets_info, regcache) 1 | 
|  | #define regsets_store_inferior_registers(regsets_info, regcache) 1 | 
|  |  | 
|  | #endif | 
|  |  | 
|  | /* Return 1 if register REGNO is supported by one of the regset ptrace | 
|  | calls or 0 if it has to be transferred individually.  */ | 
|  |  | 
|  | static int | 
|  | linux_register_in_regsets (const struct regs_info *regs_info, int regno) | 
|  | { | 
|  | unsigned char mask = 1 << (regno % 8); | 
|  | size_t index = regno / 8; | 
|  |  | 
|  | return (use_linux_regsets | 
|  | && (regs_info->regset_bitmap == NULL | 
|  | || (regs_info->regset_bitmap[index] & mask) != 0)); | 
|  | } | 
|  |  | 
|  | #ifdef HAVE_LINUX_USRREGS | 
|  |  | 
|  | static int | 
|  | register_addr (const struct usrregs_info *usrregs, int regnum) | 
|  | { | 
|  | int addr; | 
|  |  | 
|  | if (regnum < 0 || regnum >= usrregs->num_regs) | 
|  | error ("Invalid register number %d.", regnum); | 
|  |  | 
|  | addr = usrregs->regmap[regnum]; | 
|  |  | 
|  | return addr; | 
|  | } | 
|  |  | 
|  |  | 
|  | void | 
|  | linux_process_target::fetch_register (const usrregs_info *usrregs, | 
|  | regcache *regcache, int regno) | 
|  | { | 
|  | CORE_ADDR regaddr; | 
|  | int i, size; | 
|  | char *buf; | 
|  |  | 
|  | if (regno >= usrregs->num_regs) | 
|  | return; | 
|  | if (low_cannot_fetch_register (regno)) | 
|  | return; | 
|  |  | 
|  | regaddr = register_addr (usrregs, regno); | 
|  | if (regaddr == -1) | 
|  | return; | 
|  |  | 
|  | size = ((register_size (regcache->tdesc, regno) | 
|  | + sizeof (PTRACE_XFER_TYPE) - 1) | 
|  | & -sizeof (PTRACE_XFER_TYPE)); | 
|  | buf = (char *) alloca (size); | 
|  |  | 
|  | int pid = current_thread->id.lwp (); | 
|  |  | 
|  | for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) | 
|  | { | 
|  | errno = 0; | 
|  | *(PTRACE_XFER_TYPE *) (buf + i) = | 
|  | ptrace (PTRACE_PEEKUSER, pid, | 
|  | /* Coerce to a uintptr_t first to avoid potential gcc warning | 
|  | of coercing an 8 byte integer to a 4 byte pointer.  */ | 
|  | (PTRACE_TYPE_ARG3) (uintptr_t) regaddr, (PTRACE_TYPE_ARG4) 0); | 
|  | regaddr += sizeof (PTRACE_XFER_TYPE); | 
|  | if (errno != 0) | 
|  | { | 
|  | /* Mark register REGNO unavailable.  */ | 
|  | supply_register (regcache, regno, NULL); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | low_supply_ptrace_register (regcache, regno, buf); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::store_register (const usrregs_info *usrregs, | 
|  | regcache *regcache, int regno) | 
|  | { | 
|  | CORE_ADDR regaddr; | 
|  | int i, size; | 
|  | char *buf; | 
|  |  | 
|  | if (regno >= usrregs->num_regs) | 
|  | return; | 
|  | if (low_cannot_store_register (regno)) | 
|  | return; | 
|  |  | 
|  | regaddr = register_addr (usrregs, regno); | 
|  | if (regaddr == -1) | 
|  | return; | 
|  |  | 
|  | size = ((register_size (regcache->tdesc, regno) | 
|  | + sizeof (PTRACE_XFER_TYPE) - 1) | 
|  | & -sizeof (PTRACE_XFER_TYPE)); | 
|  | buf = (char *) alloca (size); | 
|  | memset (buf, 0, size); | 
|  |  | 
|  | low_collect_ptrace_register (regcache, regno, buf); | 
|  |  | 
|  | int pid = current_thread->id.lwp (); | 
|  |  | 
|  | for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) | 
|  | { | 
|  | errno = 0; | 
|  | ptrace (PTRACE_POKEUSER, pid, | 
|  | /* Coerce to a uintptr_t first to avoid potential gcc warning | 
|  | about coercing an 8 byte integer to a 4 byte pointer.  */ | 
|  | (PTRACE_TYPE_ARG3) (uintptr_t) regaddr, | 
|  | (PTRACE_TYPE_ARG4) *(PTRACE_XFER_TYPE *) (buf + i)); | 
|  | if (errno != 0) | 
|  | { | 
|  | /* At this point, ESRCH should mean the process is | 
|  | already gone, in which case we simply ignore attempts | 
|  | to change its registers.  See also the related | 
|  | comment in resume_one_lwp.  */ | 
|  | if (errno == ESRCH) | 
|  | return; | 
|  |  | 
|  |  | 
|  | if (!low_cannot_store_register (regno)) | 
|  | error ("writing register %d: %s", regno, safe_strerror (errno)); | 
|  | } | 
|  | regaddr += sizeof (PTRACE_XFER_TYPE); | 
|  | } | 
|  | } | 
|  | #endif /* HAVE_LINUX_USRREGS */ | 
|  |  | 
|  | void | 
|  | linux_process_target::low_collect_ptrace_register (regcache *regcache, | 
|  | int regno, char *buf) | 
|  | { | 
|  | collect_register (regcache, regno, buf); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::low_supply_ptrace_register (regcache *regcache, | 
|  | int regno, const char *buf) | 
|  | { | 
|  | supply_register (regcache, regno, buf); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::usr_fetch_inferior_registers (const regs_info *regs_info, | 
|  | regcache *regcache, | 
|  | int regno, int all) | 
|  | { | 
|  | #ifdef HAVE_LINUX_USRREGS | 
|  | struct usrregs_info *usr = regs_info->usrregs; | 
|  |  | 
|  | if (regno == -1) | 
|  | { | 
|  | for (regno = 0; regno < usr->num_regs; regno++) | 
|  | if (all || !linux_register_in_regsets (regs_info, regno)) | 
|  | fetch_register (usr, regcache, regno); | 
|  | } | 
|  | else | 
|  | fetch_register (usr, regcache, regno); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::usr_store_inferior_registers (const regs_info *regs_info, | 
|  | regcache *regcache, | 
|  | int regno, int all) | 
|  | { | 
|  | #ifdef HAVE_LINUX_USRREGS | 
|  | struct usrregs_info *usr = regs_info->usrregs; | 
|  |  | 
|  | if (regno == -1) | 
|  | { | 
|  | for (regno = 0; regno < usr->num_regs; regno++) | 
|  | if (all || !linux_register_in_regsets (regs_info, regno)) | 
|  | store_register (usr, regcache, regno); | 
|  | } | 
|  | else | 
|  | store_register (usr, regcache, regno); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::fetch_registers (regcache *regcache, int regno) | 
|  | { | 
|  | int use_regsets; | 
|  | int all = 0; | 
|  | const regs_info *regs_info = get_regs_info (); | 
|  |  | 
|  | if (regno == -1) | 
|  | { | 
|  | if (regs_info->usrregs != NULL) | 
|  | for (regno = 0; regno < regs_info->usrregs->num_regs; regno++) | 
|  | low_fetch_register (regcache, regno); | 
|  |  | 
|  | all = regsets_fetch_inferior_registers (regs_info->regsets_info, regcache); | 
|  | if (regs_info->usrregs != NULL) | 
|  | usr_fetch_inferior_registers (regs_info, regcache, -1, all); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (low_fetch_register (regcache, regno)) | 
|  | return; | 
|  |  | 
|  | use_regsets = linux_register_in_regsets (regs_info, regno); | 
|  | if (use_regsets) | 
|  | all = regsets_fetch_inferior_registers (regs_info->regsets_info, | 
|  | regcache); | 
|  | if ((!use_regsets || all) && regs_info->usrregs != NULL) | 
|  | usr_fetch_inferior_registers (regs_info, regcache, regno, 1); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::store_registers (regcache *regcache, int regno) | 
|  | { | 
|  | int use_regsets; | 
|  | int all = 0; | 
|  | const regs_info *regs_info = get_regs_info (); | 
|  |  | 
|  | if (regno == -1) | 
|  | { | 
|  | all = regsets_store_inferior_registers (regs_info->regsets_info, | 
|  | regcache); | 
|  | if (regs_info->usrregs != NULL) | 
|  | usr_store_inferior_registers (regs_info, regcache, regno, all); | 
|  | } | 
|  | else | 
|  | { | 
|  | use_regsets = linux_register_in_regsets (regs_info, regno); | 
|  | if (use_regsets) | 
|  | all = regsets_store_inferior_registers (regs_info->regsets_info, | 
|  | regcache); | 
|  | if ((!use_regsets || all) && regs_info->usrregs != NULL) | 
|  | usr_store_inferior_registers (regs_info, regcache, regno, 1); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::low_fetch_register (regcache *regcache, int regno) | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* A wrapper for the read_memory target op.  */ | 
|  |  | 
|  | static int | 
|  | linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) | 
|  | { | 
|  | return the_target->read_memory (memaddr, myaddr, len); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Helper for read_memory/write_memory using /proc/PID/mem.  Because | 
|  | we can use a single read/write call, this can be much more | 
|  | efficient than banging away at PTRACE_PEEKTEXT.  Also, unlike | 
|  | PTRACE_PEEKTEXT/PTRACE_POKETEXT, this works with running threads. | 
|  | One an only one of READBUF and WRITEBUF is non-null.  If READBUF is | 
|  | not null, then we're reading, otherwise we're writing.  */ | 
|  |  | 
|  | static int | 
|  | proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf, | 
|  | const gdb_byte *writebuf, int len) | 
|  | { | 
|  | gdb_assert ((readbuf == nullptr) != (writebuf == nullptr)); | 
|  |  | 
|  | process_info *proc = current_process (); | 
|  |  | 
|  | int fd = proc->priv->mem_fd; | 
|  | if (fd == -1) | 
|  | return EIO; | 
|  |  | 
|  | while (len > 0) | 
|  | { | 
|  | int bytes; | 
|  |  | 
|  | /* Use pread64/pwrite64 if available, since they save a syscall | 
|  | and can handle 64-bit offsets even on 32-bit platforms (for | 
|  | instance, SPARC debugging a SPARC64 application).  But only | 
|  | use them if the offset isn't so high that when cast to off_t | 
|  | it'd be negative, as seen on SPARC64.  pread64/pwrite64 | 
|  | outright reject such offsets.  lseek does not.  */ | 
|  | #ifdef HAVE_PREAD64 | 
|  | if ((off_t) memaddr >= 0) | 
|  | bytes = (readbuf != nullptr | 
|  | ? pread64 (fd, readbuf, len, memaddr) | 
|  | : pwrite64 (fd, writebuf, len, memaddr)); | 
|  | else | 
|  | #endif | 
|  | { | 
|  | bytes = -1; | 
|  | if (lseek (fd, memaddr, SEEK_SET) != -1) | 
|  | bytes = (readbuf != nullptr | 
|  | ? read (fd, readbuf, len) | 
|  | : write (fd, writebuf, len)); | 
|  | } | 
|  |  | 
|  | if (bytes < 0) | 
|  | return errno; | 
|  | else if (bytes == 0) | 
|  | { | 
|  | /* EOF means the address space is gone, the whole process | 
|  | exited or execed.  */ | 
|  | return EIO; | 
|  | } | 
|  |  | 
|  | memaddr += bytes; | 
|  | if (readbuf != nullptr) | 
|  | readbuf += bytes; | 
|  | else | 
|  | writebuf += bytes; | 
|  | len -= bytes; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::read_memory (CORE_ADDR memaddr, | 
|  | unsigned char *myaddr, int len) | 
|  | { | 
|  | return proc_xfer_memory (memaddr, myaddr, nullptr, len); | 
|  | } | 
|  |  | 
|  | /* Copy LEN bytes of data from debugger memory at MYADDR to inferior's | 
|  | memory at MEMADDR.  On failure (cannot write to the inferior) | 
|  | returns the value of errno.  Always succeeds if LEN is zero.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::write_memory (CORE_ADDR memaddr, | 
|  | const unsigned char *myaddr, int len) | 
|  | { | 
|  | if (debug_threads) | 
|  | { | 
|  | /* Dump up to four bytes.  */ | 
|  | char str[4 * 2 + 1]; | 
|  | char *p = str; | 
|  | int dump = len < 4 ? len : 4; | 
|  |  | 
|  | for (int i = 0; i < dump; i++) | 
|  | { | 
|  | sprintf (p, "%02x", myaddr[i]); | 
|  | p += 2; | 
|  | } | 
|  | *p = '\0'; | 
|  |  | 
|  | threads_debug_printf ("Writing %s to 0x%08lx in process %d", | 
|  | str, (long) memaddr, current_process ()->pid); | 
|  | } | 
|  |  | 
|  | return proc_xfer_memory (memaddr, nullptr, myaddr, len); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::look_up_symbols () | 
|  | { | 
|  | #ifdef USE_THREAD_DB | 
|  | struct process_info *proc = current_process (); | 
|  |  | 
|  | if (proc->priv->thread_db != NULL) | 
|  | return; | 
|  |  | 
|  | thread_db_init (); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::request_interrupt () | 
|  | { | 
|  | /* Send a SIGINT to the process group.  This acts just like the user | 
|  | typed a ^C on the controlling terminal.  */ | 
|  | int res = ::kill (-signal_pid, SIGINT); | 
|  | if (res == -1) | 
|  | warning (_("Sending SIGINT to process group of pid %ld failed: %s"), | 
|  | signal_pid, safe_strerror (errno)); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_read_auxv () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET | 
|  | to debugger memory starting at MYADDR.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::read_auxv (int pid, CORE_ADDR offset, | 
|  | unsigned char *myaddr, unsigned int len) | 
|  | { | 
|  | char filename[PATH_MAX]; | 
|  | int fd, n; | 
|  |  | 
|  | xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid); | 
|  |  | 
|  | fd = open (filename, O_RDONLY); | 
|  | if (fd < 0) | 
|  | return -1; | 
|  |  | 
|  | if (offset != (CORE_ADDR) 0 | 
|  | && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) | 
|  | n = -1; | 
|  | else | 
|  | n = read (fd, myaddr, len); | 
|  |  | 
|  | close (fd); | 
|  |  | 
|  | return n; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr, | 
|  | int size, raw_breakpoint *bp) | 
|  | { | 
|  | if (type == raw_bkpt_type_sw) | 
|  | return insert_memory_breakpoint (bp); | 
|  | else | 
|  | return low_insert_point (type, addr, size, bp); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr, | 
|  | int size, raw_breakpoint *bp) | 
|  | { | 
|  | /* Unsupported (see target.h).  */ | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr, | 
|  | int size, raw_breakpoint *bp) | 
|  | { | 
|  | if (type == raw_bkpt_type_sw) | 
|  | return remove_memory_breakpoint (bp); | 
|  | else | 
|  | return low_remove_point (type, addr, size, bp); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr, | 
|  | int size, raw_breakpoint *bp) | 
|  | { | 
|  | /* Unsupported (see target.h).  */ | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | /* Implement the stopped_by_sw_breakpoint target_ops | 
|  | method.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::stopped_by_sw_breakpoint () | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (current_thread); | 
|  |  | 
|  | return (lwp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT); | 
|  | } | 
|  |  | 
|  | /* Implement the supports_stopped_by_sw_breakpoint target_ops | 
|  | method.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_stopped_by_sw_breakpoint () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Implement the stopped_by_hw_breakpoint target_ops | 
|  | method.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::stopped_by_hw_breakpoint () | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (current_thread); | 
|  |  | 
|  | return (lwp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT); | 
|  | } | 
|  |  | 
|  | /* Implement the supports_stopped_by_hw_breakpoint target_ops | 
|  | method.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_stopped_by_hw_breakpoint () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Implement the supports_hardware_single_step target_ops method.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_hardware_single_step () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::stopped_by_watchpoint () | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (current_thread); | 
|  |  | 
|  | return lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT; | 
|  | } | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_process_target::stopped_data_address () | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (current_thread); | 
|  |  | 
|  | return lwp->stopped_data_address; | 
|  | } | 
|  |  | 
|  | /* This is only used for targets that define PT_TEXT_ADDR, | 
|  | PT_DATA_ADDR and PT_TEXT_END_ADDR.  If those are not defined, supposedly | 
|  | the target has different ways of acquiring this information, like | 
|  | loadmaps.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_read_offsets () | 
|  | { | 
|  | #ifdef SUPPORTS_READ_OFFSETS | 
|  | return true; | 
|  | #else | 
|  | return false; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /* Under uClinux, programs are loaded at non-zero offsets, which we need | 
|  | to tell gdb about.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p) | 
|  | { | 
|  | #ifdef SUPPORTS_READ_OFFSETS | 
|  | unsigned long text, text_end, data; | 
|  | int pid = current_thread->id.lwp (); | 
|  |  | 
|  | errno = 0; | 
|  |  | 
|  | text = ptrace (PTRACE_PEEKUSER, pid, (PTRACE_TYPE_ARG3) PT_TEXT_ADDR, | 
|  | (PTRACE_TYPE_ARG4) 0); | 
|  | text_end = ptrace (PTRACE_PEEKUSER, pid, (PTRACE_TYPE_ARG3) PT_TEXT_END_ADDR, | 
|  | (PTRACE_TYPE_ARG4) 0); | 
|  | data = ptrace (PTRACE_PEEKUSER, pid, (PTRACE_TYPE_ARG3) PT_DATA_ADDR, | 
|  | (PTRACE_TYPE_ARG4) 0); | 
|  |  | 
|  | if (errno == 0) | 
|  | { | 
|  | /* Both text and data offsets produced at compile-time (and so | 
|  | used by gdb) are relative to the beginning of the program, | 
|  | with the data segment immediately following the text segment. | 
|  | However, the actual runtime layout in memory may put the data | 
|  | somewhere else, so when we send gdb a data base-address, we | 
|  | use the real data base address and subtract the compile-time | 
|  | data base-address from it (which is just the length of the | 
|  | text segment).  BSS immediately follows data in both | 
|  | cases.  */ | 
|  | *text_p = text; | 
|  | *data_p = data - (text_end - text); | 
|  |  | 
|  | return 1; | 
|  | } | 
|  | return 0; | 
|  | #else | 
|  | gdb_assert_not_reached ("target op read_offsets not supported"); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_get_tls_address () | 
|  | { | 
|  | #ifdef USE_THREAD_DB | 
|  | return true; | 
|  | #else | 
|  | return false; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::get_tls_address (thread_info *thread, | 
|  | CORE_ADDR offset, | 
|  | CORE_ADDR load_module, | 
|  | CORE_ADDR *address) | 
|  | { | 
|  | #ifdef USE_THREAD_DB | 
|  | return thread_db_get_tls_address (thread, offset, load_module, address); | 
|  | #else | 
|  | return -1; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_qxfer_osdata () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::qxfer_osdata (const char *annex, | 
|  | unsigned char *readbuf, | 
|  | unsigned const char *writebuf, | 
|  | CORE_ADDR offset, int len) | 
|  | { | 
|  | return linux_common_xfer_osdata (annex, readbuf, offset, len); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::siginfo_fixup (siginfo_t *siginfo, | 
|  | gdb_byte *inf_siginfo, int direction) | 
|  | { | 
|  | bool done = low_siginfo_fixup (siginfo, inf_siginfo, direction); | 
|  |  | 
|  | /* If there was no callback, or the callback didn't do anything, | 
|  | then just do a straight memcpy.  */ | 
|  | if (!done) | 
|  | { | 
|  | if (direction == 1) | 
|  | memcpy (siginfo, inf_siginfo, sizeof (siginfo_t)); | 
|  | else | 
|  | memcpy (inf_siginfo, siginfo, sizeof (siginfo_t)); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::low_siginfo_fixup (siginfo_t *native, gdb_byte *inf, | 
|  | int direction) | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_qxfer_siginfo () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::qxfer_siginfo (const char *annex, | 
|  | unsigned char *readbuf, | 
|  | unsigned const char *writebuf, | 
|  | CORE_ADDR offset, int len) | 
|  | { | 
|  | siginfo_t siginfo; | 
|  | gdb_byte inf_siginfo[sizeof (siginfo_t)]; | 
|  |  | 
|  | if (current_thread == NULL) | 
|  | return -1; | 
|  |  | 
|  | int pid = current_thread->id.lwp (); | 
|  |  | 
|  | threads_debug_printf ("%s siginfo for lwp %d.", | 
|  | readbuf != NULL ? "Reading" : "Writing", | 
|  | pid); | 
|  |  | 
|  | if (offset >= sizeof (siginfo)) | 
|  | return -1; | 
|  |  | 
|  | if (ptrace (PTRACE_GETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, &siginfo) != 0) | 
|  | return -1; | 
|  |  | 
|  | /* When GDBSERVER is built as a 64-bit application, ptrace writes into | 
|  | SIGINFO an object with 64-bit layout.  Since debugging a 32-bit | 
|  | inferior with a 64-bit GDBSERVER should look the same as debugging it | 
|  | with a 32-bit GDBSERVER, we need to convert it.  */ | 
|  | siginfo_fixup (&siginfo, inf_siginfo, 0); | 
|  |  | 
|  | if (offset + len > sizeof (siginfo)) | 
|  | len = sizeof (siginfo) - offset; | 
|  |  | 
|  | if (readbuf != NULL) | 
|  | memcpy (readbuf, inf_siginfo + offset, len); | 
|  | else | 
|  | { | 
|  | memcpy (inf_siginfo + offset, writebuf, len); | 
|  |  | 
|  | /* Convert back to ptrace layout before flushing it out.  */ | 
|  | siginfo_fixup (&siginfo, inf_siginfo, 1); | 
|  |  | 
|  | if (ptrace (PTRACE_SETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, &siginfo) != 0) | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | return len; | 
|  | } | 
|  |  | 
|  | /* SIGCHLD handler that serves two purposes: In non-stop/async mode, | 
|  | so we notice when children change state; as the handler for the | 
|  | sigsuspend in my_waitpid.  */ | 
|  |  | 
|  | static void | 
|  | sigchld_handler (int signo) | 
|  | { | 
|  | int old_errno = errno; | 
|  |  | 
|  | if (debug_threads) | 
|  | { | 
|  | do | 
|  | { | 
|  | /* Use the async signal safe debug function.  */ | 
|  | if (debug_write ("sigchld_handler\n", | 
|  | sizeof ("sigchld_handler\n") - 1) < 0) | 
|  | break; /* just ignore */ | 
|  | } while (0); | 
|  | } | 
|  |  | 
|  | if (target_is_async_p ()) | 
|  | async_file_mark (); /* trigger a linux_wait */ | 
|  |  | 
|  | errno = old_errno; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_non_stop () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::async (bool enable) | 
|  | { | 
|  | bool previous = target_is_async_p (); | 
|  |  | 
|  | threads_debug_printf ("async (%d), previous=%d", | 
|  | enable, previous); | 
|  |  | 
|  | if (previous != enable) | 
|  | { | 
|  | sigset_t mask; | 
|  | sigemptyset (&mask); | 
|  | sigaddset (&mask, SIGCHLD); | 
|  |  | 
|  | gdb_sigmask (SIG_BLOCK, &mask, NULL); | 
|  |  | 
|  | if (enable) | 
|  | { | 
|  | if (!linux_event_pipe.open_pipe ()) | 
|  | { | 
|  | gdb_sigmask (SIG_UNBLOCK, &mask, NULL); | 
|  |  | 
|  | warning ("creating event pipe failed."); | 
|  | return previous; | 
|  | } | 
|  |  | 
|  | /* Register the event loop handler.  */ | 
|  | add_file_handler (linux_event_pipe.event_fd (), | 
|  | handle_target_event, NULL, | 
|  | "linux-low"); | 
|  |  | 
|  | /* Always trigger a linux_wait.  */ | 
|  | async_file_mark (); | 
|  | } | 
|  | else | 
|  | { | 
|  | delete_file_handler (linux_event_pipe.event_fd ()); | 
|  |  | 
|  | linux_event_pipe.close_pipe (); | 
|  | } | 
|  |  | 
|  | gdb_sigmask (SIG_UNBLOCK, &mask, NULL); | 
|  | } | 
|  |  | 
|  | return previous; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::start_non_stop (bool nonstop) | 
|  | { | 
|  | /* Register or unregister from event-loop accordingly.  */ | 
|  | target_async (nonstop); | 
|  |  | 
|  | if (target_is_async_p () != (nonstop != false)) | 
|  | return -1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_multi_process () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Check if fork events are supported.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_fork_events () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Check if vfork events are supported.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_vfork_events () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Return the set of supported thread options.  */ | 
|  |  | 
|  | gdb_thread_options | 
|  | linux_process_target::supported_thread_options () | 
|  | { | 
|  | return GDB_THREAD_OPTION_CLONE | GDB_THREAD_OPTION_EXIT; | 
|  | } | 
|  |  | 
|  | /* Check if exec events are supported.  */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_exec_events () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Target hook for 'handle_new_gdb_connection'.  Causes a reset of the | 
|  | ptrace flags for all inferiors.  This is in case the new GDB connection | 
|  | doesn't support the same set of events that the previous one did.  */ | 
|  |  | 
|  | void | 
|  | linux_process_target::handle_new_gdb_connection () | 
|  | { | 
|  | /* Request that all the lwps reset their ptrace options.  */ | 
|  | for_each_thread ([] (thread_info *thread) | 
|  | { | 
|  | struct lwp_info *lwp = get_thread_lwp (thread); | 
|  |  | 
|  | if (!lwp->stopped) | 
|  | { | 
|  | /* Stop the lwp so we can modify its ptrace options.  */ | 
|  | lwp->must_set_ptrace_flags = 1; | 
|  | linux_stop_lwp (lwp); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Already stopped; go ahead and set the ptrace options.  */ | 
|  | process_info *proc = find_process_pid (thread->id.pid ()); | 
|  | int options = linux_low_ptrace_options (proc->attached); | 
|  |  | 
|  | linux_enable_event_reporting (thread->id.lwp (), options); | 
|  | lwp->must_set_ptrace_flags = 0; | 
|  | } | 
|  | }); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::handle_monitor_command (char *mon) | 
|  | { | 
|  | #ifdef USE_THREAD_DB | 
|  | return thread_db_handle_monitor_command (mon); | 
|  | #else | 
|  | return 0; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::core_of_thread (ptid_t ptid) | 
|  | { | 
|  | return linux_common_core_of_thread (ptid); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_disable_randomization () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_agent () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_range_stepping () | 
|  | { | 
|  | if (supports_software_single_step ()) | 
|  | return true; | 
|  |  | 
|  | return low_supports_range_stepping (); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::low_supports_range_stepping () | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_pid_to_exec_file () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | const char * | 
|  | linux_process_target::pid_to_exec_file (int pid) | 
|  | { | 
|  | return linux_proc_pid_to_exec_file (pid, linux_ns_same (pid, LINUX_NS_MNT)); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_multifs () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::multifs_open (int pid, const char *filename, | 
|  | int flags, mode_t mode) | 
|  | { | 
|  | return linux_mntns_open_cloexec (pid, filename, flags, mode); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::multifs_lstat (int pid, const char *filename, struct stat *sb) | 
|  | { | 
|  | return linux_mntns_lstat (pid, filename, sb); | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::multifs_unlink (int pid, const char *filename) | 
|  | { | 
|  | return linux_mntns_unlink (pid, filename); | 
|  | } | 
|  |  | 
|  | ssize_t | 
|  | linux_process_target::multifs_readlink (int pid, const char *filename, | 
|  | char *buf, size_t bufsiz) | 
|  | { | 
|  | return linux_mntns_readlink (pid, filename, buf, bufsiz); | 
|  | } | 
|  |  | 
|  | #if defined PT_GETDSBT || defined PTRACE_GETFDPIC | 
|  | struct target_loadseg | 
|  | { | 
|  | /* Core address to which the segment is mapped.  */ | 
|  | Elf32_Addr addr; | 
|  | /* VMA recorded in the program header.  */ | 
|  | Elf32_Addr p_vaddr; | 
|  | /* Size of this segment in memory.  */ | 
|  | Elf32_Word p_memsz; | 
|  | }; | 
|  |  | 
|  | # if defined PT_GETDSBT | 
|  | struct target_loadmap | 
|  | { | 
|  | /* Protocol version number, must be zero.  */ | 
|  | Elf32_Word version; | 
|  | /* Pointer to the DSBT table, its size, and the DSBT index.  */ | 
|  | unsigned *dsbt_table; | 
|  | unsigned dsbt_size, dsbt_index; | 
|  | /* Number of segments in this map.  */ | 
|  | Elf32_Word nsegs; | 
|  | /* The actual memory map.  */ | 
|  | struct target_loadseg segs[/*nsegs*/]; | 
|  | }; | 
|  | #  define LINUX_LOADMAP		PT_GETDSBT | 
|  | #  define LINUX_LOADMAP_EXEC	PTRACE_GETDSBT_EXEC | 
|  | #  define LINUX_LOADMAP_INTERP	PTRACE_GETDSBT_INTERP | 
|  | # else | 
|  | struct target_loadmap | 
|  | { | 
|  | /* Protocol version number, must be zero.  */ | 
|  | Elf32_Half version; | 
|  | /* Number of segments in this map.  */ | 
|  | Elf32_Half nsegs; | 
|  | /* The actual memory map.  */ | 
|  | struct target_loadseg segs[/*nsegs*/]; | 
|  | }; | 
|  | #  define LINUX_LOADMAP		PTRACE_GETFDPIC | 
|  | #  define LINUX_LOADMAP_EXEC	PTRACE_GETFDPIC_EXEC | 
|  | #  define LINUX_LOADMAP_INTERP	PTRACE_GETFDPIC_INTERP | 
|  | # endif | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_read_loadmap () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | int | 
|  | linux_process_target::read_loadmap (const char *annex, CORE_ADDR offset, | 
|  | unsigned char *myaddr, unsigned int len) | 
|  | { | 
|  | int pid = current_thread->id.lwp (); | 
|  | int addr = -1; | 
|  | struct target_loadmap *data = NULL; | 
|  | unsigned int actual_length, copy_length; | 
|  |  | 
|  | if (strcmp (annex, "exec") == 0) | 
|  | addr = (int) LINUX_LOADMAP_EXEC; | 
|  | else if (strcmp (annex, "interp") == 0) | 
|  | addr = (int) LINUX_LOADMAP_INTERP; | 
|  | else | 
|  | return -1; | 
|  |  | 
|  | if (ptrace (LINUX_LOADMAP, pid, addr, &data) != 0) | 
|  | return -1; | 
|  |  | 
|  | if (data == NULL) | 
|  | return -1; | 
|  |  | 
|  | actual_length = sizeof (struct target_loadmap) | 
|  | + sizeof (struct target_loadseg) * data->nsegs; | 
|  |  | 
|  | if (offset < 0 || offset > actual_length) | 
|  | return -1; | 
|  |  | 
|  | copy_length = actual_length - offset < len ? actual_length - offset : len; | 
|  | memcpy (myaddr, (char *) data + offset, copy_length); | 
|  | return copy_length; | 
|  | } | 
|  | #endif /* defined PT_GETDSBT || defined PTRACE_GETFDPIC */ | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_catch_syscall () | 
|  | { | 
|  | return low_supports_catch_syscall (); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::low_supports_catch_syscall () | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_process_target::read_pc (regcache *regcache) | 
|  | { | 
|  | if (!low_supports_breakpoints ()) | 
|  | return 0; | 
|  |  | 
|  | return low_get_pc (regcache); | 
|  | } | 
|  |  | 
|  | void | 
|  | linux_process_target::write_pc (regcache *regcache, CORE_ADDR pc) | 
|  | { | 
|  | gdb_assert (low_supports_breakpoints ()); | 
|  |  | 
|  | low_set_pc (regcache, pc); | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_thread_stopped () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::thread_stopped (thread_info *thread) | 
|  | { | 
|  | return get_thread_lwp (thread)->stopped; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::any_resumed () | 
|  | { | 
|  | bool any_resumed; | 
|  |  | 
|  | auto status_pending_p_any = [&] (thread_info *thread) | 
|  | { | 
|  | return status_pending_p_callback (thread, minus_one_ptid); | 
|  | }; | 
|  |  | 
|  | auto not_stopped = [&] (thread_info *thread) | 
|  | { | 
|  | return not_stopped_callback (thread, minus_one_ptid); | 
|  | }; | 
|  |  | 
|  | /* Find a resumed LWP, if any.  */ | 
|  | if (find_thread (status_pending_p_any) != NULL) | 
|  | any_resumed = 1; | 
|  | else if (find_thread (not_stopped) != NULL) | 
|  | any_resumed = 1; | 
|  | else | 
|  | any_resumed = 0; | 
|  |  | 
|  | return any_resumed; | 
|  | } | 
|  |  | 
|  | /* This exposes stop-all-threads functionality to other modules.  */ | 
|  |  | 
|  | void | 
|  | linux_process_target::pause_all (bool freeze) | 
|  | { | 
|  | stop_all_lwps (freeze, NULL); | 
|  | } | 
|  |  | 
|  | /* This exposes unstop-all-threads functionality to other gdbserver | 
|  | modules.  */ | 
|  |  | 
|  | void | 
|  | linux_process_target::unpause_all (bool unfreeze) | 
|  | { | 
|  | unstop_all_lwps (unfreeze, NULL); | 
|  | } | 
|  |  | 
|  | /* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */ | 
|  |  | 
|  | static int | 
|  | get_phdr_phnum_from_proc_auxv (const int pid, const int is_elf64, | 
|  | CORE_ADDR *phdr_memaddr, int *num_phdr) | 
|  | { | 
|  | char filename[PATH_MAX]; | 
|  | int fd; | 
|  | const int auxv_size = is_elf64 | 
|  | ? sizeof (Elf64_auxv_t) : sizeof (Elf32_auxv_t); | 
|  | char buf[sizeof (Elf64_auxv_t)];  /* The larger of the two.  */ | 
|  |  | 
|  | xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid); | 
|  |  | 
|  | fd = open (filename, O_RDONLY); | 
|  | if (fd < 0) | 
|  | return 1; | 
|  |  | 
|  | *phdr_memaddr = 0; | 
|  | *num_phdr = 0; | 
|  | while (read (fd, buf, auxv_size) == auxv_size | 
|  | && (*phdr_memaddr == 0 || *num_phdr == 0)) | 
|  | { | 
|  | if (is_elf64) | 
|  | { | 
|  | Elf64_auxv_t *const aux = (Elf64_auxv_t *) buf; | 
|  |  | 
|  | switch (aux->a_type) | 
|  | { | 
|  | case AT_PHDR: | 
|  | *phdr_memaddr = aux->a_un.a_val; | 
|  | break; | 
|  | case AT_PHNUM: | 
|  | *num_phdr = aux->a_un.a_val; | 
|  | break; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | Elf32_auxv_t *const aux = (Elf32_auxv_t *) buf; | 
|  |  | 
|  | switch (aux->a_type) | 
|  | { | 
|  | case AT_PHDR: | 
|  | *phdr_memaddr = aux->a_un.a_val; | 
|  | break; | 
|  | case AT_PHNUM: | 
|  | *num_phdr = aux->a_un.a_val; | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | close (fd); | 
|  |  | 
|  | if (*phdr_memaddr == 0 || *num_phdr == 0) | 
|  | { | 
|  | warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: " | 
|  | "phdr_memaddr = %ld, phdr_num = %d", | 
|  | (long) *phdr_memaddr, *num_phdr); | 
|  | return 2; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present.  */ | 
|  |  | 
|  | static CORE_ADDR | 
|  | get_dynamic (const int pid, const int is_elf64) | 
|  | { | 
|  | CORE_ADDR phdr_memaddr, relocation; | 
|  | int num_phdr, i; | 
|  | unsigned char *phdr_buf; | 
|  | const int phdr_size = is_elf64 ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr); | 
|  |  | 
|  | if (get_phdr_phnum_from_proc_auxv (pid, is_elf64, &phdr_memaddr, &num_phdr)) | 
|  | return 0; | 
|  |  | 
|  | gdb_assert (num_phdr < 100);  /* Basic sanity check.  */ | 
|  | phdr_buf = (unsigned char *) alloca (num_phdr * phdr_size); | 
|  |  | 
|  | if (linux_read_memory (phdr_memaddr, phdr_buf, num_phdr * phdr_size)) | 
|  | return 0; | 
|  |  | 
|  | /* Compute relocation: it is expected to be 0 for "regular" executables, | 
|  | non-zero for PIE ones.  */ | 
|  | relocation = -1; | 
|  | for (i = 0; relocation == -1 && i < num_phdr; i++) | 
|  | if (is_elf64) | 
|  | { | 
|  | Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size); | 
|  |  | 
|  | if (p->p_type == PT_PHDR) | 
|  | relocation = phdr_memaddr - p->p_vaddr; | 
|  | } | 
|  | else | 
|  | { | 
|  | Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size); | 
|  |  | 
|  | if (p->p_type == PT_PHDR) | 
|  | relocation = phdr_memaddr - p->p_vaddr; | 
|  | } | 
|  |  | 
|  | if (relocation == -1) | 
|  | { | 
|  | /* PT_PHDR is optional, but necessary for PIE in general.  Fortunately | 
|  | any real world executables, including PIE executables, have always | 
|  | PT_PHDR present.  PT_PHDR is not present in some shared libraries or | 
|  | in fpc (Free Pascal 2.4) binaries but neither of those have a need for | 
|  | or present DT_DEBUG anyway (fpc binaries are statically linked). | 
|  |  | 
|  | Therefore if there exists DT_DEBUG there is always also PT_PHDR. | 
|  |  | 
|  | GDB could find RELOCATION also from AT_ENTRY - e_entry.  */ | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | for (i = 0; i < num_phdr; i++) | 
|  | { | 
|  | if (is_elf64) | 
|  | { | 
|  | Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size); | 
|  |  | 
|  | if (p->p_type == PT_DYNAMIC) | 
|  | return p->p_vaddr + relocation; | 
|  | } | 
|  | else | 
|  | { | 
|  | Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size); | 
|  |  | 
|  | if (p->p_type == PT_DYNAMIC) | 
|  | return p->p_vaddr + relocation; | 
|  | } | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Return &_r_debug in the inferior, or -1 if not present.  Return value | 
|  | can be 0 if the inferior does not yet have the library list initialized. | 
|  | We look for DT_MIPS_RLD_MAP first.  MIPS executables use this instead of | 
|  | DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too.  */ | 
|  |  | 
|  | static CORE_ADDR | 
|  | get_r_debug (const int pid, const int is_elf64) | 
|  | { | 
|  | CORE_ADDR dynamic_memaddr; | 
|  | const int dyn_size = is_elf64 ? sizeof (Elf64_Dyn) : sizeof (Elf32_Dyn); | 
|  | unsigned char buf[sizeof (Elf64_Dyn)];  /* The larger of the two.  */ | 
|  | CORE_ADDR map = -1; | 
|  |  | 
|  | dynamic_memaddr = get_dynamic (pid, is_elf64); | 
|  | if (dynamic_memaddr == 0) | 
|  | return map; | 
|  |  | 
|  | while (linux_read_memory (dynamic_memaddr, buf, dyn_size) == 0) | 
|  | { | 
|  | if (is_elf64) | 
|  | { | 
|  | Elf64_Dyn *const dyn = (Elf64_Dyn *) buf; | 
|  | #if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL | 
|  | union | 
|  | { | 
|  | Elf64_Xword map; | 
|  | unsigned char buf[sizeof (Elf64_Xword)]; | 
|  | } | 
|  | rld_map; | 
|  | #endif | 
|  | #ifdef DT_MIPS_RLD_MAP | 
|  | if (dyn->d_tag == DT_MIPS_RLD_MAP) | 
|  | { | 
|  | if (linux_read_memory (dyn->d_un.d_val, | 
|  | rld_map.buf, sizeof (rld_map.buf)) == 0) | 
|  | return rld_map.map; | 
|  | else | 
|  | break; | 
|  | } | 
|  | #endif	/* DT_MIPS_RLD_MAP */ | 
|  | #ifdef DT_MIPS_RLD_MAP_REL | 
|  | if (dyn->d_tag == DT_MIPS_RLD_MAP_REL) | 
|  | { | 
|  | if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr, | 
|  | rld_map.buf, sizeof (rld_map.buf)) == 0) | 
|  | return rld_map.map; | 
|  | else | 
|  | break; | 
|  | } | 
|  | #endif	/* DT_MIPS_RLD_MAP_REL */ | 
|  |  | 
|  | if (dyn->d_tag == DT_DEBUG && map == -1) | 
|  | map = dyn->d_un.d_val; | 
|  |  | 
|  | if (dyn->d_tag == DT_NULL) | 
|  | break; | 
|  | } | 
|  | else | 
|  | { | 
|  | Elf32_Dyn *const dyn = (Elf32_Dyn *) buf; | 
|  | #if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL | 
|  | union | 
|  | { | 
|  | Elf32_Word map; | 
|  | unsigned char buf[sizeof (Elf32_Word)]; | 
|  | } | 
|  | rld_map; | 
|  | #endif | 
|  | #ifdef DT_MIPS_RLD_MAP | 
|  | if (dyn->d_tag == DT_MIPS_RLD_MAP) | 
|  | { | 
|  | if (linux_read_memory (dyn->d_un.d_val, | 
|  | rld_map.buf, sizeof (rld_map.buf)) == 0) | 
|  | return rld_map.map; | 
|  | else | 
|  | break; | 
|  | } | 
|  | #endif	/* DT_MIPS_RLD_MAP */ | 
|  | #ifdef DT_MIPS_RLD_MAP_REL | 
|  | if (dyn->d_tag == DT_MIPS_RLD_MAP_REL) | 
|  | { | 
|  | if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr, | 
|  | rld_map.buf, sizeof (rld_map.buf)) == 0) | 
|  | return rld_map.map; | 
|  | else | 
|  | break; | 
|  | } | 
|  | #endif	/* DT_MIPS_RLD_MAP_REL */ | 
|  |  | 
|  | if (dyn->d_tag == DT_DEBUG && map == -1) | 
|  | map = dyn->d_un.d_val; | 
|  |  | 
|  | if (dyn->d_tag == DT_NULL) | 
|  | break; | 
|  | } | 
|  |  | 
|  | dynamic_memaddr += dyn_size; | 
|  | } | 
|  |  | 
|  | return map; | 
|  | } | 
|  |  | 
|  | /* Read one pointer from MEMADDR in the inferior.  */ | 
|  |  | 
|  | static int | 
|  | read_one_ptr (CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size) | 
|  | { | 
|  | int ret; | 
|  |  | 
|  | /* Go through a union so this works on either big or little endian | 
|  | hosts, when the inferior's pointer size is smaller than the size | 
|  | of CORE_ADDR.  It is assumed the inferior's endianness is the | 
|  | same of the superior's.  */ | 
|  | union | 
|  | { | 
|  | CORE_ADDR core_addr; | 
|  | unsigned int ui; | 
|  | unsigned char uc; | 
|  | } addr; | 
|  |  | 
|  | ret = linux_read_memory (memaddr, &addr.uc, ptr_size); | 
|  | if (ret == 0) | 
|  | { | 
|  | if (ptr_size == sizeof (CORE_ADDR)) | 
|  | *ptr = addr.core_addr; | 
|  | else if (ptr_size == sizeof (unsigned int)) | 
|  | *ptr = addr.ui; | 
|  | else | 
|  | gdb_assert_not_reached ("unhandled pointer size"); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_qxfer_libraries_svr4 () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | struct link_map_offsets | 
|  | { | 
|  | /* Offset and size of r_debug.r_version.  */ | 
|  | int r_version_offset; | 
|  |  | 
|  | /* Offset and size of r_debug.r_map.  */ | 
|  | int r_map_offset; | 
|  |  | 
|  | /* Offset of r_debug_extended.r_next.  */ | 
|  | int r_next_offset; | 
|  |  | 
|  | /* Offset to l_addr field in struct link_map.  */ | 
|  | int l_addr_offset; | 
|  |  | 
|  | /* Offset to l_name field in struct link_map.  */ | 
|  | int l_name_offset; | 
|  |  | 
|  | /* Offset to l_ld field in struct link_map.  */ | 
|  | int l_ld_offset; | 
|  |  | 
|  | /* Offset to l_next field in struct link_map.  */ | 
|  | int l_next_offset; | 
|  |  | 
|  | /* Offset to l_prev field in struct link_map.  */ | 
|  | int l_prev_offset; | 
|  | }; | 
|  |  | 
|  | static const link_map_offsets lmo_32bit_offsets = | 
|  | { | 
|  | 0,     /* r_version offset.  */ | 
|  | 4,     /* r_debug.r_map offset.  */ | 
|  | 20,    /* r_debug_extended.r_next.  */ | 
|  | 0,     /* l_addr offset in link_map.  */ | 
|  | 4,     /* l_name offset in link_map.  */ | 
|  | 8,     /* l_ld offset in link_map.  */ | 
|  | 12,    /* l_next offset in link_map.  */ | 
|  | 16     /* l_prev offset in link_map.  */ | 
|  | }; | 
|  |  | 
|  | static const link_map_offsets lmo_64bit_offsets = | 
|  | { | 
|  | 0,     /* r_version offset.  */ | 
|  | 8,     /* r_debug.r_map offset.  */ | 
|  | 40,    /* r_debug_extended.r_next.  */ | 
|  | 0,     /* l_addr offset in link_map.  */ | 
|  | 8,     /* l_name offset in link_map.  */ | 
|  | 16,    /* l_ld offset in link_map.  */ | 
|  | 24,    /* l_next offset in link_map.  */ | 
|  | 32     /* l_prev offset in link_map.  */ | 
|  | }; | 
|  |  | 
|  | /* Get the loaded shared libraries from one namespace.  */ | 
|  |  | 
|  | static void | 
|  | read_link_map (std::string &document, CORE_ADDR lmid, CORE_ADDR lm_addr, | 
|  | CORE_ADDR lm_prev, int ptr_size, const link_map_offsets *lmo) | 
|  | { | 
|  | CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev; | 
|  |  | 
|  | while (lm_addr | 
|  | && read_one_ptr (lm_addr + lmo->l_name_offset, | 
|  | &l_name, ptr_size) == 0 | 
|  | && read_one_ptr (lm_addr + lmo->l_addr_offset, | 
|  | &l_addr, ptr_size) == 0 | 
|  | && read_one_ptr (lm_addr + lmo->l_ld_offset, | 
|  | &l_ld, ptr_size) == 0 | 
|  | && read_one_ptr (lm_addr + lmo->l_prev_offset, | 
|  | &l_prev, ptr_size) == 0 | 
|  | && read_one_ptr (lm_addr + lmo->l_next_offset, | 
|  | &l_next, ptr_size) == 0) | 
|  | { | 
|  | unsigned char libname[PATH_MAX]; | 
|  |  | 
|  | if (lm_prev != l_prev) | 
|  | { | 
|  | warning ("Corrupted shared library list: 0x%s != 0x%s", | 
|  | paddress (lm_prev), paddress (l_prev)); | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* Not checking for error because reading may stop before we've got | 
|  | PATH_MAX worth of characters.  */ | 
|  | libname[0] = '\0'; | 
|  | linux_read_memory (l_name, libname, sizeof (libname) - 1); | 
|  | libname[sizeof (libname) - 1] = '\0'; | 
|  | if (libname[0] != '\0') | 
|  | { | 
|  | string_appendf (document, "<library name=\""); | 
|  | xml_escape_text_append (document, (char *) libname); | 
|  | string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" " | 
|  | "l_ld=\"0x%s\" lmid=\"0x%s\"/>", | 
|  | paddress (lm_addr), paddress (l_addr), | 
|  | paddress (l_ld), paddress (lmid)); | 
|  | } | 
|  |  | 
|  | lm_prev = lm_addr; | 
|  | lm_addr = l_next; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Construct qXfer:libraries-svr4:read reply.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::qxfer_libraries_svr4 (const char *annex, | 
|  | unsigned char *readbuf, | 
|  | unsigned const char *writebuf, | 
|  | CORE_ADDR offset, int len) | 
|  | { | 
|  | struct process_info_private *const priv = current_process ()->priv; | 
|  | char filename[PATH_MAX]; | 
|  | int is_elf64; | 
|  | unsigned int machine; | 
|  | CORE_ADDR lmid = 0, lm_addr = 0, lm_prev = 0; | 
|  |  | 
|  | if (writebuf != NULL) | 
|  | return -2; | 
|  | if (readbuf == NULL) | 
|  | return -1; | 
|  |  | 
|  | int pid = current_thread->id.lwp (); | 
|  | xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid); | 
|  | is_elf64 = elf_64_file_p (filename, &machine); | 
|  | const link_map_offsets *lmo; | 
|  | int ptr_size; | 
|  | if (is_elf64) | 
|  | { | 
|  | lmo = &lmo_64bit_offsets; | 
|  | ptr_size = 8; | 
|  | } | 
|  | else | 
|  | { | 
|  | lmo = &lmo_32bit_offsets; | 
|  | ptr_size = 4; | 
|  | } | 
|  |  | 
|  | while (annex[0] != '\0') | 
|  | { | 
|  | const char *sep; | 
|  | CORE_ADDR *addrp; | 
|  | int name_len; | 
|  |  | 
|  | sep = strchr (annex, '='); | 
|  | if (sep == NULL) | 
|  | break; | 
|  |  | 
|  | name_len = sep - annex; | 
|  | if (name_len == 4 && startswith (annex, "lmid")) | 
|  | addrp = &lmid; | 
|  | else if (name_len == 5 && startswith (annex, "start")) | 
|  | addrp = &lm_addr; | 
|  | else if (name_len == 4 && startswith (annex, "prev")) | 
|  | addrp = &lm_prev; | 
|  | else | 
|  | { | 
|  | annex = strchr (sep, ';'); | 
|  | if (annex == NULL) | 
|  | break; | 
|  | annex++; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | annex = decode_address_to_semicolon (addrp, sep + 1); | 
|  | } | 
|  |  | 
|  | std::string document = "<library-list-svr4 version=\"1.0\""; | 
|  |  | 
|  | /* When the starting LM_ADDR is passed in the annex, only traverse that | 
|  | namespace, which is assumed to be identified by LMID. | 
|  |  | 
|  | Otherwise, start with R_DEBUG and traverse all namespaces we find.  */ | 
|  | if (lm_addr != 0) | 
|  | { | 
|  | document += ">"; | 
|  | read_link_map (document, lmid, lm_addr, lm_prev, ptr_size, lmo); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (lm_prev != 0) | 
|  | warning ("ignoring prev=0x%s without start", paddress (lm_prev)); | 
|  |  | 
|  | /* We could interpret LMID as 'provide only the libraries for this | 
|  | namespace' but GDB is currently only providing lmid, start, and | 
|  | prev, or nothing.  */ | 
|  | if (lmid != 0) | 
|  | warning ("ignoring lmid=0x%s without start", paddress (lmid)); | 
|  |  | 
|  | CORE_ADDR r_debug = priv->r_debug; | 
|  | if (r_debug == 0) | 
|  | r_debug = priv->r_debug = get_r_debug (pid, is_elf64); | 
|  |  | 
|  | /* We failed to find DT_DEBUG.  Such situation will not change | 
|  | for this inferior - do not retry it.  Report it to GDB as | 
|  | E01, see for the reasons at the GDB solib-svr4.c side.  */ | 
|  | if (r_debug == (CORE_ADDR) -1) | 
|  | return -1; | 
|  |  | 
|  | /* Terminate the header if we end up with an empty list.  */ | 
|  | if (r_debug == 0) | 
|  | document += ">"; | 
|  |  | 
|  | while (r_debug != 0) | 
|  | { | 
|  | int r_version = 0; | 
|  | if (linux_read_memory (r_debug + lmo->r_version_offset, | 
|  | (unsigned char *) &r_version, | 
|  | sizeof (r_version)) != 0) | 
|  | { | 
|  | warning ("unable to read r_version from 0x%s", | 
|  | paddress (r_debug + lmo->r_version_offset)); | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (r_version < 1) | 
|  | { | 
|  | warning ("unexpected r_debug version %d", r_version); | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (read_one_ptr (r_debug + lmo->r_map_offset, &lm_addr, | 
|  | ptr_size) != 0) | 
|  | { | 
|  | warning ("unable to read r_map from 0x%s", | 
|  | paddress (r_debug + lmo->r_map_offset)); | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* We read the entire namespace.  */ | 
|  | lm_prev = 0; | 
|  |  | 
|  | /* The first entry corresponds to the main executable unless the | 
|  | dynamic loader was loaded late by a static executable.  But | 
|  | in such case the main executable does not have PT_DYNAMIC | 
|  | present and we would not have gotten here.  */ | 
|  | if (r_debug == priv->r_debug) | 
|  | { | 
|  | if (lm_addr != 0) | 
|  | string_appendf (document, " main-lm=\"0x%s\">", | 
|  | paddress (lm_addr)); | 
|  | else | 
|  | document += ">"; | 
|  |  | 
|  | lm_prev = lm_addr; | 
|  | if (read_one_ptr (lm_addr + lmo->l_next_offset, | 
|  | &lm_addr, ptr_size) != 0) | 
|  | { | 
|  | warning ("unable to read l_next from 0x%s", | 
|  | paddress (lm_addr + lmo->l_next_offset)); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | read_link_map (document, r_debug, lm_addr, lm_prev, ptr_size, lmo); | 
|  |  | 
|  | if (r_version < 2) | 
|  | break; | 
|  |  | 
|  | if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug, | 
|  | ptr_size) != 0) | 
|  | { | 
|  | warning ("unable to read r_next from 0x%s", | 
|  | paddress (r_debug + lmo->r_next_offset)); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | document += "</library-list-svr4>"; | 
|  |  | 
|  | int document_len = document.length (); | 
|  | if (offset < document_len) | 
|  | document_len -= offset; | 
|  | else | 
|  | document_len = 0; | 
|  | if (len > document_len) | 
|  | len = document_len; | 
|  |  | 
|  | memcpy (readbuf, document.data () + offset, len); | 
|  |  | 
|  | return len; | 
|  | } | 
|  |  | 
|  | #ifdef HAVE_LINUX_BTRACE | 
|  |  | 
|  | bool | 
|  | linux_process_target::supports_btrace () | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | btrace_target_info * | 
|  | linux_process_target::enable_btrace (thread_info *tp, | 
|  | const btrace_config *conf) | 
|  | { | 
|  | return linux_enable_btrace (tp->id, conf); | 
|  | } | 
|  |  | 
|  | /* See to_disable_btrace target method.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::disable_btrace (btrace_target_info *tinfo) | 
|  | { | 
|  | enum btrace_error err; | 
|  |  | 
|  | err = linux_disable_btrace (tinfo); | 
|  | return (err == BTRACE_ERR_NONE ? 0 : -1); | 
|  | } | 
|  |  | 
|  | /* Encode an Intel Processor Trace configuration.  */ | 
|  |  | 
|  | static void | 
|  | linux_low_encode_pt_config (std::string *buffer, | 
|  | const struct btrace_data_pt_config *config) | 
|  | { | 
|  | *buffer += "<pt-config>\n"; | 
|  |  | 
|  | switch (config->cpu.vendor) | 
|  | { | 
|  | case CV_INTEL: | 
|  | string_xml_appendf (*buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" " | 
|  | "model=\"%u\" stepping=\"%u\"/>\n", | 
|  | config->cpu.family, config->cpu.model, | 
|  | config->cpu.stepping); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | *buffer += "</pt-config>\n"; | 
|  | } | 
|  |  | 
|  | /* Encode a raw buffer.  */ | 
|  |  | 
|  | static void | 
|  | linux_low_encode_raw (std::string *buffer, const gdb_byte *data, | 
|  | unsigned int size) | 
|  | { | 
|  | if (size == 0) | 
|  | return; | 
|  |  | 
|  | /* We use hex encoding - see gdbsupport/rsp-low.h.  */ | 
|  | *buffer += "<raw>\n"; | 
|  |  | 
|  | while (size-- > 0) | 
|  | { | 
|  | char elem[2]; | 
|  |  | 
|  | elem[0] = tohex ((*data >> 4) & 0xf); | 
|  | elem[1] = tohex (*data++ & 0xf); | 
|  |  | 
|  | buffer->append (elem, 2); | 
|  | } | 
|  |  | 
|  | *buffer += "</raw>\n"; | 
|  | } | 
|  |  | 
|  | /* See to_read_btrace target method.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::read_btrace (btrace_target_info *tinfo, | 
|  | std::string *buffer, | 
|  | enum btrace_read_type type) | 
|  | { | 
|  | struct btrace_data btrace; | 
|  | enum btrace_error err; | 
|  |  | 
|  | err = linux_read_btrace (&btrace, tinfo, type); | 
|  | if (err != BTRACE_ERR_NONE) | 
|  | { | 
|  | if (err == BTRACE_ERR_OVERFLOW) | 
|  | *buffer += "E.Overflow."; | 
|  | else | 
|  | *buffer += "E.Generic Error."; | 
|  |  | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | switch (btrace.format) | 
|  | { | 
|  | case BTRACE_FORMAT_NONE: | 
|  | *buffer += "E.No Trace."; | 
|  | return -1; | 
|  |  | 
|  | case BTRACE_FORMAT_BTS: | 
|  | *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n"; | 
|  | *buffer += "<btrace version=\"1.0\">\n"; | 
|  |  | 
|  | for (const btrace_block &block : *btrace.variant.bts.blocks) | 
|  | string_xml_appendf (*buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n", | 
|  | paddress (block.begin), paddress (block.end)); | 
|  |  | 
|  | *buffer += "</btrace>\n"; | 
|  | break; | 
|  |  | 
|  | case BTRACE_FORMAT_PT: | 
|  | *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n"; | 
|  | *buffer += "<btrace version=\"1.0\">\n"; | 
|  | *buffer += "<pt>\n"; | 
|  |  | 
|  | linux_low_encode_pt_config (buffer, &btrace.variant.pt.config); | 
|  |  | 
|  | linux_low_encode_raw (buffer, btrace.variant.pt.data, | 
|  | btrace.variant.pt.size); | 
|  |  | 
|  | *buffer += "</pt>\n"; | 
|  | *buffer += "</btrace>\n"; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | *buffer += "E.Unsupported Trace Format."; | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* See to_btrace_conf target method.  */ | 
|  |  | 
|  | int | 
|  | linux_process_target::read_btrace_conf (const btrace_target_info *tinfo, | 
|  | std::string *buffer) | 
|  | { | 
|  | const struct btrace_config *conf; | 
|  |  | 
|  | *buffer += "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n"; | 
|  | *buffer += "<btrace-conf version=\"1.0\">\n"; | 
|  |  | 
|  | conf = linux_btrace_conf (tinfo); | 
|  | if (conf != NULL) | 
|  | { | 
|  | switch (conf->format) | 
|  | { | 
|  | case BTRACE_FORMAT_NONE: | 
|  | break; | 
|  |  | 
|  | case BTRACE_FORMAT_BTS: | 
|  | string_xml_appendf (*buffer, "<bts"); | 
|  | string_xml_appendf (*buffer, " size=\"0x%x\"", conf->bts.size); | 
|  | string_xml_appendf (*buffer, " />\n"); | 
|  | break; | 
|  |  | 
|  | case BTRACE_FORMAT_PT: | 
|  | string_xml_appendf (*buffer, "<pt"); | 
|  | string_xml_appendf (*buffer, " size=\"0x%x\"", conf->pt.size); | 
|  | string_xml_appendf (*buffer, "/>\n"); | 
|  | string_xml_appendf (*buffer, " ptwrite=\"%s\"", | 
|  | conf->pt.ptwrite ? "yes" : "no"); | 
|  | string_xml_appendf (*buffer, " event-tracing=\"%s\"", | 
|  | conf->pt.event_tracing ? "yes" : "no"); | 
|  | string_xml_appendf (*buffer, "/>\n"); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | *buffer += "</btrace-conf>\n"; | 
|  | return 0; | 
|  | } | 
|  | #endif /* HAVE_LINUX_BTRACE */ | 
|  |  | 
|  | /* See nat/linux-nat.h.  */ | 
|  |  | 
|  | ptid_t | 
|  | current_lwp_ptid (void) | 
|  | { | 
|  | return current_thread->id; | 
|  | } | 
|  |  | 
|  | /* A helper function that copies NAME to DEST, replacing non-printable | 
|  | characters with '?'.  Returns the original DEST as a | 
|  | convenience.  */ | 
|  |  | 
|  | static const char * | 
|  | replace_non_ascii (char *dest, const char *name) | 
|  | { | 
|  | const char *result = dest; | 
|  | while (*name != '\0') | 
|  | { | 
|  | if (!ISPRINT (*name)) | 
|  | *dest++ = '?'; | 
|  | else | 
|  | *dest++ = *name; | 
|  | ++name; | 
|  | } | 
|  | *dest = '\0'; | 
|  | return result; | 
|  | } | 
|  |  | 
|  | const char * | 
|  | linux_process_target::thread_name (ptid_t thread) | 
|  | { | 
|  | static char dest[100]; | 
|  |  | 
|  | const char *name = linux_proc_tid_get_name (thread); | 
|  | if (name == nullptr) | 
|  | return nullptr; | 
|  |  | 
|  | /* Linux limits the comm file to 16 bytes (including the trailing | 
|  | \0.  If the program or thread name is set when using a multi-byte | 
|  | encoding, this might cause it to be truncated mid-character.  In | 
|  | this situation, sending the truncated form in an XML <thread> | 
|  | response will cause a parse error in gdb.  So, instead convert | 
|  | from the locale's encoding (we can't be sure this is the correct | 
|  | encoding, but it's as good a guess as we have) to UTF-8, but in a | 
|  | way that ignores any encoding errors.  See PR remote/30618.  */ | 
|  | const char *cset = nl_langinfo (CODESET); | 
|  | iconv_t handle = iconv_open ("UTF-8//IGNORE", cset); | 
|  | if (handle == (iconv_t) -1) | 
|  | return replace_non_ascii (dest, name); | 
|  |  | 
|  | size_t inbytes = strlen (name); | 
|  | char *inbuf = const_cast<char *> (name); | 
|  | size_t outbytes = sizeof (dest); | 
|  | char *outbuf = dest; | 
|  | size_t result = iconv (handle, &inbuf, &inbytes, &outbuf, &outbytes); | 
|  |  | 
|  | if (result == (size_t) -1) | 
|  | { | 
|  | if (errno == E2BIG) | 
|  | outbuf = &dest[sizeof (dest) - 1]; | 
|  | else if ((errno == EILSEQ || errno == EINVAL) | 
|  | && outbuf < &dest[sizeof (dest) - 2]) | 
|  | *outbuf++ = '?'; | 
|  | } | 
|  | *outbuf = '\0'; | 
|  |  | 
|  | iconv_close (handle); | 
|  | return *dest == '\0' ? nullptr : dest; | 
|  | } | 
|  |  | 
|  | #if USE_THREAD_DB | 
|  | bool | 
|  | linux_process_target::thread_handle (ptid_t ptid, gdb_byte **handle, | 
|  | int *handle_len) | 
|  | { | 
|  | return thread_db_thread_handle (ptid, handle, handle_len); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | thread_info * | 
|  | linux_process_target::thread_pending_parent (thread_info *thread) | 
|  | { | 
|  | lwp_info *parent = get_thread_lwp (thread)->pending_parent (); | 
|  |  | 
|  | if (parent == nullptr) | 
|  | return nullptr; | 
|  |  | 
|  | return parent->thread; | 
|  | } | 
|  |  | 
|  | thread_info * | 
|  | linux_process_target::thread_pending_child (thread_info *thread, | 
|  | target_waitkind *kind) | 
|  | { | 
|  | lwp_info *child = get_thread_lwp (thread)->pending_child (kind); | 
|  |  | 
|  | if (child == nullptr) | 
|  | return nullptr; | 
|  |  | 
|  | return child->thread; | 
|  | } | 
|  |  | 
|  | /* Default implementation of linux_target_ops method "set_pc" for | 
|  | 32-bit pc register which is literally named "pc".  */ | 
|  |  | 
|  | void | 
|  | linux_set_pc_32bit (struct regcache *regcache, CORE_ADDR pc) | 
|  | { | 
|  | uint32_t newpc = pc; | 
|  |  | 
|  | supply_register_by_name (regcache, "pc", &newpc); | 
|  | } | 
|  |  | 
|  | /* Default implementation of linux_target_ops method "get_pc" for | 
|  | 32-bit pc register which is literally named "pc".  */ | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_get_pc_32bit (struct regcache *regcache) | 
|  | { | 
|  | uint32_t pc; | 
|  |  | 
|  | collect_register_by_name (regcache, "pc", &pc); | 
|  | threads_debug_printf ("stop pc is 0x%" PRIx32, pc); | 
|  | return pc; | 
|  | } | 
|  |  | 
|  | /* Default implementation of linux_target_ops method "set_pc" for | 
|  | 64-bit pc register which is literally named "pc".  */ | 
|  |  | 
|  | void | 
|  | linux_set_pc_64bit (struct regcache *regcache, CORE_ADDR pc) | 
|  | { | 
|  | uint64_t newpc = pc; | 
|  |  | 
|  | supply_register_by_name (regcache, "pc", &newpc); | 
|  | } | 
|  |  | 
|  | /* Default implementation of linux_target_ops method "get_pc" for | 
|  | 64-bit pc register which is literally named "pc".  */ | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_get_pc_64bit (struct regcache *regcache) | 
|  | { | 
|  | uint64_t pc; | 
|  |  | 
|  | collect_register_by_name (regcache, "pc", &pc); | 
|  | threads_debug_printf ("stop pc is 0x%" PRIx64, pc); | 
|  | return pc; | 
|  | } | 
|  |  | 
|  | /* See linux-low.h.  */ | 
|  |  | 
|  | int | 
|  | linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp) | 
|  | { | 
|  | gdb_byte *data = (gdb_byte *) alloca (2 * wordsize); | 
|  | int offset = 0; | 
|  |  | 
|  | gdb_assert (wordsize == 4 || wordsize == 8); | 
|  |  | 
|  | while (the_target->read_auxv (pid, offset, data, 2 * wordsize) | 
|  | == 2 * wordsize) | 
|  | { | 
|  | if (wordsize == 4) | 
|  | { | 
|  | uint32_t *data_p = (uint32_t *) data; | 
|  | if (data_p[0] == match) | 
|  | { | 
|  | *valp = data_p[1]; | 
|  | return 1; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | uint64_t *data_p = (uint64_t *) data; | 
|  | if (data_p[0] == match) | 
|  | { | 
|  | *valp = data_p[1]; | 
|  | return 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | offset += 2 * wordsize; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* See linux-low.h.  */ | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_get_hwcap (int pid, int wordsize) | 
|  | { | 
|  | CORE_ADDR hwcap = 0; | 
|  | linux_get_auxv (pid, wordsize, AT_HWCAP, &hwcap); | 
|  | return hwcap; | 
|  | } | 
|  |  | 
|  | /* See linux-low.h.  */ | 
|  |  | 
|  | CORE_ADDR | 
|  | linux_get_hwcap2 (int pid, int wordsize) | 
|  | { | 
|  | CORE_ADDR hwcap2 = 0; | 
|  | linux_get_auxv (pid, wordsize, AT_HWCAP2, &hwcap2); | 
|  | return hwcap2; | 
|  | } | 
|  |  | 
|  | #ifdef HAVE_LINUX_REGSETS | 
|  | void | 
|  | initialize_regsets_info (struct regsets_info *info) | 
|  | { | 
|  | for (info->num_regsets = 0; | 
|  | info->regsets[info->num_regsets].size >= 0; | 
|  | info->num_regsets++) | 
|  | ; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | void | 
|  | initialize_low (void) | 
|  | { | 
|  | struct sigaction sigchld_action; | 
|  |  | 
|  | memset (&sigchld_action, 0, sizeof (sigchld_action)); | 
|  | set_target_ops (the_linux_target); | 
|  |  | 
|  | linux_ptrace_init_warnings (); | 
|  | linux_proc_init_warnings (); | 
|  |  | 
|  | sigchld_action.sa_handler = sigchld_handler; | 
|  | sigemptyset (&sigchld_action.sa_mask); | 
|  | sigchld_action.sa_flags = SA_RESTART; | 
|  | sigaction (SIGCHLD, &sigchld_action, NULL); | 
|  |  | 
|  | initialize_low_arch (); | 
|  |  | 
|  | linux_check_ptrace_features (); | 
|  | } |