From patchwork Fri Jan 18 21:30:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027769 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="fsAh4eQu"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDw5116Gz9s9G for ; Sat, 19 Jan 2019 08:43:33 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47542 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbvH-0005XP-3j for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:43:31 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55790) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbjx-0004jp-LD for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjt-0003y1-KY for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:49 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:34376) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjt-0003k7-8l for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:45 -0500 Received: by mail-pl1-x644.google.com with SMTP id w4so6895086plz.1 for ; Fri, 18 Jan 2019 13:31:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2sBT0OtOyPsdmida1xRnXa6qbZhVoMKKJEx1iPCqOf4=; b=fsAh4eQuWTdTo2TGPIAYZbGjsuKNyMyKQflF4o7+HZW5gupqCWAs8iSOZ74Hi52tWr ikKOPUHmYsUBjil39LWka5YN+ij20jTLPbPiAU65hw2ZUjMsOYVhFfwVnE5EgykKS0Ws jKVWoCjUXos7HIX2yOrnbFYEvw4EbpTEaFTv4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2sBT0OtOyPsdmida1xRnXa6qbZhVoMKKJEx1iPCqOf4=; b=FZ3fMEF7m/LD/HNs1mBTYlAU7DUzZwi5WoDruFaBfjkW1p7a+hWxyBv58E5U3cpydg btXAFn5g4hdzLW/3VYVoGbLq3LkkPPvhVG4/K0HZKmG5Svb7QLX5QyU6AWxnT4uLzkPO uyURSGrkSp+VotyMYFNVXY83bBJnWxVSzafhA6yioVsGSrfJ7NUa0IuySJnpiLwGgYcZ wZFucYd8BSMQ+j7QOwCoMxzv68wqZQvrPCmtcYGMeURe6KISMQz6ldQSkLo+z/+DWenh vg3XnldCR3kiaId3GLWqr6w4WQ/Az2CyiYmBOApxqEM9nAaibup5YpsTfxOJBqvgHMit cUyA== X-Gm-Message-State: AJcUukdX4SYODeCvhzvKp+aqtgpsJ3X+RyrX7J4qaM73ailh4Z1QUMyc RAlIekes/414ya7wU5rgjFmSCvAFsog= X-Google-Smtp-Source: ALg8bN6rVma6dSK2QjPU74ZJvpP0wavpoFLALLWlUI2SYSoIEsFUxVr1v0YQXzm2B0o+sFrYDn6zHQ== X-Received: by 2002:a17:902:c5:: with SMTP id a63mr21026390pla.267.1547847092266; Fri, 18 Jan 2019 13:31:32 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:31 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:35 +1100 Message-Id: <20190118213122.22865-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 01/49] linux-user: Setup split syscall infrastructure X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Defines a unified structure for implementation and strace. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 17 ++ linux-user/syscall.h | 89 +++++++++ linux-user/strace.c | 388 +++++++++++++++++++++++++++----------- linux-user/syscall.c | 103 +++++++++- 4 files changed, 484 insertions(+), 113 deletions(-) create mode 100644 linux-user/syscall-defs.h create mode 100644 linux-user/syscall.h diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h new file mode 100644 index 0000000000..8c0490425a --- /dev/null +++ b/linux-user/syscall-defs.h @@ -0,0 +1,17 @@ +/* + * Linux syscall definitions + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ diff --git a/linux-user/syscall.h b/linux-user/syscall.h new file mode 100644 index 0000000000..43b5dc0684 --- /dev/null +++ b/linux-user/syscall.h @@ -0,0 +1,89 @@ +/* + * Linux syscalls internals + * Copyright (c) 2018 Linaro, Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef LINUX_USER_SYSCALL_H +#define LINUX_USER_SYSCALL_H 1 + +typedef struct SyscallDef SyscallDef; + +/* + * This hook extracts max 6 arguments from max 8 input registers. + * In the process, register pairs that store 64-bit arguments are merged. + * Finally, syscalls are demultipliexed; e.g. the hook for socketcall will + * return the SyscallDef for bind, listen, etc. In the process the hook + * may need to read from guest memory, or otherwise validate operands. + * On failure, set errno (to a host value) and return NULL; + * the (target adjusted) errno will be returned to the guest. + */ +typedef const SyscallDef *SyscallArgsFn(const SyscallDef *, int64_t out[6], + abi_long in[8]); + +/* This hook implements the syscall. */ +typedef abi_long SyscallImplFn(CPUArchState *, int64_t, int64_t, int64_t, + int64_t, int64_t, int64_t); + +/* This hook prints the arguments to the syscall for strace. */ +typedef void SyscallPrintFn(const SyscallDef *, int64_t arg[6]); + +/* This hook print the return value from the syscall for strace. */ +typedef void SyscallPrintRetFn(const SyscallDef *, abi_long); + +/* + * These flags describe the arguments for the generic fallback to + * SyscallPrintFn. ARG_NONE indicates that the argument is not present. + */ +typedef enum { + ARG_NONE = 0, + + /* These print as numbers of abi_long. */ + ARG_DEC, + ARG_HEX, + ARG_OCT, + + /* These print as sets of flags. */ + ARG_ATDIRFD, + ARG_MODEFLAG, + ARG_OPENFLAG, + + /* These are interpreted as pointers. */ + ARG_PTR, + ARG_STR, + ARG_BUF, + + /* For a 32-bit host, force printing as a 64-bit operand. */ +#if TARGET_ABI_BITS == 32 + ARG_DEC64, +#else + ARG_DEC64 = ARG_DEC, +#endif +} SyscallArgType; + +struct SyscallDef { + const char *name; + SyscallArgsFn *args; + SyscallImplFn *impl; + SyscallPrintFn *print; + SyscallPrintRetFn *print_ret; + SyscallArgType arg_type[6]; +}; + +void print_syscall_def(const SyscallDef *def, int64_t args[6]); +void print_syscall_def_ret(const SyscallDef *def, abi_long ret); +void print_syscall_ptr_ret(const SyscallDef *def, abi_long ret); + +#endif diff --git a/linux-user/strace.c b/linux-user/strace.c index 7318392e57..8c467da48e 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -10,6 +10,7 @@ #include #include #include "qemu.h" +#include "syscall.h" int do_strace=0; @@ -796,7 +797,7 @@ UNUSED static struct flags unlinkat_flags[] = { FLAG_END, }; -UNUSED static struct flags mode_flags[] = { +static struct flags const mode_flags[] = { FLAG_GENERIC(S_IFSOCK), FLAG_GENERIC(S_IFLNK), FLAG_GENERIC(S_IFREG), @@ -807,14 +808,14 @@ UNUSED static struct flags mode_flags[] = { FLAG_END, }; -UNUSED static struct flags open_access_flags[] = { +static struct flags const open_access_flags[] = { FLAG_TARGET(O_RDONLY), FLAG_TARGET(O_WRONLY), FLAG_TARGET(O_RDWR), FLAG_END, }; -UNUSED static struct flags open_flags[] = { +static struct flags const open_flags[] = { FLAG_TARGET(O_APPEND), FLAG_TARGET(O_CREAT), FLAG_TARGET(O_DIRECTORY), @@ -989,84 +990,86 @@ get_comma(int last) return ((last) ? "" : ","); } +static int add_flags(char *buf, int size, const struct flags *f, + int flags, bool octal) +{ + const char *sep = ""; + int off = 0; + + if (flags == 0 && f->f_value == 0) { + return snprintf(buf, size, "%s", f->f_string); + } + + for (; f->f_string != NULL; f++) { + if (f->f_value != 0 && (flags & f->f_value) == f->f_value) { + off += snprintf(buf + off, size - off, "%s%s", sep, f->f_string); + flags &= ~f->f_value; + sep = "|"; + } + } + + /* Print rest of the flags as numeric. */ + if (flags) { + if (octal) { + off += snprintf(buf + off, size - off, "%s%#o", sep, flags); + } else { + off += snprintf(buf + off, size - off, "%s%#x", sep, flags); + } + } + return off; +} + static void print_flags(const struct flags *f, abi_long flags, int last) { - const char *sep = ""; - int n; + char buf[256]; + add_flags(buf, sizeof(buf), f, flags, false); + gemu_log("%s%s", buf, get_comma(last)); +} - if ((flags == 0) && (f->f_value == 0)) { - gemu_log("%s%s", f->f_string, get_comma(last)); - return; - } - for (n = 0; f->f_string != NULL; f++) { - if ((f->f_value != 0) && ((flags & f->f_value) == f->f_value)) { - gemu_log("%s%s", sep, f->f_string); - flags &= ~f->f_value; - sep = "|"; - n++; - } - } - - if (n > 0) { - /* print rest of the flags as numeric */ - if (flags != 0) { - gemu_log("%s%#x%s", sep, (unsigned int)flags, get_comma(last)); - } else { - gemu_log("%s", get_comma(last)); - } +static int add_atdirfd(char *buf, int size, int fd) +{ + if (fd == AT_FDCWD) { + return snprintf(buf, size, "AT_FDCWD"); } else { - /* no string version of flags found, print them in hex then */ - gemu_log("%#x%s", (unsigned int)flags, get_comma(last)); + return snprintf(buf, size, "%d", fd); } } static void print_at_dirfd(abi_long dirfd, int last) { -#ifdef AT_FDCWD - if (dirfd == AT_FDCWD) { - gemu_log("AT_FDCWD%s", get_comma(last)); - return; - } -#endif - gemu_log("%d%s", (int)dirfd, get_comma(last)); + char buf[16]; + add_atdirfd(buf, sizeof(buf), dirfd); + gemu_log("%s%s", buf, get_comma(last)); } static void print_file_mode(abi_long mode, int last) { - const char *sep = ""; - const struct flags *m; + char buf[256]; + add_flags(buf, sizeof(buf), mode_flags, mode, true); + gemu_log("%s%s", buf, get_comma(last)); +} - for (m = &mode_flags[0]; m->f_string != NULL; m++) { - if ((m->f_value & mode) == m->f_value) { - gemu_log("%s%s", m->f_string, sep); - sep = "|"; - mode &= ~m->f_value; - break; - } +static int add_open_flags(char *buf, int size, int flags) +{ + int off = add_flags(buf, size, open_access_flags, + flags & TARGET_O_ACCMODE, false); + flags &= ~TARGET_O_ACCMODE; + if (flags == 0 || off + 2 >= size) { + return off; } - - mode &= ~S_IFMT; - /* print rest of the mode as octal */ - if (mode != 0) - gemu_log("%s%#o", sep, (unsigned int)mode); - - gemu_log("%s", get_comma(last)); + buf[off++] = '|'; + return off + add_flags(buf + off, size - off, open_flags, flags, true); } static void print_open_flags(abi_long flags, int last) { - print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1); - flags &= ~TARGET_O_ACCMODE; - if (flags == 0) { - gemu_log("%s", get_comma(last)); - return; - } - gemu_log("|"); - print_flags(open_flags, flags, last); + char buf[256]; + add_open_flags(buf, sizeof(buf), flags); + gemu_log("%s%s", buf, get_comma(last)); } static void @@ -1083,48 +1086,86 @@ print_syscall_epilogue(const struct syscallname *sc) gemu_log(")"); } -static void -print_string(abi_long addr, int last) +static int add_pointer(char *buf, int size, abi_ulong addr) { - char *s; - - if ((s = lock_user_string(addr)) != NULL) { - gemu_log("\"%s\"%s", s, get_comma(last)); - unlock_user(s, addr, 0); + if (addr) { + return snprintf(buf, size, "0x" TARGET_ABI_FMT_lx, addr); } else { - /* can't get string out of it, so print it as pointer */ - print_pointer(addr, last); + return snprintf(buf, size, "NULL"); } } +static int add_string(char *buf, int size, abi_ulong addr) +{ + char *s = lock_user_string(addr); + if (s) { + /* TODO: Escape special characters within the string. */ + /* TODO: Limit the string length for logging. */ + int len = snprintf(buf, size, "\"%s\"", s); + unlock_user(s, addr, 0); + return len; + } + return add_pointer(buf, size, addr); +} + +static void +print_string(abi_long addr, int last) +{ + char buf[256]; + add_string(buf, sizeof(buf), addr); + gemu_log("%s%s", buf, get_comma(last)); +} + #define MAX_PRINT_BUF 40 + +static int add_buffer(char *buf, int size, abi_long addr, abi_ulong len) +{ + unsigned char *p; + int off = 0; + abi_ulong i; + + p = lock_user(VERIFY_READ, addr, MIN(len, MAX_PRINT_BUF), 1); + if (!p) { + return add_pointer(buf, size, addr); + } + + buf[0] = '"'; + off = 1; + + for (i = 0; i < MAX_PRINT_BUF; ++i) { + int len; + + if (isprint(p[i])) { + buf[off] = p[i]; + len = 1; + } else { + len = snprintf(buf + off, size - off, "\\%o", p[i]); + } + off += len; + if (off + 2 >= size) { + goto overflow; + } + } + unlock_user(p, addr, 0); + + if (i == len && off + 2 < size) { + buf[off] = '"'; + buf[off + 1] = 0; + return off + 1; + } + + overflow: + off = MIN(off, size - 5); + strcpy(buf + off, "...\""); + return off + 4; +} + static void print_buf(abi_long addr, abi_long len, int last) { - uint8_t *s; - int i; - - s = lock_user(VERIFY_READ, addr, len, 1); - if (s) { - gemu_log("\""); - for (i = 0; i < MAX_PRINT_BUF && i < len; i++) { - if (isprint(s[i])) { - gemu_log("%c", s[i]); - } else { - gemu_log("\\%o", s[i]); - } - } - gemu_log("\""); - if (i != len) { - gemu_log("..."); - } - if (!last) { - gemu_log(","); - } - unlock_user(s, addr, 0); - } else { - print_pointer(addr, last); - } + char buf[256]; + add_buffer(buf, sizeof(buf), addr, len); + gemu_log("%s%s", buf, get_comma(last)); } /* @@ -1143,10 +1184,9 @@ print_raw_param(const char *fmt, abi_long param, int last) static void print_pointer(abi_long p, int last) { - if (p == 0) - gemu_log("NULL%s", get_comma(last)); - else - gemu_log("0x" TARGET_ABI_FMT_lx "%s", p, get_comma(last)); + char buf[24]; + add_pointer(buf, sizeof(buf), p); + gemu_log("%s%s", buf, get_comma(last)); } /* @@ -2638,32 +2678,170 @@ print_syscall(int num, gemu_log("Unknown syscall %d\n", num); } +static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) +{ + char buf[1024], *b = buf; + int i, rest = sizeof(buf); + + /* + * Render the argument list into BUF. This allows us to log the + * entire syscall in one write statement at the end. + * While this is still not quite as good as separate files, a-la + * strace -ff, it can minimize confusion with a multithreaded guest. + */ + buf[0] = 0; + for (i = 0; i < 6; ++i) { + SyscallArgType type = def->arg_type[i]; + int64_t arg = args[i]; + int len; + + if (type == ARG_NONE) { + break; + } + + /* Validate remaining space. */ + if (rest < 4) { + goto overflow; + } + + /* Add separator. */ + if (i > 0) { + b[0] = ','; + b[1] = ' '; + b += 2; + rest -= 2; + } + + switch (type) { +#if TARGET_ABI_BITS == 32 + /* + * ??? We don't have TARGET_ABI_FMT_* macros for exactly + * what we want here. For this case it probably makes + * most sense to just special case. + */ + case ARG_DEC: + len = snprintf(b, rest, "%d", (int32_t)arg); + break; + case ARG_HEX: + len = snprintf(b, rest, "%#x", (uint32_t)arg); + break; + case ARG_OCT: + len = snprintf(b, rest, "%#o", (uint32_t)arg); + break; + case ARG_DEC64: + len = snprintf(b, rest, "%" PRId64, arg); + break; +#else + case ARG_DEC: + len = snprintf(b, rest, "%" PRId64, arg); + break; + case ARG_OCT: + len = snprintf(b, rest, "%" PRIo64, arg); + break; + case ARG_HEX: + len = snprintf(b, rest, "%" PRIx64, arg); + break; +#endif + case ARG_ATDIRFD: + len = add_atdirfd(b, rest, arg); + break; + case ARG_MODEFLAG: + len = add_flags(b, rest, mode_flags, arg, true); + break; + case ARG_OPENFLAG: + len = add_open_flags(b, rest, arg); + break; + case ARG_PTR: + len = add_pointer(b, rest, arg); + break; + case ARG_STR: + len = add_string(b, rest, arg); + break; + case ARG_BUF: + len = add_buffer(b, rest, arg, MAX_PRINT_BUF); + break; + default: + g_assert_not_reached(); + } + + b += len; + rest -= len; + if (rest == 0) { + goto overflow; + } + } + goto done; + + overflow: + strcpy(buf + sizeof(buf) - 4, "..."); + done: + gemu_log("%d %s(%s)", getpid(), def->name, buf); +} + +void print_syscall_def(const SyscallDef *def, int64_t args[6]) +{ + SyscallPrintFn *print = def->print; + if (!print) { + print = print_syscall_def1; + } + print(def, args); +} + +static void print_syscall_def_ret1(const SyscallDef *def, abi_long ret) +{ + if (is_error(ret)) { + const char *errstr = target_strerror(-ret); + if (errstr) { + gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", + -ret, errstr); + } else { + gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld "\n", -ret); + } + } else { + gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret); + } +} void print_syscall_ret(int num, abi_long ret) { int i; - const char *errstr = NULL; for(i=0;iprint_ret; + if (!print) { + print = print_syscall_def_ret1; + } + print(def, ret); +} + void print_taken_signal(int target_signum, const target_siginfo_t *tinfo) { /* Print the strace output for a signal being taken: diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b5786d4fc1..93377f7586 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -111,6 +111,7 @@ #include "qemu.h" #include "fd-trans.h" +#include "syscall.h" #ifndef CLONE_IO #define CLONE_IO 0x80000000 /* Clone io context */ @@ -11533,12 +11534,70 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return ret; } +/* Emit the signature for a SyscallArgsFn. */ +#define SYSCALL_ARGS(NAME) \ + static const SyscallDef *args_##NAME(const SyscallDef *def, \ + int64_t out[6], abi_long in[8]) + +/* Emit the signature for a SyscallImplFn. */ +#define SYSCALL_IMPL(NAME) \ + static abi_long impl_##NAME(CPUArchState *cpu_env, int64_t arg1, \ + int64_t arg2, int64_t arg3, int64_t arg4, \ + int64_t arg5, int64_t arg6) + + +#undef SYSCALL_IMPL +#undef SYSCALL_ARGS + +/* + * Emit a complete SyscallDef structure. + */ +#define SYSCALL_DEF_FULL(NAME, ...) \ + static const SyscallDef def_##NAME = { .name = #NAME, __VA_ARGS__ } + +/* + * Emit the definition for a "simple" syscall. Such does not use + * SyscallArgsFn and only uses arg_type for strace. + */ +#define SYSCALL_DEF(NAME, ...) \ + SYSCALL_DEF_FULL(NAME, .impl = impl_##NAME, .arg_type = { __VA_ARGS__ }) + +/* Similarly, but also uses an args hook. */ +#define SYSCALL_DEF_ARGS(NAME, ...) \ + SYSCALL_DEF_FULL(NAME, .impl = impl_##NAME, .args = args_##NAME, \ + .arg_type = { __VA_ARGS__ }) + +#include "syscall-defs.h" + +#undef SYSCALL_DEF +#undef SYSCALL_DEF_ARGS +#undef SYSCALL_DEF_FULL + +static const SyscallDef *syscall_table(int num) +{ +#define SYSCALL_DEF(NAME, ...) case TARGET_NR_##NAME: return &def_##NAME +#define SYSCALL_DEF_ARGS(NAME, ...) SYSCALL_DEF(NAME) +#define SYSCALL_DEF_FULL(NAME, ...) SYSCALL_DEF(NAME) + + switch (num) { +#include "syscall-defs.h" + } + return NULL; + +#undef SYSCALL_DEF +#undef SYSCALL_DEF_ARGS +#undef SYSCALL_DEF_FULL +} + abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6, abi_long arg7, abi_long arg8) { CPUState *cpu = ENV_GET_CPU(cpu_env); + const SyscallDef *def, *orig_def; + abi_long raw_args[8] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }; + int64_t out_args[6] = { arg1, arg2, arg3, arg4, arg5, arg6 }; abi_long ret; #ifdef DEBUG_ERESTARTSYS @@ -11558,16 +11617,44 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - if (unlikely(do_strace)) { - print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); - ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8); - print_syscall_ret(num, ret); - } else { - ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8); + orig_def = def = syscall_table(num); + if (def == NULL) { + /* Unconverted. */ + if (unlikely(do_strace)) { + print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); + ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8); + print_syscall_ret(num, ret); + } else { + ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8); + } + goto fini; } + if (def->args) { + def = def->args(def, out_args, raw_args); + if (unlikely(def == NULL)) { + ret = -host_to_target_errno(errno); + if (unlikely(do_strace)) { + print_syscall_def(orig_def, out_args); + print_syscall_def_ret(orig_def, ret); + } + goto fini; + } + } + + if (unlikely(do_strace)) { + print_syscall_def(def, out_args); + ret = def->impl(cpu_env, out_args[0], out_args[1], out_args[2], + out_args[3], out_args[4], out_args[5]); + print_syscall_def_ret(def, ret); + } else { + ret = def->impl(cpu_env, out_args[0], out_args[1], out_args[2], + out_args[3], out_args[4], out_args[5]); + } + + fini: trace_guest_user_syscall_ret(cpu, num, ret); return ret; } From patchwork Fri Jan 18 21:30:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027772 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="SoTGtgd0"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDzZ2qJ2z9s9G for ; Sat, 19 Jan 2019 08:46:34 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47603 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbyC-0008G3-AI for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:46:32 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbjx-0004jx-SD for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjt-0003yK-RW for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:49 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:41189) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjs-0003lG-Ir for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:45 -0500 Received: by mail-pf1-x441.google.com with SMTP id b7so7191472pfi.8 for ; Fri, 18 Jan 2019 13:31:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ah5DcJ6uMCOPVLV6Yv1y7N+5WV2M1fI6YZhgD7/AS/w=; b=SoTGtgd0L5pzzDudOBQcoZbZlz2lwUOFK7ZmZ3y+ENnmV6QcreOaHS0kYcBqQG0mAa e4ZB1GQnNALlMFvvg/CkA5VLrb9Gt6Uec8EBLLQ9898gwa15hypAtJO4TSekDuBlBhx/ Ay/7Ki7u1CDAEZy7eT7AhKmDdlFGD5rcDEl90= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Ah5DcJ6uMCOPVLV6Yv1y7N+5WV2M1fI6YZhgD7/AS/w=; b=gGDuAvLAuv+1L7Uxb7jJg31IgmWAUK8Y/6PNXhPydBdjRDHixGAODir46+E4F6FPnV 72mqa4C91bKKShxUKt9kbhvD9kmO5Yi4Ux9USWjHP0jyuHQDzzTqvUFFWgegpMsPrceb 3XlznsPIbbYaaNwXTxz6BwTx773GiJ7OFKeHTosiJEF9KyHOTaVYkSGm7pluRuL/r+CE jiol3dBK4peAY9p6cdHiPBjvB/+ZVkc0QYHc3ijV4Cj2116gcSUbCY+35r2c/ty13CK8 FvPig1XHauQ5d+9yDONRjFKP1N+zVpKTBr7lsEtk1MporBp0Cp3ZP6tAF7UH7d9S15jh U1mg== X-Gm-Message-State: AJcUukczw4P8QYObMeLALulkmeY6FA2353q0Bh5Rue9WQ37kqXrkkoCg gx2q//4rUQGvP0ZCXQUoJtXGIK3l+m0= X-Google-Smtp-Source: ALg8bN742dbHdR14CuoTSZ5l6LxZFHFwm9WvqPnw8iDL29CACusjayKNosSjT2T4ho/1leksPLWZqw== X-Received: by 2002:a63:1a0c:: with SMTP id a12mr19005372pga.157.1547847094636; Fri, 18 Jan 2019 13:31:34 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.32 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:34 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:36 +1100 Message-Id: <20190118213122.22865-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 03/49] linux-user: Split out open, open_at X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" For the moment, leave a forward declaration for is_proc_myself until the readlink syscalls are also moved to syscall-file.inc.c. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 5 + linux-user/strace.c | 35 ---- linux-user/syscall-file.inc.c | 319 ++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 282 +----------------------------- linux-user/strace.list | 6 - 5 files changed, 326 insertions(+), 321 deletions(-) create mode 100644 linux-user/syscall-file.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 8c0490425a..1f3a9c47ab 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -15,3 +15,8 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ + +#ifdef TARGET_NR_open +SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); +#endif +SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); diff --git a/linux-user/strace.c b/linux-user/strace.c index 8c467da48e..1e4f6c9b53 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -2216,41 +2216,6 @@ print_mq_open(const struct syscallname *name, } #endif -#ifdef TARGET_NR_open -static void -print_open(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - int is_creat = (arg1 & TARGET_O_CREAT); - - print_syscall_prologue(name); - print_string(arg0, 0); - print_open_flags(arg1, (is_creat == 0)); - if (is_creat) - print_file_mode(arg2, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_openat -static void -print_openat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - int is_creat = (arg2 & TARGET_O_CREAT); - - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_open_flags(arg2, (is_creat == 0)); - if (is_creat) - print_file_mode(arg3, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_mq_unlink static void print_mq_unlink(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c new file mode 100644 index 0000000000..ca777da753 --- /dev/null +++ b/linux-user/syscall-file.inc.c @@ -0,0 +1,319 @@ +/* + * Linux file-related syscall implementations + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Helpers for do_openat, manipulating /proc/self/foo. + */ + +static int open_self_cmdline(void *cpu_env, int fd) +{ + CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); + struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm; + int i; + + for (i = 0; i < bprm->argc; i++) { + size_t len = strlen(bprm->argv[i]) + 1; + + if (write(fd, bprm->argv[i], len) != len) { + return -1; + } + } + + return 0; +} + +static int open_self_maps(void *cpu_env, int fd) +{ + CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); + TaskState *ts = cpu->opaque; + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t read; + + fp = fopen("/proc/self/maps", "r"); + if (fp == NULL) { + return -1; + } + + while ((read = getline(&line, &len, fp)) != -1) { + int fields, dev_maj, dev_min, inode; + uint64_t min, max, offset; + char flag_r, flag_w, flag_x, flag_p; + char path[512] = ""; + fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d" + " %512s", &min, &max, &flag_r, &flag_w, &flag_x, + &flag_p, &offset, &dev_maj, &dev_min, &inode, path); + + if ((fields < 10) || (fields > 11)) { + continue; + } + if (h2g_valid(min)) { + int flags = page_get_flags(h2g(min)); + max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX) + 1; + if (page_check_range(h2g(min), max - min, flags) == -1) { + continue; + } + if (h2g(min) == ts->info->stack_limit) { + pstrcpy(path, sizeof(path), " [stack]"); + } + dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr + " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n", + h2g(min), h2g(max - 1) + 1, flag_r, flag_w, + flag_x, flag_p, offset, dev_maj, dev_min, inode, + path[0] ? " " : "", path); + } + } + + free(line); + fclose(fp); + + return 0; +} + +static int open_self_stat(void *cpu_env, int fd) +{ + CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); + TaskState *ts = cpu->opaque; + abi_ulong start_stack = ts->info->start_stack; + int i; + + for (i = 0; i < 44; i++) { + char buf[128]; + int len; + uint64_t val = 0; + + if (i == 0) { + /* pid */ + val = getpid(); + snprintf(buf, sizeof(buf), "%"PRId64 " ", val); + } else if (i == 1) { + /* app name */ + snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]); + } else if (i == 27) { + /* stack bottom */ + val = start_stack; + snprintf(buf, sizeof(buf), "%"PRId64 " ", val); + } else { + /* for the rest, there is MasterCard */ + snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' '); + } + + len = strlen(buf); + if (write(fd, buf, len) != len) { + return -1; + } + } + + return 0; +} + +static int open_self_auxv(void *cpu_env, int fd) +{ + CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); + TaskState *ts = cpu->opaque; + abi_ulong auxv = ts->info->saved_auxv; + abi_ulong len = ts->info->auxv_len; + char *ptr; + + /* + * Auxiliary vector is stored in target process stack. + * read in whole auxv vector and copy it to file + */ + ptr = lock_user(VERIFY_READ, auxv, len, 0); + if (ptr != NULL) { + while (len > 0) { + ssize_t r; + r = write(fd, ptr, len); + if (r <= 0) { + break; + } + len -= r; + ptr += r; + } + lseek(fd, 0, SEEK_SET); + unlock_user(ptr, auxv, len); + } + + return 0; +} + +static int is_proc_myself(const char *filename, const char *entry) +{ + if (!strncmp(filename, "/proc/", strlen("/proc/"))) { + filename += strlen("/proc/"); + if (!strncmp(filename, "self/", strlen("self/"))) { + filename += strlen("self/"); + } else if (*filename >= '1' && *filename <= '9') { + char myself[80]; + snprintf(myself, sizeof(myself), "%d/", getpid()); + if (!strncmp(filename, myself, strlen(myself))) { + filename += strlen(myself); + } else { + return 0; + } + } else { + return 0; + } + if (!strcmp(filename, entry)) { + return 1; + } + } + return 0; +} + +#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) +static int is_proc(const char *filename, const char *entry) +{ + return strcmp(filename, entry) == 0; +} + +static int open_net_route(void *cpu_env, int fd) +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t read; + + fp = fopen("/proc/net/route", "r"); + if (fp == NULL) { + return -1; + } + + /* read header */ + + read = getline(&line, &len, fp); + dprintf(fd, "%s", line); + + /* read routes */ + + while ((read = getline(&line, &len, fp)) != -1) { + char iface[16]; + uint32_t dest, gw, mask; + unsigned int flags, refcnt, use, metric, mtu, window, irtt; + sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n", + iface, &dest, &gw, &flags, &refcnt, &use, &metric, + &mask, &mtu, &window, &irtt); + dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n", + iface, tswap32(dest), tswap32(gw), flags, refcnt, use, + metric, tswap32(mask), mtu, window, irtt); + } + + free(line); + fclose(fp); + + return 0; +} +#endif + +static int do_openat(void *cpu_env, int dirfd, const char *pathname, + int flags, mode_t mode) +{ + struct fake_open { + const char *filename; + int (*fill)(void *cpu_env, int fd); + int (*cmp)(const char *s1, const char *s2); + }; + const struct fake_open *fake_open; + static const struct fake_open fakes[] = { + { "maps", open_self_maps, is_proc_myself }, + { "stat", open_self_stat, is_proc_myself }, + { "auxv", open_self_auxv, is_proc_myself }, + { "cmdline", open_self_cmdline, is_proc_myself }, +#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) + { "/proc/net/route", open_net_route, is_proc }, +#endif + { NULL, NULL, NULL } + }; + + if (is_proc_myself(pathname, "exe")) { + int execfd = qemu_getauxval(AT_EXECFD); + return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); + } + + for (fake_open = fakes; fake_open->filename; fake_open++) { + if (fake_open->cmp(pathname, fake_open->filename)) { + break; + } + } + + if (fake_open->filename) { + const char *tmpdir; + char filename[PATH_MAX]; + int fd, r; + + /* create temporary file to map stat to */ + tmpdir = getenv("TMPDIR"); + if (!tmpdir) { + tmpdir = "/tmp"; + } + snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir); + fd = mkstemp(filename); + if (fd < 0) { + return fd; + } + unlink(filename); + + r = fake_open->fill(cpu_env, fd); + if (r) { + int e = errno; + close(fd); + errno = e; + return r; + } + lseek(fd, 0, SEEK_SET); + + return fd; + } + + return safe_openat(dirfd, path(pathname), flags, mode); +} + +#ifdef TARGET_NR_open +SYSCALL_IMPL(open) +{ + char *p = lock_user_string(arg1); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(do_openat(cpu_env, AT_FDCWD, p, + target_to_host_bitmask(arg2, fcntl_flags_tbl), + arg3)); + fd_trans_unregister(ret); + unlock_user(p, arg1, 0); + return ret; +} +#endif + +SYSCALL_IMPL(openat) +{ + char *p = lock_user_string(arg2); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(do_openat(cpu_env, arg1, p, + target_to_host_bitmask(arg3, fcntl_flags_tbl), + arg4)); + fd_trans_unregister(ret); + unlock_user(p, arg2, 0); + return ret; +} diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9367574089..32d1a285eb 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6577,266 +6577,7 @@ int host_to_target_waitstatus(int status) return status; } -static int open_self_cmdline(void *cpu_env, int fd) -{ - CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); - struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm; - int i; - - for (i = 0; i < bprm->argc; i++) { - size_t len = strlen(bprm->argv[i]) + 1; - - if (write(fd, bprm->argv[i], len) != len) { - return -1; - } - } - - return 0; -} - -static int open_self_maps(void *cpu_env, int fd) -{ - CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); - TaskState *ts = cpu->opaque; - FILE *fp; - char *line = NULL; - size_t len = 0; - ssize_t read; - - fp = fopen("/proc/self/maps", "r"); - if (fp == NULL) { - return -1; - } - - while ((read = getline(&line, &len, fp)) != -1) { - int fields, dev_maj, dev_min, inode; - uint64_t min, max, offset; - char flag_r, flag_w, flag_x, flag_p; - char path[512] = ""; - fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d" - " %512s", &min, &max, &flag_r, &flag_w, &flag_x, - &flag_p, &offset, &dev_maj, &dev_min, &inode, path); - - if ((fields < 10) || (fields > 11)) { - continue; - } - if (h2g_valid(min)) { - int flags = page_get_flags(h2g(min)); - max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX) + 1; - if (page_check_range(h2g(min), max - min, flags) == -1) { - continue; - } - if (h2g(min) == ts->info->stack_limit) { - pstrcpy(path, sizeof(path), " [stack]"); - } - dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr - " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n", - h2g(min), h2g(max - 1) + 1, flag_r, flag_w, - flag_x, flag_p, offset, dev_maj, dev_min, inode, - path[0] ? " " : "", path); - } - } - - free(line); - fclose(fp); - - return 0; -} - -static int open_self_stat(void *cpu_env, int fd) -{ - CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); - TaskState *ts = cpu->opaque; - abi_ulong start_stack = ts->info->start_stack; - int i; - - for (i = 0; i < 44; i++) { - char buf[128]; - int len; - uint64_t val = 0; - - if (i == 0) { - /* pid */ - val = getpid(); - snprintf(buf, sizeof(buf), "%"PRId64 " ", val); - } else if (i == 1) { - /* app name */ - snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]); - } else if (i == 27) { - /* stack bottom */ - val = start_stack; - snprintf(buf, sizeof(buf), "%"PRId64 " ", val); - } else { - /* for the rest, there is MasterCard */ - snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' '); - } - - len = strlen(buf); - if (write(fd, buf, len) != len) { - return -1; - } - } - - return 0; -} - -static int open_self_auxv(void *cpu_env, int fd) -{ - CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); - TaskState *ts = cpu->opaque; - abi_ulong auxv = ts->info->saved_auxv; - abi_ulong len = ts->info->auxv_len; - char *ptr; - - /* - * Auxiliary vector is stored in target process stack. - * read in whole auxv vector and copy it to file - */ - ptr = lock_user(VERIFY_READ, auxv, len, 0); - if (ptr != NULL) { - while (len > 0) { - ssize_t r; - r = write(fd, ptr, len); - if (r <= 0) { - break; - } - len -= r; - ptr += r; - } - lseek(fd, 0, SEEK_SET); - unlock_user(ptr, auxv, len); - } - - return 0; -} - -static int is_proc_myself(const char *filename, const char *entry) -{ - if (!strncmp(filename, "/proc/", strlen("/proc/"))) { - filename += strlen("/proc/"); - if (!strncmp(filename, "self/", strlen("self/"))) { - filename += strlen("self/"); - } else if (*filename >= '1' && *filename <= '9') { - char myself[80]; - snprintf(myself, sizeof(myself), "%d/", getpid()); - if (!strncmp(filename, myself, strlen(myself))) { - filename += strlen(myself); - } else { - return 0; - } - } else { - return 0; - } - if (!strcmp(filename, entry)) { - return 1; - } - } - return 0; -} - -#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) -static int is_proc(const char *filename, const char *entry) -{ - return strcmp(filename, entry) == 0; -} - -static int open_net_route(void *cpu_env, int fd) -{ - FILE *fp; - char *line = NULL; - size_t len = 0; - ssize_t read; - - fp = fopen("/proc/net/route", "r"); - if (fp == NULL) { - return -1; - } - - /* read header */ - - read = getline(&line, &len, fp); - dprintf(fd, "%s", line); - - /* read routes */ - - while ((read = getline(&line, &len, fp)) != -1) { - char iface[16]; - uint32_t dest, gw, mask; - unsigned int flags, refcnt, use, metric, mtu, window, irtt; - sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n", - iface, &dest, &gw, &flags, &refcnt, &use, &metric, - &mask, &mtu, &window, &irtt); - dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n", - iface, tswap32(dest), tswap32(gw), flags, refcnt, use, - metric, tswap32(mask), mtu, window, irtt); - } - - free(line); - fclose(fp); - - return 0; -} -#endif - -static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode) -{ - struct fake_open { - const char *filename; - int (*fill)(void *cpu_env, int fd); - int (*cmp)(const char *s1, const char *s2); - }; - const struct fake_open *fake_open; - static const struct fake_open fakes[] = { - { "maps", open_self_maps, is_proc_myself }, - { "stat", open_self_stat, is_proc_myself }, - { "auxv", open_self_auxv, is_proc_myself }, - { "cmdline", open_self_cmdline, is_proc_myself }, -#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) - { "/proc/net/route", open_net_route, is_proc }, -#endif - { NULL, NULL, NULL } - }; - - if (is_proc_myself(pathname, "exe")) { - int execfd = qemu_getauxval(AT_EXECFD); - return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); - } - - for (fake_open = fakes; fake_open->filename; fake_open++) { - if (fake_open->cmp(pathname, fake_open->filename)) { - break; - } - } - - if (fake_open->filename) { - const char *tmpdir; - char filename[PATH_MAX]; - int fd, r; - - /* create temporary file to map stat to */ - tmpdir = getenv("TMPDIR"); - if (!tmpdir) - tmpdir = "/tmp"; - snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir); - fd = mkstemp(filename); - if (fd < 0) { - return fd; - } - unlink(filename); - - if ((r = fake_open->fill(cpu_env, fd))) { - int e = errno; - close(fd); - errno = e; - return r; - } - lseek(fd, 0, SEEK_SET); - - return fd; - } - - return safe_openat(dirfd, path(pathname), flags, mode); -} +static int is_proc_myself(const char *filename, const char *entry); #define TIMER_MAGIC 0x0caf0000 #define TIMER_MAGIC_MASK 0xffff0000 @@ -7021,26 +6762,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg2, 0); return ret; -#ifdef TARGET_NR_open - case TARGET_NR_open: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(do_openat(cpu_env, AT_FDCWD, p, - target_to_host_bitmask(arg2, fcntl_flags_tbl), - arg3)); - fd_trans_unregister(ret); - unlock_user(p, arg1, 0); - return ret; -#endif - case TARGET_NR_openat: - if (!(p = lock_user_string(arg2))) - return -TARGET_EFAULT; - ret = get_errno(do_openat(cpu_env, arg1, p, - target_to_host_bitmask(arg3, fcntl_flags_tbl), - arg4)); - fd_trans_unregister(ret); - unlock_user(p, arg2, 0); - return ret; #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) case TARGET_NR_name_to_handle_at: ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5); @@ -11545,6 +11266,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, int64_t arg2, int64_t arg3, int64_t arg4, \ int64_t arg5, int64_t arg6) +#include "syscall-file.inc.c" #undef SYSCALL_IMPL #undef SYSCALL_ARGS diff --git a/linux-user/strace.list b/linux-user/strace.list index ff8bb19f5f..b2d3e99df7 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -677,12 +677,6 @@ #ifdef TARGET_NR_olduname { TARGET_NR_olduname, "olduname" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_open -{ TARGET_NR_open, "open" , NULL, print_open, NULL }, -#endif -#ifdef TARGET_NR_openat -{ TARGET_NR_openat, "openat" , NULL, print_openat, NULL }, -#endif #ifdef TARGET_NR_osf_adjtime { TARGET_NR_osf_adjtime, "osf_adjtime" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027757 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="BvhPAo3N"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDjh1w07z9s9G for ; Sat, 19 Jan 2019 08:34:32 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47405 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbmY-0006Gr-1p for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:34:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55719) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbju-0004hk-V4 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjt-0003xf-J0 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:46 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:33615) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjs-0003mi-Ip for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:45 -0500 Received: by mail-pf1-x441.google.com with SMTP id c123so7220157pfb.0 for ; Fri, 18 Jan 2019 13:31:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xn0wCKHONKALxJfo3bPxJs7CyFRY/xeQ+BVQGQWT6CM=; b=BvhPAo3NI3tJhJnsVF4oo8qoNe5fO0RrE8ym4yDgpF5y7DKpVLLCNwXg1GzA3NL8MK 2KR/U9a2pgiHxhi9CnhtkJQnABKUkM1/559ADp6eARvCbQ6IrteymWFg0pQhfkKAt7ot kx23KO8cJOKVupntcsqiGe1wiuJ0joVkpvDxQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xn0wCKHONKALxJfo3bPxJs7CyFRY/xeQ+BVQGQWT6CM=; b=rY6vS2dDm4zStoYoFdcT3wpE/RyLyhZCRCn6E+nz6vE2mD1FWkgawnVIagb6Mq2InX cSzoT7z5L6K98idgtQwHEfV3rg6JdEyWAgr80sR48phRqvX/LavFeJbTJlpzip4cfNyv ICC+Hq+XWEUt0cMfSIdCAw0Ltz5Af3q/DLOpQChW1ZizwpvjP4a4+vdw/8s8lixnE0Yt 96KnuqvKMg3PWs37xw4dkb88V/yQoPrxnaQO+IOkWi6g2924oezKiE+WMqHRc8ogGVxn ECVks26tUdSvZHwbs03gK6yR87Yw5kfkVTpZrA4jd5TBwyTWAHS8ScOq9m3HLdU+3zsq m/KA== X-Gm-Message-State: AJcUukegzZbQpNuEYn4K6DsbgX8Wc20CSrw0Mi/EjgefvjDt6l6MWgJ7 8VAPwJfFtEzv2hVi7Sv50oab3te/daw= X-Google-Smtp-Source: ALg8bN7gGFMAqty6YrJv78JEf8zAYk4YIUOSvnz8euWo1p8JXq9biseLO5Ul9/0oskWcuH3gX7Z2fg== X-Received: by 2002:a65:5bc4:: with SMTP id o4mr19550125pgr.426.1547847096927; Fri, 18 Jan 2019 13:31:36 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.34 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:36 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:37 +1100 Message-Id: <20190118213122.22865-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 04/49] linux-user: Share more code for open and openat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The do_openat helper can have all of the code that is not directly related to the argument ordering of these two syscalls. Signed-off-by: Richard Henderson --- linux-user/syscall-file.inc.c | 69 ++++++++++++++++------------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index ca777da753..ffa70bbea8 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -221,8 +221,8 @@ static int open_net_route(void *cpu_env, int fd) } #endif -static int do_openat(void *cpu_env, int dirfd, const char *pathname, - int flags, mode_t mode) +static abi_long do_openat(void *cpu_env, int dirfd, abi_ulong target_path, + int target_flags, mode_t mode) { struct fake_open { const char *filename; @@ -241,9 +241,20 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, { NULL, NULL, NULL } }; + char *pathname = lock_user_string(target_path); + int flags = target_to_host_bitmask(target_flags, fcntl_flags_tbl); + abi_long ret; + + if (!pathname) { + return -TARGET_EFAULT; + } + if (is_proc_myself(pathname, "exe")) { - int execfd = qemu_getauxval(AT_EXECFD); - return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); + ret = qemu_getauxval(AT_EXECFD); + if (ret == 0) { + ret = get_errno(safe_openat(dirfd, exec_path, flags, mode)); + } + goto done; } for (fake_open = fakes; fake_open->filename; fake_open++) { @@ -255,7 +266,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, if (fake_open->filename) { const char *tmpdir; char filename[PATH_MAX]; - int fd, r; + int fd; /* create temporary file to map stat to */ tmpdir = getenv("TMPDIR"); @@ -265,55 +276,37 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir); fd = mkstemp(filename); if (fd < 0) { - return fd; + ret = -TARGET_ENOENT; + goto done; } unlink(filename); - r = fake_open->fill(cpu_env, fd); - if (r) { - int e = errno; + ret = fake_open->fill(cpu_env, fd); + if (ret) { + ret = get_errno(ret); close(fd); - errno = e; - return r; + goto done; } lseek(fd, 0, SEEK_SET); - - return fd; + ret = fd; + goto done; } - return safe_openat(dirfd, path(pathname), flags, mode); + ret = get_errno(safe_openat(dirfd, path(pathname), flags, mode)); + done: + fd_trans_unregister(ret); + unlock_user(pathname, target_path, 0); + return ret; } #ifdef TARGET_NR_open SYSCALL_IMPL(open) { - char *p = lock_user_string(arg1); - abi_long ret; - - if (!p) { - return -TARGET_EFAULT; - } - ret = get_errno(do_openat(cpu_env, AT_FDCWD, p, - target_to_host_bitmask(arg2, fcntl_flags_tbl), - arg3)); - fd_trans_unregister(ret); - unlock_user(p, arg1, 0); - return ret; + return do_openat(cpu_env, AT_FDCWD, arg1, arg2, arg3); } #endif SYSCALL_IMPL(openat) { - char *p = lock_user_string(arg2); - abi_long ret; - - if (!p) { - return -TARGET_EFAULT; - } - ret = get_errno(do_openat(cpu_env, arg1, p, - target_to_host_bitmask(arg3, fcntl_flags_tbl), - arg4)); - fd_trans_unregister(ret); - unlock_user(p, arg2, 0); - return ret; + return do_openat(cpu_env, arg1, arg2, arg3, arg4); } From patchwork Fri Jan 18 21:30:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027749 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="dtesyX1v"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDgR36kSz9s9G for ; Sat, 19 Jan 2019 08:32:34 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47389 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkc-0004im-EH for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:32:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55701) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbju-0004hX-Bo for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjt-0003xB-ET for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:46 -0500 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]:39395) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjt-0003ow-5t for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:45 -0500 Received: by mail-pf1-x442.google.com with SMTP id r136so7200758pfc.6 for ; Fri, 18 Jan 2019 13:31:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uYCCSjdXn0Q17nLwgrskP9sJiH9L/F6XImgNprliAmk=; b=dtesyX1vmoJi+pbJBljf39RXZ+3CqrqCR3ti2Q9jWYTKSjNmkCe03koIIyUd5iPvtd TAmiAwW5rMoXTffPMkUih2mBmcqKqK45CHV3x+NgJe1umyoetzvhaT5XeUgjpDiNnmxU fv4N/lgRKe6dW2xyKkk68EHIGS+gdMo4hdP2w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uYCCSjdXn0Q17nLwgrskP9sJiH9L/F6XImgNprliAmk=; b=BYk6+QKpfmovysETUWWYnJNA+quIUsoFSy4xOcvUU3emcOV8TaQwD+e+hAKYFC0TwG SX7F3Prt+Y3Q/Z4ZJRVk7+b9f7W3hyrD604s4Xuhn2LJT++nIFW/Vm3y4qyrPh1chtcX +M9rn62hP4kuHSQjaXpEG/Bsf4iclNrxRlKJfONqzRyMO5rqAO3b/KTc15D1YWWKfYoy Ry615m78TmMhpZylA7iuYAvcnE5XSHEdXpv5TQQoPuj05MGqJ1SQr2D4v4lBepl4+5z4 g1WVv/owrNtDYjQoO5V01icFYAcy4QI93/VggfcMD5bx1rOJowifCCAOHnps00mjPNNG qqTw== X-Gm-Message-State: AJcUukcMfHsvnRTCdX+U2P2GZTtuhziLudTmlEC7vmFfIOW0kzILYCCZ OQS+fadYowCfIep046djxL4Wu1Z75Tw= X-Google-Smtp-Source: ALg8bN5tN286sfXs/cNoN1XeVVbSCkZpMjk4U+iMedan3otU0Z4edIFfdfitqODJuOOtm6LOQjZxKg== X-Received: by 2002:a62:2044:: with SMTP id g65mr20839729pfg.127.1547847099238; Fri, 18 Jan 2019 13:31:39 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:38 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:38 +1100 Message-Id: <20190118213122.22865-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::442 Subject: [Qemu-devel] [PATCH v6 05/49] linux-user: Tidy do_openat loop over fakes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Cleaner to use ARRAY_SIZE to loop over elements instead of using a sentinel within the data structure. Signed-off-by: Richard Henderson --- linux-user/syscall-file.inc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index ffa70bbea8..f202a4c8f4 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -229,7 +229,6 @@ static abi_long do_openat(void *cpu_env, int dirfd, abi_ulong target_path, int (*fill)(void *cpu_env, int fd); int (*cmp)(const char *s1, const char *s2); }; - const struct fake_open *fake_open; static const struct fake_open fakes[] = { { "maps", open_self_maps, is_proc_myself }, { "stat", open_self_stat, is_proc_myself }, @@ -238,12 +237,12 @@ static abi_long do_openat(void *cpu_env, int dirfd, abi_ulong target_path, #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) { "/proc/net/route", open_net_route, is_proc }, #endif - { NULL, NULL, NULL } }; char *pathname = lock_user_string(target_path); int flags = target_to_host_bitmask(target_flags, fcntl_flags_tbl); abi_long ret; + size_t i; if (!pathname) { return -TARGET_EFAULT; @@ -257,17 +256,16 @@ static abi_long do_openat(void *cpu_env, int dirfd, abi_ulong target_path, goto done; } - for (fake_open = fakes; fake_open->filename; fake_open++) { - if (fake_open->cmp(pathname, fake_open->filename)) { - break; - } - } - - if (fake_open->filename) { + for (i = 0; i < ARRAY_SIZE(fakes); ++i) { + const struct fake_open *fake_open = &fakes[i]; const char *tmpdir; char filename[PATH_MAX]; int fd; + if (!fake_open->cmp(pathname, fake_open->filename)) { + continue; + } + /* create temporary file to map stat to */ tmpdir = getenv("TMPDIR"); if (!tmpdir) { From patchwork Fri Jan 18 21:30:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027761 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Zu2qZHMX"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDnH3HF7z9sDL for ; Sat, 19 Jan 2019 08:37:38 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47464 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbpX-0000Yg-3N for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:37:35 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55735) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbjv-0004i0-70 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjt-0003xT-HD for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:47 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:33666) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjt-0003ss-9V for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:45 -0500 Received: by mail-pg1-x544.google.com with SMTP id z11so6660047pgu.0 for ; Fri, 18 Jan 2019 13:31:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0FyNzZUX6dDuZ4RmFXTfDNUyXGiazdUeQzMHZNrjzJM=; b=Zu2qZHMX9pG+XkGDq4AFNgb87YQP3l9FPEj+L5//1ilncCwa5sIVk3+FuwhjO5461M tJGiFVcwayJGPNq2fgJOec8EOK5L2PrLtZi9R3ybuq/hCPk9GuWPoT+UAjeMCaMG2/p5 ZbEHweTSNrvmvAJHV2S9GnyHgnBoz8kPe9vQY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0FyNzZUX6dDuZ4RmFXTfDNUyXGiazdUeQzMHZNrjzJM=; b=AjLWyGj5adOW/84fNMugAX3/tUembRXEwp+2LJCBSHGTWhgWjvrWfWwHbKmKO3YPos wCiUD/wK/eMsoMnxerHftlH3XIKjZv9NwxVSd+3tkyMlUxNKmuQfEPsdCkfI0NHcGJ1/ wqxB4tFgPpdJrBLduMBB57hq/r/y2qYkj6ApCQsuaFDt99rr8mg3b5bLxabHNlWdTdGW 6/rUxLCGHxA4v6ktZOI9fYmWPKCVHD05uLsOWogt5arPfJ37Nwd9gniTClo1JxRFIahr z+aDY2WiUivMy6Nuqm3SiLfxiQ9SEiQUh1sG445OA9VhCvWIx1+SrUh7sJa50GIYqGPG F7AQ== X-Gm-Message-State: AJcUukeWpiyE9/LDlF4EQlZZWdJp2Pz5nF/dKDYG7AzviOTuaHpdGIqx O6rYdg3IiUci5LkYdrYrlSA/OUMPndQ= X-Google-Smtp-Source: ALg8bN4h3PfrEZEaKRVYzIKBk/nbY9Z2djvzkkkwmUtjwcTN+VW6t8fOhac0AXKvP2UG+xGLVXw3wA== X-Received: by 2002:a62:1709:: with SMTP id 9mr20735392pfx.249.1547847101607; Fri, 18 Jan 2019 13:31:41 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:40 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:39 +1100 Message-Id: <20190118213122.22865-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::544 Subject: [Qemu-devel] [PATCH v6 06/49] linux-user: Split out readlink, readlinkat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Split out a shared implementation for both of these; unify the best parts of /proc/self/exe checking. Remove the temporary forward declaration for is_proc_self. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 6 ++++ linux-user/strace.c | 29 ------------------ linux-user/syscall-file.inc.c | 45 ++++++++++++++++++++++++++++ linux-user/syscall.c | 55 ----------------------------------- linux-user/strace.list | 6 ---- 5 files changed, 51 insertions(+), 90 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 1f3a9c47ab..d1a6c6fa3c 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -20,3 +20,9 @@ SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); +#ifdef TARGET_NR_readlink +SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); +#endif +#ifdef TARGET_NR_readlinkat +SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC); +#endif diff --git a/linux-user/strace.c b/linux-user/strace.c index 1e4f6c9b53..4faeb8c031 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -2244,35 +2244,6 @@ print_fstatat64(const struct syscallname *name, #define print_newfstatat print_fstatat64 #endif -#ifdef TARGET_NR_readlink -static void -print_readlink(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_pointer(arg1, 0); - print_raw_param("%u", arg2, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_readlinkat -static void -print_readlinkat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_pointer(arg2, 0); - print_raw_param("%u", arg3, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_rename static void print_rename(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index f202a4c8f4..841795f8aa 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -308,3 +308,48 @@ SYSCALL_IMPL(openat) { return do_openat(cpu_env, arg1, arg2, arg3, arg4); } + +static abi_long do_readlinkat(int dirfd, abi_ulong target_path, + abi_ulong target_buf, abi_ulong bufsiz) +{ + char *p = lock_user_string(target_path); + void *buf = lock_user(VERIFY_WRITE, target_buf, bufsiz, 0); + abi_long ret; + + if (!p || !buf) { + ret = -TARGET_EFAULT; + } else if (!bufsiz) { + /* Short circuit this for the magic exe check. */ + ret = -TARGET_EINVAL; + } else if (is_proc_myself((const char *)p, "exe")) { + char real[PATH_MAX]; + char *temp = realpath(exec_path, real); + + if (temp == NULL) { + ret = -host_to_target_errno(errno); + } else { + ret = MIN(strlen(real), bufsiz); + /* We cannot NUL terminate the string. */ + memcpy(buf, real, ret); + } + } else { + ret = get_errno(readlinkat(dirfd, path(p), buf, bufsiz)); + } + unlock_user(buf, target_buf, ret); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_readlink +SYSCALL_IMPL(readlink) +{ + return do_readlinkat(AT_FDCWD, arg1, arg2, arg3); +} +#endif + +#ifdef TARGET_NR_readlinkat +SYSCALL_IMPL(readlinkat) +{ + return do_readlinkat(arg1, arg2, arg3, arg4); +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 32d1a285eb..035f17c0d9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6577,8 +6577,6 @@ int host_to_target_waitstatus(int status) return status; } -static int is_proc_myself(const char *filename, const char *entry); - #define TIMER_MAGIC 0x0caf0000 #define TIMER_MAGIC_MASK 0xffff0000 @@ -8052,59 +8050,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } return ret; #endif -#ifdef TARGET_NR_readlink - case TARGET_NR_readlink: - { - void *p2; - p = lock_user_string(arg1); - p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); - if (!p || !p2) { - ret = -TARGET_EFAULT; - } else if (!arg3) { - /* Short circuit this for the magic exe check. */ - ret = -TARGET_EINVAL; - } else if (is_proc_myself((const char *)p, "exe")) { - char real[PATH_MAX], *temp; - temp = realpath(exec_path, real); - /* Return value is # of bytes that we wrote to the buffer. */ - if (temp == NULL) { - ret = get_errno(-1); - } else { - /* Don't worry about sign mismatch as earlier mapping - * logic would have thrown a bad address error. */ - ret = MIN(strlen(real), arg3); - /* We cannot NUL terminate the string. */ - memcpy(p2, real, ret); - } - } else { - ret = get_errno(readlink(path(p), p2, arg3)); - } - unlock_user(p2, arg2, ret); - unlock_user(p, arg1, 0); - } - return ret; -#endif -#if defined(TARGET_NR_readlinkat) - case TARGET_NR_readlinkat: - { - void *p2; - p = lock_user_string(arg2); - p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); - if (!p || !p2) { - ret = -TARGET_EFAULT; - } else if (is_proc_myself((const char *)p, "exe")) { - char real[PATH_MAX], *temp; - temp = realpath(exec_path, real); - ret = temp == NULL ? get_errno(-1) : strlen(real) ; - snprintf((char *)p2, arg4, "%s", real); - } else { - ret = get_errno(readlinkat(arg1, path(p), p2, arg4)); - } - unlock_user(p2, arg3, ret); - unlock_user(p, arg2, 0); - } - return ret; -#endif #ifdef TARGET_NR_swapon case TARGET_NR_swapon: if (!(p = lock_user_string(arg1))) diff --git a/linux-user/strace.list b/linux-user/strace.list index b2d3e99df7..2f466e5699 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1079,12 +1079,6 @@ #ifdef TARGET_NR_readdir { TARGET_NR_readdir, "readdir" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_readlink -{ TARGET_NR_readlink, "readlink" , NULL, print_readlink, NULL }, -#endif -#ifdef TARGET_NR_readlinkat -{ TARGET_NR_readlinkat, "readlinkat" , NULL, print_readlinkat, NULL }, -#endif #ifdef TARGET_NR_readv { TARGET_NR_readv, "readv" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027758 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="P0p99Kgd"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDl76hVdz9s9G for ; Sat, 19 Jan 2019 08:35:47 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47409 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbnl-0007VL-UV for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:35:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55720) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbju-0004hl-PD for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjt-0003xw-Jl for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:46 -0500 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]:37336) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjt-0003vo-CZ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:45 -0500 Received: by mail-pg1-x543.google.com with SMTP id c25so6648959pgb.4 for ; Fri, 18 Jan 2019 13:31:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=My0NLfLI/aLkwxImF9gfK+QIhgs0UBxlMpBaBuGf6j8=; b=P0p99KgdyhxLd1ivohFkQWFpI7hWSwY6WE4Jmsxg2lj69CPQ/ecYYoEWjFBE03h4UA aebmha5UVzP3CGTCpACZ0YmrbBacoiYBuCk/VUk/dlez7pEUpGS3PtJA3fwigdmcdmwT 2BnBnIgDT8hJrX2B0t6zcjudECk26pNpmdApM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=My0NLfLI/aLkwxImF9gfK+QIhgs0UBxlMpBaBuGf6j8=; b=fBhJ5Q8VrD1RfKkX36E6+dHvHgBOCJCcLni4zJDUqdP3syQBijFQiQWgE46iIISFkh yi0ruLm/Hz9dpsfpHk+NdlLb86w7kvqrZAO+eCO+CJy60zhurs53SJEfdb+aGtSLoa8e 7H5J8YLSMoqNWMoxnpg4cfUpNPtY035A/ZXeQTnXliSumwiUA/0Dyua8jN/orzqkPXir eoH5+9yORVf5yWk8l2BfuHIUkFhZ/OeeJgA1ZJ3BYAo9TGxYvdboDz1p8f8zKR+ZfVtq xEjOOa1sOI8RjLSFHbM+nCsgY2LoDll1zYWDIw79nBCntwRTx3fT6cWNgBmXzK5uO3R5 6MOw== X-Gm-Message-State: AJcUukd39+x1cN1Beac4MI2SGcabDBjDcGOtOjvzkeG9XzdwNc/iZsZk cL5iUAADtDrXCihS3DNJGD5SRlEXvOM= X-Google-Smtp-Source: ALg8bN4P3IQArRDb8cSuYwh1HENpd7oXacIM35WQCArLPmRuuJr66Y62U7Zfdq7ubbPBvlGDD6rkWA== X-Received: by 2002:a63:8149:: with SMTP id t70mr19677548pgd.172.1547847103794; Fri, 18 Jan 2019 13:31:43 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.41 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:43 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:40 +1100 Message-Id: <20190118213122.22865-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::543 Subject: [Qemu-devel] [PATCH v6 07/49] linux-user: Split out close X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall-file.inc.c | 8 ++++++++ linux-user/syscall.c | 4 ---- linux-user/strace.list | 3 --- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index d1a6c6fa3c..797426ae6f 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -16,6 +16,7 @@ * along with this program; if not, see . */ +SYSCALL_DEF(close, ARG_DEC); #ifdef TARGET_NR_open SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 841795f8aa..feb83c4e87 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -16,6 +16,14 @@ * along with this program; if not, see . */ +SYSCALL_IMPL(close) +{ + int fd = arg1; + + fd_trans_unregister(fd); + return get_errno(close(fd)); +} + /* * Helpers for do_openat, manipulating /proc/self/foo. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 035f17c0d9..f230fe161e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6771,10 +6771,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, fd_trans_unregister(ret); return ret; #endif - case TARGET_NR_close: - fd_trans_unregister(arg1); - return get_errno(close(arg1)); - case TARGET_NR_brk: return do_brk(arg1); #ifdef TARGET_NR_fork diff --git a/linux-user/strace.list b/linux-user/strace.list index 2f466e5699..71a18123bf 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -97,9 +97,6 @@ #ifdef TARGET_NR_clone { TARGET_NR_clone, "clone" , NULL, print_clone, NULL }, #endif -#ifdef TARGET_NR_close -{ TARGET_NR_close, "close" , "%s(%d)", NULL, NULL }, -#endif #ifdef TARGET_NR_connect { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027765 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="dvusg2G/"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDrj0jJhz9s9G for ; Sat, 19 Jan 2019 08:40:37 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47486 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbsR-0003AU-09 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:40:35 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55785) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbjx-0004jZ-94 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjv-00041s-KK for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:49 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:42254) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjv-00040B-Bw for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:47 -0500 Received: by mail-pf1-x441.google.com with SMTP id 64so7190254pfr.9 for ; Fri, 18 Jan 2019 13:31:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0lX6Kpl2HawVr6cLh0Iq6aWEA9i6Vz7GS35r+BCsPqA=; b=dvusg2G/XZcvWCeD7Jqt91BywW5n9mSymk7a59NDxEz9S7dh/rvveC/7psHtZsx2BU otbW7wzkj85UhuIjhCSS9OQ99AxXvnZuVl3hR6NSe+/qUIfFwndrc/b6l9AgHI6Sfwe0 gRQQ6KMd5Tbx1meCbE7g8x30sdqlh8s9AvEC0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0lX6Kpl2HawVr6cLh0Iq6aWEA9i6Vz7GS35r+BCsPqA=; b=lcEez8qjSIRnuv4xY3L1w5/B7EvfxMkaYyBaJqXASQ46zWFWmRNd8CVFLBIYWR4/tV VHkZs9DUI5vXoBiw7vUUVFqOriMd8AKNTWRhjsMP4Wj/EHq80fQ3VzJlIkZmT+6oO29G 4cRxsZe5F0rZb4UzZZ3GFNvHl4P5bt6bVGzBlAmPUM1UU+qAaC8igTSfBraConfqoV8m BllUnNbLqczGXeC0iwbZw5f5FMGVyQkRdSbggUe/HdtBiG7p+n5giO0oOQ+2dkml/S3I WVLhSHNifLa9QgrRr6C4Gw+xTnvwdtjHZ9Ws9FnI0PaC09twE+4b3McIuNUAN7DP1Ii1 QWgQ== X-Gm-Message-State: AJcUukfnFUvV3C5q8orHsgAz3wcoWyQzJiNDqck6k61mhDRBLeSU0h4a 7lEx6rGAkcMdlSozx0ObPuorM7pTi2c= X-Google-Smtp-Source: ALg8bN7C5bh55J3zKN6wZcS7ZHOmlvG1yeMXsxGinl1LxbFE6zMwLjIBgEG8/ljakCQ/2bw1aDiOjg== X-Received: by 2002:a65:50c1:: with SMTP id s1mr18915296pgp.350.1547847105984; Fri, 18 Jan 2019 13:31:45 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:45 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:41 +1100 Message-Id: <20190118213122.22865-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 08/49] linux-user: Split out read, write X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 2 ++ linux-user/syscall-file.inc.c | 58 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 34 -------------------- linux-user/strace.list | 6 ---- 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 797426ae6f..b031de1375 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -21,9 +21,11 @@ SYSCALL_DEF(close, ARG_DEC); SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); +SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC); #ifdef TARGET_NR_readlink SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); #endif #ifdef TARGET_NR_readlinkat SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC); #endif +SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC); diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index feb83c4e87..9c8025b252 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -317,6 +317,32 @@ SYSCALL_IMPL(openat) return do_openat(cpu_env, arg1, arg2, arg3, arg4); } +SYSCALL_IMPL(read) +{ + int fd = arg1; + abi_ulong target_p = arg2; + abi_ulong size = arg3; + void *p; + abi_long ret; + + if (size == 0) { + return 0; + } + p = lock_user(VERIFY_WRITE, target_p, size, 0); + if (p == NULL) { + return -TARGET_EFAULT; + } + ret = get_errno(safe_read(fd, p, size)); + if (!is_error(ret)) { + TargetFdDataFunc trans = fd_trans_host_to_target_data(fd); + if (trans) { + ret = trans(p, ret); + } + } + unlock_user(p, target_p, ret); + return ret; +} + static abi_long do_readlinkat(int dirfd, abi_ulong target_path, abi_ulong target_buf, abi_ulong bufsiz) { @@ -361,3 +387,35 @@ SYSCALL_IMPL(readlinkat) return do_readlinkat(arg1, arg2, arg3, arg4); } #endif + +SYSCALL_IMPL(write) +{ + int fd = arg1; + abi_ulong target_p = arg2; + abi_ulong size = arg3; + TargetFdDataFunc trans; + abi_long ret; + void *p; + + if (target_p == 0 && size == 0) { + return get_errno(safe_write(fd, 0, 0)); + } + p = lock_user(VERIFY_READ, target_p, size, 1); + if (p == NULL) { + return -TARGET_EFAULT; + } + trans = fd_trans_target_to_host_data(fd); + if (trans) { + void *copy = g_malloc(size); + memcpy(copy, p, size); + ret = trans(copy, size); + if (ret >= 0) { + ret = get_errno(safe_write(fd, copy, ret)); + } + g_free(copy); + } else { + ret = get_errno(safe_write(fd, p, size)); + } + unlock_user(p, target_p, 0); + return ret; +} diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f230fe161e..d4d5c25803 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6726,40 +6726,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, preexit_cleanup(cpu_env, arg1); _exit(arg1); return 0; /* avoid warning */ - case TARGET_NR_read: - if (arg3 == 0) { - return 0; - } else { - if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) - return -TARGET_EFAULT; - ret = get_errno(safe_read(arg1, p, arg3)); - if (ret >= 0 && - fd_trans_host_to_target_data(arg1)) { - ret = fd_trans_host_to_target_data(arg1)(p, ret); - } - unlock_user(p, arg2, ret); - } - return ret; - case TARGET_NR_write: - if (arg2 == 0 && arg3 == 0) { - return get_errno(safe_write(arg1, 0, 0)); - } - if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) - return -TARGET_EFAULT; - if (fd_trans_target_to_host_data(arg1)) { - void *copy = g_malloc(arg3); - memcpy(copy, p, arg3); - ret = fd_trans_target_to_host_data(arg1)(copy, arg3); - if (ret >= 0) { - ret = get_errno(safe_write(arg1, copy, ret)); - } - g_free(copy); - } else { - ret = get_errno(safe_write(arg1, p, arg3)); - } - unlock_user(p, arg2, 0); - return ret; - #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) case TARGET_NR_name_to_handle_at: ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5); diff --git a/linux-user/strace.list b/linux-user/strace.list index 71a18123bf..f3a1b0fe31 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1067,9 +1067,6 @@ #ifdef TARGET_NR_quotactl { TARGET_NR_quotactl, "quotactl" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_read -{ TARGET_NR_read, "read" , "%s(%d,%#x,%d)", NULL, NULL }, -#endif #ifdef TARGET_NR_readahead { TARGET_NR_readahead, "readahead" , NULL, NULL, NULL }, #endif @@ -1611,9 +1608,6 @@ #ifdef TARGET_NR_waitpid { TARGET_NR_waitpid, "waitpid" , "%s(%d,%p,%#x)", NULL, NULL }, #endif -#ifdef TARGET_NR_write -{ TARGET_NR_write, "write" , "%s(%d,%#x,%d)", NULL, NULL }, -#endif #ifdef TARGET_NR_writev { TARGET_NR_writev, "writev" , "%s(%d,%p,%#x)", NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027752 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="TCvl3DHY"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDgZ6yWyz9sDL for ; Sat, 19 Jan 2019 08:32:42 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47395 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkm-0004p9-QB for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:32:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbjz-0004mD-Ov for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbjy-00047f-VL for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:51 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:33665) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjy-000452-Q1 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:50 -0500 Received: by mail-pg1-x542.google.com with SMTP id z11so6660161pgu.0 for ; Fri, 18 Jan 2019 13:31:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ts3pCHDYdeSy51fKGOSak6uBOSfQZ8HGkYjqSiv6+OE=; b=TCvl3DHYAdKauStK3EB5vmCFVfNDC8xGxJWmfiC2UkjtlmHXKgQAFehUlaK0438lox gdhBdb+qAxibXAXR6/4jEWDsMygxR1zSsGfdgMg4mx0ezZ9jBpxOFVPeBqs+cPEl/S80 FNucGUFOeWCrjR1gYWkIpU7AKktQmhTsHEDdA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Ts3pCHDYdeSy51fKGOSak6uBOSfQZ8HGkYjqSiv6+OE=; b=eOdJlSL5pCmkxU7w2ijypyI31SnIKXOAO+9Va3Qw4nUavdv0RnqmoIFJBcBR6LL/MD yOL/Y5PcakKkrfqqa+b1fhMmWIYagYIy1DhsydlF0fZV4Br09CRQFjBQFgzcYbmYrERs uHKcLWd8AkmBsXqX7lV/krud4bsTk4DjzJESDOibIZFahFOcGA12SYDwc8wU+cwCDXGn qu4Vzo0jtLXqWUoE3rLL5/qtZfBWt00wJTSQN6Q0VFdHNCYZ30sRp/MTx8miF6pT1q6B 6fBZQcIhrNpLX79SIyQiAfErDsOPjABh8bvazAF37usK3QGJbANBkNDaiZPjcceKtImx niZw== X-Gm-Message-State: AJcUukdFyztukpl57c7j1ipHxzTvmEDbpAb2XEqzZKqGZOf27dI7cxJe FdDr2SFRzwfCxhfZ3Nb1OgymI2CgQkI= X-Google-Smtp-Source: ALg8bN6sscDRZBWW2EO16wXLlDNymkuHTs0lXCQsEgvdRnLSRFralRjFs7Us0w8Fi97lVQbBJ6fdLg== X-Received: by 2002:a63:2109:: with SMTP id h9mr19160206pgh.277.1547847108443; Fri, 18 Jan 2019 13:31:48 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:47 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:42 +1100 Message-Id: <20190118213122.22865-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::542 Subject: [Qemu-devel] [PATCH v6 09/49] linux-user: Reduce regpairs_aligned & target_offset64 ifdefs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall.c | 54 ++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d4d5c25803..c236a80437 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -474,37 +474,38 @@ static inline int next_free_host_timer(void) } #endif -/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */ +/* + * Returns true if syscall NUM expects 64bit types aligned even + * on pairs of registers. + */ +static inline bool regpairs_aligned(void *cpu_env, int num) +{ #ifdef TARGET_ARM -static inline int regpairs_aligned(void *cpu_env, int num) -{ - return ((((CPUARMState *)cpu_env)->eabi) == 1) ; -} -#elif defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32) -static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } + return ((CPUARMState *)cpu_env)->eabi; +#elif defined(TARGET_MIPS) && TARGET_ABI_BITS == 32 + return true; #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) -/* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs - * of registers which translates to the same as ARM/MIPS, because we start with - * r3 as arg1 */ -static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } + /* + * SysV AVI for PPC32 expects 64bit parameters to be passed on + * odd/even pairs of registers which translates to the same as + * we start with r3 as arg1. + */ + return true; #elif defined(TARGET_SH4) -/* SH4 doesn't align register pairs, except for p{read,write}64 */ -static inline int regpairs_aligned(void *cpu_env, int num) -{ + /* SH4 doesn't align register pairs, except for p{read,write}64. */ switch (num) { case TARGET_NR_pread64: case TARGET_NR_pwrite64: - return 1; - + return true; default: - return 0; + return false; } -} #elif defined(TARGET_XTENSA) -static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } + return true; #else -static inline int regpairs_aligned(void *cpu_env, int num) { return 0; } + return false; #endif +} #define ERRNO_TABLE_SIZE 1200 @@ -6105,21 +6106,16 @@ void syscall_init(void) } } -#if TARGET_ABI_BITS == 32 -static inline uint64_t target_offset64(uint32_t word0, uint32_t word1) +static inline uint64_t target_offset64(abi_ulong word0, abi_ulong word1) { -#ifdef TARGET_WORDS_BIGENDIAN +#if TARGET_ABI_BITS == 64 + return word0; +#elif defined(TARGET_WORDS_BIGENDIAN) return ((uint64_t)word0 << 32) | word1; #else return ((uint64_t)word1 << 32) | word0; #endif } -#else /* TARGET_ABI_BITS == 32 */ -static inline uint64_t target_offset64(uint64_t word0, uint64_t word1) -{ - return word0; -} -#endif /* TARGET_ABI_BITS != 32 */ #ifdef TARGET_NR_truncate64 static inline abi_long target_truncate64(void *cpu_env, const char *arg1, From patchwork Fri Jan 18 21:30:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027762 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Q4MrDzxa"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDpf6jSzz9sDL for ; Sat, 19 Jan 2019 08:38:50 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47468 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbqi-0001WG-Qm for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:38:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55835) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbk0-0004nP-Vb for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbk0-0004Aa-2w for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:52 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:47054) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbjz-00049F-Su for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:52 -0500 Received: by mail-pl1-x644.google.com with SMTP id t13so6870017ply.13 for ; Fri, 18 Jan 2019 13:31:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WbkFzNdw4ZUaUkoqoS/QfvrwzkBXiBnsY3U3DGJDqiI=; b=Q4MrDzxaswTU1rPbVVZPCWexH6i0DJQQTVv/PkJkG8/y0XKnPJCLEVHJKeVosDOOtA 1FsAvL6UOZioRjmuSu4fYtT5geK9pdhaFJJLA2efBP4+qEFAEA+DsdC1dtJUhhGS2B8t iqb/qbxXvoR/tk4FFlUgfPPi32Do5fc+S7xo8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WbkFzNdw4ZUaUkoqoS/QfvrwzkBXiBnsY3U3DGJDqiI=; b=S2aU0tTeJa056evNBUvjXqHATKNmnuCqLA2o6uOIb3ogVoll5FVj4ypPwTXmTKs8GW 1l0aS8bAO8sXeyKUFfTqmFI0eDlQ2TZuAPtSgggntqVdysSsXh3AqJ1z8tCZEIDRH0+m Ax3TC7jqlh3zMnXIr+ZJJYctU5++rhrQLFqlX/N/LC3aGqCxgt+WZfTDTrCcQjQ4UhMv LpiAGs0dYEwmxznIZWVe2hAmcNicg6/x0sMCi6Uirv2iUBIggfeDzPwx3C2jEMYFUwlq E09TGTclUJVwfYPgtCdCOHaWrLHFkJbLSi0Jq2oakPXbDKMcV+5P8T25caMk9RgeUAnr pefQ== X-Gm-Message-State: AJcUukdBt/6sZa4jJ7DKHgRXRyrsqjuja4qHjChK8LziAXz2So4KIqzF QDi9xB7dri3Ffw0ehPqAWuEZLQo0MKA= X-Google-Smtp-Source: ALg8bN65c33L739w7M0G3mfvN0TLF0/UpzhyZmnp/BqNcv8qBFTCCblRTMZqRRfFIP4X0a7Kc1WdVA== X-Received: by 2002:a17:902:c05:: with SMTP id 5mr20826248pls.155.1547847110624; Fri, 18 Jan 2019 13:31:50 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:50 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:43 +1100 Message-Id: <20190118213122.22865-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 10/49] linux-user: Split out readv, writev X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 2 ++ linux-user/syscall-file.inc.c | 34 ++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 22 ---------------------- linux-user/strace.list | 6 ------ 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index b031de1375..130ba7e344 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -28,4 +28,6 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); #ifdef TARGET_NR_readlinkat SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC); #endif +SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC); SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC); +SYSCALL_DEF(writev, ARG_DEC, ARG_PTR, ARG_DEC); diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 9c8025b252..9bd21ac5cd 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -343,6 +343,23 @@ SYSCALL_IMPL(read) return ret; } +SYSCALL_IMPL(readv) +{ + int fd = arg1; + abi_ulong target_vec = arg2; + int count = arg3; + struct iovec *vec = lock_iovec(VERIFY_WRITE, target_vec, count, 0); + abi_long ret; + + if (vec != NULL) { + ret = get_errno(safe_readv(fd, vec, count)); + unlock_iovec(vec, target_vec, count, 1); + } else { + ret = -host_to_target_errno(errno); + } + return ret; +} + static abi_long do_readlinkat(int dirfd, abi_ulong target_path, abi_ulong target_buf, abi_ulong bufsiz) { @@ -419,3 +436,20 @@ SYSCALL_IMPL(write) unlock_user(p, target_p, 0); return ret; } + +SYSCALL_IMPL(writev) +{ + int fd = arg1; + abi_ulong target_vec = arg2; + int count = arg3; + struct iovec *vec = lock_iovec(VERIFY_READ, target_vec, count, 1); + abi_long ret; + + if (vec != NULL) { + ret = get_errno(safe_writev(fd, vec, count)); + unlock_iovec(vec, target_vec, count, 0); + } else { + ret = -host_to_target_errno(errno); + } + return ret; +} diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c236a80437..df47ee106e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8949,28 +8949,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, /* NOTE: the flock constant seems to be the same for every Linux platform */ return get_errno(safe_flock(arg1, arg2)); - case TARGET_NR_readv: - { - struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); - if (vec != NULL) { - ret = get_errno(safe_readv(arg1, vec, arg3)); - unlock_iovec(vec, arg2, arg3, 1); - } else { - ret = -host_to_target_errno(errno); - } - } - return ret; - case TARGET_NR_writev: - { - struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); - if (vec != NULL) { - ret = get_errno(safe_writev(arg1, vec, arg3)); - unlock_iovec(vec, arg2, arg3, 0); - } else { - ret = -host_to_target_errno(errno); - } - } - return ret; #if defined(TARGET_NR_preadv) case TARGET_NR_preadv: { diff --git a/linux-user/strace.list b/linux-user/strace.list index f3a1b0fe31..e02a854cea 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1073,9 +1073,6 @@ #ifdef TARGET_NR_readdir { TARGET_NR_readdir, "readdir" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_readv -{ TARGET_NR_readv, "readv" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_reboot { TARGET_NR_reboot, "reboot" , NULL, NULL, NULL }, #endif @@ -1608,9 +1605,6 @@ #ifdef TARGET_NR_waitpid { TARGET_NR_waitpid, "waitpid" , "%s(%d,%p,%#x)", NULL, NULL }, #endif -#ifdef TARGET_NR_writev -{ TARGET_NR_writev, "writev" , "%s(%d,%p,%#x)", NULL, NULL }, -#endif #ifdef TARGET_NR_utimensat { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL }, #endif From patchwork Fri Jan 18 21:30:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027779 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="cVjoLfRM"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF4r3GLXz9sDL for ; Sat, 19 Jan 2019 08:51:08 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47667 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc2c-0003Nh-Cj for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:51:06 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55848) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbk3-0004qb-Ix for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbk2-0004EU-JZ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:55 -0500 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]:38216) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbk2-0004Dq-DI for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:54 -0500 Received: by mail-pl1-x641.google.com with SMTP id e5so6883429plb.5 for ; Fri, 18 Jan 2019 13:31:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Aqf9UEWPigqViOeOjucwyE9XXkOX9SJjCTh9tkuco54=; b=cVjoLfRMkXL2xpvb1CTCOb5rPutl1FwnmgaEqXbz7/tGIrDvio4bHXWQ15B75bjCXF 4Oud3GAd2xeej8BKa5SQWh4SN4yUQDRoYtyQa8AyhTUDLXNzs7l7a5ug3zmLP9/rAHaJ RM77UTummptIMFUJUnmVGII9NGTxAdTMnUrrQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Aqf9UEWPigqViOeOjucwyE9XXkOX9SJjCTh9tkuco54=; b=BUziLvop3Ivu+SzH+A6g8MK0Op+nnv74ZZDEbeYuqbuOysMvW4QfS+dfhmf6oMUnfy WgmvQOWdWtns1dkTRGNC1uDsGstYx9xt/ytNWzRZqq8Ng5gkmGPRyItGr6e7zg1KntYK cKv9TO65hww4e4SBeq0UeRaPrT21O3du4OR5Pg5TmFt0jOW5VZrr6eG77j69UbN+1Wqt faL8TGs+vDjTCY2aETMbTqqPlyZkxhHvJi4jriIhFgV5FtvPvHFR4IRbRry3y5Ic9b2Z cQBctBxiZFVFPtB3fK8OYSbjrEBAjRqBYK52zWTzNEUUU+CzvEdh05aSEdobgCdHQDR7 6Hlg== X-Gm-Message-State: AJcUukcTkTxLaaA3Wym6y4B42NLtT4DqcB1iYtRNM5AYdFYBqrbnUR2T eR5LSNuf1CA3nbXb+aZlp1x4E1zqdG4= X-Google-Smtp-Source: ALg8bN7TnMteECP8BH68V7r8H1nvYXumnmIlQK/Toy6kQac+eHlS6HkjV/GXZe+EVXj0mR0ypbgnkQ== X-Received: by 2002:a17:902:14e:: with SMTP id 72mr20873369plb.287.1547847113059; Fri, 18 Jan 2019 13:31:53 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:52 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:44 +1100 Message-Id: <20190118213122.22865-11-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::641 Subject: [Qemu-devel] [PATCH v6 11/49] linux-user: Split out pread64, pwrite64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 6 ++++ linux-user/syscall-file.inc.c | 62 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 36 -------------------- linux-user/strace.list | 6 ---- 4 files changed, 68 insertions(+), 42 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 130ba7e344..027793d5d0 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -21,6 +21,12 @@ SYSCALL_DEF(close, ARG_DEC); SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); +SYSCALL_DEF_FULL(pread64, .impl = impl_pread64, + .args = args_pread64_pwrite64, + .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); +SYSCALL_DEF_FULL(pwrite64, .impl = impl_pwrite64, + .args = args_pread64_pwrite64, + .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC); #ifdef TARGET_NR_readlink SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 9bd21ac5cd..e79cfabf56 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -317,6 +317,68 @@ SYSCALL_IMPL(openat) return do_openat(cpu_env, arg1, arg2, arg3, arg4); } +/* + * Both pread64 and pwrite64 merge args into a 64-bit offset, + * but the input registers and ordering are target specific. + */ +#if TARGET_ABI_BITS == 32 +SYSCALL_ARGS(pread64_pwrite64) +{ + /* We have already assigned out[0-2]. */ + int off = regpairs_aligned(cpu_env, TARGET_NR_pread64); + out[3] = target_offset64(in[3 + off], in[4 + off]); + return def; +} +#else +#define args_pread64_pwrite64 NULL +#endif + +SYSCALL_IMPL(pread64) +{ + int fd = arg1; + abi_ulong target_buf = arg2; + abi_ulong len = arg3; + uint64_t off = arg4; + void *p; + abi_long ret; + + if (target_buf == 0 && len == 0) { + /* Special-case NULL buffer and zero length, which should succeed */ + p = NULL; + } else { + p = lock_user(VERIFY_WRITE, target_buf, len, 0); + if (!p) { + return -TARGET_EFAULT; + } + } + ret = get_errno(pread64(fd, p, len, off)); + unlock_user(p, target_buf, ret); + return ret; +} + +SYSCALL_IMPL(pwrite64) +{ + int fd = arg1; + abi_ulong target_buf = arg2; + abi_ulong len = arg3; + uint64_t off = arg4; + void *p; + abi_long ret; + + if (target_buf == 0 && len == 0) { + /* Special-case NULL buffer and zero length, which should succeed */ + p = 0; + } else { + p = lock_user(VERIFY_READ, target_buf, len, 1); + if (!p) { + return -TARGET_EFAULT; + } + } + ret = get_errno(pwrite64(fd, p, len, off)); + unlock_user(p, target_buf, 0); + return ret; +} + SYSCALL_IMPL(read) { int fd = arg1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index df47ee106e..80806c0150 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9312,42 +9312,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #else #error unreachable #endif -#endif -#ifdef TARGET_NR_pread64 - case TARGET_NR_pread64: - if (regpairs_aligned(cpu_env, num)) { - arg4 = arg5; - arg5 = arg6; - } - if (arg2 == 0 && arg3 == 0) { - /* Special-case NULL buffer and zero length, which should succeed */ - p = 0; - } else { - p = lock_user(VERIFY_WRITE, arg2, arg3, 0); - if (!p) { - return -TARGET_EFAULT; - } - } - ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5))); - unlock_user(p, arg2, ret); - return ret; - case TARGET_NR_pwrite64: - if (regpairs_aligned(cpu_env, num)) { - arg4 = arg5; - arg5 = arg6; - } - if (arg2 == 0 && arg3 == 0) { - /* Special-case NULL buffer and zero length, which should succeed */ - p = 0; - } else { - p = lock_user(VERIFY_READ, arg2, arg3, 1); - if (!p) { - return -TARGET_EFAULT; - } - } - ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5))); - unlock_user(p, arg2, 0); - return ret; #endif case TARGET_NR_getcwd: if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0))) diff --git a/linux-user/strace.list b/linux-user/strace.list index e02a854cea..c7e573669d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1025,9 +1025,6 @@ #ifdef TARGET_NR_prctl { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pread64 -{ TARGET_NR_pread64, "pread64" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_preadv { TARGET_NR_preadv, "preadv" , NULL, NULL, NULL }, #endif @@ -1055,9 +1052,6 @@ #ifdef TARGET_NR_putpmsg { TARGET_NR_putpmsg, "putpmsg" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pwrite64 -{ TARGET_NR_pwrite64, "pwrite64" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_pwritev { TARGET_NR_pwritev, "pwritev" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027760 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="IwgB15aQ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDlN6x43z9s9G for ; Sat, 19 Jan 2019 08:36:00 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47449 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbny-0007jB-Rz for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:35:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55871) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbk6-0004tG-9e for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbk5-0004K3-60 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:58 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:45977) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbk4-0004II-VC for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:57 -0500 Received: by mail-pl1-x642.google.com with SMTP id a14so6865602plm.12 for ; Fri, 18 Jan 2019 13:31:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=I6X/MozJcMBqJ6YJKlH5AoTg3Rm23QUrPNJcn9bFsPY=; b=IwgB15aQo6B0xlOYdrPbcxf8ZkRQhlPzj5kMVbQFJOKMnWVHUf38MwkkyKzi3Pvd8h hHMt2VfWnl9Q9QAhZIF6xhf0meRFPUyx3pwX6wGqCtzNbUUjTn+DuiwboMX2qJ7JOmx8 RR2UvDBwavo6ddvBEkcCP77EZuSsp+WyTqlGY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=I6X/MozJcMBqJ6YJKlH5AoTg3Rm23QUrPNJcn9bFsPY=; b=rzKkJC7WHWKrwvJf7LJ0YQ2oLpADgrK2CP/Tkh68hOMO0NW6aQu5xQIfXl0zwcUaYO PSUBlsCSEidsOpsuFpQ8Fo8CLXuYVho5CajNfkJud1276Igl8m92xtyy/NLuQWBTziuZ 9rvsC6Zncsvqt7WYuPVoA5u7odpBT6/c59JaEWLKfTh4xewgQ+HLYIPbnhSyWzWvb7Po Kww50eL9oWAG6iW6sarDwR/RLGDV/c/2704twXqloRqT2rZhZ8gTfTVYUEpjbhEnA6ni xXgOe9lz+Rbwg6uaqsdr99n0ZOnI+85HzFTc5MTHIpMONUlpm32Wapuho43kwY49zqiC obJA== X-Gm-Message-State: AJcUukcTCfQHINqaB2YNTIBWAumgf3bQFcs1uVqnR+nl5Hz7G+Qrwc2F bStYLmyBtjaDlBdeUiUZqGgJsrkl0ko= X-Google-Smtp-Source: ALg8bN7zF1zILR7pxNx3MNbovelbyO7ApbPv30kyyUt6b4kly99Q0oz5ETKVetvZCp7ttH6xQ3GxzQ== X-Received: by 2002:a17:902:8f97:: with SMTP id z23mr20955607plo.283.1547847115577; Fri, 18 Jan 2019 13:31:55 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:54 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:45 +1100 Message-Id: <20190118213122.22865-12-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH v6 12/49] linux-user: Split out preadv, pwritev X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 6 ++++ linux-user/syscall-file.inc.c | 64 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 49 --------------------------- linux-user/strace.list | 6 ---- 4 files changed, 70 insertions(+), 55 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 027793d5d0..ae89be0e87 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -27,6 +27,12 @@ SYSCALL_DEF_FULL(pread64, .impl = impl_pread64, SYSCALL_DEF_FULL(pwrite64, .impl = impl_pwrite64, .args = args_pread64_pwrite64, .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); +SYSCALL_DEF_FULL(preadv, .impl = impl_preadv, + .args = args_preadv_pwritev, + .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); +SYSCALL_DEF_FULL(pwritev, .impl = impl_pwritev, + .args = args_preadv_pwritev, + .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC); #ifdef TARGET_NR_readlink SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index e79cfabf56..63401684c3 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -379,6 +379,70 @@ SYSCALL_IMPL(pwrite64) return ret; } +/* + * Both preadv and pwritev merge args 4/5 into a 64-bit offset. + * Moreover, the parts are *always* in little-endian order. + */ +#if TARGET_ABI_BITS == 32 +SYSCALL_ARGS(preadv_pwritev) +{ + /* We have already assigned out[0-2]. */ + abi_ulong lo = in[3], hi = in[4]; + out[3] = (((uint64_t)hi << (TARGET_ABI_BITS - 1)) << 1) | lo; + return def; +} +#else +#define args_preadv_pwritev NULL +#endif + +/* Perform the inverse operation for the host. */ +static inline void host_offset64_low_high(unsigned long *l, unsigned long *h, + uint64_t off) +{ + *l = off; + *h = (off >> (HOST_LONG_BITS - 1)) >> 1; +} + +SYSCALL_IMPL(preadv) +{ + int fd = arg1; + abi_ulong target_vec = arg2; + int count = arg3; + uint64_t off = arg4; + struct iovec *vec = lock_iovec(VERIFY_WRITE, target_vec, count, 0); + unsigned long lo, hi; + abi_long ret; + + if (vec == NULL) { + return -TARGET_EFAULT; + } + + host_offset64_low_high(&lo, &hi, off); + ret = get_errno(safe_preadv(fd, vec, count, lo, hi)); + unlock_iovec(vec, target_vec, count, 1); + return ret; +} + +SYSCALL_IMPL(pwritev) +{ + int fd = arg1; + abi_ulong target_vec = arg2; + int count = arg3; + uint64_t off = arg4; + struct iovec *vec = lock_iovec(VERIFY_READ, target_vec, count, 1); + unsigned long lo, hi; + abi_long ret; + + if (vec == NULL) { + return -TARGET_EFAULT; + } + + host_offset64_low_high(&lo, &hi, off); + ret = get_errno(safe_pwritev(fd, vec, count, lo, hi)); + unlock_iovec(vec, target_vec, count, 0); + return ret; +} + SYSCALL_IMPL(read) { int fd = arg1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 80806c0150..9606f15a09 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2403,23 +2403,6 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, return ret; } -/* Convert target low/high pair representing file offset into the host - * low/high pair. This function doesn't handle offsets bigger than 64 bits - * as the kernel doesn't handle them either. - */ -static void target_to_host_low_high(abi_ulong tlow, - abi_ulong thigh, - unsigned long *hlow, - unsigned long *hhigh) -{ - uint64_t off = tlow | - ((unsigned long long)thigh << TARGET_LONG_BITS / 2) << - TARGET_LONG_BITS / 2; - - *hlow = off; - *hhigh = (off >> HOST_LONG_BITS / 2) >> HOST_LONG_BITS / 2; -} - static struct iovec *lock_iovec(int type, abi_ulong target_addr, abi_ulong count, int copy) { @@ -8949,38 +8932,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, /* NOTE: the flock constant seems to be the same for every Linux platform */ return get_errno(safe_flock(arg1, arg2)); -#if defined(TARGET_NR_preadv) - case TARGET_NR_preadv: - { - struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); - if (vec != NULL) { - unsigned long low, high; - - target_to_host_low_high(arg4, arg5, &low, &high); - ret = get_errno(safe_preadv(arg1, vec, arg3, low, high)); - unlock_iovec(vec, arg2, arg3, 1); - } else { - ret = -host_to_target_errno(errno); - } - } - return ret; -#endif -#if defined(TARGET_NR_pwritev) - case TARGET_NR_pwritev: - { - struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); - if (vec != NULL) { - unsigned long low, high; - - target_to_host_low_high(arg4, arg5, &low, &high); - ret = get_errno(safe_pwritev(arg1, vec, arg3, low, high)); - unlock_iovec(vec, arg2, arg3, 0); - } else { - ret = -host_to_target_errno(errno); - } - } - return ret; -#endif case TARGET_NR_getsid: return get_errno(getsid(arg1)); #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */ diff --git a/linux-user/strace.list b/linux-user/strace.list index c7e573669d..586eb55482 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1025,9 +1025,6 @@ #ifdef TARGET_NR_prctl { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_preadv -{ TARGET_NR_preadv, "preadv" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_prlimit64 { TARGET_NR_prlimit64, "prlimit64" , NULL, NULL, NULL }, #endif @@ -1052,9 +1049,6 @@ #ifdef TARGET_NR_putpmsg { TARGET_NR_putpmsg, "putpmsg" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pwritev -{ TARGET_NR_pwritev, "pwritev" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_query_module { TARGET_NR_query_module, "query_module" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027783 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="itERBaT7"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF8N5Yvdz9s9G for ; Sat, 19 Jan 2019 08:54:12 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47696 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc5a-0005m5-KX for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:54:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55891) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbk8-0004vC-Ox for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbk7-0004Nr-E7 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:00 -0500 Received: from mail-pl1-x643.google.com ([2607:f8b0:4864:20::643]:42952) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbk7-0004MC-5d for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:31:59 -0500 Received: by mail-pl1-x643.google.com with SMTP id y1so6880156plp.9 for ; Fri, 18 Jan 2019 13:31:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ufQpxh/X57xDiUtYrlRUraS/a7MW5Pi6EG4Y2IHH6IA=; b=itERBaT7qSQ9aj9qSyrGX4nvoQ0n4joEF+dsHoG1u/e1YCjH4ixdNRaN+BNB/0PhOj SSjGjn9M6SqZLnEG071Zpi55IklFJZ0YscuoU/jdSZLpwwKCtJ8PZvDvYbAFEoyDmefT 4uSF9Do9RVq1wz/Mn/pku0W193V2KoTaeFxrQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ufQpxh/X57xDiUtYrlRUraS/a7MW5Pi6EG4Y2IHH6IA=; b=o+YzzXtzm2isBwBTbAKUdE98WpYpZ3ED+m1ee6ohJvgSVjoLJiL8zFuSlpO1e2cUMm nqcjs4xl2rN8IQVkk3OPpAoU3KgI6CDLH8c36GHTPGTLc/9jM3k1E9RFEzjEpFGi2dV5 wN9qqDiMdHkqBWipJl2AygoiA/nd/zDElj0hAfHY11Oo+0CKmnNlKL1KtRwRzwxue0fJ hYg5ObncZI2ciQ23Fb5l7R+EXI2HaJoqKJbZJiBqThbKONvnjNmVbpEXjr99IAtpXGUf G2utIV7LIDj9al18sPJpPZMNWNH2LiQoZX5tm+A75Jz5yeo9S96AstAgMGx6YBuqMgoe imgA== X-Gm-Message-State: AJcUukeVtPTO6R3k4BIQjcRK/cNWiLzejApcs3/Bu+K0ysE4W6SF7Ff+ R3+yrBLHG3J/04PCsFjnjRbUsr7uqsI= X-Google-Smtp-Source: ALg8bN4303ZkaHmWgsMmhEie9AsPSDk9R9WbqVdqvSk4HqVWv4avUd6xatALA6fiy8uwuxwQ+ZZJTQ== X-Received: by 2002:a17:902:7882:: with SMTP id q2mr21279391pll.305.1547847117832; Fri, 18 Jan 2019 13:31:57 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:57 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:46 +1100 Message-Id: <20190118213122.22865-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::643 Subject: [Qemu-devel] [PATCH v6 13/49] linux-user: Split out name_to_handle_at, open_by_handle_at X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" All targets have these syscalls, so they need not be ifdefed. If we provide safe syscalls for the host, we can remove the configure test for this too. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 3 + linux-user/syscall.h | 1 + linux-user/strace.c | 5 +- linux-user/syscall-file.inc.c | 81 +++++++++++++++++++++++++++ linux-user/syscall.c | 102 ++-------------------------------- configure | 20 ------- linux-user/strace.list | 3 - 7 files changed, 93 insertions(+), 122 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index ae89be0e87..1fc89c1b08 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -17,10 +17,13 @@ */ SYSCALL_DEF(close, ARG_DEC); +SYSCALL_DEF(name_to_handle_at, + ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); #ifdef TARGET_NR_open SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); +SYSCALL_DEF(open_by_handle_at, ARG_DEC, ARG_PTR, ARG_OPENFLAG); SYSCALL_DEF_FULL(pread64, .impl = impl_pread64, .args = args_pread64_pwrite64, .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 43b5dc0684..83f602f8e7 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -57,6 +57,7 @@ typedef enum { /* These print as sets of flags. */ ARG_ATDIRFD, + ARG_ATFLAG, ARG_MODEFLAG, ARG_OPENFLAG, diff --git a/linux-user/strace.c b/linux-user/strace.c index 4faeb8c031..ed311b081b 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -780,7 +780,7 @@ UNUSED static struct flags access_flags[] = { FLAG_END, }; -UNUSED static struct flags at_file_flags[] = { +static struct flags const at_file_flags[] = { #ifdef AT_EACCESS FLAG_GENERIC(AT_EACCESS), #endif @@ -2681,6 +2681,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_ATDIRFD: len = add_atdirfd(b, rest, arg); break; + case ARG_ATFLAG: + len = add_flags(b, rest, at_file_flags, arg, false); + break; case ARG_MODEFLAG: len = add_flags(b, rest, mode_flags, arg, true); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 63401684c3..81423cfd64 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -317,6 +317,87 @@ SYSCALL_IMPL(openat) return do_openat(cpu_env, arg1, arg2, arg3, arg4); } +SYSCALL_IMPL(name_to_handle_at) +{ + struct file_handle *target_fh; + struct file_handle *fh; + int mid = 0; + abi_long ret; + char *name; + uint32_t size, total_size; + + if (get_user_s32(size, arg3)) { + return -TARGET_EFAULT; + } + total_size = sizeof(struct file_handle) + size; + target_fh = lock_user(VERIFY_WRITE, arg3, total_size, 0); + if (!target_fh) { + return -TARGET_EFAULT; + } + + name = lock_user_string(arg2); + if (!name) { + unlock_user(target_fh, arg3, 0); + return -TARGET_EFAULT; + } + + fh = g_malloc0(total_size); + fh->handle_bytes = size; + + ret = get_errno(safe_name_to_handle_at(arg1, path(name), fh, &mid, arg5)); + unlock_user(name, arg2, 0); + + /* + * man name_to_handle_at(2): + * Other than the use of the handle_bytes field, the caller should treat + * the file_handle structure as an opaque data type + */ + if (!is_error(ret)) { + memcpy(target_fh, fh, total_size); + target_fh->handle_bytes = tswap32(fh->handle_bytes); + target_fh->handle_type = tswap32(fh->handle_type); + g_free(fh); + unlock_user(target_fh, arg3, total_size); + + if (put_user_s32(mid, arg4)) { + return -TARGET_EFAULT; + } + } + return ret; +} + +SYSCALL_IMPL(open_by_handle_at) +{ + abi_long mount_fd = arg1; + abi_long handle = arg2; + int host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl); + struct file_handle *target_fh; + struct file_handle *fh; + unsigned int size, total_size; + abi_long ret; + + if (get_user_s32(size, handle)) { + return -TARGET_EFAULT; + } + total_size = sizeof(struct file_handle) + size; + target_fh = lock_user(VERIFY_READ, handle, total_size, 1); + if (!target_fh) { + return -TARGET_EFAULT; + } + + fh = g_memdup(target_fh, total_size); + fh->handle_bytes = size; + fh->handle_type = tswap32(target_fh->handle_type); + + ret = get_errno(safe_open_by_handle_at(mount_fd, fh, host_flags)); + + g_free(fh); + unlock_user(target_fh, handle, total_size); + + fd_trans_unregister(ret); + return ret; +} + /* * Both pread64 and pwrite64 merge args into a 64-bit offset, * but the input registers and ordering are target specific. diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9606f15a09..18dea32b60 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -816,6 +816,10 @@ safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr, safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr, size_t, len, unsigned *, prio, const struct timespec *, timeout) #endif +safe_syscall5(int, name_to_handle_at, int, dirfd, const char *, pathname, + struct file_handle *, handle, int *, mount_id, int, flags) +safe_syscall3(int, open_by_handle_at, int, mount_fd, + struct file_handle *, handle, int, flags) /* We do ioctl like this rather than via safe_syscall3 to preserve the * "third argument might be integer or pointer or not present" behaviour of * the libc function. @@ -6423,93 +6427,6 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, return -TARGET_ENOSYS; } } -#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) -static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname, - abi_long handle, abi_long mount_id, - abi_long flags) -{ - struct file_handle *target_fh; - struct file_handle *fh; - int mid = 0; - abi_long ret; - char *name; - unsigned int size, total_size; - - if (get_user_s32(size, handle)) { - return -TARGET_EFAULT; - } - - name = lock_user_string(pathname); - if (!name) { - return -TARGET_EFAULT; - } - - total_size = sizeof(struct file_handle) + size; - target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0); - if (!target_fh) { - unlock_user(name, pathname, 0); - return -TARGET_EFAULT; - } - - fh = g_malloc0(total_size); - fh->handle_bytes = size; - - ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags)); - unlock_user(name, pathname, 0); - - /* man name_to_handle_at(2): - * Other than the use of the handle_bytes field, the caller should treat - * the file_handle structure as an opaque data type - */ - - memcpy(target_fh, fh, total_size); - target_fh->handle_bytes = tswap32(fh->handle_bytes); - target_fh->handle_type = tswap32(fh->handle_type); - g_free(fh); - unlock_user(target_fh, handle, total_size); - - if (put_user_s32(mid, mount_id)) { - return -TARGET_EFAULT; - } - - return ret; - -} -#endif - -#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) -static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle, - abi_long flags) -{ - struct file_handle *target_fh; - struct file_handle *fh; - unsigned int size, total_size; - abi_long ret; - - if (get_user_s32(size, handle)) { - return -TARGET_EFAULT; - } - - total_size = sizeof(struct file_handle) + size; - target_fh = lock_user(VERIFY_READ, handle, total_size, 1); - if (!target_fh) { - return -TARGET_EFAULT; - } - - fh = g_memdup(target_fh, total_size); - fh->handle_bytes = size; - fh->handle_type = tswap32(target_fh->handle_type); - - ret = get_errno(open_by_handle_at(mount_fd, fh, - target_to_host_bitmask(flags, fcntl_flags_tbl))); - - g_free(fh); - - unlock_user(target_fh, handle, total_size); - - return ret; -} -#endif #if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4) @@ -6705,17 +6622,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, preexit_cleanup(cpu_env, arg1); _exit(arg1); return 0; /* avoid warning */ -#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) - case TARGET_NR_name_to_handle_at: - ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5); - return ret; -#endif -#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE) - case TARGET_NR_open_by_handle_at: - ret = do_open_by_handle_at(arg1, arg2, arg3); - fd_trans_unregister(ret); - return ret; -#endif case TARGET_NR_brk: return do_brk(arg1); #ifdef TARGET_NR_fork diff --git a/configure b/configure index 3eee3fcf70..1d45056f62 100755 --- a/configure +++ b/configure @@ -5028,22 +5028,6 @@ if test "$debug_stack_usage" = "yes"; then fi -########################################## -# check if we have open_by_handle_at - -open_by_handle_at=no -cat > $TMPC << EOF -#include -#if !defined(AT_EMPTY_PATH) -# error missing definition -#else -int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } -#endif -EOF -if compile_prog "" "" ; then - open_by_handle_at=yes -fi - ######################################## # check if we have linux/magic.h @@ -6701,10 +6685,6 @@ if test "$crypto_afalg" = "yes" ; then echo "CONFIG_AF_ALG=y" >> $config_host_mak fi -if test "$open_by_handle_at" = "yes" ; then - echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak -fi - if test "$linux_magic_h" = "yes" ; then echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak fi diff --git a/linux-user/strace.list b/linux-user/strace.list index 586eb55482..26ad95dc7e 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -635,9 +635,6 @@ #ifdef TARGET_NR_munmap { TARGET_NR_munmap, "munmap" , NULL, print_munmap, NULL }, #endif -#ifdef TARGET_NR_name_to_handle_at -{ TARGET_NR_name_to_handle_at, "name_to_handle_at" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_nanosleep { TARGET_NR_nanosleep, "nanosleep" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="LLKCLD84"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDq12LsMz9s9G for ; Sat, 19 Jan 2019 08:39:09 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47476 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbr1-0001gx-5k for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:39:07 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55927) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkI-00053J-3H for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkB-0004SC-Ph for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:09 -0500 Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]:39399) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkB-0004RV-CS for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:03 -0500 Received: by mail-pf1-x444.google.com with SMTP id r136so7201126pfc.6 for ; Fri, 18 Jan 2019 13:32:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aPVmoPM1dJPX2g1TIRx9GM31fQmagRJSRjmItQPpqJo=; b=LLKCLD84fTfQfG0iB8CAf+k3EJT/oFXP0NHqTCvxf4yIedIAccLSE+BI4JteN0Ifyl WV7Ji3fyqTp9jldc1YO8RGAOp8XNYV7Su0TTzn2P58UFXYi4BWTtUrnkoGZl/0/h6EJh sypvYM1BsztzJcT7bEv7XS9yiNAnz0uEiIB1A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aPVmoPM1dJPX2g1TIRx9GM31fQmagRJSRjmItQPpqJo=; b=crmJfrJ5qoFppIXyOdPON6WVCv9Xed7WZ8hMTV79bAWLp0ak2ytM7r/LgWcyL4Ttjc p9SfeqXGPzQFwNMSuhCrzqsWBF718enulC0Ag8hl/ySr+Yps/oxxHJ6eIyD966meYP7s tBE+JOsKHk8OkaxaSuf3FV0RsCvV+BkIQInvzN9IvoOTp+3/IsLj8Za4kk8hUoVmQGe7 bkLHI8esVq4SYnFqxz9hWuS5TnwbaGVO7HDXSM/cn3nQPFIx8H9gsh0LLsBiN83YF9vA J8ba4gL156Z6s5Y87FDDu10nYfmdpz06vC/Fe9QT6SQbZBk8rQ90vu0yGsSD+ifyyeWD Efhw== X-Gm-Message-State: AJcUukdM2CWooEy8XqynRxBZDxlu6oYSRjQ53gJPblbEK3jQFzUQOVL2 zV3ZjUR8YJnVx0hAkBj4u7SeMp1VLEw= X-Google-Smtp-Source: ALg8bN7oPQnLiF5ngbJzcqWC54dMAqN1bd2lIq0hk2qXE3EHFJLPYRaHQGNQfHIHxpEt66MPMdQQCQ== X-Received: by 2002:a63:24c2:: with SMTP id k185mr18906299pgk.406.1547847120697; Fri, 18 Jan 2019 13:32:00 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.31.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:31:59 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:47 +1100 Message-Id: <20190118213122.22865-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::444 Subject: [Qemu-devel] [PATCH v6 14/49] linux-user: Split out ipc syscalls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Because of the ipc multiplex syscall, these must be done all at once. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 38 ++ linux-user/strace.c | 83 --- linux-user/syscall-ipc.inc.c | 1086 ++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 972 +----------------------------- linux-user/strace.list | 42 -- 5 files changed, 1127 insertions(+), 1094 deletions(-) create mode 100644 linux-user/syscall-ipc.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 1fc89c1b08..6d6349da01 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -17,6 +17,21 @@ */ SYSCALL_DEF(close, ARG_DEC); +#ifdef TARGET_NR_ipc +SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgctl) +SYSCALL_DEF(msgctl, ARG_DEC, ARG_DEC, ARG_PTR); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgget) +SYSCALL_DEF(msgget, ARG_DEC, ARG_DEC); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgrcv) +SYSCALL_DEF(msgrcv, ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC, ARG_HEX); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgsnd) +SYSCALL_DEF(msgsnd, ARG_DEC, ARG_PTR, ARG_DEC, ARG_HEX); +#endif SYSCALL_DEF(name_to_handle_at, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); #ifdef TARGET_NR_open @@ -44,5 +59,28 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC); #endif SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC); +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl) +SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semget) +SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semop) +SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmat) +SYSCALL_DEF_FULL(shmat, .impl = impl_shmat, + .print_ret = print_syscall_ptr_ret, + .arg_type = { ARG_DEC, ARG_PTR, ARG_HEX }); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmctl) +SYSCALL_DEF(shmctl, ARG_DEC, ARG_DEC, ARG_PTR); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmdt) +SYSCALL_DEF(shmdt, ARG_PTR); +#endif +#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget) +SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); +#endif SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC); SYSCALL_DEF(writev, ARG_DEC, ARG_PTR, ARG_DEC); diff --git a/linux-user/strace.c b/linux-user/strace.c index ed311b081b..3233230527 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1,8 +1,4 @@ #include "qemu/osdep.h" -#include -#include -#include -#include #include #include #include @@ -74,54 +70,6 @@ UNUSED static void print_socket_protocol(int domain, int type, int protocol); /* * Utility functions */ -static void -print_ipc_cmd(int cmd) -{ -#define output_cmd(val) \ -if( cmd == val ) { \ - gemu_log(#val); \ - return; \ -} - - cmd &= 0xff; - - /* General IPC commands */ - output_cmd( IPC_RMID ); - output_cmd( IPC_SET ); - output_cmd( IPC_STAT ); - output_cmd( IPC_INFO ); - /* msgctl() commands */ - output_cmd( MSG_STAT ); - output_cmd( MSG_INFO ); - /* shmctl() commands */ - output_cmd( SHM_LOCK ); - output_cmd( SHM_UNLOCK ); - output_cmd( SHM_STAT ); - output_cmd( SHM_INFO ); - /* semctl() commands */ - output_cmd( GETPID ); - output_cmd( GETVAL ); - output_cmd( GETALL ); - output_cmd( GETNCNT ); - output_cmd( GETZCNT ); - output_cmd( SETVAL ); - output_cmd( SETALL ); - output_cmd( SEM_STAT ); - output_cmd( SEM_INFO ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - output_cmd( IPC_RMID ); - - /* Some value we don't recognize */ - gemu_log("%d",cmd); -} - static void print_signal(abi_ulong arg, int last) { @@ -620,18 +568,6 @@ print_newselect(const struct syscallname *name, } #endif -#ifdef TARGET_NR_semctl -static void -print_semctl(const struct syscallname *name, - abi_long arg1, abi_long arg2, abi_long arg3, - abi_long arg4, abi_long arg5, abi_long arg6) -{ - gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, arg1, arg2); - print_ipc_cmd(arg3); - gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4); -} -#endif - static void print_execve(const struct syscallname *name, abi_long arg1, abi_long arg2, abi_long arg3, @@ -664,25 +600,6 @@ print_execve(const struct syscallname *name, gemu_log("NULL})"); } -#ifdef TARGET_NR_ipc -static void -print_ipc(const struct syscallname *name, - abi_long arg1, abi_long arg2, abi_long arg3, - abi_long arg4, abi_long arg5, abi_long arg6) -{ - switch(arg1) { - case IPCOP_semctl: - gemu_log("semctl(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", arg1, arg2); - print_ipc_cmd(arg3); - gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4); - break; - default: - gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")", - name->name, arg1, arg2, arg3, arg4); - } -} -#endif - /* * Variants for the return value output function */ diff --git a/linux-user/syscall-ipc.inc.c b/linux-user/syscall-ipc.inc.c new file mode 100644 index 0000000000..18076017b8 --- /dev/null +++ b/linux-user/syscall-ipc.inc.c @@ -0,0 +1,1086 @@ +/* + * Linux ipc-related syscalls + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +#ifdef __NR_msgsnd +safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz, + int, flags) +safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz, + long, msgtype, int, flags) +safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops, + unsigned, nsops, const struct timespec *, timeout) +#else +/* + * This host kernel architecture uses a single ipc syscall; fake up + * wrappers for the sub-operations to hide this implementation detail. + * Annoyingly we can't include linux/ipc.h to get the constant definitions + * for the call parameter because some structs in there conflict with the + * sys/ipc.h ones. So we just define them here, and rely on them being + * the same for all host architectures. + */ +#define Q_SEMTIMEDOP 4 +#define Q_MSGSND 11 +#define Q_MSGRCV 12 +#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP)) + +safe_syscall6(int, ipc, int, call, long, first, long, second, long, third, + void *, ptr, long, fifth) + +static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags) +{ + return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0); +} + +static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags) +{ + return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type); +} + +static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops, + const struct timespec *timeout) +{ + return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops, + (long)timeout); +} +#endif + +/* See comment above. */ +#define SEMOPM 500 + +#define N_SHM_REGIONS 32 + +static struct shm_region { + abi_ulong start; + abi_ulong size; + bool in_use; +} shm_regions[N_SHM_REGIONS]; + +#ifndef TARGET_SEMID64_DS +/* asm-generic version of this struct */ +struct target_semid64_ds { + struct target_ipc_perm sem_perm; + abi_ulong sem_otime; +#if TARGET_ABI_BITS == 32 + abi_ulong __unused1; +#endif + abi_ulong sem_ctime; +#if TARGET_ABI_BITS == 32 + abi_ulong __unused2; +#endif + abi_ulong sem_nsems; + abi_ulong __unused3; + abi_ulong __unused4; +}; +#endif + +static abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip, + abi_ulong target_addr) +{ + struct target_ipc_perm *target_ip; + struct target_semid64_ds *target_sd; + + if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) { + return -TARGET_EFAULT; + } + target_ip = &target_sd->sem_perm; + host_ip->__key = tswap32(target_ip->__key); + host_ip->uid = tswap32(target_ip->uid); + host_ip->gid = tswap32(target_ip->gid); + host_ip->cuid = tswap32(target_ip->cuid); + host_ip->cgid = tswap32(target_ip->cgid); +#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC) + host_ip->mode = tswap32(target_ip->mode); +#else + host_ip->mode = tswap16(target_ip->mode); +#endif +#if defined(TARGET_PPC) + host_ip->__seq = tswap32(target_ip->__seq); +#else + host_ip->__seq = tswap16(target_ip->__seq); +#endif + unlock_user_struct(target_sd, target_addr, 0); + return 0; +} + +static abi_long host_to_target_ipc_perm(abi_ulong target_addr, + struct ipc_perm *host_ip) +{ + struct target_ipc_perm *target_ip; + struct target_semid64_ds *target_sd; + + if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) { + return -TARGET_EFAULT; + } + target_ip = &target_sd->sem_perm; + target_ip->__key = tswap32(host_ip->__key); + target_ip->uid = tswap32(host_ip->uid); + target_ip->gid = tswap32(host_ip->gid); + target_ip->cuid = tswap32(host_ip->cuid); + target_ip->cgid = tswap32(host_ip->cgid); +#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC) + target_ip->mode = tswap32(host_ip->mode); +#else + target_ip->mode = tswap16(host_ip->mode); +#endif +#if defined(TARGET_PPC) + target_ip->__seq = tswap32(host_ip->__seq); +#else + target_ip->__seq = tswap16(host_ip->__seq); +#endif + unlock_user_struct(target_sd, target_addr, 1); + return 0; +} + +static abi_long target_to_host_semid_ds(struct semid_ds *host_sd, + abi_ulong target_addr) +{ + struct target_semid64_ds *target_sd; + + if (target_to_host_ipc_perm(&host_sd->sem_perm, target_addr)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) { + return -TARGET_EFAULT; + } + host_sd->sem_nsems = tswapal(target_sd->sem_nsems); + host_sd->sem_otime = tswapal(target_sd->sem_otime); + host_sd->sem_ctime = tswapal(target_sd->sem_ctime); + unlock_user_struct(target_sd, target_addr, 0); + return 0; +} + +static abi_long host_to_target_semid_ds(abi_ulong target_addr, + struct semid_ds *host_sd) +{ + struct target_semid64_ds *target_sd; + + if (host_to_target_ipc_perm(target_addr, &host_sd->sem_perm)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) { + return -TARGET_EFAULT; + } + target_sd->sem_nsems = tswapal(host_sd->sem_nsems); + target_sd->sem_otime = tswapal(host_sd->sem_otime); + target_sd->sem_ctime = tswapal(host_sd->sem_ctime); + unlock_user_struct(target_sd, target_addr, 1); + return 0; +} + +struct target_seminfo { + int semmap; + int semmni; + int semmns; + int semmnu; + int semmsl; + int semopm; + int semume; + int semusz; + int semvmx; + int semaem; +}; + +static abi_long host_to_target_seminfo(abi_ulong target_addr, + struct seminfo *host_seminfo) +{ + struct target_seminfo *target_seminfo; + + if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_seminfo->semmap, &target_seminfo->semmap); + __put_user(host_seminfo->semmni, &target_seminfo->semmni); + __put_user(host_seminfo->semmns, &target_seminfo->semmns); + __put_user(host_seminfo->semmnu, &target_seminfo->semmnu); + __put_user(host_seminfo->semmsl, &target_seminfo->semmsl); + __put_user(host_seminfo->semopm, &target_seminfo->semopm); + __put_user(host_seminfo->semume, &target_seminfo->semume); + __put_user(host_seminfo->semusz, &target_seminfo->semusz); + __put_user(host_seminfo->semvmx, &target_seminfo->semvmx); + __put_user(host_seminfo->semaem, &target_seminfo->semaem); + unlock_user_struct(target_seminfo, target_addr, 1); + return 0; +} + +union semun { + int val; + struct semid_ds *buf; + unsigned short *array; + struct seminfo *__buf; +}; + +union target_semun { + int val; + abi_ulong buf; + abi_ulong array; + abi_ulong __buf; +}; + +static abi_long target_to_host_semarray(int semid, + unsigned short **host_array, + abi_ulong target_addr) +{ + int nsems; + unsigned short *array; + union semun semun; + struct semid_ds semid_ds; + int i, ret; + + semun.buf = &semid_ds; + + ret = semctl(semid, 0, IPC_STAT, semun); + if (ret == -1) { + return get_errno(ret); + } + + nsems = semid_ds.sem_nsems; + + *host_array = g_try_new(unsigned short, nsems); + if (!*host_array) { + return -TARGET_ENOMEM; + } + array = lock_user(VERIFY_READ, target_addr, + nsems * sizeof(unsigned short), 1); + if (!array) { + g_free(*host_array); + return -TARGET_EFAULT; + } + for (i = 0; i < nsems; i++) { + __get_user((*host_array)[i], &array[i]); + } + unlock_user(array, target_addr, 0); + + return 0; +} + +static abi_long host_to_target_semarray(int semid, abi_ulong target_addr, + unsigned short **host_array) +{ + int nsems; + unsigned short *array; + union semun semun; + struct semid_ds semid_ds; + int i, ret; + + semun.buf = &semid_ds; + + ret = semctl(semid, 0, IPC_STAT, semun); + if (ret == -1) { + return get_errno(ret); + } + + nsems = semid_ds.sem_nsems; + + array = lock_user(VERIFY_WRITE, target_addr, + nsems * sizeof(unsigned short), 0); + if (!array) { + return -TARGET_EFAULT; + } + for (i = 0; i < nsems; i++) { + __put_user((*host_array)[i], &array[i]); + } + g_free(*host_array); + unlock_user(array, target_addr, 1); + + return 0; +} + +struct target_sembuf { + unsigned short sem_num; + short sem_op; + short sem_flg; +}; + +static abi_long target_to_host_sembuf(struct sembuf *host_sembuf, + abi_ulong target_addr, + unsigned nsops) +{ + struct target_sembuf *target_sembuf; + int i; + + target_sembuf = lock_user(VERIFY_READ, target_addr, + nsops * sizeof(struct target_sembuf), 1); + if (!target_sembuf) { + return -TARGET_EFAULT; + } + for (i = 0; i < nsops; i++) { + __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num); + __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op); + __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg); + } + unlock_user(target_sembuf, target_addr, 0); + return 0; +} + +struct target_msqid_ds { + struct target_ipc_perm msg_perm; + abi_ulong msg_stime; +#if TARGET_ABI_BITS == 32 + abi_ulong __unused1; +#endif + abi_ulong msg_rtime; +#if TARGET_ABI_BITS == 32 + abi_ulong __unused2; +#endif + abi_ulong msg_ctime; +#if TARGET_ABI_BITS == 32 + abi_ulong __unused3; +#endif + abi_ulong __msg_cbytes; + abi_ulong msg_qnum; + abi_ulong msg_qbytes; + abi_ulong msg_lspid; + abi_ulong msg_lrpid; + abi_ulong __unused4; + abi_ulong __unused5; +}; + +static abi_long target_to_host_msqid_ds(struct msqid_ds *host_md, + abi_ulong target_addr) +{ + struct target_msqid_ds *target_md; + + if (target_to_host_ipc_perm(&host_md->msg_perm, target_addr)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1)) { + return -TARGET_EFAULT; + } + host_md->msg_stime = tswapal(target_md->msg_stime); + host_md->msg_rtime = tswapal(target_md->msg_rtime); + host_md->msg_ctime = tswapal(target_md->msg_ctime); + host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes); + host_md->msg_qnum = tswapal(target_md->msg_qnum); + host_md->msg_qbytes = tswapal(target_md->msg_qbytes); + host_md->msg_lspid = tswapal(target_md->msg_lspid); + host_md->msg_lrpid = tswapal(target_md->msg_lrpid); + unlock_user_struct(target_md, target_addr, 0); + return 0; +} + +static abi_long host_to_target_msqid_ds(abi_ulong target_addr, + struct msqid_ds *host_md) +{ + struct target_msqid_ds *target_md; + + if (host_to_target_ipc_perm(target_addr, &host_md->msg_perm)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) { + return -TARGET_EFAULT; + } + target_md->msg_stime = tswapal(host_md->msg_stime); + target_md->msg_rtime = tswapal(host_md->msg_rtime); + target_md->msg_ctime = tswapal(host_md->msg_ctime); + target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes); + target_md->msg_qnum = tswapal(host_md->msg_qnum); + target_md->msg_qbytes = tswapal(host_md->msg_qbytes); + target_md->msg_lspid = tswapal(host_md->msg_lspid); + target_md->msg_lrpid = tswapal(host_md->msg_lrpid); + unlock_user_struct(target_md, target_addr, 1); + return 0; +} + +struct target_msginfo { + int msgpool; + int msgmap; + int msgmax; + int msgmnb; + int msgmni; + int msgssz; + int msgtql; + unsigned short int msgseg; +}; + +static abi_long host_to_target_msginfo(abi_ulong target_addr, + struct msginfo *host_msginfo) +{ + struct target_msginfo *target_msginfo; + + if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_msginfo->msgpool, &target_msginfo->msgpool); + __put_user(host_msginfo->msgmap, &target_msginfo->msgmap); + __put_user(host_msginfo->msgmax, &target_msginfo->msgmax); + __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb); + __put_user(host_msginfo->msgmni, &target_msginfo->msgmni); + __put_user(host_msginfo->msgssz, &target_msginfo->msgssz); + __put_user(host_msginfo->msgtql, &target_msginfo->msgtql); + __put_user(host_msginfo->msgseg, &target_msginfo->msgseg); + unlock_user_struct(target_msginfo, target_addr, 1); + return 0; +} + +struct target_msgbuf { + abi_long mtype; + char mtext[1]; +}; + +static abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd, + abi_ulong target_addr) +{ + struct target_shmid_ds *target_sd; + + if (target_to_host_ipc_perm(&host_sd->shm_perm, target_addr)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) { + return -TARGET_EFAULT; + } + __get_user(host_sd->shm_segsz, &target_sd->shm_segsz); + __get_user(host_sd->shm_atime, &target_sd->shm_atime); + __get_user(host_sd->shm_dtime, &target_sd->shm_dtime); + __get_user(host_sd->shm_ctime, &target_sd->shm_ctime); + __get_user(host_sd->shm_cpid, &target_sd->shm_cpid); + __get_user(host_sd->shm_lpid, &target_sd->shm_lpid); + __get_user(host_sd->shm_nattch, &target_sd->shm_nattch); + unlock_user_struct(target_sd, target_addr, 0); + return 0; +} + +static abi_long host_to_target_shmid_ds(abi_ulong target_addr, + struct shmid_ds *host_sd) +{ + struct target_shmid_ds *target_sd; + + if (host_to_target_ipc_perm(target_addr, &host_sd->shm_perm)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_sd->shm_segsz, &target_sd->shm_segsz); + __put_user(host_sd->shm_atime, &target_sd->shm_atime); + __put_user(host_sd->shm_dtime, &target_sd->shm_dtime); + __put_user(host_sd->shm_ctime, &target_sd->shm_ctime); + __put_user(host_sd->shm_cpid, &target_sd->shm_cpid); + __put_user(host_sd->shm_lpid, &target_sd->shm_lpid); + __put_user(host_sd->shm_nattch, &target_sd->shm_nattch); + unlock_user_struct(target_sd, target_addr, 1); + return 0; +} + +struct target_shminfo { + abi_ulong shmmax; + abi_ulong shmmin; + abi_ulong shmmni; + abi_ulong shmseg; + abi_ulong shmall; +}; + +static abi_long host_to_target_shminfo(abi_ulong target_addr, + struct shminfo *host_shminfo) +{ + struct target_shminfo *target_shminfo; + + if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_shminfo->shmmax, &target_shminfo->shmmax); + __put_user(host_shminfo->shmmin, &target_shminfo->shmmin); + __put_user(host_shminfo->shmmni, &target_shminfo->shmmni); + __put_user(host_shminfo->shmseg, &target_shminfo->shmseg); + __put_user(host_shminfo->shmall, &target_shminfo->shmall); + unlock_user_struct(target_shminfo, target_addr, 1); + return 0; +} + +struct target_shm_info { + int used_ids; + abi_ulong shm_tot; + abi_ulong shm_rss; + abi_ulong shm_swp; + abi_ulong swap_attempts; + abi_ulong swap_successes; +}; + +static abi_long host_to_target_shm_info(abi_ulong target_addr, + struct shm_info *host_shm_info) +{ + struct target_shm_info *target_shm_info; + + if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_shm_info->used_ids, &target_shm_info->used_ids); + __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot); + __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss); + __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp); + __put_user(host_shm_info->swap_attempts, + &target_shm_info->swap_attempts); + __put_user(host_shm_info->swap_successes, + &target_shm_info->swap_successes); + unlock_user_struct(target_shm_info, target_addr, 1); + return 0; +} + +#ifndef TARGET_FORCE_SHMLBA +/* + * For most architectures, SHMLBA is the same as the page size; + * some architectures have larger values, in which case they should + * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function. + * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA + * and defining its own value for SHMLBA. + * + * The kernel also permits SHMLBA to be set by the architecture to a + * value larger than the page size without setting __ARCH_FORCE_SHMLBA; + * this means that addresses are rounded to the large size if + * SHM_RND is set but addresses not aligned to that size are not rejected + * as long as they are at least page-aligned. Since the only architecture + * which uses this is ia64 this code doesn't provide for that oddity. + */ +static abi_ulong target_shmlba(CPUArchState *cpu_env) +{ + return TARGET_PAGE_SIZE; +} +#endif + + +SYSCALL_IMPL(msgctl) +{ + abi_long msgid = arg1; + int cmd = arg2 & 0xff; + abi_ulong ptr = arg3; + struct msqid_ds dsarg; + struct msginfo msginfo; + abi_long ret; + + switch (cmd) { + case IPC_STAT: + case IPC_SET: + case MSG_STAT: + if (target_to_host_msqid_ds(&dsarg, ptr)) { + return -TARGET_EFAULT; + } + ret = get_errno(msgctl(msgid, cmd, &dsarg)); + if (!is_error(ret) && host_to_target_msqid_ds(ptr, &dsarg)) { + return -TARGET_EFAULT; + } + return ret; + + case IPC_RMID: + return get_errno(msgctl(msgid, cmd, NULL)); + + case IPC_INFO: + case MSG_INFO: + ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo)); + if (host_to_target_msginfo(ptr, &msginfo)) { + return -TARGET_EFAULT; + } + return ret; + + default: + return -TARGET_EINVAL; + } +} + +SYSCALL_IMPL(msgget) +{ + return get_errno(msgget(arg1, arg2)); +} + +SYSCALL_IMPL(msgrcv) +{ + int msqid = arg1; + abi_ulong msgp = arg2; + abi_long msgsz = arg3; + abi_long msgtyp = arg4; + int msgflg = arg5; + struct target_msgbuf *target_mb; + char *target_mtext; + struct msgbuf *host_mb; + abi_long ret = 0; + + if (msgsz < 0) { + return -TARGET_EINVAL; + } + if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) { + return -TARGET_EFAULT; + } + + host_mb = g_try_malloc(msgsz + sizeof(long)); + if (!host_mb) { + ret = -TARGET_ENOMEM; + goto end; + } + ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg)); + + if (ret > 0) { + abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); + target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0); + if (!target_mtext) { + ret = -TARGET_EFAULT; + goto end; + } + memcpy(target_mb->mtext, host_mb->mtext, ret); + unlock_user(target_mtext, target_mtext_addr, ret); + } + target_mb->mtype = tswapal(host_mb->mtype); + + end: + unlock_user_struct(target_mb, msgp, 1); + g_free(host_mb); + return ret; +} + +SYSCALL_IMPL(msgsnd) +{ + int msqid = arg1; + abi_ulong msgp = arg2; + abi_long msgsz = arg3; + int msgflg = arg4; + struct target_msgbuf *target_mb; + struct msgbuf *host_mb; + abi_long ret = 0; + + if (msgsz < 0) { + return -TARGET_EINVAL; + } + if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) { + return -TARGET_EFAULT; + } + host_mb = g_try_malloc(msgsz + sizeof(long)); + if (!host_mb) { + unlock_user_struct(target_mb, msgp, 0); + return -TARGET_ENOMEM; + } + + host_mb->mtype = (abi_long)tswapal(target_mb->mtype); + memcpy(host_mb->mtext, target_mb->mtext, msgsz); + ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg)); + + g_free(host_mb); + unlock_user_struct(target_mb, msgp, 0); + return ret; +} + +SYSCALL_IMPL(semctl) +{ + abi_long semid = arg1; + abi_long semnum = arg2; + int cmd = arg3 & 0xff; + abi_ulong target_arg = arg4; + union target_semun target_su = { .buf = target_arg }; + union semun arg; + struct semid_ds dsarg; + unsigned short *array = NULL; + struct seminfo seminfo; + abi_long ret, err; + + switch (cmd) { + case GETVAL: + case SETVAL: + /* + * In 64 bit cross-endian situations, we will erroneously pick up + * the wrong half of the union for the "val" element. To rectify + * this, the entire 8-byte structure is byteswapped, followed by + * a swap of the 4 byte val field. In other cases, the data is + * already in proper host byte order. + */ + if (sizeof(target_su.val) != sizeof(target_su.buf)) { + target_su.buf = tswapal(target_su.buf); + arg.val = tswap32(target_su.val); + } else { + arg.val = target_su.val; + } + return get_errno(semctl(semid, semnum, cmd, arg)); + + case GETALL: + case SETALL: + err = target_to_host_semarray(semid, &array, target_su.array); + if (err) { + return err; + } + arg.array = array; + ret = get_errno(semctl(semid, semnum, cmd, arg)); + if (!is_error(ret)) { + err = host_to_target_semarray(semid, target_su.array, &array); + if (err) { + return err; + } + } + return ret; + + case IPC_STAT: + case IPC_SET: + case SEM_STAT: + err = target_to_host_semid_ds(&dsarg, target_su.buf); + if (err) { + return err; + } + arg.buf = &dsarg; + ret = get_errno(semctl(semid, semnum, cmd, arg)); + if (!is_error(ret)) { + err = host_to_target_semid_ds(target_su.buf, &dsarg); + if (err) { + return err; + } + } + return ret; + + case IPC_INFO: + case SEM_INFO: + arg.__buf = &seminfo; + ret = get_errno(semctl(semid, semnum, cmd, arg)); + if (!is_error(ret)) { + err = host_to_target_seminfo(target_su.__buf, &seminfo); + if (err) { + return err; + } + } + return ret; + + case IPC_RMID: + case GETPID: + case GETNCNT: + case GETZCNT: + return get_errno(semctl(semid, semnum, cmd, NULL)); + + default: + return -TARGET_EINVAL; + } +} + +SYSCALL_IMPL(semget) +{ + return get_errno(semget(arg1, arg2, arg3)); +} + +SYSCALL_IMPL(semop) +{ + abi_long semid = arg1; + abi_ulong ptr = arg2; + abi_ulong nsops = arg3; + struct sembuf sops[SEMOPM]; + + if (nsops > SEMOPM) { + return -TARGET_E2BIG; + } + if (target_to_host_sembuf(sops, ptr, nsops)) { + return -TARGET_EFAULT; + } + return get_errno(safe_semtimedop(semid, sops, nsops, NULL)); +} + +SYSCALL_IMPL(shmat) +{ + int shmid = arg1; + abi_ulong shmaddr = arg2; + int shmflg = arg3; + abi_ulong raddr; + void *host_raddr; + struct shmid_ds shm_info; + int i, ret; + abi_ulong shmlba; + + /* Find out the length of the shared memory segment. */ + ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info)); + if (is_error(ret)) { + /* can't get length, bail out */ + return ret; + } + + /* Validate memory placement and alignment for the guest. */ + shmlba = target_shmlba(cpu_env); + if (shmaddr & (shmlba - 1)) { + if (shmflg & SHM_RND) { + shmaddr &= ~(shmlba - 1); + } else { + return -TARGET_EINVAL; + } + } + if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) { + return -TARGET_EINVAL; + } + + mmap_lock(); + + if (shmaddr) { + host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg); + } else { + abi_ulong mmap_start = mmap_find_vma(0, shm_info.shm_segsz); + if (mmap_start == -1) { + errno = ENOMEM; + host_raddr = (void *)-1; + } else { + host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP); + } + } + if (host_raddr == (void *)-1) { + mmap_unlock(); + return get_errno((intptr_t)host_raddr); + } + + raddr = h2g((uintptr_t)host_raddr); + page_set_flags(raddr, raddr + shm_info.shm_segsz, + PAGE_VALID | PAGE_READ | + (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE)); + + for (i = 0; i < N_SHM_REGIONS; i++) { + if (!shm_regions[i].in_use) { + shm_regions[i].in_use = true; + shm_regions[i].start = raddr; + shm_regions[i].size = shm_info.shm_segsz; + break; + } + } + mmap_unlock(); + return raddr; +} + +SYSCALL_IMPL(shmctl) +{ + int shmid = arg1; + int cmd = arg2 & 0xff; + abi_ulong buf = arg3; + struct shmid_ds dsarg; + struct shminfo shminfo; + struct shm_info shm_info; + abi_long ret; + + switch (cmd) { + case IPC_STAT: + case IPC_SET: + case SHM_STAT: + if (target_to_host_shmid_ds(&dsarg, buf)) { + return -TARGET_EFAULT; + } + ret = get_errno(shmctl(shmid, cmd, &dsarg)); + if (!is_error(ret) && host_to_target_shmid_ds(buf, &dsarg)) { + return -TARGET_EFAULT; + } + return ret; + + case IPC_INFO: + ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo)); + if (!is_error(ret) && host_to_target_shminfo(buf, &shminfo)) { + return -TARGET_EFAULT; + } + return ret; + + case SHM_INFO: + ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info)); + if (!is_error(ret) && host_to_target_shm_info(buf, &shm_info)) { + return -TARGET_EFAULT; + } + return ret; + + case IPC_RMID: + case SHM_LOCK: + case SHM_UNLOCK: + return get_errno(shmctl(shmid, cmd, NULL)); + + default: + return -TARGET_EINVAL; + } +} + +SYSCALL_IMPL(shmdt) +{ + abi_ulong shmaddr = arg1; + abi_long ret; + int i; + + mmap_lock(); + + for (i = 0; i < N_SHM_REGIONS; ++i) { + if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) { + shm_regions[i].in_use = false; + page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0); + break; + } + } + ret = get_errno(shmdt(g2h(shmaddr))); + + mmap_unlock(); + + return ret; +} + +SYSCALL_IMPL(shmget) +{ + return get_errno(shmget(arg1, arg2, arg3)); +} + +#ifdef TARGET_NR_ipc +/* + * This differs from normal shmat in returning the result via a pointer. + * Here we have shifted that pointer to arg4. + */ +SYSCALL_IMPL(ipc_shmat) +{ + abi_long ret = impl_shmat(cpu_env, arg1, arg2, arg3, 0, 0, 0); + + if (is_error(ret)) { + return ret; + } + if (put_user_ual(ret, arg4)) { + return -TARGET_EFAULT; + } + return 0; +} + +static const SyscallDef def_ipc_shmat = { + .name = "shmat", + .impl = impl_ipc_shmat, + .arg_type = { ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR }, +}; + +/* These get defined later via syscall-defs.h. */ +static const SyscallDef def_semop; +static const SyscallDef def_semget; +static const SyscallDef def_semctl; +static const SyscallDef def_msgget; +static const SyscallDef def_msgsnd; +static const SyscallDef def_msgctl; +static const SyscallDef def_msgrcv; +static const SyscallDef def_shmdt; +static const SyscallDef def_shmget; +static const SyscallDef def_shmctl; + +/* + * Demultiplex the IPC syscall and shuffle the arguments around + * into the "normal" ordering. + */ +SYSCALL_ARGS(ipc) +{ + int call = extract32(in[0], 0, 16); + int version = extract32(in[0], 16, 16); + abi_long first = in[1]; + abi_long second = in[2]; + abi_long third = in[3]; + abi_ulong ptr = in[4]; + abi_long fifth = in[5]; + abi_ulong atptr; + + /* IPC_* and SHM_* command values are the same on all linux platforms */ + switch (call) { + case IPCOP_semop: + out[0] = first; + out[1] = ptr; + out[2] = second; + return &def_semop; + + case IPCOP_semget: + out[0] = first; + out[1] = second; + out[2] = third; + return &def_semget; + + case IPCOP_semctl: + /* + * The semun argument to semctl is passed by value, + * so dereference the ptr argument. + */ + if (get_user_ual(atptr, ptr)) { + errno = EFAULT; + return NULL; + } + out[0] = first; + out[1] = second; + out[2] = third; + out[3] = atptr; + return &def_semctl; + + case IPCOP_msgget: + out[0] = first; + out[1] = second; + return &def_msgget; + + case IPCOP_msgsnd: + out[0] = first; + out[1] = ptr; + out[2] = second; + out[3] = third; + return &def_msgsnd; + + case IPCOP_msgctl: + out[0] = first; + out[1] = second; + out[2] = ptr; + return &def_msgctl; + + case IPCOP_msgrcv: + if (version == 0) { + struct target_ipc_kludge { + abi_long msgp; + abi_long msgtyp; + } *tmp; + + if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) { + errno = EFAULT; + return NULL; + } + out[0] = first; + out[1] = tswapal(tmp->msgp); + out[2] = second; + out[3] = tswapal(tmp->msgtyp); + out[4] = third; + unlock_user_struct(tmp, ptr, 0); + } else { + out[0] = first; + out[1] = ptr; + out[2] = second; + out[3] = fifth; + out[4] = third; + } + return &def_msgrcv; + + case IPCOP_shmat: + if (version == 1) { + errno = EINVAL; + return NULL; + } + out[0] = first; + out[1] = ptr; + out[2] = second; + out[3] = third; + return &def_ipc_shmat; + + case IPCOP_shmdt: + out[0] = ptr; + return &def_shmdt; + + case IPCOP_shmget: + out[0] = first; + out[1] = second; + out[2] = third; + return &def_shmget; + + case IPCOP_shmctl: + out[0] = first; + out[1] = second; + out[2] = ptr; + return &def_shmctl; + + default: + /* Invalid syscall. Continue to impl_ipc for logging. */ + return def; + } +} + +SYSCALL_IMPL(ipc) +{ + int call = extract32(arg1, 0, 16); + int version = extract32(arg1, 16, 16); + + gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); + return -TARGET_ENOSYS; +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 18dea32b60..ad5ccbefdb 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -773,43 +773,6 @@ safe_syscall2(int, nanosleep, const struct timespec *, req, safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags, const struct timespec *, req, struct timespec *, rem) #endif -#ifdef __NR_msgsnd -safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz, - int, flags) -safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz, - long, msgtype, int, flags) -safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops, - unsigned, nsops, const struct timespec *, timeout) -#else -/* This host kernel architecture uses a single ipc syscall; fake up - * wrappers for the sub-operations to hide this implementation detail. - * Annoyingly we can't include linux/ipc.h to get the constant definitions - * for the call parameter because some structs in there conflict with the - * sys/ipc.h ones. So we just define them here, and rely on them being - * the same for all host architectures. - */ -#define Q_SEMTIMEDOP 4 -#define Q_MSGSND 11 -#define Q_MSGRCV 12 -#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP)) - -safe_syscall6(int, ipc, int, call, long, first, long, second, long, third, - void *, ptr, long, fifth) -static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags) -{ - return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0); -} -static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags) -{ - return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type); -} -static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops, - const struct timespec *timeout) -{ - return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops, - (long)timeout); -} -#endif #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open) safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr, size_t, len, unsigned, prio, const struct timespec *, timeout) @@ -3134,890 +3097,6 @@ static abi_long do_socketcall(int num, abi_ulong vptr) } #endif -#define N_SHM_REGIONS 32 - -static struct shm_region { - abi_ulong start; - abi_ulong size; - bool in_use; -} shm_regions[N_SHM_REGIONS]; - -#ifndef TARGET_SEMID64_DS -/* asm-generic version of this struct */ -struct target_semid64_ds -{ - struct target_ipc_perm sem_perm; - abi_ulong sem_otime; -#if TARGET_ABI_BITS == 32 - abi_ulong __unused1; -#endif - abi_ulong sem_ctime; -#if TARGET_ABI_BITS == 32 - abi_ulong __unused2; -#endif - abi_ulong sem_nsems; - abi_ulong __unused3; - abi_ulong __unused4; -}; -#endif - -static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip, - abi_ulong target_addr) -{ - struct target_ipc_perm *target_ip; - struct target_semid64_ds *target_sd; - - if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) - return -TARGET_EFAULT; - target_ip = &(target_sd->sem_perm); - host_ip->__key = tswap32(target_ip->__key); - host_ip->uid = tswap32(target_ip->uid); - host_ip->gid = tswap32(target_ip->gid); - host_ip->cuid = tswap32(target_ip->cuid); - host_ip->cgid = tswap32(target_ip->cgid); -#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC) - host_ip->mode = tswap32(target_ip->mode); -#else - host_ip->mode = tswap16(target_ip->mode); -#endif -#if defined(TARGET_PPC) - host_ip->__seq = tswap32(target_ip->__seq); -#else - host_ip->__seq = tswap16(target_ip->__seq); -#endif - unlock_user_struct(target_sd, target_addr, 0); - return 0; -} - -static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr, - struct ipc_perm *host_ip) -{ - struct target_ipc_perm *target_ip; - struct target_semid64_ds *target_sd; - - if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) - return -TARGET_EFAULT; - target_ip = &(target_sd->sem_perm); - target_ip->__key = tswap32(host_ip->__key); - target_ip->uid = tswap32(host_ip->uid); - target_ip->gid = tswap32(host_ip->gid); - target_ip->cuid = tswap32(host_ip->cuid); - target_ip->cgid = tswap32(host_ip->cgid); -#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC) - target_ip->mode = tswap32(host_ip->mode); -#else - target_ip->mode = tswap16(host_ip->mode); -#endif -#if defined(TARGET_PPC) - target_ip->__seq = tswap32(host_ip->__seq); -#else - target_ip->__seq = tswap16(host_ip->__seq); -#endif - unlock_user_struct(target_sd, target_addr, 1); - return 0; -} - -static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd, - abi_ulong target_addr) -{ - struct target_semid64_ds *target_sd; - - if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) - return -TARGET_EFAULT; - if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr)) - return -TARGET_EFAULT; - host_sd->sem_nsems = tswapal(target_sd->sem_nsems); - host_sd->sem_otime = tswapal(target_sd->sem_otime); - host_sd->sem_ctime = tswapal(target_sd->sem_ctime); - unlock_user_struct(target_sd, target_addr, 0); - return 0; -} - -static inline abi_long host_to_target_semid_ds(abi_ulong target_addr, - struct semid_ds *host_sd) -{ - struct target_semid64_ds *target_sd; - - if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) - return -TARGET_EFAULT; - if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm))) - return -TARGET_EFAULT; - target_sd->sem_nsems = tswapal(host_sd->sem_nsems); - target_sd->sem_otime = tswapal(host_sd->sem_otime); - target_sd->sem_ctime = tswapal(host_sd->sem_ctime); - unlock_user_struct(target_sd, target_addr, 1); - return 0; -} - -struct target_seminfo { - int semmap; - int semmni; - int semmns; - int semmnu; - int semmsl; - int semopm; - int semume; - int semusz; - int semvmx; - int semaem; -}; - -static inline abi_long host_to_target_seminfo(abi_ulong target_addr, - struct seminfo *host_seminfo) -{ - struct target_seminfo *target_seminfo; - if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0)) - return -TARGET_EFAULT; - __put_user(host_seminfo->semmap, &target_seminfo->semmap); - __put_user(host_seminfo->semmni, &target_seminfo->semmni); - __put_user(host_seminfo->semmns, &target_seminfo->semmns); - __put_user(host_seminfo->semmnu, &target_seminfo->semmnu); - __put_user(host_seminfo->semmsl, &target_seminfo->semmsl); - __put_user(host_seminfo->semopm, &target_seminfo->semopm); - __put_user(host_seminfo->semume, &target_seminfo->semume); - __put_user(host_seminfo->semusz, &target_seminfo->semusz); - __put_user(host_seminfo->semvmx, &target_seminfo->semvmx); - __put_user(host_seminfo->semaem, &target_seminfo->semaem); - unlock_user_struct(target_seminfo, target_addr, 1); - return 0; -} - -union semun { - int val; - struct semid_ds *buf; - unsigned short *array; - struct seminfo *__buf; -}; - -union target_semun { - int val; - abi_ulong buf; - abi_ulong array; - abi_ulong __buf; -}; - -static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array, - abi_ulong target_addr) -{ - int nsems; - unsigned short *array; - union semun semun; - struct semid_ds semid_ds; - int i, ret; - - semun.buf = &semid_ds; - - ret = semctl(semid, 0, IPC_STAT, semun); - if (ret == -1) - return get_errno(ret); - - nsems = semid_ds.sem_nsems; - - *host_array = g_try_new(unsigned short, nsems); - if (!*host_array) { - return -TARGET_ENOMEM; - } - array = lock_user(VERIFY_READ, target_addr, - nsems*sizeof(unsigned short), 1); - if (!array) { - g_free(*host_array); - return -TARGET_EFAULT; - } - - for(i=0; imsg_perm),target_addr)) - return -TARGET_EFAULT; - host_md->msg_stime = tswapal(target_md->msg_stime); - host_md->msg_rtime = tswapal(target_md->msg_rtime); - host_md->msg_ctime = tswapal(target_md->msg_ctime); - host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes); - host_md->msg_qnum = tswapal(target_md->msg_qnum); - host_md->msg_qbytes = tswapal(target_md->msg_qbytes); - host_md->msg_lspid = tswapal(target_md->msg_lspid); - host_md->msg_lrpid = tswapal(target_md->msg_lrpid); - unlock_user_struct(target_md, target_addr, 0); - return 0; -} - -static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr, - struct msqid_ds *host_md) -{ - struct target_msqid_ds *target_md; - - if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) - return -TARGET_EFAULT; - if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm))) - return -TARGET_EFAULT; - target_md->msg_stime = tswapal(host_md->msg_stime); - target_md->msg_rtime = tswapal(host_md->msg_rtime); - target_md->msg_ctime = tswapal(host_md->msg_ctime); - target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes); - target_md->msg_qnum = tswapal(host_md->msg_qnum); - target_md->msg_qbytes = tswapal(host_md->msg_qbytes); - target_md->msg_lspid = tswapal(host_md->msg_lspid); - target_md->msg_lrpid = tswapal(host_md->msg_lrpid); - unlock_user_struct(target_md, target_addr, 1); - return 0; -} - -struct target_msginfo { - int msgpool; - int msgmap; - int msgmax; - int msgmnb; - int msgmni; - int msgssz; - int msgtql; - unsigned short int msgseg; -}; - -static inline abi_long host_to_target_msginfo(abi_ulong target_addr, - struct msginfo *host_msginfo) -{ - struct target_msginfo *target_msginfo; - if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0)) - return -TARGET_EFAULT; - __put_user(host_msginfo->msgpool, &target_msginfo->msgpool); - __put_user(host_msginfo->msgmap, &target_msginfo->msgmap); - __put_user(host_msginfo->msgmax, &target_msginfo->msgmax); - __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb); - __put_user(host_msginfo->msgmni, &target_msginfo->msgmni); - __put_user(host_msginfo->msgssz, &target_msginfo->msgssz); - __put_user(host_msginfo->msgtql, &target_msginfo->msgtql); - __put_user(host_msginfo->msgseg, &target_msginfo->msgseg); - unlock_user_struct(target_msginfo, target_addr, 1); - return 0; -} - -static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr) -{ - struct msqid_ds dsarg; - struct msginfo msginfo; - abi_long ret = -TARGET_EINVAL; - - cmd &= 0xff; - - switch (cmd) { - case IPC_STAT: - case IPC_SET: - case MSG_STAT: - if (target_to_host_msqid_ds(&dsarg,ptr)) - return -TARGET_EFAULT; - ret = get_errno(msgctl(msgid, cmd, &dsarg)); - if (host_to_target_msqid_ds(ptr,&dsarg)) - return -TARGET_EFAULT; - break; - case IPC_RMID: - ret = get_errno(msgctl(msgid, cmd, NULL)); - break; - case IPC_INFO: - case MSG_INFO: - ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo)); - if (host_to_target_msginfo(ptr, &msginfo)) - return -TARGET_EFAULT; - break; - } - - return ret; -} - -struct target_msgbuf { - abi_long mtype; - char mtext[1]; -}; - -static inline abi_long do_msgsnd(int msqid, abi_long msgp, - ssize_t msgsz, int msgflg) -{ - struct target_msgbuf *target_mb; - struct msgbuf *host_mb; - abi_long ret = 0; - - if (msgsz < 0) { - return -TARGET_EINVAL; - } - - if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) - return -TARGET_EFAULT; - host_mb = g_try_malloc(msgsz + sizeof(long)); - if (!host_mb) { - unlock_user_struct(target_mb, msgp, 0); - return -TARGET_ENOMEM; - } - host_mb->mtype = (abi_long) tswapal(target_mb->mtype); - memcpy(host_mb->mtext, target_mb->mtext, msgsz); - ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg)); - g_free(host_mb); - unlock_user_struct(target_mb, msgp, 0); - - return ret; -} - -static inline abi_long do_msgrcv(int msqid, abi_long msgp, - ssize_t msgsz, abi_long msgtyp, - int msgflg) -{ - struct target_msgbuf *target_mb; - char *target_mtext; - struct msgbuf *host_mb; - abi_long ret = 0; - - if (msgsz < 0) { - return -TARGET_EINVAL; - } - - if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) - return -TARGET_EFAULT; - - host_mb = g_try_malloc(msgsz + sizeof(long)); - if (!host_mb) { - ret = -TARGET_ENOMEM; - goto end; - } - ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg)); - - if (ret > 0) { - abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); - target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0); - if (!target_mtext) { - ret = -TARGET_EFAULT; - goto end; - } - memcpy(target_mb->mtext, host_mb->mtext, ret); - unlock_user(target_mtext, target_mtext_addr, ret); - } - - target_mb->mtype = tswapal(host_mb->mtype); - -end: - if (target_mb) - unlock_user_struct(target_mb, msgp, 1); - g_free(host_mb); - return ret; -} - -static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd, - abi_ulong target_addr) -{ - struct target_shmid_ds *target_sd; - - if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) - return -TARGET_EFAULT; - if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr)) - return -TARGET_EFAULT; - __get_user(host_sd->shm_segsz, &target_sd->shm_segsz); - __get_user(host_sd->shm_atime, &target_sd->shm_atime); - __get_user(host_sd->shm_dtime, &target_sd->shm_dtime); - __get_user(host_sd->shm_ctime, &target_sd->shm_ctime); - __get_user(host_sd->shm_cpid, &target_sd->shm_cpid); - __get_user(host_sd->shm_lpid, &target_sd->shm_lpid); - __get_user(host_sd->shm_nattch, &target_sd->shm_nattch); - unlock_user_struct(target_sd, target_addr, 0); - return 0; -} - -static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr, - struct shmid_ds *host_sd) -{ - struct target_shmid_ds *target_sd; - - if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) - return -TARGET_EFAULT; - if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm))) - return -TARGET_EFAULT; - __put_user(host_sd->shm_segsz, &target_sd->shm_segsz); - __put_user(host_sd->shm_atime, &target_sd->shm_atime); - __put_user(host_sd->shm_dtime, &target_sd->shm_dtime); - __put_user(host_sd->shm_ctime, &target_sd->shm_ctime); - __put_user(host_sd->shm_cpid, &target_sd->shm_cpid); - __put_user(host_sd->shm_lpid, &target_sd->shm_lpid); - __put_user(host_sd->shm_nattch, &target_sd->shm_nattch); - unlock_user_struct(target_sd, target_addr, 1); - return 0; -} - -struct target_shminfo { - abi_ulong shmmax; - abi_ulong shmmin; - abi_ulong shmmni; - abi_ulong shmseg; - abi_ulong shmall; -}; - -static inline abi_long host_to_target_shminfo(abi_ulong target_addr, - struct shminfo *host_shminfo) -{ - struct target_shminfo *target_shminfo; - if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0)) - return -TARGET_EFAULT; - __put_user(host_shminfo->shmmax, &target_shminfo->shmmax); - __put_user(host_shminfo->shmmin, &target_shminfo->shmmin); - __put_user(host_shminfo->shmmni, &target_shminfo->shmmni); - __put_user(host_shminfo->shmseg, &target_shminfo->shmseg); - __put_user(host_shminfo->shmall, &target_shminfo->shmall); - unlock_user_struct(target_shminfo, target_addr, 1); - return 0; -} - -struct target_shm_info { - int used_ids; - abi_ulong shm_tot; - abi_ulong shm_rss; - abi_ulong shm_swp; - abi_ulong swap_attempts; - abi_ulong swap_successes; -}; - -static inline abi_long host_to_target_shm_info(abi_ulong target_addr, - struct shm_info *host_shm_info) -{ - struct target_shm_info *target_shm_info; - if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0)) - return -TARGET_EFAULT; - __put_user(host_shm_info->used_ids, &target_shm_info->used_ids); - __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot); - __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss); - __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp); - __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts); - __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes); - unlock_user_struct(target_shm_info, target_addr, 1); - return 0; -} - -static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf) -{ - struct shmid_ds dsarg; - struct shminfo shminfo; - struct shm_info shm_info; - abi_long ret = -TARGET_EINVAL; - - cmd &= 0xff; - - switch(cmd) { - case IPC_STAT: - case IPC_SET: - case SHM_STAT: - if (target_to_host_shmid_ds(&dsarg, buf)) - return -TARGET_EFAULT; - ret = get_errno(shmctl(shmid, cmd, &dsarg)); - if (host_to_target_shmid_ds(buf, &dsarg)) - return -TARGET_EFAULT; - break; - case IPC_INFO: - ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo)); - if (host_to_target_shminfo(buf, &shminfo)) - return -TARGET_EFAULT; - break; - case SHM_INFO: - ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info)); - if (host_to_target_shm_info(buf, &shm_info)) - return -TARGET_EFAULT; - break; - case IPC_RMID: - case SHM_LOCK: - case SHM_UNLOCK: - ret = get_errno(shmctl(shmid, cmd, NULL)); - break; - } - - return ret; -} - -#ifndef TARGET_FORCE_SHMLBA -/* For most architectures, SHMLBA is the same as the page size; - * some architectures have larger values, in which case they should - * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function. - * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA - * and defining its own value for SHMLBA. - * - * The kernel also permits SHMLBA to be set by the architecture to a - * value larger than the page size without setting __ARCH_FORCE_SHMLBA; - * this means that addresses are rounded to the large size if - * SHM_RND is set but addresses not aligned to that size are not rejected - * as long as they are at least page-aligned. Since the only architecture - * which uses this is ia64 this code doesn't provide for that oddity. - */ -static inline abi_ulong target_shmlba(CPUArchState *cpu_env) -{ - return TARGET_PAGE_SIZE; -} -#endif - -static inline abi_ulong do_shmat(CPUArchState *cpu_env, - int shmid, abi_ulong shmaddr, int shmflg) -{ - abi_long raddr; - void *host_raddr; - struct shmid_ds shm_info; - int i,ret; - abi_ulong shmlba; - - /* find out the length of the shared memory segment */ - ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info)); - if (is_error(ret)) { - /* can't get length, bail out */ - return ret; - } - - shmlba = target_shmlba(cpu_env); - - if (shmaddr & (shmlba - 1)) { - if (shmflg & SHM_RND) { - shmaddr &= ~(shmlba - 1); - } else { - return -TARGET_EINVAL; - } - } - if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) { - return -TARGET_EINVAL; - } - - mmap_lock(); - - if (shmaddr) - host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg); - else { - abi_ulong mmap_start; - - mmap_start = mmap_find_vma(0, shm_info.shm_segsz); - - if (mmap_start == -1) { - errno = ENOMEM; - host_raddr = (void *)-1; - } else - host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP); - } - - if (host_raddr == (void *)-1) { - mmap_unlock(); - return get_errno((long)host_raddr); - } - raddr=h2g((unsigned long)host_raddr); - - page_set_flags(raddr, raddr + shm_info.shm_segsz, - PAGE_VALID | PAGE_READ | - ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE)); - - for (i = 0; i < N_SHM_REGIONS; i++) { - if (!shm_regions[i].in_use) { - shm_regions[i].in_use = true; - shm_regions[i].start = raddr; - shm_regions[i].size = shm_info.shm_segsz; - break; - } - } - - mmap_unlock(); - return raddr; - -} - -static inline abi_long do_shmdt(abi_ulong shmaddr) -{ - int i; - abi_long rv; - - mmap_lock(); - - for (i = 0; i < N_SHM_REGIONS; ++i) { - if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) { - shm_regions[i].in_use = false; - page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0); - break; - } - } - rv = get_errno(shmdt(g2h(shmaddr))); - - mmap_unlock(); - - return rv; -} - -#ifdef TARGET_NR_ipc -/* ??? This only works with linear mappings. */ -/* do_ipc() must return target values and target errnos. */ -static abi_long do_ipc(CPUArchState *cpu_env, - unsigned int call, abi_long first, - abi_long second, abi_long third, - abi_long ptr, abi_long fifth) -{ - int version; - abi_long ret = 0; - - version = call >> 16; - call &= 0xffff; - - switch (call) { - case IPCOP_semop: - ret = do_semop(first, ptr, second); - break; - - case IPCOP_semget: - ret = get_errno(semget(first, second, third)); - break; - - case IPCOP_semctl: { - /* The semun argument to semctl is passed by value, so dereference the - * ptr argument. */ - abi_ulong atptr; - get_user_ual(atptr, ptr); - ret = do_semctl(first, second, third, atptr); - break; - } - - case IPCOP_msgget: - ret = get_errno(msgget(first, second)); - break; - - case IPCOP_msgsnd: - ret = do_msgsnd(first, ptr, second, third); - break; - - case IPCOP_msgctl: - ret = do_msgctl(first, second, ptr); - break; - - case IPCOP_msgrcv: - switch (version) { - case 0: - { - struct target_ipc_kludge { - abi_long msgp; - abi_long msgtyp; - } *tmp; - - if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) { - ret = -TARGET_EFAULT; - break; - } - - ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third); - - unlock_user_struct(tmp, ptr, 0); - break; - } - default: - ret = do_msgrcv(first, ptr, second, fifth, third); - } - break; - - case IPCOP_shmat: - switch (version) { - default: - { - abi_ulong raddr; - raddr = do_shmat(cpu_env, first, ptr, second); - if (is_error(raddr)) - return get_errno(raddr); - if (put_user_ual(raddr, third)) - return -TARGET_EFAULT; - break; - } - case 1: - ret = -TARGET_EINVAL; - break; - } - break; - case IPCOP_shmdt: - ret = do_shmdt(ptr); - break; - - case IPCOP_shmget: - /* IPC_* flag values are the same on all linux platforms */ - ret = get_errno(shmget(first, second, third)); - break; - - /* IPC_* and SHM_* command values are the same on all linux platforms */ - case IPCOP_shmctl: - ret = do_shmctl(first, second, ptr); - break; - default: - gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); - ret = -TARGET_ENOSYS; - break; - } - return ret; -} -#endif - /* kernel structure types definitions */ #define STRUCT(name, ...) STRUCT_ ## name, @@ -8395,54 +7474,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } } return ret; -#ifdef TARGET_NR_ipc - case TARGET_NR_ipc: - return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); -#endif -#ifdef TARGET_NR_semget - case TARGET_NR_semget: - return get_errno(semget(arg1, arg2, arg3)); -#endif -#ifdef TARGET_NR_semop - case TARGET_NR_semop: - return do_semop(arg1, arg2, arg3); -#endif -#ifdef TARGET_NR_semctl - case TARGET_NR_semctl: - return do_semctl(arg1, arg2, arg3, arg4); -#endif -#ifdef TARGET_NR_msgctl - case TARGET_NR_msgctl: - return do_msgctl(arg1, arg2, arg3); -#endif -#ifdef TARGET_NR_msgget - case TARGET_NR_msgget: - return get_errno(msgget(arg1, arg2)); -#endif -#ifdef TARGET_NR_msgrcv - case TARGET_NR_msgrcv: - return do_msgrcv(arg1, arg2, arg3, arg4, arg5); -#endif -#ifdef TARGET_NR_msgsnd - case TARGET_NR_msgsnd: - return do_msgsnd(arg1, arg2, arg3, arg4); -#endif -#ifdef TARGET_NR_shmget - case TARGET_NR_shmget: - return get_errno(shmget(arg1, arg2, arg3)); -#endif -#ifdef TARGET_NR_shmctl - case TARGET_NR_shmctl: - return do_shmctl(arg1, arg2, arg3); -#endif -#ifdef TARGET_NR_shmat - case TARGET_NR_shmat: - return do_shmat(cpu_env, arg1, arg2, arg3); -#endif -#ifdef TARGET_NR_shmdt - case TARGET_NR_shmdt: - return do_shmdt(arg1); -#endif case TARGET_NR_fsync: return get_errno(fsync(arg1)); case TARGET_NR_clone: @@ -10969,6 +10000,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, int64_t arg5, int64_t arg6) #include "syscall-file.inc.c" +#include "syscall-ipc.inc.c" #undef SYSCALL_IMPL #undef SYSCALL_ARGS @@ -11002,6 +10034,7 @@ static const SyscallDef * __attribute__((noinline)) syscall_table(int num) #define SYSCALL_DEF(NAME, ...) case TARGET_NR_##NAME: return &def_##NAME #define SYSCALL_DEF_ARGS(NAME, ...) SYSCALL_DEF(NAME) #define SYSCALL_DEF_FULL(NAME, ...) SYSCALL_DEF(NAME) +#define SYSCALL_TABLE switch (num) { #include "syscall-defs.h" @@ -11011,6 +10044,7 @@ static const SyscallDef * __attribute__((noinline)) syscall_table(int num) #undef SYSCALL_DEF #undef SYSCALL_DEF_ARGS #undef SYSCALL_DEF_FULL +#undef SYSCALL_TABLE } abi_long do_syscall(void *cpu_env, int num, abi_long arg1, diff --git a/linux-user/strace.list b/linux-user/strace.list index 26ad95dc7e..15dc0e9087 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -452,9 +452,6 @@ #ifdef TARGET_NR_io_submit { TARGET_NR_io_submit, "io_submit" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_ipc -{ TARGET_NR_ipc, "ipc" , NULL, print_ipc, NULL }, -#endif #ifdef TARGET_NR_kcmp { TARGET_NR_kcmp, "kcmp" , NULL, NULL, NULL }, #endif @@ -608,18 +605,6 @@ #ifdef TARGET_NR_mremap { TARGET_NR_mremap, "mremap" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_msgctl -{ TARGET_NR_msgctl, "msgctl" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_msgget -{ TARGET_NR_msgget, "msgget" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_msgrcv -{ TARGET_NR_msgrcv, "msgrcv" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_msgsnd -{ TARGET_NR_msgsnd, "msgsnd" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_msync { TARGET_NR_msync, "msync" , NULL, NULL, NULL }, #endif @@ -917,9 +902,6 @@ #ifdef TARGET_NR_osf_settimeofday { TARGET_NR_osf_settimeofday, "osf_settimeofday" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_osf_shmat -{ TARGET_NR_osf_shmat, "osf_shmat" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_osf_signal { TARGET_NR_osf_signal, "osf_signal" , NULL, NULL, NULL }, #endif @@ -1184,18 +1166,6 @@ #ifdef TARGET_NR_select { TARGET_NR_select, "select" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_semctl -{ TARGET_NR_semctl, "semctl" , NULL, print_semctl, NULL }, -#endif -#ifdef TARGET_NR_semget -{ TARGET_NR_semget, "semget" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_semop -{ TARGET_NR_semop, "semop" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_semtimedop -{ TARGET_NR_semtimedop, "semtimedop" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_send { TARGET_NR_send, "send" , NULL, NULL, NULL }, #endif @@ -1323,18 +1293,6 @@ #ifdef TARGET_NR_sgetmask { TARGET_NR_sgetmask, "sgetmask" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_shmat -{ TARGET_NR_shmat, "shmat" , NULL, NULL, print_syscall_ret_addr }, -#endif -#ifdef TARGET_NR_shmctl -{ TARGET_NR_shmctl, "shmctl" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_shmdt -{ TARGET_NR_shmdt, "shmdt" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_shmget -{ TARGET_NR_shmget, "shmget" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_shutdown { TARGET_NR_shutdown, "shutdown" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027770 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="J/m6G+T7"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDxS21Kvz9s9G for ; Sat, 19 Jan 2019 08:44:44 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbwM-0006iN-CN for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:44:38 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55905) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkE-000530-Sb for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkC-0004TA-Qw for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:06 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:34618) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkC-0004SU-Ir for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:04 -0500 Received: by mail-pf1-x441.google.com with SMTP id h3so7218223pfg.1 for ; Fri, 18 Jan 2019 13:32:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jKzWWGb2MbALIY3t6MisuVI/wq08UtEaX91zei22CBE=; b=J/m6G+T76O8/nluB6FMJeKVJCSPOCBo7gHCvG3bhXU2PsQks5FTQKFWKNJxSqEdWpq 2N3sj+4pJMYvGoqmd3+q3tVE8dEzYnsVTBKN0uhlURYYkV+GnmEzbApRWoeCTVHuX7Ai J1135yDSQKPh0V4gEa9ibITUuMUnHC+XbzxtA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jKzWWGb2MbALIY3t6MisuVI/wq08UtEaX91zei22CBE=; b=izDAngqXqNhEZvwzmcrz6SFE8VfZ1nXbxOrh2/IyxFsXbJBrgBCMlulwT4eTuz5Jp6 NCVXL2FbxVwuMXUZcfH9ycMsVEZxxzUwVAFv0Ns3IGOCachrbaAS9+xPGXPaQaYD0YsW OXz35VDCZ7wMo7ymuGA3W1RPDv01z6vuPktHsq4G5yWs3R13QMeB5lTEajb2SV0fKds6 tPC1qwvWKFnwJDmOXQm5AhFQztAzFE9J9Q0JOq5P8hhKoSNUBXw4omZmHWgA9GcuCFxd W2+uqVIc8A+H9Vnq+K752iLmMMHGDfa2EKe3TAKgH54/C4Ieruxf/0ObabTcOeV73Yf1 T6SQ== X-Gm-Message-State: AJcUukd4+2hAV85Xpj6hYbIRvsxd0WzMsdw/RLGq1Uhxd7Sy49s/tGET S7Pj/3rcPfbKmorTUtIUcED7jt03Gbc= X-Google-Smtp-Source: ALg8bN6RftUC//PDT68FPPH/foi7RY7dFwCpu+DMJfgOrvMjnL1bFvd9U1D48AnLUF9aIY+DC+uHbw== X-Received: by 2002:a65:6148:: with SMTP id o8mr19351219pgv.451.1547847123117; Fri, 18 Jan 2019 13:32:03 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:02 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:48 +1100 Message-Id: <20190118213122.22865-15-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 15/49] linux-user: Split out memory syscalls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes mmap, mmap2, munmap, mlock, mlockall, munlock, munlockall, mprotect, mremap, msync. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 24 ++++++ linux-user/syscall.h | 2 + linux-user/strace.c | 55 ++----------- linux-user/syscall-mem.inc.c | 154 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 119 +-------------------------- linux-user/strace.list | 33 -------- 6 files changed, 189 insertions(+), 198 deletions(-) create mode 100644 linux-user/syscall-mem.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 6d6349da01..88f433e998 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -20,6 +20,26 @@ SYSCALL_DEF(close, ARG_DEC); #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif +SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC); +SYSCALL_DEF(mlockall, ARG_HEX); +#ifdef TARGET_NR_mmap +SYSCALL_DEF_FULL(mmap, .impl = impl_mmap, + .args = args_mmap, + .print_ret = print_syscall_ptr_ret, + .arg_type = { ARG_PTR, ARG_DEC, ARG_MMAPPROT, + ARG_MMAPFLAG, ARG_DEC, ARG_DEC }); +#endif +#ifdef TARGET_NR_mmap2 +SYSCALL_DEF_FULL(mmap2, .impl = impl_mmap, + .args = args_mmap2, + .print_ret = print_syscall_ptr_ret, + .arg_type = { ARG_PTR, ARG_DEC, ARG_MMAPPROT, + ARG_MMAPFLAG, ARG_DEC, ARG_DEC64 }); +#endif +SYSCALL_DEF(mprotect, ARG_PTR, ARG_DEC, ARG_MMAPPROT); +SYSCALL_DEF_FULL(mremap, .impl = impl_mremap, + .print_ret = print_syscall_ptr_ret, + .arg_type = { ARG_PTR, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR }); #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgctl) SYSCALL_DEF(msgctl, ARG_DEC, ARG_DEC, ARG_PTR); #endif @@ -32,6 +52,10 @@ SYSCALL_DEF(msgrcv, ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC, ARG_HEX); #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_msgsnd) SYSCALL_DEF(msgsnd, ARG_DEC, ARG_PTR, ARG_DEC, ARG_HEX); #endif +SYSCALL_DEF(msync, ARG_PTR, ARG_DEC, ARG_HEX); +SYSCALL_DEF(munlock, ARG_PTR, ARG_DEC); +SYSCALL_DEF(munlockall); +SYSCALL_DEF(munmap, ARG_PTR, ARG_DEC); SYSCALL_DEF(name_to_handle_at, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); #ifdef TARGET_NR_open diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 83f602f8e7..8175de4c31 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -58,6 +58,8 @@ typedef enum { /* These print as sets of flags. */ ARG_ATDIRFD, ARG_ATFLAG, + ARG_MMAPFLAG, + ARG_MMAPPROT, ARG_MODEFLAG, ARG_OPENFLAG, diff --git a/linux-user/strace.c b/linux-user/strace.c index 3233230527..5619defec8 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -801,7 +801,7 @@ UNUSED static struct flags umount2_flags[] = { FLAG_END, }; -UNUSED static struct flags mmap_prot_flags[] = { +static struct flags const mmap_prot_flags[] = { FLAG_GENERIC(PROT_NONE), FLAG_GENERIC(PROT_EXEC), FLAG_GENERIC(PROT_READ), @@ -812,7 +812,7 @@ UNUSED static struct flags mmap_prot_flags[] = { FLAG_END, }; -UNUSED static struct flags mmap_flags[] = { +static struct flags const mmap_flags[] = { FLAG_TARGET(MAP_SHARED), FLAG_TARGET(MAP_PRIVATE), FLAG_TARGET(MAP_ANONYMOUS), @@ -2350,51 +2350,6 @@ print_utimensat(const struct syscallname *name, } #endif -#if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2) -static void -print_mmap(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_pointer(arg0, 0); - print_raw_param("%d", arg1, 0); - print_flags(mmap_prot_flags, arg2, 0); - print_flags(mmap_flags, arg3, 0); - print_raw_param("%d", arg4, 0); - print_raw_param("%#x", arg5, 1); - print_syscall_epilogue(name); -} -#define print_mmap2 print_mmap -#endif - -#ifdef TARGET_NR_mprotect -static void -print_mprotect(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_pointer(arg0, 0); - print_raw_param("%d", arg1, 0); - print_flags(mmap_prot_flags, arg2, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_munmap -static void -print_munmap(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_pointer(arg0, 0); - print_raw_param("%d", arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_futex static void print_futex_op(abi_long tflag, int last) { @@ -2601,6 +2556,12 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_ATFLAG: len = add_flags(b, rest, at_file_flags, arg, false); break; + case ARG_MMAPFLAG: + len = add_flags(b, rest, mmap_flags, arg, false); + break; + case ARG_MMAPPROT: + len = add_flags(b, rest, mmap_prot_flags, arg, false); + break; case ARG_MODEFLAG: len = add_flags(b, rest, mode_flags, arg, true); break; diff --git a/linux-user/syscall-mem.inc.c b/linux-user/syscall-mem.inc.c new file mode 100644 index 0000000000..d2ce0cb8cc --- /dev/null +++ b/linux-user/syscall-mem.inc.c @@ -0,0 +1,154 @@ +/* + * Linux memory-related syscalls + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +static bitmask_transtbl const mmap_flags_tbl[] = { + { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED }, + { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE }, + { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED }, + { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, + MAP_ANONYMOUS, MAP_ANONYMOUS }, + { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, + MAP_GROWSDOWN, MAP_GROWSDOWN }, + { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, + MAP_DENYWRITE, MAP_DENYWRITE }, + { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, + MAP_EXECUTABLE, MAP_EXECUTABLE }, + { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED }, + { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, + MAP_NORESERVE, MAP_NORESERVE }, + { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB }, + /* + * MAP_STACK had been ignored by the kernel for quite some time. + * Recognize it for the target insofar as we do not want to pass + * it through to the host. + */ + { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 }, + { 0, 0, 0, 0 } +}; + + +SYSCALL_IMPL(mlock) +{ + return get_errno(mlock(g2h(arg1), arg2)); +} + +SYSCALL_IMPL(mlockall) +{ + int host_flag = 0; + if (arg1 & TARGET_MLOCKALL_MCL_CURRENT) { + host_flag |= MCL_CURRENT; + } + if (arg1 & TARGET_MLOCKALL_MCL_FUTURE) { + host_flag |= MCL_FUTURE; + } + return get_errno(mlockall(host_flag)); +} + +#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \ + (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \ + defined(TARGET_M68K) || defined(TARGET_CRIS) || \ + defined(TARGET_MICROBLAZE) || defined(TARGET_S390X) +SYSCALL_ARGS(mmap) +{ + abi_ulong ptr = in[0]; + abi_long *v = lock_user(VERIFY_READ, ptr, 6 * sizeof(abi_long), 1); + if (v == NULL) { + errno = EFAULT; + return NULL; + } + out[0] = tswapal(v[0]); + out[1] = tswapal(v[1]); + out[2] = tswapal(v[2]); + out[3] = tswapal(v[3]); + out[4] = tswapal(v[4]); + out[5] = tswapal(v[5]); + unlock_user(v, ptr, 0); + return def; +} +#else +# define args_mmap NULL +#endif + +SYSCALL_IMPL(mmap) +{ + int host_flags = target_to_host_bitmask(arg4, mmap_flags_tbl); + return get_errno(target_mmap(arg1, arg2, arg3, host_flags, arg5, arg6)); +} + +#ifdef TARGET_NR_mmap2 +/* + * Define mmap2 in terms of mmap. + * !!! Note that there is a fundamental problem here in that + * target_mmap has an offset parameter that is abi_ulong + * and not off_t. This means that we cannot actually pass + * through a 64-bit file offset as intended. + */ + +#ifndef MMAP_SHIFT +# define MMAP_SHIFT 12 +#endif + +SYSCALL_ARGS(mmap2) +{ + /* We have already assigned out[0-4]. */ + out[5] = (uint64_t)(abi_ulong)in[5] << MMAP_SHIFT; + return def; +} +#endif + +SYSCALL_IMPL(mprotect) +{ + CPUState *cpu = ENV_GET_CPU(cpu_env); + TaskState *ts = cpu->opaque; + + /* Special hack to detect libc making the stack executable. */ + if ((arg3 & PROT_GROWSDOWN) + && arg1 >= ts->info->stack_limit + && arg1 <= ts->info->start_stack) { + arg3 &= ~PROT_GROWSDOWN; + arg2 = arg2 + arg1 - ts->info->stack_limit; + arg1 = ts->info->stack_limit; + } + return get_errno(target_mprotect(arg1, arg2, arg3)); +} + +SYSCALL_IMPL(mremap) +{ + return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); +} + +SYSCALL_IMPL(msync) +{ + return get_errno(msync(g2h(arg1), arg2, arg3)); +} + +SYSCALL_IMPL(munlock) +{ + return get_errno(munlock(g2h(arg1), arg2)); +} + +SYSCALL_IMPL(munlockall) +{ + return get_errno(munlockall()); +} + +SYSCALL_IMPL(munmap) +{ + return get_errno(target_munmap(arg1, arg2)); +} diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ad5ccbefdb..142654a0a0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4130,29 +4130,6 @@ static const StructEntry struct_termios_def = { .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) }, }; -static bitmask_transtbl mmap_flags_tbl[] = { - { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED }, - { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE }, - { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED }, - { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, - MAP_ANONYMOUS, MAP_ANONYMOUS }, - { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, - MAP_GROWSDOWN, MAP_GROWSDOWN }, - { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, - MAP_DENYWRITE, MAP_DENYWRITE }, - { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, - MAP_EXECUTABLE, MAP_EXECUTABLE }, - { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED }, - { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, - MAP_NORESERVE, MAP_NORESERVE }, - { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB }, - /* MAP_STACK had been ignored by the kernel for quite some time. - Recognize it for the target insofar as we do not want to pass - it through to the host. */ - { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 }, - { 0, 0, 0, 0 } -}; - #if defined(TARGET_I386) /* NOTE: there is really one LDT for all the threads */ @@ -5373,21 +5350,6 @@ static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp, return 0; } -#if defined(TARGET_NR_mlockall) -static inline int target_to_host_mlockall_arg(int arg) -{ - int result = 0; - - if (arg & TARGET_MLOCKALL_MCL_CURRENT) { - result |= MCL_CURRENT; - } - if (arg & TARGET_MLOCKALL_MCL_FUTURE) { - result |= MCL_FUTURE; - } - return result; -} -#endif - #if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) || \ defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) || \ defined(TARGET_NR_newfstatat)) @@ -6997,86 +6959,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, ret = get_errno(reboot(arg1, arg2, arg3, NULL)); } return ret; -#ifdef TARGET_NR_mmap - case TARGET_NR_mmap: -#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \ - (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \ - defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \ - || defined(TARGET_S390X) - { - abi_ulong *v; - abi_ulong v1, v2, v3, v4, v5, v6; - if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1))) - return -TARGET_EFAULT; - v1 = tswapal(v[0]); - v2 = tswapal(v[1]); - v3 = tswapal(v[2]); - v4 = tswapal(v[3]); - v5 = tswapal(v[4]); - v6 = tswapal(v[5]); - unlock_user(v, arg1, 0); - ret = get_errno(target_mmap(v1, v2, v3, - target_to_host_bitmask(v4, mmap_flags_tbl), - v5, v6)); - } -#else - ret = get_errno(target_mmap(arg1, arg2, arg3, - target_to_host_bitmask(arg4, mmap_flags_tbl), - arg5, - arg6)); -#endif - return ret; -#endif -#ifdef TARGET_NR_mmap2 - case TARGET_NR_mmap2: -#ifndef MMAP_SHIFT -#define MMAP_SHIFT 12 -#endif - ret = target_mmap(arg1, arg2, arg3, - target_to_host_bitmask(arg4, mmap_flags_tbl), - arg5, arg6 << MMAP_SHIFT); - return get_errno(ret); -#endif - case TARGET_NR_munmap: - return get_errno(target_munmap(arg1, arg2)); - case TARGET_NR_mprotect: - { - TaskState *ts = cpu->opaque; - /* Special hack to detect libc making the stack executable. */ - if ((arg3 & PROT_GROWSDOWN) - && arg1 >= ts->info->stack_limit - && arg1 <= ts->info->start_stack) { - arg3 &= ~PROT_GROWSDOWN; - arg2 = arg2 + arg1 - ts->info->stack_limit; - arg1 = ts->info->stack_limit; - } - } - return get_errno(target_mprotect(arg1, arg2, arg3)); -#ifdef TARGET_NR_mremap - case TARGET_NR_mremap: - return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); -#endif - /* ??? msync/mlock/munlock are broken for softmmu. */ -#ifdef TARGET_NR_msync - case TARGET_NR_msync: - return get_errno(msync(g2h(arg1), arg2, arg3)); -#endif -#ifdef TARGET_NR_mlock - case TARGET_NR_mlock: - return get_errno(mlock(g2h(arg1), arg2)); -#endif -#ifdef TARGET_NR_munlock - case TARGET_NR_munlock: - return get_errno(munlock(g2h(arg1), arg2)); -#endif -#ifdef TARGET_NR_mlockall - case TARGET_NR_mlockall: - return get_errno(mlockall(target_to_host_mlockall_arg(arg1))); -#endif -#ifdef TARGET_NR_munlockall - case TARGET_NR_munlockall: - return get_errno(munlockall()); -#endif #ifdef TARGET_NR_truncate case TARGET_NR_truncate: if (!(p = lock_user_string(arg1))) @@ -10001,6 +9883,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #include "syscall-file.inc.c" #include "syscall-ipc.inc.c" +#include "syscall-mem.inc.c" #undef SYSCALL_IMPL #undef SYSCALL_ARGS diff --git a/linux-user/strace.list b/linux-user/strace.list index 15dc0e9087..d0160f841f 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -554,21 +554,6 @@ #ifdef TARGET_NR_mknodat { TARGET_NR_mknodat, "mknodat" , NULL, print_mknodat, NULL }, #endif -#ifdef TARGET_NR_mlock -{ TARGET_NR_mlock, "mlock" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_mlock2 -{ TARGET_NR_mlock2, "mlock2" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_mlockall -{ TARGET_NR_mlockall, "mlockall" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_mmap -{ TARGET_NR_mmap, "mmap" , NULL, print_mmap, print_syscall_ret_addr }, -#endif -#ifdef TARGET_NR_mmap2 -{ TARGET_NR_mmap2, "mmap2" , NULL, print_mmap2, print_syscall_ret_addr }, -#endif #ifdef TARGET_NR_modify_ldt { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL }, #endif @@ -578,9 +563,6 @@ #ifdef TARGET_NR_move_pages { TARGET_NR_move_pages, "move_pages" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_mprotect -{ TARGET_NR_mprotect, "mprotect" , NULL, print_mprotect, NULL }, -#endif #ifdef TARGET_NR_mpx { TARGET_NR_mpx, "mpx" , NULL, NULL, NULL }, #endif @@ -602,24 +584,9 @@ #ifdef TARGET_NR_mq_unlink { TARGET_NR_mq_unlink, "mq_unlink" , NULL, print_mq_unlink, NULL }, #endif -#ifdef TARGET_NR_mremap -{ TARGET_NR_mremap, "mremap" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_msync -{ TARGET_NR_msync, "msync" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_multiplexer { TARGET_NR_multiplexer, "multiplexer" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_munlock -{ TARGET_NR_munlock, "munlock" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_munlockall -{ TARGET_NR_munlockall, "munlockall" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_munmap -{ TARGET_NR_munmap, "munmap" , NULL, print_munmap, NULL }, -#endif #ifdef TARGET_NR_nanosleep { TARGET_NR_nanosleep, "nanosleep" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Dw9pimRz"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDt33tflz9s9G for ; Sat, 19 Jan 2019 08:41:47 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47522 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbtZ-00048l-GL for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:41:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55911) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkF-00053A-Nh for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkE-0004W1-N4 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:07 -0500 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:44425) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkE-0004VE-HH for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:06 -0500 Received: by mail-pf1-x443.google.com with SMTP id u6so7187532pfh.11 for ; Fri, 18 Jan 2019 13:32:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IEs81U6tUCmwElYln5xMlJL31vkwoJDM0cxjxPoE4mA=; b=Dw9pimRzOCnCIj7bLqPuvsGtiN/9tg7qfN1Bq7d0FarjImv4mVIZamJ4zlNVR2soBW hmCMtbP3lRSRj4gFa0Y5ZcBDc2zouR8jOui67zMXobaMv+mMsD/0ArJXwwqCNGapzj5k euteBlCnbQElLZ8J+m6jCHlHgmKVwwnhrUvoY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IEs81U6tUCmwElYln5xMlJL31vkwoJDM0cxjxPoE4mA=; b=Uv7HJNC8gobSFh2/Kscwj5lgUyz/sOhQqmGF4xt2nzvEshrJgKWTXTuMRZ6FbHZvX2 CQpvMi+mJI130RSRHRW/LgbeWa6N8rp1N2p0jz98THugKzI5yzPHxv158UNYj3BeVOjG 5asz+2KhzjkAJskHjh3LzIiBHL0yCqIocSXXd+VdEyir7qbVcreP+Ku4CcR4C/7eEblT C2taJiF4J4IFLS2kl2pgojdUC3SB+sl1S+ZKgIC0tmUeo4uhJLAQHSLmX0QTRR/I4fTo tcnwx3FyJEz1L5biRWEl/3Bb7f0P5mbmmvFSZ9oqGvA4oKKEwtZwmC50mfQnjkJkhj/d QZnA== X-Gm-Message-State: AJcUukf4cD1mYGxodczdqK0j+f4zCCfjUWlDM686U/+UDh3fttQUSSxq 8MeV5ySapsflrWj1LpdswogqewoQ8mM= X-Google-Smtp-Source: ALg8bN7rdPMW0nm8hhI0KpDbDOSIMlCeUqRtYFmGOkAMw0A5TpRn3f208phoYHDYiH/WfsDPtG7QNA== X-Received: by 2002:a62:6408:: with SMTP id y8mr20802491pfb.202.1547847125269; Fri, 18 Jan 2019 13:32:05 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:04 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:49 +1100 Message-Id: <20190118213122.22865-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::443 Subject: [Qemu-devel] [PATCH v6 16/49] linux-user: Split out exit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall-proc.inc.c | 61 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 38 +--------------------- 3 files changed, 63 insertions(+), 37 deletions(-) create mode 100644 linux-user/syscall-proc.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 88f433e998..88aa1a6bfd 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -17,6 +17,7 @@ */ SYSCALL_DEF(close, ARG_DEC); +SYSCALL_DEF(exit, ARG_DEC); #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c new file mode 100644 index 0000000000..96ad363c1a --- /dev/null +++ b/linux-user/syscall-proc.inc.c @@ -0,0 +1,61 @@ +/* + * Linux process related syscalls + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +SYSCALL_IMPL(exit) +{ + CPUState *cpu = ENV_GET_CPU(cpu_env); + int status = arg1; + + /* + * In old applications this may be used to implement _exit(2). + * However in threaded applictions it is used for thread termination, + * and _exit_group is used for application termination. + * Do thread termination if we have more then one thread. + */ + if (block_signals()) { + return -TARGET_ERESTARTSYS; + } + + cpu_list_lock(); + + if (CPU_NEXT(first_cpu)) { + TaskState *ts; + + /* Remove the CPU from the list. */ + QTAILQ_REMOVE_RCU(&cpus, cpu, node); + + cpu_list_unlock(); + + ts = cpu->opaque; + if (ts->child_tidptr) { + put_user_u32(0, ts->child_tidptr); + sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, + NULL, NULL, 0); + } + thread_cpu = NULL; + object_unref(OBJECT(cpu)); + g_free(ts); + rcu_unregister_thread(); + pthread_exit(NULL); + } + + cpu_list_unlock(); + preexit_cleanup(cpu_env, status); + _exit(status); +} diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 142654a0a0..02010f9ae0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5626,43 +5626,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_exit: - /* In old applications this may be used to implement _exit(2). - However in threaded applictions it is used for thread termination, - and _exit_group is used for application termination. - Do thread termination if we have more then one thread. */ - - if (block_signals()) { - return -TARGET_ERESTARTSYS; - } - - cpu_list_lock(); - - if (CPU_NEXT(first_cpu)) { - TaskState *ts; - - /* Remove the CPU from the list. */ - QTAILQ_REMOVE_RCU(&cpus, cpu, node); - - cpu_list_unlock(); - - ts = cpu->opaque; - if (ts->child_tidptr) { - put_user_u32(0, ts->child_tidptr); - sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, - NULL, NULL, 0); - } - thread_cpu = NULL; - object_unref(OBJECT(cpu)); - g_free(ts); - rcu_unregister_thread(); - pthread_exit(NULL); - } - - cpu_list_unlock(); - preexit_cleanup(cpu_env, arg1); - _exit(arg1); - return 0; /* avoid warning */ case TARGET_NR_brk: return do_brk(arg1); #ifdef TARGET_NR_fork @@ -9884,6 +9847,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #include "syscall-file.inc.c" #include "syscall-ipc.inc.c" #include "syscall-mem.inc.c" +#include "syscall-proc.inc.c" #undef SYSCALL_IMPL #undef SYSCALL_ARGS From patchwork Fri Jan 18 21:30:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027759 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="j0aFwG1r"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDlD2CXgz9s9G for ; Sat, 19 Jan 2019 08:35:52 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbnq-0007cQ-6f for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:35:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55938) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkI-00053K-HE for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkH-0004Z3-3D for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:10 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:45027) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkG-0004XX-Qg for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:09 -0500 Received: by mail-pl1-x644.google.com with SMTP id e11so6872945plt.11 for ; Fri, 18 Jan 2019 13:32:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MwgCZGcEc5lQOM9B1e8no3PfGioWwuL5PT0O9ad7iHA=; b=j0aFwG1rXu9jPT1J0sdoZNvvl5qSzGCy6LNmvuAW9gV2W/qBmS3BLw6XoBEgFJgH1u 45HKkmOCuFnY1C9Wsm5fV9DnfDRQjGR4WInYY9S68eMIONJ5BgM/UYr8wmw8QwTgVnyZ hsHCOEBBJqQ0oEqhJwIDjsZs5obKae04qOhgw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MwgCZGcEc5lQOM9B1e8no3PfGioWwuL5PT0O9ad7iHA=; b=S+ZEu6on9/g04fLyVwMGc+eRvXyrm7+IFK9ljXETJxuMSzpMAqVKOIWS9lqcLJyFf3 N+WAhyaz58oERVGEs9l92u6L2gkloTDsIDAqopmmvDrY4eu+Xg7bp1FwQnWBDbrJdBo4 VocwohMCB1H3xt+boD4+/qLyWT9+iQa9rb8IetmZEPbaabcz/+Lnq09/C6g/3vQQtrzr mXehBuc+L8hnt2r/WlSpgHbxbfdvgeX2MRiOOI9jFJ2Inc0VZpiS5fCZOvJGfr+oCCIR 06mYl2ybCDEwbwHpRVsDLtZnEQo/Sqafq6Qsw2BeXdzwxfcjN54ev0TaSCwSeyIeywmM s9Hg== X-Gm-Message-State: AJcUukenvWLby2xzXcNzvN5LltnSmP9i0o3+kpuZN7eGLo5hLjCu2UTF wt9pIG4P7IcG7xWEHgYT+MR+iikicpI= X-Google-Smtp-Source: ALg8bN7mdhaDEAvmYmft3nnSU2c3/cHlHLk+rIQ6C0nwklbZgM1YSJs8KOR9CwVs62j9iKdhUuRJZA== X-Received: by 2002:a17:902:7402:: with SMTP id g2mr20212111pll.198.1547847127550; Fri, 18 Jan 2019 13:32:07 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:06 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:50 +1100 Message-Id: <20190118213122.22865-17-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 17/49] linux-user: Split out brk X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 3 ++ linux-user/strace.c | 35 -------------- linux-user/syscall-mem.inc.c | 90 ++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 93 ------------------------------------ linux-user/strace.list | 3 -- 5 files changed, 93 insertions(+), 131 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 88aa1a6bfd..c3ed22ff16 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -16,6 +16,9 @@ * along with this program; if not, see . */ +SYSCALL_DEF_FULL(brk, .impl = impl_brk, + .print_ret = print_syscall_ptr_ret, + .arg_type = { ARG_PTR }); SYSCALL_DEF(close, ARG_DEC); SYSCALL_DEF(exit, ARG_DEC); #ifdef TARGET_NR_ipc diff --git a/linux-user/strace.c b/linux-user/strace.c index 5619defec8..ba541432eb 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -604,29 +604,6 @@ print_execve(const struct syscallname *name, * Variants for the return value output function */ -static void -print_syscall_ret_addr(const struct syscallname *name, abi_long ret) -{ - const char *errstr = NULL; - - if (ret < 0) { - errstr = target_strerror(-ret); - } - if (errstr) { - gemu_log(" = -1 errno=%d (%s)\n", (int)-ret, errstr); - } else { - gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret); - } -} - -#if 0 /* currently unused */ -static void -print_syscall_ret_raw(struct syscallname *name, abi_long ret) -{ - gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret); -} -#endif - #ifdef TARGET_NR__newselect static void print_syscall_ret_newselect(const struct syscallname *name, abi_long ret) @@ -1168,18 +1145,6 @@ print_access(const struct syscallname *name, } #endif -#ifdef TARGET_NR_brk -static void -print_brk(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_pointer(arg0, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_chdir static void print_chdir(const struct syscallname *name, diff --git a/linux-user/syscall-mem.inc.c b/linux-user/syscall-mem.inc.c index d2ce0cb8cc..17ba8e3d97 100644 --- a/linux-user/syscall-mem.inc.c +++ b/linux-user/syscall-mem.inc.c @@ -42,6 +42,96 @@ static bitmask_transtbl const mmap_flags_tbl[] = { { 0, 0, 0, 0 } }; +static abi_ulong target_brk; +static abi_ulong target_original_brk; +static abi_ulong brk_page; + +void target_set_brk(abi_ulong new_brk) +{ + target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); + brk_page = HOST_PAGE_ALIGN(target_brk); +} + +/* do_brk() must return target values and target errnos. */ +abi_long do_brk(abi_ulong new_brk) +{ + abi_long mapped_addr; + abi_ulong new_alloc_size; + + if (!new_brk) { + return target_brk; + } + if (new_brk < target_original_brk) { + return target_brk; + } + + /* + * If the new brk is less than the highest page reserved to the + * target heap allocation, set it and we're almost done... + */ + if (new_brk <= brk_page) { + /* + * Heap contents are initialized to zero, + * as for anonymous mapped pages. + */ + if (new_brk > target_brk) { + memset(g2h(target_brk), 0, new_brk - target_brk); + } + target_brk = new_brk; + return target_brk; + } + + /* + * We need to allocate more memory after the brk... Note that + * we don't use MAP_FIXED because that will map over the top of + * any existing mapping (like the one with the host libc or qemu + * itself); instead we treat "mapped but at wrong address" as + * a failure and unmap again. + */ + new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page); + mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, + PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0)); + + if (mapped_addr == brk_page) { + /* + * Heap contents are initialized to zero, as for anonymous + * mapped pages. Technically the new pages are already + * initialized to zero since they *are* anonymous mapped + * pages, however we have to take care with the contents that + * come from the remaining part of the previous page: it may + * contains garbage data due to a previous heap usage (grown + * then shrunken). + */ + memset(g2h(target_brk), 0, brk_page - target_brk); + + target_brk = new_brk; + brk_page = HOST_PAGE_ALIGN(target_brk); + return target_brk; + } else if (mapped_addr != -1) { + /* + * Mapped but at wrong address, meaning there wasn't actually + * enough space for this brk. + */ + target_munmap(mapped_addr, new_alloc_size); + mapped_addr = -1; + } + +#if defined(TARGET_ALPHA) + /* + * We (partially) emulate OSF/1 on Alpha, which requires we + * return a proper errno, not an unchanged brk value. + */ + return -TARGET_ENOMEM; +#endif + /* For everything else, return the previous break. */ + return target_brk; +} + +SYSCALL_IMPL(brk) +{ + return do_brk(arg1); +} SYSCALL_IMPL(mlock) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 02010f9ae0..fbca989021 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -830,97 +830,6 @@ static inline int host_to_target_sock_type(int host_type) return target_type; } -static abi_ulong target_brk; -static abi_ulong target_original_brk; -static abi_ulong brk_page; - -void target_set_brk(abi_ulong new_brk) -{ - target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); - brk_page = HOST_PAGE_ALIGN(target_brk); -} - -//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0) -#define DEBUGF_BRK(message, args...) - -/* do_brk() must return target values and target errnos. */ -abi_long do_brk(abi_ulong new_brk) -{ - abi_long mapped_addr; - abi_ulong new_alloc_size; - - DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk); - - if (!new_brk) { - DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk); - return target_brk; - } - if (new_brk < target_original_brk) { - DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n", - target_brk); - return target_brk; - } - - /* If the new brk is less than the highest page reserved to the - * target heap allocation, set it and we're almost done... */ - if (new_brk <= brk_page) { - /* Heap contents are initialized to zero, as for anonymous - * mapped pages. */ - if (new_brk > target_brk) { - memset(g2h(target_brk), 0, new_brk - target_brk); - } - target_brk = new_brk; - DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk); - return target_brk; - } - - /* We need to allocate more memory after the brk... Note that - * we don't use MAP_FIXED because that will map over the top of - * any existing mapping (like the one with the host libc or qemu - * itself); instead we treat "mapped but at wrong address" as - * a failure and unmap again. - */ - new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page); - mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, - PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, 0, 0)); - - if (mapped_addr == brk_page) { - /* Heap contents are initialized to zero, as for anonymous - * mapped pages. Technically the new pages are already - * initialized to zero since they *are* anonymous mapped - * pages, however we have to take care with the contents that - * come from the remaining part of the previous page: it may - * contains garbage data due to a previous heap usage (grown - * then shrunken). */ - memset(g2h(target_brk), 0, brk_page - target_brk); - - target_brk = new_brk; - brk_page = HOST_PAGE_ALIGN(target_brk); - DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n", - target_brk); - return target_brk; - } else if (mapped_addr != -1) { - /* Mapped but at wrong address, meaning there wasn't actually - * enough space for this brk. - */ - target_munmap(mapped_addr, new_alloc_size); - mapped_addr = -1; - DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk); - } - else { - DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk); - } - -#if defined(TARGET_ALPHA) - /* We (partially) emulate OSF/1 on Alpha, which requires we - return a proper errno, not an unchanged brk value. */ - return -TARGET_ENOMEM; -#endif - /* For everything else, return the previous break. */ - return target_brk; -} - static inline abi_long copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n) @@ -5626,8 +5535,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_brk: - return do_brk(arg1); #ifdef TARGET_NR_fork case TARGET_NR_fork: return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0)); diff --git a/linux-user/strace.list b/linux-user/strace.list index d0160f841f..bdc1401b01 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -49,9 +49,6 @@ #ifdef TARGET_NR_break { TARGET_NR_break, "break" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_brk -{ TARGET_NR_brk, "brk" , NULL, print_brk, print_syscall_ret_addr }, -#endif #ifdef TARGET_NR_cachectl { TARGET_NR_cachectl, "cachectl" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027768 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XGMfJho+"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDtj4Qjrz9s9G for ; Sat, 19 Jan 2019 08:42:21 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47533 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbu7-0004bC-H4 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:42:19 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55949) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkM-00057Q-SZ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkK-0004bw-2e for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:14 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:43342) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkJ-0004b4-Hh for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:11 -0500 Received: by mail-pl1-x642.google.com with SMTP id gn14so6875725plb.10 for ; Fri, 18 Jan 2019 13:32:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Y4kDRWo46EMNH+XWQ9xHwjxn4z5QeynTmweFdcxTt5I=; b=XGMfJho+jMDc+FuS++F/iwJeuUlk1/LKu4aNmkCoOQoQsXJ+mdUtCYrwyTTx5+EZK/ ocNQL4+TWQmxAdJkJXKhbYbrtXynlBvhA13GkFjmKoDcSZCS+7/NN6uO8HQdARrPKeLt 4RUdHGzriiv+Cc1wcvAD1Pt4fo2FwHyscHekU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y4kDRWo46EMNH+XWQ9xHwjxn4z5QeynTmweFdcxTt5I=; b=DimP+WTa1cATRE/IShv55h6MuNJ6DjZd++LzHw0820T6j0crZnEQDDvi0UW29UfvYC FNjS5m/cNfWlWBs8MN6w0jghdR1SFs9meoo/DMKs//Z+aBbDuplrfHxUrIdEXHFugZf4 kbrSuvsOGozmRGp5zVj4ALrGGCth4+CphDvRUNbFX+b0kbv8D2DfZDdPWVt62nvkNnnm 35Ib4q5nb0wonNhDsg+rMXhD05Rn1bvjVCDHXubNn7F5+6SylTDdShJEdCkUZWZ99vCd c//WqQ2JJC/eJBJbLmC3mX9Wgp0i2ezrU5mTTl3E13NFi/6EtGC6BNjHz4/XMF9PzBq3 Njiw== X-Gm-Message-State: AJcUukcrAfQ2IxPyO7CcJ6fflT/Nv3dh0+WL4e66JbtZHkFL9xWnPTn2 VF2Y9GG4NBkxf/ix/I2H8mwQ4pixczA= X-Google-Smtp-Source: ALg8bN4hglloX5v/8XeAnbW2mHG6HVeUiLik4gKyuEBKnlFFxFqMRcmrsES02jZqD4XKVgvuDu3E3Q== X-Received: by 2002:a17:902:7d90:: with SMTP id a16mr19906302plm.249.1547847130002; Fri, 18 Jan 2019 13:32:10 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:09 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:51 +1100 Message-Id: <20190118213122.22865-18-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH v6 18/49] linux-user: Split out clone, fork, vfork X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Rename do_fork to do_clone, since that is what it does. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 8 ++ linux-user/syscall.h | 1 + linux-user/strace.c | 36 +---- linux-user/syscall-proc.inc.c | 259 ++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 218 ---------------------------- linux-user/strace.list | 9 -- 6 files changed, 272 insertions(+), 259 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index c3ed22ff16..6f6f77927b 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -19,8 +19,12 @@ SYSCALL_DEF_FULL(brk, .impl = impl_brk, .print_ret = print_syscall_ptr_ret, .arg_type = { ARG_PTR }); +SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR); SYSCALL_DEF(close, ARG_DEC); SYSCALL_DEF(exit, ARG_DEC); +#ifdef TARGET_NR_fork +SYSCALL_DEF(fork); +#endif #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif @@ -110,5 +114,9 @@ SYSCALL_DEF(shmdt, ARG_PTR); #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget) SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); #endif +#ifdef TARGET_NR_vfork +/* Emulate vfork() with fork(). */ +SYSCALL_DEF_FULL(vfork, .impl = impl_fork); +#endif SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC); SYSCALL_DEF(writev, ARG_DEC, ARG_PTR, ARG_DEC); diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 8175de4c31..f75cd3ddd0 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -58,6 +58,7 @@ typedef enum { /* These print as sets of flags. */ ARG_ATDIRFD, ARG_ATFLAG, + ARG_CLONEFLAG, ARG_MMAPFLAG, ARG_MMAPPROT, ARG_MODEFLAG, diff --git a/linux-user/strace.c b/linux-user/strace.c index ba541432eb..d7847e7cd6 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -813,7 +813,7 @@ static struct flags const mmap_flags[] = { FLAG_END, }; -UNUSED static struct flags clone_flags[] = { +static struct flags const clone_flags[] = { FLAG_GENERIC(CLONE_VM), FLAG_GENERIC(CLONE_FS), FLAG_GENERIC(CLONE_FILES), @@ -1183,37 +1183,6 @@ print_clock_adjtime(const struct syscallname *name, } #endif -#ifdef TARGET_NR_clone -static void do_print_clone(unsigned int flags, abi_ulong newsp, - abi_ulong parent_tidptr, target_ulong newtls, - abi_ulong child_tidptr) -{ - print_flags(clone_flags, flags, 0); - print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, newsp, 0); - print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, parent_tidptr, 0); - print_raw_param("tls=0x" TARGET_ABI_FMT_lx, newtls, 0); - print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, child_tidptr, 1); -} - -static void -print_clone(const struct syscallname *name, - abi_long arg1, abi_long arg2, abi_long arg3, - abi_long arg4, abi_long arg5, abi_long arg6) -{ - print_syscall_prologue(name); -#if defined(TARGET_MICROBLAZE) - do_print_clone(arg1, arg2, arg4, arg6, arg5); -#elif defined(TARGET_CLONE_BACKWARDS) - do_print_clone(arg1, arg2, arg3, arg4, arg5); -#elif defined(TARGET_CLONE_BACKWARDS2) - do_print_clone(arg2, arg1, arg3, arg5, arg4); -#else - do_print_clone(arg1, arg2, arg3, arg5, arg4); -#endif - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_creat static void print_creat(const struct syscallname *name, @@ -2521,6 +2490,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_ATFLAG: len = add_flags(b, rest, at_file_flags, arg, false); break; + case ARG_CLONEFLAG: + len = add_flags(b, rest, clone_flags, arg, false); + break; case ARG_MMAPFLAG: len = add_flags(b, rest, mmap_flags, arg, false); break; diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index 96ad363c1a..b89ac56552 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -16,6 +16,258 @@ * along with this program; if not, see . */ +#ifndef CLONE_IO +#define CLONE_IO 0x80000000 /* Clone io context */ +#endif + +/* + * We can't directly call the host clone syscall, because this will + * badly confuse libc (breaking mutexes, for example). So we must + * divide clone flags into: + * * flag combinations that look like pthread_create() + * * flag combinations that look like fork() + * * flags we can implement within QEMU itself + * * flags we can't support and will return an error for + * + * For thread creation, all these flags must be present; for + * fork, none must be present. + */ +#define CLONE_THREAD_FLAGS \ + (CLONE_VM | CLONE_FS | CLONE_FILES | \ + CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM) + +/* + * These flags are ignored: + * CLONE_DETACHED is now ignored by the kernel; + * CLONE_IO is just an optimisation hint to the I/O scheduler + */ +#define CLONE_IGNORED_FLAGS \ + (CLONE_DETACHED | CLONE_IO) + +/* Flags for fork which we can implement within QEMU itself */ +#define CLONE_OPTIONAL_FORK_FLAGS \ + (CLONE_SETTLS | CLONE_PARENT_SETTID | \ + CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID) + +/* Flags for thread creation which we can implement within QEMU itself */ +#define CLONE_OPTIONAL_THREAD_FLAGS \ + (CLONE_SETTLS | CLONE_PARENT_SETTID | \ + CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT) + +#define CLONE_INVALID_FORK_FLAGS \ + (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS)) + +#define CLONE_INVALID_THREAD_FLAGS \ + (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS | \ + CLONE_IGNORED_FLAGS)) + +/* + * CLONE_VFORK is special cased early in do_fork(). The other flag bits + * have almost all been allocated. We cannot support any of + * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC, + * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED. + * The checks against the invalid thread masks above will catch these. + * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.) + */ + +/** + * do_clone: + * Arguments as for clone(2), returns target errnos. + */ +static abi_long do_clone(CPUArchState *env, unsigned int flags, + abi_ulong newsp, abi_ulong parent_tidptr, + abi_ulong child_tidptr, target_ulong newtls) +{ + CPUState *cpu = ENV_GET_CPU(env); + abi_long ret; + TaskState *ts; + CPUState *new_cpu; + CPUArchState *new_env; + sigset_t sigmask; + + flags &= ~CLONE_IGNORED_FLAGS; + + /* Emulate vfork() with fork() */ + if (flags & CLONE_VFORK) { + flags &= ~(CLONE_VFORK | CLONE_VM); + } + + if (flags & CLONE_VM) { + /* If CLONE_VM, we consider it a new thread. */ + TaskState *parent_ts = (TaskState *)cpu->opaque; + new_thread_info info; + pthread_attr_t attr; + + if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) || + (flags & CLONE_INVALID_THREAD_FLAGS)) { + return -TARGET_EINVAL; + } + + ts = g_new0(TaskState, 1); + init_task_state(ts); + + /* Grab a mutex so that thread setup appears atomic. */ + pthread_mutex_lock(&clone_lock); + + /* Create a new CPU instance. */ + new_env = cpu_copy(env); + + /* Init regs that differ from the parent. */ + cpu_clone_regs(new_env, newsp); + new_cpu = ENV_GET_CPU(new_env); + new_cpu->opaque = ts; + ts->bprm = parent_ts->bprm; + ts->info = parent_ts->info; + ts->signal_mask = parent_ts->signal_mask; + + if (flags & CLONE_CHILD_CLEARTID) { + ts->child_tidptr = child_tidptr; + } + + if (flags & CLONE_SETTLS) { + cpu_set_tls(new_env, newtls); + } + + memset(&info, 0, sizeof(info)); + pthread_mutex_init(&info.mutex, NULL); + pthread_mutex_lock(&info.mutex); + pthread_cond_init(&info.cond, NULL); + info.env = new_env; + if (flags & CLONE_CHILD_SETTID) { + info.child_tidptr = child_tidptr; + } + if (flags & CLONE_PARENT_SETTID) { + info.parent_tidptr = parent_tidptr; + } + + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE); + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + /* + * It is not safe to deliver signals until the child has finished + * initializing, so temporarily block all signals. + */ + sigfillset(&sigmask); + sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); + + /* + * If this is our first additional thread, we need to ensure we + * generate code for parallel execution and flush old translations. + */ + if (!parallel_cpus) { + parallel_cpus = true; + tb_flush(cpu); + } + + ret = pthread_create(&info.thread, &attr, clone_func, &info); + /* TODO: Free new CPU state if thread creation failed. */ + + sigprocmask(SIG_SETMASK, &info.sigmask, NULL); + pthread_attr_destroy(&attr); + if (ret == 0) { + /* Wait for the child to initialize. */ + pthread_cond_wait(&info.cond, &info.mutex); + ret = info.tid; + } else { + ret = host_to_target_errno(ret); + } + pthread_mutex_unlock(&info.mutex); + pthread_cond_destroy(&info.cond); + pthread_mutex_destroy(&info.mutex); + pthread_mutex_unlock(&clone_lock); + } else { + /* If no CLONE_VM, we consider it a fork. */ + if (flags & CLONE_INVALID_FORK_FLAGS) { + return -TARGET_EINVAL; + } + + /* We can't support custom termination signals. */ + if ((flags & CSIGNAL) != TARGET_SIGCHLD) { + return -TARGET_EINVAL; + } + + if (block_signals()) { + return -TARGET_ERESTARTSYS; + } + + fork_start(); + ret = fork(); + if (ret == 0) { + /* Child Process. */ + cpu_clone_regs(env, newsp); + fork_end(1); + /* + * There is a race condition here. The parent process could + * theoretically read the TID in the child process before the + * child tid is set. This would require using either ptrace + * (not implemented) or having *_tidptr to point at a shared + * memory mapping. We can't repeat the spinlock hack used + * above because the child process gets its own copy of the lock. + */ + if (flags & CLONE_CHILD_SETTID) { + put_user_u32(gettid(), child_tidptr); + } + if (flags & CLONE_PARENT_SETTID) { + put_user_u32(gettid(), parent_tidptr); + } + ts = (TaskState *)cpu->opaque; + if (flags & CLONE_SETTLS) { + cpu_set_tls(env, newtls); + } + if (flags & CLONE_CHILD_CLEARTID) { + ts->child_tidptr = child_tidptr; + } + } else { + fork_end(0); + ret = get_errno(ret); + } + } + return ret; +} + +#if defined(TARGET_MICROBLAZE) || \ + defined(TARGET_CLONE_BACKWARDS) || \ + defined(TARGET_CLONE_BACKWARDS2) +SYSCALL_ARGS(clone) +{ + /* + * Linux manages to have three "standard" orderings for its + * arguments to clone(); the BACKWARDS and BACKWARDS2 defines + * match the kernel's CONFIG_CLONE_* settings. + * Microblaze is further special in that it uses a sixth + * implicit argument to clone for the TLS pointer. + * + * Standardize on the non-BACKWARDS ordering. + */ +# if defined(TARGET_MICROBLAZE) + /* We have already assigned out[0-1]. */ + out[2] = in[3]; + out[3] = in[4]; + out[4] = in[5]; +# elif defined(TARGET_CLONE_BACKWARDS) + /* We have already assigned out[0-2]. */ + out[3] = in[4]; + out[4] = in[3]; +# elif defined(TARGET_CLONE_BACKWARDS2) + out[0] = in[1]; + out[1] = in[0]; + out[2] = in[2]; + out[3] = in[4]; + out[4] = in[3]; +# else +# error Missing case +# endif + return def; +} +#else +#define args_clone NULL +#endif + +SYSCALL_IMPL(clone) +{ + return do_clone(cpu_env, arg1, arg2, arg3, arg4, arg5); +} SYSCALL_IMPL(exit) { @@ -59,3 +311,10 @@ SYSCALL_IMPL(exit) preexit_cleanup(cpu_env, status); _exit(status); } + +#if defined(TARGET_NR_fork) || defined(TARGET_NR_vfork) +SYSCALL_IMPL(fork) +{ + return do_clone(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0); +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index fbca989021..1d18d28fbe 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -113,57 +113,6 @@ #include "fd-trans.h" #include "syscall.h" -#ifndef CLONE_IO -#define CLONE_IO 0x80000000 /* Clone io context */ -#endif - -/* We can't directly call the host clone syscall, because this will - * badly confuse libc (breaking mutexes, for example). So we must - * divide clone flags into: - * * flag combinations that look like pthread_create() - * * flag combinations that look like fork() - * * flags we can implement within QEMU itself - * * flags we can't support and will return an error for - */ -/* For thread creation, all these flags must be present; for - * fork, none must be present. - */ -#define CLONE_THREAD_FLAGS \ - (CLONE_VM | CLONE_FS | CLONE_FILES | \ - CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM) - -/* These flags are ignored: - * CLONE_DETACHED is now ignored by the kernel; - * CLONE_IO is just an optimisation hint to the I/O scheduler - */ -#define CLONE_IGNORED_FLAGS \ - (CLONE_DETACHED | CLONE_IO) - -/* Flags for fork which we can implement within QEMU itself */ -#define CLONE_OPTIONAL_FORK_FLAGS \ - (CLONE_SETTLS | CLONE_PARENT_SETTID | \ - CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID) - -/* Flags for thread creation which we can implement within QEMU itself */ -#define CLONE_OPTIONAL_THREAD_FLAGS \ - (CLONE_SETTLS | CLONE_PARENT_SETTID | \ - CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT) - -#define CLONE_INVALID_FORK_FLAGS \ - (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS)) - -#define CLONE_INVALID_THREAD_FLAGS \ - (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS | \ - CLONE_IGNORED_FLAGS)) - -/* CLONE_VFORK is special cased early in do_fork(). The other flag bits - * have almost all been allocated. We cannot support any of - * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC, - * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED. - * The checks against the invalid thread masks above will catch these. - * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.) - */ - /* Define DEBUG_ERESTARTSYS to force every syscall to be restarted * once. This exercises the codepaths for restart. */ @@ -4397,146 +4346,6 @@ static void *clone_func(void *arg) return NULL; } -/* do_fork() Must return host values and target errnos (unlike most - do_*() functions). */ -static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, - abi_ulong parent_tidptr, target_ulong newtls, - abi_ulong child_tidptr) -{ - CPUState *cpu = ENV_GET_CPU(env); - int ret; - TaskState *ts; - CPUState *new_cpu; - CPUArchState *new_env; - sigset_t sigmask; - - flags &= ~CLONE_IGNORED_FLAGS; - - /* Emulate vfork() with fork() */ - if (flags & CLONE_VFORK) - flags &= ~(CLONE_VFORK | CLONE_VM); - - if (flags & CLONE_VM) { - TaskState *parent_ts = (TaskState *)cpu->opaque; - new_thread_info info; - pthread_attr_t attr; - - if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) || - (flags & CLONE_INVALID_THREAD_FLAGS)) { - return -TARGET_EINVAL; - } - - ts = g_new0(TaskState, 1); - init_task_state(ts); - - /* Grab a mutex so that thread setup appears atomic. */ - pthread_mutex_lock(&clone_lock); - - /* we create a new CPU instance. */ - new_env = cpu_copy(env); - /* Init regs that differ from the parent. */ - cpu_clone_regs(new_env, newsp); - new_cpu = ENV_GET_CPU(new_env); - new_cpu->opaque = ts; - ts->bprm = parent_ts->bprm; - ts->info = parent_ts->info; - ts->signal_mask = parent_ts->signal_mask; - - if (flags & CLONE_CHILD_CLEARTID) { - ts->child_tidptr = child_tidptr; - } - - if (flags & CLONE_SETTLS) { - cpu_set_tls (new_env, newtls); - } - - memset(&info, 0, sizeof(info)); - pthread_mutex_init(&info.mutex, NULL); - pthread_mutex_lock(&info.mutex); - pthread_cond_init(&info.cond, NULL); - info.env = new_env; - if (flags & CLONE_CHILD_SETTID) { - info.child_tidptr = child_tidptr; - } - if (flags & CLONE_PARENT_SETTID) { - info.parent_tidptr = parent_tidptr; - } - - ret = pthread_attr_init(&attr); - ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE); - ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - /* It is not safe to deliver signals until the child has finished - initializing, so temporarily block all signals. */ - sigfillset(&sigmask); - sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); - - /* If this is our first additional thread, we need to ensure we - * generate code for parallel execution and flush old translations. - */ - if (!parallel_cpus) { - parallel_cpus = true; - tb_flush(cpu); - } - - ret = pthread_create(&info.thread, &attr, clone_func, &info); - /* TODO: Free new CPU state if thread creation failed. */ - - sigprocmask(SIG_SETMASK, &info.sigmask, NULL); - pthread_attr_destroy(&attr); - if (ret == 0) { - /* Wait for the child to initialize. */ - pthread_cond_wait(&info.cond, &info.mutex); - ret = info.tid; - } else { - ret = -1; - } - pthread_mutex_unlock(&info.mutex); - pthread_cond_destroy(&info.cond); - pthread_mutex_destroy(&info.mutex); - pthread_mutex_unlock(&clone_lock); - } else { - /* if no CLONE_VM, we consider it is a fork */ - if (flags & CLONE_INVALID_FORK_FLAGS) { - return -TARGET_EINVAL; - } - - /* We can't support custom termination signals */ - if ((flags & CSIGNAL) != TARGET_SIGCHLD) { - return -TARGET_EINVAL; - } - - if (block_signals()) { - return -TARGET_ERESTARTSYS; - } - - fork_start(); - ret = fork(); - if (ret == 0) { - /* Child Process. */ - cpu_clone_regs(env, newsp); - fork_end(1); - /* There is a race condition here. The parent process could - theoretically read the TID in the child process before the child - tid is set. This would require using either ptrace - (not implemented) or having *_tidptr to point at a shared memory - mapping. We can't repeat the spinlock hack used above because - the child process gets its own copy of the lock. */ - if (flags & CLONE_CHILD_SETTID) - put_user_u32(gettid(), child_tidptr); - if (flags & CLONE_PARENT_SETTID) - put_user_u32(gettid(), parent_tidptr); - ts = (TaskState *)cpu->opaque; - if (flags & CLONE_SETTLS) - cpu_set_tls (env, newtls); - if (flags & CLONE_CHILD_CLEARTID) - ts->child_tidptr = child_tidptr; - } else { - fork_end(0); - } - } - return ret; -} - /* warning : doesn't handle linux specific flags... */ static int target_to_host_fcntl_cmd(int cmd) { @@ -5535,10 +5344,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_fork - case TARGET_NR_fork: - return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0)); -#endif #ifdef TARGET_NR_waitpid case TARGET_NR_waitpid: { @@ -7228,23 +7033,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return ret; case TARGET_NR_fsync: return get_errno(fsync(arg1)); - case TARGET_NR_clone: - /* Linux manages to have three different orderings for its - * arguments to clone(); the BACKWARDS and BACKWARDS2 defines - * match the kernel's CONFIG_CLONE_* settings. - * Microblaze is further special in that it uses a sixth - * implicit argument to clone for the TLS pointer. - */ -#if defined(TARGET_MICROBLAZE) - ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5)); -#elif defined(TARGET_CLONE_BACKWARDS) - ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); -#elif defined(TARGET_CLONE_BACKWARDS2) - ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4)); -#else - ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4)); -#endif - return ret; #ifdef __NR_exit_group /* new thread calls */ case TARGET_NR_exit_group: @@ -8079,12 +7867,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } #endif #endif -#ifdef TARGET_NR_vfork - case TARGET_NR_vfork: - return get_errno(do_fork(cpu_env, - CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD, - 0, 0, 0, 0)); -#endif #ifdef TARGET_NR_ugetrlimit case TARGET_NR_ugetrlimit: { diff --git a/linux-user/strace.list b/linux-user/strace.list index bdc1401b01..0d978ea580 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -91,9 +91,6 @@ #ifdef TARGET_NR_clock_settime { TARGET_NR_clock_settime, "clock_settime" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_clone -{ TARGET_NR_clone, "clone" , NULL, print_clone, NULL }, -#endif #ifdef TARGET_NR_connect { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL }, #endif @@ -220,9 +217,6 @@ #ifdef TARGET_NR_flock { TARGET_NR_flock, "flock" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_fork -{ TARGET_NR_fork, "fork" , "%s()", NULL, NULL }, -#endif #ifdef TARGET_NR_fremovexattr { TARGET_NR_fremovexattr, "fremovexattr" , NULL, NULL, NULL }, #endif @@ -1485,9 +1479,6 @@ #ifdef TARGET_NR_utrap_install { TARGET_NR_utrap_install, "utrap_install" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_vfork -{ TARGET_NR_vfork, "vfork" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_vhangup { TARGET_NR_vhangup, "vhangup" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027788 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="C4yqZTPS"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFCv6z1nz9sD9 for ; Sat, 19 Jan 2019 08:57:15 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47748 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc8X-0008WL-Qe for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:57:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55981) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkZ-0005HS-Ro for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkQ-0004hk-MZ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:21 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:47056) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkM-0004dE-Tp for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:16 -0500 Received: by mail-pl1-x644.google.com with SMTP id t13so6870391ply.13 for ; Fri, 18 Jan 2019 13:32:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=abx648KpDmxzA5gUxo/+UEW+pYX645WiVIJP5iJ8QA0=; b=C4yqZTPS2p6XczItYJ5UVAoBJ2LmFhLjSqpT8Go16Ild3R+0nhWNjCAXmSghJUKFq0 gU+XDTeBLgazW01D0ZS/uLa8zPP7bqKbruA0VO4O+dqT5/XFvaoirncDTTdNrIjfG293 jUfUtHYxQzJ8fn4MHFZP41jLnAXlCoZFGUWcg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=abx648KpDmxzA5gUxo/+UEW+pYX645WiVIJP5iJ8QA0=; b=F3BRnLD5ZouURglDfPP7u9zYcS4/Kk7Q+ncVc2wR4QJhDIZiyuhOwV4sOttaZjmzLQ /gvPyINDCrKJ8JgZhxye5geZquqYYTYyhMM7QnWvZTijP377awgVV9tbx2mTVeBOLNLZ YozUXgkxMdji11lwX8weFsIokzh46hus7Wzz2aQVHrjh0hEc+hj6vSQCsmtMKOpIox4X 8ADxDEbb4jX2fZUkymZFYcax130GOAnk8rJgDbp9WklJoTsL0iQtSIOyvydgHgxSLjGG KjDNIsCT9CByKt26wp24fF6sP/0jMQIap5KLq5tmWjbnUxBSkIL8yuaoSUkqPs8td3HW wS6w== X-Gm-Message-State: AJcUukfIWQ3dMNiJdl0jUF/lLj0H3bvIywglag9wR1Bhym5aEhF/cZVM rGfIZhVrgcf0rD4XV6WLgTh4LSqQDCY= X-Google-Smtp-Source: ALg8bN7eBIAGnvFmZf+cOZ0dGnnbds3rUENB+zdxVNOLfGbuEdzl20MX7of1FhWaFtcfNeitVs1edw== X-Received: by 2002:a17:902:d911:: with SMTP id c17mr21298461plz.151.1547847132327; Fri, 18 Jan 2019 13:32:12 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:11 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:52 +1100 Message-Id: <20190118213122.22865-19-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 19/49] linux-user: Split out wait4, waitid, waitpid X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that waitid is universally provided and need not be conditional. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 5 ++ linux-user/syscall-proc.inc.c | 88 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 67 -------------------------- linux-user/strace.list | 9 ---- 4 files changed, 93 insertions(+), 76 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 6f6f77927b..a84050a318 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -118,5 +118,10 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); /* Emulate vfork() with fork(). */ SYSCALL_DEF_FULL(vfork, .impl = impl_fork); #endif +SYSCALL_DEF(wait4, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR); +SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX); +#ifdef TARGET_NR_waitpid +SYSCALL_DEF(waitpid, ARG_DEC, ARG_PTR, ARG_HEX); +#endif SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC); SYSCALL_DEF(writev, ARG_DEC, ARG_PTR, ARG_DEC); diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index b89ac56552..37f5bbe197 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -318,3 +318,91 @@ SYSCALL_IMPL(fork) return do_clone(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0); } #endif + +/* + * Map host to target signal numbers for the wait family of syscalls. + * Assume all other status bits are the same. + */ +int host_to_target_waitstatus(int status) +{ + if (WIFSIGNALED(status)) { + return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); + } + if (WIFSTOPPED(status)) { + return (host_to_target_signal(WSTOPSIG(status)) << 8) + | (status & 0xff); + } + return status; +} + +SYSCALL_IMPL(wait4) +{ + int status; + pid_t pid = arg1; + abi_ulong status_ptr = arg2; + int options = arg3; + abi_ulong target_rusage = arg4; + struct rusage rusage; + struct rusage *rusage_ptr = target_rusage ? &rusage : NULL; + abi_long ret; + + ret = get_errno(safe_wait4(pid, &status, options, rusage_ptr)); + if (!is_error(ret)) { + if (status_ptr && ret) { + status = host_to_target_waitstatus(status); + if (put_user_s32(status, status_ptr)) { + return -TARGET_EFAULT; + } + } + if (target_rusage) { + abi_long err = host_to_target_rusage(target_rusage, &rusage); + if (err) { + ret = err; + } + } + } + return ret; +} + +SYSCALL_IMPL(waitid) +{ + idtype_t idtype = arg1; + id_t id = arg2; + abi_ulong target_info = arg3; + int options = arg4; + siginfo_t info, *info_ptr = target_info ? &info : NULL; + abi_long ret; + + info.si_pid = 0; + ret = get_errno(safe_waitid(idtype, id, info_ptr, options, NULL)); + if (!is_error(ret) && target_info && info.si_pid != 0) { + target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info, + sizeof(target_siginfo_t), 0); + if (!p) { + return -TARGET_EFAULT; + } + host_to_target_siginfo(p, &info); + unlock_user(p, target_info, sizeof(target_siginfo_t)); + } + return ret; +} + +#ifdef TARGET_NR_waitpid +SYSCALL_IMPL(waitpid) +{ + pid_t pid = arg1; + abi_ulong target_status = arg2; + int options = arg3; + int status; + abi_long ret; + + ret = get_errno(safe_wait4(pid, &status, options, NULL)); + if (!is_error(ret) + && target_status + && ret + && put_user_s32(host_to_target_waitstatus(status), target_status)) { + return -TARGET_EFAULT; + } + return ret; +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1d18d28fbe..8da92dd188 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5218,20 +5218,6 @@ static abi_long do_signalfd4(int fd, abi_long mask, int flags) } #endif -/* Map host to target signal numbers for the wait family of syscalls. - Assume all other status bits are the same. */ -int host_to_target_waitstatus(int status) -{ - if (WIFSIGNALED(status)) { - return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); - } - if (WIFSTOPPED(status)) { - return (host_to_target_signal(WSTOPSIG(status)) << 8) - | (status & 0xff); - } - return status; -} - #define TIMER_MAGIC 0x0caf0000 #define TIMER_MAGIC_MASK 0xffff0000 @@ -5344,32 +5330,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_waitpid - case TARGET_NR_waitpid: - { - int status; - ret = get_errno(safe_wait4(arg1, &status, arg3, 0)); - if (!is_error(ret) && arg2 && ret - && put_user_s32(host_to_target_waitstatus(status), arg2)) - return -TARGET_EFAULT; - } - return ret; -#endif -#ifdef TARGET_NR_waitid - case TARGET_NR_waitid: - { - siginfo_t info; - info.si_pid = 0; - ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL)); - if (!is_error(ret) && arg3 && info.si_pid != 0) { - if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0))) - return -TARGET_EFAULT; - host_to_target_siginfo(p, &info); - unlock_user(p, arg3, sizeof(target_siginfo_t)); - } - } - return ret; -#endif #ifdef TARGET_NR_creat /* not on alpha */ case TARGET_NR_creat: if (!(p = lock_user_string(arg1))) @@ -6969,33 +6929,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5, arg6, arg7, arg8, 0); #endif - case TARGET_NR_wait4: - { - int status; - abi_long status_ptr = arg2; - struct rusage rusage, *rusage_ptr; - abi_ulong target_rusage = arg4; - abi_long rusage_err; - if (target_rusage) - rusage_ptr = &rusage; - else - rusage_ptr = NULL; - ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr)); - if (!is_error(ret)) { - if (status_ptr && ret) { - status = host_to_target_waitstatus(status); - if (put_user_s32(status, status_ptr)) - return -TARGET_EFAULT; - } - if (target_rusage) { - rusage_err = host_to_target_rusage(target_rusage, &rusage); - if (rusage_err) { - ret = rusage_err; - } - } - } - } - return ret; #ifdef TARGET_NR_swapoff case TARGET_NR_swapoff: if (!(p = lock_user_string(arg1))) diff --git a/linux-user/strace.list b/linux-user/strace.list index 0d978ea580..afa1521e2d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1494,15 +1494,6 @@ #ifdef TARGET_NR_vserver { TARGET_NR_vserver, "vserver" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_wait4 -{ TARGET_NR_wait4, "wait4" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_waitid -{ TARGET_NR_waitid, "waitid" , "%s(%#x,%d,%p,%#x)", NULL, NULL }, -#endif -#ifdef TARGET_NR_waitpid -{ TARGET_NR_waitpid, "waitpid" , "%s(%d,%p,%#x)", NULL, NULL }, -#endif #ifdef TARGET_NR_utimensat { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL }, #endif From patchwork Fri Jan 18 21:30:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="YVYeamRX"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFGv0sRcz9sDL for ; Sat, 19 Jan 2019 08:59:51 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47774 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcB3-0002Uf-23 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:59:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkb-0005Iy-Bu for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkZ-0004oS-0V for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:29 -0500 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]:45977) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkQ-0004ea-L4 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:20 -0500 Received: by mail-pl1-x641.google.com with SMTP id a14so6865894plm.12 for ; Fri, 18 Jan 2019 13:32:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=W1Z9Vd3YSX5Q31DkxW6Gq3ieWVMIgFgXheKfcYbSUmk=; b=YVYeamRXxcH+Uo4D/eev09z49vvFAvwL/Fhl4nrtRNZOArY4WUG97OOA4hZEIpJjcY Y51x41Eo3YbejpguP/jyJtlu+VAOPUASC6uYwPK/S/VlQ850qFFZGhMD8Yvtiup6Kes7 GO5GFf597l/tH8YNqtrP+u6JX3l51g7zZImNE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=W1Z9Vd3YSX5Q31DkxW6Gq3ieWVMIgFgXheKfcYbSUmk=; b=MnEEiUoxx70xTpdZ42wgKs5BR7VJVeY1gcon+ykxGKQWsKwBSVihGUfFzQEJmb2nrb mqhhMxS2AW+1uYkpOy4jVF8jgaMzIo1EtCKSU/LqSU+k5hF4jmGmu5/MIBOWEzl2i503 ORLZYRLQW4ry/PawVPqFw8PnbrohhZSmd26UGZmlj4SHR2N+XttaHWJeLm8b24N/D3h8 uIkaS3gYICUiTTeKxyGvGw/tEytcE34zBba8kxUltEQtJKkPaXojU0cNW9lHnQqSrRZj c08N7xS10ytqxhAc4MH8CokOY/OiczJGUzatHe0Su91ELnvufljjcviiLHfmRSXLV/W7 Ckmg== X-Gm-Message-State: AJcUukcRv2F9J8p5AfyAZ1+43NbdU3QFXDpyqqrmSSBWI4sOYq4ozQGS Mw+Hz2B7+tUdn2LMOcwt7K7hyRcve8M= X-Google-Smtp-Source: ALg8bN5JgIeeCJozbbEN2SNW2d3bTTug/X+wLfQceYcTrY/hAyAqpdjpartrVm+NXeulokaYzilNmw== X-Received: by 2002:a17:902:b03:: with SMTP id 3mr20541807plq.91.1547847134635; Fri, 18 Jan 2019 13:32:14 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.12 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:13 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:53 +1100 Message-Id: <20190118213122.22865-20-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::641 Subject: [Qemu-devel] [PATCH v6 20/49] linux-user: Implement rusage argument to waitid X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The kernel interface, which we are supposed to be implementing, takes a fifth argument: an rusage pointer akin to wait4. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 2 +- linux-user/syscall-proc.inc.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index a84050a318..f099d98fa3 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -119,7 +119,7 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); SYSCALL_DEF_FULL(vfork, .impl = impl_fork); #endif SYSCALL_DEF(wait4, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR); -SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX); +SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR); #ifdef TARGET_NR_waitpid SYSCALL_DEF(waitpid, ARG_DEC, ARG_PTR, ARG_HEX); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index 37f5bbe197..de4efed9f4 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -370,19 +370,30 @@ SYSCALL_IMPL(waitid) id_t id = arg2; abi_ulong target_info = arg3; int options = arg4; + abi_ulong target_rusage = arg5; siginfo_t info, *info_ptr = target_info ? &info : NULL; + struct rusage rusage; + struct rusage *rusage_ptr = target_rusage ? &rusage : NULL; abi_long ret; info.si_pid = 0; - ret = get_errno(safe_waitid(idtype, id, info_ptr, options, NULL)); - if (!is_error(ret) && target_info && info.si_pid != 0) { - target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info, - sizeof(target_siginfo_t), 0); - if (!p) { - return -TARGET_EFAULT; + ret = get_errno(safe_waitid(idtype, id, info_ptr, options, rusage_ptr)); + if (!is_error(ret)) { + if (target_info && info.si_pid != 0) { + target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info, + sizeof(target_siginfo_t), 0); + if (!p) { + return -TARGET_EFAULT; + } + host_to_target_siginfo(p, &info); + unlock_user(p, target_info, sizeof(target_siginfo_t)); + } + if (target_rusage) { + abi_long err = host_to_target_rusage(target_rusage, &rusage); + if (err) { + ret = err; + } } - host_to_target_siginfo(p, &info); - unlock_user(p, target_info, sizeof(target_siginfo_t)); } return ret; } From patchwork Fri Jan 18 21:30:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027794 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="NwvHjzf9"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFL225k4z9sDB for ; Sat, 19 Jan 2019 09:02:34 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47826 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcDg-0004X9-83 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:02:32 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56001) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkd-0005Kt-Ad for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkb-0004ql-CF for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:31 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:36043) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkZ-0004iA-Nq for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:28 -0500 Received: by mail-pg1-x544.google.com with SMTP id n2so6649960pgm.3 for ; Fri, 18 Jan 2019 13:32:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+6nI3f9RtV/+MKWZGdObQgBIQ2b5qq2UFrnLz/a6Jm0=; b=NwvHjzf9zr9XMxtZHid0fzXnnkxE3vmzt4eNQpULZuqUfxkZfJpCMG/fU+Xm7u6R86 8QmBnlcROHm9pQBJT33GHAP20pFtFPKW28A9jhZ6p27RKIYc0PaXJ6NmrM9YMEFiEf7Y i1oaIiUsQkhyArX68V3vjTqaT5ZOQ4UPi28II= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+6nI3f9RtV/+MKWZGdObQgBIQ2b5qq2UFrnLz/a6Jm0=; b=r8O2QlwV1UxzT6AYHCDvcvt6ydskMlY0EljETqqsBrbsUeVbe8q0w3jlYI0jz6YHsE vVxl5mNIZlEEkzmmIrkEp9GQSVvGRo9tZ75DtV3iDg0fDcDdXpdcPdEUvXKLw4hQPcM2 p0ax94F7mOfkapDJVQjXufvDMza51Q9NLiFTt21qqz2ZnCRzSFfwQxnY9uKbUEtA1IV1 TP0D0EU8IHkRfo5Ipb3XC8ZfffNT0+RzVr/6cmV2BY5c208MgQipkwJK2g3ccIHvUmzs iwcmOgbeGE78pwOz9uJoeUmHD8WbsayyCU8I5x2XmTUUSS27jsslcFaH1os8Nhg2fVaY arnQ== X-Gm-Message-State: AJcUukcdU58a0GPl7nChpVQ2Kfs4j12Ldtf69fOnzbUu1MHtf9pKj2wf K0RdhM/RWLw+aNzngGE70bBJ7Wz52DA= X-Google-Smtp-Source: ALg8bN5bUoRgHZawBwRCKndsajpsAZ+E/CmgFI7OvyZjjA6DOY9zxTORczqxADEpkgbiD+35C2X5RA== X-Received: by 2002:a63:b81a:: with SMTP id p26mr19635805pge.433.1547847137041; Fri, 18 Jan 2019 13:32:17 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:16 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:54 +1100 Message-Id: <20190118213122.22865-21-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::544 Subject: [Qemu-devel] [PATCH v6 21/49] linux-user: Split out creat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 3 +++ linux-user/strace.c | 13 ------------- linux-user/syscall-file.inc.c | 16 ++++++++++++++++ linux-user/syscall.c | 9 --------- linux-user/strace.list | 3 --- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index f099d98fa3..de7a99f0c6 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -21,6 +21,9 @@ SYSCALL_DEF_FULL(brk, .impl = impl_brk, .arg_type = { ARG_PTR }); SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR); SYSCALL_DEF(close, ARG_DEC); +#ifdef TARGET_NR_creat +SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG); +#endif SYSCALL_DEF(exit, ARG_DEC); #ifdef TARGET_NR_fork SYSCALL_DEF(fork); diff --git a/linux-user/strace.c b/linux-user/strace.c index d7847e7cd6..5cb77223fd 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1183,19 +1183,6 @@ print_clock_adjtime(const struct syscallname *name, } #endif -#ifdef TARGET_NR_creat -static void -print_creat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_file_mode(arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_execv static void print_execv(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 81423cfd64..62e1790e3b 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -24,6 +24,22 @@ SYSCALL_IMPL(close) return get_errno(close(fd)); } +#ifdef TARGET_NR_creat +SYSCALL_IMPL(creat) +{ + char *p = lock_user_string(arg1); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(creat(p, arg2)); + fd_trans_unregister(ret); + unlock_user(p, arg1, 0); + return ret; +} +#endif + /* * Helpers for do_openat, manipulating /proc/self/foo. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8da92dd188..1e9478611c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5330,15 +5330,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_creat /* not on alpha */ - case TARGET_NR_creat: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(creat(p, arg2)); - fd_trans_unregister(ret); - unlock_user(p, arg1, 0); - return ret; -#endif #ifdef TARGET_NR_link case TARGET_NR_link: { diff --git a/linux-user/strace.list b/linux-user/strace.list index afa1521e2d..be0392810c 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -94,9 +94,6 @@ #ifdef TARGET_NR_connect { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL }, #endif -#ifdef TARGET_NR_creat -{ TARGET_NR_creat, "creat" , NULL, print_creat, NULL }, -#endif #ifdef TARGET_NR_create_module { TARGET_NR_create_module, "create_module" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027774 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="DRSonpbv"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF0v5Zlnz9sDL for ; Sat, 19 Jan 2019 08:47:43 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47611 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbzJ-0000f2-KQ for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:47:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56033) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbke-0005Lw-Ag for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkd-0004sc-C7 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:32 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:44929) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkb-0004jS-Iw for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:31 -0500 Received: by mail-pg1-x544.google.com with SMTP id t13so6634927pgr.11 for ; Fri, 18 Jan 2019 13:32:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xWyW/AxGb4DGE67el7J8JfHnvATN5W0cXS6IRi20Ck0=; b=DRSonpbvv/0NJrN6ejyjyVfrnRB2VZvUfiEuMQlcg+gDS9/xuvP5TRcrcsGp73rzPZ DMK/ogirFKE9ZXtrEyNoG+SCn/URh3F385QofPJStD+J8MNxN56jM0vijUSunucmVBpR audx+bX3yZhN7N8ced8s+bTZOMvVXzccMJklY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xWyW/AxGb4DGE67el7J8JfHnvATN5W0cXS6IRi20Ck0=; b=VBeDq3BmFq0GO3u3LJw/O+A2hLHUzVcO7tcAR2V3+TTgefQRwnveelkBEJgiZIiuDQ ch7nzDuNV83PN/PV8rclZRc6em7nMYGpVuI9Hr6GyaxnNcejBQXVuB8dnLgAPqZ0u2I+ wVH3qRNIgzLF+Z1axWF52jTzTdjzJ0dpLyEj7qFahSs8bSgOMgH+/2zy1SGpRWukcZjc RkiEPuTtj3knFGNmyEw3hy3Yk2qBhJwMPtr+NLjn7HjXIk8I9pvALxaqrxqtevTVP+WN SX+su3Zo6J+ZXHlU3wYuDOVDbiXbL5RZ8hIIOqUAwPIOWBkec+qg7+v7Q2d5c9yIrXmg f8dA== X-Gm-Message-State: AJcUukfuYoPQLwJat4XpDPWhz61rQAt3bh6tQt9VyY6yowG/bDeE8/Ww MZf21qZTPlIOjD7QwzlBeS/KTsMDQNI= X-Google-Smtp-Source: ALg8bN6y3m++oZ1wQsMSF1ObrwwuVOCrVrr2gLUVRvJ7KKNMQHCfFNTBz+HkQiQZpYA81T4fPvKzKw== X-Received: by 2002:a63:2054:: with SMTP id r20mr19184131pgm.328.1547847139504; Fri, 18 Jan 2019 13:32:19 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:18 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:55 +1100 Message-Id: <20190118213122.22865-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::544 Subject: [Qemu-devel] [PATCH v6 22/49] linux-user: Split out link, linkat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that linkat is universally provided. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 4 ++++ linux-user/strace.c | 29 ----------------------------- linux-user/syscall-file.inc.c | 28 ++++++++++++++++++++++++++++ linux-user/syscall.c | 32 -------------------------------- linux-user/strace.list | 6 ------ 5 files changed, 32 insertions(+), 67 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index de7a99f0c6..41dd887dbc 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -31,6 +31,10 @@ SYSCALL_DEF(fork); #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif +#ifdef TARGET_NR_link +SYSCALL_DEF(link, ARG_STR, ARG_STR); +#endif +SYSCALL_DEF(linkat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR, ARG_ATFLAG); SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC); SYSCALL_DEF(mlockall, ARG_HEX); #ifdef TARGET_NR_mmap diff --git a/linux-user/strace.c b/linux-user/strace.c index 5cb77223fd..5b78eb137b 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1357,35 +1357,6 @@ print_futimesat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_link -static void -print_link(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_string(arg1, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_linkat -static void -print_linkat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_at_dirfd(arg2, 0); - print_string(arg3, 0); - print_flags(at_file_flags, arg4, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR__llseek static void print__llseek(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 62e1790e3b..c6ca80955b 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -40,6 +40,34 @@ SYSCALL_IMPL(creat) } #endif +static abi_long do_linkat(int olddirfd, abi_ulong target_oldpath, + int newdirfd, abi_ulong target_newpath, + int flags) +{ + char *oldpath = lock_user_string(target_oldpath); + char *newpath = lock_user_string(target_newpath); + abi_long ret = -TARGET_EFAULT; + + if (oldpath && newpath) { + ret = get_errno(linkat(olddirfd, oldpath, newdirfd, newpath, flags)); + } + unlock_user(oldpath, target_oldpath, 0); + unlock_user(newpath, target_newpath, 0); + return ret; +} + +#ifdef TARGET_NR_link +SYSCALL_IMPL(link) +{ + return do_linkat(AT_FDCWD, arg1, AT_FDCWD, arg2, 0); +} +#endif + +SYSCALL_IMPL(linkat) +{ + return do_linkat(arg1, arg2, arg3, arg4, arg5); +} + /* * Helpers for do_openat, manipulating /proc/self/foo. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1e9478611c..f1e8d06996 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5330,38 +5330,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_link - case TARGET_NR_link: - { - void * p2; - p = lock_user_string(arg1); - p2 = lock_user_string(arg2); - if (!p || !p2) - ret = -TARGET_EFAULT; - else - ret = get_errno(link(p, p2)); - unlock_user(p2, arg2, 0); - unlock_user(p, arg1, 0); - } - return ret; -#endif -#if defined(TARGET_NR_linkat) - case TARGET_NR_linkat: - { - void * p2 = NULL; - if (!arg2 || !arg4) - return -TARGET_EFAULT; - p = lock_user_string(arg2); - p2 = lock_user_string(arg4); - if (!p || !p2) - ret = -TARGET_EFAULT; - else - ret = get_errno(linkat(arg1, p, arg3, p2, arg5)); - unlock_user(p, arg2, 0); - unlock_user(p2, arg4, 0); - } - return ret; -#endif #ifdef TARGET_NR_unlink case TARGET_NR_unlink: if (!(p = lock_user_string(arg1))) diff --git a/linux-user/strace.list b/linux-user/strace.list index be0392810c..c369915759 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -461,12 +461,6 @@ #ifdef TARGET_NR_lgetxattr { TARGET_NR_lgetxattr, "lgetxattr" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_link -{ TARGET_NR_link, "link" , NULL, print_link, NULL }, -#endif -#ifdef TARGET_NR_linkat -{ TARGET_NR_linkat, "linkat" , NULL, print_linkat, NULL }, -#endif #ifdef TARGET_NR_Linux { TARGET_NR_Linux, "Linux" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="eXhnTrPE"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF4m0PhJz9sDP for ; Sat, 19 Jan 2019 08:51:04 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47653 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc2Y-0003JV-0L for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:51:02 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56075) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkf-0005Mf-3s for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkd-0004tV-SZ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:33 -0500 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]:45120) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkd-0004l3-Lg for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:31 -0500 Received: by mail-pg1-x541.google.com with SMTP id y4so6629776pgc.12 for ; Fri, 18 Jan 2019 13:32:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QcTx9xUhMTLOsLF+/TTUz9FMaNWvx4h/CHXeU4naRY4=; b=eXhnTrPEwO/i7yQAyszRaTn5Ou3JnH4crOFCaBUPcC6Wh8Y1Re9mSHX0CleIz0FQFT /DrodTmZnAeMHAhTEgyi4EWIsFfdR76Qm110wRjlmBz4cDzdYYXlh9RVT6PYPkwd84S0 OXNizxQTCnQ23SI6WQ26D4XE981zu9YQUsg2Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QcTx9xUhMTLOsLF+/TTUz9FMaNWvx4h/CHXeU4naRY4=; b=RZu4sZPXwLxZez7jfxm8Xd/ehyGkU087aKvN8V4yueQqu8559jU2IQoB+u48r79DqK 0eBpXJ9TinLH42WEn7oNZaIEaTsx5zDYOxjHf4U4mEE6Qg2hp+BMRh8p/D/d9DUXhlfb FtCWQQl/j2sUHB5Ek7FpcclqYrhAmal43XDfRCVW+D10xFxnV2tg7W6UgYOg5bESsO5W EDspB67hHxCSq2XrA9FBBtJKVQfJuKGVQr4qsaUBH0dvW7cTsEX3DvWp7AdMHO000TGP Ny2jxjTDgKoqALFEP7NNoK+hctkmPz8WVRrr7S/Qmy6+3dlNNHmpUwHc91IHki7AXll4 Ub1A== X-Gm-Message-State: AJcUuke/NkDPGt4kZWAdfvNiGh7H+zPxpyUebBIYmg0badNXyBQ5M9iB YCzP9BSCD9SY5ar19pUQ1/Ck4fki1D4= X-Google-Smtp-Source: ALg8bN4mrLUuFFlJ/DMQxQGVdBpgK6MXHINHZW6LAN5PdiotZI4dm9+Gd+pH+IQNydKQo+0rqEvjsw== X-Received: by 2002:a63:2406:: with SMTP id k6mr18682337pgk.229.1547847141836; Fri, 18 Jan 2019 13:32:21 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:21 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:56 +1100 Message-Id: <20190118213122.22865-23-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::541 Subject: [Qemu-devel] [PATCH v6 23/49] linux-user: Split out unlink, unlinkat, rmdir X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that unlinkat is universally provided. Implement rmdir in terms of unlinkat. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 7 ++++++ linux-user/syscall.h | 1 + linux-user/strace.c | 43 ++++------------------------------- linux-user/syscall-file.inc.c | 32 ++++++++++++++++++++++++++ linux-user/syscall.c | 24 ------------------- linux-user/strace.list | 9 -------- 6 files changed, 44 insertions(+), 72 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 41dd887dbc..78d3f600eb 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -98,6 +98,9 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC); #endif SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC); +#ifdef TARGET_NR_rmdir +SYSCALL_DEF(rmdir, ARG_STR); +#endif #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl) SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX); #endif @@ -121,6 +124,10 @@ SYSCALL_DEF(shmdt, ARG_PTR); #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget) SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); #endif +#ifdef TARGET_NR_unlink +SYSCALL_DEF(unlink, ARG_STR); +#endif +SYSCALL_DEF(unlinkat, ARG_ATDIRFD, ARG_STR, ARG_UNLINKATFLAG); #ifdef TARGET_NR_vfork /* Emulate vfork() with fork(). */ SYSCALL_DEF_FULL(vfork, .impl = impl_fork); diff --git a/linux-user/syscall.h b/linux-user/syscall.h index f75cd3ddd0..bdc4d653c4 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -63,6 +63,7 @@ typedef enum { ARG_MMAPPROT, ARG_MODEFLAG, ARG_OPENFLAG, + ARG_UNLINKATFLAG, /* These are interpreted as pointers. */ ARG_PTR, diff --git a/linux-user/strace.c b/linux-user/strace.c index 5b78eb137b..a41b6dcfe7 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -684,7 +684,7 @@ static struct flags const at_file_flags[] = { FLAG_END, }; -UNUSED static struct flags unlinkat_flags[] = { +static struct flags const unlinkat_flags[] = { #ifdef AT_REMOVEDIR FLAG_GENERIC(AT_REMOVEDIR), #endif @@ -1798,18 +1798,6 @@ print_mkdirat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_rmdir -static void -print_rmdir(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_rt_sigaction static void print_rt_sigaction(const struct syscallname *name, @@ -2175,32 +2163,6 @@ print_umount2(const struct syscallname *name, } #endif -#ifdef TARGET_NR_unlink -static void -print_unlink(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_unlinkat -static void -print_unlinkat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_flags(unlinkat_flags, arg2, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_utime static void print_utime(const struct syscallname *name, @@ -2463,6 +2425,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_OPENFLAG: len = add_open_flags(b, rest, arg); break; + case ARG_UNLINKATFLAG: + len = add_flags(b, rest, unlinkat_flags, arg, true); + break; case ARG_PTR: len = add_pointer(b, rest, arg); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index c6ca80955b..2dd57176b3 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -656,6 +656,38 @@ SYSCALL_IMPL(readlinkat) } #endif +static abi_long do_unlinkat(int dirfd, abi_ulong target_path, int flags) +{ + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(unlinkat(dirfd, p, flags)); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_unlink +SYSCALL_IMPL(unlink) +{ + return do_unlinkat(AT_FDCWD, arg1, 0); +} +#endif + +#ifdef TARGET_NR_rmdir +SYSCALL_IMPL(rmdir) +{ + return do_unlinkat(AT_FDCWD, arg1, AT_REMOVEDIR); +} +#endif + +SYSCALL_IMPL(unlinkat) +{ + return do_unlinkat(arg1, arg2, arg3); +} + SYSCALL_IMPL(write) { int fd = arg1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f1e8d06996..eda199d46f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5330,22 +5330,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_unlink - case TARGET_NR_unlink: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(unlink(p)); - unlock_user(p, arg1, 0); - return ret; -#endif -#if defined(TARGET_NR_unlinkat) - case TARGET_NR_unlinkat: - if (!(p = lock_user_string(arg2))) - return -TARGET_EFAULT; - ret = get_errno(unlinkat(arg1, p, arg3)); - unlock_user(p, arg2, 0); - return ret; -#endif case TARGET_NR_execve: { char **argp, **envp; @@ -5737,14 +5721,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, ret = get_errno(mkdirat(arg1, p, arg3)); unlock_user(p, arg2, 0); return ret; -#endif -#ifdef TARGET_NR_rmdir - case TARGET_NR_rmdir: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(rmdir(p)); - unlock_user(p, arg1, 0); - return ret; #endif case TARGET_NR_dup: ret = get_errno(dup(arg1)); diff --git a/linux-user/strace.list b/linux-user/strace.list index c369915759..faa0a9012d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -527,9 +527,6 @@ #ifdef TARGET_NR_mkdirat { TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL }, #endif -#ifdef TARGET_NR_rmdir -{ TARGET_NR_rmdir, "rmdir" , NULL, print_rmdir, NULL }, -#endif #ifdef TARGET_NR_mknod { TARGET_NR_mknod, "mknod" , NULL, print_mknod, NULL }, #endif @@ -1425,12 +1422,6 @@ #ifdef TARGET_NR_uname { TARGET_NR_uname, "uname" , "%s(%p)", NULL, NULL }, #endif -#ifdef TARGET_NR_unlink -{ TARGET_NR_unlink, "unlink" , NULL, print_unlink, NULL }, -#endif -#ifdef TARGET_NR_unlinkat -{ TARGET_NR_unlinkat, "unlinkat" , NULL, print_unlinkat, NULL }, -#endif #ifdef TARGET_NR_unshare { TARGET_NR_unshare, "unshare" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027800 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="WrdM/qGh"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFSM5t4hz9sDL for ; Sat, 19 Jan 2019 09:08:03 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47911 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcIz-0000EH-NX for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:08:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56082) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkf-0005Mq-93 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkd-0004td-Tg for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:33 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:39398) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkd-0004mg-KQ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:31 -0500 Received: by mail-pf1-x441.google.com with SMTP id r136so7201503pfc.6 for ; Fri, 18 Jan 2019 13:32:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+fTBAf0C8A6A480A95zgMw1/4VjmqrTZEt0WUaFU6OY=; b=WrdM/qGhgkwRaH/ZDgr1cBia7AJE7mcAIf9Mr3+99xP0rDUiBGU9PxrhqvYcISISzd mn96+X7KraZOFFcZLVKa+H3obNcMY3/9UHVPZhL3aSbhha+4GNU6ezgNN0QpzSxoxI50 eK19z5d2jQdJJDXywx5wuff9tpJjfiKipntXw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+fTBAf0C8A6A480A95zgMw1/4VjmqrTZEt0WUaFU6OY=; b=jzurltqRSQXQ4VKavn2pIOpNZcejXWcjLpFtLVMcImaKfH/jXq09DqYU2f4bTjojvw TKq28j/t78Sovu5+HotOxwNNDiwnQOaITOenrLD6KX5rR3IZvGHocjk+bdbUKfexJHPH RxK+vxbxFoEj957+J4PKc4c7dTXWq2ns8AMihMgNyXywQuvKzrzPQQZD5gmKdxf8ND8l d77tG+kN30cIfEdj709tL9HDATI9mmcG8JxykhrYt2caMXiTy/7MV6gOHwiCdiPb2h8y yGMYYdipIUr/2FKIdujWiuyv8V4tBZEpPfsb21DwVS3/EZRCDda/SPbBI+i+YlU+2mTg SThQ== X-Gm-Message-State: AJcUukc2tx5W6Rrx8bPctx3gWnFjnIX5MfZVRBNdT0Dfr+zy4hwZ1p7A 8xg+rNviJ68heuI0GNX6Nm8CHz9DkFA= X-Google-Smtp-Source: ALg8bN7TkeV/XImL5Nny6UiCs2XPVNHq3f7HhioF+AZmmiwHge22QnUBs2RecUiYI3zvul/GmpW7HQ== X-Received: by 2002:a65:50c1:: with SMTP id s1mr18917189pgp.350.1547847144103; Fri, 18 Jan 2019 13:32:24 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.22 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:23 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:57 +1100 Message-Id: <20190118213122.22865-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 24/49] linux-user: Split out execve X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/strace.c | 32 ---------- linux-user/syscall-proc.inc.c | 110 ++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 97 ------------------------------ linux-user/strace.list | 3 - 5 files changed, 111 insertions(+), 132 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 78d3f600eb..58fef48666 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -25,6 +25,7 @@ SYSCALL_DEF(close, ARG_DEC); SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG); #endif SYSCALL_DEF(exit, ARG_DEC); +SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR); #ifdef TARGET_NR_fork SYSCALL_DEF(fork); #endif diff --git a/linux-user/strace.c b/linux-user/strace.c index a41b6dcfe7..43865e9df9 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -568,38 +568,6 @@ print_newselect(const struct syscallname *name, } #endif -static void -print_execve(const struct syscallname *name, - abi_long arg1, abi_long arg2, abi_long arg3, - abi_long arg4, abi_long arg5, abi_long arg6) -{ - abi_ulong arg_ptr_addr; - char *s; - - if (!(s = lock_user_string(arg1))) - return; - gemu_log("%s(\"%s\",{", name->name, s); - unlock_user(s, arg1, 0); - - for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) { - abi_ulong *arg_ptr, arg_addr; - - arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); - if (!arg_ptr) - return; - arg_addr = tswapal(*arg_ptr); - unlock_user(arg_ptr, arg_ptr_addr, 0); - if (!arg_addr) - break; - if ((s = lock_user_string(arg_addr))) { - gemu_log("\"%s\",", s); - unlock_user(s, arg_addr, 0); - } - } - - gemu_log("NULL})"); -} - /* * Variants for the return value output function */ diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index de4efed9f4..552aea60ae 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -269,6 +269,116 @@ SYSCALL_IMPL(clone) return do_clone(cpu_env, arg1, arg2, arg3, arg4, arg5); } +SYSCALL_IMPL(execve) +{ + char **argp, **envp; + int argc, envc; + abi_ulong gp; + abi_ulong guest_path = arg1; + abi_ulong guest_argp = arg2; + abi_ulong guest_envp = arg3; + abi_ulong addr; + char **q, *p; + int total_size = 0; + abi_long ret = -TARGET_EFAULT; + + argc = 0; + for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) { + if (get_user_ual(addr, gp)) { + goto execve_nofree; + } + if (!addr) { + break; + } + argc++; + } + envc = 0; + for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) { + if (get_user_ual(addr, gp)) { + goto execve_nofree; + } + if (!addr) { + break; + } + envc++; + } + + argp = g_new0(char *, argc + 1); + envp = g_new0(char *, envc + 1); + + for (gp = guest_argp, q = argp; gp; gp += sizeof(abi_ulong), q++) { + char *this_q; + + if (get_user_ual(addr, gp)) { + goto execve_free; + } + if (!addr) { + break; + } + this_q = lock_user_string(addr); + if (!this_q) { + goto execve_free; + } + *q = this_q; + total_size += strlen(this_q) + 1; + } + + for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { + char *this_q; + + if (get_user_ual(addr, gp)) { + goto execve_free; + } + if (!addr) { + break; + } + this_q = lock_user_string(addr); + if (!this_q) { + goto execve_free; + } + *q = this_q; + total_size += strlen(this_q) + 1; + } + + p = lock_user_string(guest_path); + if (!p) { + goto execve_free; + } + + /* + * Although execve() is not an interruptible syscall it is + * a special case where we must use the safe_syscall wrapper: + * if we allow a signal to happen before we make the host + * syscall then we will 'lose' it, because at the point of + * execve the process leaves QEMU's control. So we use the + * safe syscall wrapper to ensure that we either take the + * signal as a guest signal, or else it does not happen + * before the execve completes and makes it the other + * program's problem. + */ + ret = get_errno(safe_execve(p, argp, envp)); + unlock_user(p, guest_path, 0); + + execve_free: + for (gp = guest_argp, q = argp; *q; gp += sizeof(abi_ulong), q++) { + if (get_user_ual(addr, gp) || !addr) { + break; + } + unlock_user(*q, addr, 0); + } + for (gp = guest_envp, q = envp; *q; gp += sizeof(abi_ulong), q++) { + if (get_user_ual(addr, gp) || !addr) { + break; + } + unlock_user(*q, addr, 0); + } + g_free(argp); + g_free(envp); + + execve_nofree: + return ret; +} + SYSCALL_IMPL(exit) { CPUState *cpu = ENV_GET_CPU(cpu_env); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index eda199d46f..9b5b2eb7f1 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5330,103 +5330,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_execve: - { - char **argp, **envp; - int argc, envc; - abi_ulong gp; - abi_ulong guest_argp; - abi_ulong guest_envp; - abi_ulong addr; - char **q; - int total_size = 0; - - argc = 0; - guest_argp = arg2; - for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) { - if (get_user_ual(addr, gp)) - return -TARGET_EFAULT; - if (!addr) - break; - argc++; - } - envc = 0; - guest_envp = arg3; - for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) { - if (get_user_ual(addr, gp)) - return -TARGET_EFAULT; - if (!addr) - break; - envc++; - } - - argp = g_new0(char *, argc + 1); - envp = g_new0(char *, envc + 1); - - for (gp = guest_argp, q = argp; gp; - gp += sizeof(abi_ulong), q++) { - if (get_user_ual(addr, gp)) - goto execve_efault; - if (!addr) - break; - if (!(*q = lock_user_string(addr))) - goto execve_efault; - total_size += strlen(*q) + 1; - } - *q = NULL; - - for (gp = guest_envp, q = envp; gp; - gp += sizeof(abi_ulong), q++) { - if (get_user_ual(addr, gp)) - goto execve_efault; - if (!addr) - break; - if (!(*q = lock_user_string(addr))) - goto execve_efault; - total_size += strlen(*q) + 1; - } - *q = NULL; - - if (!(p = lock_user_string(arg1))) - goto execve_efault; - /* Although execve() is not an interruptible syscall it is - * a special case where we must use the safe_syscall wrapper: - * if we allow a signal to happen before we make the host - * syscall then we will 'lose' it, because at the point of - * execve the process leaves QEMU's control. So we use the - * safe syscall wrapper to ensure that we either take the - * signal as a guest signal, or else it does not happen - * before the execve completes and makes it the other - * program's problem. - */ - ret = get_errno(safe_execve(p, argp, envp)); - unlock_user(p, arg1, 0); - - goto execve_end; - - execve_efault: - ret = -TARGET_EFAULT; - - execve_end: - for (gp = guest_argp, q = argp; *q; - gp += sizeof(abi_ulong), q++) { - if (get_user_ual(addr, gp) - || !addr) - break; - unlock_user(*q, addr, 0); - } - for (gp = guest_envp, q = envp; *q; - gp += sizeof(abi_ulong), q++) { - if (get_user_ual(addr, gp) - || !addr) - break; - unlock_user(*q, addr, 0); - } - - g_free(argp); - g_free(envp); - } - return ret; case TARGET_NR_chdir: if (!(p = lock_user_string(arg1))) return -TARGET_EFAULT; diff --git a/linux-user/strace.list b/linux-user/strace.list index faa0a9012d..8bc3fe6088 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -139,9 +139,6 @@ #ifdef TARGET_NR_execv { TARGET_NR_execv, "execv" , NULL, print_execv, NULL }, #endif -#ifdef TARGET_NR_execve -{ TARGET_NR_execve, "execve" , NULL, print_execve, NULL }, -#endif #ifdef TARGET_NR_execveat { TARGET_NR_execveat, "execveat" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027763 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ayx2SJw/"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDpm0d4wz9sDL for ; Sat, 19 Jan 2019 08:38:55 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47472 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbqn-0001bW-PH for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:38:53 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56111) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkh-0005Op-Mn for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkd-0004tD-QN for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:35 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:38208) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkd-0004oi-Ct for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:31 -0500 Received: by mail-pf1-x441.google.com with SMTP id q1so7203420pfi.5 for ; Fri, 18 Jan 2019 13:32:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SMMAnvYSaJFQPxNPvJ9sKrp9BWoGMbm6WSf/IZZEqBk=; b=ayx2SJw/eNyyLQfY/KBNKHKQC4LGeUPls6JB0538aL+esqd39unFc535e7O1WPljGK paObudBLPWUFwRLotcdghcX9vnEmTTb0M2DCHsFvhv3x9uBuRn1aaeEu/YH8lOlqCmd6 KO3CaXU6R0RCdn1Q4PscWl/ZfQIlGryzI+olg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SMMAnvYSaJFQPxNPvJ9sKrp9BWoGMbm6WSf/IZZEqBk=; b=mpL+g9Xbweq4r1l2V5FxmWqZ09+giow6C8QiVt4IT9U5c1LvtOd3fMoGQLt3KzO+6B 2jpufdV6MRhQ8DEtnQG/kHwxDpROZKAylvCbss/55a1pieNc4ebcNYRwR+D9CkjQU5bB uAgB6UuDmO+3kok1EDPgWUwRL5mZhIwDPBpHloA83z4jAg3fwFLfG3Gzt92rCnyG8qld iQvplXlRkc0la3Jqf9ixkgSPxzricl4Nes+cd5o2/jcRirCht/rEYNW0D6jfi3xs1qfe wd25prFmr2SLs6CXFXuuHbxSlnYGHTKrH+PJy3rZ7H29W0UXd9Lypf/WSae/4FOMk1Zn KifA== X-Gm-Message-State: AJcUukfHDZeX3vI5dLDl5cDl8dJ3OIgJFLlIUd75JsN/2iV0pQwBtU2q bl7oqg/YUQ2cHLpKy396Kx1tB90hMsk= X-Google-Smtp-Source: ALg8bN61DjmIFOKdZObCJmXp1H2FQwc9bt7udoFqkj6gB7nenD6otqdl4PrNS1h72bEBrLlGFdoj/A== X-Received: by 2002:a63:ca02:: with SMTP id n2mr19516194pgi.187.1547847146607; Fri, 18 Jan 2019 13:32:26 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:25 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:58 +1100 Message-Id: <20190118213122.22865-25-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 25/49] linux-user: Implement execveat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A trivial extension to our current execve implementation to support the new(ish) syscall. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall-proc.inc.c | 19 ++++++++++++++----- linux-user/syscall.c | 3 ++- linux-user/strace.list | 3 --- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 58fef48666..392bd1579c 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -26,6 +26,7 @@ SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG); #endif SYSCALL_DEF(exit, ARG_DEC); SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR); +SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); #ifdef TARGET_NR_fork SYSCALL_DEF(fork); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index 552aea60ae..699370c290 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -269,14 +269,13 @@ SYSCALL_IMPL(clone) return do_clone(cpu_env, arg1, arg2, arg3, arg4, arg5); } -SYSCALL_IMPL(execve) +static abi_long do_execveat(int dirfd, abi_ulong guest_path, + abi_ulong guest_argp, abi_ulong guest_envp, + int flags) { char **argp, **envp; int argc, envc; abi_ulong gp; - abi_ulong guest_path = arg1; - abi_ulong guest_argp = arg2; - abi_ulong guest_envp = arg3; abi_ulong addr; char **q, *p; int total_size = 0; @@ -356,7 +355,7 @@ SYSCALL_IMPL(execve) * before the execve completes and makes it the other * program's problem. */ - ret = get_errno(safe_execve(p, argp, envp)); + ret = get_errno(safe_execveat(dirfd, p, argp, envp, flags)); unlock_user(p, guest_path, 0); execve_free: @@ -379,6 +378,16 @@ SYSCALL_IMPL(execve) return ret; } +SYSCALL_IMPL(execve) +{ + return do_execveat(AT_FDCWD, arg1, arg2, arg3, 0); +} + +SYSCALL_IMPL(execveat) +{ + return do_execveat(arg1, arg2, arg3, arg4, arg5); +} + SYSCALL_IMPL(exit) { CPUState *cpu = ENV_GET_CPU(cpu_env); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9b5b2eb7f1..3a027651e3 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -682,7 +682,8 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \ struct rusage *, rusage) safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \ int, options, struct rusage *, rusage) -safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp) +safe_syscall5(int, execveat, int, dirfd, const char *, filename, + char **, argv, char **, envp, int, flags) safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \ fd_set *, exceptfds, struct timespec *, timeout, void *, sig) safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds, diff --git a/linux-user/strace.list b/linux-user/strace.list index 8bc3fe6088..202bfa8f9e 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -139,9 +139,6 @@ #ifdef TARGET_NR_execv { TARGET_NR_execv, "execv" , NULL, print_execv, NULL }, #endif -#ifdef TARGET_NR_execveat -{ TARGET_NR_execveat, "execveat" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_exec_with_loader { TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:30:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027798 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="JlGVG4iQ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFP76FP8z9sDL for ; Sat, 19 Jan 2019 09:05:15 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47842 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcGH-0006ND-4k for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:05:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56049) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbke-0005MB-IG for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkd-0004t6-MG for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:32 -0500 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]:36043) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkd-0004r5-AK for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:31 -0500 Received: by mail-pg1-x543.google.com with SMTP id n2so6650154pgm.3 for ; Fri, 18 Jan 2019 13:32:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hmuO8q5HCd/lfOBJ33u/IYvoVONCPzg6P8Xq5WUIsgQ=; b=JlGVG4iQ3sApX5NE0K9+HxL5+N/lPcqMn4BIsk6TkzOnijcxaLSG4IW1DTzBP5Lo0n vh0a+zFRiAJqqBTyvLiO9UeZXHP8XJ/l8VsXM+WXO3KbWT0KnE31rANfJMwavHblua0y /ZRS99DXDa82RRSf0BfHoufZhYo/yGM17rw04= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hmuO8q5HCd/lfOBJ33u/IYvoVONCPzg6P8Xq5WUIsgQ=; b=mYWS+0NxGEx+zNOS1rgWkxIxKeFvMVVwXfdCcHFnBYSlrkE8EcwkruSoXHurxwuWim f8m4mO6xJFefWHKxoqBRy1MXsHz0JY7HS5KUWZxl8d/GhiiJS1pfG7s/+0xpCFP819C1 aSruJBItansIGiRLIRYacL0E2vckj72TGQmEFc2GX+WFiStY53zR9ifqB6YoBnWDdJBl XEYMDHW/GnblT+lWLwhKOtvVs3TvkuULqkNxq80Jhmn+MhUBJIp81eKqYqGDhYDF4sTX R0QUMu3uGjfT8lEY1JjvLnqTf072lBJJq3YP7VdX5TTteS76isR9Gh66si9J+hwvmplf Z56g== X-Gm-Message-State: AJcUukftj14yqNu6DwA/pSrXTUJCBtYkPrm9OfcVT0tyTefwBwr9qMIi ZGys1zHolYFXpSLi7Mk92vGQU79gAQ4= X-Google-Smtp-Source: ALg8bN7JIqsjBB+n3g8HnUsXfq5a85q4FTyCwF2diD+M9PW9Hf0eObnLb7XR14dsw5d7JjBkbQsfEg== X-Received: by 2002:a63:2109:: with SMTP id h9mr19162227pgh.277.1547847148882; Fri, 18 Jan 2019 13:32:28 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:28 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:30:59 +1100 Message-Id: <20190118213122.22865-26-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::543 Subject: [Qemu-devel] [PATCH v6 26/49] linux-user: Split out chdir X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that chdir is universally provided. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/strace.c | 12 ------------ linux-user/syscall-file.inc.c | 14 ++++++++++++++ linux-user/syscall.c | 6 ------ linux-user/strace.list | 3 --- 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 392bd1579c..3fad9d51f0 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -19,6 +19,7 @@ SYSCALL_DEF_FULL(brk, .impl = impl_brk, .print_ret = print_syscall_ptr_ret, .arg_type = { ARG_PTR }); +SYSCALL_DEF(chdir, ARG_STR); SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR); SYSCALL_DEF(close, ARG_DEC); #ifdef TARGET_NR_creat diff --git a/linux-user/strace.c b/linux-user/strace.c index 43865e9df9..5133998c4f 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1113,18 +1113,6 @@ print_access(const struct syscallname *name, } #endif -#ifdef TARGET_NR_chdir -static void -print_chdir(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_chmod static void print_chmod(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 2dd57176b3..7a4751d460 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -16,6 +16,20 @@ * along with this program; if not, see . */ +SYSCALL_IMPL(chdir) +{ + abi_ulong target_path = arg1; + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(chdir(p)); + unlock_user(p, target_path, 0); + return ret; +} + SYSCALL_IMPL(close) { int fd = arg1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 3a027651e3..1cdc9727a9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5331,12 +5331,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_chdir: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(chdir(p)); - unlock_user(p, arg1, 0); - return ret; #ifdef TARGET_NR_time case TARGET_NR_time: { diff --git a/linux-user/strace.list b/linux-user/strace.list index 202bfa8f9e..357984dd6f 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -61,9 +61,6 @@ #ifdef TARGET_NR_capset { TARGET_NR_capset, "capset" , "%s(%p,%p)", NULL, NULL }, #endif -#ifdef TARGET_NR_chdir -{ TARGET_NR_chdir, "chdir" , NULL, print_chdir, NULL }, -#endif #ifdef TARGET_NR_chmod { TARGET_NR_chmod, "chmod" , NULL, print_chmod, NULL }, #endif From patchwork Fri Jan 18 21:31:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027767 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="AZ/t2HYf"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDt81lrVz9s9G for ; Sat, 19 Jan 2019 08:41:52 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47526 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbte-0004F0-41 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:41:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56089) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkf-0005Ni-Sd for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbke-0004v5-IN for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:33 -0500 Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]:41193) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbke-0004tQ-Bd for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:32 -0500 Received: by mail-pf1-x444.google.com with SMTP id b7so7192468pfi.8 for ; Fri, 18 Jan 2019 13:32:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=N4AEijcfhSLtaoaWm0ch5ZKqRV8AkG+w+zrqUah4AVM=; b=AZ/t2HYfbMEAscbm9eF9lL7HFTboFB8Knwj0Lw+6oTlElkkg5/j8AqLjhX6CkNTc5L 8v+jmyWu2JSuXyQ/kPN8STB5sBzIzRd2Lrdj7hJRwbk/6zWSHKVKVmU4WBDAHHc0kYPe FtMTw2EyyuRlIiXMnBn5nBlKRX4pAjhrf+gxE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=N4AEijcfhSLtaoaWm0ch5ZKqRV8AkG+w+zrqUah4AVM=; b=TzNsrjGgloJ4Rmed/YifZrccASR+4yPKSAdskCNVMOZRxa5tQeW2HSXCZrk96bpMRS /YagJhfJxYidIxEVumTebSwxmQ/RBBmmJJkdElrkdEJJxCn4bAYEyvjx9R1fhSM2JeZt +DQ1K7A4rVzRNSpFWPImoyf2X9x9hYqjVVJXjDBAMddigI5GNW8nKR0KYjtm/IhcT1R2 JA00T72smP/rGZkMjwX/3PyXTgVuga/tEUSi0nz8/UBH1kHZts861erTMTkVon+93LtG l07l5HOo/42fwXcL7/wPSik32ggdNiBw5fXJfX6zHMc6sQ8j7x84nF7/pnenOdd/IXnY bc+g== X-Gm-Message-State: AJcUukec98WKVmjKk67FSO4Irsa1jHMLrGQWSzbfmErFay8qOv60Fbrh CXzH8a70wE6Lz+zp49Cs/p3IxxI32iw= X-Google-Smtp-Source: ALg8bN6B8BaHZQkaDB1LIV9V0zcNbIouYExxADUxllf+yPUGbmzWI7tBawsCu2M+YSwlhvHkV+UfUA== X-Received: by 2002:a63:5b48:: with SMTP id l8mr19413851pgm.80.1547847151052; Fri, 18 Jan 2019 13:32:31 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:30 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:00 +1100 Message-Id: <20190118213122.22865-27-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::444 Subject: [Qemu-devel] [PATCH v6 27/49] linux-user: Split out time X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 3 +++ linux-user/syscall-time.inc.c | 32 ++++++++++++++++++++++++++++++++ linux-user/syscall.c | 13 +------------ linux-user/strace.list | 3 --- 4 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 linux-user/syscall-time.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 3fad9d51f0..9950b73e76 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -127,6 +127,9 @@ SYSCALL_DEF(shmdt, ARG_PTR); #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget) SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); #endif +#ifdef TARGET_NR_time +SYSCALL_DEF(time, ARG_PTR); +#endif #ifdef TARGET_NR_unlink SYSCALL_DEF(unlink, ARG_STR); #endif diff --git a/linux-user/syscall-time.inc.c b/linux-user/syscall-time.inc.c new file mode 100644 index 0000000000..14fec88e47 --- /dev/null +++ b/linux-user/syscall-time.inc.c @@ -0,0 +1,32 @@ +/* + * Linux time related syscalls + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifdef TARGET_NR_time +SYSCALL_IMPL(time) +{ + time_t host_time; + abi_long ret = get_errno(time(&host_time)); + + if (!is_error(ret) + && arg1 + && put_user_sal(host_time, arg1)) { + return -TARGET_EFAULT; + } + return ret; +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1cdc9727a9..cc5360ae43 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5331,18 +5331,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_time - case TARGET_NR_time: - { - time_t host_time; - ret = get_errno(time(&host_time)); - if (!is_error(ret) - && arg1 - && put_user_sal(host_time, arg1)) - return -TARGET_EFAULT; - } - return ret; -#endif #ifdef TARGET_NR_mknod case TARGET_NR_mknod: if (!(p = lock_user_string(arg1))) @@ -9303,6 +9291,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #include "syscall-ipc.inc.c" #include "syscall-mem.inc.c" #include "syscall-proc.inc.c" +#include "syscall-time.inc.c" #undef SYSCALL_IMPL #undef SYSCALL_ARGS diff --git a/linux-user/strace.list b/linux-user/strace.list index 357984dd6f..3505014501 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1350,9 +1350,6 @@ #ifdef TARGET_NR_tgkill { TARGET_NR_tgkill, "tgkill" , NULL, print_tgkill, NULL }, #endif -#ifdef TARGET_NR_time -{ TARGET_NR_time, "time" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_timer_create { TARGET_NR_timer_create, "timer_create" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027801 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="EObQG4nu"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFWS6KT0z9sDB for ; Sat, 19 Jan 2019 09:10:43 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47935 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcLY-0002cW-Fy for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:10:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56109) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkh-0005Oo-M3 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkg-0004xv-N7 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:35 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:37340) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkg-0004xP-HH for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:34 -0500 Received: by mail-pg1-x544.google.com with SMTP id c25so6649801pgb.4 for ; Fri, 18 Jan 2019 13:32:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1cv5rx86Uif3gdCSQE6eFlguRpyPaS7fmT8hkmM0gW4=; b=EObQG4nuDsnIvWzbvn0qYPt39Ru9AoQ74VmdTOkzm5kjMUS8/bUjB6VD0hZIMJvSvT gOLYlmT1njo7IQJpc5Ww4ZjKcJxdDtx2xUUR6cwnf6V76trqbURHDvH0Z3cCdbEvN4El i+UVTtmTWX8QenZaQxT9pyAhW2NxQwMI1lIhY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1cv5rx86Uif3gdCSQE6eFlguRpyPaS7fmT8hkmM0gW4=; b=tfZWpYSHj2xaA2fQlTz5go7LL7J/XILjoaIGeGmUhjm+zoBIZqNQlW3AvRl7Bfj1te 9VXwpB/uqllQ6onF527Q6I0vq/sq/ZO8f37DSEPKNfUbDLEdqN/VIuhtHZUUNjtRDX6C 083xZyC/AdASK3OLabNLMxJrQmWtk/HJsrqBNIDhl1TQddcuib6uEQ2uzSA9tHS2PYkF XbxgTKStoZd+J1X4Yeh173zuVuJ2Mb6ZaYUGINsbfg5WJuRuhIZmttHbREhupKgQgY9+ a1eTA1DLg/k2t0iJnOyFk8rXNIQUpV+xJXNWB069MvjidoGuE8YQN6A8KeBoI0XRZWWY 10uQ== X-Gm-Message-State: AJcUukeu6ZnY0H3ZfJtUs/nZ8nKj+5VjQN2URooLKDMU5LdxKutbEKkB LnDheE07m1OvTASgp7vRVlXNMvFXLfI= X-Google-Smtp-Source: ALg8bN50yI0H+5S32WhCxQ8Ierl8xgMJCcvhQ53S95SPF53pSQBLp79QrJ8HlBaVWtvrMYfTMaDI6g== X-Received: by 2002:a63:e302:: with SMTP id f2mr19576651pgh.320.1547847153286; Fri, 18 Jan 2019 13:32:33 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.31 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:32 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:01 +1100 Message-Id: <20190118213122.22865-28-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::544 Subject: [Qemu-devel] [PATCH v6 28/49] linux-user: Split out mknod, mknodat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that mknodat is universally provided. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 4 ++++ linux-user/strace.c | 39 ----------------------------------- linux-user/syscall-file.inc.c | 26 +++++++++++++++++++++++ linux-user/syscall.c | 16 -------------- linux-user/strace.list | 6 ------ 5 files changed, 30 insertions(+), 61 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 9950b73e76..b5951e6911 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -38,6 +38,10 @@ SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); SYSCALL_DEF(link, ARG_STR, ARG_STR); #endif SYSCALL_DEF(linkat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR, ARG_ATFLAG); +#ifdef TARGET_NR_mknod +SYSCALL_DEF(mknod, ARG_STR, ARG_MODEFLAG, ARG_HEX); +#endif +SYSCALL_DEF(mknodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG, ARG_HEX); SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC); SYSCALL_DEF(mlockall, ARG_HEX); #ifdef TARGET_NR_mmap diff --git a/linux-user/strace.c b/linux-user/strace.c index 5133998c4f..668e6a4759 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1911,45 +1911,6 @@ print_syslog(const struct syscallname *name, } #endif -#ifdef TARGET_NR_mknod -static void -print_mknod(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - int hasdev = (arg1 & (S_IFCHR|S_IFBLK)); - - print_syscall_prologue(name); - print_string(arg0, 0); - print_file_mode(arg1, (hasdev == 0)); - if (hasdev) { - print_raw_param("makedev(%d", major(arg2), 0); - print_raw_param("%d)", minor(arg2), 1); - } - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_mknodat -static void -print_mknodat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - int hasdev = (arg2 & (S_IFCHR|S_IFBLK)); - - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_file_mode(arg2, (hasdev == 0)); - if (hasdev) { - print_raw_param("makedev(%d", major(arg3), 0); - print_raw_param("%d)", minor(arg3), 1); - } - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_mq_open static void print_mq_open(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 7a4751d460..3b5a79fe74 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -82,6 +82,32 @@ SYSCALL_IMPL(linkat) return do_linkat(arg1, arg2, arg3, arg4, arg5); } +static abi_long do_mknodat(int dirfd, abi_ulong target_path, + mode_t mode, dev_t dev) +{ + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(mknodat(dirfd, p, mode, dev)); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_mknod +SYSCALL_IMPL(mknod) +{ + return do_mknodat(AT_FDCWD, arg1, arg2, arg3); +} +#endif + +SYSCALL_IMPL(mknodat) +{ + return do_mknodat(arg1, arg2, arg3, arg4); +} + /* * Helpers for do_openat, manipulating /proc/self/foo. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index cc5360ae43..d46b4df677 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5331,22 +5331,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_mknod - case TARGET_NR_mknod: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(mknod(p, arg2, arg3)); - unlock_user(p, arg1, 0); - return ret; -#endif -#if defined(TARGET_NR_mknodat) - case TARGET_NR_mknodat: - if (!(p = lock_user_string(arg2))) - return -TARGET_EFAULT; - ret = get_errno(mknodat(arg1, p, arg3, arg4)); - unlock_user(p, arg2, 0); - return ret; -#endif #ifdef TARGET_NR_chmod case TARGET_NR_chmod: if (!(p = lock_user_string(arg1))) diff --git a/linux-user/strace.list b/linux-user/strace.list index 3505014501..adf8955278 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -518,12 +518,6 @@ #ifdef TARGET_NR_mkdirat { TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL }, #endif -#ifdef TARGET_NR_mknod -{ TARGET_NR_mknod, "mknod" , NULL, print_mknod, NULL }, -#endif -#ifdef TARGET_NR_mknodat -{ TARGET_NR_mknodat, "mknodat" , NULL, print_mknodat, NULL }, -#endif #ifdef TARGET_NR_modify_ldt { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027804 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XyA4wkCo"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFY86Jc8z9sDB for ; Sat, 19 Jan 2019 09:12:12 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47998 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcN0-00043F-Rg for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:12:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkn-0005Sk-Jn for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkl-000528-Pi for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:41 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:40106) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkj-0004zL-SC for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:39 -0500 Received: by mail-pl1-x642.google.com with SMTP id u18so6885895plq.7 for ; Fri, 18 Jan 2019 13:32:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zDlRdC1NTM0KeXCW3hCrt9ktirWpz96vKzURH5zW4i8=; b=XyA4wkCo4kDR69tsrOfi02xcYWXge3mzqsLLeJZ4jlReLt5n8Cw6ta1s1fP0aCHdWw KFqzm//w6QD29FEGN97NGpq5qRTnfBpoyxgcbYSt8lsplk8tN6bhUsO5k4f6Eue31tgM 55ANuq71H9287lobOZoptBVqFNFEKV686W8Zo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zDlRdC1NTM0KeXCW3hCrt9ktirWpz96vKzURH5zW4i8=; b=cJUV8MvlheE29PPrWOz/qHF4yYUaAR2HsbcWT7GJasvF7+7KTAySALkPPyYP9KI4k1 2j85PfFvq9FX8Ct2AzINTWeLRi6DfT/gWXK+k9lDxddhY/l0/WIx5St0Kc+1Tnbr7i96 YS8ZUMoSA7G2HjCuNbRW6Sq8lW+XyVOqRYdn3aataVPDKG9kkGYRTReADJ6025bet9zL VNIvKdytVE6fcD5aEDNkuDQsjj0CfrTKmJWPgNIr+8nli6VS5coD9bgySdtJHOihlZwM 5bO/WPmUoDOrdpoPI8DJdez57bs4bdJ6zDVg1AnxA5PdGW+IjTityr4467qgClf3GcVy ULTQ== X-Gm-Message-State: AJcUukdk4Wvb+xZpgCNurQULi6ky4FUPJU1QalQuZXgpCO28A4ZLCfOV XRdhAblvvsBC9f2GBP5odgrmekszXI8= X-Google-Smtp-Source: ALg8bN7GF8W9N+Bm2fu3PdUnoq5j00r/pSjJo5tdFz5Ci6WglP5z2GjtT1PvW+/j2mGWcET0t3IS5Q== X-Received: by 2002:a17:902:8f97:: with SMTP id z23mr20957641plo.283.1547847155448; Fri, 18 Jan 2019 13:32:35 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.33 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:34 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:02 +1100 Message-Id: <20190118213122.22865-29-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH v6 29/49] linux-user: Split out chmod, fchmod, fchmodat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that fchmodat is universally provided. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 5 +++++ linux-user/strace.c | 28 ---------------------------- linux-user/syscall-file.inc.c | 30 ++++++++++++++++++++++++++++++ linux-user/syscall.c | 18 ------------------ linux-user/strace.list | 9 --------- 5 files changed, 35 insertions(+), 55 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index b5951e6911..3ddf8aa0e3 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -20,6 +20,9 @@ SYSCALL_DEF_FULL(brk, .impl = impl_brk, .print_ret = print_syscall_ptr_ret, .arg_type = { ARG_PTR }); SYSCALL_DEF(chdir, ARG_STR); +#ifdef TARGET_NR_chmod +SYSCALL_DEF(chmod, ARG_STR, ARG_MODEFLAG); +#endif SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR); SYSCALL_DEF(close, ARG_DEC); #ifdef TARGET_NR_creat @@ -28,6 +31,8 @@ SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG); SYSCALL_DEF(exit, ARG_DEC); SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR); SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); +SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG); +SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG); #ifdef TARGET_NR_fork SYSCALL_DEF(fork); #endif diff --git a/linux-user/strace.c b/linux-user/strace.c index 668e6a4759..66d981b9e6 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1113,19 +1113,6 @@ print_access(const struct syscallname *name, } #endif -#ifdef TARGET_NR_chmod -static void -print_chmod(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_file_mode(arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_clock_adjtime static void print_clock_adjtime(const struct syscallname *name, @@ -1167,21 +1154,6 @@ print_faccessat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_fchmodat -static void -print_fchmodat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_file_mode(arg2, 0); - print_flags(at_file_flags, arg3, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_fchownat static void print_fchownat(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 3b5a79fe74..9844382166 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -30,6 +30,26 @@ SYSCALL_IMPL(chdir) return ret; } +static abi_long do_fchmodat(int dirfd, abi_ulong target_path, mode_t mode) +{ + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(fchmodat(dirfd, p, mode, 0)); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_chmod +SYSCALL_IMPL(chmod) +{ + return do_fchmodat(AT_FDCWD, arg1, arg2); +} +#endif + SYSCALL_IMPL(close) { int fd = arg1; @@ -54,6 +74,16 @@ SYSCALL_IMPL(creat) } #endif +SYSCALL_IMPL(fchmod) +{ + return get_errno(fchmod(arg1, arg2)); +} + +SYSCALL_IMPL(fchmodat) +{ + return do_fchmodat(arg1, arg2, arg3); +} + static abi_long do_linkat(int olddirfd, abi_ulong target_oldpath, int newdirfd, abi_ulong target_newpath, int flags) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d46b4df677..f9101d0b08 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5331,14 +5331,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_chmod - case TARGET_NR_chmod: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(chmod(p, arg2)); - unlock_user(p, arg1, 0); - return ret; -#endif #ifdef TARGET_NR_lseek case TARGET_NR_lseek: return get_errno(lseek(arg1, arg2, arg3)); @@ -6410,16 +6402,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_ftruncate case TARGET_NR_ftruncate: return get_errno(ftruncate(arg1, arg2)); -#endif - case TARGET_NR_fchmod: - return get_errno(fchmod(arg1, arg2)); -#if defined(TARGET_NR_fchmodat) - case TARGET_NR_fchmodat: - if (!(p = lock_user_string(arg2))) - return -TARGET_EFAULT; - ret = get_errno(fchmodat(arg1, p, arg3, 0)); - unlock_user(p, arg2, 0); - return ret; #endif case TARGET_NR_getpriority: /* Note that negative values are valid for getpriority, so we must diff --git a/linux-user/strace.list b/linux-user/strace.list index adf8955278..92a86c682c 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -61,9 +61,6 @@ #ifdef TARGET_NR_capset { TARGET_NR_capset, "capset" , "%s(%p,%p)", NULL, NULL }, #endif -#ifdef TARGET_NR_chmod -{ TARGET_NR_chmod, "chmod" , NULL, print_chmod, NULL }, -#endif #ifdef TARGET_NR_chown { TARGET_NR_chown, "chown" , NULL, NULL, NULL }, #endif @@ -169,12 +166,6 @@ #ifdef TARGET_NR_fchdir { TARGET_NR_fchdir, "fchdir" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_fchmod -{ TARGET_NR_fchmod, "fchmod" , "%s(%d,%#o)", NULL, NULL }, -#endif -#ifdef TARGET_NR_fchmodat -{ TARGET_NR_fchmodat, "fchmodat" , NULL, print_fchmodat, NULL }, -#endif #ifdef TARGET_NR_fchown { TARGET_NR_fchown, "fchown" , "%s(%d,%d,%d)", NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027782 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="YJ7jBpsW"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF8K5sCGz9sDL for ; Sat, 19 Jan 2019 08:54:09 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47692 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc5X-0005jo-7n for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:54:07 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56177) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkr-0005Wq-Cn for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkn-00053Z-Iq for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:43 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:34617) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkl-000513-QQ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:40 -0500 Received: by mail-pg1-x542.google.com with SMTP id j10so6663302pga.1 for ; Fri, 18 Jan 2019 13:32:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8/DfaAGT153G06illQz/Ugse3vNW/xtvULpHoEkL9XQ=; b=YJ7jBpsWAtZHHfSlaKcfzi5F8P/sc1LzT8DJaa0JqkmW0U5rqIL7S8FA9NTO/JFuwK FK48ghU9kMaN0IOe3v1vQJPNWmSBQP23tossPupeJxrjFv0Bym1dllSUPfd2hI5rUkPz CPKOM5dypyyhAftIeE3y8CAh1GsKsPDSAmXd0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8/DfaAGT153G06illQz/Ugse3vNW/xtvULpHoEkL9XQ=; b=R5655sYZ0toee87EbShv1NlzWf/qK3mlJO6tjKqONmQo/c6Q+6JbTKg5gsxesJR0CC hefOLb1sTJHpKSZ24fNotW5iq2YdODTlkXnFXqJM05fXtW83tromHXl+wCeVdjBU4DU8 VltUso4mEJVWlapcQ15rDp+9Vg+EAqJQQJOTEauRJDyoTYa2ut5icORoM1b6EHCua8HJ 80mZYkiXtXVRPHvSd1L3P0NBPgSKVESizOrcpZZJuax4YwoS7kqaNnpSNNd1EMAi0jH2 9Bcp5DSzhhPaZeEzUiTIbAm2NKEvGphV8K0IEERrsYTY0vZ3RLDBMouWnlyVr6XiD7pJ JVNQ== X-Gm-Message-State: AJcUukdMyhIb8MpzY+zktwf/ed/Ykn/h+1walxT83CE1WQ9t48FqdZWz KWO0br9RLx9PWc3GxfPZfK/Nt2mfNb8= X-Google-Smtp-Source: ALg8bN6y8yHNgMd7sN7Nbl9jbGbiZXxa/3yWgtn2Y8Fm9oe1U8vL4d+biX8a3Y0VQWhUPSZdqakcKQ== X-Received: by 2002:a63:1a0c:: with SMTP id a12mr19008580pga.157.1547847157639; Fri, 18 Jan 2019 13:32:37 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.35 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:37 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:03 +1100 Message-Id: <20190118213122.22865-30-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::542 Subject: [Qemu-devel] [PATCH v6 30/49] linux-user: Split out lseek, llseek X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Canonicalise the target syscall name on llseek (new kernels) instead of _llseek (old kernels). Always use host lseek(3) rather than attempting to use the host llseek(2). Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 6 ++++++ linux-user/syscall.h | 1 + linux-user/strace.c | 39 +++++++++++++++-------------------- linux-user/syscall-file.inc.c | 36 ++++++++++++++++++++++++++++++++ linux-user/syscall.c | 32 ++-------------------------- linux-user/strace.list | 6 ------ 6 files changed, 62 insertions(+), 58 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 3ddf8aa0e3..3453e7afdf 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -43,6 +43,12 @@ SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); SYSCALL_DEF(link, ARG_STR, ARG_STR); #endif SYSCALL_DEF(linkat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR, ARG_ATFLAG); +#ifdef TARGET_NR_lseek +SYSCALL_DEF(lseek, ARG_DEC, ARG_DEC, ARG_LSEEKWHENCE); +#endif +#ifdef TARGET_NR_llseek +SYSCALL_DEF_ARGS(llseek, ARG_DEC, ARG_DEC, ARG_PTR, ARG_LSEEKWHENCE); +#endif #ifdef TARGET_NR_mknod SYSCALL_DEF(mknod, ARG_STR, ARG_MODEFLAG, ARG_HEX); #endif diff --git a/linux-user/syscall.h b/linux-user/syscall.h index bdc4d653c4..c16c0a3f1e 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -64,6 +64,7 @@ typedef enum { ARG_MODEFLAG, ARG_OPENFLAG, ARG_UNLINKATFLAG, + ARG_LSEEKWHENCE, /* These are interpreted as pointers. */ ARG_PTR, diff --git a/linux-user/strace.c b/linux-user/strace.c index 66d981b9e6..c08dbdff0c 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -934,6 +934,20 @@ print_open_flags(abi_long flags, int last) gemu_log("%s%s", buf, get_comma(last)); } +static int add_lseek_whence(char *buf, int size, int whence) +{ + switch (whence) { + case SEEK_SET: + return snprintf(buf, size, "SEEK_SET"); + case SEEK_CUR: + return snprintf(buf, size, "SEEK_CUR"); + case SEEK_END: + return snprintf(buf, size, "SEEK_END"); + default: + return snprintf(buf, size, "%#x", whence); + } +} + static void print_syscall_prologue(const struct syscallname *sc) { @@ -1285,28 +1299,6 @@ print_futimesat(const struct syscallname *name, } #endif -#ifdef TARGET_NR__llseek -static void -print__llseek(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - const char *whence = "UNKNOWN"; - print_syscall_prologue(name); - print_raw_param("%d", arg0, 0); - print_raw_param("%ld", arg1, 0); - print_raw_param("%ld", arg2, 0); - print_pointer(arg3, 0); - switch(arg4) { - case SEEK_SET: whence = "SEEK_SET"; break; - case SEEK_CUR: whence = "SEEK_CUR"; break; - case SEEK_END: whence = "SEEK_END"; break; - } - gemu_log("%s",whence); - print_syscall_epilogue(name); -} -#endif - #if defined(TARGET_NR_socket) static void print_socket(const struct syscallname *name, @@ -2317,6 +2309,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_UNLINKATFLAG: len = add_flags(b, rest, unlinkat_flags, arg, true); break; + case ARG_LSEEKWHENCE: + len = add_lseek_whence(b, rest, arg); + break; case ARG_PTR: len = add_pointer(b, rest, arg); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 9844382166..e23d21bdfc 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -112,6 +112,42 @@ SYSCALL_IMPL(linkat) return do_linkat(arg1, arg2, arg3, arg4, arg5); } +#ifdef TARGET_NR_lseek +SYSCALL_IMPL(lseek) +{ + return get_errno(lseek(arg1, arg2, arg3)); +} +#endif + +#ifdef TARGET_NR_llseek +SYSCALL_ARGS(llseek) +{ + /* The parts for offset are *always* in big-endian order. */ + abi_ulong lo = in[2], hi = in[1]; + out[1] = (((uint64_t)hi << (TARGET_ABI_BITS - 1)) << 1) | lo; + out[2] = in[3]; + out[3] = in[4]; + return def; +} + +SYSCALL_IMPL(llseek) +{ + int fd = arg1; + int64_t offset = arg2; + abi_ulong target_res = arg3; + int whence = arg4; + + off_t res = lseek(fd, offset, whence); + + if (res == -1) { + return get_errno(-1); + } else if (put_user_s64(res, target_res)) { + return -TARGET_EFAULT; + } + return 0; +} +#endif + static abi_long do_mknodat(int dirfd, abi_ulong target_path, mode_t mode, dev_t dev) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f9101d0b08..09fcec7812 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -195,8 +195,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #endif /* Newer kernel ports have llseek() instead of _llseek() */ -#if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek) -#define TARGET_NR__llseek TARGET_NR_llseek +#if !defined(TARGET_NR_llseek) && defined(TARGET_NR__llseek) +#define TARGET_NR_llseek TARGET_NR__llseek #endif #ifdef __NR_gettid @@ -227,10 +227,6 @@ _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count) (defined(TARGET_NR_getdents64) && defined(__NR_getdents64)) _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count); #endif -#if defined(TARGET_NR__llseek) && defined(__NR_llseek) -_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, - loff_t *, res, uint, wh); -#endif _syscall3(int, sys_rt_sigqueueinfo, pid_t, pid, int, sig, siginfo_t *, uinfo) _syscall4(int, sys_rt_tgsigqueueinfo, pid_t, pid, pid_t, tid, int, sig, siginfo_t *, uinfo) @@ -5331,10 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_lseek - case TARGET_NR_lseek: - return get_errno(lseek(arg1, arg2, arg3)); -#endif #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA) /* Alpha specific */ case TARGET_NR_getxpid: @@ -6833,26 +6825,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return get_errno(fchdir(arg1)); case TARGET_NR_personality: return get_errno(personality(arg1)); -#ifdef TARGET_NR__llseek /* Not on alpha */ - case TARGET_NR__llseek: - { - int64_t res; -#if !defined(__NR_llseek) - res = lseek(arg1, ((uint64_t)arg2 << 32) | (abi_ulong)arg3, arg5); - if (res == -1) { - ret = get_errno(res); - } else { - ret = 0; - } -#else - ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); -#endif - if ((ret == 0) && put_user_s64(res, arg4)) { - return -TARGET_EFAULT; - } - } - return ret; -#endif #ifdef TARGET_NR_getdents case TARGET_NR_getdents: #ifdef EMULATE_GETDENTS_WITH_GETDENTS diff --git a/linux-user/strace.list b/linux-user/strace.list index 92a86c682c..18c93ccc2d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -455,9 +455,6 @@ #ifdef TARGET_NR_llistxattr { TARGET_NR_llistxattr, "llistxattr" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR__llseek -{ TARGET_NR__llseek, "_llseek" , NULL, print__llseek, NULL }, -#endif #ifdef TARGET_NR_lock { TARGET_NR_lock, "lock" , NULL, NULL, NULL }, #endif @@ -467,9 +464,6 @@ #ifdef TARGET_NR_lremovexattr { TARGET_NR_lremovexattr, "lremovexattr" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_lseek -{ TARGET_NR_lseek, "lseek" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_lsetxattr { TARGET_NR_lsetxattr, "lsetxattr" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027787 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Aka7+PCg"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFCs13cgz9sDL for ; Sat, 19 Jan 2019 08:57:12 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47746 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc8U-0008T8-J3 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:57:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56191) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkt-0005YW-9z for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkp-00055c-H0 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:45 -0500 Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]:34622) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkn-00052s-IU for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:42 -0500 Received: by mail-pf1-x444.google.com with SMTP id h3so7218884pfg.1 for ; Fri, 18 Jan 2019 13:32:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LLOQ0aPeYq0RU7owywYYSEV/qQ8eh0gn9IoFhaLpsAY=; b=Aka7+PCgeg2zFkvAuYcabAnsHvRQYcQwNI4i+zlEskk3ViQgVCTYzDg0aS1hRaMoqF 2KJxM2YvWDRq9lc26itUhrThk+DjX8w+v6XDvEIxjj5YxoIo4vZBwPe6GkXOqN6TnE+f tTrK5jK92yWC/FbJ6lCSMFz4dhz1pC34CcSoI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LLOQ0aPeYq0RU7owywYYSEV/qQ8eh0gn9IoFhaLpsAY=; b=dYnJ5kvAYB9L43vzahYDeZvW8ljMWkrBRKEsRKg/+Nmxp5Qw+/QBw7oEgoX5eJJpxn XCvhrlAv15CW2nTJzwgc6pU/KXOlhCScYOtGWt/RB/ltV42vok3my/Xri+n1OguzUPlX CZjQPdRGEP9XI488cDznLcocEgfmeZ66TlF8yOemAsMW3IrGvGProgHamyPFgf8td9xv ZLccRKHONnpxB/cwyn7aawj0pwTaHOArofMW6e49rI3Yw3GaWRWnCGsf/ra1pjy0m/E/ uBiKEtBbrXClr7ACecwXiZ9VrXte75QXtr1g6GlCAr6jzD1cbyzMXHMZrA3u/wShSpnc 4VoQ== X-Gm-Message-State: AJcUukd8fxu8hfUdy5B+FhIC/LuWk44wlJMFwTN9NXbJ0/bkHc7KucsS 6dlAuMitq64qSjjp0anVbS69pxcnVl8= X-Google-Smtp-Source: ALg8bN7TmpdvHZcHxrvlDKixGFHS2p4cBgT4RidZEhLsq/4xqACrXrUuya6eUQOC/xY8WGuOOYJqzg== X-Received: by 2002:a62:7892:: with SMTP id t140mr20940712pfc.237.1547847159783; Fri, 18 Jan 2019 13:32:39 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:39 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:04 +1100 Message-Id: <20190118213122.22865-31-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::444 Subject: [Qemu-devel] [PATCH v6 31/49] linux-user: Split out getpid, getppid, getxpid X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 9 +++++++++ linux-user/syscall-proc.inc.c | 23 +++++++++++++++++++++++ linux-user/syscall.c | 14 -------------- linux-user/strace.list | 9 --------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 3453e7afdf..d163bbf409 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -36,6 +36,15 @@ SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG); #ifdef TARGET_NR_fork SYSCALL_DEF(fork); #endif +#ifdef TARGET_NR_getpid +SYSCALL_DEF(getpid); +#endif +#ifdef TARGET_NR_getppid +SYSCALL_DEF(getppid); +#endif +#ifdef TARGET_NR_getxpid +SYSCALL_DEF(getxpid); +#endif #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index 699370c290..c09c83775c 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -438,6 +438,29 @@ SYSCALL_IMPL(fork) } #endif +#ifdef TARGET_NR_getpid +SYSCALL_IMPL(getpid) +{ + return getpid(); +} +#endif + +#ifdef TARGET_NR_getppid +SYSCALL_IMPL(getppid) +{ + return getppid(); +} +#endif + +#ifdef TARGET_NR_getxpid +SYSCALL_IMPL(getxpid) +{ + /* Alpha specific */ + cpu_env->ir[IR_A4] = getppid(); + return getpid(); +} +#endif + /* * Map host to target signal numbers for the wait family of syscalls. * Assume all other status bits are the same. diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 09fcec7812..6ea1a67345 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,16 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA) - /* Alpha specific */ - case TARGET_NR_getxpid: - ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid(); - return get_errno(getpid()); -#endif -#ifdef TARGET_NR_getpid - case TARGET_NR_getpid: - return get_errno(getpid()); -#endif case TARGET_NR_mount: { /* need to look at the data field */ @@ -5668,10 +5658,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return ret; } #endif -#ifdef TARGET_NR_getppid /* not on alpha */ - case TARGET_NR_getppid: - return get_errno(getppid()); -#endif #ifdef TARGET_NR_getpgrp case TARGET_NR_getpgrp: return get_errno(getpgrp()); diff --git a/linux-user/strace.list b/linux-user/strace.list index 18c93ccc2d..344a2232d6 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -298,15 +298,9 @@ #ifdef TARGET_NR_getpgrp { TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_getpid -{ TARGET_NR_getpid, "getpid" , "%s()", NULL, NULL }, -#endif #ifdef TARGET_NR_getpmsg { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_getppid -{ TARGET_NR_getppid, "getppid" , "%s()", NULL, NULL }, -#endif #ifdef TARGET_NR_getpriority { TARGET_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL }, #endif @@ -365,9 +359,6 @@ #ifdef TARGET_NR_getxgid { TARGET_NR_getxgid, "getxgid" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_getxpid -{ TARGET_NR_getxpid, "getxpid" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_getxuid { TARGET_NR_getxuid, "getxuid" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027773 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="PllCFBqt"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF0v1v3qz9s9G for ; Sat, 19 Jan 2019 08:47:42 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47609 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbzH-0000eM-Ox for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:47:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56245) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkz-0005at-6v for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkx-0005B6-04 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:53 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:42955) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkt-00054z-CU for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:49 -0500 Received: by mail-pl1-x644.google.com with SMTP id y1so6880894plp.9 for ; Fri, 18 Jan 2019 13:32:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=81GJt5WLaa4PEnMi0/KdLKOBBXY88vrv1HEVQU6kpFA=; b=PllCFBqtBnpNqkUcEfHNehFVxrVwYVsfJ6N6g6qp4S79+3vc0J0xdlZlkCF5eS2myY iMyWHtqZLaAMeTNDw5H9ZgL0ntncSHiSngP/frMi7Wm995tbHsPgL4er3YgZR4upI+sz q4knxBk4Lyw7Z/TrxxUzTFOg7Q0HGP7vBojQI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=81GJt5WLaa4PEnMi0/KdLKOBBXY88vrv1HEVQU6kpFA=; b=B5l7c8UcVCEz6mv9LQFHMu78W/tdNn9xIu7+ZbrWk5W2Pvj1YmFCc1aSRUGmN9dauh t8bZ03c4txo6l1YmLhkWZIci+aXst95wvqcUQevWRFrtRbsB3V9XuKEY4KN/KI45S8f5 XaaACb7BggPgrjHZMUNsXbfFn5aOK4YOP0GZV2YaBkGVO3XPQY37dvzeaVDXLW/y8ata vR+ZS6XFILGYOIbSPT1EQV5wVsSeRlFJ4+gb/HjeUxYLl03IHge8GlJUO3fkKJM/ReFi eYsDpVxAIUql2HQRq2Wbzm23qEt5N9xX2tqmjYwdYy04wP40DfxRHmOehduPzI3SGc2V 0zIA== X-Gm-Message-State: AJcUukctOy9W/8dZG2v1sy5tEsgJ+0GOmSYy+sfaGUEAOSq5ckIG64xv fXUHDSMdoAstzOXQGeiX84pEzVnM0O4= X-Google-Smtp-Source: ALg8bN758VhEIcMzyiZf4qVWCBMyEvttcrNBt89RKOs/b1sqBpinTNhFS0Gajmmnh7LvSWssXQD1aw== X-Received: by 2002:a17:902:7882:: with SMTP id q2mr21281784pll.305.1547847162025; Fri, 18 Jan 2019 13:32:42 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:41 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:05 +1100 Message-Id: <20190118213122.22865-32-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 32/49] linux-user: Split out mount X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall.h | 1 + linux-user/strace.c | 21 +++---------- linux-user/syscall-file.inc.c | 48 ++++++++++++++++++++++++++++++ linux-user/syscall.c | 55 ----------------------------------- linux-user/strace.list | 3 -- 6 files changed, 54 insertions(+), 75 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index d163bbf409..2b331c6a6d 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -78,6 +78,7 @@ SYSCALL_DEF_FULL(mmap2, .impl = impl_mmap, .arg_type = { ARG_PTR, ARG_DEC, ARG_MMAPPROT, ARG_MMAPFLAG, ARG_DEC, ARG_DEC64 }); #endif +SYSCALL_DEF(mount, ARG_STR, ARG_STR, ARG_STR, ARG_MOUNTFLAG, ARG_PTR); SYSCALL_DEF(mprotect, ARG_PTR, ARG_DEC, ARG_MMAPPROT); SYSCALL_DEF_FULL(mremap, .impl = impl_mremap, .print_ret = print_syscall_ptr_ret, diff --git a/linux-user/syscall.h b/linux-user/syscall.h index c16c0a3f1e..35dd3e5fa3 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -62,6 +62,7 @@ typedef enum { ARG_MMAPFLAG, ARG_MMAPPROT, ARG_MODEFLAG, + ARG_MOUNTFLAG, ARG_OPENFLAG, ARG_UNLINKATFLAG, ARG_LSEEKWHENCE, diff --git a/linux-user/strace.c b/linux-user/strace.c index c08dbdff0c..eb02430eba 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -708,7 +708,7 @@ static struct flags const open_flags[] = { FLAG_END, }; -UNUSED static struct flags mount_flags[] = { +static struct flags const mount_flags[] = { #ifdef MS_BIND FLAG_GENERIC(MS_BIND), #endif @@ -2003,22 +2003,6 @@ print_symlinkat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_mount -static void -print_mount(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_string(arg1, 0); - print_string(arg2, 0); - print_flags(mount_flags, arg3, 0); - print_pointer(arg4, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_umount static void print_umount(const struct syscallname *name, @@ -2303,6 +2287,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_MODEFLAG: len = add_flags(b, rest, mode_flags, arg, true); break; + case ARG_MOUNTFLAG: + len = add_flags(b, rest, mount_flags, arg, true); + break; case ARG_OPENFLAG: len = add_open_flags(b, rest, arg); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index e23d21bdfc..d7eb72cc31 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -174,6 +174,54 @@ SYSCALL_IMPL(mknodat) return do_mknodat(arg1, arg2, arg3, arg4); } +SYSCALL_IMPL(mount) +{ + abi_ulong target_src = arg1; + abi_ulong target_tgt = arg2; + abi_ulong target_fst = arg3; + abi_ulong mountflags = arg4; + abi_ulong target_data = arg5; + char *p_src = NULL, *p_tgt = NULL, *p_fst = NULL, *p_data = NULL; + abi_long ret = -TARGET_EFAULT; + + if (target_src) { + p_src = lock_user_string(target_src); + if (!p_src) { + goto exit0; + } + } + + p_tgt = lock_user_string(target_tgt); + if (!p_tgt) { + goto exit1; + } + + if (target_fst) { + p_fst = lock_user_string(target_fst); + if (!p_fst) { + goto exit2; + } + } + + /* + * FIXME - arg5 should be locked, but it isn't clear how to + * do that since it's not guaranteed to be a NULL-terminated + * string. + */ + if (target_data) { + p_data = g2h(target_data); + } + ret = get_errno(mount(p_src, p_tgt, p_fst, mountflags, p_data)); + + unlock_user(p_fst, target_fst, 0); + exit2: + unlock_user(p_tgt, target_tgt, 0); + exit1: + unlock_user(p_src, target_src, 0); + exit0: + return ret; +} + /* * Helpers for do_openat, manipulating /proc/self/foo. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6ea1a67345..39e749a985 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,61 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_mount: - { - /* need to look at the data field */ - void *p2, *p3; - - if (arg1) { - p = lock_user_string(arg1); - if (!p) { - return -TARGET_EFAULT; - } - } else { - p = NULL; - } - - p2 = lock_user_string(arg2); - if (!p2) { - if (arg1) { - unlock_user(p, arg1, 0); - } - return -TARGET_EFAULT; - } - - if (arg3) { - p3 = lock_user_string(arg3); - if (!p3) { - if (arg1) { - unlock_user(p, arg1, 0); - } - unlock_user(p2, arg2, 0); - return -TARGET_EFAULT; - } - } else { - p3 = NULL; - } - - /* FIXME - arg5 should be locked, but it isn't clear how to - * do that since it's not guaranteed to be a NULL-terminated - * string. - */ - if (!arg5) { - ret = mount(p, p2, p3, (unsigned long)arg4, NULL); - } else { - ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)); - } - ret = get_errno(ret); - - if (arg1) { - unlock_user(p, arg1, 0); - } - unlock_user(p2, arg2, 0); - if (arg3) { - unlock_user(p3, arg3, 0); - } - } - return ret; #ifdef TARGET_NR_umount case TARGET_NR_umount: if (!(p = lock_user_string(arg1))) diff --git a/linux-user/strace.list b/linux-user/strace.list index 344a2232d6..5f07e0e23d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -497,9 +497,6 @@ #ifdef TARGET_NR_modify_ldt { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_mount -{ TARGET_NR_mount, "mount" , NULL, print_mount, NULL }, -#endif #ifdef TARGET_NR_move_pages { TARGET_NR_move_pages, "move_pages" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027807 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="SIId+idr"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFZX1TSdz9sDB for ; Sat, 19 Jan 2019 09:13:24 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48008 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcOA-0004hA-60 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:13:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56244) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkz-0005as-6y for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkx-0005BV-96 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:53 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:40625) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkt-00056n-Dp for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:49 -0500 Received: by mail-pg1-x544.google.com with SMTP id z10so6647489pgp.7 for ; Fri, 18 Jan 2019 13:32:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=W3z+QQSMQZhI4Cw/AlBaCLLQDlmHhIuHBH2JUURMgp8=; b=SIId+idruHvBIAhdOff6FAP3JCFTX7a577jNn71K8SgsOxNo8D0UXFMY1pEZstMuM7 kn+y7POITeDSbMNgfKi64x+6qZwTF4NDNxDfoC8Xlbgyl2KeuHmAvI4fqoLTglP8bZJP d6EN3Xea5IrjowkHbZ6HjxTx7el/3JLoB9ess= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=W3z+QQSMQZhI4Cw/AlBaCLLQDlmHhIuHBH2JUURMgp8=; b=kGhXbVMzr6r+EPASFM/am/WaaaB6Bg25NkpuVppsw1G9cu7NjBjnt2eRRCvw6Vtr47 y7Ar8lg9EX/WNAnJtRlIhhoBFJfaFwGH8L3V9Zl/IQIekA0ggFPOgvTpfzlqqkPcenWv 117Q7xF/gYogvfJpUTpGXjZgKUJC03e8zoREte76EkQGhdIMHr/nKPrxoSyX+6jk/DBw jInaI2YTfR18zrPTDGxgdBJoC6b7ZOfxxqcIYpjv1v2YA5/2pdFCySIrnlvvnUBYoQ8+ 8X0H8fAimu8jEeHm4mEoe3c5HRMi7eMrcsenC5AhD6zZj070hNdO2FgShK8yyArWCXNB 7VOw== X-Gm-Message-State: AJcUukfdkWe4AFchLZm0CpWoMphaM7HuSBeYRZbshdawsfhbdG5YB8uO d4pn/59pO5Rhr/Tw8oNEwd2hXjNzKFU= X-Google-Smtp-Source: ALg8bN4/ZuuuBISbChnnDDgriOMLrRwmo3cb75KJo19np45Fiox80cGXqvzNrbnPG2FhmY/NQiaiZg== X-Received: by 2002:a65:5bc4:: with SMTP id o4mr19553567pgr.426.1547847164257; Fri, 18 Jan 2019 13:32:44 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:43 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:06 +1100 Message-Id: <20190118213122.22865-33-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::544 Subject: [Qemu-devel] [PATCH v6 33/49] linux-user: Split out umount, umount2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that umount2 is unconditionally available. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 4 ++++ linux-user/syscall.h | 1 + linux-user/strace.c | 30 ++++-------------------------- linux-user/syscall-file.inc.c | 25 +++++++++++++++++++++++++ linux-user/syscall.c | 16 ---------------- linux-user/strace.list | 6 ------ 6 files changed, 34 insertions(+), 48 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 2b331c6a6d..0d8da0c6d6 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -155,6 +155,10 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); #ifdef TARGET_NR_time SYSCALL_DEF(time, ARG_PTR); #endif +#ifdef TARGET_NR_umount +SYSCALL_DEF(umount, ARG_STR); +#endif +SYSCALL_DEF(umount2, ARG_STR, ARG_UMOUNTFLAG); #ifdef TARGET_NR_unlink SYSCALL_DEF(unlink, ARG_STR); #endif diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 35dd3e5fa3..3c936b648a 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -64,6 +64,7 @@ typedef enum { ARG_MODEFLAG, ARG_MOUNTFLAG, ARG_OPENFLAG, + ARG_UMOUNTFLAG, ARG_UNLINKATFLAG, ARG_LSEEKWHENCE, diff --git a/linux-user/strace.c b/linux-user/strace.c index eb02430eba..78781b8817 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -733,7 +733,7 @@ static struct flags const mount_flags[] = { FLAG_END, }; -UNUSED static struct flags umount2_flags[] = { +static struct flags const umount2_flags[] = { #ifdef MNT_FORCE FLAG_GENERIC(MNT_FORCE), #endif @@ -2003,31 +2003,6 @@ print_symlinkat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_umount -static void -print_umount(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_umount2 -static void -print_umount2(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_flags(umount2_flags, arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_utime static void print_utime(const struct syscallname *name, @@ -2293,6 +2268,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_OPENFLAG: len = add_open_flags(b, rest, arg); break; + case ARG_UMOUNTFLAG: + len = add_flags(b, rest, umount2_flags, arg, false); + break; case ARG_UNLINKATFLAG: len = add_flags(b, rest, unlinkat_flags, arg, true); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index d7eb72cc31..7ec1c26347 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -810,6 +810,31 @@ SYSCALL_IMPL(readlinkat) } #endif +static abi_long do_umount2(abi_ulong target_path, int flags) +{ + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(umount2(p, flags)); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_umount +SYSCALL_IMPL(umount) +{ + return do_umount2(arg1, 0); +} +#endif + +SYSCALL_IMPL(umount2) +{ + return do_umount2(arg1, arg2); +} + static abi_long do_unlinkat(int dirfd, abi_ulong target_path, int flags) { char *p = lock_user_string(target_path); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 39e749a985..b35d84794f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,14 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_umount - case TARGET_NR_umount: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(umount(p)); - unlock_user(p, arg1, 0); - return ret; -#endif #ifdef TARGET_NR_stime /* not on alpha */ case TARGET_NR_stime: { @@ -5555,14 +5547,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg1, 0); } return ret; -#ifdef TARGET_NR_umount2 - case TARGET_NR_umount2: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(umount2(p, arg2)); - unlock_user(p, arg1, 0); - return ret; -#endif case TARGET_NR_ioctl: return do_ioctl(arg1, arg2, arg3); #ifdef TARGET_NR_fcntl diff --git a/linux-user/strace.list b/linux-user/strace.list index 5f07e0e23d..0f32c456cd 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1368,12 +1368,6 @@ #ifdef TARGET_NR_umask { TARGET_NR_umask, "umask" , "%s(%#o)", NULL, NULL }, #endif -#ifdef TARGET_NR_umount -{ TARGET_NR_umount, "umount" , NULL, print_umount, NULL }, -#endif -#ifdef TARGET_NR_umount2 -{ TARGET_NR_umount2, "umount2" , NULL, print_umount2, NULL }, -#endif #ifdef TARGET_NR_uname { TARGET_NR_uname, "uname" , "%s(%p)", NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027790 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="g20s13ad"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFGq2TVkz9sDB for ; Sat, 19 Jan 2019 08:59:47 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47772 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcAz-0002Rt-7j for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:59:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56243) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbkz-0005ar-6u for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkx-0005CD-J5 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:53 -0500 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:33621) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkx-00058Z-8R for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:51 -0500 Received: by mail-pf1-x443.google.com with SMTP id c123so7221377pfb.0 for ; Fri, 18 Jan 2019 13:32:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mwzNcDdyudRZjt1ZvriB7bmoUmG2mLJC7b5JwOaLK+g=; b=g20s13adrxEG9ADUEGos/yDsmuuRNL9j5a5ZoPihjm5sC1Ze4quGPGBndfS/GSbXrP XFV2+6kYO7+IyDNx1llGNgEwSzEDKj2qI6pVkPhDvo1Om6jtpRER/crYCR9kYpQ5E4mX Gz+0alfGUhCZQjGIlAymJyFp4ykdkeEOWPImw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mwzNcDdyudRZjt1ZvriB7bmoUmG2mLJC7b5JwOaLK+g=; b=a2FTo8tgP9QIXwmTHCR6etQggD3FB2Q9vWFmxULLg/NwRkSdPp7TTyl+XnoUw7re0B PYTW9idWB7JZuyuTFdTsiqy5Wd5kyRgUULWjWPqy6es4Q9WIY6s1/Yfevykv6qaHE/Qg FTipqyTHoGBCCqmNnhSKOsRWGhLygRON6/VTgnCPt1PURGwpmAw5zPNQ+0eCzc8/v34b b6PMcbR8K/mVKzY9AofdKMONIIjPYSddWknFy7RJNWuu8llmaDh0+0OsLGzq0oasc3Eh LdyX3RtBu/NIuk3350tnCwuz9XPih7IZm+IAfUO618qQ4shrgBYejwh/j4kH1TnLBlQg cGDQ== X-Gm-Message-State: AJcUukcEprDUYxi2pJMxAAJXclVDjyjOFNyWTFK0W72ucxa7eXHzAyEC ytjOX+4MpzCz1HhdmB4kV56xpVreIv8= X-Google-Smtp-Source: ALg8bN7u9qrYoDgofhEXhsIVLFASAEfsLX/ITDHSCEigjqhZ5IR3kgAFF3F+G5J1hqZ/wtHZVPjyjQ== X-Received: by 2002:a63:4948:: with SMTP id y8mr19385894pgk.32.1547847166479; Fri, 18 Jan 2019 13:32:46 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:45 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:07 +1100 Message-Id: <20190118213122.22865-34-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::443 Subject: [Qemu-devel] [PATCH v6 34/49] linux-user: Split out stime X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 3 +++ linux-user/syscall-time.inc.c | 12 ++++++++++++ linux-user/syscall.c | 9 --------- linux-user/strace.list | 3 --- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 0d8da0c6d6..6ca82af397 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -152,6 +152,9 @@ SYSCALL_DEF(shmdt, ARG_PTR); #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget) SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); #endif +#ifdef TARGET_NR_stime +SYSCALL_DEF(stime, ARG_PTR); +#endif #ifdef TARGET_NR_time SYSCALL_DEF(time, ARG_PTR); #endif diff --git a/linux-user/syscall-time.inc.c b/linux-user/syscall-time.inc.c index 14fec88e47..d1fb72bde0 100644 --- a/linux-user/syscall-time.inc.c +++ b/linux-user/syscall-time.inc.c @@ -16,6 +16,18 @@ * along with this program; if not, see . */ +#ifdef TARGET_NR_stime +SYSCALL_IMPL(stime) +{ + time_t host_time; + + if (get_user_sal(host_time, arg1)) { + return -TARGET_EFAULT; + } + return get_errno(stime(&host_time)); +} +#endif + #ifdef TARGET_NR_time SYSCALL_IMPL(time) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b35d84794f..c0ce4068b6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,15 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_stime /* not on alpha */ - case TARGET_NR_stime: - { - time_t host_time; - if (get_user_sal(host_time, arg1)) - return -TARGET_EFAULT; - return get_errno(stime(&host_time)); - } -#endif #ifdef TARGET_NR_alarm /* not on alpha */ case TARGET_NR_alarm: return alarm(arg1); diff --git a/linux-user/strace.list b/linux-user/strace.list index 0f32c456cd..a5f308c497 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1254,9 +1254,6 @@ #ifdef TARGET_NR_statfs64 { TARGET_NR_statfs64, "statfs64" , NULL, print_statfs64, NULL }, #endif -#ifdef TARGET_NR_stime -{ TARGET_NR_stime, "stime" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_streams1 { TARGET_NR_streams1, "streams1" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027776 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="DkDiJawZ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF4l0Znyz9s9G for ; Sat, 19 Jan 2019 08:51:03 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47651 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc2W-0003JG-KI for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:51:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56271) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbl1-0005ay-1L for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbkz-0005Dp-5f for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:54 -0500 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]:37788) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbkx-0005AG-A3 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:51 -0500 Received: by mail-pf1-x442.google.com with SMTP id y126so7208025pfb.4 for ; Fri, 18 Jan 2019 13:32:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3H+95VtDDX2rcLMDnBtfg92YRSY78G9AsnE1EvNA9Jo=; b=DkDiJawZtTzP+nrgRTmxQYprrt93SIvVykrykcsufkKGNaN4JiFDhXocTMNIo6ofFL mlEWVK2iLnJlZM6O3CYN7EXpK7Xr8jOqvOP9LoZiakQU9URXXnYBrJDxJ5YLBTMEJE9V gaq46ASEjYbmuN3VZOxCk74/IFwhgW13++A+4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3H+95VtDDX2rcLMDnBtfg92YRSY78G9AsnE1EvNA9Jo=; b=ocdDD63FYbWrbx33QGTfWTdnqHMyUYZfePblwQ7KTQ+bg5Qiq2dmHnCPe6QLq1O1B6 3xvuqmGNmfC/fxAz0MPpY2nIFdXqDBRoyxBLQ++F2NVrJkIh/LTr/Dx+ux24yJ+9jRqo 2L4TZ2wgdoVyLUbG8gewg2QbmRjWVbQlnMDyaM9i73cAtkFoAuGygtF+bBYWjBy+iFjB I0XRlz3gnvRLaLnndTasor6yoIMcGUG3CUNCfmqYZISxGBX8ZWEpWK846A/SCxq0rYsJ I9YSlskydyMZgGpdC7Biw1v8WPdL4TW9kMT2BcpmAeCH1EVlaZ02CNMe1Ie91w3ttvtq SJRg== X-Gm-Message-State: AJcUukcNjogQKTiQeKMwH8Jp9bpWGtrOmDuQfCwSZ8egr+b7qzb94TSt JennPDLZtXuk5RKKPrRsf33mLLEuq3M= X-Google-Smtp-Source: ALg8bN4yOVMt3xyusijlQqXPhSVR4el7OGUcKmAQL1qJqUdznA2Mn5ELA+8CtUPtPV4tSfvINQb1OA== X-Received: by 2002:a63:7044:: with SMTP id a4mr18936839pgn.359.1547847168771; Fri, 18 Jan 2019 13:32:48 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:48 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:08 +1100 Message-Id: <20190118213122.22865-35-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::442 Subject: [Qemu-devel] [PATCH v6 35/49] linux-user: Split out alarm, pause X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 6 ++++++ linux-user/syscall-sig.inc.c | 36 ++++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 12 +----------- linux-user/strace.list | 6 ------ 4 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 linux-user/syscall-sig.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 6ca82af397..9d0dd7457b 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -16,6 +16,9 @@ * along with this program; if not, see . */ +#ifdef TARGET_NR_alarm +SYSCALL_DEF(alarm, ARG_DEC); +#endif SYSCALL_DEF_FULL(brk, .impl = impl_brk, .print_ret = print_syscall_ptr_ret, .arg_type = { ARG_PTR }); @@ -106,6 +109,9 @@ SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); SYSCALL_DEF(open_by_handle_at, ARG_DEC, ARG_PTR, ARG_OPENFLAG); +#ifdef TARGET_NR_pause +SYSCALL_DEF(pause); +#endif SYSCALL_DEF_FULL(pread64, .impl = impl_pread64, .args = args_pread64_pwrite64, .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c new file mode 100644 index 0000000000..f4e43eb00e --- /dev/null +++ b/linux-user/syscall-sig.inc.c @@ -0,0 +1,36 @@ +/* + * Linux signal related syscalls + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifdef TARGET_NR_alarm +SYSCALL_IMPL(alarm) +{ + return alarm(arg1); +} +#endif + +#ifdef TARGET_NR_pause +SYSCALL_IMPL(pause) +{ + if (!block_signals()) { + CPUState *cpu = ENV_GET_CPU(cpu_env); + TaskState *ts = cpu->opaque; + sigsuspend(&ts->signal_mask); + } + return -TARGET_EINTR; +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c0ce4068b6..f3ea9600c8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,17 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_alarm /* not on alpha */ - case TARGET_NR_alarm: - return alarm(arg1); -#endif -#ifdef TARGET_NR_pause /* not on alpha */ - case TARGET_NR_pause: - if (!block_signals()) { - sigsuspend(&((TaskState *)cpu->opaque)->signal_mask); - } - return -TARGET_EINTR; -#endif #ifdef TARGET_NR_utime case TARGET_NR_utime: { @@ -9135,6 +9124,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #include "syscall-ipc.inc.c" #include "syscall-mem.inc.c" #include "syscall-proc.inc.c" +#include "syscall-sig.inc.c" #include "syscall-time.inc.c" #undef SYSCALL_IMPL diff --git a/linux-user/strace.list b/linux-user/strace.list index a5f308c497..b119b7a20c 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -25,9 +25,6 @@ #ifdef TARGET_NR_afs_syscall { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_alarm -{ TARGET_NR_alarm, "alarm" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_aplib { TARGET_NR_aplib, "aplib" , NULL, NULL, NULL }, #endif @@ -872,9 +869,6 @@ #ifdef TARGET_NR_osf_waitid { TARGET_NR_osf_waitid, "osf_waitid" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pause -{ TARGET_NR_pause, "pause" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_pciconfig_iobase { TARGET_NR_pciconfig_iobase, "pciconfig_iobase" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027771 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="KkR/JdGz"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hDxT68mzz9s9G for ; Sat, 19 Jan 2019 08:44:45 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47552 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbwR-0006ni-N4 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:44:43 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56307) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbl4-0005eC-Qw for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbl3-0005KB-5t for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:58 -0500 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:43471) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbl2-0005D1-Sg for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:57 -0500 Received: by mail-pf1-x443.google.com with SMTP id w73so7189495pfk.10 for ; Fri, 18 Jan 2019 13:32:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=K+wNFSCsbxRWr3U8isWrQQJrl4aYn/PQ1fyYDV6k6YI=; b=KkR/JdGzjynWyJY8W9Rznbja9FLFX6lL5oE74S8c5vjGjg5XfGJvYp7BQtofm2DJl4 yuvdONErB6WIqHT0MFPAjXy7IcLokU3XMHlsW7HbYhsG6OUCF0j8XU5IZ/fUSDUsHEZ4 f73D+WCHXp1gb1ioTtdEAQVAiUVoExaej6sbM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=K+wNFSCsbxRWr3U8isWrQQJrl4aYn/PQ1fyYDV6k6YI=; b=GHUUkEqZyUBw6thI5UKenc9acIEYC+HB0LYLluj5KUWeaccDWXlIO469dgEbuPzb8B ad2zIGEkrQT2Qp7DNJputzKXPeHvfdZwmtMn4uSndV9WPajWEe5+wdcKAuJoawXcRZtj Yx4WAiqT424qRPy60zgcsSFOenooSZbpg4F2QB7k3+hFVK6MS+9Q5P9LTrKmdGC0iJgF Bg2QnXQzavFhZca7x1TQhGCHAFvxUlIcqplKAcIVRCG7NSWUUCX5/0zF3Kp6PaU2vK5m YsedH9aFE9BBn0rMCNHpRroS6lgupropUB0HnyE1idkQP5Ai2dJxYiBz9vWNyhQ4iLQs laOQ== X-Gm-Message-State: AJcUukflW66eBaXWxDey9MeTjaTLuzIh9k5DBwCcYvhXRV893jF1hdQW yBcCZ1mfRHE3wferJUSa351bHPguPZQ= X-Google-Smtp-Source: ALg8bN7dV4X6MHVbsuZlGHhmqa94WDN6ZnVi/pX+FHzb/ypwVYKK1F+f4EuEUumTCbQeaRgs9xR7fw== X-Received: by 2002:a63:4b60:: with SMTP id k32mr19228152pgl.186.1547847171528; Fri, 18 Jan 2019 13:32:51 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:50 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:09 +1100 Message-Id: <20190118213122.22865-36-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::443 Subject: [Qemu-devel] [PATCH v6 36/49] linux-user: Split out utime, utimes, futimesat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 9 ++++ linux-user/strace.c | 41 --------------- linux-user/syscall-file.inc.c | 95 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 63 ----------------------- linux-user/strace.list | 9 ---- 5 files changed, 104 insertions(+), 113 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 9d0dd7457b..2767e335d8 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -36,6 +36,9 @@ SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR); SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG); SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG); +#ifdef TARGET_NR_futimesat +SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR); +#endif #ifdef TARGET_NR_fork SYSCALL_DEF(fork); #endif @@ -172,6 +175,12 @@ SYSCALL_DEF(umount2, ARG_STR, ARG_UMOUNTFLAG); SYSCALL_DEF(unlink, ARG_STR); #endif SYSCALL_DEF(unlinkat, ARG_ATDIRFD, ARG_STR, ARG_UNLINKATFLAG); +#ifdef TARGET_NR_utime +SYSCALL_DEF(utime, ARG_STR, ARG_PTR); +#endif +#ifdef TARGET_NR_utimes +SYSCALL_DEF(utimes, ARG_STR, ARG_PTR); +#endif #ifdef TARGET_NR_vfork /* Emulate vfork() with fork(). */ SYSCALL_DEF_FULL(vfork, .impl = impl_fork); diff --git a/linux-user/strace.c b/linux-user/strace.c index 78781b8817..b54949df27 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1284,21 +1284,6 @@ print_fcntl(const struct syscallname *name, #endif -#ifdef TARGET_NR_futimesat -static void -print_futimesat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_timeval(arg2, 0); - print_timeval(arg2 + sizeof (struct target_timeval), 1); - print_syscall_epilogue(name); -} -#endif - #if defined(TARGET_NR_socket) static void print_socket(const struct syscallname *name, @@ -2003,32 +1988,6 @@ print_symlinkat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_utime -static void -print_utime(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_pointer(arg1, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_utimes -static void -print_utimes(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_pointer(arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_utimensat static void print_utimensat(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 7ec1c26347..6a7ef80bfc 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -84,6 +84,38 @@ SYSCALL_IMPL(fchmodat) return do_fchmodat(arg1, arg2, arg3); } +#ifdef TARGET_NR_futimesat +SYSCALL_IMPL(futimesat) +{ + int dirfd = arg1; + abi_ulong target_path = arg2; + abi_ulong target_tv = arg3; + struct timeval *tvp, tv[2]; + char *p; + abi_long ret; + + if (target_tv) { + if (copy_from_user_timeval(&tv[0], target_tv) + || copy_from_user_timeval(&tv[1], + target_tv + + sizeof(struct target_timeval))) { + return -TARGET_EFAULT; + } + tvp = tv; + } else { + tvp = NULL; + } + + p = lock_user_string(target_path); + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(futimesat(dirfd, path(p), tvp)); + unlock_user(p, target_path, 0); + return ret; +} +#endif + static abi_long do_linkat(int olddirfd, abi_ulong target_oldpath, int newdirfd, abi_ulong target_newpath, int flags) @@ -867,6 +899,69 @@ SYSCALL_IMPL(unlinkat) return do_unlinkat(arg1, arg2, arg3); } +#ifdef TARGET_NR_utime +SYSCALL_IMPL(utime) +{ + abi_ulong target_path = arg1; + abi_ulong target_times = arg2; + struct utimbuf tbuf, *host_tbuf; + struct target_utimbuf *target_tbuf; + char *p; + abi_long ret; + + if (target_times) { + if (!lock_user_struct(VERIFY_READ, target_tbuf, target_times, 1)) { + return -TARGET_EFAULT; + } + tbuf.actime = tswapal(target_tbuf->actime); + tbuf.modtime = tswapal(target_tbuf->modtime); + unlock_user_struct(target_tbuf, arg2, 0); + host_tbuf = &tbuf; + } else { + host_tbuf = NULL; + } + + p = lock_user_string(target_path); + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(utime(p, host_tbuf)); + unlock_user(p, target_path, 0); + return ret; +} +#endif + +#ifdef TARGET_NR_utimes +SYSCALL_IMPL(utimes) +{ + abi_ulong target_path = arg1; + abi_ulong target_tv = arg2; + struct timeval *tvp, tv[2]; + char *p; + abi_long ret; + + if (target_tv) { + if (copy_from_user_timeval(&tv[0], target_tv) + || copy_from_user_timeval(&tv[1], + target_tv + + sizeof(struct target_timeval))) { + return -TARGET_EFAULT; + } + tvp = tv; + } else { + tvp = NULL; + } + + p = lock_user_string(target_path); + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(utimes(p, tvp)); + unlock_user(p, target_path, 0); + return ret; +} +#endif + SYSCALL_IMPL(write) { int fd = arg1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f3ea9600c8..ca462fde61 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,69 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_utime - case TARGET_NR_utime: - { - struct utimbuf tbuf, *host_tbuf; - struct target_utimbuf *target_tbuf; - if (arg2) { - if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1)) - return -TARGET_EFAULT; - tbuf.actime = tswapal(target_tbuf->actime); - tbuf.modtime = tswapal(target_tbuf->modtime); - unlock_user_struct(target_tbuf, arg2, 0); - host_tbuf = &tbuf; - } else { - host_tbuf = NULL; - } - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(utime(p, host_tbuf)); - unlock_user(p, arg1, 0); - } - return ret; -#endif -#ifdef TARGET_NR_utimes - case TARGET_NR_utimes: - { - struct timeval *tvp, tv[2]; - if (arg2) { - if (copy_from_user_timeval(&tv[0], arg2) - || copy_from_user_timeval(&tv[1], - arg2 + sizeof(struct target_timeval))) - return -TARGET_EFAULT; - tvp = tv; - } else { - tvp = NULL; - } - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(utimes(p, tvp)); - unlock_user(p, arg1, 0); - } - return ret; -#endif -#if defined(TARGET_NR_futimesat) - case TARGET_NR_futimesat: - { - struct timeval *tvp, tv[2]; - if (arg3) { - if (copy_from_user_timeval(&tv[0], arg3) - || copy_from_user_timeval(&tv[1], - arg3 + sizeof(struct target_timeval))) - return -TARGET_EFAULT; - tvp = tv; - } else { - tvp = NULL; - } - if (!(p = lock_user_string(arg2))) { - return -TARGET_EFAULT; - } - ret = get_errno(futimesat(arg1, path(p), tvp)); - unlock_user(p, arg2, 0); - } - return ret; -#endif #ifdef TARGET_NR_access case TARGET_NR_access: if (!(p = lock_user_string(arg1))) { diff --git a/linux-user/strace.list b/linux-user/strace.list index b119b7a20c..c0c1b896f7 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -226,9 +226,6 @@ #ifdef TARGET_NR_futex { TARGET_NR_futex, "futex" , NULL, print_futex, NULL }, #endif -#ifdef TARGET_NR_futimesat -{ TARGET_NR_futimesat, "futimesat" , NULL, print_futimesat, NULL }, -#endif #ifdef TARGET_NR_getcpu { TARGET_NR_getcpu, "getcpu" , "%s(%p,%d)", NULL, NULL }, #endif @@ -1392,12 +1389,6 @@ #ifdef TARGET_NR_ustat { TARGET_NR_ustat, "ustat" , "%s(%#x,%p)", NULL, NULL }, #endif -#ifdef TARGET_NR_utime -{ TARGET_NR_utime, "utime" , NULL, print_utime, NULL }, -#endif -#ifdef TARGET_NR_utimes -{ TARGET_NR_utimes, "utimes" , NULL, print_utimes, NULL }, -#endif #ifdef TARGET_NR_utrap_install { TARGET_NR_utrap_install, "utrap_install" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027792 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="eRg2tOo4"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFL06vYjz9sDB for ; Sat, 19 Jan 2019 09:02:32 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47824 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcDe-0004VM-90 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:02:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56328) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbl6-0005g5-JH for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbl4-0005Lo-DL for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:00 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:33671) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbl3-0005Fk-2l for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:57 -0500 Received: by mail-pg1-x542.google.com with SMTP id z11so6661221pgu.0 for ; Fri, 18 Jan 2019 13:32:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=R+Y7Q/knJrp4IbesLUM7CvnwCm1qZrvO4LyA8sL+Brs=; b=eRg2tOo4bCfC/6fnXT482WfCDxMyG3Wdv7aIBm9KSCw8FeYFfqhJxw2d/1/GXqFP+b W5RrSmaa8QNsD3rvtbKKzc8mfG88MEVpKl1XCXWaxOon2c0jSjZt77/T6I8fxTSatDh1 umzgiBeP0rDZPDfyDrRxd4Tr9rSAVHpT0u6K8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R+Y7Q/knJrp4IbesLUM7CvnwCm1qZrvO4LyA8sL+Brs=; b=HM3bonRPEz2d7a/P3ixePz8yQm112bhDdiMSIM1EJYLvT0QBIYQSQeI9norplvr5Y6 jEoclmMC9ktyuJRp6u4tBS0ukQojMx1Zztoagzs3bdYoxGsHohEDo3ynOQsau+ZJRZJ8 tTfugCJRrwXnf6d96/CLMNspKW4lTIcf3L+PziUAYTa4lzp4BtN4NFLFv+nb0hbue7z3 WL29X2Gw9FlyWf/GdM4Nb1X3teEC6zN2PXAnsCluviIWru1oPM3FBHw8z3YZX/X3RA5Z QeFmnFbofvIWFKrWW++LIH9XNiY/Oir+H0zQf3JG8zhad7bsJjR+X6vUPXvWI4jGw495 6qwg== X-Gm-Message-State: AJcUukd2aGqrSzbpo9knZhdl3o1I/Kacb6aIJC+t/hktBaR8BgC0uOee vSBbAJerqJvz8HaaMwO0CUEw6td7Xgg= X-Google-Smtp-Source: ALg8bN7NNzjyCRNVddrWkZjgs7K+00EvUc7er9uuS+25vzTHNxEifafnuYp+vff0CcKwaprDcOVxmg== X-Received: by 2002:a63:8149:: with SMTP id t70mr19681133pgd.172.1547847173657; Fri, 18 Jan 2019 13:32:53 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:53 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:10 +1100 Message-Id: <20190118213122.22865-37-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::542 Subject: [Qemu-devel] [PATCH v6 37/49] linux-user: Split out access, faccessat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that faccessat is unconditionally available. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 4 ++++ linux-user/syscall.h | 1 + linux-user/strace.c | 33 ++++----------------------------- linux-user/syscall-file.inc.c | 25 +++++++++++++++++++++++++ linux-user/syscall.c | 18 ------------------ linux-user/strace.list | 6 ------ 6 files changed, 34 insertions(+), 53 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 2767e335d8..39e3ae3c21 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -16,6 +16,9 @@ * along with this program; if not, see . */ +#ifdef TARGET_NR_access +SYSCALL_DEF(access, ARG_STR, ARG_ACCESSFLAG); +#endif #ifdef TARGET_NR_alarm SYSCALL_DEF(alarm, ARG_DEC); #endif @@ -34,6 +37,7 @@ SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG); SYSCALL_DEF(exit, ARG_DEC); SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR); SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); +SYSCALL_DEF(faccessat, ARG_ATDIRFD, ARG_STR, ARG_ACCESSFLAG); SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG); SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG); #ifdef TARGET_NR_futimesat diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 3c936b648a..84a52b2d9a 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -57,6 +57,7 @@ typedef enum { /* These print as sets of flags. */ ARG_ATDIRFD, + ARG_ACCESSFLAG, ARG_ATFLAG, ARG_CLONEFLAG, ARG_MMAPFLAG, diff --git a/linux-user/strace.c b/linux-user/strace.c index b54949df27..da2cc30f82 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -634,7 +634,7 @@ print_syscall_ret_adjtimex(const struct syscallname *name, abi_long ret) gemu_log("\n"); } -UNUSED static struct flags access_flags[] = { +static struct flags const access_flags[] = { FLAG_GENERIC(F_OK), FLAG_GENERIC(R_OK), FLAG_GENERIC(W_OK), @@ -1114,19 +1114,6 @@ print_accept(const struct syscallname *name, } #endif -#ifdef TARGET_NR_access -static void -print_access(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_flags(access_flags, arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_clock_adjtime static void print_clock_adjtime(const struct syscallname *name, @@ -1153,21 +1140,6 @@ print_execv(const struct syscallname *name, } #endif -#ifdef TARGET_NR_faccessat -static void -print_faccessat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_flags(access_flags, arg2, 0); - print_flags(at_file_flags, arg3, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_fchownat static void print_fchownat(const struct syscallname *name, @@ -2206,6 +2178,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_ATDIRFD: len = add_atdirfd(b, rest, arg); break; + case ARG_ACCESSFLAG: + len = add_flags(b, rest, access_flags, arg, false); + break; case ARG_ATFLAG: len = add_flags(b, rest, at_file_flags, arg, false); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 6a7ef80bfc..3111abd861 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -16,6 +16,26 @@ * along with this program; if not, see . */ +static abi_long do_faccessat(int dirfd, abi_ulong target_path, int mode) +{ + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(faccessat(dirfd, p, mode, 0)); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_access +SYSCALL_IMPL(access) +{ + return do_faccessat(AT_FDCWD, arg1, arg2); +} +#endif + SYSCALL_IMPL(chdir) { abi_ulong target_path = arg1; @@ -74,6 +94,11 @@ SYSCALL_IMPL(creat) } #endif +SYSCALL_IMPL(faccessat) +{ + return do_faccessat(arg1, arg2, arg3); +} + SYSCALL_IMPL(fchmod) { return get_errno(fchmod(arg1, arg2)); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ca462fde61..9074cf8b8d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,24 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_access - case TARGET_NR_access: - if (!(p = lock_user_string(arg1))) { - return -TARGET_EFAULT; - } - ret = get_errno(access(path(p), arg2)); - unlock_user(p, arg1, 0); - return ret; -#endif -#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) - case TARGET_NR_faccessat: - if (!(p = lock_user_string(arg2))) { - return -TARGET_EFAULT; - } - ret = get_errno(faccessat(arg1, p, arg3, 0)); - unlock_user(p, arg2, 0); - return ret; -#endif #ifdef TARGET_NR_nice /* not on alpha */ case TARGET_NR_nice: return get_errno(nice(arg1)); diff --git a/linux-user/strace.list b/linux-user/strace.list index c0c1b896f7..fc0eb91e29 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -9,9 +9,6 @@ #ifdef TARGET_NR_accept4 { TARGET_NR_accept4, "accept4" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_access -{ TARGET_NR_access, "access" , NULL, print_access, NULL }, -#endif #ifdef TARGET_NR_acct { TARGET_NR_acct, "acct" , NULL, NULL, NULL }, #endif @@ -142,9 +139,6 @@ #ifdef TARGET_NR_exit_group { TARGET_NR_exit_group, "exit_group" , "%s(%d)\n", NULL, NULL }, #endif -#ifdef TARGET_NR_faccessat -{ TARGET_NR_faccessat, "faccessat" , NULL, print_faccessat, NULL }, -#endif #ifdef TARGET_NR_fadvise64 { TARGET_NR_fadvise64, "fadvise64" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027775 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ECsFVkky"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF0w1dwZz9sDP for ; Sat, 19 Jan 2019 08:47:44 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47613 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbzK-0000hG-1B for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:47:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56330) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbl6-0005g6-JO for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbl4-0005N7-Qa for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:00 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:45122) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbl3-0005J5-58 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:32:58 -0500 Received: by mail-pg1-x542.google.com with SMTP id y4so6630308pgc.12 for ; Fri, 18 Jan 2019 13:32:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mMLXq3y5oDzTH+FS6gxmVbqTOM9CfvVIfIxHklj9DEE=; b=ECsFVkkyG2U2ifnOLYIPTNfoG6MEgQK7Dplr84fRKJFiV996G/SHJq2v/56qUPOZtp W6szXUTdSSCh9/Am54pB9BcQJU/S9JnYs9QFQ14rHVV6MPGkYis7oCG4L0Flx/QiVuDQ 6mLQopO6cyS+T4VyLX3FNA1WQkn+EfP1rXV1k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mMLXq3y5oDzTH+FS6gxmVbqTOM9CfvVIfIxHklj9DEE=; b=nZzc3OMDX4jijNOqFioxDOskk0XVTJM1H05LcvjKwjYa55YAHGS9jKuOoMiHwOToRL ydxGnwM3Fo3fBrigUvEyeUpz3n30Nx5Hv1Chc5qwdFA6f18EViXU9SJm+OUTkQQfEVHn DMJ8Dw1pwwWKB87h2BHYYt89fA8Ja5sZWfIh4qr+mUxYK8h9Ks11CCiRhj20+MpCMEpg trlZn8BL2Zq61ZTCJv+OdKk8+iDCa+vRrcR45ZADwedO7aubGgP4DS3+S7JciPeSJ+PT g3EdzB1/sl3rfz5BCVA3y7713uyxOLlO43I6hrnu+eGvmTdNt02fM/Hh+Z7E8JB5D+6H byTA== X-Gm-Message-State: AJcUukddTfVpf/yJoQ6XAB5hcsvNBvSFpvFGaOgwiOH+LsnGDNR9aVa4 2e2TsmysuKBCCTiSM+0gwKeMSfm+13M= X-Google-Smtp-Source: ALg8bN6OkxKJEPzklQrbC5IkiFG0iidNRLKaDCX6wsyu09IG9KiwbVDudQf5rAldIzrEMP101fq8CQ== X-Received: by 2002:a65:50c1:: with SMTP id s1mr18918723pgp.350.1547847175906; Fri, 18 Jan 2019 13:32:55 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:55 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:11 +1100 Message-Id: <20190118213122.22865-38-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::542 Subject: [Qemu-devel] [PATCH v6 38/49] linux-user: Split out nice X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 3 +++ linux-user/syscall-proc.inc.c | 7 +++++++ linux-user/syscall.c | 4 ---- linux-user/strace.list | 3 --- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 39e3ae3c21..860754aaca 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -111,6 +111,9 @@ SYSCALL_DEF(munlockall); SYSCALL_DEF(munmap, ARG_PTR, ARG_DEC); SYSCALL_DEF(name_to_handle_at, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); +#ifdef TARGET_NR_nice +SYSCALL_DEF(nice, ARG_DEC); +#endif #ifdef TARGET_NR_open SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index c09c83775c..58c0a22300 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -461,6 +461,13 @@ SYSCALL_IMPL(getxpid) } #endif +#ifdef TARGET_NR_nice +SYSCALL_IMPL(nice) +{ + return get_errno(nice(arg1)); +} +#endif + /* * Map host to target signal numbers for the wait family of syscalls. * Assume all other status bits are the same. diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9074cf8b8d..351b2a6288 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5327,10 +5327,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_nice /* not on alpha */ - case TARGET_NR_nice: - return get_errno(nice(arg1)); -#endif case TARGET_NR_sync: sync(); return 0; diff --git a/linux-user/strace.list b/linux-user/strace.list index fc0eb91e29..aaea23d433 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -527,9 +527,6 @@ #ifdef TARGET_NR_nfsservctl { TARGET_NR_nfsservctl, "nfsservctl" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_nice -{ TARGET_NR_nice, "nice" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_old_adjtimex { TARGET_NR_old_adjtimex, "old_adjtimex" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027781 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RpdDd2M6"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF8K5s8Yz9s9G for ; Sat, 19 Jan 2019 08:54:08 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc5S-0005hj-Ap for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:54:02 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56358) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbl8-0005gN-QJ for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbl6-0005Q0-Nq for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:02 -0500 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]:36046) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbl6-0005NR-Hg for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:00 -0500 Received: by mail-pg1-x543.google.com with SMTP id n2so6650602pgm.3 for ; Fri, 18 Jan 2019 13:32:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=u8Rc++t84OpvMGiXblGmPrszhVLdnSkDh7cV8BTE/9A=; b=RpdDd2M6oMxGt9vnVoJy8Tok0hvBw+LUR7oETEzhrB8Ab+fwvm9UlG/7XTDHNBWJZZ I29oHhcW7+N27mk44OJM2SlVCQtRsiYFSD/YbYCiRKd19NameqNx2AVFiAntSKWsyhEa /f8qrwj2Ag3uA4tBF7M75olxuBcE4U3sHSzZI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=u8Rc++t84OpvMGiXblGmPrszhVLdnSkDh7cV8BTE/9A=; b=JzB0J+DLbKu3yGGVmH8ZvXC7002Q5P78hftSLsA6+qJl9JtTRKNmzYdjeA5WL3A50x eZhW7HgQJGPly1yJN7XelqyNVgIII35AwvauXsgE9ILjeYpRbrs6//K77jeDmn1Tc4dl qth2z9M40DZ2y9iJvlX3MAp9WYE7vu0xPML+v+hRqFQPVX8+RZILviTW2hJCyJF3o/zj 6IfnOPtw9BwGPfTq00mEQreOJqjO+TGNCN9ScnsLguz5KykqXJ8FZIt5wyUikwNrXc5B H9LFVA6n4fBtu/EIArGNcDQVZTQlxa4Nf0nn6wru7SrnHWIxfind+p9FgN8OMUnChlBd qj0g== X-Gm-Message-State: AJcUukeh6pE17vdII+qYAta/B0pBpmtIXpY2oAVeBLdkrc/AnGpOI/zo AKglIQyZlqYpiBH8+FZ1DeRCfDBuwuU= X-Google-Smtp-Source: ALg8bN7T+Q3Y4M2fiXtIi32Q02oRrSC66izvv7KqFnfC9x5ECP6e7KgCG2focfdjiOTTaryLNX2ufg== X-Received: by 2002:a63:9f19:: with SMTP id g25mr19301741pge.327.1547847178178; Fri, 18 Jan 2019 13:32:58 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:32:57 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:12 +1100 Message-Id: <20190118213122.22865-39-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::543 Subject: [Qemu-devel] [PATCH v6 39/49] linux-user: Split out sync, syncfs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that syncfs is universally available. If !CONFIG_SYNCFS, provide our own syscall replacement. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 2 ++ linux-user/syscall-file.inc.c | 11 +++++++++++ linux-user/syscall.c | 20 ++++++++++++-------- linux-user/strace.list | 6 ------ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 860754aaca..497fbdba66 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -171,6 +171,8 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); #ifdef TARGET_NR_stime SYSCALL_DEF(stime, ARG_PTR); #endif +SYSCALL_DEF(sync); +SYSCALL_DEF(syncfs, ARG_DEC); #ifdef TARGET_NR_time SYSCALL_DEF(time, ARG_PTR); #endif diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 3111abd861..80dec33971 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -867,6 +867,17 @@ SYSCALL_IMPL(readlinkat) } #endif +SYSCALL_IMPL(sync) +{ + sync(); + return 0; +} + +SYSCALL_IMPL(syncfs) +{ + return get_errno(syncfs(arg1)); +} + static abi_long do_umount2(abi_ulong target_path, int flags) { char *p = lock_user_string(target_path); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 351b2a6288..6668e4ada8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -199,6 +199,15 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #define TARGET_NR_llseek TARGET_NR__llseek #endif +/* + * These definitions produce an ENOSYS from the host kernel. + * Performing a bogus sysacll is lazier than boilerplating + * the replacement functions here in C. + */ +#ifndef __NR_syncfs +#define __NR_syncfs -1 +#endif + #ifdef __NR_gettid _syscall0(int, gettid) #else @@ -264,11 +273,13 @@ _syscall3(int, ioprio_set, int, which, int, who, int, ioprio) #if defined(TARGET_NR_getrandom) && defined(__NR_getrandom) _syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags) #endif - #if defined(TARGET_NR_kcmp) && defined(__NR_kcmp) _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2) #endif +#ifndef CONFIG_SYNCFS +_syscall1(int, syncfs, int, fd) +#endif static bitmask_transtbl fcntl_flags_tbl[] = { { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, @@ -5327,13 +5338,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_sync: - sync(); - return 0; -#if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS) - case TARGET_NR_syncfs: - return get_errno(syncfs(arg1)); -#endif case TARGET_NR_kill: return get_errno(safe_kill(arg1, target_to_host_signal(arg2))); #ifdef TARGET_NR_rename diff --git a/linux-user/strace.list b/linux-user/strace.list index aaea23d433..56f25c15b7 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1260,12 +1260,6 @@ #ifdef TARGET_NR_symlinkat { TARGET_NR_symlinkat, "symlinkat", NULL, print_symlinkat, NULL }, #endif -#ifdef TARGET_NR_sync -{ TARGET_NR_sync, "sync" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_syncfs -{ TARGET_NR_syncfs, "syncfs" , "%s(%d)", NULL, NULL }, -#endif #ifdef TARGET_NR_syscall { TARGET_NR_syscall, "syscall" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027808 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RHAjRVMB"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFbx4dsPz9sBQ for ; Sat, 19 Jan 2019 09:14:37 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48016 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcPL-0005Zg-Gv for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:14:35 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56369) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblA-0005hV-N3 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbl8-0005S4-Rz for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:04 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:36456) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbl8-0005Qc-3b for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:02 -0500 Received: by mail-pl1-x644.google.com with SMTP id g9so6895762plo.3 for ; Fri, 18 Jan 2019 13:33:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LiKNsrT5K+9huwcDKVj3zEFjQudVZx9YMALKhLtpl5w=; b=RHAjRVMBKgQJXcwTC0TVoBIiWj027k7NrfalQK+Q5xRKydsxVZZh7AmnDHuQPZtMM0 bgcbUXA1Bn5yJX2gLQRnGBZ4f8CaPIwqXxFTjo6Q4Hgh00lpa0Z8MspSbBdldvtZUu8N 5Kugw9QI3Ae6atT6iUBHLB8MU8PDAWaeWZoVw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LiKNsrT5K+9huwcDKVj3zEFjQudVZx9YMALKhLtpl5w=; b=F6rWIhhGFLjqI2pdYUS1ytmEA0gZrA+Zl9w6kDfw0Svis/11M1yhlpuaQlLu+TGmeP /vcNQBMbStPysXRiaqlCT44qR2F84uv14n3DiLCAtzg6C33i+RvFXDvbIqMujSwgpHog bIUz9Wu787HAVixzJ8vYZo82Tk0ezgIp1ux/shE9jpBuwzu5CjSmZnj7QSWqRWVvC5MO osckWImh5NJfY9rJDgpCgteYTagahALzkX0rtEg5fney/8DvUgreIZzspR8ygsKxJnWn oSAl2g2NmMmEoWnLxdFKypH9ohO+CcUTeF1taxEi24jU9pSyTU8B/gTRzXCGbVMfBpmi RuVw== X-Gm-Message-State: AJcUukdNELWX6NvcHp4CIy8H+HfIxLLVQjphgYq5D8hSC3LkevPi0/t8 vyxssl0+OiLUD3xv+U5XnOVH+rCWUmI= X-Google-Smtp-Source: ALg8bN4jk4pPq5yvkisSOvH+/1FSCV5bu/NoDhsD34GJdKN5PZzOHE02BiUZ22V4nZQlyIv4U0kgVQ== X-Received: by 2002:a17:902:c5:: with SMTP id a63mr21030958pla.267.1547847180676; Fri, 18 Jan 2019 13:33:00 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.32.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:00 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:13 +1100 Message-Id: <20190118213122.22865-40-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 40/49] linux-user: Split out kill X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall.h | 7 +++- linux-user/strace.c | 76 ++++++++++++++++++------------------ linux-user/syscall-sig.inc.c | 5 +++ linux-user/syscall.c | 2 - linux-user/strace.list | 3 -- 6 files changed, 48 insertions(+), 46 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 497fbdba66..c672b5ad99 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -58,6 +58,7 @@ SYSCALL_DEF(getxpid); #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif +SYSCALL_DEF(kill, ARG_DEC, ARG_SIGNAL); #ifdef TARGET_NR_link SYSCALL_DEF(link, ARG_STR, ARG_STR); #endif diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 84a52b2d9a..642fb6dccb 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -55,8 +55,12 @@ typedef enum { ARG_HEX, ARG_OCT, - /* These print as sets of flags. */ + /* These numbers are interpreted. */ ARG_ATDIRFD, + ARG_SIGNAL, + ARG_LSEEKWHENCE, + + /* These print as sets of flags. */ ARG_ACCESSFLAG, ARG_ATFLAG, ARG_CLONEFLAG, @@ -67,7 +71,6 @@ typedef enum { ARG_OPENFLAG, ARG_UMOUNTFLAG, ARG_UNLINKATFLAG, - ARG_LSEEKWHENCE, /* These are interpreted as pointers. */ ARG_PTR, diff --git a/linux-user/strace.c b/linux-user/strace.c index da2cc30f82..ec36fcf2c2 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -70,35 +70,43 @@ UNUSED static void print_socket_protocol(int domain, int type, int protocol); /* * Utility functions */ +static int +add_signal(char *buf, int size, int sig) +{ + static const char * const signals[] = { + [TARGET_SIGHUP] = "SIGHUP", + [TARGET_SIGINT] = "SIGINT", + [TARGET_SIGQUIT] = "SIGQUIT", + [TARGET_SIGILL] = "SIGILL", + [TARGET_SIGABRT] = "SIGABRT", + [TARGET_SIGFPE] = "SIGFPE", + [TARGET_SIGKILL] = "SIGKILL", + [TARGET_SIGSEGV] = "SIGSEGV", + [TARGET_SIGPIPE] = "SIGPIPE", + [TARGET_SIGALRM] = "SIGALRM", + [TARGET_SIGTERM] = "SIGTERM", + [TARGET_SIGUSR1] = "SIGUSR1", + [TARGET_SIGUSR2] = "SIGUSR2", + [TARGET_SIGCHLD] = "SIGCHLD", + [TARGET_SIGCONT] = "SIGCONT", + [TARGET_SIGSTOP] = "SIGSTOP", + [TARGET_SIGTTIN] = "SIGTTIN", + [TARGET_SIGTTOU] = "SIGTTOU", + }; + + if (sig >= 0 && sig < ARRAY_SIZE(signals) && signals[sig]) { + return snprintf(buf, size, "%s", signals[sig]); + } else { + return snprintf(buf, size, "%d", sig); + } +} + static void print_signal(abi_ulong arg, int last) { - const char *signal_name = NULL; - switch(arg) { - case TARGET_SIGHUP: signal_name = "SIGHUP"; break; - case TARGET_SIGINT: signal_name = "SIGINT"; break; - case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break; - case TARGET_SIGILL: signal_name = "SIGILL"; break; - case TARGET_SIGABRT: signal_name = "SIGABRT"; break; - case TARGET_SIGFPE: signal_name = "SIGFPE"; break; - case TARGET_SIGKILL: signal_name = "SIGKILL"; break; - case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break; - case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break; - case TARGET_SIGALRM: signal_name = "SIGALRM"; break; - case TARGET_SIGTERM: signal_name = "SIGTERM"; break; - case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break; - case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break; - case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break; - case TARGET_SIGCONT: signal_name = "SIGCONT"; break; - case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break; - case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break; - case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break; - } - if (signal_name == NULL) { - print_raw_param("%ld", arg, last); - return; - } - gemu_log("%s%s", signal_name, get_comma(last)); + char buf[16]; + add_signal(buf, sizeof(buf), arg); + gemu_log("%s%s", buf, get_comma(last)); } static void print_si_code(int arg) @@ -2032,19 +2040,6 @@ print_futex(const struct syscallname *name, } #endif -#ifdef TARGET_NR_kill -static void -print_kill(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_raw_param("%d", arg0, 0); - print_signal(arg1, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_tkill static void print_tkill(const struct syscallname *name, @@ -2178,6 +2173,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_ATDIRFD: len = add_atdirfd(b, rest, arg); break; + case ARG_SIGNAL: + len = add_signal(b, rest, arg); + break; case ARG_ACCESSFLAG: len = add_flags(b, rest, access_flags, arg, false); break; diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c index f4e43eb00e..a4fbcc567d 100644 --- a/linux-user/syscall-sig.inc.c +++ b/linux-user/syscall-sig.inc.c @@ -23,6 +23,11 @@ SYSCALL_IMPL(alarm) } #endif +SYSCALL_IMPL(kill) +{ + return get_errno(safe_kill(arg1, target_to_host_signal(arg2))); +} + #ifdef TARGET_NR_pause SYSCALL_IMPL(pause) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6668e4ada8..fef955ce66 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5338,8 +5338,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_kill: - return get_errno(safe_kill(arg1, target_to_host_signal(arg2))); #ifdef TARGET_NR_rename case TARGET_NR_rename: { diff --git a/linux-user/strace.list b/linux-user/strace.list index 56f25c15b7..b120f11dc2 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -410,9 +410,6 @@ #ifdef TARGET_NR_keyctl { TARGET_NR_keyctl, "keyctl" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_kill -{ TARGET_NR_kill, "kill", NULL, print_kill, NULL }, -#endif #ifdef TARGET_NR_lchown { TARGET_NR_lchown, "lchown" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027797 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="PE6KHQ4F"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFP76FqNz9sDP for ; Sat, 19 Jan 2019 09:05:14 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47840 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcGF-0006Mg-P6 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:05:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56386) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblD-0005l4-6v for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblA-0005Ub-Vj for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:06 -0500 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]:36454) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblA-0005TQ-Ns for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:04 -0500 Received: by mail-pl1-x641.google.com with SMTP id g9so6895802plo.3 for ; Fri, 18 Jan 2019 13:33:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kfnpoBOZ3QnhfCaB6uxqqg+GQ9uply4bFdEiuD9NdEg=; b=PE6KHQ4FQPPO4dJkNMVwgabOcUvHfLSsqtPSrP9dS5EsI/KoKaNlS3rRg0k7b5nJga VoG9wb9i0hDJFUzxskNb6M6rZd91Zdy5xZ02Vzfp98yQJa+cd2FDUOHe85A3fX8SUYVY UP2AyZuE2Vrq8RJCmuWItEqSLaS3dhc15MQiE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kfnpoBOZ3QnhfCaB6uxqqg+GQ9uply4bFdEiuD9NdEg=; b=uifamrMxiW1ryU7HABNGt/jFhb9t8h7szXD+AzT9NPJ/gbdu7BOoRbo0/tNL7PvaXp hA3CuKtTdzVN+o6hjCs0tW2/RXQ9lZNAY7rIrDGwyBYgAkqYdsvS/Xs4ufrf2GIhNVL5 w1kJ/otZktoQL7RW2WBn6aLo+Nr7KWIp8FTY+koS1Cdg0fRtX23+odSNhB6bMbIk2elq iUNc9lrqwpDHX1Kb8vSMxMfBMOndAl0932K0Ji+QWOJQH8AqqkiQEVSK84vEJoifA5HC Y/rg15nNnsiUD5WkfpqYM5Si2J6/EDEVtMG28REElcZ7g3MlkSIqYoHq2KxZiwXsf8aj BmGg== X-Gm-Message-State: AJcUukeYX5sEvbhVBVvdiFpiJKhBL4sbKbXN510Inm3DgyB4MZfxLcr6 MjqsS4M5SyIZwVXchYAo6bDrxvveLHo= X-Google-Smtp-Source: ALg8bN7HHQu1tz7QY+hMOrq/lIl4uf+BeAJ+C06zB4ionHkTH8HbXy2c/HpJygTQ15fpMqsiEA80Gg== X-Received: by 2002:a17:902:14e:: with SMTP id 72mr20877017plb.287.1547847183043; Fri, 18 Jan 2019 13:33:03 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:02 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:14 +1100 Message-Id: <20190118213122.22865-41-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::641 Subject: [Qemu-devel] [PATCH v6 41/49] linux-user: Split out rename, renameat, renameat2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that renameat2 is universally available for guests. Merge sys_renameat2 into the new do_renameat2 helper. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 8 +++++ linux-user/syscall.h | 1 + linux-user/strace.c | 39 ++++++--------------- linux-user/syscall-file.inc.c | 45 ++++++++++++++++++++++++ linux-user/syscall.c | 64 ----------------------------------- linux-user/strace.list | 9 ----- 6 files changed, 65 insertions(+), 101 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index c672b5ad99..0ed01aa100 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -142,6 +142,14 @@ SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC); #ifdef TARGET_NR_readlinkat SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC); #endif +#ifdef TARGET_NR_rename +SYSCALL_DEF(rename, ARG_STR, ARG_STR); +#endif +#ifdef TARGET_NR_renameat +SYSCALL_DEF(renameat, ARG_ATDIRFD, ARG_STR, ARG_ATDIRFD, ARG_STR); +#endif +SYSCALL_DEF(renameat2, ARG_ATDIRFD, ARG_STR, + ARG_ATDIRFD, ARG_STR, ARG_RENAMEFLAG); SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC); #ifdef TARGET_NR_rmdir SYSCALL_DEF(rmdir, ARG_STR); diff --git a/linux-user/syscall.h b/linux-user/syscall.h index 642fb6dccb..7b197840f5 100644 --- a/linux-user/syscall.h +++ b/linux-user/syscall.h @@ -69,6 +69,7 @@ typedef enum { ARG_MODEFLAG, ARG_MOUNTFLAG, ARG_OPENFLAG, + ARG_RENAMEFLAG, ARG_UMOUNTFLAG, ARG_UNLINKATFLAG, diff --git a/linux-user/strace.c b/linux-user/strace.c index ec36fcf2c2..6dce7e52c0 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "qemu.h" #include "syscall.h" @@ -741,6 +742,13 @@ static struct flags const mount_flags[] = { FLAG_END, }; +static struct flags const renameat2_flags[] = { + FLAG_GENERIC(RENAME_EXCHANGE), + FLAG_GENERIC(RENAME_NOREPLACE), + FLAG_GENERIC(RENAME_WHITEOUT), + FLAG_END, +}; + static struct flags const umount2_flags[] = { #ifdef MNT_FORCE FLAG_GENERIC(MNT_FORCE), @@ -1887,34 +1895,6 @@ print_fstatat64(const struct syscallname *name, #define print_newfstatat print_fstatat64 #endif -#ifdef TARGET_NR_rename -static void -print_rename(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_string(arg1, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_renameat -static void -print_renameat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_at_dirfd(arg2, 0); - print_string(arg3, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_statfs static void print_statfs(const struct syscallname *name, @@ -2200,6 +2180,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6]) case ARG_OPENFLAG: len = add_open_flags(b, rest, arg); break; + case ARG_RENAMEFLAG: + len = add_flags(b, rest, renameat2_flags, arg, false); + break; case ARG_UMOUNTFLAG: len = add_flags(b, rest, umount2_flags, arg, false); break; diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 80dec33971..9099107631 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -867,6 +867,51 @@ SYSCALL_IMPL(readlinkat) } #endif +static abi_long do_renameat2(int oldfd, abi_ulong target_oldpath, + int newfd, abi_ulong target_newpath, + unsigned int flags) +{ + char *p_old = lock_user_string(target_oldpath); + char *p_new = lock_user_string(target_newpath); + abi_long ret = -TARGET_EFAULT; + + if (p_old && p_new) { + if (flags == 0) { + ret = renameat(oldfd, p_old, newfd, p_new); + } else { +#ifdef __NR_renameat2 + ret = syscall(__NR_renameat2, oldfd, p_old, newfd, p_new, flags); +#else + errno = ENOSYS; + ret = -1; +#endif + } + ret = get_errno(ret); + } + unlock_user(p_old, target_oldpath, 0); + unlock_user(p_new, target_newpath, 0); + return ret; +} + +#ifdef TARGET_NR_rename +SYSCALL_IMPL(rename) +{ + return do_renameat2(AT_FDCWD, arg1, AT_FDCWD, arg2, 0); +} +#endif + +#ifdef TARGET_NR_renameat +SYSCALL_IMPL(renameat) +{ + return do_renameat2(arg1, arg2, arg3, arg4, 0); +} +#endif + +SYSCALL_IMPL(renameat2) +{ + return do_renameat2(arg1, arg2, arg3, arg4, arg5); +} + SYSCALL_IMPL(sync) { sync(); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index fef955ce66..fe38ec59d4 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -341,24 +341,6 @@ static int sys_utimensat(int dirfd, const char *pathname, #endif #endif /* TARGET_NR_utimensat */ -#ifdef TARGET_NR_renameat2 -#if defined(__NR_renameat2) -#define __NR_sys_renameat2 __NR_renameat2 -_syscall5(int, sys_renameat2, int, oldfd, const char *, old, int, newfd, - const char *, new, unsigned int, flags) -#else -static int sys_renameat2(int oldfd, const char *old, - int newfd, const char *new, int flags) -{ - if (flags == 0) { - return renameat(oldfd, old, newfd, new); - } - errno = ENOSYS; - return -1; -} -#endif -#endif /* TARGET_NR_renameat2 */ - #ifdef CONFIG_INOTIFY #include @@ -5338,52 +5320,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_rename - case TARGET_NR_rename: - { - void *p2; - p = lock_user_string(arg1); - p2 = lock_user_string(arg2); - if (!p || !p2) - ret = -TARGET_EFAULT; - else - ret = get_errno(rename(p, p2)); - unlock_user(p2, arg2, 0); - unlock_user(p, arg1, 0); - } - return ret; -#endif -#if defined(TARGET_NR_renameat) - case TARGET_NR_renameat: - { - void *p2; - p = lock_user_string(arg2); - p2 = lock_user_string(arg4); - if (!p || !p2) - ret = -TARGET_EFAULT; - else - ret = get_errno(renameat(arg1, p, arg3, p2)); - unlock_user(p2, arg4, 0); - unlock_user(p, arg2, 0); - } - return ret; -#endif -#if defined(TARGET_NR_renameat2) - case TARGET_NR_renameat2: - { - void *p2; - p = lock_user_string(arg2); - p2 = lock_user_string(arg4); - if (!p || !p2) { - ret = -TARGET_EFAULT; - } else { - ret = get_errno(sys_renameat2(arg1, p, arg3, p2, arg5)); - } - unlock_user(p2, arg4, 0); - unlock_user(p, arg2, 0); - } - return ret; -#endif #ifdef TARGET_NR_mkdir case TARGET_NR_mkdir: if (!(p = lock_user_string(arg1))) diff --git a/linux-user/strace.list b/linux-user/strace.list index b120f11dc2..56aab25d9f 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -944,15 +944,6 @@ #ifdef TARGET_NR_removexattr { TARGET_NR_removexattr, "removexattr" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_rename -{ TARGET_NR_rename, "rename" , NULL, print_rename, NULL }, -#endif -#ifdef TARGET_NR_renameat -{ TARGET_NR_renameat, "renameat" , NULL, print_renameat, NULL }, -#endif -#ifdef TARGET_NR_renameat2 -{ TARGET_NR_renameat2, "renameat2" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_request_key { TARGET_NR_request_key, "request_key" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027799 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="O8qBEX2l"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFSM4Yjbz9sDB for ; Sat, 19 Jan 2019 09:08:03 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47909 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcIz-0000D8-C9 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:08:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56417) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblD-0005mr-QT for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblC-0005Xn-Qj for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:07 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:42955) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblC-0005Wg-KW for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:06 -0500 Received: by mail-pl1-x642.google.com with SMTP id y1so6881261plp.9 for ; Fri, 18 Jan 2019 13:33:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=l2U9V7OWcdwqxw57y+bKKgPCSnPcotL021xUC/JbE6c=; b=O8qBEX2lSA28jSsUdzd4X4UW/aE/umX+htbqOf47v7GuLQ3C2qZctQFMiqCywRMWW7 vSpeu1N/bOh79ZS5MmT4BdYv0iRG6JuUe5Juc4epRIMj7ia93qI5DGBMzVhu2t/IpqMV o3Iv62pfM+rsRd0ZhkDDwDPGVhaK9pa8RQExg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=l2U9V7OWcdwqxw57y+bKKgPCSnPcotL021xUC/JbE6c=; b=cMsCXSKfz/Jc4NDH2tNGrDV1kQ4PkqSvbutV4bXdkFgTpEmf2+LGWfV++OKGbcyUqs QDPvKVmKq14V4H5ECgdCsiPxspMNP96idTwbcScNZ8sPyTcnbwy2EOLFq/By88/52oeA icKcOmhCF2evCEF0vZvJeU61VyqVQwqXCu64MYB8Y/lnXEK4ZaUC+XrhCXImUG40jq5Y MxLze23sEPC0pnp4sEmKinV9DD20skaro2xNobADk/eENbS/4AawqDhaPGA1NFI9tFy+ HC9wJIRimGZJCBlmE5d+DEMTb0JiVFPZaEhGkSX9+y9k1ijqZeiUVfx7QV6xLWvbm3Su uuEA== X-Gm-Message-State: AJcUukd4KyPzEoqiDI1KtiqkHpMQ01mFTjxW4eCG13panOlDXX1u658O cNgo4NCXkDLlhkUTIqCQH5W7en4zLRA= X-Google-Smtp-Source: ALg8bN5fX7EdmTh4dDBbKYo79KV3hWcjaC3rIPbYLXdg/5O/043oS9+M5MJjzriDDsEuHRQRg1Dg8w== X-Received: by 2002:a17:902:b112:: with SMTP id q18mr20752660plr.255.1547847185391; Fri, 18 Jan 2019 13:33:05 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:04 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:15 +1100 Message-Id: <20190118213122.22865-42-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH v6 42/49] linux-user: Split out mkdir, mkdirat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that mkdirat is universally available. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 4 ++++ linux-user/strace.c | 27 --------------------------- linux-user/syscall-file.inc.c | 25 +++++++++++++++++++++++++ linux-user/syscall.c | 16 ---------------- linux-user/strace.list | 6 ------ 5 files changed, 29 insertions(+), 49 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 0ed01aa100..8b6d8f75ff 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -69,6 +69,10 @@ SYSCALL_DEF(lseek, ARG_DEC, ARG_DEC, ARG_LSEEKWHENCE); #ifdef TARGET_NR_llseek SYSCALL_DEF_ARGS(llseek, ARG_DEC, ARG_DEC, ARG_PTR, ARG_LSEEKWHENCE); #endif +#ifdef TARGET_NR_mkdir +SYSCALL_DEF(mkdir, ARG_STR, ARG_MODEFLAG); +#endif +SYSCALL_DEF(mkdirat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG); #ifdef TARGET_NR_mknod SYSCALL_DEF(mknod, ARG_STR, ARG_MODEFLAG, ARG_HEX); #endif diff --git a/linux-user/strace.c b/linux-user/strace.c index 6dce7e52c0..ca8e110675 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1664,33 +1664,6 @@ print_fstat(const struct syscallname *name, #define print_fstat64 print_fstat #endif -#ifdef TARGET_NR_mkdir -static void -print_mkdir(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_string(arg0, 0); - print_file_mode(arg1, 1); - print_syscall_epilogue(name); -} -#endif - -#ifdef TARGET_NR_mkdirat -static void -print_mkdirat(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_at_dirfd(arg0, 0); - print_string(arg1, 0); - print_file_mode(arg2, 1); - print_syscall_epilogue(name); -} -#endif - #ifdef TARGET_NR_rt_sigaction static void print_rt_sigaction(const struct syscallname *name, diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 9099107631..83174c5781 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -205,6 +205,31 @@ SYSCALL_IMPL(llseek) } #endif +static abi_long do_mkdirat(int dirfd, abi_ulong target_path, mode_t mode) +{ + char *p = lock_user_string(target_path); + abi_long ret; + + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(mkdirat(dirfd, p, mode)); + unlock_user(p, target_path, 0); + return ret; +} + +#ifdef TARGET_NR_mkdir +SYSCALL_IMPL(mkdir) +{ + return do_mkdirat(AT_FDCWD, arg1, arg2); +} +#endif + +SYSCALL_IMPL(mkdirat) +{ + return do_mkdirat(arg1, arg2, arg3); +} + static abi_long do_mknodat(int dirfd, abi_ulong target_path, mode_t mode, dev_t dev) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index fe38ec59d4..7874a48840 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5320,22 +5320,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_mkdir - case TARGET_NR_mkdir: - if (!(p = lock_user_string(arg1))) - return -TARGET_EFAULT; - ret = get_errno(mkdir(p, arg2)); - unlock_user(p, arg1, 0); - return ret; -#endif -#if defined(TARGET_NR_mkdirat) - case TARGET_NR_mkdirat: - if (!(p = lock_user_string(arg2))) - return -TARGET_EFAULT; - ret = get_errno(mkdirat(arg1, p, arg3)); - unlock_user(p, arg2, 0); - return ret; -#endif case TARGET_NR_dup: ret = get_errno(dup(arg1)); if (ret >= 0) { diff --git a/linux-user/strace.list b/linux-user/strace.list index 56aab25d9f..678feeeb7b 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -473,12 +473,6 @@ #ifdef TARGET_NR_mincore { TARGET_NR_mincore, "mincore" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_mkdir -{ TARGET_NR_mkdir, "mkdir" , NULL, print_mkdir, NULL }, -#endif -#ifdef TARGET_NR_mkdirat -{ TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL }, -#endif #ifdef TARGET_NR_modify_ldt { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="i81tnu+j"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF4l2qfzz9sDL for ; Sat, 19 Jan 2019 08:51:03 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47655 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc2X-0003JX-As for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:51:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56469) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblI-0005rk-9j for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblG-0005dZ-7I for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:11 -0500 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:42957) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblG-0005cN-1N for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:10 -0500 Received: by mail-pl1-x644.google.com with SMTP id y1so6881297plp.9 for ; Fri, 18 Jan 2019 13:33:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vmCtoR9C6IQTdM473qGfZ62d2l6KdjovhF6X9LQHAX4=; b=i81tnu+jii7bS6piBYNl9xEACuyeafryIFG9apcXFnDTq8e7L9vY47Yj9YZ5NW6f9B RTEwAo6/ZsoCac6c4zUXcl1MBB/ABMf9Kr5/zgafv3XmR6d9JPFxxk0rz5geZ5h9y9jb ntSwC08v2+DPaSH9nUuhhDrXlRqVTSzuHGAkI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vmCtoR9C6IQTdM473qGfZ62d2l6KdjovhF6X9LQHAX4=; b=qxTXlplVwHxUuxuzMGWm+IGUZgTlguKIyTrDOgz1IVgRqvUzyHCqHRnNFbcTcoTNIG mST01e/9A6hGx4WfFEeIhB3QPd87JCSgD5jEAiBnKBkSXqbeJpquDV2R1zMCDlSKk7Qj I9Z9H6/AZwyPX8RPQhiC/beVuFN9YCGdYzpTh7RXkcuORhQ9SkwgV5CYdsiUpEh1J8kX HxoabCJ+n6LYAhCUQy5GRKzavcAYW5mw2kTgS/pb14Syxv2XkOe2000p0kYbwBQDXKgg tVFJjN/CCCXZtrmhIi/4tqq7h+yGq+KhB0pizpQ4vEfr7BmdmGH97rZKxxANTDJ0xDTQ HRXQ== X-Gm-Message-State: AJcUukfgMXB1VWRxSHpCZdSRVKNbirWSsFb2RFCr9exjmuo8plWaTyhM WpARoiNi2YMHakU9QHgnpsuN8ft62Yw= X-Google-Smtp-Source: ALg8bN5PFdrIFFOJmZedcF8PtdcgTHPLqWMUhHxeslQEHKTuSdrrwvcv87dBKN5RqzlePiSb+RmQ/Q== X-Received: by 2002:a17:902:6b0c:: with SMTP id o12mr20915979plk.291.1547847187810; Fri, 18 Jan 2019 13:33:07 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:07 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:16 +1100 Message-Id: <20190118213122.22865-43-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::644 Subject: [Qemu-devel] [PATCH v6 43/49] linux-user: Split out dup, dup2, dup3 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that dup3 is universally available for guests. Implement host support with syscall when !CONFIG_DUP3. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 5 +++++ linux-user/syscall-file.inc.c | 42 +++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 33 +++------------------------ linux-user/strace.list | 6 ----- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 8b6d8f75ff..062adddd75 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -34,6 +34,11 @@ SYSCALL_DEF(close, ARG_DEC); #ifdef TARGET_NR_creat SYSCALL_DEF(creat, ARG_STR, ARG_MODEFLAG); #endif +SYSCALL_DEF(dup, ARG_DEC); +#ifdef TARGET_NR_dup2 +SYSCALL_DEF(dup2, ARG_DEC, ARG_DEC); +#endif +SYSCALL_DEF(dup3, ARG_DEC, ARG_DEC, ARG_OPENFLAG); SYSCALL_DEF(exit, ARG_DEC); SYSCALL_DEF(execve, ARG_STR, ARG_PTR, ARG_PTR); SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 83174c5781..5e8298fdb3 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -94,6 +94,48 @@ SYSCALL_IMPL(creat) } #endif +SYSCALL_IMPL(dup) +{ + abi_long ret = get_errno(dup(arg1)); + if (ret >= 0) { + fd_trans_dup(arg1, ret); + } + return ret; +} + +#ifdef TARGET_NR_dup2 +SYSCALL_IMPL(dup2) +{ + abi_long ret = get_errno(dup2(arg1, arg2)); + if (ret >= 0) { + fd_trans_dup(arg1, arg2); + } + return ret; +} +#endif + +SYSCALL_IMPL(dup3) +{ + int ofd = arg1; + int nfd = arg2; + int host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl); + abi_long ret; + +#ifdef CONFIG_DUP3 + ret = dup3(ofd, nfd, host_flags); +#else + if (host_flags == 0) { + if (ofd == nfd) { + return -TARGET_EINVAL; + } + ret = dup2(ofd, nfd); + } else { + ret = syscall(__NR_dup3, ofd, nfd, host_flags); + } +#endif + return get_errno(ret); +} + SYSCALL_IMPL(faccessat) { return do_faccessat(arg1, arg2, arg3); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 7874a48840..29a9d5fce4 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -204,6 +204,9 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ * Performing a bogus sysacll is lazier than boilerplating * the replacement functions here in C. */ +#ifndef __NR_dup3 +#define __NR_dup3 -1 +#endif #ifndef __NR_syncfs #define __NR_syncfs -1 #endif @@ -5320,12 +5323,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_dup: - ret = get_errno(dup(arg1)); - if (ret >= 0) { - fd_trans_dup(arg1, ret); - } - return ret; #ifdef TARGET_NR_pipe case TARGET_NR_pipe: return do_pipe(cpu_env, arg1, 0, 0); @@ -5380,30 +5377,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, ret = get_errno(chroot(p)); unlock_user(p, arg1, 0); return ret; -#ifdef TARGET_NR_dup2 - case TARGET_NR_dup2: - ret = get_errno(dup2(arg1, arg2)); - if (ret >= 0) { - fd_trans_dup(arg1, arg2); - } - return ret; -#endif -#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3) - case TARGET_NR_dup3: - { - int host_flags; - - if ((arg3 & ~TARGET_O_CLOEXEC) != 0) { - return -EINVAL; - } - host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl); - ret = get_errno(dup3(arg1, arg2, host_flags)); - if (ret >= 0) { - fd_trans_dup(arg1, arg2); - } - return ret; - } -#endif #ifdef TARGET_NR_getpgrp case TARGET_NR_getpgrp: return get_errno(getpgrp()); diff --git a/linux-user/strace.list b/linux-user/strace.list index 678feeeb7b..151b0eb42d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -91,12 +91,6 @@ #ifdef TARGET_NR_dipc { TARGET_NR_dipc, "dipc" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_dup -{ TARGET_NR_dup, "dup" , NULL, NULL, NULL }, -#endif -#ifdef TARGET_NR_dup2 -{ TARGET_NR_dup2, "dup2" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_epoll_create { TARGET_NR_epoll_create, "epoll_create" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027809 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="jmw/gAAb"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFdP1rghz9sDB for ; Sat, 19 Jan 2019 09:15:52 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48055 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcQW-0006ay-M4 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:15:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56476) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblI-0005s2-IW for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblH-0005gd-Gs for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:12 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:39402) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblH-0005fI-Af for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:11 -0500 Received: by mail-pf1-x441.google.com with SMTP id r136so7202294pfc.6 for ; Fri, 18 Jan 2019 13:33:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ae2iuDtozqnYPQdWOWjfYMdlhZ9AoZuZXTdwHHiIJt4=; b=jmw/gAAbMh1Q6sJMjPp0Y6rm+H4GJKBNLTieELyp3tzas4wPaHCU2GP8Ij85uPxh7O PE+fK8yYvYJJmYtfZ/UEtqLpsFOmTxV4v2iiOCffOnI/IMS1qWfjD24gRNEgW90hsoD1 nE7khmqjcc5SR/XkAQ1boyaFkPa3v6hPV4ZnQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ae2iuDtozqnYPQdWOWjfYMdlhZ9AoZuZXTdwHHiIJt4=; b=lRJnXe5zDNNiKCKZfC7wzgU5yYbt2e2c/shORnCIy36suk496b9VQyUlQizJu8vjhB dha8DIwzd3ULntGWrEg9CWEh3XzGLyHTkQEe4zA8tuaW/3gU9pHCKAC/9lnVwV0H/s2C d3YPaRaa+978sKPeYbh8Y14Ouk29bc9gesPEofi0lsl8hSXL4yFno3yuSBVM8MCWx0jw jeIdDAh0cdUQRV+REYAAmoTNp7nTu9fgqdjKAKTDaJHTZSbN5SoOVzSlGImj4QCd4jsH KBWAFPkrhFhfKiv6KhvUFWynmi8lnYETkBqRdbASODkK2ao8TnXj+/DiO5fBNA+WQDft T33w== X-Gm-Message-State: AJcUukcla/CqtpQ9zdlClH8fqwrN/X7JO78Qc+zN0EJsstwZh/g3AYUm 62hwXydlBK96CtXnsnnUeBsNfUncMA8= X-Google-Smtp-Source: ALg8bN4pJvqWNqiKBY2qVhv2Z4SbWET4G7w4jQfqCdfKStfHYO7XiSYXzo4ufktB6iavT3iGf1XcYg== X-Received: by 2002:a62:e30d:: with SMTP id g13mr20809862pfh.151.1547847190045; Fri, 18 Jan 2019 13:33:10 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:09 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:17 +1100 Message-Id: <20190118213122.22865-44-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::441 Subject: [Qemu-devel] [PATCH v6 44/49] linux-user: Split out pipe, pipe2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Note that pipe2 is universally available for guests. Implement host support with syscall when !CONFIG_PIPE2. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 10 ++++++ linux-user/syscall-file.inc.c | 51 +++++++++++++++++++++++++++ linux-user/syscall.c | 65 +++++++---------------------------- linux-user/strace.list | 6 ---- 4 files changed, 74 insertions(+), 58 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 062adddd75..bd3301a72f 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -132,6 +132,16 @@ SYSCALL_DEF(open_by_handle_at, ARG_DEC, ARG_PTR, ARG_OPENFLAG); #ifdef TARGET_NR_pause SYSCALL_DEF(pause); #endif +#ifdef TARGET_NR_pipe +# if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || \ + defined(TARGET_SH4) || defined(TARGET_SPARC) +/* ??? We have no way for strace to display the second returned fd. */ +SYSCALL_DEF(pipe); +# else +SYSCALL_DEF(pipe, ARG_PTR); +# endif +#endif +SYSCALL_DEF(pipe2, ARG_PTR, ARG_OPENFLAG); SYSCALL_DEF_FULL(pread64, .impl = impl_pread64, .args = args_pread64_pwrite64, .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }); diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 5e8298fdb3..90aacfacaf 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -720,6 +720,57 @@ SYSCALL_IMPL(open_by_handle_at) return ret; } +static abi_long do_pipe(CPUArchState *cpu_env, abi_ulong target_fds, + int target_flags, bool is_pipe2) +{ + int host_flags = target_to_host_bitmask(target_flags, fcntl_flags_tbl); + int host_fds[2]; + abi_long ret; + + ret = pipe2(host_fds, host_flags); + if (is_error(ret)) { + return get_errno(ret); + } + + /* + * Several targets have special calling conventions for the original + * pipe syscall, but didn't replicate this into the pipe2 syscall. + */ + if (!is_pipe2) { +#if defined(TARGET_ALPHA) + cpu_env->ir[IR_A4] = host_fds[1]; + return host_fds[0]; +#elif defined(TARGET_MIPS) + cpu_env->active_tc.gpr[3] = host_fds[1]; + return host_fds[0]; +#elif defined(TARGET_SH4) + cpu_env->gregs[1] = host_fds[1]; + return host_fds[0]; +#elif defined(TARGET_SPARC) + cpu_env->regwptr[1] = host_fds[1]; + return host_fds[0]; +#endif + } + + if (put_user_s32(host_fds[0], target_fds) + || put_user_s32(host_fds[1], target_fds + 4)) { + return -TARGET_EFAULT; + } + return 0; +} + +#ifdef TARGET_NR_pipe +SYSCALL_IMPL(pipe) +{ + return do_pipe(cpu_env, arg1, 0, false); +} +#endif + +SYSCALL_IMPL(pipe2) +{ + return do_pipe(cpu_env, arg1, arg2, true); +} + /* * Both pread64 and pwrite64 merge args into a 64-bit offset, * but the input registers and ordering are target specific. diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 29a9d5fce4..3a322a61ca 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -207,6 +207,9 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #ifndef __NR_dup3 #define __NR_dup3 -1 #endif +#ifndef __NR_pipe2 +#define __NR_pipe2 -1 +#endif #ifndef __NR_syncfs #define __NR_syncfs -1 #endif @@ -283,6 +286,16 @@ _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type, #ifndef CONFIG_SYNCFS _syscall1(int, syncfs, int, fd) #endif +#ifndef CONFIG_PIPE2 +static int pipe2(int *fds, int flags) +{ + if (flags) { + return syscall(__NR_pipe2, fds, flags); + } else { + return pipe(fds); + } +} +#endif static bitmask_transtbl fcntl_flags_tbl[] = { { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, @@ -1134,49 +1147,6 @@ static abi_long do_old_select(abi_ulong arg1) #endif #endif -static abi_long do_pipe2(int host_pipe[], int flags) -{ -#ifdef CONFIG_PIPE2 - return pipe2(host_pipe, flags); -#else - return -ENOSYS; -#endif -} - -static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, - int flags, int is_pipe2) -{ - int host_pipe[2]; - abi_long ret; - ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe); - - if (is_error(ret)) - return get_errno(ret); - - /* Several targets have special calling conventions for the original - pipe syscall, but didn't replicate this into the pipe2 syscall. */ - if (!is_pipe2) { -#if defined(TARGET_ALPHA) - ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1]; - return host_pipe[0]; -#elif defined(TARGET_MIPS) - ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; - return host_pipe[0]; -#elif defined(TARGET_SH4) - ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; - return host_pipe[0]; -#elif defined(TARGET_SPARC) - ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1]; - return host_pipe[0]; -#endif - } - - if (put_user_s32(host_pipe[0], pipedes) - || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) - return -TARGET_EFAULT; - return get_errno(ret); -} - static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, abi_ulong target_addr, socklen_t len) @@ -5323,15 +5293,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_pipe - case TARGET_NR_pipe: - return do_pipe(cpu_env, arg1, 0, 0); -#endif -#ifdef TARGET_NR_pipe2 - case TARGET_NR_pipe2: - return do_pipe(cpu_env, arg1, - target_to_host_bitmask(arg2, fcntl_flags_tbl), 1); -#endif case TARGET_NR_times: { struct target_tms *tmsp; diff --git a/linux-user/strace.list b/linux-user/strace.list index 151b0eb42d..ac25e13bfa 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -860,9 +860,6 @@ #ifdef TARGET_NR_personality { TARGET_NR_personality, "personality" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pipe -{ TARGET_NR_pipe, "pipe" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_pivot_root { TARGET_NR_pivot_root, "pivot_root" , NULL, NULL, NULL }, #endif @@ -1377,9 +1374,6 @@ #ifdef TARGET_NR_sync_file_range2 { TARGET_NR_sync_file_range2, "sync_file_range2", NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pipe2 -{ TARGET_NR_pipe2, "pipe2", NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_atomic_cmpxchg_32 { TARGET_NR_atomic_cmpxchg_32, "atomic_cmpxchg_32", NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027786 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="fBfvB5LT"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFCl6dT5z9sD9 for ; Sat, 19 Jan 2019 08:57:07 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47742 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc8P-0008Ph-S5 for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:57:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56519) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkble-00068t-KW for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblQ-0005t3-L2 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:26 -0500 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:38211) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblO-0005jf-0s for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:18 -0500 Received: by mail-pf1-x443.google.com with SMTP id q1so7204236pfi.5 for ; Fri, 18 Jan 2019 13:33:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rux+kRu2UAl1QIPUh/1VQqUdHSpoV4AukU1szKGl9bY=; b=fBfvB5LT3Jk57DYzHjGUNedsBZ+273ivbG7f4lPFtGTB5DQXHoXizLILQrhf6ti3oE MnrG6mkm1kGipC5zoKAuEsiJoainGjzHT2NMzMM7je4hkX4/2e+VH9af7qnxm5DvSEs3 zEP38DN/VlLmbYnD1d55jVOHC0suazXOLjwhQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rux+kRu2UAl1QIPUh/1VQqUdHSpoV4AukU1szKGl9bY=; b=QjJaoUvyfy5m+KEA9NZZjkysGXNJIAf0/EHE2GPOJUPIQau5PPIZy47PnwwJ+XzFbx x6FvbwmqEKa37UAbHkle1WUTyPWDPzmnOtv+oj8SYAkT7P1pyQu9X4gDgkIaFkaSvJaN e94EVpOLxl9XYvMFxFJZSboHfAl2zcTlccHKAGThVgfFiNkJsZJL1NpIJqsh7bRAjJj5 eI9ft0/C+b5oAu/w/+g+OO8YnrquikDhrw/YjGoO3VmXyQCyRTx5kDxRiA7ByylNq8Q+ FMllnC1WB3mSDnpX+RZz4LQIWHHz+fHexLVv5prkO5Urk0p13LO8+66M4YrGiZe2uBx9 dNfg== X-Gm-Message-State: AJcUukfyA4iXAssgpfdv/je7vAoD+Q1DlAKFokB7Tg4ZNwezc1RCCikM qM2KCdm8KueWlGu+hF7JZ8nu78EdsLg= X-Google-Smtp-Source: ALg8bN51ESAYChf0S7nzRUBHFl9ejGrhaod+T+vB4NT2TA9KMHlKwzGqNg6GB87u8lajoeNroxN9Gg== X-Received: by 2002:a62:b80a:: with SMTP id p10mr19676364pfe.32.1547847192333; Fri, 18 Jan 2019 13:33:12 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:11 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:18 +1100 Message-Id: <20190118213122.22865-45-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::443 Subject: [Qemu-devel] [PATCH v6 45/49] linux-user: Split out times X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall-proc.inc.c | 25 +++++++++++++++++++++++++ linux-user/syscall.c | 18 ------------------ linux-user/strace.list | 3 --- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index bd3301a72f..25d5aaccd1 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -204,6 +204,7 @@ SYSCALL_DEF(syncfs, ARG_DEC); #ifdef TARGET_NR_time SYSCALL_DEF(time, ARG_PTR); #endif +SYSCALL_DEF(times, ARG_PTR); #ifdef TARGET_NR_umount SYSCALL_DEF(umount, ARG_STR); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index 58c0a22300..09a0306406 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -468,6 +468,31 @@ SYSCALL_IMPL(nice) } #endif +SYSCALL_IMPL(times) +{ + abi_ulong target_buf = arg1; + struct tms tms; + abi_long ret; + + ret = get_errno(times(&tms)); + if (target_buf) { + struct target_tms *tmsp = lock_user(VERIFY_WRITE, target_buf, + sizeof(struct target_tms), 0); + if (!tmsp) { + return -TARGET_EFAULT; + } + tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime)); + tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime)); + tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime)); + tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime)); + unlock_user(tmsp, target_buf, sizeof(struct target_tms)); + } + if (!is_error(ret)) { + ret = host_to_target_clock_t(ret); + } + return ret; +} + /* * Map host to target signal numbers for the wait family of syscalls. * Assume all other status bits are the same. diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 3a322a61ca..d0bf339281 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5293,24 +5293,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_times: - { - struct target_tms *tmsp; - struct tms tms; - ret = get_errno(times(&tms)); - if (arg1) { - tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0); - if (!tmsp) - return -TARGET_EFAULT; - tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime)); - tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime)); - tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime)); - tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime)); - } - if (!is_error(ret)) - ret = host_to_target_clock_t(ret); - } - return ret; case TARGET_NR_acct: if (arg1 == 0) { ret = get_errno(acct(NULL)); diff --git a/linux-user/strace.list b/linux-user/strace.list index ac25e13bfa..4ea11f162e 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1290,9 +1290,6 @@ #ifdef TARGET_NR_timerfd_settime { TARGET_NR_timerfd_settime, "timerfd_settime" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_times -{ TARGET_NR_times, "times" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_tkill { TARGET_NR_tkill, "tkill" , NULL, print_tkill, NULL }, #endif From patchwork Fri Jan 18 21:31:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027784 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="jmi5XAv2"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hF9d00nVz9sDP for ; Sat, 19 Jan 2019 08:55:16 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47698 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkc6d-0006iD-0X for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:55:15 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56573) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbln-0006CE-ON for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkbll-0006KO-PM for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:43 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:33674) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblj-0005mP-Nx for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:39 -0500 Received: by mail-pg1-x544.google.com with SMTP id z11so6661606pgu.0 for ; Fri, 18 Jan 2019 13:33:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cKg8c0GdaGBrpr59vF70WkJKA+3W0/Fdq6RBztRFrcQ=; b=jmi5XAv2YXgxL8KDT6flfBMd049avg8BLp4V6eMKGOyZw02EPj4YG/eW9EIL/1HL/O KkTyvaPz0NHs0QLvT2bQNBcSeO9ysw2R/nMfFZCydwcZ1yhSb5kdfANIsaHQrXg7CkSe 2NkrEgbc3lKHNzzcLcT1T0VHZSnOmFZMWvqW0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cKg8c0GdaGBrpr59vF70WkJKA+3W0/Fdq6RBztRFrcQ=; b=c1mBWdlDcAzlaeqJYj7R2zuOYOtXYKrBxmPIuda+ikhSS/JRT6hCscVrqhLh6dJ9ce WlM6/hPL8qtOvjLmcVCtfm+eXv33QxkTpVPpalbTLRhOAa/g9U2sX3SklhQuChu7jvX+ tDsBK8SAQLh+1NBkkU6PuW80WuuILpyQvX/mkng7yXfgrbIA/3MncpPSTsAtDMB7IFmP H3jaUB+vVzXdHjSc3KO1GRvg6cB9FL8ML9DWW/8iJPKo0a3tdiM9Gq8V/QM5Iu2UDEgX qCr4ip9ZtKdE62UBM/JEWJEWftiozqAtAGbs6SAWn3l7WiqilhnHKAg4dYq6mnkT8CUl g/hQ== X-Gm-Message-State: AJcUuke6D6DBTyUqspQHVkFL81wOAPROHdzWi87yxJYDXBYOKoWj6WW9 CjhE9dxeJsnkCMcaU/z4Vf0lAvkyBhU= X-Google-Smtp-Source: ALg8bN5f9JbDb4fpuqBN4wH3uUSKUscJ1rXbnAIdRMJzQddv4meYhhEr0PSFKRg1s0foEuvgBoeL8A== X-Received: by 2002:a63:9a52:: with SMTP id e18mr19379832pgo.14.1547847194678; Fri, 18 Jan 2019 13:33:14 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.12 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:14 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:19 +1100 Message-Id: <20190118213122.22865-46-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::544 Subject: [Qemu-devel] [PATCH v6 46/49] linux-user: Split out acct X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall-file.inc.c | 18 ++++++++++++++++++ linux-user/syscall.c | 11 ----------- linux-user/strace.list | 3 --- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index 25d5aaccd1..f8f280f376 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -19,6 +19,7 @@ #ifdef TARGET_NR_access SYSCALL_DEF(access, ARG_STR, ARG_ACCESSFLAG); #endif +SYSCALL_DEF(acct, ARG_STR); #ifdef TARGET_NR_alarm SYSCALL_DEF(alarm, ARG_DEC); #endif diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c index 90aacfacaf..dd0bf877d5 100644 --- a/linux-user/syscall-file.inc.c +++ b/linux-user/syscall-file.inc.c @@ -36,6 +36,24 @@ SYSCALL_IMPL(access) } #endif +SYSCALL_IMPL(acct) +{ + abi_ulong target_path = arg1; + abi_long ret; + + if (target_path == 0) { + ret = get_errno(acct(NULL)); + } else { + char *p = lock_user_string(target_path); + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(acct(path(p))); + unlock_user(p, target_path, 0); + } + return ret; +} + SYSCALL_IMPL(chdir) { abi_ulong target_path = arg1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d0bf339281..33d536262f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5293,17 +5293,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_acct: - if (arg1 == 0) { - ret = get_errno(acct(NULL)); - } else { - if (!(p = lock_user_string(arg1))) { - return -TARGET_EFAULT; - } - ret = get_errno(acct(path(p))); - unlock_user(p, arg1, 0); - } - return ret; case TARGET_NR_ioctl: return do_ioctl(arg1, arg2, arg3); #ifdef TARGET_NR_fcntl diff --git a/linux-user/strace.list b/linux-user/strace.list index 4ea11f162e..9f2f8977b4 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -9,9 +9,6 @@ #ifdef TARGET_NR_accept4 { TARGET_NR_accept4, "accept4" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_acct -{ TARGET_NR_acct, "acct" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_add_key { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027810 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="crFywOam"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFfk3LNZz9sDB for ; Sat, 19 Jan 2019 09:17:02 +1100 (AEDT) Received: from localhost ([127.0.0.1]:48061 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcRg-0007CK-EA for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:17:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56562) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkbll-0006AN-PE for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblj-0006HU-Vt for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:41 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:44931) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbli-0005ob-4g for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:39 -0500 Received: by mail-pg1-x542.google.com with SMTP id t13so6635893pgr.11 for ; Fri, 18 Jan 2019 13:33:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9nUzq8HAn9hIBb4vo9SImCmbGSK+P9J37KbeA0FCTpI=; b=crFywOamw5KY1TeqoRgeTd3sw7qu8VC5qYjUIzsSmDFgv6p+KMbRGf/99YyWgfx9Dd Yp04s2yTBZTVAEJRQYqKWGMY3FuuempFUxW74zsC1GdSTDDPWQ3EvpnxdlY70fn/V3Vd v5xhS4vUNuW4cbBb3gW+FEu02Rk8WYZaBNIIs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9nUzq8HAn9hIBb4vo9SImCmbGSK+P9J37KbeA0FCTpI=; b=RGde5hEOJUzVdRFXDg4pQbnrOMFYrBMX/9MFGs0Fqfv3rZqB2/dFsAFCCQU/c6gjSi tXBUvsWwPXBnpC4ZfeyO9qLBltMvbWqz9fNyrCwKXvit804TQu+mci5dVfCvcQjIKml/ Fx0itBxMXCovn6xmauuxX8fpXU9pgajhM2+Zf5JWuqzCx/pcZq1TkY4EYWcuGPrZd65p yhc8N3cHtmho68In7MVU18VO943Zor07hhuZ6c1OFq1bwKEl7nQ2xSx+PQ0oVK3muX/T F8Tvp/szhGyucsCthcm5qZRKk1UAwgJexCmeKDAMt6vZNCdXkAu6U3KL0dGOND3GpGvA ssKA== X-Gm-Message-State: AJcUukehBo2XCcAbHMsrYuq6MPqmL3w0Ye0po5g2T3oTNhZFhc7bu71B 5opZFDUckA+8Tfy4cx6nAv3GC9zijHg= X-Google-Smtp-Source: ALg8bN4RaXz2x1+ZrGDcCbmG1NepGyABvx4O+dxicEqYFzCsVuVFXiCVB/vlHwBWQRFtBHtVqrtwdA== X-Received: by 2002:a63:24c2:: with SMTP id k185mr18909967pgk.406.1547847197036; Fri, 18 Jan 2019 13:33:17 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:16 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:20 +1100 Message-Id: <20190118213122.22865-47-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::542 Subject: [Qemu-devel] [PATCH v6 47/49] linux-user: Move syscall_init to the end X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" No functional change. This will aid moving everything related to ioctls to a separate file. Signed-off-by: Richard Henderson --- linux-user/syscall.c | 113 +++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 52 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 33d536262f..82b7267b20 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4778,58 +4778,6 @@ _syscall1(int, sys_setgid, gid_t, gid) _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) -void syscall_init(void) -{ - IOCTLEntry *ie; - const argtype *arg_type; - int size; - int i; - - thunk_init(STRUCT_MAX); - -#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); -#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); -#include "syscall_types.h" -#undef STRUCT -#undef STRUCT_SPECIAL - - /* Build target_to_host_errno_table[] table from - * host_to_target_errno_table[]. */ - for (i = 0; i < ERRNO_TABLE_SIZE; i++) { - target_to_host_errno_table[host_to_target_errno_table[i]] = i; - } - - /* we patch the ioctl size if necessary. We rely on the fact that - no ioctl has all the bits at '1' in the size field */ - ie = ioctl_entries; - while (ie->target_cmd != 0) { - if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) == - TARGET_IOC_SIZEMASK) { - arg_type = ie->arg_type; - if (arg_type[0] != TYPE_PTR) { - fprintf(stderr, "cannot patch size for ioctl 0x%x\n", - ie->target_cmd); - exit(1); - } - arg_type++; - size = thunk_type_size(arg_type, 0); - ie->target_cmd = (ie->target_cmd & - ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | - (size << TARGET_IOC_SIZESHIFT); - } - - /* automatic consistency check if same arch */ -#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \ - (defined(__x86_64__) && defined(TARGET_X86_64)) - if (unlikely(ie->target_cmd != ie->host_cmd)) { - fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n", - ie->name, ie->target_cmd, ie->host_cmd); - } -#endif - ie++; - } -} - static inline uint64_t target_offset64(abi_ulong word0, abi_ulong word1) { #if TARGET_ABI_BITS == 64 @@ -8983,3 +8931,64 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, trace_guest_user_syscall_ret(cpu, num, ret); return ret; } + +void syscall_init(void) +{ + IOCTLEntry *ie; + const argtype *arg_type; + int size; + int i; + + thunk_init(STRUCT_MAX); + +#define STRUCT(name, ...) \ + thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); +#define STRUCT_SPECIAL(name) \ + thunk_register_struct_direct(STRUCT_ ## name, #name, \ + &struct_ ## name ## _def); + +#include "syscall_types.h" + +#undef STRUCT +#undef STRUCT_SPECIAL + + /* + * Build target_to_host_errno_table[] table from + * host_to_target_errno_table[]. + */ + for (i = 0; i < ERRNO_TABLE_SIZE; i++) { + target_to_host_errno_table[host_to_target_errno_table[i]] = i; + } + + /* + * We patch the ioctl size if necessary. We rely on the fact that + * no ioctl has all the bits at '1' in the size field. + */ + ie = ioctl_entries; + while (ie->target_cmd != 0) { + if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) == + TARGET_IOC_SIZEMASK) { + arg_type = ie->arg_type; + if (arg_type[0] != TYPE_PTR) { + fprintf(stderr, "cannot patch size for ioctl 0x%x\n", + ie->target_cmd); + exit(1); + } + arg_type++; + size = thunk_type_size(arg_type, 0); + ie->target_cmd = (ie->target_cmd & + ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | + (size << TARGET_IOC_SIZESHIFT); + } + + /* automatic consistency check if same arch */ +#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \ + (defined(__x86_64__) && defined(TARGET_X86_64)) + if (unlikely(ie->target_cmd != ie->host_cmd)) { + fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n", + ie->name, ie->target_cmd, ie->host_cmd); + } +#endif + ie++; + } +} From patchwork Fri Jan 18 21:31:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027793 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="FiIXsuC0"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFL06wccz9sDL for ; Sat, 19 Jan 2019 09:02:32 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47822 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcDe-0004UM-Ob for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 17:02:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56693) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblz-0006Yl-94 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:34:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblr-0006XB-J7 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:54 -0500 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:39404) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkblp-0005to-EP for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:47 -0500 Received: by mail-pf1-x443.google.com with SMTP id r136so7202449pfc.6 for ; Fri, 18 Jan 2019 13:33:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CVKJR2ib+J2Scg3TdIwS0V4iGxkWgnN0cHykwdQzHPM=; b=FiIXsuC0/KC0hBv91/AcKHndryJSmgV5Rtjw5OebWEf9pA0G/9B/fkm94+Ww0Sey3g m1X8N6zKEHIVXoR0iRAeCLLO/tN7szuQoD+BpdCdrm73OF6tUWIu/sztn6Rj//MUCLaT 3D/Hj9sxJYrVmEzito5uheLZpnSGlsu8UPpzk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CVKJR2ib+J2Scg3TdIwS0V4iGxkWgnN0cHykwdQzHPM=; b=fvBG6S7oO2vboq5QDnlUwQPPtkiReDZvg3X/hTYt+BKv4+pTpL0ZFZ5FOq7CnaRqnS NSYOizOmtEzCLEMuop8Y2mmo7w3ngfhXbzZCVaHk8lT7H2h7IGZEUabFYeegz2/saO6j OHr4mJFj21UozHIuTJfAH1ry0kStHS8Q+wNo1lqYjHqcCIb7wNz0Efn785pjIJ9dtVk1 Sg5hVtFfV7wsiYcKxhfsJw7MDW43+VVAW8+hBSZj9/NnMORmnW3xpboXNZJGfPZxYRop AccH/lERAErowd/ZjRnXPFonAeQmG9+dAu6Qgqk8K2X5ifrTUbdWSWDWspsRCNb6LabT eITg== X-Gm-Message-State: AJcUukdxo5eXoyza6uf4f4W7y8/JaB5jBTGsKyrK5C2gPw+L2iO3SWad z9X9mmsl1F0uXAWCVXdLg9U/nmiPi1Y= X-Google-Smtp-Source: ALg8bN658MQMVD/8dbomE+bKP6bNM4mcovROwJjd9Jzjs0r3ZkNx05fQ3HbCCdJzY4q/4uua37nWuw== X-Received: by 2002:a62:2044:: with SMTP id g65mr20844559pfg.127.1547847199651; Fri, 18 Jan 2019 13:33:19 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:18 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:21 +1100 Message-Id: <20190118213122.22865-48-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::443 Subject: [Qemu-devel] [PATCH v6 48/49] linux-user: Split out ioctl X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 1 + linux-user/syscall-ioctl.inc.c | 873 +++++++++++++++++++++++++++++++++ linux-user/syscall.c | 843 +------------------------------ linux-user/strace.list | 3 - 4 files changed, 875 insertions(+), 845 deletions(-) create mode 100644 linux-user/syscall-ioctl.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index f8f280f376..f58b9745a4 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -61,6 +61,7 @@ SYSCALL_DEF(getppid); #ifdef TARGET_NR_getxpid SYSCALL_DEF(getxpid); #endif +SYSCALL_DEF(ioctl, ARG_DEC, ARG_HEX); #ifdef TARGET_NR_ipc SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX); #endif diff --git a/linux-user/syscall-ioctl.inc.c b/linux-user/syscall-ioctl.inc.c new file mode 100644 index 0000000000..820994105f --- /dev/null +++ b/linux-user/syscall-ioctl.inc.c @@ -0,0 +1,873 @@ +/* + * Linux ioctl syscall implementation + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +typedef struct IOCTLEntry IOCTLEntry; + +typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg); + +struct IOCTLEntry { + int target_cmd; + unsigned int host_cmd; + const char *name; + int access; + do_ioctl_fn *do_ioctl; + const argtype arg_type[5]; +}; + +#define IOC_R 0x0001 +#define IOC_W 0x0002 +#define IOC_RW (IOC_R | IOC_W) + +#define MAX_STRUCT_SIZE 4096 + +#ifdef CONFIG_FIEMAP +/* + * So fiemap access checks don't overflow on 32 bit systems. + * This is very slightly smaller than the limit imposed by + * the underlying kernel. + */ +#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \ + / sizeof(struct fiemap_extent)) + +static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + /* + * The parameter for this ioctl is a struct fiemap followed + * by an array of struct fiemap_extent whose size is set + * in fiemap->fm_extent_count. The array is filled in by the + * ioctl. + */ + int target_size_in, target_size_out; + struct fiemap *fm; + const argtype *arg_type = ie->arg_type; + const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) }; + void *argptr, *p; + abi_long ret; + int i, extent_size = thunk_type_size(extent_arg_type, 0); + uint32_t outbufsz; + int free_fm = 0; + + assert(arg_type[0] == TYPE_PTR); + assert(ie->access == IOC_RW); + arg_type++; + target_size_in = thunk_type_size(arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size_in, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + fm = (struct fiemap *)buf_temp; + if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) { + return -TARGET_EINVAL; + } + + outbufsz = sizeof(*fm) + sizeof(struct fiemap_extent) * fm->fm_extent_count; + + if (outbufsz > MAX_STRUCT_SIZE) { + /* + * We can't fit all the extents into the fixed size buffer. + * Allocate one that is large enough and use it instead. + */ + fm = g_try_malloc(outbufsz); + if (!fm) { + return -TARGET_ENOMEM; + } + memcpy(fm, buf_temp, sizeof(struct fiemap)); + free_fm = 1; + } + ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm)); + if (!is_error(ret)) { + target_size_out = target_size_in; + /* + * An extent_count of 0 means we were only counting the extents + * so there are no structs to copy + */ + if (fm->fm_extent_count != 0) { + target_size_out += fm->fm_mapped_extents * extent_size; + } + argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0); + if (!argptr) { + ret = -TARGET_EFAULT; + } else { + /* Convert the struct fiemap */ + thunk_convert(argptr, fm, arg_type, THUNK_TARGET); + if (fm->fm_extent_count != 0) { + p = argptr + target_size_in; + /* ...and then all the struct fiemap_extents */ + for (i = 0; i < fm->fm_mapped_extents; i++) { + thunk_convert(p, &fm->fm_extents[i], extent_arg_type, + THUNK_TARGET); + p += extent_size; + } + } + unlock_user(argptr, arg, target_size_out); + } + } + if (free_fm) { + g_free(fm); + } + return ret; +} +#endif + +static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + const argtype *arg_type = ie->arg_type; + int target_size; + void *argptr; + int ret; + struct ifconf *host_ifconf; + uint32_t outbufsz; + const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) }; + int target_ifreq_size; + int nb_ifreq; + int free_buf = 0; + int i; + int target_ifc_len; + abi_long target_ifc_buf; + int host_ifc_len; + char *host_ifc_buf; + + assert(arg_type[0] == TYPE_PTR); + assert(ie->access == IOC_RW); + + arg_type++; + target_size = thunk_type_size(arg_type, 0); + + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + host_ifconf = (struct ifconf *)(unsigned long)buf_temp; + target_ifc_len = host_ifconf->ifc_len; + target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; + + target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); + nb_ifreq = target_ifc_len / target_ifreq_size; + host_ifc_len = nb_ifreq * sizeof(struct ifreq); + + outbufsz = sizeof(*host_ifconf) + host_ifc_len; + if (outbufsz > MAX_STRUCT_SIZE) { + /* + * We can't fit all the extents into the fixed size buffer. + * Allocate one that is large enough and use it instead. + */ + host_ifconf = malloc(outbufsz); + if (!host_ifconf) { + return -TARGET_ENOMEM; + } + memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); + free_buf = 1; + } + host_ifc_buf = (char *)host_ifconf + sizeof(*host_ifconf); + + host_ifconf->ifc_len = host_ifc_len; + host_ifconf->ifc_buf = host_ifc_buf; + + ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf)); + if (!is_error(ret)) { + /* convert host ifc_len to target ifc_len */ + + nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq); + target_ifc_len = nb_ifreq * target_ifreq_size; + host_ifconf->ifc_len = target_ifc_len; + + /* restore target ifc_buf */ + + host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf; + + /* copy struct ifconf to target user */ + + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET); + unlock_user(argptr, arg, target_size); + + /* copy ifreq[] to target user */ + + argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0); + for (i = 0; i < nb_ifreq ; i++) { + thunk_convert(argptr + i * target_ifreq_size, + host_ifc_buf + i * sizeof(struct ifreq), + ifreq_arg_type, THUNK_TARGET); + } + unlock_user(argptr, target_ifc_buf, target_ifc_len); + } + + if (free_buf) { + free(host_ifconf); + } + + return ret; +} + +#if defined(CONFIG_USBFS) +#if HOST_LONG_BITS > 64 +#error USBDEVFS thunks do not support >64 bit hosts yet. +#endif +struct live_urb { + uint64_t target_urb_adr; + uint64_t target_buf_adr; + char *target_buf_ptr; + struct usbdevfs_urb host_urb; +}; + +static GHashTable *usbdevfs_urb_hashtable(void) +{ + static GHashTable *urb_hashtable; + + if (!urb_hashtable) { + urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal); + } + return urb_hashtable; +} + +static void urb_hashtable_insert(struct live_urb *urb) +{ + GHashTable *urb_hashtable = usbdevfs_urb_hashtable(); + g_hash_table_insert(urb_hashtable, urb, urb); +} + +static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr) +{ + GHashTable *urb_hashtable = usbdevfs_urb_hashtable(); + return g_hash_table_lookup(urb_hashtable, &target_urb_adr); +} + +static void urb_hashtable_remove(struct live_urb *urb) +{ + GHashTable *urb_hashtable = usbdevfs_urb_hashtable(); + g_hash_table_remove(urb_hashtable, urb); +} + +static abi_long +do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) }; + const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 }; + struct live_urb *lurb; + void *argptr; + uint64_t hurb; + int target_size; + uintptr_t target_urb_adr; + abi_long ret; + + target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET); + + memset(buf_temp, 0, sizeof(uint64_t)); + ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + if (is_error(ret)) { + return ret; + } + + memcpy(&hurb, buf_temp, sizeof(uint64_t)); + lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb)); + if (!lurb->target_urb_adr) { + return -TARGET_EFAULT; + } + urb_hashtable_remove(lurb); + unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, + lurb->host_urb.buffer_length); + lurb->target_buf_ptr = NULL; + + /* restore the guest buffer pointer */ + lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr; + + /* update the guest urb struct */ + argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0); + if (!argptr) { + g_free(lurb); + return -TARGET_EFAULT; + } + thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET); + unlock_user(argptr, lurb->target_urb_adr, target_size); + + target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET); + /* write back the urb handle */ + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); + if (!argptr) { + g_free(lurb); + return -TARGET_EFAULT; + } + + /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */ + target_urb_adr = lurb->target_urb_adr; + thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET); + unlock_user(argptr, arg, target_size); + + g_free(lurb); + return ret; +} + +static abi_long +do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie, + uint8_t *buf_temp __attribute__((unused)), + int fd, int cmd, abi_long arg) +{ + struct live_urb *lurb; + + /* map target address back to host URB with metadata. */ + lurb = urb_hashtable_lookup(arg); + if (!lurb) { + return -TARGET_EFAULT; + } + return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb)); +} + +static abi_long +do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + const argtype *arg_type = ie->arg_type; + int target_size; + abi_long ret; + void *argptr; + int rw_dir; + struct live_urb *lurb; + + /* + * each submitted URB needs to map to a unique ID for the + * kernel, and that unique ID needs to be a pointer to + * host memory. hence, we need to malloc for each URB. + * isochronous transfers have a variable length struct. + */ + arg_type++; + target_size = thunk_type_size(arg_type, THUNK_TARGET); + + /* construct host copy of urb and metadata */ + lurb = g_try_malloc0(sizeof(struct live_urb)); + if (!lurb) { + return -TARGET_ENOMEM; + } + + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + g_free(lurb); + return -TARGET_EFAULT; + } + thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + lurb->target_urb_adr = arg; + lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer; + + /* buffer space used depends on endpoint type so lock the entire buffer */ + /* control type urbs should check the buffer contents for true direction */ + rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ; + lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr, + lurb->host_urb.buffer_length, 1); + if (lurb->target_buf_ptr == NULL) { + g_free(lurb); + return -TARGET_EFAULT; + } + + /* update buffer pointer in host copy */ + lurb->host_urb.buffer = lurb->target_buf_ptr; + + ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb)); + if (is_error(ret)) { + unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0); + g_free(lurb); + } else { + urb_hashtable_insert(lurb); + } + + return ret; +} +#endif /* CONFIG_USBFS */ + +static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd, + int cmd, abi_long arg) +{ + void *argptr; + struct dm_ioctl *host_dm; + abi_long guest_data; + uint32_t guest_data_size; + int target_size; + const argtype *arg_type = ie->arg_type; + abi_long ret; + void *big_buf = NULL; + char *host_data; + + arg_type++; + target_size = thunk_type_size(arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + ret = -TARGET_EFAULT; + goto out; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + /* buf_temp is too small, so fetch things into a bigger buffer */ + big_buf = g_malloc0(((struct dm_ioctl *)buf_temp)->data_size * 2); + memcpy(big_buf, buf_temp, target_size); + buf_temp = big_buf; + host_dm = big_buf; + + guest_data = arg + host_dm->data_start; + if ((guest_data - arg) < 0) { + ret = -TARGET_EINVAL; + goto out; + } + guest_data_size = host_dm->data_size - host_dm->data_start; + host_data = (char *)host_dm + host_dm->data_start; + + argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1); + if (!argptr) { + ret = -TARGET_EFAULT; + goto out; + } + + switch (ie->host_cmd) { + case DM_REMOVE_ALL: + case DM_LIST_DEVICES: + case DM_DEV_CREATE: + case DM_DEV_REMOVE: + case DM_DEV_SUSPEND: + case DM_DEV_STATUS: + case DM_DEV_WAIT: + case DM_TABLE_STATUS: + case DM_TABLE_CLEAR: + case DM_TABLE_DEPS: + case DM_LIST_VERSIONS: + /* no input data */ + break; + case DM_DEV_RENAME: + case DM_DEV_SET_GEOMETRY: + /* data contains only strings */ + memcpy(host_data, argptr, guest_data_size); + break; + case DM_TARGET_MSG: + memcpy(host_data, argptr, guest_data_size); + *(uint64_t *)host_data = tswap64(*(uint64_t *)argptr); + break; + case DM_TABLE_LOAD: + { + void *gspec = argptr; + void *cur_data = host_data; + const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) }; + int spec_size = thunk_type_size(arg_type, 0); + int i; + + for (i = 0; i < host_dm->target_count; i++) { + struct dm_target_spec *spec = cur_data; + uint32_t next; + int slen; + + thunk_convert(spec, gspec, arg_type, THUNK_HOST); + slen = strlen((char *)gspec + spec_size) + 1; + next = spec->next; + spec->next = sizeof(*spec) + slen; + strcpy((char *)&spec[1], gspec + spec_size); + gspec += next; + cur_data += spec->next; + } + break; + } + default: + ret = -TARGET_EINVAL; + unlock_user(argptr, guest_data, 0); + goto out; + } + unlock_user(argptr, guest_data, 0); + + ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + if (!is_error(ret)) { + guest_data = arg + host_dm->data_start; + guest_data_size = host_dm->data_size - host_dm->data_start; + argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0); + switch (ie->host_cmd) { + case DM_REMOVE_ALL: + case DM_DEV_CREATE: + case DM_DEV_REMOVE: + case DM_DEV_RENAME: + case DM_DEV_SUSPEND: + case DM_DEV_STATUS: + case DM_TABLE_LOAD: + case DM_TABLE_CLEAR: + case DM_TARGET_MSG: + case DM_DEV_SET_GEOMETRY: + /* no return data */ + break; + case DM_LIST_DEVICES: + { + struct dm_name_list *nl = (void *)host_dm + host_dm->data_start; + uint32_t remaining_data = guest_data_size; + void *cur_data = argptr; + const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) }; + int nl_size = 12; /* can't use thunk_size due to alignment */ + + while (1) { + uint32_t next = nl->next; + if (next) { + nl->next = nl_size + (strlen(nl->name) + 1); + } + if (remaining_data < nl->next) { + host_dm->flags |= DM_BUFFER_FULL_FLAG; + break; + } + thunk_convert(cur_data, nl, arg_type, THUNK_TARGET); + strcpy(cur_data + nl_size, nl->name); + cur_data += nl->next; + remaining_data -= nl->next; + if (!next) { + break; + } + nl = (void *)nl + next; + } + break; + } + case DM_DEV_WAIT: + case DM_TABLE_STATUS: + { + struct dm_target_spec *spec + = (void *)host_dm + host_dm->data_start; + void *cur_data = argptr; + const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) }; + int spec_size = thunk_type_size(arg_type, 0); + int i; + + for (i = 0; i < host_dm->target_count; i++) { + uint32_t next = spec->next; + int slen = strlen((char *)&spec[1]) + 1; + spec->next = (cur_data - argptr) + spec_size + slen; + if (guest_data_size < spec->next) { + host_dm->flags |= DM_BUFFER_FULL_FLAG; + break; + } + thunk_convert(cur_data, spec, arg_type, THUNK_TARGET); + strcpy(cur_data + spec_size, (char *)&spec[1]); + cur_data = argptr + spec->next; + spec = (void *)host_dm + host_dm->data_start + next; + } + break; + } + case DM_TABLE_DEPS: + { + void *hdata = (void *)host_dm + host_dm->data_start; + int count = *(uint32_t *)hdata; + uint64_t *hdev = hdata + 8; + uint64_t *gdev = argptr + 8; + int i; + + *(uint32_t *)argptr = tswap32(count); + for (i = 0; i < count; i++) { + *gdev = tswap64(*hdev); + gdev++; + hdev++; + } + break; + } + case DM_LIST_VERSIONS: + { + struct dm_target_versions *vers + = (void *)host_dm + host_dm->data_start; + uint32_t remaining_data = guest_data_size; + void *cur_data = argptr; + const argtype arg_type[] + = { MK_STRUCT(STRUCT_dm_target_versions) }; + int vers_size = thunk_type_size(arg_type, 0); + + while (1) { + uint32_t next = vers->next; + if (next) { + vers->next = vers_size + strlen(vers->name) + 1; + } + if (remaining_data < vers->next) { + host_dm->flags |= DM_BUFFER_FULL_FLAG; + break; + } + thunk_convert(cur_data, vers, arg_type, THUNK_TARGET); + strcpy(cur_data + vers_size, vers->name); + cur_data += vers->next; + remaining_data -= vers->next; + if (!next) { + break; + } + vers = (void *)vers + next; + } + break; + } + default: + unlock_user(argptr, guest_data, 0); + ret = -TARGET_EINVAL; + goto out; + } + unlock_user(argptr, guest_data, guest_data_size); + + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); + if (!argptr) { + ret = -TARGET_EFAULT; + goto out; + } + thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); + unlock_user(argptr, arg, target_size); + } +out: + g_free(big_buf); + return ret; +} + +static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd, + int cmd, abi_long arg) +{ + void *argptr; + int target_size; + const argtype *arg_type = ie->arg_type; + const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) }; + abi_long ret; + struct blkpg_ioctl_arg *host_blkpg = (void *)buf_temp; + struct blkpg_partition host_part; + + /* Read and convert blkpg */ + arg_type++; + target_size = thunk_type_size(arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + ret = -TARGET_EFAULT; + goto out; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + switch (host_blkpg->op) { + case BLKPG_ADD_PARTITION: + case BLKPG_DEL_PARTITION: + /* payload is struct blkpg_partition */ + break; + default: + /* Unknown opcode */ + ret = -TARGET_EINVAL; + goto out; + } + + /* Read and convert blkpg->data */ + arg = (abi_long)(uintptr_t)host_blkpg->data; + target_size = thunk_type_size(part_arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + ret = -TARGET_EFAULT; + goto out; + } + thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + /* Swizzle the data pointer to our local copy and call! */ + host_blkpg->data = &host_part; + ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg)); + +out: + return ret; +} + +static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + const argtype *arg_type = ie->arg_type; + const StructEntry *se; + const argtype *field_types; + const int *dst_offsets, *src_offsets; + int target_size; + void *argptr; + abi_ulong *target_rt_dev_ptr; + unsigned long *host_rt_dev_ptr; + abi_long ret; + int i; + + assert(ie->access == IOC_W); + assert(*arg_type == TYPE_PTR); + arg_type++; + assert(*arg_type == TYPE_STRUCT); + target_size = thunk_type_size(arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + arg_type++; + assert(*arg_type == (int)STRUCT_rtentry); + se = struct_entries + *arg_type++; + assert(se->convert[0] == NULL); + /* convert struct here to be able to catch rt_dev string */ + field_types = se->field_types; + dst_offsets = se->field_offsets[THUNK_HOST]; + src_offsets = se->field_offsets[THUNK_TARGET]; + for (i = 0; i < se->nb_fields; i++) { + if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) { + assert(*field_types == TYPE_PTRVOID); + target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]); + host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]); + if (*target_rt_dev_ptr != 0) { + *host_rt_dev_ptr = (unsigned long)lock_user_string( + tswapal(*target_rt_dev_ptr)); + if (!*host_rt_dev_ptr) { + unlock_user(argptr, arg, 0); + return -TARGET_EFAULT; + } + } else { + *host_rt_dev_ptr = 0; + } + field_types++; + continue; + } + field_types = thunk_convert(buf_temp + dst_offsets[i], + argptr + src_offsets[i], + field_types, THUNK_HOST); + } + unlock_user(argptr, arg, 0); + + ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + if (*host_rt_dev_ptr != 0) { + unlock_user((void *)*host_rt_dev_ptr, + *target_rt_dev_ptr, 0); + } + return ret; +} + +static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + int sig = target_to_host_signal(arg); + return get_errno(safe_ioctl(fd, ie->host_cmd, sig)); +} + +#ifdef TIOCGPTPEER +static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, int cmd, abi_long arg) +{ + int flags = target_to_host_bitmask(arg, fcntl_flags_tbl); + return get_errno(safe_ioctl(fd, ie->host_cmd, flags)); +} +#endif + +static IOCTLEntry ioctl_entries[] = { +#define IOCTL(cmd, access, ...) \ + { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, +#define IOCTL_SPECIAL(cmd, access, dofn, ...) \ + { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } }, +#define IOCTL_IGNORE(cmd) \ + { TARGET_ ## cmd, 0, #cmd }, +#include "ioctls.h" + { 0, 0, }, +}; + +/* ??? Implement proper locking for ioctls. */ +SYSCALL_IMPL(ioctl) +{ + int fd = arg1; + abi_ulong cmd = arg2; + abi_ulong arg = arg3; + const IOCTLEntry *ie; + const argtype *arg_type; + abi_long ret; + uint8_t buf_temp[MAX_STRUCT_SIZE]; + int target_size; + void *argptr; + + for (ie = ioctl_entries; ; ie++) { + if (ie->target_cmd == 0) { + gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); + return -TARGET_ENOSYS; + } + if (ie->target_cmd == cmd) { + break; + } + } + + arg_type = ie->arg_type; + if (ie->do_ioctl) { + return ie->do_ioctl(ie, buf_temp, fd, cmd, arg); + } else if (!ie->host_cmd) { + /* + * Some architectures define BSD ioctls in their headers + * that are not implemented in Linux. + */ + return -TARGET_ENOSYS; + } + + switch (arg_type[0]) { + case TYPE_NULL: + /* no argument */ + ret = get_errno(safe_ioctl(fd, ie->host_cmd)); + break; + case TYPE_PTRVOID: + case TYPE_INT: + ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg)); + break; + case TYPE_PTR: + arg_type++; + target_size = thunk_type_size(arg_type, 0); + switch (ie->access) { + case IOC_R: + ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + if (!is_error(ret)) { + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); + unlock_user(argptr, arg, target_size); + } + break; + case IOC_W: + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + break; + default: + case IOC_RW: + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + if (!is_error(ret)) { + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); + unlock_user(argptr, arg, target_size); + } + break; + } + break; + default: + gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", + (long)cmd, arg_type[0]); + ret = -TARGET_ENOSYS; + break; + } + return ret; +} diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 82b7267b20..03ecf0a15a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2935,846 +2935,6 @@ STRUCT_MAX #undef STRUCT #undef STRUCT_SPECIAL -typedef struct IOCTLEntry IOCTLEntry; - -typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg); - -struct IOCTLEntry { - int target_cmd; - unsigned int host_cmd; - const char *name; - int access; - do_ioctl_fn *do_ioctl; - const argtype arg_type[5]; -}; - -#define IOC_R 0x0001 -#define IOC_W 0x0002 -#define IOC_RW (IOC_R | IOC_W) - -#define MAX_STRUCT_SIZE 4096 - -#ifdef CONFIG_FIEMAP -/* So fiemap access checks don't overflow on 32 bit systems. - * This is very slightly smaller than the limit imposed by - * the underlying kernel. - */ -#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \ - / sizeof(struct fiemap_extent)) - -static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - /* The parameter for this ioctl is a struct fiemap followed - * by an array of struct fiemap_extent whose size is set - * in fiemap->fm_extent_count. The array is filled in by the - * ioctl. - */ - int target_size_in, target_size_out; - struct fiemap *fm; - const argtype *arg_type = ie->arg_type; - const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) }; - void *argptr, *p; - abi_long ret; - int i, extent_size = thunk_type_size(extent_arg_type, 0); - uint32_t outbufsz; - int free_fm = 0; - - assert(arg_type[0] == TYPE_PTR); - assert(ie->access == IOC_RW); - arg_type++; - target_size_in = thunk_type_size(arg_type, 0); - argptr = lock_user(VERIFY_READ, arg, target_size_in, 1); - if (!argptr) { - return -TARGET_EFAULT; - } - thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - fm = (struct fiemap *)buf_temp; - if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) { - return -TARGET_EINVAL; - } - - outbufsz = sizeof (*fm) + - (sizeof(struct fiemap_extent) * fm->fm_extent_count); - - if (outbufsz > MAX_STRUCT_SIZE) { - /* We can't fit all the extents into the fixed size buffer. - * Allocate one that is large enough and use it instead. - */ - fm = g_try_malloc(outbufsz); - if (!fm) { - return -TARGET_ENOMEM; - } - memcpy(fm, buf_temp, sizeof(struct fiemap)); - free_fm = 1; - } - ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm)); - if (!is_error(ret)) { - target_size_out = target_size_in; - /* An extent_count of 0 means we were only counting the extents - * so there are no structs to copy - */ - if (fm->fm_extent_count != 0) { - target_size_out += fm->fm_mapped_extents * extent_size; - } - argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0); - if (!argptr) { - ret = -TARGET_EFAULT; - } else { - /* Convert the struct fiemap */ - thunk_convert(argptr, fm, arg_type, THUNK_TARGET); - if (fm->fm_extent_count != 0) { - p = argptr + target_size_in; - /* ...and then all the struct fiemap_extents */ - for (i = 0; i < fm->fm_mapped_extents; i++) { - thunk_convert(p, &fm->fm_extents[i], extent_arg_type, - THUNK_TARGET); - p += extent_size; - } - } - unlock_user(argptr, arg, target_size_out); - } - } - if (free_fm) { - g_free(fm); - } - return ret; -} -#endif - -static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - const argtype *arg_type = ie->arg_type; - int target_size; - void *argptr; - int ret; - struct ifconf *host_ifconf; - uint32_t outbufsz; - const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) }; - int target_ifreq_size; - int nb_ifreq; - int free_buf = 0; - int i; - int target_ifc_len; - abi_long target_ifc_buf; - int host_ifc_len; - char *host_ifc_buf; - - assert(arg_type[0] == TYPE_PTR); - assert(ie->access == IOC_RW); - - arg_type++; - target_size = thunk_type_size(arg_type, 0); - - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) - return -TARGET_EFAULT; - thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - - host_ifconf = (struct ifconf *)(unsigned long)buf_temp; - target_ifc_len = host_ifconf->ifc_len; - target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; - - target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); - nb_ifreq = target_ifc_len / target_ifreq_size; - host_ifc_len = nb_ifreq * sizeof(struct ifreq); - - outbufsz = sizeof(*host_ifconf) + host_ifc_len; - if (outbufsz > MAX_STRUCT_SIZE) { - /* We can't fit all the extents into the fixed size buffer. - * Allocate one that is large enough and use it instead. - */ - host_ifconf = malloc(outbufsz); - if (!host_ifconf) { - return -TARGET_ENOMEM; - } - memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); - free_buf = 1; - } - host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf); - - host_ifconf->ifc_len = host_ifc_len; - host_ifconf->ifc_buf = host_ifc_buf; - - ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf)); - if (!is_error(ret)) { - /* convert host ifc_len to target ifc_len */ - - nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq); - target_ifc_len = nb_ifreq * target_ifreq_size; - host_ifconf->ifc_len = target_ifc_len; - - /* restore target ifc_buf */ - - host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf; - - /* copy struct ifconf to target user */ - - argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); - if (!argptr) - return -TARGET_EFAULT; - thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET); - unlock_user(argptr, arg, target_size); - - /* copy ifreq[] to target user */ - - argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0); - for (i = 0; i < nb_ifreq ; i++) { - thunk_convert(argptr + i * target_ifreq_size, - host_ifc_buf + i * sizeof(struct ifreq), - ifreq_arg_type, THUNK_TARGET); - } - unlock_user(argptr, target_ifc_buf, target_ifc_len); - } - - if (free_buf) { - free(host_ifconf); - } - - return ret; -} - -#if defined(CONFIG_USBFS) -#if HOST_LONG_BITS > 64 -#error USBDEVFS thunks do not support >64 bit hosts yet. -#endif -struct live_urb { - uint64_t target_urb_adr; - uint64_t target_buf_adr; - char *target_buf_ptr; - struct usbdevfs_urb host_urb; -}; - -static GHashTable *usbdevfs_urb_hashtable(void) -{ - static GHashTable *urb_hashtable; - - if (!urb_hashtable) { - urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal); - } - return urb_hashtable; -} - -static void urb_hashtable_insert(struct live_urb *urb) -{ - GHashTable *urb_hashtable = usbdevfs_urb_hashtable(); - g_hash_table_insert(urb_hashtable, urb, urb); -} - -static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr) -{ - GHashTable *urb_hashtable = usbdevfs_urb_hashtable(); - return g_hash_table_lookup(urb_hashtable, &target_urb_adr); -} - -static void urb_hashtable_remove(struct live_urb *urb) -{ - GHashTable *urb_hashtable = usbdevfs_urb_hashtable(); - g_hash_table_remove(urb_hashtable, urb); -} - -static abi_long -do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) }; - const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 }; - struct live_urb *lurb; - void *argptr; - uint64_t hurb; - int target_size; - uintptr_t target_urb_adr; - abi_long ret; - - target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET); - - memset(buf_temp, 0, sizeof(uint64_t)); - ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); - if (is_error(ret)) { - return ret; - } - - memcpy(&hurb, buf_temp, sizeof(uint64_t)); - lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb)); - if (!lurb->target_urb_adr) { - return -TARGET_EFAULT; - } - urb_hashtable_remove(lurb); - unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, - lurb->host_urb.buffer_length); - lurb->target_buf_ptr = NULL; - - /* restore the guest buffer pointer */ - lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr; - - /* update the guest urb struct */ - argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0); - if (!argptr) { - g_free(lurb); - return -TARGET_EFAULT; - } - thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET); - unlock_user(argptr, lurb->target_urb_adr, target_size); - - target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET); - /* write back the urb handle */ - argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); - if (!argptr) { - g_free(lurb); - return -TARGET_EFAULT; - } - - /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */ - target_urb_adr = lurb->target_urb_adr; - thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET); - unlock_user(argptr, arg, target_size); - - g_free(lurb); - return ret; -} - -static abi_long -do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie, - uint8_t *buf_temp __attribute__((unused)), - int fd, int cmd, abi_long arg) -{ - struct live_urb *lurb; - - /* map target address back to host URB with metadata. */ - lurb = urb_hashtable_lookup(arg); - if (!lurb) { - return -TARGET_EFAULT; - } - return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb)); -} - -static abi_long -do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - const argtype *arg_type = ie->arg_type; - int target_size; - abi_long ret; - void *argptr; - int rw_dir; - struct live_urb *lurb; - - /* - * each submitted URB needs to map to a unique ID for the - * kernel, and that unique ID needs to be a pointer to - * host memory. hence, we need to malloc for each URB. - * isochronous transfers have a variable length struct. - */ - arg_type++; - target_size = thunk_type_size(arg_type, THUNK_TARGET); - - /* construct host copy of urb and metadata */ - lurb = g_try_malloc0(sizeof(struct live_urb)); - if (!lurb) { - return -TARGET_ENOMEM; - } - - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) { - g_free(lurb); - return -TARGET_EFAULT; - } - thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - - lurb->target_urb_adr = arg; - lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer; - - /* buffer space used depends on endpoint type so lock the entire buffer */ - /* control type urbs should check the buffer contents for true direction */ - rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ; - lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr, - lurb->host_urb.buffer_length, 1); - if (lurb->target_buf_ptr == NULL) { - g_free(lurb); - return -TARGET_EFAULT; - } - - /* update buffer pointer in host copy */ - lurb->host_urb.buffer = lurb->target_buf_ptr; - - ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb)); - if (is_error(ret)) { - unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0); - g_free(lurb); - } else { - urb_hashtable_insert(lurb); - } - - return ret; -} -#endif /* CONFIG_USBFS */ - -static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd, - int cmd, abi_long arg) -{ - void *argptr; - struct dm_ioctl *host_dm; - abi_long guest_data; - uint32_t guest_data_size; - int target_size; - const argtype *arg_type = ie->arg_type; - abi_long ret; - void *big_buf = NULL; - char *host_data; - - arg_type++; - target_size = thunk_type_size(arg_type, 0); - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) { - ret = -TARGET_EFAULT; - goto out; - } - thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - - /* buf_temp is too small, so fetch things into a bigger buffer */ - big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2); - memcpy(big_buf, buf_temp, target_size); - buf_temp = big_buf; - host_dm = big_buf; - - guest_data = arg + host_dm->data_start; - if ((guest_data - arg) < 0) { - ret = -TARGET_EINVAL; - goto out; - } - guest_data_size = host_dm->data_size - host_dm->data_start; - host_data = (char*)host_dm + host_dm->data_start; - - argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1); - if (!argptr) { - ret = -TARGET_EFAULT; - goto out; - } - - switch (ie->host_cmd) { - case DM_REMOVE_ALL: - case DM_LIST_DEVICES: - case DM_DEV_CREATE: - case DM_DEV_REMOVE: - case DM_DEV_SUSPEND: - case DM_DEV_STATUS: - case DM_DEV_WAIT: - case DM_TABLE_STATUS: - case DM_TABLE_CLEAR: - case DM_TABLE_DEPS: - case DM_LIST_VERSIONS: - /* no input data */ - break; - case DM_DEV_RENAME: - case DM_DEV_SET_GEOMETRY: - /* data contains only strings */ - memcpy(host_data, argptr, guest_data_size); - break; - case DM_TARGET_MSG: - memcpy(host_data, argptr, guest_data_size); - *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr); - break; - case DM_TABLE_LOAD: - { - void *gspec = argptr; - void *cur_data = host_data; - const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) }; - int spec_size = thunk_type_size(arg_type, 0); - int i; - - for (i = 0; i < host_dm->target_count; i++) { - struct dm_target_spec *spec = cur_data; - uint32_t next; - int slen; - - thunk_convert(spec, gspec, arg_type, THUNK_HOST); - slen = strlen((char*)gspec + spec_size) + 1; - next = spec->next; - spec->next = sizeof(*spec) + slen; - strcpy((char*)&spec[1], gspec + spec_size); - gspec += next; - cur_data += spec->next; - } - break; - } - default: - ret = -TARGET_EINVAL; - unlock_user(argptr, guest_data, 0); - goto out; - } - unlock_user(argptr, guest_data, 0); - - ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); - if (!is_error(ret)) { - guest_data = arg + host_dm->data_start; - guest_data_size = host_dm->data_size - host_dm->data_start; - argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0); - switch (ie->host_cmd) { - case DM_REMOVE_ALL: - case DM_DEV_CREATE: - case DM_DEV_REMOVE: - case DM_DEV_RENAME: - case DM_DEV_SUSPEND: - case DM_DEV_STATUS: - case DM_TABLE_LOAD: - case DM_TABLE_CLEAR: - case DM_TARGET_MSG: - case DM_DEV_SET_GEOMETRY: - /* no return data */ - break; - case DM_LIST_DEVICES: - { - struct dm_name_list *nl = (void*)host_dm + host_dm->data_start; - uint32_t remaining_data = guest_data_size; - void *cur_data = argptr; - const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) }; - int nl_size = 12; /* can't use thunk_size due to alignment */ - - while (1) { - uint32_t next = nl->next; - if (next) { - nl->next = nl_size + (strlen(nl->name) + 1); - } - if (remaining_data < nl->next) { - host_dm->flags |= DM_BUFFER_FULL_FLAG; - break; - } - thunk_convert(cur_data, nl, arg_type, THUNK_TARGET); - strcpy(cur_data + nl_size, nl->name); - cur_data += nl->next; - remaining_data -= nl->next; - if (!next) { - break; - } - nl = (void*)nl + next; - } - break; - } - case DM_DEV_WAIT: - case DM_TABLE_STATUS: - { - struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start; - void *cur_data = argptr; - const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) }; - int spec_size = thunk_type_size(arg_type, 0); - int i; - - for (i = 0; i < host_dm->target_count; i++) { - uint32_t next = spec->next; - int slen = strlen((char*)&spec[1]) + 1; - spec->next = (cur_data - argptr) + spec_size + slen; - if (guest_data_size < spec->next) { - host_dm->flags |= DM_BUFFER_FULL_FLAG; - break; - } - thunk_convert(cur_data, spec, arg_type, THUNK_TARGET); - strcpy(cur_data + spec_size, (char*)&spec[1]); - cur_data = argptr + spec->next; - spec = (void*)host_dm + host_dm->data_start + next; - } - break; - } - case DM_TABLE_DEPS: - { - void *hdata = (void*)host_dm + host_dm->data_start; - int count = *(uint32_t*)hdata; - uint64_t *hdev = hdata + 8; - uint64_t *gdev = argptr + 8; - int i; - - *(uint32_t*)argptr = tswap32(count); - for (i = 0; i < count; i++) { - *gdev = tswap64(*hdev); - gdev++; - hdev++; - } - break; - } - case DM_LIST_VERSIONS: - { - struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start; - uint32_t remaining_data = guest_data_size; - void *cur_data = argptr; - const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) }; - int vers_size = thunk_type_size(arg_type, 0); - - while (1) { - uint32_t next = vers->next; - if (next) { - vers->next = vers_size + (strlen(vers->name) + 1); - } - if (remaining_data < vers->next) { - host_dm->flags |= DM_BUFFER_FULL_FLAG; - break; - } - thunk_convert(cur_data, vers, arg_type, THUNK_TARGET); - strcpy(cur_data + vers_size, vers->name); - cur_data += vers->next; - remaining_data -= vers->next; - if (!next) { - break; - } - vers = (void*)vers + next; - } - break; - } - default: - unlock_user(argptr, guest_data, 0); - ret = -TARGET_EINVAL; - goto out; - } - unlock_user(argptr, guest_data, guest_data_size); - - argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); - if (!argptr) { - ret = -TARGET_EFAULT; - goto out; - } - thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); - unlock_user(argptr, arg, target_size); - } -out: - g_free(big_buf); - return ret; -} - -static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd, - int cmd, abi_long arg) -{ - void *argptr; - int target_size; - const argtype *arg_type = ie->arg_type; - const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) }; - abi_long ret; - - struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp; - struct blkpg_partition host_part; - - /* Read and convert blkpg */ - arg_type++; - target_size = thunk_type_size(arg_type, 0); - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) { - ret = -TARGET_EFAULT; - goto out; - } - thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - - switch (host_blkpg->op) { - case BLKPG_ADD_PARTITION: - case BLKPG_DEL_PARTITION: - /* payload is struct blkpg_partition */ - break; - default: - /* Unknown opcode */ - ret = -TARGET_EINVAL; - goto out; - } - - /* Read and convert blkpg->data */ - arg = (abi_long)(uintptr_t)host_blkpg->data; - target_size = thunk_type_size(part_arg_type, 0); - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) { - ret = -TARGET_EFAULT; - goto out; - } - thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - - /* Swizzle the data pointer to our local copy and call! */ - host_blkpg->data = &host_part; - ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg)); - -out: - return ret; -} - -static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - const argtype *arg_type = ie->arg_type; - const StructEntry *se; - const argtype *field_types; - const int *dst_offsets, *src_offsets; - int target_size; - void *argptr; - abi_ulong *target_rt_dev_ptr; - unsigned long *host_rt_dev_ptr; - abi_long ret; - int i; - - assert(ie->access == IOC_W); - assert(*arg_type == TYPE_PTR); - arg_type++; - assert(*arg_type == TYPE_STRUCT); - target_size = thunk_type_size(arg_type, 0); - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) { - return -TARGET_EFAULT; - } - arg_type++; - assert(*arg_type == (int)STRUCT_rtentry); - se = struct_entries + *arg_type++; - assert(se->convert[0] == NULL); - /* convert struct here to be able to catch rt_dev string */ - field_types = se->field_types; - dst_offsets = se->field_offsets[THUNK_HOST]; - src_offsets = se->field_offsets[THUNK_TARGET]; - for (i = 0; i < se->nb_fields; i++) { - if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) { - assert(*field_types == TYPE_PTRVOID); - target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]); - host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]); - if (*target_rt_dev_ptr != 0) { - *host_rt_dev_ptr = (unsigned long)lock_user_string( - tswapal(*target_rt_dev_ptr)); - if (!*host_rt_dev_ptr) { - unlock_user(argptr, arg, 0); - return -TARGET_EFAULT; - } - } else { - *host_rt_dev_ptr = 0; - } - field_types++; - continue; - } - field_types = thunk_convert(buf_temp + dst_offsets[i], - argptr + src_offsets[i], - field_types, THUNK_HOST); - } - unlock_user(argptr, arg, 0); - - ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); - if (*host_rt_dev_ptr != 0) { - unlock_user((void *)*host_rt_dev_ptr, - *target_rt_dev_ptr, 0); - } - return ret; -} - -static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - int sig = target_to_host_signal(arg); - return get_errno(safe_ioctl(fd, ie->host_cmd, sig)); -} - -#ifdef TIOCGPTPEER -static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp, - int fd, int cmd, abi_long arg) -{ - int flags = target_to_host_bitmask(arg, fcntl_flags_tbl); - return get_errno(safe_ioctl(fd, ie->host_cmd, flags)); -} -#endif - -static IOCTLEntry ioctl_entries[] = { -#define IOCTL(cmd, access, ...) \ - { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, -#define IOCTL_SPECIAL(cmd, access, dofn, ...) \ - { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } }, -#define IOCTL_IGNORE(cmd) \ - { TARGET_ ## cmd, 0, #cmd }, -#include "ioctls.h" - { 0, 0, }, -}; - -/* ??? Implement proper locking for ioctls. */ -/* do_ioctl() Must return target values and target errnos. */ -static abi_long do_ioctl(int fd, int cmd, abi_long arg) -{ - const IOCTLEntry *ie; - const argtype *arg_type; - abi_long ret; - uint8_t buf_temp[MAX_STRUCT_SIZE]; - int target_size; - void *argptr; - - ie = ioctl_entries; - for(;;) { - if (ie->target_cmd == 0) { - gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); - return -TARGET_ENOSYS; - } - if (ie->target_cmd == cmd) - break; - ie++; - } - arg_type = ie->arg_type; - if (ie->do_ioctl) { - return ie->do_ioctl(ie, buf_temp, fd, cmd, arg); - } else if (!ie->host_cmd) { - /* Some architectures define BSD ioctls in their headers - that are not implemented in Linux. */ - return -TARGET_ENOSYS; - } - - switch(arg_type[0]) { - case TYPE_NULL: - /* no argument */ - ret = get_errno(safe_ioctl(fd, ie->host_cmd)); - break; - case TYPE_PTRVOID: - case TYPE_INT: - ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg)); - break; - case TYPE_PTR: - arg_type++; - target_size = thunk_type_size(arg_type, 0); - switch(ie->access) { - case IOC_R: - ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); - if (!is_error(ret)) { - argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); - if (!argptr) - return -TARGET_EFAULT; - thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); - unlock_user(argptr, arg, target_size); - } - break; - case IOC_W: - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) - return -TARGET_EFAULT; - thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); - break; - default: - case IOC_RW: - argptr = lock_user(VERIFY_READ, arg, target_size, 1); - if (!argptr) - return -TARGET_EFAULT; - thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); - unlock_user(argptr, arg, 0); - ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); - if (!is_error(ret)) { - argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); - if (!argptr) - return -TARGET_EFAULT; - thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); - unlock_user(argptr, arg, target_size); - } - break; - } - break; - default: - gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", - (long)cmd, arg_type[0]); - ret = -TARGET_ENOSYS; - break; - } - return ret; -} - static const bitmask_transtbl iflag_tbl[] = { { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK }, { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT }, @@ -5241,8 +4401,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { - case TARGET_NR_ioctl: - return do_ioctl(arg1, arg2, arg3); #ifdef TARGET_NR_fcntl case TARGET_NR_fcntl: return do_fcntl(arg1, arg2, arg3); @@ -8811,6 +7969,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, int64_t arg5, int64_t arg6) #include "syscall-file.inc.c" +#include "syscall-ioctl.inc.c" #include "syscall-ipc.inc.c" #include "syscall-mem.inc.c" #include "syscall-proc.inc.c" diff --git a/linux-user/strace.list b/linux-user/strace.list index 9f2f8977b4..15208b5349 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -365,9 +365,6 @@ #ifdef TARGET_NR_io_cancel { TARGET_NR_io_cancel, "io_cancel" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_ioctl -{ TARGET_NR_ioctl, "ioctl" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_io_destroy { TARGET_NR_io_destroy, "io_destroy" , NULL, NULL, NULL }, #endif From patchwork Fri Jan 18 21:31:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1027789 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="aFJ4IpmQ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43hFGn0LB0z9sDP for ; Sat, 19 Jan 2019 08:59:43 +1100 (AEDT) Received: from localhost ([127.0.0.1]:47764 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkcAt-0002Fy-TZ for incoming@patchwork.ozlabs.org; Fri, 18 Jan 2019 16:59:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56669) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkblx-0006S1-8g for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkblp-0006Tm-G1 for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:48 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:42957) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkbln-0005vu-PM for qemu-devel@nongnu.org; Fri, 18 Jan 2019 16:33:45 -0500 Received: by mail-pl1-x642.google.com with SMTP id y1so6881523plp.9 for ; Fri, 18 Jan 2019 13:33:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bVtzcqpIw/hL5BeV8mp3wVe8vrxdnl7Of92ZgCgm8CI=; b=aFJ4IpmQQzR+OoDp4wnuDZgJH4ITialB+uMV1ISzehx8w6fguWAPXLfx/7ba98A6mo 6CH/VSrglv+kEkXfqfJsQtgkjApVpdgA/cUUhkmQu4khAHGnhcdw2jxcLkgsbpTMK0bD 7vuxFOjgL8VVqlqVpnsPO7ToJiY1cXuXJe3ss= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bVtzcqpIw/hL5BeV8mp3wVe8vrxdnl7Of92ZgCgm8CI=; b=QxIw97U2rIFrL6KtIhSWN0Mk7XpE9pJ8XQoYcbuMDSmzZ/H1sHGAnsEcJ9K+aYGxxK KPAWXLt3DPDcAp5fvThKXFops/qoeCHPj6urSCDhX4j62Kp8Lue8G8Pzx4TtIL/+Em8F jZF1fE4N+GCGapy1bU4PQbgjmDScFXjbIy4Vvbh9ZJH+qa0+aikbDbbA/P8dWsX17yTh fi67TvJRF84UEwzCJR7OYlSyb7HFXdDpDTI7CaqsDXDOe0nwMWkuFAvbqn3JM6p5KECL epKOSct+lu9xHIQcoPaU/fBUa2kSKoe3kTLLYGbEZ89oYWfqnvUxBAgFh5DnC1G0EzUN AZLg== X-Gm-Message-State: AJcUukcWWLbLEAnQDzFd9hXmy1BR5jGKEHY7ODY5ZxkJ08Tyu+fesQgS hU3zbLyAQhwOtIv4n7XZKdfmo9M845k= X-Google-Smtp-Source: ALg8bN4cRkoYBhXUxh/bHGYnnlpyqqik3Wy1buJRFabJGsNNfDQ4qQ9CgeJja2NdJyteSRrEJU5NCw== X-Received: by 2002:a17:902:9a02:: with SMTP id v2mr21129715plp.180.1547847202164; Fri, 18 Jan 2019 13:33:22 -0800 (PST) Received: from cloudburst.twiddle.net ([2001:8000:10e0:a000:c673:a6b6:fdef:1933]) by smtp.gmail.com with ESMTPSA id v12sm5833667pgg.41.2019.01.18.13.33.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 13:33:21 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 19 Jan 2019 08:31:22 +1100 Message-Id: <20190118213122.22865-49-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190118213122.22865-1-richard.henderson@linaro.org> References: <20190118213122.22865-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH v6 49/49] linux-user: Split out fcntl, fcntl64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Preserving strace functionality is tricky with this one. Rearrange to lookup structures that contain the data for both execution and strace for each command. Do not allow lookup of 64-bit fcntl commands from 32-bit fcntl. Signed-off-by: Richard Henderson --- linux-user/syscall-defs.h | 6 + linux-user/strace.c | 100 ---------- linux-user/syscall-fcntl.inc.c | 322 +++++++++++++++++++++++++++++++++ linux-user/syscall.c | 256 +------------------------- linux-user/strace.list | 6 - 5 files changed, 329 insertions(+), 361 deletions(-) create mode 100644 linux-user/syscall-fcntl.inc.c diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index f58b9745a4..5cf39f2bb9 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -46,6 +46,12 @@ SYSCALL_DEF(execveat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG); SYSCALL_DEF(faccessat, ARG_ATDIRFD, ARG_STR, ARG_ACCESSFLAG); SYSCALL_DEF(fchmod, ARG_DEC, ARG_MODEFLAG); SYSCALL_DEF(fchmodat, ARG_ATDIRFD, ARG_STR, ARG_MODEFLAG); +#ifdef TARGET_NR_fcntl +SYSCALL_DEF_FULL(fcntl, .impl = impl_fcntl, .print = print_fcntl); +#endif +#if TARGET_ABI_BITS == 32 +SYSCALL_DEF_FULL(fcntl64, .impl = impl_fcntl64, .print = print_fcntl64); +#endif #ifdef TARGET_NR_futimesat SYSCALL_DEF(futimesat, ARG_ATDIRFD, ARG_STR, ARG_PTR); #endif diff --git a/linux-user/strace.c b/linux-user/strace.c index ca8e110675..787bf41307 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1172,106 +1172,6 @@ print_fchownat(const struct syscallname *name, } #endif -#if defined(TARGET_NR_fcntl) || defined(TARGET_NR_fcntl64) -static void -print_fcntl(const struct syscallname *name, - abi_long arg0, abi_long arg1, abi_long arg2, - abi_long arg3, abi_long arg4, abi_long arg5) -{ - print_syscall_prologue(name); - print_raw_param("%d", arg0, 0); - switch(arg1) { - case TARGET_F_DUPFD: - gemu_log("F_DUPFD,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); - break; - case TARGET_F_GETFD: - gemu_log("F_GETFD"); - break; - case TARGET_F_SETFD: - gemu_log("F_SETFD,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); - break; - case TARGET_F_GETFL: - gemu_log("F_GETFL"); - break; - case TARGET_F_SETFL: - gemu_log("F_SETFL,"); - print_open_flags(arg2, 1); - break; - case TARGET_F_GETLK: - gemu_log("F_GETLK,"); - print_pointer(arg2, 1); - break; - case TARGET_F_SETLK: - gemu_log("F_SETLK,"); - print_pointer(arg2, 1); - break; - case TARGET_F_SETLKW: - gemu_log("F_SETLKW,"); - print_pointer(arg2, 1); - break; - case TARGET_F_GETOWN: - gemu_log("F_GETOWN"); - break; - case TARGET_F_SETOWN: - gemu_log("F_SETOWN,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); - break; - case TARGET_F_GETSIG: - gemu_log("F_GETSIG"); - break; - case TARGET_F_SETSIG: - gemu_log("F_SETSIG,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); - break; -#if TARGET_ABI_BITS == 32 - case TARGET_F_GETLK64: - gemu_log("F_GETLK64,"); - print_pointer(arg2, 1); - break; - case TARGET_F_SETLK64: - gemu_log("F_SETLK64,"); - print_pointer(arg2, 1); - break; - case TARGET_F_SETLKW64: - gemu_log("F_SETLKW64,"); - print_pointer(arg2, 1); - break; -#endif - case TARGET_F_SETLEASE: - gemu_log("F_SETLEASE,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); - break; - case TARGET_F_GETLEASE: - gemu_log("F_GETLEASE"); - break; - case TARGET_F_SETPIPE_SZ: - gemu_log("F_SETPIPE_SZ,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); - break; - case TARGET_F_GETPIPE_SZ: - gemu_log("F_GETPIPE_SZ"); - break; - case TARGET_F_DUPFD_CLOEXEC: - gemu_log("F_DUPFD_CLOEXEC,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 1); - break; - case TARGET_F_NOTIFY: - gemu_log("F_NOTIFY,"); - print_raw_param(TARGET_ABI_FMT_ld, arg2, 0); - break; - default: - print_raw_param(TARGET_ABI_FMT_ld, arg1, 0); - print_pointer(arg2, 1); - break; - } - print_syscall_epilogue(name); -} -#define print_fcntl64 print_fcntl -#endif - - #if defined(TARGET_NR_socket) static void print_socket(const struct syscallname *name, diff --git a/linux-user/syscall-fcntl.inc.c b/linux-user/syscall-fcntl.inc.c new file mode 100644 index 0000000000..768682bd17 --- /dev/null +++ b/linux-user/syscall-fcntl.inc.c @@ -0,0 +1,322 @@ +/* + * Linux fcntl syscall implementation + * Copyright (c) 2003 Fabrice Bellard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +typedef struct FcntlEntry FcntlEntry; + +typedef abi_long FcntlFn(int fd, int host_cmd, abi_long arg); + +struct FcntlEntry { + const char *name; + FcntlFn *host_fn; + int host_cmd; + SyscallArgType arg_type; +}; + +static abi_long do_fcntl_int(int fd, int host_cmd, abi_long arg) +{ + return get_errno(safe_fcntl(fd, host_cmd, arg)); +} + +static abi_long do_fcntl_getfl(int fd, int host_cmd, abi_long arg) +{ + abi_long ret = get_errno(safe_fcntl(fd, host_cmd)); + if (!is_error(ret)) { + ret = host_to_target_bitmask(ret, fcntl_flags_tbl); + } + return ret; +} + +static abi_long do_fcntl_setfl(int fd, int host_cmd, abi_long arg) +{ + return get_errno(safe_fcntl(fd, host_cmd, + target_to_host_bitmask(arg, fcntl_flags_tbl))); +} + +static abi_long do_fcntl_getlk_1(int fd, int host_cmd, abi_long arg, + from_flock64_fn *copy_from, + to_flock64_fn *copy_to) +{ + struct flock64 fl64; + abi_long ret; + + ret = copy_from(&fl64, arg); + if (ret == 0) { + ret = get_errno(safe_fcntl(fd, host_cmd, &fl64)); + if (ret == 0) { + ret = copy_to(arg, &fl64); + } + } + return ret; +} + +static abi_long do_fcntl_setlk_1(int fd, int host_cmd, abi_long arg, + from_flock64_fn *copy_from) +{ + struct flock64 fl64; + abi_long ret; + + ret = copy_from(&fl64, arg); + if (ret == 0) { + ret = get_errno(safe_fcntl(fd, host_cmd, &fl64)); + } + return ret; +} + +static abi_long do_fcntl_getlk(int fd, int cmd, abi_long arg) +{ + return do_fcntl_getlk_1(fd, cmd, arg, + copy_from_user_flock, + copy_to_user_flock); +} + +static abi_long do_fcntl_setlk(int fd, int cmd, abi_long arg) +{ + return do_fcntl_setlk_1(fd, cmd, arg, copy_from_user_flock); +} + +static abi_long do_fcntl_getlk64(int fd, int cmd, abi_long arg) +{ + return do_fcntl_getlk_1(fd, cmd, arg, + copy_from_user_flock64, + copy_to_user_flock64); +} + +static abi_long do_fcntl_setlk64(int fd, int cmd, abi_long arg) +{ + return do_fcntl_setlk_1(fd, cmd, arg, copy_from_user_flock64); +} + +#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32 +static abi_long do_fcntl_oabi_getlk64(int fd, int cmd, abi_long arg) +{ + return do_fcntl_getlk_1(fd, cmd, arg, + copy_from_user_oabi_flock64, + copy_to_user_oabi_flock64); +} + +static abi_long do_fcntl_oabi_setlk64(int fd, int cmd, abi_long arg) +{ + return do_fcntl_setlk_1(fd, cmd, arg, copy_from_user_oabi_flock64); +} +#endif /* TARGET_ARM */ + +#ifdef F_GETOWN_EX +static abi_long do_fcntl_getown_ex(int fd, int cmd, abi_long arg) +{ + struct f_owner_ex fox; + abi_long ret = get_errno(safe_fcntl(fd, cmd, &fox)); + + if (!is_error(ret)) { + struct target_f_owner_ex *target_fox; + if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0)) { + return -TARGET_EFAULT; + } + target_fox->type = tswap32(fox.type); + target_fox->pid = tswap32(fox.pid); + unlock_user_struct(target_fox, arg, 1); + } + return ret; +} + +static abi_long do_fcntl_setown_ex(int fd, int cmd, abi_long arg) +{ + struct target_f_owner_ex *target_fox; + struct f_owner_ex fox; + + if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1)) { + return -TARGET_EFAULT; + } + fox.type = tswap32(target_fox->type); + fox.pid = tswap32(target_fox->pid); + unlock_user_struct(target_fox, arg, 0); + return get_errno(safe_fcntl(fd, cmd, &fox)); +} +#endif /* F_GETOWN_EX */ + +static const FcntlEntry *target_fcntl_cmd(int cmd, int is_64) +{ +#define CMD2(T, H, A, FN) \ + case TARGET_##T: do { \ + static const FcntlEntry ent_##T = { \ + .name = #T, .host_cmd = H, .host_fn = FN, .arg_type = A \ + }; \ + return &ent_##T; \ + } while(0) + +#define CMD1(T, A, FN) \ + case TARGET_##T: do { \ + static const FcntlEntry ent_##T = { \ + .name = #T, .host_cmd = T, .host_fn = FN, .arg_type = A \ + }; \ + return &ent_##T; \ + } while(0) + +#if TARGET_ABI_BITS == 64 +# ifdef __powerpc64__ +/* + * On PPC64, glibc headers has the F_*LK* defined to 12, 13 and 14 and + * is not supported by kernel. The glibc fcntl call actually adjusts + * them to 5, 6 and 7 before making the syscall(). Since we make the + * syscall directly, adjust to what is supported by the kernel. + */ +# define HOST_CMD_ADJ64(C) (C - (F_GETLK64 - 5)) +# else +# define HOST_CMD_ADJ64(C) C +# endif +# define CMD64(T, FN) \ + case TARGET_##T: do { \ + static const FcntlEntry ent_##T = { \ + .name = #T, .host_cmd = HOST_CMD_ADJ64(T), \ + .host_fn = do_fcntl_##FN, .arg_type = ARG_PTR \ + }; \ + return &ent_##T; \ + } while(0) +#elif defined(TARGET_ARM) +# define CMD64(T, FN) \ + case TARGET_##T: do { \ + if (!is_64) { \ + return NULL; \ + } else if (is_64 > 0) { \ + static const FcntlEntry ent_##T = { \ + .name = #T, .host_cmd = T, \ + .host_fn = do_fcntl_##FN, .arg_type = ARG_PTR \ + }; \ + return &ent_##T; \ + } else { \ + static const FcntlEntry ent_oabi_##T = { \ + .name = #T, .host_cmd = T, \ + .host_fn = do_fcntl_oabi_##FN, .arg_type = ARG_PTR \ + }; \ + return &ent_oabi_##T; \ + } \ + } while (0) +#else +# define CMD64(T, FN) \ + case TARGET_##T: do { \ + static const FcntlEntry ent_##T = { \ + .name = #T, .host_cmd = T, \ + .host_fn = do_fcntl_##FN, .arg_type = ARG_PTR \ + }; \ + return is_64 ? &ent_##T : NULL; \ + } while (0) +#endif + + switch (cmd) { + CMD1(F_DUPFD, ARG_DEC, do_fcntl_int); + CMD1(F_GETFD, ARG_NONE, do_fcntl_int); + CMD1(F_SETFD, ARG_DEC, do_fcntl_int); + CMD1(F_GETFL, ARG_NONE, do_fcntl_getfl); + CMD1(F_SETFL, ARG_DEC, do_fcntl_setfl); + + CMD2(F_GETLK, F_GETLK64, ARG_PTR, do_fcntl_getlk); + CMD2(F_SETLK, F_SETLK64, ARG_PTR, do_fcntl_setlk); + CMD2(F_SETLKW, F_SETLKW64, ARG_PTR, do_fcntl_setlk); + + CMD1(F_GETOWN, ARG_NONE, do_fcntl_int); + CMD1(F_SETOWN, ARG_DEC, do_fcntl_int); + CMD1(F_GETSIG, ARG_NONE, do_fcntl_int); + CMD1(F_SETSIG, ARG_DEC, do_fcntl_int); + + CMD64(F_GETLK64, getlk64); + CMD64(F_SETLK64, setlk64); + CMD64(F_SETLKW64, setlk64); + + CMD1(F_GETLEASE, ARG_NONE, do_fcntl_int); + CMD1(F_SETLEASE, ARG_DEC, do_fcntl_int); +#ifdef F_DUPFD_CLOEXEC + CMD1(F_DUPFD_CLOEXEC, ARG_DEC, do_fcntl_int); +#endif + CMD1(F_NOTIFY, ARG_DEC, do_fcntl_int); +#ifdef F_GETOWN_EX + CMD1(F_GETOWN_EX, ARG_PTR, do_fcntl_getown_ex); + CMD1(F_SETOWN_EX, ARG_PTR, do_fcntl_setown_ex); +#endif +#ifdef F_SETPIPE_SZ + CMD1(F_SETPIPE_SZ, ARG_DEC, do_fcntl_int); + CMD1(F_GETPIPE_SZ, ARG_DEC, do_fcntl_int); +#endif + } + return NULL; + +#undef CMD1 +#undef CMD2 +#undef CMD64 +#undef HOST_CMD_ADJ64 +} + +static abi_long do_fcntl(int fd, int target_cmd, abi_ulong arg, int is_64) +{ + const FcntlEntry *ent = target_fcntl_cmd(target_cmd, is_64); + + if (ent == NULL) { + return -TARGET_EINVAL; + } + return ent->host_fn(fd, ent->host_cmd, arg); +} + +static void do_print_fcntl(const SyscallDef *def, int fd, int target_cmd, + abi_ulong arg, int is_64) +{ + const FcntlEntry *ent = target_fcntl_cmd(target_cmd, is_64); + + switch (ent->arg_type) { + case ARG_NONE: + gemu_log("%d %s(%d,%s)", getpid(), def->name, fd, ent->name); + break; + case ARG_DEC: + gemu_log("%d %s(%d,%s," TARGET_ABI_FMT_ld ")", + getpid(), def->name, fd, ent->name, arg); + break; + case ARG_PTR: + gemu_log("%d %s(%d,%s,0x" TARGET_ABI_FMT_lx ")", + getpid(), def->name, fd, ent->name, arg); + break; + default: + g_assert_not_reached(); + } +} + +#ifdef TARGET_NR_fcntl +SYSCALL_IMPL(fcntl) +{ + return do_fcntl(arg1, arg2, arg3, 0); +} + +static void print_fcntl(const SyscallDef *def, int64_t in[6]) +{ + return do_print_fcntl(def, in[0], in[1], in[2], 0); +} +#endif + +#if TARGET_ABI_BITS == 32 +SYSCALL_IMPL(fcntl64) +{ + int is_64 = 1; +#ifdef TARGET_ARM + if (!cpu_env->eabi) { + is_64 = -1; + } +#endif + return do_fcntl(arg1, arg2, arg3, is_64); +} + +static void print_fcntl64(const SyscallDef *def, int64_t in[6]) +{ + return do_print_fcntl(def, in[0], in[1], in[2], 1); +} +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 03ecf0a15a..bce26592d2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3469,102 +3469,6 @@ static void *clone_func(void *arg) return NULL; } -/* warning : doesn't handle linux specific flags... */ -static int target_to_host_fcntl_cmd(int cmd) -{ - int ret; - - switch(cmd) { - case TARGET_F_DUPFD: - case TARGET_F_GETFD: - case TARGET_F_SETFD: - case TARGET_F_GETFL: - case TARGET_F_SETFL: - ret = cmd; - break; - case TARGET_F_GETLK: - ret = F_GETLK64; - break; - case TARGET_F_SETLK: - ret = F_SETLK64; - break; - case TARGET_F_SETLKW: - ret = F_SETLKW64; - break; - case TARGET_F_GETOWN: - ret = F_GETOWN; - break; - case TARGET_F_SETOWN: - ret = F_SETOWN; - break; - case TARGET_F_GETSIG: - ret = F_GETSIG; - break; - case TARGET_F_SETSIG: - ret = F_SETSIG; - break; -#if TARGET_ABI_BITS == 32 - case TARGET_F_GETLK64: - ret = F_GETLK64; - break; - case TARGET_F_SETLK64: - ret = F_SETLK64; - break; - case TARGET_F_SETLKW64: - ret = F_SETLKW64; - break; -#endif - case TARGET_F_SETLEASE: - ret = F_SETLEASE; - break; - case TARGET_F_GETLEASE: - ret = F_GETLEASE; - break; -#ifdef F_DUPFD_CLOEXEC - case TARGET_F_DUPFD_CLOEXEC: - ret = F_DUPFD_CLOEXEC; - break; -#endif - case TARGET_F_NOTIFY: - ret = F_NOTIFY; - break; -#ifdef F_GETOWN_EX - case TARGET_F_GETOWN_EX: - ret = F_GETOWN_EX; - break; -#endif -#ifdef F_SETOWN_EX - case TARGET_F_SETOWN_EX: - ret = F_SETOWN_EX; - break; -#endif -#ifdef F_SETPIPE_SZ - case TARGET_F_SETPIPE_SZ: - ret = F_SETPIPE_SZ; - break; - case TARGET_F_GETPIPE_SZ: - ret = F_GETPIPE_SZ; - break; -#endif - default: - ret = -TARGET_EINVAL; - break; - } - -#if defined(__powerpc64__) - /* On PPC64, glibc headers has the F_*LK* defined to 12, 13 and 14 and - * is not supported by kernel. The glibc fcntl call actually adjusts - * them to 5, 6 and 7 before making the syscall(). Since we make the - * syscall directly, adjust to what is supported by the kernel. - */ - if (ret >= F_GETLK64 && ret <= F_SETLKW64) { - ret -= F_GETLK64 - 5; - } -#endif - - return ret; -} - #define FLOCK_TRANSTBL \ switch (type) { \ TRANSTBL_CONVERT(F_RDLCK); \ @@ -3730,114 +3634,6 @@ static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr, return 0; } -static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) -{ - struct flock64 fl64; -#ifdef F_GETOWN_EX - struct f_owner_ex fox; - struct target_f_owner_ex *target_fox; -#endif - abi_long ret; - int host_cmd = target_to_host_fcntl_cmd(cmd); - - if (host_cmd == -TARGET_EINVAL) - return host_cmd; - - switch(cmd) { - case TARGET_F_GETLK: - ret = copy_from_user_flock(&fl64, arg); - if (ret) { - return ret; - } - ret = get_errno(safe_fcntl(fd, host_cmd, &fl64)); - if (ret == 0) { - ret = copy_to_user_flock(arg, &fl64); - } - break; - - case TARGET_F_SETLK: - case TARGET_F_SETLKW: - ret = copy_from_user_flock(&fl64, arg); - if (ret) { - return ret; - } - ret = get_errno(safe_fcntl(fd, host_cmd, &fl64)); - break; - - case TARGET_F_GETLK64: - ret = copy_from_user_flock64(&fl64, arg); - if (ret) { - return ret; - } - ret = get_errno(safe_fcntl(fd, host_cmd, &fl64)); - if (ret == 0) { - ret = copy_to_user_flock64(arg, &fl64); - } - break; - case TARGET_F_SETLK64: - case TARGET_F_SETLKW64: - ret = copy_from_user_flock64(&fl64, arg); - if (ret) { - return ret; - } - ret = get_errno(safe_fcntl(fd, host_cmd, &fl64)); - break; - - case TARGET_F_GETFL: - ret = get_errno(safe_fcntl(fd, host_cmd, arg)); - if (ret >= 0) { - ret = host_to_target_bitmask(ret, fcntl_flags_tbl); - } - break; - - case TARGET_F_SETFL: - ret = get_errno(safe_fcntl(fd, host_cmd, - target_to_host_bitmask(arg, - fcntl_flags_tbl))); - break; - -#ifdef F_GETOWN_EX - case TARGET_F_GETOWN_EX: - ret = get_errno(safe_fcntl(fd, host_cmd, &fox)); - if (ret >= 0) { - if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0)) - return -TARGET_EFAULT; - target_fox->type = tswap32(fox.type); - target_fox->pid = tswap32(fox.pid); - unlock_user_struct(target_fox, arg, 1); - } - break; -#endif - -#ifdef F_SETOWN_EX - case TARGET_F_SETOWN_EX: - if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1)) - return -TARGET_EFAULT; - fox.type = tswap32(target_fox->type); - fox.pid = tswap32(target_fox->pid); - unlock_user_struct(target_fox, arg, 0); - ret = get_errno(safe_fcntl(fd, host_cmd, &fox)); - break; -#endif - - case TARGET_F_SETOWN: - case TARGET_F_GETOWN: - case TARGET_F_SETSIG: - case TARGET_F_GETSIG: - case TARGET_F_SETLEASE: - case TARGET_F_GETLEASE: - case TARGET_F_SETPIPE_SZ: - case TARGET_F_GETPIPE_SZ: - ret = get_errno(safe_fcntl(fd, host_cmd, arg)); - break; - - default: - ret = get_errno(safe_fcntl(fd, cmd, arg)); - break; - } - return ret; -} - #ifdef USE_UID16 static inline int high2lowuid(int uid) @@ -4401,10 +4197,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_fcntl - case TARGET_NR_fcntl: - return do_fcntl(arg1, arg2, arg3); -#endif case TARGET_NR_setpgid: return get_errno(setpgid(arg1, arg2)); case TARGET_NR_umask: @@ -6935,53 +6727,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, This is a hint, so ignoring and returning success is ok. */ return 0; #endif -#if TARGET_ABI_BITS == 32 - case TARGET_NR_fcntl64: - { - int cmd; - struct flock64 fl; - from_flock64_fn *copyfrom = copy_from_user_flock64; - to_flock64_fn *copyto = copy_to_user_flock64; - -#ifdef TARGET_ARM - if (!((CPUARMState *)cpu_env)->eabi) { - copyfrom = copy_from_user_oabi_flock64; - copyto = copy_to_user_oabi_flock64; - } -#endif - - cmd = target_to_host_fcntl_cmd(arg2); - if (cmd == -TARGET_EINVAL) { - return cmd; - } - - switch(arg2) { - case TARGET_F_GETLK64: - ret = copyfrom(&fl, arg3); - if (ret) { - break; - } - ret = get_errno(safe_fcntl(arg1, cmd, &fl)); - if (ret == 0) { - ret = copyto(arg3, &fl); - } - break; - - case TARGET_F_SETLK64: - case TARGET_F_SETLKW64: - ret = copyfrom(&fl, arg3); - if (ret) { - break; - } - ret = get_errno(safe_fcntl(arg1, cmd, &fl)); - break; - default: - ret = do_fcntl(arg1, arg2, arg3); - break; - } - return ret; - } -#endif #ifdef TARGET_NR_cacheflush case TARGET_NR_cacheflush: /* self-modifying code is handled automatically, so nothing needed */ @@ -7968,6 +7713,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, int64_t arg2, int64_t arg3, int64_t arg4, \ int64_t arg5, int64_t arg6) +#include "syscall-fcntl.inc.c" #include "syscall-file.inc.c" #include "syscall-ioctl.inc.c" #include "syscall-ipc.inc.c" diff --git a/linux-user/strace.list b/linux-user/strace.list index 15208b5349..8762892db5 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -157,12 +157,6 @@ #ifdef TARGET_NR_fchownat { TARGET_NR_fchownat, "fchownat" , NULL, print_fchownat, NULL }, #endif -#ifdef TARGET_NR_fcntl -{ TARGET_NR_fcntl, "fcntl" , NULL, print_fcntl, NULL }, -#endif -#ifdef TARGET_NR_fcntl64 -{ TARGET_NR_fcntl64, "fcntl64" , NULL, print_fcntl64, NULL }, -#endif #ifdef TARGET_NR_fdatasync { TARGET_NR_fdatasync, "fdatasync" , NULL, NULL, NULL }, #endif