summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog24
-rw-r--r--gdb/NEWS13
-rw-r--r--gdb/break-catch-syscall.c11
-rw-r--r--gdb/doc/ChangeLog7
-rw-r--r--gdb/doc/gdb.texinfo23
-rw-r--r--gdb/gdbarch.h3
-rwxr-xr-xgdb/gdbarch.sh3
-rw-r--r--gdb/syscalls/gdb-syscalls.dtd1
-rw-r--r--gdb/xml-syscall.c61
-rw-r--r--gdb/xml-syscall.h10
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
diff --git a/gdb/NEWS b/gdb/NEWS
index fc880c74c64..913f3ae3b66 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -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