]> granicus.if.org Git - strace/commitdiff
tests: add ksysent.test
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 10 Dec 2015 02:06:25 +0000 (02:06 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 10 Dec 2015 02:06:25 +0000 (02:06 +0000)
Check that syscall names and numbers defined in syscallent files
match kernel __NR_* constants defined by <asm/unistd.h>.

Tested on various platforms, including the following combinations
of architectures and kernel headers:

x86_64: 4.4-rc, 4.3, 4.2, 4.1, 3.19, 3.17, 3.16, 3.12, 3.11,
3.10-rhel, 2.6.32-rhel, 2.6.27-sle, 2.6.18-rhel
i386: 4.4-rc, 4.3, 4.2, 4.1, 3.19, 3.17, 3.16, 3.11,
3.10-rhel, 2.6.32-rhel, 2.6.27-sle, 2.6.18-rhel
aarch64: 4.4-rc
alpha: 4.3
arm eabi: 4.4-rc, 4.2, 4.1
hppa: 3.18
ia64: 3.18
mips o32: 4.1
ppc: 3.18
ppc64: 3.10-rhel, 2.6.32-rhel
s390: 3.18
s390x: 3.18
sparc: 4.1
sparc: 3.18
x32: 3.19

The only platform which is known at this moment to fail the test
is CentOS-5 provided by OBS.  On x86_64 instance it fails with
error: "prlimit64" syscall #300 is "fanotify_init" in syscallent.h
and on i586 it similarly fails with
error: "prlimit64" syscall #338 is "fanotify_init" in syscallent.h
So this is a real platform bug that is not likely to be worked around
on the strace side.

* tests/ksysent.c: New file.
* tests/ksysent.sed: Likewise.
* tests/ksysent.test: New test.
* tests/Makefile.am (AM_CPPFLAGS): Add -I$(builddir).
(check_PROGRAMS): Add ksysent.
(TESTS): Add ksysent.test.
(EXTRA_DIST): Add ksysent.sed.
(ksysent.h): New rule.
(BUILT_SOURCES, CLEANFILES): Add ksysent.h.
* tests/.gitignore: Add ksysent.

tests/.gitignore
tests/Makefile.am
tests/ksysent.c [new file with mode: 0644]
tests/ksysent.sed [new file with mode: 0644]
tests/ksysent.test [new file with mode: 0755]

index 714d82ba805e4a2f61bcfc832deb2fba994c88da..6cc56cc29883772a56c03ad480f76675a4595fb4 100644 (file)
@@ -37,6 +37,7 @@ ipc_msg
 ipc_msgbuf
 ipc_sem
 ipc_shm
+ksysent
 llseek
 lseek
 lstat
index a13dc308c7aab0c565d88877eff7e0d6559bb5a2..fdeb5ec709d2f6237377eaf094610299cf377108 100644 (file)
@@ -5,6 +5,7 @@ ARCH = @arch@
 ARCH_MFLAGS =
 AM_CFLAGS = $(WARN_CFLAGS)
 AM_CPPFLAGS = $(ARCH_MFLAGS) \
+             -I$(builddir) \
              -I$(top_builddir)/$(OS)/$(ARCH) \
              -I$(top_srcdir)/$(OS)/$(ARCH) \
              -I$(top_builddir)/$(OS) \
@@ -46,6 +47,7 @@ check_PROGRAMS = \
        ipc_msgbuf \
        ipc_sem \
        ipc_shm \
+       ksysent \
        llseek \
        lseek \
        lstat \
@@ -136,6 +138,7 @@ stack_fcall_SOURCES = stack-fcall.c \
 TESTS = \
        strace-f.test \
        qual_syscall.test \
+       ksysent.test \
        \
        _newselect.test \
        adjtimex.test \
@@ -264,6 +267,7 @@ EXTRA_DIST = init.sh run.sh match.awk \
             ip_mreq.expected \
             ipc.sh \
             ipc_msgbuf.expected \
+            ksysent.sed \
             lstatx.c \
             memfd_create.expected \
             mmsg.expected \
@@ -294,4 +298,12 @@ EXTRA_DIST = init.sh run.sh match.awk \
             xstatx.c \
             $(TESTS)
 
-CLEANFILES = $(TESTS:=.tmp)
+ksysent.h: $(srcdir)/ksysent.sed
+       echo '#include <asm/unistd.h>' | \
+               $(CPP) $(AM_CPPFLAGS) $(CPPFLAGS) -dD - > $@.t1
+       LC_COLLATE=C sed -n -f $(srcdir)/ksysent.sed < $@.t1 > $@.t2
+       mv -f $@.t2 $@
+       rm -f $@.t1
+
+BUILT_SOURCES = ksysent.h
+CLEANFILES = ksysent.h $(TESTS:=.tmp)
diff --git a/tests/ksysent.c b/tests/ksysent.c
new file mode 100644 (file)
index 0000000..1d09917
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include "syscall.h"
+
+#define TD 0
+#define TF 0
+#define TI 0
+#define TN 0
+#define TP 0
+#define TS 0
+#define TM 0
+#define NF 0
+#define MA 0
+#define SI 0
+#define SE 0
+#define SEN(arg) 0,0
+
+static const struct_sysent syscallent[] = {
+#include "syscallent.h"
+};
+
+typedef const char const *pstr_t;
+static const pstr_t ksyslist[] = {
+#include "ksysent.h"
+};
+
+int
+main(void)
+{
+       int rc = 0;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(ksyslist); ++i) {
+               if (!ksyslist[i])
+                       continue;
+               if (i >= ARRAY_SIZE(syscallent) || !syscallent[i].sys_name) {
+                       fprintf(stderr, "warning: \"%s\" syscall #%u"
+                               " is missing in syscallent.h\n",
+                               ksyslist[i], i);
+                       continue;
+               }
+#ifdef SYS_socket_nsubcalls
+               if (i >= SYS_socket_subcall &&
+                   i < SYS_socket_subcall + SYS_socket_nsubcalls) {
+                       fprintf(stderr, "error: \"%s\" syscall #%u"
+                               " is a socket subcall in syscallent.h\n",
+                               ksyslist[i], i);
+                       rc = 1;
+                       continue;
+               }
+#endif
+#ifdef SYS_ipc_nsubcalls
+               if (i >= SYS_ipc_subcall &&
+                   i < SYS_ipc_subcall + SYS_ipc_nsubcalls) {
+                       fprintf(stderr, "error: \"%s\" syscall #%u"
+                               " is an ipc subcall in syscallent.h\n",
+                               ksyslist[i], i);
+                       rc = 1;
+                       continue;
+               }
+#endif
+               if (strcmp(ksyslist[i], syscallent[i].sys_name)) {
+                       fprintf(stderr, "error: \"%s\" syscall #%u"
+                               " is \"%s\" in syscallent.h\n",
+                               ksyslist[i], i, syscallent[i].sys_name);
+                       rc = 1;
+                       continue;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(syscallent); ++i) {
+               if (!syscallent[i].sys_name
+#ifdef SYS_socket_nsubcalls
+                   || (i >= SYS_socket_subcall &&
+                       i < SYS_socket_subcall + SYS_socket_nsubcalls)
+#endif
+#ifdef SYS_ipc_nsubcalls
+                   || (i >= SYS_ipc_subcall &&
+                       i < SYS_ipc_subcall + SYS_ipc_nsubcalls)
+#endif
+#ifdef ARM_FIRST_SHUFFLED_SYSCALL
+                   || (i >= ARM_FIRST_SHUFFLED_SYSCALL &&
+                       i <= ARM_FIRST_SHUFFLED_SYSCALL +
+                           ARM_LAST_SPECIAL_SYSCALL + 1)
+#endif
+                  )
+                       continue;
+               if (i >= ARRAY_SIZE(ksyslist) || !ksyslist[i]) {
+                       fprintf(stderr, "note: unknown syscall #%u"
+                               " is \"%s\" in syscallent.h\n",
+                               i, syscallent[i].sys_name);
+               }
+       }
+
+       return rc;
+}
diff --git a/tests/ksysent.sed b/tests/ksysent.sed
new file mode 100644 (file)
index 0000000..56fe042
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sed -nf
+
+# should not have been exported at all
+/#define[[:space:]]\+__NR_\(sys_epoll_\|arch_specific_syscall\|syscalls\|syscall_count\|syscall_max\|available\|reserved\|unused\)/d
+
+# should not be named this way
+s/__NR_\(arm\|xtensa\)_fadvise64_64/__NR_fadvise64_64/
+
+# legacy names
+s/__NR_get_cpu/__NR_getcpu/
+s/__NR_madvise1/__NR_madvise/
+s/__NR_paccept/__NR_accept4/
+
+# generate
+s/#define[[:space:]]\+__NR_\([a-z_][^[:space:]]\+\)\([[:space:]].*\)\?$/#ifdef __NR_\1\n[__NR_\1 \& 0xffff] = "\1",\n#endif/p
diff --git a/tests/ksysent.test b/tests/ksysent.test
new file mode 100755 (executable)
index 0000000..8026648
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Validate syscallent.h
+
+./ksysent