From bab4ef4272cd2596c7390b34ea8acc086ee8fdb2 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Thu, 10 Dec 2015 02:06:25 +0000 Subject: [PATCH] tests: add ksysent.test Check that syscall names and numbers defined in syscallent files match kernel __NR_* constants defined by . 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 | 1 + tests/Makefile.am | 14 +++++- tests/ksysent.c | 122 +++++++++++++++++++++++++++++++++++++++++++++ tests/ksysent.sed | 15 ++++++ tests/ksysent.test | 5 ++ 5 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 tests/ksysent.c create mode 100644 tests/ksysent.sed create mode 100755 tests/ksysent.test diff --git a/tests/.gitignore b/tests/.gitignore index 714d82ba..6cc56cc2 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -37,6 +37,7 @@ ipc_msg ipc_msgbuf ipc_sem ipc_shm +ksysent llseek lseek lstat diff --git a/tests/Makefile.am b/tests/Makefile.am index a13dc308..fdeb5ec7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 ' | \ + $(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 index 00000000..1d099177 --- /dev/null +++ b/tests/ksysent.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015 Dmitry V. Levin + * 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 index 00000000..56fe042e --- /dev/null +++ b/tests/ksysent.sed @@ -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 index 00000000..80266488 --- /dev/null +++ b/tests/ksysent.test @@ -0,0 +1,5 @@ +#!/bin/sh + +# Validate syscallent.h + +./ksysent -- 2.40.0