From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout.gmx.net (mout.gmx.net [212.227.15.18]) by sourceware.org (Postfix) with ESMTPS id 3B332385B835 for ; Fri, 17 Apr 2020 14:46:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3B332385B835 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gmx.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=n54@gmx.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1587134774; bh=VTDdEZOCzP0GMCUKp1SjAkLzUusUjVcZ57ayCnQBt+0=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date; b=cpHFaNM4dYazSVhhioy+CitgFvCgrwTmNR5EUlnf2t6ZpXdcZlSQ4FYAQ3nLU/nlD C1J4MlUn76lrSrNme6zDsspG03LAxcj/uJhHDvA5sp0fynOZnXpV882rl3q+KtPcXl SRcVhKUVujfyODVkTlPz91XjDIwDFxN0fWWxcADs= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([89.79.191.25]) by mail.gmx.com (mrgmx004 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MRmfo-1joBCe2evC-00T9Ci; Fri, 17 Apr 2020 16:46:14 +0200 From: Kamil Rytarowski To: gdb-patches@sourceware.org Subject: [PATCH] Add basic event handling in the NetBSD target Date: Fri, 17 Apr 2020 16:45:08 +0200 Message-Id: <20200417144508.6366-1-n54@gmx.com> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:2EVJScb+8QW7FxmAW1Gi3WqTzgtUIfla9RYZJnqRofAtc0r0vAy tiR1fwT5K1ZlpzOXIfFy47ZO66xbDfqUks7i8a8JaBxdWuP1V4GEkbhksWJasYWb5+2PWD+ Z1QLkuaorS1IqYpvLK3W0bjAq7lJSoq4XzqxCVyrBjpWot+TyA8CI2328DRTTgtXkvmn/U3 dr/9pbrXV0QPk4GB/V84g== X-UI-Out-Filterresults: notjunk:1;V03:K0:seEilZ2soaA=:iJwnMclCg2c1pzaudcBbf8 FSPqtDWWLBg/7CqV+uBC6PnUGvqAqRJu1tZuspWF1DWzrQfwo5rN1M/GLWHG78g8L429km4BN +XjD1D4rwlWEXSwyXVOwaZVtDWYP/ha7XINM4aiFIWBExs52rUiuudZOZTp+rkqH9Wxe7iUlI 9UAD2ctHlj13wX4Hpb2piC7xXfvbdnPVbDBJF4dmEjfUjVh9dSOFReYoITrRcBxmlgozJGE/U Wj79eVQtZgGGY/7My9MRYq1y52OyjmtKB482Nv4ZwNzcAeIY2Cao+XmRm8NjgIPdHmoegdt9j pHYXQz4P3u2Czpj1V3cmF1TjpTCTCAhZ0Swussis1llr7v4737byBeXVE2dCHceJTu7kraQqQ YfYrh86AiLdquoZly6N0EjfVTYzYBn+sI9Bq7yKR/WK9ofSl9fAUIJLd3Ou46wNm5tgVEBChD eXusNTmkQc5MNfDQqrLCSGP6v0u85Bcdie9qhQJRl71Fhb3VnGZ3mD7A1DbxjCkkxg6V7lEiI +SkkY4LRPtWEUDaa1zMTd7Zj4btwsC2k24F5IChhZj5vFkUyPKd6d9KruZxegXUvcL/HbbRPv FGGFT0ncpPbgXllFh1xsypZMmtN2AKAxb/Lo7KcD7Z8qHV60OYJu7/9GCm9W6PbofzLzzL7lq c8q0/ACgKeUjOb1/lageOuya5FvzrGWQsOf6fMyxiM9x6+wSSmYSkt+SqPBJf5rlf0kNSKudb V0abwtDkpUwPJpYuIi0bHF9HFTGAnEOhFRnHXM134NRWev8/dhTfwJZSL3sQ9C7ce8hBsZVS3 fHlQ17s4KWAJVM2o3doXIzr1Fe3GKhGxhK4nts0QJ38j/O1+vJc0Y5Lk5/ckQ38CE5FPoJi4k z/Kofg++ULZ9BOo5ITmEUvuDOD4ZW3ndBGG4r4dfX1Be199qXQASaMRbV5kbyFG5Gv3W2zumr Dc0a57lYe3VDPRrf8faz+AefET0ZXhW6BPi+DLhL1k1moLrA+xUDLLHpdAh/tElb5MKGJR+o3 R5Q+fCN0IkyoRmX0e2C1fqCxLv9vwT2usCgNzXcBO5Mw1FD8NkK4Ig0PaZfCuYmsPPrQVUPXG l4eWSDh3vMlEOrZBXnWHADzAmEEOvuh+p9/iAzQj6gLh6P6A978LBZbDFzKvXcQCYuuHZMtgJ Roho5g+mRbehJnYZOjsxyWqEtBN9Iqg+55Z3B53ljf0uzqmt/Fvcyz7eNW/BzB/ZSnrF0= X-Spam-Status: No, score=-28.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Apr 2020 14:46:21 -0000 Implement the following events: - single step (TRAP_TRACE) - software breakpoint (TRAP_DBREG) - exec() (TRAP_EXEC) - syscall entry/exit (TRAP_SCE / TRAP_SCX) Add support for NetBSD specific ::wait () and ::resume (). Instruct the generic code that exec and syscall events are supported. Define an empty nbsd_get_syscall_number as it is prerequisite for catching syscall entry and exit events, even if it is unused. This function is used to detect whether the gdbarch supports the 'catch syscall' feature. gdb/ChangeLog: * nbsd-nat.c: Include "sys/wait.h". * (nbsd_nat_target::resume, nbsd_wait, nbsd_nat_target::wait) (nbsd_nat_target::insert_exec_catchpoint) (nbsd_nat_target::remove_exec_catchpoint) (nbsd_nat_target::set_syscall_catchpoint): Add. * nbsd-nat.h (nbsd_nat_target::resume, nbsd_nat_target::wait) (nbsd_nat_target::insert_exec_catchpoint) (nbsd_nat_target::remove_exec_catchpoint) (nbsd_nat_target::set_syscall_catchpoint): Add. * nbsd-tdep.c (nbsd_get_syscall_number): Add. (nbsd_init_abi): Call `set_gdbarch_get_syscall_number' and pass `nbsd_get_syscall_number'. =2D-- gdb/ChangeLog | 15 ++++ gdb/nbsd-nat.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/nbsd-nat.h | 9 +++ gdb/nbsd-tdep.c | 18 +++++ 4 files changed, 253 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0caeca04e79..9652daabbbd 100644 =2D-- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2020-04-16 Kamil Rytarowski + + * nbsd-nat.c: Include "sys/wait.h". + * (nbsd_nat_target::resume, nbsd_wait, nbsd_nat_target::wait) + (nbsd_nat_target::insert_exec_catchpoint) + (nbsd_nat_target::remove_exec_catchpoint) + (nbsd_nat_target::set_syscall_catchpoint): Add. + * nbsd-nat.h (nbsd_nat_target::resume, nbsd_nat_target::wait) + (nbsd_nat_target::insert_exec_catchpoint) + (nbsd_nat_target::remove_exec_catchpoint) + (nbsd_nat_target::set_syscall_catchpoint): Add. + * nbsd-tdep.c (nbsd_get_syscall_number): Add. + (nbsd_init_abi): Call `set_gdbarch_get_syscall_number' and pass + `nbsd_get_syscall_number'. + 2020-04-16 Kamil Rytarowski * inf-ptrace.h (follow_fork, insert_fork_catchpoint) diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c index d41cfc815d3..f9e85e10b16 100644 =2D-- a/gdb/nbsd-nat.c +++ b/gdb/nbsd-nat.c @@ -28,6 +28,7 @@ #include #include #include +#include /* Return the name of a file that can be opened to get the symbols for the child process identified by PID. */ @@ -539,3 +540,213 @@ nbsd_nat_target::info_proc (const char *args, enum i= nfo_proc_what what) return true; } + +/* Resume execution of thread PTID, or all threads if PTID is -1. If + STEP is nonzero, single-step it. If SIGNAL is nonzero, give it + that signal. */ + +void +nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal) +{ + int request; + + if (ptid.lwp_p ()) + { + /* If ptid is a specific LWP, suspend all other LWPs in the process= . */ + inferior *inf =3D find_inferior_ptid (this, ptid); + + for (thread_info *tp : inf->non_exited_threads ()) + { + if (tp->ptid.lwp () =3D=3D ptid.lwp ()) + request =3D PT_RESUME; + else + request =3D PT_SUSPEND; + + if (ptrace (request, tp->ptid.pid (), NULL, tp->ptid.lwp ()) = =3D=3D -1) + perror_with_name (("ptrace")); + } + } + else + { + /* If ptid is a wildcard, resume all matching threads (they won't r= un + until the process is continued however). */ + for (thread_info *tp : all_non_exited_threads (this, ptid)) + if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) = =3D=3D -1) + perror_with_name (("ptrace")); + ptid =3D inferior_ptid; + } + + if (step) + { + for (thread_info *tp : all_non_exited_threads (this, ptid)) + if (ptrace (PT_SETSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) = =3D=3D -1) + perror_with_name (("ptrace")); + } + else + { + for (thread_info *tp : all_non_exited_threads (this, ptid)) + if (ptrace (PT_CLEARSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) = =3D=3D -1) + perror_with_name (("ptrace")); + } + + if (minus_one_ptid =3D=3D ptid) + /* Resume all threads. Traditionally ptrace() only supports + single-threaded processes, so simply resume the inferior. */ + ptid =3D ptid_t (inferior_ptid.pid ()); + + if (catch_syscall_enabled () > 0) + request =3D PT_SYSCALL; + else + request =3D PT_CONTINUE; + + /* An address of (void *)1 tells ptrace to continue from + where it was. If GDB wanted it to start some other way, we have + already written a new program counter value to the child. */ + if (ptrace (request, ptid.pid (), (void *)1, gdb_signal_to_host (signal= )) =3D=3D -1) + perror_with_name (("ptrace")); +} + +/* Implement the "update_thread_list" target_ops method. */ + +static ptid_t +nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) +{ + pid_t pid; + int status; + + set_sigint_trap (); + + do + { + /* The common code passes WNOHANG that leads to crashes, overwrite = it. */ + pid =3D waitpid (ptid.pid (), &status, 0); + } + while (pid =3D=3D -1 && errno =3D=3D EINTR); + + clear_sigint_trap (); + + if (pid =3D=3D -1) + perror_with_name (_("Child process unexpectedly missing")); + + store_waitstatus (ourstatus, status); + return ptid_t (pid); +} + +/* Wait for the child specified by PTID to do something. Return the + process ID of the child, or MINUS_ONE_PTID in case of error; store + the status in *OURSTATUS. */ + +ptid_t +nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, + int target_options) +{ + ptid_t wptid =3D nbsd_wait(ptid, ourstatus, target_options); + + /* If the child stopped, keep investigating its status. */ + if (ourstatus->kind !=3D TARGET_WAITKIND_STOPPED) + return wptid; + + pid_t pid =3D wptid.pid (); + + /* Extract the event and thread that received a signal. */ + ptrace_siginfo_t psi; + if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) =3D=3D -1) + perror_with_name (("ptrace")); + + /* Pick child's siginfo_t. */ + siginfo_t *si =3D &psi.psi_siginfo; + + int lwp =3D psi.psi_lwpid; + + int signo =3D si->si_signo; + const int code =3D si->si_code; + + /* Construct PTID with a specified thread that received the event. + If a signal was targeted to the whole process, lwp is 0. */ + wptid =3D ptid_t (pid, lwp, 0); + + /* Bail out on non-debugger oriented signals.. */ + if (signo !=3D SIGTRAP) + return wptid; + + /* Stop examining non-debugger oriented SIGTRAP codes. */ + if (code <=3D SI_USER || code =3D=3D SI_NOINFO) + return wptid; + + if (in_thread_list (this, ptid_t (pid))) + { + thread_change_ptid (this, ptid_t (pid), wptid); + } + + if (code =3D=3D TRAP_EXEC) + { + ourstatus->kind =3D TARGET_WAITKIND_EXECD; + ourstatus->value.execd_pathname =3D xstrdup (pid_to_exec_file (pid)= ); + return wptid; + } + + if (code =3D=3D TRAP_TRACE) + { + /* Unhandled at this level. */ + return wptid; + } + + if (code =3D=3D TRAP_SCE || code =3D=3D TRAP_SCX) + { + int sysnum =3D si->si_sysnum; + + if (!catch_syscall_enabled () || !catching_syscall_number (sysnum)) + { + /* If the core isn't interested in this event, ignore it. */ + ourstatus->kind =3D TARGET_WAITKIND_SPURIOUS; + return wptid; + } + + ourstatus->kind =3D + (code =3D=3D TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY : + TARGET_WAITKIND_SYSCALL_RETURN; + ourstatus->value.syscall_number =3D sysnum; + return wptid; + } + + if (code =3D=3D TRAP_BRKPT) + { + /* Unhandled at this level. */ + return wptid; + } + + /* Unclassified SIGTRAP event. */ + ourstatus->kind =3D TARGET_WAITKIND_SPURIOUS; + return wptid; +} + +/* Implement the "insert_exec_catchpoint" target_ops method. */ + +int +nbsd_nat_target::insert_exec_catchpoint (int pid) +{ + /* Nothing to do. */ + return 0; +} + +/* Implement the "remove_exec_catchpoint" target_ops method. */ + +int +nbsd_nat_target::remove_exec_catchpoint (int pid) +{ + /* Nothing to do. */ + return 0; +} + +/* Implement the "set_syscall_catchpoint" target_ops method. */ + +int +nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed, + int any_count, + gdb::array_view sysca= ll_counts) +{ + /* Ignore the arguments. inf-ptrace.c will use PT_SYSCALL which + will catch all system call entries and exits. The system calls + are filtered by GDB rather than the kernel. */ + return 0; +} diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h index 256db4b9017..6e14cbb889d 100644 =2D-- a/gdb/nbsd-nat.h +++ b/gdb/nbsd-nat.h @@ -38,6 +38,15 @@ struct nbsd_nat_target : public inf_ptrace_target int find_memory_regions (find_memory_region_ftype func, void *data) ove= rride; bool info_proc (const char *, enum info_proc_what) override; + + void resume (ptid_t, int, enum gdb_signal) override; + ptid_t wait (ptid_t, struct target_waitstatus *, int) override; + int insert_exec_catchpoint (int pid) override; + int remove_exec_catchpoint (int pid) override; + int set_syscall_catchpoint (int pid, bool needed, int any_count, + gdb::array_view syscall_counts) + override; + }; #endif /* nbsd-nat.h */ diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c index 52e0640e35c..d5d1b7211c1 100644 =2D-- a/gdb/nbsd-tdep.c +++ b/gdb/nbsd-tdep.c @@ -444,6 +444,21 @@ nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST= kve_start, } } +/* Implement the "get_syscall_number" gdbarch method. */ + +static LONGEST +nbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) +{ + + /* FreeBSD doesn't use gdbarch_get_syscall_number since NetBSD + native targets fetch the system call number from the + 'si_sysnum' member of siginfo_t in nbsd_nat_target::wait. + However, system call catching requires this function to be + set. */ + + internal_error (__FILE__, __LINE__, _("nbsd_get_sycall_number called"))= ; +} + /* See nbsd-tdep.h. */ void @@ -453,4 +468,7 @@ nbsd_init_abi (struct gdbarch_info info, struct gdbarc= h *gdbarch) set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target); set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver); set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse); + + /* `catch syscall' */ + set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number); } =2D- 2.25.0