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:
commit
ceabf6e500
1
linux-user/aarch64/target_flat.h
Normal file
1
linux-user/aarch64/target_flat.h
Normal file
@ -0,0 +1 @@
|
||||
#include "../generic/target_flat.h"
|
1
linux-user/arm/target_flat.h
Normal file
1
linux-user/arm/target_flat.h
Normal file
@ -0,0 +1 @@
|
||||
#include "../generic/target_flat.h"
|
1
linux-user/m68k/target_flat.h
Normal file
1
linux-user/m68k/target_flat.h
Normal file
@ -0,0 +1 @@
|
||||
#include "../generic/target_flat.h"
|
1
linux-user/microblaze/target_flat.h
Normal file
1
linux-user/microblaze/target_flat.h
Normal file
@ -0,0 +1 @@
|
||||
#include "../generic/target_flat.h"
|
@ -857,7 +857,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
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;
|
||||
|
||||
@ -901,23 +901,53 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
|
||||
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
|
||||
* private file-backed mappings into anonymous mappings.
|
||||
* Most advice values are hints, so ignoring and returning success is ok.
|
||||
*
|
||||
* 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
|
||||
* complicated. However, there is one low-hanging fruit: mappings that are
|
||||
* known to have the same semantics in the host and the guest. In this case
|
||||
* passthrough is safe, so do it.
|
||||
* A straight passthrough for those may not be safe because qemu sometimes
|
||||
* turns private file-backed mappings into anonymous mappings.
|
||||
* can_passthrough_madvise() helps to check if a passthrough is possible by
|
||||
* 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();
|
||||
if (advice == TARGET_MADV_DONTNEED &&
|
||||
can_passthrough_madv_dontneed(start, end)) {
|
||||
ret = get_errno(madvise(g2h_untagged(start), len, MADV_DONTNEED));
|
||||
if (ret == 0) {
|
||||
page_reset_target_data(start, start + len);
|
||||
switch (advice) {
|
||||
case MADV_WIPEONFORK:
|
||||
case MADV_KEEPONFORK:
|
||||
ret = -EINVAL;
|
||||
/* 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();
|
||||
|
1
linux-user/sh4/target_flat.h
Normal file
1
linux-user/sh4/target_flat.h
Normal file
@ -0,0 +1 @@
|
||||
#include "../generic/target_flat.h"
|
@ -506,21 +506,69 @@ print_socket_protocol(int domain, int type, int protocol)
|
||||
case NETLINK_ROUTE:
|
||||
qemu_log("NETLINK_ROUTE");
|
||||
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:
|
||||
qemu_log("NETLINK_AUDIT");
|
||||
break;
|
||||
case NETLINK_FIB_LOOKUP:
|
||||
qemu_log("NETLINK_FIB_LOOKUP");
|
||||
break;
|
||||
case NETLINK_CONNECTOR:
|
||||
qemu_log("NETLINK_CONNECTOR");
|
||||
break;
|
||||
case NETLINK_NETFILTER:
|
||||
qemu_log("NETLINK_NETFILTER");
|
||||
break;
|
||||
case NETLINK_IP6_FW:
|
||||
qemu_log("NETLINK_IP6_FW");
|
||||
break;
|
||||
case NETLINK_DNRTMSG:
|
||||
qemu_log("NETLINK_DNRTMSG");
|
||||
break;
|
||||
case NETLINK_KOBJECT_UEVENT:
|
||||
qemu_log("NETLINK_KOBJECT_UEVENT");
|
||||
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:
|
||||
qemu_log("NETLINK_RDMA");
|
||||
break;
|
||||
case NETLINK_CRYPTO:
|
||||
qemu_log("NETLINK_CRYPTO");
|
||||
break;
|
||||
case NETLINK_SMC:
|
||||
qemu_log("NETLINK_SMC");
|
||||
break;
|
||||
default:
|
||||
qemu_log("%d", protocol);
|
||||
break;
|
||||
@ -616,38 +664,6 @@ print_semctl(CPUArchState *cpu_env, const struct syscallname *name,
|
||||
}
|
||||
#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
|
||||
static void
|
||||
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
|
||||
|
||||
UNUSED static struct flags access_flags[] = {
|
||||
UNUSED static const struct flags access_flags[] = {
|
||||
FLAG_GENERIC(F_OK),
|
||||
FLAG_GENERIC(R_OK),
|
||||
FLAG_GENERIC(W_OK),
|
||||
@ -953,7 +969,7 @@ UNUSED static struct flags access_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags at_file_flags[] = {
|
||||
UNUSED static const struct flags at_file_flags[] = {
|
||||
#ifdef AT_EACCESS
|
||||
FLAG_GENERIC(AT_EACCESS),
|
||||
#endif
|
||||
@ -963,14 +979,14 @@ UNUSED static struct flags at_file_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags unlinkat_flags[] = {
|
||||
UNUSED static const struct flags unlinkat_flags[] = {
|
||||
#ifdef AT_REMOVEDIR
|
||||
FLAG_GENERIC(AT_REMOVEDIR),
|
||||
#endif
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags mode_flags[] = {
|
||||
UNUSED static const struct flags mode_flags[] = {
|
||||
FLAG_GENERIC(S_IFSOCK),
|
||||
FLAG_GENERIC(S_IFLNK),
|
||||
FLAG_GENERIC(S_IFREG),
|
||||
@ -981,14 +997,14 @@ UNUSED static struct flags mode_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags open_access_flags[] = {
|
||||
UNUSED static const struct flags open_access_flags[] = {
|
||||
FLAG_TARGET(O_RDONLY),
|
||||
FLAG_TARGET(O_WRONLY),
|
||||
FLAG_TARGET(O_RDWR),
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags open_flags[] = {
|
||||
UNUSED static const struct flags open_flags[] = {
|
||||
FLAG_TARGET(O_APPEND),
|
||||
FLAG_TARGET(O_CREAT),
|
||||
FLAG_TARGET(O_DIRECTORY),
|
||||
@ -1019,7 +1035,7 @@ UNUSED static struct flags open_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags mount_flags[] = {
|
||||
UNUSED static const struct flags mount_flags[] = {
|
||||
#ifdef MS_BIND
|
||||
FLAG_GENERIC(MS_BIND),
|
||||
#endif
|
||||
@ -1044,7 +1060,7 @@ UNUSED static struct flags mount_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags umount2_flags[] = {
|
||||
UNUSED static const struct flags umount2_flags[] = {
|
||||
#ifdef MNT_FORCE
|
||||
FLAG_GENERIC(MNT_FORCE),
|
||||
#endif
|
||||
@ -1057,7 +1073,7 @@ UNUSED static struct flags umount2_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags mmap_prot_flags[] = {
|
||||
UNUSED static const struct flags mmap_prot_flags[] = {
|
||||
FLAG_GENERIC(PROT_NONE),
|
||||
FLAG_GENERIC(PROT_EXEC),
|
||||
FLAG_GENERIC(PROT_READ),
|
||||
@ -1068,7 +1084,7 @@ UNUSED static struct flags mmap_prot_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags mmap_flags[] = {
|
||||
UNUSED static const struct flags mmap_flags[] = {
|
||||
FLAG_TARGET(MAP_SHARED),
|
||||
FLAG_TARGET(MAP_PRIVATE),
|
||||
FLAG_TARGET(MAP_ANONYMOUS),
|
||||
@ -1089,10 +1105,12 @@ UNUSED static struct flags mmap_flags[] = {
|
||||
#ifdef TARGET_MAP_UNINITIALIZED
|
||||
FLAG_TARGET(MAP_UNINITIALIZED),
|
||||
#endif
|
||||
FLAG_TARGET(MAP_HUGETLB),
|
||||
FLAG_TARGET(MAP_STACK),
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags clone_flags[] = {
|
||||
UNUSED static const struct flags clone_flags[] = {
|
||||
FLAG_GENERIC(CLONE_VM),
|
||||
FLAG_GENERIC(CLONE_FS),
|
||||
FLAG_GENERIC(CLONE_FILES),
|
||||
@ -1136,7 +1154,17 @@ UNUSED static struct flags clone_flags[] = {
|
||||
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 */
|
||||
FLAG_GENERIC(MSG_CONFIRM),
|
||||
FLAG_GENERIC(MSG_DONTROUTE),
|
||||
@ -1156,7 +1184,7 @@ UNUSED static struct flags msg_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags statx_flags[] = {
|
||||
UNUSED static const struct flags statx_flags[] = {
|
||||
#ifdef AT_EMPTY_PATH
|
||||
FLAG_GENERIC(AT_EMPTY_PATH),
|
||||
#endif
|
||||
@ -1178,7 +1206,7 @@ UNUSED static struct flags statx_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags statx_mask[] = {
|
||||
UNUSED static const struct flags statx_mask[] = {
|
||||
/* This must come first, because it includes everything. */
|
||||
#ifdef STATX_ALL
|
||||
FLAG_GENERIC(STATX_ALL),
|
||||
@ -1226,7 +1254,7 @@ UNUSED static struct flags statx_mask[] = {
|
||||
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_PUNCH_HOLE),
|
||||
#ifdef FALLOC_FL_NO_HIDE_STALE
|
||||
@ -1246,7 +1274,7 @@ UNUSED static struct flags falloc_flags[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
UNUSED static struct flags termios_iflags[] = {
|
||||
UNUSED static const struct flags termios_iflags[] = {
|
||||
FLAG_TARGET(IGNBRK),
|
||||
FLAG_TARGET(BRKINT),
|
||||
FLAG_TARGET(IGNPAR),
|
||||
@ -1265,7 +1293,7 @@ UNUSED static struct flags termios_iflags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags termios_oflags[] = {
|
||||
UNUSED static const struct flags termios_oflags[] = {
|
||||
FLAG_TARGET(OPOST),
|
||||
FLAG_TARGET(OLCUC),
|
||||
FLAG_TARGET(ONLCR),
|
||||
@ -1349,7 +1377,7 @@ UNUSED static struct enums termios_cflags_CSIZE[] = {
|
||||
ENUM_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags termios_cflags[] = {
|
||||
UNUSED static const struct flags termios_cflags[] = {
|
||||
FLAG_TARGET(CSTOPB),
|
||||
FLAG_TARGET(CREAD),
|
||||
FLAG_TARGET(PARENB),
|
||||
@ -1360,7 +1388,7 @@ UNUSED static struct flags termios_cflags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags termios_lflags[] = {
|
||||
UNUSED static const struct flags termios_lflags[] = {
|
||||
FLAG_TARGET(ISIG),
|
||||
FLAG_TARGET(ICANON),
|
||||
FLAG_TARGET(XCASE),
|
||||
@ -1380,7 +1408,8 @@ UNUSED static struct flags termios_lflags[] = {
|
||||
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_FUTURE),
|
||||
#ifdef MCL_ONFAULT
|
||||
@ -1388,6 +1417,7 @@ UNUSED static struct flags mlockall_flags[] = {
|
||||
#endif
|
||||
FLAG_END,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* IDs of the various system clocks */
|
||||
#define TARGET_CLOCK_REALTIME 0
|
||||
@ -1969,6 +1999,58 @@ print_execv(CPUArchState *cpu_env, const struct syscallname *name,
|
||||
}
|
||||
#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)
|
||||
static void
|
||||
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);
|
||||
print_pointer(arg1, 0);
|
||||
print_pointer(arg2, 1);
|
||||
print_pointer(arg2, 0);
|
||||
print_raw_param("%u", arg3, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
@ -86,6 +86,9 @@
|
||||
{ TARGET_NR_clock_getres, "clock_getres" , NULL, print_clock_getres,
|
||||
print_syscall_ret_clock_getres },
|
||||
#endif
|
||||
#ifdef TARGET_NR_clock_getres_time64
|
||||
{ TARGET_NR_clock_getres_time64, "clock_getres_time64" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_clock_gettime
|
||||
{ TARGET_NR_clock_gettime, "clock_gettime" , NULL, print_clock_gettime,
|
||||
print_syscall_ret_clock_gettime },
|
||||
@ -164,7 +167,7 @@
|
||||
{ TARGET_NR_execve, "execve" , NULL, print_execve, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_execveat
|
||||
{ TARGET_NR_execveat, "execveat" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_execveat, "execveat" , NULL, print_execveat, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_exec_with_loader
|
||||
{ TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL },
|
||||
@ -275,6 +278,9 @@
|
||||
#ifdef TARGET_NR_futex
|
||||
{ TARGET_NR_futex, "futex" , NULL, print_futex, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_futex_time64
|
||||
{ TARGET_NR_futex_time64, "futex_time64" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_futimesat
|
||||
{ TARGET_NR_futimesat, "futimesat" , NULL, print_futimesat, NULL },
|
||||
#endif
|
||||
@ -315,10 +321,10 @@
|
||||
{ TARGET_NR_getgid32, "getgid32" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getgroups
|
||||
{ TARGET_NR_getgroups, "getgroups" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getgroups, "getgroups" , "%s(%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getgroups32
|
||||
{ TARGET_NR_getgroups32, "getgroups32" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getgroups32, "getgroups32" , "%s(%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_gethostname
|
||||
{ TARGET_NR_gethostname, "gethostname" , NULL, NULL, NULL },
|
||||
@ -337,7 +343,7 @@
|
||||
{ TARGET_NR_getpagesize, "getpagesize" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getpeername
|
||||
{ TARGET_NR_getpeername, "getpeername" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getpeername, "getpeername" , "%s(%d,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getpgid
|
||||
{ TARGET_NR_getpgid, "getpgid" , "%s(%u)", NULL, NULL },
|
||||
@ -361,19 +367,19 @@
|
||||
{ TARGET_NR_getrandom, "getrandom", "%s(%p,%u,%u)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresgid
|
||||
{ TARGET_NR_getresgid, "getresgid" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getresgid, "getresgid" , "%s(%p,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresgid32
|
||||
{ TARGET_NR_getresgid32, "getresgid32" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresuid
|
||||
{ TARGET_NR_getresuid, "getresuid" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getresuid, "getresuid" , "%s(%p,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresuid32
|
||||
{ TARGET_NR_getresuid32, "getresuid32" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getrlimit
|
||||
{ TARGET_NR_getrlimit, "getrlimit" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getrlimit, "getrlimit" , "%s(%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_get_robust_list
|
||||
{ TARGET_NR_get_robust_list, "get_robust_list" , NULL, NULL, NULL },
|
||||
@ -385,10 +391,10 @@
|
||||
{ TARGET_NR_getsid, "getsid" , "%s(%d)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getsockname
|
||||
{ TARGET_NR_getsockname, "getsockname" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getsockname, "getsockname" , "%s(%d,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getsockopt
|
||||
{ TARGET_NR_getsockopt, "getsockopt" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getsockopt, "getsockopt" , "%s(%d,%d,%d,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_get_thread_area
|
||||
#if defined(TARGET_I386) && defined(TARGET_ABI32)
|
||||
@ -1043,7 +1049,8 @@
|
||||
{ TARGET_NR_perfctr, "perfctr" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#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
|
||||
#ifdef TARGET_NR_pipe
|
||||
{ TARGET_NR_pipe, "pipe" , NULL, NULL, NULL },
|
||||
@ -1052,10 +1059,10 @@
|
||||
{ TARGET_NR_pivot_root, "pivot_root" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_poll
|
||||
{ TARGET_NR_poll, "poll" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_poll, "poll" , "%s(%p,%u,%d)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_ppoll
|
||||
{ TARGET_NR_ppoll, "ppoll" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_ppoll, "ppoll" , "%s(%p,%u,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_prctl
|
||||
{ TARGET_NR_prctl, "prctl" , NULL, NULL, NULL },
|
||||
@ -1124,7 +1131,7 @@
|
||||
{ TARGET_NR_reboot, "reboot" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_recv
|
||||
{ TARGET_NR_recv, "recv" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_recv, "recv" , "%s(%d,%p,%u,%d)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_recvfrom
|
||||
{ TARGET_NR_recvfrom, "recvfrom" , NULL, NULL, NULL },
|
||||
@ -1184,7 +1191,7 @@
|
||||
{ TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, print_rt_sigqueueinfo, NULL },
|
||||
#endif
|
||||
#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
|
||||
#ifdef TARGET_NR_rt_sigsuspend
|
||||
{ TARGET_NR_rt_sigsuspend, "rt_sigsuspend" , NULL, NULL, NULL },
|
||||
@ -1196,16 +1203,19 @@
|
||||
{ TARGET_NR_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" , NULL, print_rt_tgsigqueueinfo, NULL },
|
||||
#endif
|
||||
#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
|
||||
#ifdef TARGET_NR_sched_get_affinity
|
||||
{ TARGET_NR_sched_get_affinity, "sched_get_affinity" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#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
|
||||
#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
|
||||
#ifdef TARGET_NR_sched_get_priority_max
|
||||
{ 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 },
|
||||
#endif
|
||||
#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
|
||||
#ifdef TARGET_NR_sched_setatt
|
||||
{ TARGET_NR_sched_setatt, "sched_setatt" , NULL, NULL, NULL },
|
||||
@ -1298,10 +1308,10 @@
|
||||
{ TARGET_NR_setgid32, "setgid32" , "%s(%u)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_setgroups
|
||||
{ TARGET_NR_setgroups, "setgroups" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_setgroups, "setgroups" , "%s(%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_setgroups32
|
||||
{ TARGET_NR_setgroups32, "setgroups32" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_setgroups32, "setgroups32" , "%s(%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_sethae
|
||||
{ TARGET_NR_sethae, "sethae" , NULL, NULL, NULL },
|
||||
@ -1353,23 +1363,23 @@
|
||||
{ TARGET_NR_setreuid32, "setreuid32" , "%s(%u,%u)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_setrlimit
|
||||
{ TARGET_NR_setrlimit, "setrlimit" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_setrlimit, "setrlimit" , "%s(%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#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
|
||||
#ifdef TARGET_NR_setsid
|
||||
{ TARGET_NR_setsid, "setsid" , "%s()", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_setsockopt
|
||||
{ TARGET_NR_setsockopt, "setsockopt" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_setsockopt, "setsockopt" , "%s(%d,%d,%d,%p,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_set_thread_area
|
||||
{ TARGET_NR_set_thread_area, "set_thread_area", "%s(0x"TARGET_ABI_FMT_lx")",
|
||||
NULL, NULL },
|
||||
#endif
|
||||
#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
|
||||
#ifdef TARGET_NR_settimeofday
|
||||
{ TARGET_NR_settimeofday, "settimeofday" , NULL, print_settimeofday, NULL },
|
||||
@ -1498,7 +1508,7 @@
|
||||
{ TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_sysinfo
|
||||
{ TARGET_NR_sysinfo, "sysinfo" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_sysinfo, "sysinfo" , "%s(%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_sys_kexec_load
|
||||
{ TARGET_NR_sys_kexec_load, "sys_kexec_load" , NULL, NULL, NULL },
|
||||
@ -1648,7 +1658,7 @@
|
||||
{ TARGET_NR_vserver, "vserver" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_wait4
|
||||
{ TARGET_NR_wait4, "wait4" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_wait4, "wait4" , "%s(%d,%p,%d,%p)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_waitid
|
||||
{ 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 },
|
||||
#endif
|
||||
#ifdef TARGET_NR_pipe2
|
||||
{ TARGET_NR_pipe2, "pipe2", NULL, NULL, NULL },
|
||||
{ TARGET_NR_pipe2, "pipe2", "%s(%p,%d)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_pidfd_open
|
||||
{ TARGET_NR_pidfd_open, "pidfd_open", "%s(%d,%u)", NULL, NULL },
|
||||
|
@ -95,50 +95,7 @@
|
||||
#include <linux/soundcard.h>
|
||||
#include <linux/kd.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>
|
||||
#endif
|
||||
#include <linux/fd.h>
|
||||
#if defined(CONFIG_FIEMAP)
|
||||
#include <linux/fiemap.h>
|
||||
@ -696,7 +653,8 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
|
||||
#endif
|
||||
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)
|
||||
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
|
||||
defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
|
||||
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->uid, &target_cred->uid);
|
||||
__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 {
|
||||
qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
|
||||
cmsg->cmsg_level, cmsg->cmsg_type);
|
||||
@ -2800,8 +2766,13 @@ get_timeout:
|
||||
ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (optname == SO_TYPE) {
|
||||
switch (optname) {
|
||||
case SO_TYPE:
|
||||
val = host_to_target_sock_type(val);
|
||||
break;
|
||||
case SO_ERROR:
|
||||
val = host_to_target_errno(val);
|
||||
break;
|
||||
}
|
||||
if (len > lv)
|
||||
len = lv;
|
||||
@ -3322,7 +3293,10 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
target_vec, count, send);
|
||||
if (vec == NULL) {
|
||||
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_iov = vec;
|
||||
@ -3374,7 +3348,9 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
}
|
||||
|
||||
out:
|
||||
unlock_iovec(vec, target_vec, count, !send);
|
||||
if (vec) {
|
||||
unlock_iovec(vec, target_vec, count, !send);
|
||||
}
|
||||
out2:
|
||||
return ret;
|
||||
}
|
||||
@ -8269,11 +8245,17 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
|
||||
#if defined(TARGET_HPPA)
|
||||
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
|
||||
{
|
||||
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\n");
|
||||
dprintf(fd, "model name\t: Merlin L2 160 QEMU (9000/778/B160L)\n");
|
||||
int i, num_cpus;
|
||||
|
||||
num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
for (i = 0; i < num_cpus; i++) {
|
||||
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;
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
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_MASK 0xffff0000
|
||||
|
||||
@ -8642,7 +8737,13 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
||||
if (CPU_NEXT(first_cpu)) {
|
||||
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));
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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;
|
||||
g_free(ts);
|
||||
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);
|
||||
return ret;
|
||||
#endif
|
||||
case TARGET_NR_execveat:
|
||||
return do_execveat(cpu_env, arg1, arg2, arg3, arg4, arg5);
|
||||
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;
|
||||
|
||||
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;
|
||||
return do_execveat(cpu_env, AT_FDCWD, arg1, arg2, arg3, 0);
|
||||
case TARGET_NR_chdir:
|
||||
if (!(p = lock_user_string(arg1)))
|
||||
return -TARGET_EFAULT;
|
||||
|
@ -2040,8 +2040,6 @@ config_host_data.set('HAVE_OPTRESET',
|
||||
cc.has_header_symbol('getopt.h', 'optreset'))
|
||||
config_host_data.set('HAVE_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
|
||||
config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
|
||||
|
Loading…
Reference in New Issue
Block a user