linux-user branch pull request 20230204

Implement execveat()
 un-parent OBJECT(cpu) when closing thread
 Revert fix for glibc >= 2.36 sys/mount.h
 Fix/update strace
 move target_flat.h to target subdirs
 Fix SO_ERROR return code of getsockopt()
 Fix /proc/cpuinfo output for hppa
 Add emulation for MADV_WIPEONFORK and MADV_KEEPONFORK in madvise()
 Implement SOL_ALG encryption support
 linux-user: Allow sendmsg() without IOV
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmPeguUSHGxhdXJlbnRA
 dml2aWVyLmV1AAoJEPMMOL0/L748tnQP/1A4eu33pLe4+tjBuDGt2zcGAVuz+wN9
 rcwN5BQgjILwfECfRsy9QIkC8+M496tLk4W7pNkW9x/GSpzBp9x0+066uUghsa1Q
 c0bFU0FM8xpywEXvOrz3LvEWaWqeBV/R+XYMqKFaiBQXf/5kmmteei9guH42L3gV
 a+d0s1cWT48TslTaga9ECbiPD9lK+yfW879+wRhex1/BetkJPzLU1hZB4vfC5YQo
 XagcmLWiseT4U8uCysikOgKQE4g2bv1oJXUuYjBxW15s5/llg8e57dEboO7MFEPK
 a9P3Hl1qiA5Ol3scF1I7WURmGP6UVfdhTYe1aKYHhKY7QVBVjbU7r/NkdQ3dR6Nv
 db58Lkurnrf5dMksZk8+25F/fvJT0nZpnbipunZejetNjrDVPk19XK5E6kJf91hk
 3W3vOeWMp4QjThpqghnlQ3gm2XfVmCGSMIOywTKZ4/M/TP28+9zY7GZqQXQXCBMy
 nJFahfVTCfiYaGAYGjlMe5CMOQ6tJ6lwxuTCl9O1X565ifMBNUj3rcte1FvO/i24
 Rk0/lQVO+tD9ImxHJrei0Y2C0xzo7V8kaB9+foAf6Ku91SY1X1FIOm81DEyAhK61
 Biv2zlNwUV0aCierrn3oLuDkviVaAg6FkLO9snPG+lQy2uxgyJJ2/Pv0OCZhniWI
 9WifjYZKAXDa
 =AcC6
 -----END PGP SIGNATURE-----

Merge tag 'linux-user-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging

linux-user branch pull request 20230204

Implement execveat()
un-parent OBJECT(cpu) when closing thread
Revert fix for glibc >= 2.36 sys/mount.h
Fix/update strace
move target_flat.h to target subdirs
Fix SO_ERROR return code of getsockopt()
Fix /proc/cpuinfo output for hppa
Add emulation for MADV_WIPEONFORK and MADV_KEEPONFORK in madvise()
Implement SOL_ALG encryption support
linux-user: Allow sendmsg() without IOV

# -----BEGIN PGP SIGNATURE-----
#
# iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmPeguUSHGxhdXJlbnRA
# dml2aWVyLmV1AAoJEPMMOL0/L748tnQP/1A4eu33pLe4+tjBuDGt2zcGAVuz+wN9
# rcwN5BQgjILwfECfRsy9QIkC8+M496tLk4W7pNkW9x/GSpzBp9x0+066uUghsa1Q
# c0bFU0FM8xpywEXvOrz3LvEWaWqeBV/R+XYMqKFaiBQXf/5kmmteei9guH42L3gV
# a+d0s1cWT48TslTaga9ECbiPD9lK+yfW879+wRhex1/BetkJPzLU1hZB4vfC5YQo
# XagcmLWiseT4U8uCysikOgKQE4g2bv1oJXUuYjBxW15s5/llg8e57dEboO7MFEPK
# a9P3Hl1qiA5Ol3scF1I7WURmGP6UVfdhTYe1aKYHhKY7QVBVjbU7r/NkdQ3dR6Nv
# db58Lkurnrf5dMksZk8+25F/fvJT0nZpnbipunZejetNjrDVPk19XK5E6kJf91hk
# 3W3vOeWMp4QjThpqghnlQ3gm2XfVmCGSMIOywTKZ4/M/TP28+9zY7GZqQXQXCBMy
# nJFahfVTCfiYaGAYGjlMe5CMOQ6tJ6lwxuTCl9O1X565ifMBNUj3rcte1FvO/i24
# Rk0/lQVO+tD9ImxHJrei0Y2C0xzo7V8kaB9+foAf6Ku91SY1X1FIOm81DEyAhK61
# Biv2zlNwUV0aCierrn3oLuDkviVaAg6FkLO9snPG+lQy2uxgyJJ2/Pv0OCZhniWI
# 9WifjYZKAXDa
# =AcC6
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 04 Feb 2023 16:08:05 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* tag 'linux-user-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu: (22 commits)
  linux-user: Allow sendmsg() without IOV
  linux-user: Implement SOL_ALG encryption support
  linux-user: Enhance strace output for various syscalls
  linux-user: Show 4th argument of rt_sigprocmask() in strace
  linux-user: Add emulation for MADV_WIPEONFORK and MADV_KEEPONFORK in madvise()
  linux-user: Improve strace output of personality() and sysinfo()
  linux-user: Fix /proc/cpuinfo output for hppa
  linux-user: Fix SO_ERROR return code of getsockopt()
  linux-user: move target_flat.h to target subdirs
  linux-user: Improve strace output of getgroups() and setgroups()
  linux-user: Add strace output for clock_getres_time64() and futex_time64()
  Revert "linux-user: fix compat with glibc >= 2.36 sys/mount.h"
  Revert "linux-user: add more compat ioctl definitions"
  linux-user: add more netlink protocol constants
  linux-user: fix strace build w/out munlockall
  linux-user: un-parent OBJECT(cpu) when closing thread
  linux-user: Add missing MAP_HUGETLB and MAP_STACK flags in strace
  linux-user/syscall: Implement execveat()
  linux-user/syscall: Extract do_execve() from do_syscall1()
  linux-user/strace: Add output for execveat() syscall
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2023-02-04 17:17:15 +00:00
commit ceabf6e500
11 changed files with 378 additions and 250 deletions

View File

@ -0,0 +1 @@
#include "../generic/target_flat.h"

View File

@ -0,0 +1 @@
#include "../generic/target_flat.h"

View File

@ -0,0 +1 @@
#include "../generic/target_flat.h"

View File

@ -0,0 +1 @@
#include "../generic/target_flat.h"

View File

@ -857,7 +857,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
return new_addr; return new_addr;
} }
static bool can_passthrough_madv_dontneed(abi_ulong start, abi_ulong end) static bool can_passthrough_madvise(abi_ulong start, abi_ulong end)
{ {
ulong addr; ulong addr;
@ -901,23 +901,53 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
return -TARGET_EINVAL; return -TARGET_EINVAL;
} }
/* Translate for some architectures which have different MADV_xxx values */
switch (advice) {
case TARGET_MADV_DONTNEED: /* alpha */
advice = MADV_DONTNEED;
break;
case TARGET_MADV_WIPEONFORK: /* parisc */
advice = MADV_WIPEONFORK;
break;
case TARGET_MADV_KEEPONFORK: /* parisc */
advice = MADV_KEEPONFORK;
break;
/* we do not care about the other MADV_xxx values yet */
}
/* /*
* A straight passthrough may not be safe because qemu sometimes turns * Most advice values are hints, so ignoring and returning success is ok.
* private file-backed mappings into anonymous mappings.
* *
* This is a hint, so ignoring and returning success is ok. * However, some advice values such as MADV_DONTNEED, MADV_WIPEONFORK and
* MADV_KEEPONFORK are not hints and need to be emulated.
* *
* This breaks MADV_DONTNEED, completely implementing which is quite * A straight passthrough for those may not be safe because qemu sometimes
* complicated. However, there is one low-hanging fruit: mappings that are * turns private file-backed mappings into anonymous mappings.
* known to have the same semantics in the host and the guest. In this case * can_passthrough_madvise() helps to check if a passthrough is possible by
* passthrough is safe, so do it. * comparing mappings that are known to have the same semantics in the host
* and the guest. In this case passthrough is safe.
*
* We pass through MADV_WIPEONFORK and MADV_KEEPONFORK if possible and
* return failure if not.
*
* MADV_DONTNEED is passed through as well, if possible.
* If passthrough isn't possible, we nevertheless (wrongly!) return
* success, which is broken but some userspace programs fail to work
* otherwise. Completely implementing such emulation is quite complicated
* though.
*/ */
mmap_lock(); mmap_lock();
if (advice == TARGET_MADV_DONTNEED && switch (advice) {
can_passthrough_madv_dontneed(start, end)) { case MADV_WIPEONFORK:
ret = get_errno(madvise(g2h_untagged(start), len, MADV_DONTNEED)); case MADV_KEEPONFORK:
if (ret == 0) { ret = -EINVAL;
page_reset_target_data(start, start + len); /* fall through */
case MADV_DONTNEED:
if (can_passthrough_madvise(start, end)) {
ret = get_errno(madvise(g2h_untagged(start), len, advice));
if ((advice == MADV_DONTNEED) && (ret == 0)) {
page_reset_target_data(start, start + len);
}
} }
} }
mmap_unlock(); mmap_unlock();

View File

@ -0,0 +1 @@
#include "../generic/target_flat.h"

View File

@ -506,21 +506,69 @@ print_socket_protocol(int domain, int type, int protocol)
case NETLINK_ROUTE: case NETLINK_ROUTE:
qemu_log("NETLINK_ROUTE"); qemu_log("NETLINK_ROUTE");
break; break;
case NETLINK_UNUSED:
qemu_log("NETLINK_UNUSED");
break;
case NETLINK_USERSOCK:
qemu_log("NETLINK_USERSOCK");
break;
case NETLINK_FIREWALL:
qemu_log("NETLINK_FIREWALL");
break;
case NETLINK_SOCK_DIAG:
qemu_log("NETLINK_SOCK_DIAG");
break;
case NETLINK_NFLOG:
qemu_log("NETLINK_NFLOG");
break;
case NETLINK_XFRM:
qemu_log("NETLINK_XFRM");
break;
case NETLINK_SELINUX:
qemu_log("NETLINK_SELINUX");
break;
case NETLINK_ISCSI:
qemu_log("NETLINK_ISCSI");
break;
case NETLINK_AUDIT: case NETLINK_AUDIT:
qemu_log("NETLINK_AUDIT"); qemu_log("NETLINK_AUDIT");
break; break;
case NETLINK_FIB_LOOKUP:
qemu_log("NETLINK_FIB_LOOKUP");
break;
case NETLINK_CONNECTOR:
qemu_log("NETLINK_CONNECTOR");
break;
case NETLINK_NETFILTER: case NETLINK_NETFILTER:
qemu_log("NETLINK_NETFILTER"); qemu_log("NETLINK_NETFILTER");
break; break;
case NETLINK_IP6_FW:
qemu_log("NETLINK_IP6_FW");
break;
case NETLINK_DNRTMSG:
qemu_log("NETLINK_DNRTMSG");
break;
case NETLINK_KOBJECT_UEVENT: case NETLINK_KOBJECT_UEVENT:
qemu_log("NETLINK_KOBJECT_UEVENT"); qemu_log("NETLINK_KOBJECT_UEVENT");
break; break;
case NETLINK_GENERIC:
qemu_log("NETLINK_GENERIC");
break;
case NETLINK_SCSITRANSPORT:
qemu_log("NETLINK_SCSITRANSPORT");
break;
case NETLINK_ECRYPTFS:
qemu_log("NETLINK_ECRYPTFS");
break;
case NETLINK_RDMA: case NETLINK_RDMA:
qemu_log("NETLINK_RDMA"); qemu_log("NETLINK_RDMA");
break; break;
case NETLINK_CRYPTO: case NETLINK_CRYPTO:
qemu_log("NETLINK_CRYPTO"); qemu_log("NETLINK_CRYPTO");
break; break;
case NETLINK_SMC:
qemu_log("NETLINK_SMC");
break;
default: default:
qemu_log("%d", protocol); qemu_log("%d", protocol);
break; break;
@ -616,38 +664,6 @@ print_semctl(CPUArchState *cpu_env, const struct syscallname *name,
} }
#endif #endif
static void
print_execve(CPUArchState *cpu_env, 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;
qemu_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))) {
qemu_log("\"%s\",", s);
unlock_user(s, arg_addr, 0);
}
}
qemu_log("NULL})");
}
#ifdef TARGET_NR_ipc #ifdef TARGET_NR_ipc
static void static void
print_ipc(CPUArchState *cpu_env, const struct syscallname *name, print_ipc(CPUArchState *cpu_env, const struct syscallname *name,
@ -945,7 +961,7 @@ print_syscall_ret_ioctl(CPUArchState *cpu_env, const struct syscallname *name,
} }
#endif #endif
UNUSED static struct flags access_flags[] = { UNUSED static const struct flags access_flags[] = {
FLAG_GENERIC(F_OK), FLAG_GENERIC(F_OK),
FLAG_GENERIC(R_OK), FLAG_GENERIC(R_OK),
FLAG_GENERIC(W_OK), FLAG_GENERIC(W_OK),
@ -953,7 +969,7 @@ UNUSED static struct flags access_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags at_file_flags[] = { UNUSED static const struct flags at_file_flags[] = {
#ifdef AT_EACCESS #ifdef AT_EACCESS
FLAG_GENERIC(AT_EACCESS), FLAG_GENERIC(AT_EACCESS),
#endif #endif
@ -963,14 +979,14 @@ UNUSED static struct flags at_file_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags unlinkat_flags[] = { UNUSED static const struct flags unlinkat_flags[] = {
#ifdef AT_REMOVEDIR #ifdef AT_REMOVEDIR
FLAG_GENERIC(AT_REMOVEDIR), FLAG_GENERIC(AT_REMOVEDIR),
#endif #endif
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags mode_flags[] = { UNUSED static const struct flags mode_flags[] = {
FLAG_GENERIC(S_IFSOCK), FLAG_GENERIC(S_IFSOCK),
FLAG_GENERIC(S_IFLNK), FLAG_GENERIC(S_IFLNK),
FLAG_GENERIC(S_IFREG), FLAG_GENERIC(S_IFREG),
@ -981,14 +997,14 @@ UNUSED static struct flags mode_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags open_access_flags[] = { UNUSED static const struct flags open_access_flags[] = {
FLAG_TARGET(O_RDONLY), FLAG_TARGET(O_RDONLY),
FLAG_TARGET(O_WRONLY), FLAG_TARGET(O_WRONLY),
FLAG_TARGET(O_RDWR), FLAG_TARGET(O_RDWR),
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags open_flags[] = { UNUSED static const struct flags open_flags[] = {
FLAG_TARGET(O_APPEND), FLAG_TARGET(O_APPEND),
FLAG_TARGET(O_CREAT), FLAG_TARGET(O_CREAT),
FLAG_TARGET(O_DIRECTORY), FLAG_TARGET(O_DIRECTORY),
@ -1019,7 +1035,7 @@ UNUSED static struct flags open_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags mount_flags[] = { UNUSED static const struct flags mount_flags[] = {
#ifdef MS_BIND #ifdef MS_BIND
FLAG_GENERIC(MS_BIND), FLAG_GENERIC(MS_BIND),
#endif #endif
@ -1044,7 +1060,7 @@ UNUSED static struct flags mount_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags umount2_flags[] = { UNUSED static const struct flags umount2_flags[] = {
#ifdef MNT_FORCE #ifdef MNT_FORCE
FLAG_GENERIC(MNT_FORCE), FLAG_GENERIC(MNT_FORCE),
#endif #endif
@ -1057,7 +1073,7 @@ UNUSED static struct flags umount2_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags mmap_prot_flags[] = { UNUSED static const struct flags mmap_prot_flags[] = {
FLAG_GENERIC(PROT_NONE), FLAG_GENERIC(PROT_NONE),
FLAG_GENERIC(PROT_EXEC), FLAG_GENERIC(PROT_EXEC),
FLAG_GENERIC(PROT_READ), FLAG_GENERIC(PROT_READ),
@ -1068,7 +1084,7 @@ UNUSED static struct flags mmap_prot_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags mmap_flags[] = { UNUSED static const struct flags mmap_flags[] = {
FLAG_TARGET(MAP_SHARED), FLAG_TARGET(MAP_SHARED),
FLAG_TARGET(MAP_PRIVATE), FLAG_TARGET(MAP_PRIVATE),
FLAG_TARGET(MAP_ANONYMOUS), FLAG_TARGET(MAP_ANONYMOUS),
@ -1089,10 +1105,12 @@ UNUSED static struct flags mmap_flags[] = {
#ifdef TARGET_MAP_UNINITIALIZED #ifdef TARGET_MAP_UNINITIALIZED
FLAG_TARGET(MAP_UNINITIALIZED), FLAG_TARGET(MAP_UNINITIALIZED),
#endif #endif
FLAG_TARGET(MAP_HUGETLB),
FLAG_TARGET(MAP_STACK),
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags clone_flags[] = { UNUSED static const struct flags clone_flags[] = {
FLAG_GENERIC(CLONE_VM), FLAG_GENERIC(CLONE_VM),
FLAG_GENERIC(CLONE_FS), FLAG_GENERIC(CLONE_FS),
FLAG_GENERIC(CLONE_FILES), FLAG_GENERIC(CLONE_FILES),
@ -1136,7 +1154,17 @@ UNUSED static struct flags clone_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags msg_flags[] = { UNUSED static const struct flags execveat_flags[] = {
#ifdef AT_EMPTY_PATH
FLAG_GENERIC(AT_EMPTY_PATH),
#endif
#ifdef AT_SYMLINK_NOFOLLOW
FLAG_GENERIC(AT_SYMLINK_NOFOLLOW),
#endif
FLAG_END,
};
UNUSED static const struct flags msg_flags[] = {
/* send */ /* send */
FLAG_GENERIC(MSG_CONFIRM), FLAG_GENERIC(MSG_CONFIRM),
FLAG_GENERIC(MSG_DONTROUTE), FLAG_GENERIC(MSG_DONTROUTE),
@ -1156,7 +1184,7 @@ UNUSED static struct flags msg_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags statx_flags[] = { UNUSED static const struct flags statx_flags[] = {
#ifdef AT_EMPTY_PATH #ifdef AT_EMPTY_PATH
FLAG_GENERIC(AT_EMPTY_PATH), FLAG_GENERIC(AT_EMPTY_PATH),
#endif #endif
@ -1178,7 +1206,7 @@ UNUSED static struct flags statx_flags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags statx_mask[] = { UNUSED static const struct flags statx_mask[] = {
/* This must come first, because it includes everything. */ /* This must come first, because it includes everything. */
#ifdef STATX_ALL #ifdef STATX_ALL
FLAG_GENERIC(STATX_ALL), FLAG_GENERIC(STATX_ALL),
@ -1226,7 +1254,7 @@ UNUSED static struct flags statx_mask[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags falloc_flags[] = { UNUSED static const struct flags falloc_flags[] = {
FLAG_GENERIC(FALLOC_FL_KEEP_SIZE), FLAG_GENERIC(FALLOC_FL_KEEP_SIZE),
FLAG_GENERIC(FALLOC_FL_PUNCH_HOLE), FLAG_GENERIC(FALLOC_FL_PUNCH_HOLE),
#ifdef FALLOC_FL_NO_HIDE_STALE #ifdef FALLOC_FL_NO_HIDE_STALE
@ -1246,7 +1274,7 @@ UNUSED static struct flags falloc_flags[] = {
#endif #endif
}; };
UNUSED static struct flags termios_iflags[] = { UNUSED static const struct flags termios_iflags[] = {
FLAG_TARGET(IGNBRK), FLAG_TARGET(IGNBRK),
FLAG_TARGET(BRKINT), FLAG_TARGET(BRKINT),
FLAG_TARGET(IGNPAR), FLAG_TARGET(IGNPAR),
@ -1265,7 +1293,7 @@ UNUSED static struct flags termios_iflags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags termios_oflags[] = { UNUSED static const struct flags termios_oflags[] = {
FLAG_TARGET(OPOST), FLAG_TARGET(OPOST),
FLAG_TARGET(OLCUC), FLAG_TARGET(OLCUC),
FLAG_TARGET(ONLCR), FLAG_TARGET(ONLCR),
@ -1349,7 +1377,7 @@ UNUSED static struct enums termios_cflags_CSIZE[] = {
ENUM_END, ENUM_END,
}; };
UNUSED static struct flags termios_cflags[] = { UNUSED static const struct flags termios_cflags[] = {
FLAG_TARGET(CSTOPB), FLAG_TARGET(CSTOPB),
FLAG_TARGET(CREAD), FLAG_TARGET(CREAD),
FLAG_TARGET(PARENB), FLAG_TARGET(PARENB),
@ -1360,7 +1388,7 @@ UNUSED static struct flags termios_cflags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags termios_lflags[] = { UNUSED static const struct flags termios_lflags[] = {
FLAG_TARGET(ISIG), FLAG_TARGET(ISIG),
FLAG_TARGET(ICANON), FLAG_TARGET(ICANON),
FLAG_TARGET(XCASE), FLAG_TARGET(XCASE),
@ -1380,7 +1408,8 @@ UNUSED static struct flags termios_lflags[] = {
FLAG_END, FLAG_END,
}; };
UNUSED static struct flags mlockall_flags[] = { #ifdef TARGET_NR_mlockall
static const struct flags mlockall_flags[] = {
FLAG_TARGET(MCL_CURRENT), FLAG_TARGET(MCL_CURRENT),
FLAG_TARGET(MCL_FUTURE), FLAG_TARGET(MCL_FUTURE),
#ifdef MCL_ONFAULT #ifdef MCL_ONFAULT
@ -1388,6 +1417,7 @@ UNUSED static struct flags mlockall_flags[] = {
#endif #endif
FLAG_END, FLAG_END,
}; };
#endif
/* IDs of the various system clocks */ /* IDs of the various system clocks */
#define TARGET_CLOCK_REALTIME 0 #define TARGET_CLOCK_REALTIME 0
@ -1969,6 +1999,58 @@ print_execv(CPUArchState *cpu_env, const struct syscallname *name,
} }
#endif #endif
static void
print_execve_argv(abi_long argv, int last)
{
abi_ulong arg_ptr_addr;
char *s;
qemu_log("{");
for (arg_ptr_addr = argv; ; 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;
}
s = lock_user_string(arg_addr);
if (s) {
qemu_log("\"%s\",", s);
unlock_user(s, arg_addr, 0);
}
}
qemu_log("NULL}%s", get_comma(last));
}
static void
print_execve(CPUArchState *cpu_env, 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);
print_string(arg1, 0);
print_execve_argv(arg2, 1);
print_syscall_epilogue(name);
}
static void
print_execveat(CPUArchState *cpu_env, 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);
print_at_dirfd(arg1, 0);
print_string(arg2, 0);
print_execve_argv(arg3, 0);
print_flags(execveat_flags, arg5, 1);
print_syscall_epilogue(name);
}
#if defined(TARGET_NR_faccessat) || defined(TARGET_NR_faccessat2) #if defined(TARGET_NR_faccessat) || defined(TARGET_NR_faccessat2)
static void static void
print_faccessat(CPUArchState *cpu_env, const struct syscallname *name, print_faccessat(CPUArchState *cpu_env, const struct syscallname *name,
@ -3142,7 +3224,8 @@ print_rt_sigprocmask(CPUArchState *cpu_env, const struct syscallname *name,
} }
qemu_log("%s,", how); qemu_log("%s,", how);
print_pointer(arg1, 0); print_pointer(arg1, 0);
print_pointer(arg2, 1); print_pointer(arg2, 0);
print_raw_param("%u", arg3, 1);
print_syscall_epilogue(name); print_syscall_epilogue(name);
} }
#endif #endif

View File

@ -86,6 +86,9 @@
{ TARGET_NR_clock_getres, "clock_getres" , NULL, print_clock_getres, { TARGET_NR_clock_getres, "clock_getres" , NULL, print_clock_getres,
print_syscall_ret_clock_getres }, print_syscall_ret_clock_getres },
#endif #endif
#ifdef TARGET_NR_clock_getres_time64
{ TARGET_NR_clock_getres_time64, "clock_getres_time64" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_clock_gettime #ifdef TARGET_NR_clock_gettime
{ TARGET_NR_clock_gettime, "clock_gettime" , NULL, print_clock_gettime, { TARGET_NR_clock_gettime, "clock_gettime" , NULL, print_clock_gettime,
print_syscall_ret_clock_gettime }, print_syscall_ret_clock_gettime },
@ -164,7 +167,7 @@
{ TARGET_NR_execve, "execve" , NULL, print_execve, NULL }, { TARGET_NR_execve, "execve" , NULL, print_execve, NULL },
#endif #endif
#ifdef TARGET_NR_execveat #ifdef TARGET_NR_execveat
{ TARGET_NR_execveat, "execveat" , NULL, NULL, NULL }, { TARGET_NR_execveat, "execveat" , NULL, print_execveat, NULL },
#endif #endif
#ifdef TARGET_NR_exec_with_loader #ifdef TARGET_NR_exec_with_loader
{ TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL }, { TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL },
@ -275,6 +278,9 @@
#ifdef TARGET_NR_futex #ifdef TARGET_NR_futex
{ TARGET_NR_futex, "futex" , NULL, print_futex, NULL }, { TARGET_NR_futex, "futex" , NULL, print_futex, NULL },
#endif #endif
#ifdef TARGET_NR_futex_time64
{ TARGET_NR_futex_time64, "futex_time64" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_futimesat #ifdef TARGET_NR_futimesat
{ TARGET_NR_futimesat, "futimesat" , NULL, print_futimesat, NULL }, { TARGET_NR_futimesat, "futimesat" , NULL, print_futimesat, NULL },
#endif #endif
@ -315,10 +321,10 @@
{ TARGET_NR_getgid32, "getgid32" , NULL, NULL, NULL }, { TARGET_NR_getgid32, "getgid32" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getgroups #ifdef TARGET_NR_getgroups
{ TARGET_NR_getgroups, "getgroups" , NULL, NULL, NULL }, { TARGET_NR_getgroups, "getgroups" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getgroups32 #ifdef TARGET_NR_getgroups32
{ TARGET_NR_getgroups32, "getgroups32" , NULL, NULL, NULL }, { TARGET_NR_getgroups32, "getgroups32" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_gethostname #ifdef TARGET_NR_gethostname
{ TARGET_NR_gethostname, "gethostname" , NULL, NULL, NULL }, { TARGET_NR_gethostname, "gethostname" , NULL, NULL, NULL },
@ -337,7 +343,7 @@
{ TARGET_NR_getpagesize, "getpagesize" , NULL, NULL, NULL }, { TARGET_NR_getpagesize, "getpagesize" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getpeername #ifdef TARGET_NR_getpeername
{ TARGET_NR_getpeername, "getpeername" , NULL, NULL, NULL }, { TARGET_NR_getpeername, "getpeername" , "%s(%d,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getpgid #ifdef TARGET_NR_getpgid
{ TARGET_NR_getpgid, "getpgid" , "%s(%u)", NULL, NULL }, { TARGET_NR_getpgid, "getpgid" , "%s(%u)", NULL, NULL },
@ -361,19 +367,19 @@
{ TARGET_NR_getrandom, "getrandom", "%s(%p,%u,%u)", NULL, NULL }, { TARGET_NR_getrandom, "getrandom", "%s(%p,%u,%u)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getresgid #ifdef TARGET_NR_getresgid
{ TARGET_NR_getresgid, "getresgid" , NULL, NULL, NULL }, { TARGET_NR_getresgid, "getresgid" , "%s(%p,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getresgid32 #ifdef TARGET_NR_getresgid32
{ TARGET_NR_getresgid32, "getresgid32" , NULL, NULL, NULL }, { TARGET_NR_getresgid32, "getresgid32" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getresuid #ifdef TARGET_NR_getresuid
{ TARGET_NR_getresuid, "getresuid" , NULL, NULL, NULL }, { TARGET_NR_getresuid, "getresuid" , "%s(%p,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getresuid32 #ifdef TARGET_NR_getresuid32
{ TARGET_NR_getresuid32, "getresuid32" , NULL, NULL, NULL }, { TARGET_NR_getresuid32, "getresuid32" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getrlimit #ifdef TARGET_NR_getrlimit
{ TARGET_NR_getrlimit, "getrlimit" , NULL, NULL, NULL }, { TARGET_NR_getrlimit, "getrlimit" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_get_robust_list #ifdef TARGET_NR_get_robust_list
{ TARGET_NR_get_robust_list, "get_robust_list" , NULL, NULL, NULL }, { TARGET_NR_get_robust_list, "get_robust_list" , NULL, NULL, NULL },
@ -385,10 +391,10 @@
{ TARGET_NR_getsid, "getsid" , "%s(%d)", NULL, NULL }, { TARGET_NR_getsid, "getsid" , "%s(%d)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getsockname #ifdef TARGET_NR_getsockname
{ TARGET_NR_getsockname, "getsockname" , NULL, NULL, NULL }, { TARGET_NR_getsockname, "getsockname" , "%s(%d,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_getsockopt #ifdef TARGET_NR_getsockopt
{ TARGET_NR_getsockopt, "getsockopt" , NULL, NULL, NULL }, { TARGET_NR_getsockopt, "getsockopt" , "%s(%d,%d,%d,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_get_thread_area #ifdef TARGET_NR_get_thread_area
#if defined(TARGET_I386) && defined(TARGET_ABI32) #if defined(TARGET_I386) && defined(TARGET_ABI32)
@ -1043,7 +1049,8 @@
{ TARGET_NR_perfctr, "perfctr" , NULL, NULL, NULL }, { TARGET_NR_perfctr, "perfctr" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_personality #ifdef TARGET_NR_personality
{ TARGET_NR_personality, "personality" , NULL, NULL, NULL }, { TARGET_NR_personality, "personality" , "%s(0x"TARGET_ABI_FMT_lx")", NULL,
print_syscall_ret_addr },
#endif #endif
#ifdef TARGET_NR_pipe #ifdef TARGET_NR_pipe
{ TARGET_NR_pipe, "pipe" , NULL, NULL, NULL }, { TARGET_NR_pipe, "pipe" , NULL, NULL, NULL },
@ -1052,10 +1059,10 @@
{ TARGET_NR_pivot_root, "pivot_root" , NULL, NULL, NULL }, { TARGET_NR_pivot_root, "pivot_root" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_poll #ifdef TARGET_NR_poll
{ TARGET_NR_poll, "poll" , NULL, NULL, NULL }, { TARGET_NR_poll, "poll" , "%s(%p,%u,%d)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_ppoll #ifdef TARGET_NR_ppoll
{ TARGET_NR_ppoll, "ppoll" , NULL, NULL, NULL }, { TARGET_NR_ppoll, "ppoll" , "%s(%p,%u,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_prctl #ifdef TARGET_NR_prctl
{ TARGET_NR_prctl, "prctl" , NULL, NULL, NULL }, { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL },
@ -1124,7 +1131,7 @@
{ TARGET_NR_reboot, "reboot" , NULL, NULL, NULL }, { TARGET_NR_reboot, "reboot" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_recv #ifdef TARGET_NR_recv
{ TARGET_NR_recv, "recv" , NULL, NULL, NULL }, { TARGET_NR_recv, "recv" , "%s(%d,%p,%u,%d)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_recvfrom #ifdef TARGET_NR_recvfrom
{ TARGET_NR_recvfrom, "recvfrom" , NULL, NULL, NULL }, { TARGET_NR_recvfrom, "recvfrom" , NULL, NULL, NULL },
@ -1184,7 +1191,7 @@
{ TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, print_rt_sigqueueinfo, NULL }, { TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, print_rt_sigqueueinfo, NULL },
#endif #endif
#ifdef TARGET_NR_rt_sigreturn #ifdef TARGET_NR_rt_sigreturn
{ TARGET_NR_rt_sigreturn, "rt_sigreturn" , NULL, NULL, NULL }, { TARGET_NR_rt_sigreturn, "rt_sigreturn" , "%s(%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_rt_sigsuspend #ifdef TARGET_NR_rt_sigsuspend
{ TARGET_NR_rt_sigsuspend, "rt_sigsuspend" , NULL, NULL, NULL }, { TARGET_NR_rt_sigsuspend, "rt_sigsuspend" , NULL, NULL, NULL },
@ -1196,16 +1203,19 @@
{ TARGET_NR_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" , NULL, print_rt_tgsigqueueinfo, NULL }, { TARGET_NR_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" , NULL, print_rt_tgsigqueueinfo, NULL },
#endif #endif
#ifdef TARGET_NR_sched_getaffinity #ifdef TARGET_NR_sched_getaffinity
{ TARGET_NR_sched_getaffinity, "sched_getaffinity" , NULL, NULL, NULL }, { TARGET_NR_sched_getaffinity, "sched_getaffinity" , "%s(%d,%u,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sched_get_affinity #ifdef TARGET_NR_sched_get_affinity
{ TARGET_NR_sched_get_affinity, "sched_get_affinity" , NULL, NULL, NULL }, { TARGET_NR_sched_get_affinity, "sched_get_affinity" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sched_getattr #ifdef TARGET_NR_sched_getattr
{ TARGET_NR_sched_getattr, "sched_getattr" , NULL, NULL, NULL }, { TARGET_NR_sched_getattr, "sched_getattr" , "%s(%d,%p,%u,%u)", NULL, NULL },
#endif
#ifdef TARGET_NR_sched_setattr
{ TARGET_NR_sched_setattr, "sched_setattr" , "%s(%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sched_getparam #ifdef TARGET_NR_sched_getparam
{ TARGET_NR_sched_getparam, "sched_getparam" , NULL, NULL, NULL }, { TARGET_NR_sched_getparam, "sched_getparam" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sched_get_priority_max #ifdef TARGET_NR_sched_get_priority_max
{ TARGET_NR_sched_get_priority_max, "sched_get_priority_max" , NULL, NULL, NULL }, { TARGET_NR_sched_get_priority_max, "sched_get_priority_max" , NULL, NULL, NULL },
@ -1220,7 +1230,7 @@
{ TARGET_NR_sched_rr_get_interval, "sched_rr_get_interval" , NULL, NULL, NULL }, { TARGET_NR_sched_rr_get_interval, "sched_rr_get_interval" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sched_setaffinity #ifdef TARGET_NR_sched_setaffinity
{ TARGET_NR_sched_setaffinity, "sched_setaffinity" , NULL, NULL, NULL }, { TARGET_NR_sched_setaffinity, "sched_setaffinity" , "%s(%d,%u,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sched_setatt #ifdef TARGET_NR_sched_setatt
{ TARGET_NR_sched_setatt, "sched_setatt" , NULL, NULL, NULL }, { TARGET_NR_sched_setatt, "sched_setatt" , NULL, NULL, NULL },
@ -1298,10 +1308,10 @@
{ TARGET_NR_setgid32, "setgid32" , "%s(%u)", NULL, NULL }, { TARGET_NR_setgid32, "setgid32" , "%s(%u)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_setgroups #ifdef TARGET_NR_setgroups
{ TARGET_NR_setgroups, "setgroups" , NULL, NULL, NULL }, { TARGET_NR_setgroups, "setgroups" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_setgroups32 #ifdef TARGET_NR_setgroups32
{ TARGET_NR_setgroups32, "setgroups32" , NULL, NULL, NULL }, { TARGET_NR_setgroups32, "setgroups32" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sethae #ifdef TARGET_NR_sethae
{ TARGET_NR_sethae, "sethae" , NULL, NULL, NULL }, { TARGET_NR_sethae, "sethae" , NULL, NULL, NULL },
@ -1353,23 +1363,23 @@
{ TARGET_NR_setreuid32, "setreuid32" , "%s(%u,%u)", NULL, NULL }, { TARGET_NR_setreuid32, "setreuid32" , "%s(%u,%u)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_setrlimit #ifdef TARGET_NR_setrlimit
{ TARGET_NR_setrlimit, "setrlimit" , NULL, NULL, NULL }, { TARGET_NR_setrlimit, "setrlimit" , "%s(%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_set_robust_list #ifdef TARGET_NR_set_robust_list
{ TARGET_NR_set_robust_list, "set_robust_list" , NULL, NULL, NULL }, { TARGET_NR_set_robust_list, "set_robust_list" , "%s(%p,%u)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_setsid #ifdef TARGET_NR_setsid
{ TARGET_NR_setsid, "setsid" , "%s()", NULL, NULL }, { TARGET_NR_setsid, "setsid" , "%s()", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_setsockopt #ifdef TARGET_NR_setsockopt
{ TARGET_NR_setsockopt, "setsockopt" , NULL, NULL, NULL }, { TARGET_NR_setsockopt, "setsockopt" , "%s(%d,%d,%d,%p,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_set_thread_area #ifdef TARGET_NR_set_thread_area
{ TARGET_NR_set_thread_area, "set_thread_area", "%s(0x"TARGET_ABI_FMT_lx")", { TARGET_NR_set_thread_area, "set_thread_area", "%s(0x"TARGET_ABI_FMT_lx")",
NULL, NULL }, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_set_tid_address #ifdef TARGET_NR_set_tid_address
{ TARGET_NR_set_tid_address, "set_tid_address" , NULL, NULL, NULL }, { TARGET_NR_set_tid_address, "set_tid_address" , "%s(%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_settimeofday #ifdef TARGET_NR_settimeofday
{ TARGET_NR_settimeofday, "settimeofday" , NULL, print_settimeofday, NULL }, { TARGET_NR_settimeofday, "settimeofday" , NULL, print_settimeofday, NULL },
@ -1498,7 +1508,7 @@
{ TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL }, { TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sysinfo #ifdef TARGET_NR_sysinfo
{ TARGET_NR_sysinfo, "sysinfo" , NULL, NULL, NULL }, { TARGET_NR_sysinfo, "sysinfo" , "%s(%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_sys_kexec_load #ifdef TARGET_NR_sys_kexec_load
{ TARGET_NR_sys_kexec_load, "sys_kexec_load" , NULL, NULL, NULL }, { TARGET_NR_sys_kexec_load, "sys_kexec_load" , NULL, NULL, NULL },
@ -1648,7 +1658,7 @@
{ TARGET_NR_vserver, "vserver" , NULL, NULL, NULL }, { TARGET_NR_vserver, "vserver" , NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_wait4 #ifdef TARGET_NR_wait4
{ TARGET_NR_wait4, "wait4" , NULL, NULL, NULL }, { TARGET_NR_wait4, "wait4" , "%s(%d,%p,%d,%p)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_waitid #ifdef TARGET_NR_waitid
{ TARGET_NR_waitid, "waitid" , "%s(%#x,%d,%p,%#x)", NULL, NULL }, { TARGET_NR_waitid, "waitid" , "%s(%#x,%d,%p,%#x)", NULL, NULL },
@ -1672,7 +1682,7 @@
{ TARGET_NR_sync_file_range2, "sync_file_range2", NULL, NULL, NULL }, { TARGET_NR_sync_file_range2, "sync_file_range2", NULL, NULL, NULL },
#endif #endif
#ifdef TARGET_NR_pipe2 #ifdef TARGET_NR_pipe2
{ TARGET_NR_pipe2, "pipe2", NULL, NULL, NULL }, { TARGET_NR_pipe2, "pipe2", "%s(%p,%d)", NULL, NULL },
#endif #endif
#ifdef TARGET_NR_pidfd_open #ifdef TARGET_NR_pidfd_open
{ TARGET_NR_pidfd_open, "pidfd_open", "%s(%d,%u)", NULL, NULL }, { TARGET_NR_pidfd_open, "pidfd_open", "%s(%d,%u)", NULL, NULL },

View File

@ -95,50 +95,7 @@
#include <linux/soundcard.h> #include <linux/soundcard.h>
#include <linux/kd.h> #include <linux/kd.h>
#include <linux/mtio.h> #include <linux/mtio.h>
#ifdef HAVE_SYS_MOUNT_FSCONFIG
/*
* glibc >= 2.36 linux/mount.h conflicts with sys/mount.h,
* which in turn prevents use of linux/fs.h. So we have to
* define the constants ourselves for now.
*/
#define FS_IOC_GETFLAGS _IOR('f', 1, long)
#define FS_IOC_SETFLAGS _IOW('f', 2, long)
#define FS_IOC_GETVERSION _IOR('v', 1, long)
#define FS_IOC_SETVERSION _IOW('v', 2, long)
#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
#define FS_IOC32_GETFLAGS _IOR('f', 1, int)
#define FS_IOC32_SETFLAGS _IOW('f', 2, int)
#define FS_IOC32_GETVERSION _IOR('v', 1, int)
#define FS_IOC32_SETVERSION _IOW('v', 2, int)
#define BLKGETSIZE64 _IOR(0x12,114,size_t)
#define BLKDISCARD _IO(0x12,119)
#define BLKIOMIN _IO(0x12,120)
#define BLKIOOPT _IO(0x12,121)
#define BLKALIGNOFF _IO(0x12,122)
#define BLKPBSZGET _IO(0x12,123)
#define BLKDISCARDZEROES _IO(0x12,124)
#define BLKSECDISCARD _IO(0x12,125)
#define BLKROTATIONAL _IO(0x12,126)
#define BLKZEROOUT _IO(0x12,127)
#define FIBMAP _IO(0x00,1)
#define FIGETBSZ _IO(0x00,2)
struct file_clone_range {
__s64 src_fd;
__u64 src_offset;
__u64 src_length;
__u64 dest_offset;
};
#define FICLONE _IOW(0x94, 9, int)
#define FICLONERANGE _IOW(0x94, 13, struct file_clone_range)
#else
#include <linux/fs.h> #include <linux/fs.h>
#endif
#include <linux/fd.h> #include <linux/fd.h>
#if defined(CONFIG_FIEMAP) #if defined(CONFIG_FIEMAP)
#include <linux/fiemap.h> #include <linux/fiemap.h>
@ -696,7 +653,8 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
#endif #endif
safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \ safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
int, options, struct rusage *, rusage) 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)
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \ #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64) defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \ safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
@ -1871,6 +1829,14 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
__get_user(cred->pid, &target_cred->pid); __get_user(cred->pid, &target_cred->pid);
__get_user(cred->uid, &target_cred->uid); __get_user(cred->uid, &target_cred->uid);
__get_user(cred->gid, &target_cred->gid); __get_user(cred->gid, &target_cred->gid);
} else if (cmsg->cmsg_level == SOL_ALG) {
uint32_t *dst = (uint32_t *)data;
memcpy(dst, target_data, len);
/* fix endianess of first 32-bit word */
if (len >= sizeof(uint32_t)) {
*dst = tswap32(*dst);
}
} else { } else {
qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n", qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
cmsg->cmsg_level, cmsg->cmsg_type); cmsg->cmsg_level, cmsg->cmsg_type);
@ -2800,8 +2766,13 @@ get_timeout:
ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
if (ret < 0) if (ret < 0)
return ret; return ret;
if (optname == SO_TYPE) { switch (optname) {
case SO_TYPE:
val = host_to_target_sock_type(val); val = host_to_target_sock_type(val);
break;
case SO_ERROR:
val = host_to_target_errno(val);
break;
} }
if (len > lv) if (len > lv)
len = lv; len = lv;
@ -3322,7 +3293,10 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
target_vec, count, send); target_vec, count, send);
if (vec == NULL) { if (vec == NULL) {
ret = -host_to_target_errno(errno); ret = -host_to_target_errno(errno);
goto out2; /* allow sending packet without any iov, e.g. with MSG_MORE flag */
if (!send || ret) {
goto out2;
}
} }
msg.msg_iovlen = count; msg.msg_iovlen = count;
msg.msg_iov = vec; msg.msg_iov = vec;
@ -3374,7 +3348,9 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
} }
out: out:
unlock_iovec(vec, target_vec, count, !send); if (vec) {
unlock_iovec(vec, target_vec, count, !send);
}
out2: out2:
return ret; return ret;
} }
@ -8269,11 +8245,17 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
#if defined(TARGET_HPPA) #if defined(TARGET_HPPA)
static int open_cpuinfo(CPUArchState *cpu_env, int fd) static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{ {
dprintf(fd, "cpu family\t: PA-RISC 1.1e\n"); int i, num_cpus;
dprintf(fd, "cpu\t\t: PA7300LC (PCX-L2)\n");
dprintf(fd, "capabilities\t: os32\n"); num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
dprintf(fd, "model\t\t: 9000/778/B160L\n"); for (i = 0; i < num_cpus; i++) {
dprintf(fd, "model name\t: Merlin L2 160 QEMU (9000/778/B160L)\n"); dprintf(fd, "processor\t: %d\n", i);
dprintf(fd, "cpu family\t: PA-RISC 1.1e\n");
dprintf(fd, "cpu\t\t: PA7300LC (PCX-L2)\n");
dprintf(fd, "capabilities\t: os32\n");
dprintf(fd, "model\t\t: 9000/778/B160L - "
"Merlin L2 160 QEMU (9000/778/B160L)\n\n");
}
return 0; return 0;
} }
#endif #endif
@ -8357,6 +8339,119 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int
return safe_openat(dirfd, path(pathname), flags, mode); return safe_openat(dirfd, path(pathname), flags, mode);
} }
static int do_execveat(CPUArchState *cpu_env, int dirfd,
abi_long pathname, abi_long guest_argp,
abi_long guest_envp, int flags)
{
int ret;
char **argp, **envp;
int argc, envc;
abi_ulong gp;
abi_ulong addr;
char **q;
void *p;
argc = 0;
for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
if (get_user_ual(addr, gp)) {
return -TARGET_EFAULT;
}
if (!addr) {
break;
}
argc++;
}
envc = 0;
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;
}
*q = lock_user_string(addr);
if (!*q) {
goto execve_efault;
}
}
*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;
}
*q = lock_user_string(addr);
if (!*q) {
goto execve_efault;
}
}
*q = NULL;
/*
* 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.
*/
p = lock_user_string(pathname);
if (!p) {
goto execve_efault;
}
if (is_proc_myself(p, "exe")) {
ret = get_errno(safe_execveat(dirfd, exec_path, argp, envp, flags));
} else {
ret = get_errno(safe_execveat(dirfd, p, argp, envp, flags));
}
unlock_user(p, pathname, 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;
}
#define TIMER_MAGIC 0x0caf0000 #define TIMER_MAGIC 0x0caf0000
#define TIMER_MAGIC_MASK 0xffff0000 #define TIMER_MAGIC_MASK 0xffff0000
@ -8642,7 +8737,13 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
if (CPU_NEXT(first_cpu)) { if (CPU_NEXT(first_cpu)) {
TaskState *ts = cpu->opaque; TaskState *ts = cpu->opaque;
object_property_set_bool(OBJECT(cpu), "realized", false, NULL); if (ts->child_tidptr) {
put_user_u32(0, ts->child_tidptr);
do_sys_futex(g2h(cpu, ts->child_tidptr),
FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
}
object_unparent(OBJECT(cpu));
object_unref(OBJECT(cpu)); object_unref(OBJECT(cpu));
/* /*
* At this point the CPU should be unrealized and removed * At this point the CPU should be unrealized and removed
@ -8652,11 +8753,6 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
pthread_mutex_unlock(&clone_lock); pthread_mutex_unlock(&clone_lock);
if (ts->child_tidptr) {
put_user_u32(0, ts->child_tidptr);
do_sys_futex(g2h(cpu, ts->child_tidptr),
FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
}
thread_cpu = NULL; thread_cpu = NULL;
g_free(ts); g_free(ts);
rcu_unregister_thread(); rcu_unregister_thread();
@ -8866,104 +8962,10 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
unlock_user(p, arg2, 0); unlock_user(p, arg2, 0);
return ret; return ret;
#endif #endif
case TARGET_NR_execveat:
return do_execveat(cpu_env, arg1, arg2, arg3, arg4, arg5);
case TARGET_NR_execve: case TARGET_NR_execve:
{ return do_execveat(cpu_env, AT_FDCWD, arg1, arg2, arg3, 0);
char **argp, **envp;
int argc, envc;
abi_ulong gp;
abi_ulong guest_argp;
abi_ulong guest_envp;
abi_ulong addr;
char **q;
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;
}
*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;
}
*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.
*/
if (is_proc_myself(p, "exe")) {
ret = get_errno(safe_execve(exec_path, argp, envp));
} else {
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: case TARGET_NR_chdir:
if (!(p = lock_user_string(arg1))) if (!(p = lock_user_string(arg1)))
return -TARGET_EFAULT; return -TARGET_EFAULT;

View File

@ -2040,8 +2040,6 @@ config_host_data.set('HAVE_OPTRESET',
cc.has_header_symbol('getopt.h', 'optreset')) cc.has_header_symbol('getopt.h', 'optreset'))
config_host_data.set('HAVE_IPPROTO_MPTCP', config_host_data.set('HAVE_IPPROTO_MPTCP',
cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
config_host_data.set('HAVE_SYS_MOUNT_FSCONFIG',
cc.has_header_symbol('sys/mount.h', 'FSCONFIG_SET_FLAG'))
# has_member # has_member
config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',