* copy_file_range.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* linux/32/syscallent.h (copy_file_range): New entry.
* linux/64/syscallent.h: Likewise.
* linux/arm/syscallent.h: Likewise.
* linux/i386/syscallent.h: Likewise.
* linux/ia64/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/powerpc64/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sparc64/syscallent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/syscallent.h: Likewise.
* pathtrace.c (pathtrace_match): Add SEN_copy_file_range.
* NEWS: Mention new syscall parser.
* tests/copy_file_range.c: New file.
* tests/copy_file_range.test: New test.
* tests/.gitignore: Add copy_file_range.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(TESTS): Add copy_file_range.test.
chdir.c \
chmod.c \
clone.c \
+ copy_file_range.c \
count.c \
defs.h \
desc.c \
* Added decoding of bind, listen, and setsockopt direct syscalls on sparc.
* Implemented caching of netlink conversations to reduce amount of time
spent in decoding socket details in -yy mode.
+ * Implemented decoding of copy_file_range syscall.
* Bug fixes
* Fixed build on arc, metag, nios2, or1k, and tile architectures.
--- /dev/null
+/*
+ * Copyright (c) 2016 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"
+
+SYS_FUNC(copy_file_range)
+{
+ /* int fd_in */
+ printfd(tcp, tcp->u_arg[0]);
+ tprints(", ");
+ /* loff_t *off_in */
+ printnum_int64(tcp, tcp->u_arg[1], "%" PRId64);
+ tprints(", ");
+ /* int fd_out */
+ printfd(tcp, tcp->u_arg[2]);
+ tprints(", ");
+ /* loff_t *off_out */
+ printnum_int64(tcp, tcp->u_arg[3], "%" PRId64);
+ tprints(", ");
+ /* size_t len */
+ tprintf("%lu, ", tcp->u_arg[4]);
+ /* unsigned int flags */
+ tprintf("%u", (unsigned int) tcp->u_arg[5]);
+
+ return RVAL_DECODED;
+}
[282] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[283] = { 2, 0, SEN(membarrier), "membarrier", },
[284] = { 3, TM, SEN(mlock2), "mlock2" },
+[285] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
#undef sys_ARCH_mmap
#undef ARCH_WANT_SYNC_FILE_RANGE2
[282] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[283] = { 2, 0, SEN(membarrier), "membarrier", },
[284] = { 3, TM, SEN(mlock2), "mlock2" },
+[285] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
[388] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[389] = { 2, 0, SEN(membarrier), "membarrier", },
[390] = { 3, TM, SEN(mlock2), "mlock2" },
-[391 ... 399] = { },
+[391] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[392 ... 399] = { },
#ifdef __ARM_EABI__
# define ARM_FIRST_SHUFFLED_SYSCALL 400
[374] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[375] = { 2, 0, SEN(membarrier), "membarrier", },
[376] = { 3, TM, SEN(mlock2), "mlock2" },
-[377 ... 399] = { },
+[377] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[378 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[1344] = { 2, 0, SEN(membarrier), "membarrier", },
[1345] = { 5, 0, SEN(kcmp), "kcmp" },
[1346] = { 3, TM, SEN(mlock2), "mlock2" },
+[1347] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
[373] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[374] = { 2, 0, SEN(membarrier), "membarrier", },
[375] = { 3, TM, SEN(mlock2), "mlock2" },
-[376 ... 399] = { },
+[376] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[377 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[376] = { 3, TI, SEN(shmget), "shmget" },
[377] = { 3, TI, SEN(shmctl), "shmctl" },
[378] = { 3, TM, SEN(mlock2), "mlock2" },
-[379 ... 399] = { },
+[379] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[380 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[376] = { 3, TI, SEN(shmget), "shmget" },
[377] = { 3, TI, SEN(shmctl), "shmctl" },
[378] = { 3, TM, SEN(mlock2), "mlock2" },
-[379 ... 399] = { },
+[379] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[380 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[372] = { 3, TN, SEN(recvmsg), "recvmsg" },
[373] = { 2, TN, SEN(shutdown), "shutdown" },
[374] = { 3, TM, SEN(mlock2), "mlock2" },
-[375 ... 399] = { },
+[375] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[376 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[372] = { 3, TN, SEN(recvmsg), "recvmsg" },
[373] = { 2, TN, SEN(shutdown), "shutdown" },
[374] = { 3, TM, SEN(mlock2), "mlock2" },
-[375 ... 399] = { },
+[375] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[376 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[354] = { 2, TN, SEN(listen), "listen" },
[355] = { 5, TN, SEN(setsockopt), "setsockopt" },
[356] = { 3, TM, SEN(mlock2), "mlock2" },
-[357 ... 399] = { },
+[357] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[358 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[354] = { 2, TN, SEN(listen), "listen" },
[355] = { 5, TN, SEN(setsockopt), "setsockopt" },
[356] = { 3, TM, SEN(mlock2), "mlock2" },
-[357 ... 399] = { },
+[357] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[358 ... 399] = { },
#define SYS_socket_subcall 400
#include "subcall.h"
[323] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[324] = { 2, 0, SEN(membarrier), "membarrier", },
[325] = { 3, TM, SEN(mlock2), "mlock2" },
-[326 ... 511] = { },
+[326] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
+[327 ... 511] = { },
/*
* x32-specific system call numbers start at 512 to avoid cache impact
* for native 64-bit operation.
[323] = { 1, TD, SEN(userfaultfd), "userfaultfd", },
[324] = { 2, 0, SEN(membarrier), "membarrier", },
[325] = { 3, TM, SEN(mlock2), "mlock2" },
+[326] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
upathmatch(tcp, tcp->u_arg[0]) ||
upathmatch(tcp, tcp->u_arg[2]);
+ case SEN_copy_file_range:
case SEN_splice:
- /* fd, x, fd, x, x */
+ /* fd, x, fd, x, x, x */
return fdmatch(tcp, tcp->u_arg[0]) ||
fdmatch(tcp, tcp->u_arg[2]);
caps
clock_nanosleep
clock_xettime
+copy_file_range
epoll_create1
eventfd
execve
caps \
clock_nanosleep \
clock_xettime \
+ copy_file_range \
epoll_create1 \
eventfd \
execve \
caps.test \
clock_nanosleep.test \
clock_xettime.test \
+ copy_file_range.test \
dumpio.test \
epoll_create1.test \
eventfd.test \
--- /dev/null
+/*
+ * This file is part of copy_file_range strace test.
+ *
+ * Copyright (c) 2016 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 "tests.h"
+#include <sys/syscall.h>
+
+#if defined __NR_copy_file_range
+
+# include <assert.h>
+# include <errno.h>
+# include <stdio.h>
+# include <unistd.h>
+
+int
+main(void)
+{
+ const long int fd_in = (long int) 0xdeadbeefffffffff;
+ const long int fd_out = (long int) 0xdeadbeeffffffffe;
+ long long int *const off_in = tail_alloc(sizeof(*off_in));
+ long long int *const off_out = tail_alloc(sizeof(*off_out));
+ *off_in = 0xdeadbef1facefed1;
+ *off_out = 0xdeadbef2facefed2;
+ const size_t len = (size_t) 0xdeadbef3facefed3ULL;
+ const unsigned int flags = 0;
+
+ assert(syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out,
+ len, flags) == -1);
+ printf("copy_file_range(%d, [%lld], %d, [%lld], %zu, %u) = -1 %s (%m)\n",
+ (int) fd_in, *off_in, (int) fd_out, *off_out, len, flags,
+ errno == ENOSYS ? "ENOSYS" : "EBADF");
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_copy_file_range")
+
+#endif
--- /dev/null
+#!/bin/sh
+
+# Check copy_file_range syscall decoding.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+OUT="$LOG.out"
+run_strace -ecopy_file_range $args > "$OUT"
+match_diff "$LOG" "$OUT"
+rm -f "$OUT"