From patchwork Tue Jun 14 20:57:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 13086 Received: (qmail 101163 invoked by alias); 14 Jun 2016 20:58:25 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 101153 invoked by uid 89); 14 Jun 2016 20:58:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.3 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_SOFTFAIL autolearn=no version=3.3.2 spammy=profil, v850tdepc, v850-tdep.c, UD:v850-tdep.c X-HELO: bigwig.baldwin.cx Received: from bigwig.baldwin.cx (HELO bigwig.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 14 Jun 2016 20:58:14 +0000 Received: from ralph.baldwin.cx.net (c-73-231-226-104.hsd1.ca.comcast.net [73.231.226.104]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 2FD93B95B for ; Tue, 14 Jun 2016 16:58:11 -0400 (EDT) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH] Add support for catching system calls to native FreeBSD targets. Date: Tue, 14 Jun 2016 13:57:51 -0700 Message-Id: <20160614205751.11566-1-jhb@FreeBSD.org> X-IsSubscribed: yes All platforms on FreeBSD use a shared system call table, so use a single XML file to describe the system calls available on each FreeBSD platform. xRecent versions of FreeBSD include the identifier of the current system call when reporting a system call entry or exit event in the ptrace_lwpinfo structure obtained via PT_LWPINFO in fbsd_wait. As such, FreeBSD native targets do not use the gdbarch method to fetch the system call code. In addition, FreeBSD register sets fetched via ptrace do not include an equivalent of 'orig_rax' (on amd64 for example), so the system call code cannot be extracted from the available registers during a system call exit. However, GDB assumes that system call catch points are not supported if the gdbarch method is not present. As a workaround, FreeBSD ABIs install a dummy gdbarch method that throws an internal_error if it is ever invoked. gdb/ChangeLog: * configure.ac: Check for support for system call LWP fields on FreeBSD. * config.in, configure: Rebuild. * data-directory/Makefile.in (SYSCALLS_FILES): Add freebsd.xml. * fbsd-nat.c (fbsd_wait) [HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE]: Report system call events. [HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE] (fbsd_set_syscall_catchpoint): New function. (fbsd_nat_add_target) [HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE]: Set "to_set_syscall_catchpoint" to "fbsd_set_syscall_catchpoint". * fbsd-tdep.c: Include xml-syscall.h (fbsd_get_syscall_number): New function. (fbsd_init_abi): Set XML system call file name. Add "get_syscall_number" gdbarch method. * syscalls/freebsd.xml: New file. --- gdb/ChangeLog | 18 ++ gdb/config.in | 3 + gdb/configure | 14 ++ gdb/configure.ac | 5 + gdb/data-directory/Makefile.in | 3 +- gdb/fbsd-nat.c | 50 +++++ gdb/fbsd-tdep.c | 19 ++ gdb/syscalls/freebsd.xml | 410 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 gdb/syscalls/freebsd.xml diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9e57431..08cf78c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,23 @@ 2016-06-14 John Baldwin + * configure.ac: Check for support for system call LWP fields on + FreeBSD. + * config.in, configure: Rebuild. + * data-directory/Makefile.in (SYSCALLS_FILES): Add freebsd.xml. + * fbsd-nat.c (fbsd_wait) [HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE]: + Report system call events. + [HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE] + (fbsd_set_syscall_catchpoint): New function. + (fbsd_nat_add_target) [HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE]: + Set "to_set_syscall_catchpoint" to "fbsd_set_syscall_catchpoint". + * fbsd-tdep.c: Include xml-syscall.h + (fbsd_get_syscall_number): New function. + (fbsd_init_abi): Set XML system call file name. + Add "get_syscall_number" gdbarch method. + * syscalls/freebsd.xml: New file. + +2016-06-14 John Baldwin + * v850-tdep.c (v850_use_struct_convention): Trim type length checks. 2016-06-14 John Baldwin diff --git a/gdb/config.in b/gdb/config.in index 905caf0..c82a5b4 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -456,6 +456,9 @@ /* Define to 1 if `struct ptrace_lwpinfo' is a member of `pl_tdname'. */ #undef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME +/* Define to 1 if `struct ptrace_lwpinfo' is a member of `pl_syscall_code'. */ +#undef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE + /* Define to 1 if your system has struct reg in . */ #undef HAVE_STRUCT_REG diff --git a/gdb/configure b/gdb/configure index 60ea884..5cdfc98 100755 --- a/gdb/configure +++ b/gdb/configure @@ -12927,6 +12927,20 @@ _ACEOF fi +# See if supports syscall fields on FreeBSD +# Older FreeBSD versions don't have the pl_syscall_code member of +# `struct ptrace_lwpinfo'. +ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_syscall_code" "ac_cv_member_struct_ptrace_lwpinfo_pl_syscall_code" "#include +" +if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_syscall_code" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 1 +_ACEOF + + +fi + # Detect which type of /proc is in use, such as for Solaris. diff --git a/gdb/configure.ac b/gdb/configure.ac index 6a72f72..4ed706a 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1526,6 +1526,11 @@ fi AC_CHECK_MEMBERS([struct ptrace_lwpinfo.pl_tdname], [], [], [#include ]) +# See if supports syscall fields on FreeBSD +# Older FreeBSD versions don't have the pl_syscall_code member of +# `struct ptrace_lwpinfo'. +AC_CHECK_MEMBERS([struct ptrace_lwpinfo.pl_syscall_code], [], [], + [#include ]) # Detect which type of /proc is in use, such as for Solaris. diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index c05f379..0beca55 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -51,7 +51,8 @@ SYSCALLS_FILES = \ i386-linux.xml amd64-linux.xml \ sparc-linux.xml sparc64-linux.xml \ mips-o32-linux.xml mips-n32-linux.xml mips-n64-linux.xml \ - s390-linux.xml s390x-linux.xml + s390-linux.xml s390x-linux.xml \ + freebsd.xml PYTHON_DIR = python PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR) diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index b582abe..741a96d 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -707,6 +707,40 @@ fbsd_wait (struct target_ops *ops, return wptid; } #endif + + /* Note that PL_FLAG_SCE is set for any event reported while + a thread is executing a system call in the kernel. In + particular, signals that interrupt a sleep in a system + call will report this flag as part of their event. Stops + explicitly for system call entry and exit always use + SIGTRAP, so only treat SIGTRAP events as system call + entriy/exit events. */ + if (pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX) + && ourstatus->value.sig == SIGTRAP) + { +#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE + if (catch_syscall_enabled ()) + { + if (catching_syscall_number (pl.pl_syscall_code)) + { + if (pl.pl_flags & PL_FLAG_SCE) + ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY; + else + ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN; + ourstatus->value.syscall_number = pl.pl_syscall_code; + return wptid; + } + } +#endif + /* If the core isn't interested in this event, just + continue the process explicitly and wait for another + event. Note that PT_SYSCALL is "sticky" on FreeBSD + and once system call stops are enabled on a process + it stops for all system call entries and exits. */ + if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1) + perror_with_name (("ptrace")); + continue; + } } return wptid; } @@ -817,6 +851,19 @@ fbsd_remove_exec_catchpoint (struct target_ops *self, int pid) return 0; } #endif + +#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE +static int +fbsd_set_syscall_catchpoint (struct target_ops *self, int pid, int needed, + int any_count, int table_size, int *table) +{ + + /* 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; +} +#endif #endif void @@ -849,6 +896,9 @@ fbsd_nat_add_target (struct target_ops *t) t->to_insert_exec_catchpoint = fbsd_insert_exec_catchpoint; t->to_remove_exec_catchpoint = fbsd_remove_exec_catchpoint; #endif +#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE + t->to_set_syscall_catchpoint = fbsd_set_syscall_catchpoint; +#endif #endif add_target (t); } diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index 7310ea0..d7fe201 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -23,6 +23,7 @@ #include "regcache.h" #include "regset.h" #include "gdbthread.h" +#include "xml-syscall.h" #include "elf-bfd.h" #include "fbsd-tdep.h" @@ -283,6 +284,20 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) return note_data; } +static LONGEST +fbsd_get_syscall_number (struct gdbarch *gdbarch, + ptid_t ptid) +{ + + /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD + native targets fetch the system call number from the + 'pl_syscall_code' member of struct ptrace_lwpinfo in fbsd_wait. + However, system call catching requires this function to be + set. */ + + internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called")); +} + /* To be called from GDB_OSABI_FREEBSD_ELF handlers. */ void @@ -291,4 +306,8 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str); set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name); set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); + + /* `catch syscall' */ + set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml"); + set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number); } diff --git a/gdb/syscalls/freebsd.xml b/gdb/syscalls/freebsd.xml new file mode 100644 index 0000000..7d52168 --- /dev/null +++ b/gdb/syscalls/freebsd.xml @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +