summaryrefslogtreecommitdiffstats
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c100
1 files changed, 85 insertions, 15 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 2e954d8dbd..8402c1399d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -111,6 +111,31 @@
#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
@@ -158,6 +183,7 @@
#include "qapi/error.h"
#include "fd-trans.h"
#include "tcg/tcg.h"
+#include "cpu_loop-common.h"
#ifndef CLONE_IO
#define CLONE_IO 0x80000000 /* Clone io context */
@@ -8144,6 +8170,33 @@ static int is_proc_myself(const char *filename, const char *entry)
return 0;
}
+static void excp_dump_file(FILE *logfile, CPUArchState *env,
+ const char *fmt, int code)
+{
+ if (logfile) {
+ CPUState *cs = env_cpu(env);
+
+ fprintf(logfile, fmt, code);
+ fprintf(logfile, "Failing executable: %s\n", exec_path);
+ cpu_dump_state(cs, logfile, 0);
+ open_self_maps(env, fileno(logfile));
+ }
+}
+
+void target_exception_dump(CPUArchState *env, const char *fmt, int code)
+{
+ /* dump to console */
+ excp_dump_file(stderr, env, fmt, code);
+
+ /* dump to log file */
+ if (qemu_log_separate()) {
+ FILE *logfile = qemu_log_trylock();
+
+ excp_dump_file(logfile, env, fmt, code);
+ qemu_log_unlock(logfile);
+ }
+}
+
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
static int is_proc(const char *filename, const char *entry)
@@ -8251,8 +8304,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int
};
if (is_proc_myself(pathname, "exe")) {
- int execfd = qemu_getauxval(AT_EXECFD);
- return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
+ return safe_openat(dirfd, exec_path, flags, mode);
}
for (fake_open = fakes; fake_open->filename; fake_open++) {
@@ -8679,16 +8731,21 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#if defined(__NR_pidfd_send_signal) && defined(TARGET_NR_pidfd_send_signal)
case TARGET_NR_pidfd_send_signal:
{
- siginfo_t uinfo;
+ siginfo_t uinfo, *puinfo;
- p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
- if (!p) {
- return -TARGET_EFAULT;
+ if (arg3) {
+ p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ target_to_host_siginfo(&uinfo, p);
+ unlock_user(p, arg3, 0);
+ puinfo = &uinfo;
+ } else {
+ puinfo = NULL;
}
- target_to_host_siginfo(&uinfo, p);
- unlock_user(p, arg3, 0);
ret = get_errno(pidfd_send_signal(arg1, target_to_host_signal(arg2),
- &uinfo, arg4));
+ puinfo, arg4));
}
return ret;
#endif
@@ -8855,7 +8912,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
* before the execve completes and makes it the other
* program's problem.
*/
- ret = get_errno(safe_execve(p, argp, envp));
+ 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;
@@ -9110,6 +9171,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
unlock_user(p, arg2, 0);
return ret;
#endif
+#if defined(TARGET_NR_faccessat2)
+ case TARGET_NR_faccessat2:
+ if (!(p = lock_user_string(arg2))) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(faccessat(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
+ return ret;
+#endif
#ifdef TARGET_NR_nice /* not on alpha */
case TARGET_NR_nice:
return get_errno(nice(arg1));
@@ -11793,7 +11863,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
return -host_to_target_errno(ret);
#endif
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
#ifdef TARGET_NR_fadvise64_64
case TARGET_NR_fadvise64_64:
@@ -11920,7 +11990,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
return get_errno(sys_gettid());
#ifdef TARGET_NR_readahead
case TARGET_NR_readahead:
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
if (regpairs_aligned(cpu_env, num)) {
arg2 = arg3;
arg3 = arg4;
@@ -12612,7 +12682,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#endif /* CONFIG_EVENTFD */
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
case TARGET_NR_fallocate:
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
target_offset64(arg5, arg6)));
#else
@@ -12623,7 +12693,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#if defined(CONFIG_SYNC_FILE_RANGE)
#if defined(TARGET_NR_sync_file_range)
case TARGET_NR_sync_file_range:
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
#if defined(TARGET_MIPS)
ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
target_offset64(arg5, arg6), arg7));
@@ -12645,7 +12715,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
case TARGET_NR_arm_sync_file_range:
#endif
/* This is like sync_file_range but the arguments are reordered */
-#if TARGET_ABI_BITS == 32
+#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
target_offset64(arg5, arg6), arg2));
#else