diff options
Diffstat (limited to 'gdbserver')
-rw-r--r-- | gdbserver/ChangeLog | 64 | ||||
-rw-r--r-- | gdbserver/linux-low.cc | 192 | ||||
-rw-r--r-- | gdbserver/linux-low.h | 78 |
3 files changed, 213 insertions, 121 deletions
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 5f543bb..d6d5eee 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,5 +1,69 @@ 2020-04-02 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> + Turn some more static methods in linux-low into private methods + of linux_process_target. + + * linux-low.cc (get_pc): Turn into... + (linux_process_target::get_pc): ...this. + (save_stop_reason): Turn into... + (linux_process_target::save_stop_reason): ...this. + (thread_still_has_status_pending_p): Turn into... + (linux_process_target::thread_still_has_status_pending): ...this. + (status_pending_p_callback): Turn into... + (linux_process_target::status_pending_p_callback): ...this. + (resume_stopped_resumed_lwps): Turn into... + (linux_process_target::resume_stopped_resumed_lwps): ...this. + (install_software_single_step_breakpoints): Turn into... + (linux_process_target::install_software_single_step_breakpoints): + ...this. + (single_step): Turn into... + (linux_process_target::single_step): ...this. + (linux_resume_one_lwp_throw): Turn into... + (linux_process_target::resume_one_lwp_throw): ...this. + (linux_resume_one_lwp): Turn into... + (linux_process_target::resume_one_lwp): ...this. + (resume_status_pending_p): Turn into... + (linux_process_target::resume_status_pending): ...this. + (need_step_over_p): Turn into... + (linux_process_target::thread_needs_step_over): ...this. + (linux_resume_one_thread): Turn into... + (linux_process_target::resume_one_thread): ...this. + (proceed_one_lwp): Turn into... + (linux_process_target::proceed_one_lwp): ...this. + (unsuspend_and_proceed_one_lwp): Turn into... + (linux_process_target::unsuspend_and_proceed_one_lwp): ...this. + + Update the calls/references to the above functions below. + + (linux_process_target::handle_extended_wait) + (linux_process_target::filter_event) + (linux_process_target::wait_for_event_filtered) + (linux_process_target::wait_1) + (linux_process_target::move_out_of_jump_pad) + (linux_process_target::start_step_over) + (linux_process_target::resume) + (linux_process_target::proceed_all_lwps) + (regsets_store_inferior_registers) + (linux_process_target::store_register) + + * linux-low.h (class linux_process_target) + <get_pc> + <save_stop_reason> + <thread_still_has_status_pending> + <status_pending_p_callback> + <resume_stopped_resumed_lwps> + <install_software_single_step_breakpoints> + <single_step> + <resume_one_lwp_throw> + <resume_one_lwp> + <resume_status_pending> + <thread_needs_step_over> + <resume_one_thread> + <proceed_one_lwp> + <unsuspend_and_proceed_one_lwp>: Declare. + +2020-04-02 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> + Turn the 'fetch_register' linux target op into a method of linux_process_target. diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index c77e92d..65edde8 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -267,8 +267,6 @@ int using_threads = 1; jump pads). */ static int stabilizing_threads; -static void linux_resume_one_lwp (struct lwp_info *lwp, - int step, int signal, siginfo_t *info); static void unsuspend_all_lwps (struct lwp_info *except); static struct lwp_info *add_lwp (ptid_t ptid); static void mark_lwp_dead (struct lwp_info *lwp, int wstat); @@ -278,7 +276,6 @@ 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); -static void proceed_one_lwp (thread_info *thread, lwp_info *except); /* When the event-loop is doing a step-over, this points at the thread being stepped. */ @@ -438,8 +435,6 @@ linux_add_process (int pid, int attached) return proc; } -static CORE_ADDR get_pc (struct lwp_info *lwp); - void linux_process_target::arch_setup_thread (thread_info *thread) { @@ -616,9 +611,9 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, new_lwp = add_lwp (ptid); /* Either we're going to immediately resume the new thread - or leave it stopped. linux_resume_one_lwp is a nop if it + or leave it stopped. resume_one_lwp is a nop if it thinks the thread is currently running, so set this first - before calling linux_resume_one_lwp. */ + before calling resume_one_lwp. */ new_lwp->stopped = 1; /* If we're suspending all threads, leave this one suspended @@ -726,11 +721,8 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event); } -/* Return the PC as read from the regcache of LWP, without any - adjustment. */ - -static CORE_ADDR -get_pc (struct lwp_info *lwp) +CORE_ADDR +linux_process_target::get_pc (lwp_info *lwp) { struct thread_info *saved_thread; struct regcache *regcache; @@ -783,14 +775,8 @@ get_syscall_trapinfo (struct lwp_info *lwp, int *sysno) static int check_stopped_by_watchpoint (struct lwp_info *child); -/* Called when the LWP stopped for a signal/trap. If it stopped for a - trap check what caused it (breakpoint, watchpoint, trace, etc.), - and save the result in the LWP's stop_reason field. If it stopped - for a breakpoint, decrement the PC if necessary on the lwp's - architecture. Returns true if we now have the LWP's stop PC. */ - -static int -save_stop_reason (struct lwp_info *lwp) +bool +linux_process_target::save_stop_reason (lwp_info *lwp) { CORE_ADDR pc; CORE_ADDR sw_breakpoint_pc; @@ -800,7 +786,7 @@ save_stop_reason (struct lwp_info *lwp) #endif if (the_low_target.get_pc == NULL) - return 0; + return false; pc = get_pc (lwp); sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break; @@ -921,7 +907,7 @@ save_stop_reason (struct lwp_info *lwp) lwp->stop_pc = pc; current_thread = saved_thread; - return 1; + return true; } static struct lwp_info * @@ -1678,12 +1664,8 @@ linux_process_target::thread_alive (ptid_t ptid) return 0; } -/* Return 1 if this lwp still has an interesting status pending. If - not (e.g., it had stopped for a breakpoint that is gone), return - false. */ - -static int -thread_still_has_status_pending_p (struct thread_info *thread) +bool +linux_process_target::thread_still_has_status_pending (thread_info *thread) { struct lwp_info *lp = get_thread_lwp (thread); @@ -1766,9 +1748,9 @@ lwp_resumed (struct lwp_info *lwp) return 0; } -/* Return true if this lwp has an interesting status pending. */ -static bool -status_pending_p_callback (thread_info *thread, ptid_t ptid) +bool +linux_process_target::status_pending_p_callback (thread_info *thread, + ptid_t ptid) { struct lwp_info *lp = get_thread_lwp (thread); @@ -1781,9 +1763,9 @@ status_pending_p_callback (thread_info *thread, ptid_t ptid) return 0; if (lp->status_pending_p - && !thread_still_has_status_pending_p (thread)) + && !thread_still_has_status_pending (thread)) { - linux_resume_one_lwp (lp, lp->stepping, GDB_SIGNAL_0, NULL); + resume_one_lwp (lp, lp->stepping, GDB_SIGNAL_0, NULL); return 0; } @@ -2517,7 +2499,7 @@ linux_process_target::filter_event (int lwpid, int wstat) child->stepping ? "step" : "continue", target_pid_to_str (ptid_of (thread))); - linux_resume_one_lwp (child, child->stepping, 0, NULL); + resume_one_lwp (child, child->stepping, 0, NULL); return NULL; } } @@ -2543,11 +2525,8 @@ maybe_hw_step (struct thread_info *thread) } } -/* Resume LWPs that are currently stopped without any pending status - to report, but are resumed from the core's perspective. */ - -static void -resume_stopped_resumed_lwps (thread_info *thread) +void +linux_process_target::resume_stopped_resumed_lwps (thread_info *thread) { struct lwp_info *lp = get_thread_lwp (thread); @@ -2567,7 +2546,7 @@ resume_stopped_resumed_lwps (thread_info *thread) paddress (lp->stop_pc), step); - linux_resume_one_lwp (lp, step, GDB_SIGNAL_0, NULL); + resume_one_lwp (lp, step, GDB_SIGNAL_0, NULL); } } @@ -2614,7 +2593,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid, &requested_child->status_pending); requested_child->status_pending_p = 0; requested_child->status_pending = 0; - linux_resume_one_lwp (requested_child, 0, 0, NULL); + resume_one_lwp (requested_child, 0, 0, NULL); } if (requested_child->suspended @@ -2702,7 +2681,10 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid, /* 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 (resume_stopped_resumed_lwps); + 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. */ @@ -3272,7 +3254,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n", WSTOPSIG (w), lwpid_of (current_thread)); - linux_resume_one_lwp (event_child, 0, 0, NULL); + resume_one_lwp (event_child, 0, 0, NULL); if (debug_threads) debug_exit (); @@ -3372,8 +3354,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, lwpid_of (current_thread)); } - linux_resume_one_lwp (event_child, event_child->stepping, - 0, NULL); + resume_one_lwp (event_child, event_child->stepping, 0, NULL); if (debug_threads) debug_exit (); @@ -3429,8 +3410,8 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, } else { - linux_resume_one_lwp (event_child, event_child->stepping, - WSTOPSIG (w), info_p); + resume_one_lwp (event_child, event_child->stepping, + WSTOPSIG (w), info_p); } if (debug_threads) @@ -4039,7 +4020,7 @@ linux_process_target::move_out_of_jump_pad (thread_info *thread) WSTOPSIG (*wstat), lwpid_of (thread)); } - linux_resume_one_lwp (lwp, 0, 0, NULL); + resume_one_lwp (lwp, 0, 0, NULL); } else lwp_suspended_inc (lwp); @@ -4117,10 +4098,8 @@ enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info) lwp->pending_signals = p_sig; } -/* Install breakpoints for software single stepping. */ - -static void -install_software_single_step_breakpoints (struct lwp_info *lwp) +void +linux_process_target::install_software_single_step_breakpoints (lwp_info *lwp) { struct thread_info *thread = get_lwp_thread (lwp); struct regcache *regcache = get_thread_regcache (thread, 1); @@ -4134,12 +4113,8 @@ install_software_single_step_breakpoints (struct lwp_info *lwp) set_single_step_breakpoint (pc, current_ptid); } -/* Single step via hardware or software single step. - Return 1 if hardware single stepping, 0 if software single stepping - or can't single step. */ - -static int -single_step (struct lwp_info* lwp) +int +linux_process_target::single_step (lwp_info* lwp) { int step = 0; @@ -4174,12 +4149,9 @@ lwp_signal_can_be_delivered (struct lwp_info *lwp) == fast_tpoint_collect_result::not_collecting); } -/* Resume execution of LWP. If STEP is nonzero, single-step it. If - SIGNAL is nonzero, give it that signal. */ - -static void -linux_resume_one_lwp_throw (struct lwp_info *lwp, - int step, int signal, siginfo_t *info) +void +linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step, + int signal, siginfo_t *info) { struct thread_info *thread = get_lwp_thread (lwp); struct thread_info *saved_thread; @@ -4416,16 +4388,13 @@ check_ptrace_stopped_lwp_gone (struct lwp_info *lp) return 0; } -/* Like linux_resume_one_lwp_throw, but no error is thrown if the LWP - disappears while we try to resume it. */ - -static void -linux_resume_one_lwp (struct lwp_info *lwp, - int step, int signal, siginfo_t *info) +void +linux_process_target::resume_one_lwp (lwp_info *lwp, int step, int signal, + siginfo_t *info) { try { - linux_resume_one_lwp_throw (lwp, step, signal, info); + resume_one_lwp_throw (lwp, step, signal, info); } catch (const gdb_exception_error &ex) { @@ -4546,11 +4515,8 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n) lwp->resume = NULL; } -/* find_thread callback for linux_resume. Return true if this lwp has an - interesting status pending. */ - -static bool -resume_status_pending_p (thread_info *thread) +bool +linux_process_target::resume_status_pending (thread_info *thread) { struct lwp_info *lwp = get_thread_lwp (thread); @@ -4559,16 +4525,11 @@ resume_status_pending_p (thread_info *thread) if (lwp->resume == NULL) return false; - return thread_still_has_status_pending_p (thread); + return thread_still_has_status_pending (thread); } -/* Return 1 if this lwp that GDB wants running is stopped at an - internal breakpoint that we need to step over. It assumes that any - required STOP_PC adjustment has already been propagated to the - inferior's regcache. */ - -static bool -need_step_over_p (thread_info *thread) +bool +linux_process_target::thread_needs_step_over (thread_info *thread) { struct lwp_info *lwp = get_thread_lwp (thread); struct thread_info *saved_thread; @@ -4739,7 +4700,7 @@ linux_process_target::start_step_over (lwp_info *lwp) current_thread = saved_thread; - linux_resume_one_lwp (lwp, step, 0, NULL); + resume_one_lwp (lwp, step, 0, NULL); /* Require next event from this LWP. */ step_over_bkpt = thread->id; @@ -4814,21 +4775,9 @@ linux_process_target::complete_ongoing_step_over () } } -/* This function is called once per thread. We check the thread's resume - request, which will tell us whether to resume, step, or leave the thread - stopped; and what signal, if any, it should be sent. - - For threads which we aren't explicitly told otherwise, we preserve - the stepping flag; this is used for stepping over gdbserver-placed - breakpoints. - - If pending_flags was set in any thread, we queue any needed - signals, since we won't actually resume. We already have a pending - event to report, so we don't need to preserve any step requests; - they should be re-issued if necessary. */ - -static void -linux_resume_one_thread (thread_info *thread, bool leave_all_stopped) +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; @@ -4955,7 +4904,10 @@ linux_process_target::resume (thread_resume *resume_info, size_t n) before considering to start a step-over (in all-stop). */ bool any_pending = false; if (!non_stop) - any_pending = find_thread (resume_status_pending_p) != NULL; + 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 @@ -4964,7 +4916,10 @@ linux_process_target::resume (thread_resume *resume_info, size_t n) to queue any signals that would otherwise be delivered or queued. */ if (!any_pending && supports_breakpoints ()) - need_step_over = find_thread (need_step_over_p); + 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); @@ -4983,7 +4938,7 @@ linux_process_target::resume (thread_resume *resume_info, size_t n) otherwise deliver. */ for_each_thread ([&] (thread_info *thread) { - linux_resume_one_thread (thread, leave_all_stopped); + resume_one_thread (thread, leave_all_stopped); }); if (need_step_over) @@ -5001,17 +4956,8 @@ linux_process_target::resume (thread_resume *resume_info, size_t n) async_file_mark (); } -/* This function is called once per thread. We check the thread's - last resume request, which will tell us whether to resume, step, or - leave the thread stopped. Any signal the client requested to be - delivered has already been enqueued at this point. - - If any thread that GDB wants running is stopped at an internal - breakpoint that needs stepping over, we start a step-over operation - on that particular thread, and leave all others stopped. */ - -static void -proceed_one_lwp (thread_info *thread, lwp_info *except) +void +linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except) { struct lwp_info *lwp = get_thread_lwp (thread); int step; @@ -5104,11 +5050,12 @@ proceed_one_lwp (thread_info *thread, lwp_info *except) else step = 0; - linux_resume_one_lwp (lwp, step, 0, NULL); + resume_one_lwp (lwp, step, 0, NULL); } -static void -unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except) +void +linux_process_target::unsuspend_and_proceed_one_lwp (thread_info *thread, + lwp_info *except) { struct lwp_info *lwp = get_thread_lwp (thread); @@ -5132,7 +5079,10 @@ linux_process_target::proceed_all_lwps () if (supports_breakpoints ()) { - need_step_over = find_thread (need_step_over_p); + need_step_over = find_thread ([this] (thread_info *thread) + { + return thread_needs_step_over (thread); + }); if (need_step_over != NULL) { @@ -5149,7 +5099,7 @@ linux_process_target::proceed_all_lwps () if (debug_threads) debug_printf ("Proceeding, no step-over needed\n"); - for_each_thread ([] (thread_info *thread) + for_each_thread ([this] (thread_info *thread) { proceed_one_lwp (thread, NULL); }); @@ -5362,7 +5312,7 @@ regsets_store_inferior_registers (struct regsets_info *regsets_info, /* 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 linux_resume_one_lwp. */ + comment in resume_one_lwp. */ free (buf); return 0; } @@ -5509,7 +5459,7 @@ linux_process_target::store_register (const usrregs_info *usrregs, /* 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 linux_resume_one_lwp. */ + comment in resume_one_lwp. */ if (errno == ESRCH) return; diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h index 7ac9086..4f5502b 100644 --- a/gdbserver/linux-low.h +++ b/gdbserver/linux-low.h @@ -580,6 +580,84 @@ private: void usr_store_inferior_registers (const regs_info *regs_info, regcache *regcache, int regno, int all); + /* Return the PC as read from the regcache of LWP, without any + adjustment. */ + CORE_ADDR get_pc (lwp_info *lwp); + + /* Called when the LWP stopped for a signal/trap. If it stopped for a + trap check what caused it (breakpoint, watchpoint, trace, etc.), + and save the result in the LWP's stop_reason field. If it stopped + for a breakpoint, decrement the PC if necessary on the lwp's + architecture. Returns true if we now have the LWP's stop PC. */ + bool save_stop_reason (lwp_info *lwp); + + /* Resume execution of LWP. If STEP is nonzero, single-step it. If + SIGNAL is nonzero, give it that signal. */ + void resume_one_lwp_throw (lwp_info *lwp, int step, int signal, + siginfo_t *info); + + /* Like resume_one_lwp_throw, but no error is thrown if the LWP + disappears while we try to resume it. */ + void resume_one_lwp (lwp_info *lwp, int step, int signal, siginfo_t *info); + + /* This function is called once per thread. We check the thread's + last resume request, which will tell us whether to resume, step, or + leave the thread stopped. Any signal the client requested to be + delivered has already been enqueued at this point. + + If any thread that GDB wants running is stopped at an internal + breakpoint that needs stepping over, we start a step-over operation + on that particular thread, and leave all others stopped. */ + void proceed_one_lwp (thread_info *thread, lwp_info *except); + + /* This function is called once per thread. We check the thread's + resume request, which will tell us whether to resume, step, or + leave the thread stopped; and what signal, if any, it should be + sent. + + For threads which we aren't explicitly told otherwise, we preserve + the stepping flag; this is used for stepping over gdbserver-placed + breakpoints. + + If pending_flags was set in any thread, we queue any needed + signals, since we won't actually resume. We already have a pending + event to report, so we don't need to preserve any step requests; + they should be re-issued if necessary. */ + void resume_one_thread (thread_info *thread, bool leave_all_stopped); + + /* Return true if this lwp has an interesting status pending. */ + bool status_pending_p_callback (thread_info *thread, ptid_t ptid); + + /* Resume LWPs that are currently stopped without any pending status + to report, but are resumed from the core's perspective. */ + void resume_stopped_resumed_lwps (thread_info *thread); + + /* Unsuspend THREAD, except EXCEPT, and proceed. */ + void unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except); + + /* Return true if this lwp still has an interesting status pending. + If not (e.g., it had stopped for a breakpoint that is gone), return + false. */ + bool thread_still_has_status_pending (thread_info *thread); + + /* Return true if this lwp is to-be-resumed and has an interesting + status pending. */ + bool resume_status_pending (thread_info *thread); + + /* Return true if this lwp that GDB wants running is stopped at an + internal breakpoint that we need to step over. It assumes that + any required STOP_PC adjustment has already been propagated to + the inferior's regcache. */ + bool thread_needs_step_over (thread_info *thread); + + /* Single step via hardware or software single step. + Return 1 if hardware single stepping, 0 if software single stepping + or can't single step. */ + int single_step (lwp_info* lwp); + + /* Install breakpoints for software single stepping. */ + void install_software_single_step_breakpoints (lwp_info *lwp); + protected: /* The architecture-specific "low" methods are listed below. */ |