diff options
-rw-r--r-- | gdb/ChangeLog | 24 | ||||
-rw-r--r-- | gdb/NEWS | 13 | ||||
-rw-r--r-- | gdb/break-catch-syscall.c | 11 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 23 | ||||
-rw-r--r-- | gdb/gdbarch.h | 3 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 3 | ||||
-rw-r--r-- | gdb/syscalls/gdb-syscalls.dtd | 1 | ||||
-rw-r--r-- | gdb/xml-syscall.c | 61 | ||||
-rw-r--r-- | gdb/xml-syscall.h | 10 |
10 files changed, 112 insertions, 44 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 93ee629cee5..2a1a6e25184 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,29 @@ 2018-12-13 John Baldwin <jhb@FreeBSD.org> + * NEWS: Add entry documenting system call aliases. + * break-catch-syscall.c (catch_syscall_split_args): Pass 'result' + to get_syscalls_by_name. + * gdbarch.sh (UNKNOWN_SYSCALL): Remove. + * gdbarch.h: Regenerate. + * syscalls/gdb-syscalls.dtd (syscall): Add alias attribute. + * xml-syscall.c [!HAVE_LIBEXPAT] (get_syscalls_by_name): Rename + from get_syscall_by_name. Now accepts a pointer to a vector of + integers and returns a bool. + [HAVE_LIBEXPAT] (struct syscall_desc): Add alias member. + (syscall_create_syscall_desc): Add alias parameter and pass it to + syscall_desc constructor. + (syscall_start_syscall): Handle alias attribute. + (syscall_attr): Add alias attribute. + (xml_get_syscalls_by_name): Rename from xml_get_syscall_number. + Now accepts a pointer to a vector of integers and returns a + bool. Add syscalls whose alias or name matches the requested + name. + (get_syscalls_by_name): Rename from get_syscall_by_name. Now + accepts a pointer to a vector of integers and returns a bool. + * xml-syscall.h (get_syscalls_by_name): Likewise. + +2018-12-13 John Baldwin <jhb@FreeBSD.org> + * break-catch-syscall.c (catch_syscall_split_args): Pass 'result' to get_syscalls_by_group. * xml-syscall.c [!HAVE_LIBEXPAT] (get_syscalls_by_group): Return @@ -40,6 +40,19 @@ * The RISC-V target now supports target descriptions. +* System call catchpoints now support system call aliases on FreeBSD. + When the ABI of a system call changes in FreeBSD, this is + implemented by leaving a compatibility system call using the old ABI + at the existing number and allocating a new system call number for + the new ABI. For example, FreeBSD 12 altered the layout of 'struct + kevent' used by the 'kevent' system call. As a result, FreeBSD 12 + kernels ship with both 'kevent' and 'freebsd11_kevent' system calls. + The 'freebsd11_kevent' system call is assigned an alias of 'kevent' + so that a system call catchpoint for the 'kevent' system call will + catch invocations of both the 'kevent' and 'freebsd11_kevent' + binaries. This ensures that 'kevent' system calls are caught for + binaries using either the old or new ABIs. + * New targets NXP S12Z s12z-*-elf diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c index bad34d6fd86..14158d80049 100644 --- a/gdb/break-catch-syscall.c +++ b/gdb/break-catch-syscall.c @@ -419,18 +419,13 @@ catch_syscall_split_args (const char *arg) } else { - /* We have a name. Let's check if it's valid and convert it - to a number. */ - get_syscall_by_name (gdbarch, cur_name, &s); - - if (s.number == UNKNOWN_SYSCALL) + /* We have a name. Let's check if it's valid and fetch a + list of matching numbers. */ + if (!get_syscalls_by_name (gdbarch, cur_name, &result)) /* Here we have to issue an error instead of a warning, because GDB cannot do anything useful if there's no syscall number to be caught. */ error (_("Unknown syscall name '%s'."), cur_name); - - /* Ok, it's valid. */ - result.push_back (s.number); } } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 59e7330a4dc..68d3068c722 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,10 @@ +2018-12-13 John Baldwin <jhb@FreeBSD.org> + + * gdb.texinfo (Set Catchpoints): Add an anchor for 'catch syscall'. + (Native): Add a FreeBSD subsection. + (FreeBSD): Document use of system call aliases for compatibility + system calls. + 2018-11-21 Andrew Burgess <andrew.burgess@embecosm.com> * gdb.texinfo (Standard Target Features): Add RISC-V Features diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 7350d945738..d766e44e631 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4560,6 +4560,7 @@ A failed Ada assertion. @cindex break on fork/exec A call to @code{exec}. +@anchor{catch syscall} @item syscall @itemx syscall @r{[}@var{name} @r{|} @var{number} @r{|} @r{group:}@var{groupname} @r{|} @r{g:}@var{groupname}@r{]} @dots{} @kindex catch syscall @@ -22357,6 +22358,7 @@ configurations. * Cygwin Native:: Features specific to the Cygwin port * Hurd Native:: Features specific to @sc{gnu} Hurd * Darwin:: Features specific to Darwin +* FreeBSD:: Features specific to FreeBSD @end menu @node BSD libkvm Interface @@ -23242,6 +23244,27 @@ better understand the cause of a fault. The default is off. Show the current state of exceptions trapping. @end table +@node FreeBSD +@subsection FreeBSD +@cindex FreeBSD + +When the ABI of a system call is changed in the FreeBSD kernel, this +is implemented by leaving a compatibility system call using the old +ABI at the existing number and allocating a new system call number for +the version using the new ABI. As a convenience, when a system call +is caught by name (@pxref{catch syscall}), compatibility system calls +are also caught. + +For example, FreeBSD 12 introduced a new variant of the @code{kevent} +system call and catching the @code{kevent} system call by name catches +both variants: + +@smallexample +(@value{GDBP}) catch syscall kevent +Catchpoint 1 (syscalls 'freebsd11_kevent' [363] 'kevent' [560]) +(@value{GDBP}) +@end smallexample + @node Embedded OS @section Embedded Operating Systems diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 8356e6e7b4e..e13c4699a60 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1592,9 +1592,6 @@ typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct typ extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type); extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align); -/* Definition for an unknown syscall, used basically in error-cases. */ -#define UNKNOWN_SYSCALL (-1) - extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index ddd93c27176..a876a21555e 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1416,9 +1416,6 @@ done # close it off cat <<EOF -/* Definition for an unknown syscall, used basically in error-cases. */ -#define UNKNOWN_SYSCALL (-1) - extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); diff --git a/gdb/syscalls/gdb-syscalls.dtd b/gdb/syscalls/gdb-syscalls.dtd index c2aa478aa4f..6aa73f288a9 100644 --- a/gdb/syscalls/gdb-syscalls.dtd +++ b/gdb/syscalls/gdb-syscalls.dtd @@ -12,4 +12,5 @@ <!ATTLIST syscall name CDATA #REQUIRED number CDATA #REQUIRED + alias CDATA #IMPLIED groups CDATA #IMPLIED> diff --git a/gdb/xml-syscall.c b/gdb/xml-syscall.c index d1b5bf8a2fe..a09ccb99b2a 100644 --- a/gdb/xml-syscall.c +++ b/gdb/xml-syscall.c @@ -61,13 +61,12 @@ get_syscall_by_number (struct gdbarch *gdbarch, s->name = NULL; } -void -get_syscall_by_name (struct gdbarch *gdbarch, const char *syscall_name, - struct syscall *s) +bool +get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name, + std::vector<int> *syscall_numbers) { syscall_warn_user (); - s->number = UNKNOWN_SYSCALL; - s->name = syscall_name; + return false; } const char ** @@ -97,8 +96,8 @@ get_syscall_group_names (struct gdbarch *gdbarch) /* Structure which describes a syscall. */ struct syscall_desc { - syscall_desc (int number_, std::string name_) - : number (number_), name (name_) + syscall_desc (int number_, std::string name_, std::string alias_) + : number (number_), name (name_), alias (alias_) {} /* The syscall number. */ @@ -108,6 +107,10 @@ struct syscall_desc /* The syscall name. */ std::string name; + + /* An optional alias. */ + + std::string alias; }; typedef std::unique_ptr<syscall_desc> syscall_desc_up; @@ -207,10 +210,11 @@ syscall_group_add_syscall (struct syscalls_info *syscalls_info, static void syscall_create_syscall_desc (struct syscalls_info *syscalls_info, - const char *name, int number, + const char *name, int number, const char *alias, char *groups) { - syscall_desc *sysdesc = new syscall_desc (number, name); + syscall_desc *sysdesc = new syscall_desc (number, name, + alias != NULL ? alias : ""); syscalls_info->syscalls.emplace_back (sysdesc); @@ -235,6 +239,7 @@ syscall_start_syscall (struct gdb_xml_parser *parser, /* syscall info. */ char *name = NULL; int number = 0; + char *alias = NULL; char *groups = NULL; for (const gdb_xml_value &attr : attributes) @@ -243,6 +248,8 @@ syscall_start_syscall (struct gdb_xml_parser *parser, name = (char *) attr.value.get (); else if (strcmp (attr.name, "number") == 0) number = * (ULONGEST *) attr.value.get (); + else if (strcmp (attr.name, "alias") == 0) + alias = (char *) attr.value.get (); else if (strcmp (attr.name, "groups") == 0) groups = (char *) attr.value.get (); else @@ -251,7 +258,8 @@ syscall_start_syscall (struct gdb_xml_parser *parser, } gdb_assert (name); - syscall_create_syscall_desc (data->syscalls_info, name, number, groups); + syscall_create_syscall_desc (data->syscalls_info, name, number, alias, + groups); } @@ -259,6 +267,7 @@ syscall_start_syscall (struct gdb_xml_parser *parser, static const struct gdb_xml_attribute syscall_attr[] = { { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, { "name", GDB_XML_AF_NONE, NULL, NULL }, + { "alias", GDB_XML_AF_OPTIONAL, NULL, NULL }, { "groups", GDB_XML_AF_OPTIONAL, NULL, NULL }, { NULL, GDB_XML_AF_NONE, NULL, NULL } }; @@ -390,21 +399,22 @@ syscall_group_get_group_by_name (const struct syscalls_info *syscalls_info, return NULL; } -static int -xml_get_syscall_number (struct gdbarch *gdbarch, - const char *syscall_name) +static bool +xml_get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name, + std::vector<int> *syscall_numbers) { struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch); - if (syscalls_info == NULL - || syscall_name == NULL) - return UNKNOWN_SYSCALL; - - for (const syscall_desc_up &sysdesc : syscalls_info->syscalls) - if (sysdesc->name == syscall_name) - return sysdesc->number; + bool found = false; + if (syscalls_info != NULL && syscall_name != NULL && syscall_numbers != NULL) + for (const syscall_desc_up &sysdesc : syscalls_info->syscalls) + if (sysdesc->name == syscall_name || sysdesc->alias == syscall_name) + { + syscall_numbers->push_back (sysdesc->number); + found = true; + } - return UNKNOWN_SYSCALL; + return found; } static const char * @@ -510,14 +520,13 @@ get_syscall_by_number (struct gdbarch *gdbarch, s->name = xml_get_syscall_name (gdbarch, syscall_number); } -void -get_syscall_by_name (struct gdbarch *gdbarch, - const char *syscall_name, struct syscall *s) +bool +get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name, + std::vector<int> *syscall_numbers) { init_syscalls_info (gdbarch); - s->number = xml_get_syscall_number (gdbarch, syscall_name); - s->name = syscall_name; + return xml_get_syscalls_by_name (gdbarch, syscall_name, syscall_numbers); } const char ** diff --git a/gdb/xml-syscall.h b/gdb/xml-syscall.h index 012a4b75a4e..31a13e231d5 100644 --- a/gdb/xml-syscall.h +++ b/gdb/xml-syscall.h @@ -38,11 +38,13 @@ void set_xml_syscall_file_name (struct gdbarch *gdbarch, void get_syscall_by_number (struct gdbarch *gdbarch, int syscall_number, struct syscall *s); -/* Function that retrieves the syscall number corresponding to the given - name. It puts the requested information inside 'struct syscall'. */ +/* Function that retrieves the syscall numbers corresponding to the + given name. The numbers of all syscalls with either a name or + alias equal to SYSCALL_NAME are appended to SYSCALL_NUMBERS. If no + matching syscalls are found, return false. */ -void get_syscall_by_name (struct gdbarch *gdbarch, - const char *syscall_name, struct syscall *s); +bool get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name, + std::vector<int> *syscall_numbers); /* Function used to retrieve the list of syscalls in the system. This list is returned as an array of strings. Returns the list of syscalls in the |