summaryrefslogtreecommitdiffstats
path: root/qemu/linux-user
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/linux-user')
-rw-r--r--qemu/linux-user/aarch64/syscall_nr.h70
-rw-r--r--qemu/linux-user/aarch64/target_syscall.h (renamed from qemu/linux-user/aarch64/syscall.h)5
-rw-r--r--qemu/linux-user/alpha/syscall_nr.h6
-rw-r--r--qemu/linux-user/alpha/target_syscall.h (renamed from qemu/linux-user/alpha/syscall.h)5
-rw-r--r--qemu/linux-user/arm/nwfpe/double_cpdo.c1
-rw-r--r--qemu/linux-user/arm/nwfpe/extended_cpdo.c1
-rw-r--r--qemu/linux-user/arm/nwfpe/fpa11.c2
-rw-r--r--qemu/linux-user/arm/nwfpe/fpa11.h5
-rw-r--r--qemu/linux-user/arm/nwfpe/fpa11_cpdo.c1
-rw-r--r--qemu/linux-user/arm/nwfpe/fpa11_cpdt.c1
-rw-r--r--qemu/linux-user/arm/nwfpe/fpa11_cprt.c1
-rw-r--r--qemu/linux-user/arm/nwfpe/fpopcode.c1
-rw-r--r--qemu/linux-user/arm/nwfpe/single_cpdo.c1
-rw-r--r--qemu/linux-user/arm/syscall_nr.h12
-rw-r--r--qemu/linux-user/arm/target_syscall.h (renamed from qemu/linux-user/arm/syscall.h)4
-rw-r--r--qemu/linux-user/cris/syscall_nr.h24
-rw-r--r--qemu/linux-user/cris/target_syscall.h (renamed from qemu/linux-user/cris/syscall.h)0
-rw-r--r--qemu/linux-user/elfload.c201
-rw-r--r--qemu/linux-user/flatload.c8
-rw-r--r--qemu/linux-user/i386/syscall_nr.h29
-rw-r--r--qemu/linux-user/i386/target_syscall.h (renamed from qemu/linux-user/i386/syscall.h)5
-rw-r--r--qemu/linux-user/linuxload.c15
-rw-r--r--qemu/linux-user/m68k-sim.c9
-rw-r--r--qemu/linux-user/m68k/syscall_nr.h29
-rw-r--r--qemu/linux-user/m68k/target_syscall.h (renamed from qemu/linux-user/m68k/syscall.h)4
-rw-r--r--qemu/linux-user/main.c561
-rw-r--r--qemu/linux-user/microblaze/syscall_nr.h8
-rw-r--r--qemu/linux-user/microblaze/target_syscall.h (renamed from qemu/linux-user/microblaze/syscall.h)0
-rw-r--r--qemu/linux-user/mips/syscall_nr.h12
-rw-r--r--qemu/linux-user/mips/target_syscall.h (renamed from qemu/linux-user/mips/syscall.h)4
-rw-r--r--qemu/linux-user/mips64/syscall_nr.h23
-rw-r--r--qemu/linux-user/mips64/target_syscall.h (renamed from qemu/linux-user/mips64/syscall.h)4
-rw-r--r--qemu/linux-user/mmap.c48
-rw-r--r--qemu/linux-user/openrisc/syscall_nr.h28
-rw-r--r--qemu/linux-user/openrisc/target_syscall.h (renamed from qemu/linux-user/openrisc/syscall.h)5
-rw-r--r--qemu/linux-user/ppc/syscall_nr.h26
-rw-r--r--qemu/linux-user/ppc/target_syscall.h (renamed from qemu/linux-user/ppc/syscall.h)5
-rw-r--r--qemu/linux-user/qemu.h16
-rw-r--r--qemu/linux-user/s390x/syscall_nr.h30
-rw-r--r--qemu/linux-user/s390x/target_syscall.h (renamed from qemu/linux-user/s390x/syscall.h)5
-rw-r--r--qemu/linux-user/sh4/syscall_nr.h2
-rw-r--r--qemu/linux-user/sh4/target_syscall.h (renamed from qemu/linux-user/sh4/syscall.h)5
-rw-r--r--qemu/linux-user/signal.c420
-rw-r--r--qemu/linux-user/sparc/syscall_nr.h16
-rw-r--r--qemu/linux-user/sparc/target_syscall.h (renamed from qemu/linux-user/sparc/syscall.h)5
-rw-r--r--qemu/linux-user/sparc64/syscall_nr.h14
-rw-r--r--qemu/linux-user/sparc64/target_syscall.h (renamed from qemu/linux-user/sparc64/syscall.h)5
-rw-r--r--qemu/linux-user/strace.c4
-rw-r--r--qemu/linux-user/syscall.c526
-rw-r--r--qemu/linux-user/syscall_defs.h64
-rw-r--r--qemu/linux-user/tilegx/syscall_nr.h328
-rw-r--r--qemu/linux-user/tilegx/target_cpu.h35
-rw-r--r--qemu/linux-user/tilegx/target_signal.h28
-rw-r--r--qemu/linux-user/tilegx/target_structs.h46
-rw-r--r--qemu/linux-user/tilegx/target_syscall.h43
-rw-r--r--qemu/linux-user/tilegx/termbits.h274
-rw-r--r--qemu/linux-user/uaccess.c4
-rw-r--r--qemu/linux-user/uname.c2
-rw-r--r--qemu/linux-user/unicore32/target_signal.h6
-rw-r--r--qemu/linux-user/unicore32/target_syscall.h (renamed from qemu/linux-user/unicore32/syscall.h)0
-rw-r--r--qemu/linux-user/vm86.c7
-rw-r--r--qemu/linux-user/x86_64/syscall_nr.h15
-rw-r--r--qemu/linux-user/x86_64/target_syscall.h (renamed from qemu/linux-user/x86_64/syscall.h)5
63 files changed, 2424 insertions, 645 deletions
diff --git a/qemu/linux-user/aarch64/syscall_nr.h b/qemu/linux-user/aarch64/syscall_nr.h
index 743255db0..59511d855 100644
--- a/qemu/linux-user/aarch64/syscall_nr.h
+++ b/qemu/linux-user/aarch64/syscall_nr.h
@@ -262,62 +262,16 @@
#define TARGET_NR_process_vm_writev 271
#define TARGET_NR_kcmp 272
#define TARGET_NR_finit_module 273
-#define TARGET_NR_open 1024
-#define TARGET_NR_link 1025
-#define TARGET_NR_unlink 1026
-#define TARGET_NR_mknod 1027
-#define TARGET_NR_chmod 1028
-#define TARGET_NR_chown 1029
-#define TARGET_NR_mkdir 1030
-#define TARGET_NR_rmdir 1031
-#define TARGET_NR_lchown 1032
-#define TARGET_NR_access 1033
-#define TARGET_NR_rename 1034
-#define TARGET_NR_readlink 1035
-#define TARGET_NR_symlink 1036
-#define TARGET_NR_utimes 1037
-#define TARGET_NR_stat 1038
-#define TARGET_NR_lstat 1039
-#define TARGET_NR_pipe 1040
-#define TARGET_NR_dup2 1041
-#define TARGET_NR_epoll_create 1042
-#define TARGET_NR_inotify_init 1043
-#define TARGET_NR_eventfd 1044
-#define TARGET_NR_signalfd 1045
-#define TARGET_NR_sendfile64 1046
-#define TARGET_NR_ftruncate64 1047
-#define TARGET_NR_truncate64 1048
-#define TARGET_NR_stat64 1049
-#define TARGET_NR_lstat64 1050
-#define TARGET_NR_fstat64 1051
-#define TARGET_NR_fcntl64 1052
-/* #define TARGET_NR_fadvise64 1053 */
-#define TARGET_NR_newfstatat 1054
-#define TARGET_NR_fstatfs64 1055
-#define TARGET_NR_statfs64 1056
-#define TARGET_NR_lseek64 1057
-#define TARGET_NR_mmap64 1058
-#define TARGET_NR_alarm 1059
-#define TARGET_NR_getpgrp 1060
-#define TARGET_NR_pause 1061
-#define TARGET_NR_time 1062
-#define TARGET_NR_utime 1063
-#define TARGET_NR_creat 1064
-#define TARGET_NR_getdents 1065
-#define TARGET_NR_futimesat 1066
-#define TARGET_NR_select 1067
-#define TARGET_NR_poll 1068
-#define TARGET_NR_epoll_wait 1069
-#define TARGET_NR_ustat 1070
-#define TARGET_NR_vfork 1071
-#define TARGET_NR_oldwait4 1072
-#define TARGET_NR_recv 1073
-#define TARGET_NR_send 1074
-#define TARGET_NR_bdflush 1075
-#define TARGET_NR_umount 1076
-#define TARGET_NR_uselib 1077
-#define TARGET_NR__sysctl 1078
-#define TARGET_NR_fork 1079
-#define TARGET_NR_syscalls (__NR_fork+1)
+#define TARGET_NR_sched_setattr 274
+#define TARGET_NR_sched_getattr 275
+#define TARGET_NR_renameat2 276
+#define TARGET_NR_seccomp 277
+#define TARGET_NR_getrandom 278
+#define TARGET_NR_memfd_create 279
+#define TARGET_NR_bpf 280
+#define TARGET_NR_execveat 281
+#define TARGET_NR_userfaultfd 282
+#define TARGET_NR_membarrier 283
+#define TARGET_NR_mlock2 284
+#define TARGET_NR_copy_file_range 285
-#define TARGET_NR_sigreturn 1999
diff --git a/qemu/linux-user/aarch64/syscall.h b/qemu/linux-user/aarch64/target_syscall.h
index dc72a15c5..f45801804 100644
--- a/qemu/linux-user/aarch64/syscall.h
+++ b/qemu/linux-user/aarch64/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
struct target_pt_regs {
uint64_t regs[31];
uint64_t sp;
@@ -11,3 +14,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/alpha/syscall_nr.h b/qemu/linux-user/alpha/syscall_nr.h
index dde8d5c6a..00e14bb6b 100644
--- a/qemu/linux-user/alpha/syscall_nr.h
+++ b/qemu/linux-user/alpha/syscall_nr.h
@@ -444,3 +444,9 @@
#define TARGET_NR_process_vm_writev 505
#define TARGET_NR_kcmp 506
#define TARGET_NR_finit_module 507
+#define TARGET_NR_sched_setattr 508
+#define TARGET_NR_sched_getattr 509
+#define TARGET_NR_renameat2 510
+#define TARGET_NR_getrandom 511
+#define TARGET_NR_memfd_create 512
+#define TARGET_NR_execveat 513
diff --git a/qemu/linux-user/alpha/syscall.h b/qemu/linux-user/alpha/target_syscall.h
index 245cff254..3db4b16f6 100644
--- a/qemu/linux-user/alpha/syscall.h
+++ b/qemu/linux-user/alpha/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
/* default linux values for the selectors */
#define __USER_DS (1)
@@ -255,3 +258,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 4096
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/arm/nwfpe/double_cpdo.c b/qemu/linux-user/arm/nwfpe/double_cpdo.c
index 41c28f309..1cef38085 100644
--- a/qemu/linux-user/arm/nwfpe/double_cpdo.c
+++ b/qemu/linux-user/arm/nwfpe/double_cpdo.c
@@ -18,6 +18,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/nwfpe/extended_cpdo.c b/qemu/linux-user/arm/nwfpe/extended_cpdo.c
index 48eca3b4a..1c8a41229 100644
--- a/qemu/linux-user/arm/nwfpe/extended_cpdo.c
+++ b/qemu/linux-user/arm/nwfpe/extended_cpdo.c
@@ -18,6 +18,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/nwfpe/fpa11.c b/qemu/linux-user/arm/nwfpe/fpa11.c
index eebd93fc0..441e3b1cf 100644
--- a/qemu/linux-user/arm/nwfpe/fpa11.c
+++ b/qemu/linux-user/arm/nwfpe/fpa11.c
@@ -18,6 +18,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpopcode.h"
@@ -27,7 +28,6 @@
//#include <asm/system.h>
-#include <stdio.h>
FPA11* qemufpa = NULL;
CPUARMState* user_registers;
diff --git a/qemu/linux-user/arm/nwfpe/fpa11.h b/qemu/linux-user/arm/nwfpe/fpa11.h
index bb9ac6554..0b072843d 100644
--- a/qemu/linux-user/arm/nwfpe/fpa11.h
+++ b/qemu/linux-user/arm/nwfpe/fpa11.h
@@ -21,9 +21,6 @@
#ifndef __FPA11_H__
#define __FPA11_H__
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
#include <cpu.h>
@@ -108,7 +105,7 @@ static inline void writeRegister(unsigned int x, unsigned int y)
static inline void writeConditionCodes(unsigned int x)
{
- cpsr_write(user_registers,x,CPSR_NZCV);
+ cpsr_write(user_registers, x, CPSR_NZCV, CPSRWriteByInstr);
}
#define ARM_REG_PC 15
diff --git a/qemu/linux-user/arm/nwfpe/fpa11_cpdo.c b/qemu/linux-user/arm/nwfpe/fpa11_cpdo.c
index 5f4a6a413..94ac98aef 100644
--- a/qemu/linux-user/arm/nwfpe/fpa11_cpdo.c
+++ b/qemu/linux-user/arm/nwfpe/fpa11_cpdo.c
@@ -18,6 +18,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/nwfpe/fpa11_cpdt.c b/qemu/linux-user/arm/nwfpe/fpa11_cpdt.c
index 007a3d650..c32b0c2fa 100644
--- a/qemu/linux-user/arm/nwfpe/fpa11_cpdt.c
+++ b/qemu/linux-user/arm/nwfpe/fpa11_cpdt.c
@@ -19,6 +19,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/nwfpe/fpa11_cprt.c b/qemu/linux-user/arm/nwfpe/fpa11_cprt.c
index 7be93fa54..04dc2ebb0 100644
--- a/qemu/linux-user/arm/nwfpe/fpa11_cprt.c
+++ b/qemu/linux-user/arm/nwfpe/fpa11_cprt.c
@@ -19,6 +19,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/nwfpe/fpopcode.c b/qemu/linux-user/arm/nwfpe/fpopcode.c
index 0ada30c6b..6784256d2 100644
--- a/qemu/linux-user/arm/nwfpe/fpopcode.c
+++ b/qemu/linux-user/arm/nwfpe/fpopcode.c
@@ -18,6 +18,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/nwfpe/single_cpdo.c b/qemu/linux-user/arm/nwfpe/single_cpdo.c
index 2bfb359eb..21e177bae 100644
--- a/qemu/linux-user/arm/nwfpe/single_cpdo.c
+++ b/qemu/linux-user/arm/nwfpe/single_cpdo.c
@@ -18,6 +18,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"
diff --git a/qemu/linux-user/arm/syscall_nr.h b/qemu/linux-user/arm/syscall_nr.h
index 53552beab..cc9089ccd 100644
--- a/qemu/linux-user/arm/syscall_nr.h
+++ b/qemu/linux-user/arm/syscall_nr.h
@@ -384,3 +384,15 @@
#define TARGET_NR_process_vm_writev (377)
#define TARGET_NR_kcmp (378)
#define TARGET_NR_finit_module (379)
+
+#define TARGET_NR_sched_setattr (380)
+#define TARGET_NR_sched_getattr (381)
+#define TARGET_NR_renameat2 (382)
+#define TARGET_NR_seccomp (383)
+#define TARGET_NR_getrandom (384)
+#define TARGET_NR_memfd_create (385)
+#define TARGET_NR_bpf (386)
+#define TARGET_NR_execveat (387)
+#define TARGET_NR_userfaultfd (388)
+#define TARGET_NR_membarrier (389)
+#define TARGET_NR_mlock2 (390)
diff --git a/qemu/linux-user/arm/syscall.h b/qemu/linux-user/arm/target_syscall.h
index 3844a9611..ea863db0b 100644
--- a/qemu/linux-user/arm/syscall.h
+++ b/qemu/linux-user/arm/target_syscall.h
@@ -1,3 +1,5 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
@@ -48,3 +50,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/cris/syscall_nr.h b/qemu/linux-user/cris/syscall_nr.h
index 694bd02fa..44f0b645b 100644
--- a/qemu/linux-user/cris/syscall_nr.h
+++ b/qemu/linux-user/cris/syscall_nr.h
@@ -336,3 +336,27 @@
#define TARGET_NR_preadv 333
#define TARGET_NR_pwritev 334
#define TARGET_NR_setns 335
+#define TARGET_NR_name_to_handle_at 336
+#define TARGET_NR_open_by_handle_at 337
+#define TARGET_NR_rt_tgsigqueueinfo 338
+#define TARGET_NR_perf_event_open 339
+#define TARGET_NR_recvmmsg 340
+#define TARGET_NR_accept4 341
+#define TARGET_NR_fanotify_init 342
+#define TARGET_NR_fanotify_mark 343
+#define TARGET_NR_prlimit64 344
+#define TARGET_NR_clock_adjtime 345
+#define TARGET_NR_syncfs 346
+#define TARGET_NR_sendmmsg 347
+#define TARGET_NR_process_vm_readv 348
+#define TARGET_NR_process_vm_writev 349
+#define TARGET_NR_kcmp 350
+#define TARGET_NR_finit_module 351
+#define TARGET_NR_sched_setattr 352
+#define TARGET_NR_sched_getattr 353
+#define TARGET_NR_renameat2 354
+#define TARGET_NR_seccomp 355
+#define TARGET_NR_getrandom 356
+#define TARGET_NR_memfd_create 357
+#define TARGET_NR_bpf 358
+#define TARGET_NR_execveat 359
diff --git a/qemu/linux-user/cris/syscall.h b/qemu/linux-user/cris/target_syscall.h
index 2957b0d6a..2957b0d6a 100644
--- a/qemu/linux-user/cris/syscall.h
+++ b/qemu/linux-user/cris/target_syscall.h
diff --git a/qemu/linux-user/elfload.c b/qemu/linux-user/elfload.c
index 17883686f..e47caff7a 100644
--- a/qemu/linux-user/elfload.c
+++ b/qemu/linux-user/elfload.c
@@ -1,20 +1,13 @@
/* This is the Linux kernel elf-loading code, ported into user space */
-#include <sys/time.h>
+#include "qemu/osdep.h"
#include <sys/param.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
#include <sys/mman.h>
#include <sys/resource.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
#include "qemu.h"
#include "disas/disas.h"
+#include "qemu/path.h"
#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
@@ -145,7 +138,6 @@ static uint32_t get_elf_hwcap(void)
#ifdef TARGET_X86_64
#define ELF_START_MMAP 0x2aaaaab000ULL
-#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
@@ -273,9 +265,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ((x) == ELF_MACHINE)
-
-#define ELF_ARCH ELF_MACHINE
+#define ELF_ARCH EM_ARM
#define ELF_CLASS ELFCLASS32
static inline void init_thread(struct target_pt_regs *regs,
@@ -481,9 +471,7 @@ static uint32_t get_elf_hwcap2(void)
/* 64 bit ARM definitions */
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ((x) == ELF_MACHINE)
-
-#define ELF_ARCH ELF_MACHINE
+#define ELF_ARCH EM_AARCH64
#define ELF_CLASS ELFCLASS64
#define ELF_PLATFORM "aarch64"
@@ -556,8 +544,6 @@ static uint32_t get_elf_hwcap(void)
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ((x) == EM_UNICORE32)
-
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_UNICORE32
@@ -666,7 +652,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_START_MMAP 0x80000000
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
| HWCAP_SPARC_MULDIV)
-#define elf_check_arch(x) ( (x) == EM_SPARC )
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SPARC
@@ -686,6 +671,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#ifdef TARGET_PPC
+#define ELF_MACHINE PPC_ELF_MACHINE
#define ELF_START_MMAP 0x80000000
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
@@ -696,8 +682,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#else
-#define elf_check_arch(x) ( (x) == EM_PPC )
-
#define ELF_CLASS ELFCLASS32
#endif
@@ -875,8 +859,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_MIPS )
-
#ifdef TARGET_MIPS64
#define ELF_CLASS ELFCLASS64
#else
@@ -985,8 +967,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
#define ELF_START_MMAP 0x08000000
-#define elf_check_arch(x) ((x) == EM_OPENRISC)
-
#define ELF_ARCH EM_OPENRISC
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
@@ -1026,8 +1006,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_SH )
-
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SH
@@ -1110,8 +1088,6 @@ static uint32_t get_elf_hwcap(void)
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_CRIS )
-
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_CRIS
@@ -1129,8 +1105,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_68K )
-
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_68K
@@ -1182,8 +1156,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#define ELF_START_MMAP (0x30000000000ULL)
-#define elf_check_arch(x) ( (x) == ELF_ARCH )
-
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_ALPHA
@@ -1203,8 +1175,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_START_MMAP (0x20000000000ULL)
-#define elf_check_arch(x) ( (x) == ELF_ARCH )
-
#define ELF_CLASS ELFCLASS64
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_S390
@@ -1218,10 +1188,41 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
#endif /* TARGET_S390X */
+#ifdef TARGET_TILEGX
+
+/* 42 bits real used address, a half for user mode */
+#define ELF_START_MMAP (0x00000020000000000ULL)
+
+#define elf_check_arch(x) ((x) == EM_TILEGX)
+
+#define ELF_CLASS ELFCLASS64
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_TILEGX
+
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
+{
+ regs->pc = infop->entry;
+ regs->sp = infop->start_stack;
+
+}
+
+#define ELF_EXEC_PAGESIZE 65536 /* TILE-Gx page size is 64KB */
+
+#endif /* TARGET_TILEGX */
+
#ifndef ELF_PLATFORM
#define ELF_PLATFORM (NULL)
#endif
+#ifndef ELF_MACHINE
+#define ELF_MACHINE ELF_ARCH
+#endif
+
+#ifndef elf_check_arch
+#define elf_check_arch(x) ((x) == ELF_ARCH)
+#endif
+
#ifndef ELF_HWCAP
#define ELF_HWCAP 0
#endif
@@ -1365,66 +1366,69 @@ static bool elf_check_ehdr(struct elfhdr *ehdr)
* to be put directly into the top of new user memory.
*
*/
-static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
- abi_ulong p)
+static abi_ulong copy_elf_strings(int argc, char **argv, char *scratch,
+ abi_ulong p, abi_ulong stack_limit)
{
- char *tmp, *tmp1, *pag = NULL;
- int len, offset = 0;
+ char *tmp;
+ int len, offset;
+ abi_ulong top = p;
if (!p) {
return 0; /* bullet-proofing */
}
+
+ offset = ((p - 1) % TARGET_PAGE_SIZE) + 1;
+
while (argc-- > 0) {
tmp = argv[argc];
if (!tmp) {
fprintf(stderr, "VFS: argc is wrong");
exit(-1);
}
- tmp1 = tmp;
- while (*tmp++);
- len = tmp - tmp1;
- if (p < len) { /* this shouldn't happen - 128kB */
+ len = strlen(tmp) + 1;
+ tmp += len;
+
+ if (len > (p - stack_limit)) {
return 0;
}
while (len) {
- --p; --tmp; --len;
- if (--offset < 0) {
- offset = p % TARGET_PAGE_SIZE;
- pag = (char *)page[p/TARGET_PAGE_SIZE];
- if (!pag) {
- pag = g_try_malloc0(TARGET_PAGE_SIZE);
- page[p/TARGET_PAGE_SIZE] = pag;
- if (!pag)
- return 0;
- }
- }
- if (len == 0 || offset == 0) {
- *(pag + offset) = *tmp;
- }
- else {
- int bytes_to_copy = (len > offset) ? offset : len;
- tmp -= bytes_to_copy;
- p -= bytes_to_copy;
- offset -= bytes_to_copy;
- len -= bytes_to_copy;
- memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
+ int bytes_to_copy = (len > offset) ? offset : len;
+ tmp -= bytes_to_copy;
+ p -= bytes_to_copy;
+ offset -= bytes_to_copy;
+ len -= bytes_to_copy;
+
+ memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);
+
+ if (offset == 0) {
+ memcpy_to_target(p, scratch, top - p);
+ top = p;
+ offset = TARGET_PAGE_SIZE;
}
}
}
+ if (offset) {
+ memcpy_to_target(p, scratch + offset, top - p);
+ }
+
return p;
}
-static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
+/* Older linux kernels provide up to MAX_ARG_PAGES (default: 32) of
+ * argument/environment space. Newer kernels (>2.6.33) allow more,
+ * dependent on stack size, but guarantee at least 32 pages for
+ * backwards compatibility.
+ */
+#define STACK_LOWER_LIMIT (32 * TARGET_PAGE_SIZE)
+
+static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
struct image_info *info)
{
- abi_ulong stack_base, size, error, guard;
- int i;
+ abi_ulong size, error, guard;
- /* Create enough stack to hold everything. If we don't use
- it for args, we'll use it for something else. */
size = guest_stack_size;
- if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) {
- size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
+ if (size < STACK_LOWER_LIMIT) {
+ size = STACK_LOWER_LIMIT;
}
guard = TARGET_PAGE_SIZE;
if (guard < qemu_real_host_page_size) {
@@ -1442,19 +1446,8 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
target_mprotect(error, guard, PROT_NONE);
info->stack_limit = error + guard;
- stack_base = info->stack_limit + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
- p += stack_base;
-
- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
- if (bprm->page[i]) {
- info->rss++;
- /* FIXME - check return value of memcpy_to_target() for failure */
- memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
- g_free(bprm->page[i]);
- }
- stack_base += TARGET_PAGE_SIZE;
- }
- return p;
+
+ return info->stack_limit + size - sizeof(void *);
}
/* Map and zero the bss. We need to explicitly zero any fractional pages
@@ -1478,8 +1471,7 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot)
host_start = (uintptr_t) g2h(elf_bss);
host_end = (uintptr_t) g2h(last_bss);
- host_map_start = (host_start + qemu_real_host_page_size - 1);
- host_map_start &= -qemu_real_host_page_size;
+ host_map_start = REAL_HOST_PAGE_ALIGN(host_start);
if (host_map_start < host_end) {
void *p = mmap((void *)host_map_start, host_end - host_map_start,
@@ -1744,7 +1736,7 @@ unsigned long init_guest_space(unsigned long host_start,
}
}
- qemu_log("Reserved 0x%lx bytes of guest address space\n", host_size);
+ qemu_log_mask(CPU_LOG_PAGE, "Reserved 0x%lx bytes of guest address space\n", host_size);
return real_start;
}
@@ -1756,7 +1748,6 @@ static void probe_guest_base(const char *image_name,
* it explicitly, and set guest_base appropriately.
* In case of error we will print a suitable message and exit.
*/
-#if defined(CONFIG_USE_GUEST_BASE)
const char *errmsg;
if (!have_guest_base && !reserved_va) {
unsigned long host_start, real_start, host_size;
@@ -1786,16 +1777,15 @@ static void probe_guest_base(const char *image_name,
}
guest_base = real_start - loaddr;
- qemu_log("Relocating guest address space from 0x"
- TARGET_ABI_FMT_lx " to 0x%lx\n",
- loaddr, real_start);
+ qemu_log_mask(CPU_LOG_PAGE, "Relocating guest address space from 0x"
+ TARGET_ABI_FMT_lx " to 0x%lx\n",
+ loaddr, real_start);
}
return;
exit_errmsg:
fprintf(stderr, "%s: %s\n", image_name, errmsg);
exit(-1);
-#endif
}
@@ -2198,10 +2188,9 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
struct image_info interp_info;
struct elfhdr elf_ex;
char *elf_interpreter = NULL;
+ char *scratch;
info->start_mmap = (abi_ulong)ELF_START_MMAP;
- info->mmap = 0;
- info->rss = 0;
load_elf_image(bprm->filename, bprm->fd, info,
&elf_interpreter, bprm->buf);
@@ -2211,18 +2200,24 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
when we load the interpreter. */
elf_ex = *(struct elfhdr *)bprm->buf;
- bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
- bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
- bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
+ /* Do this so that we can load the interpreter, if need be. We will
+ change some of these later */
+ bprm->p = setup_arg_pages(bprm, info);
+
+ scratch = g_new0(char, TARGET_PAGE_SIZE);
+ bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
+ bprm->p, info->stack_limit);
+ bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch,
+ bprm->p, info->stack_limit);
+ bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch,
+ bprm->p, info->stack_limit);
+ g_free(scratch);
+
if (!bprm->p) {
fprintf(stderr, "%s: %s\n", bprm->filename, strerror(E2BIG));
exit(-1);
}
- /* Do this so that we can load the interpreter, if need be. We will
- change some of these later */
- bprm->p = setup_arg_pages(bprm->p, bprm, info);
-
if (elf_interpreter) {
load_elf_interp(elf_interpreter, &interp_info, bprm->buf);
@@ -2850,7 +2845,7 @@ static int fill_note_info(struct elf_note_info *info,
TaskState *ts = (TaskState *)cpu->opaque;
int i;
- info->notes = g_malloc0(NUMNOTES * sizeof (struct memelfnote));
+ info->notes = g_new0(struct memelfnote, NUMNOTES);
if (info->notes == NULL)
return (-ENOMEM);
info->prstatus = g_malloc0(sizeof (*info->prstatus));
@@ -3016,7 +3011,7 @@ static int elf_core_dump(int signr, const CPUArchState *env)
if (dump_write(fd, &elf, sizeof (elf)) != 0)
goto out;
- /* fill in in-memory version of notes */
+ /* fill in the in-memory version of notes */
if (fill_note_info(&info, signr, env) < 0)
goto out;
diff --git a/qemu/linux-user/flatload.c b/qemu/linux-user/flatload.c
index 566a7a87a..f9139c399 100644
--- a/qemu/linux-user/flatload.c
+++ b/qemu/linux-user/flatload.c
@@ -33,15 +33,11 @@
/****************************************************************************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
+#include "qemu/osdep.h"
#include <sys/mman.h>
-#include <unistd.h>
#include "qemu.h"
#include "flat.h"
-#define ntohl(x) be32_to_cpu(x)
#include <target_flat.h>
//#define DEBUG
@@ -707,7 +703,7 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
int load_flt_binary(struct linux_binprm *bprm, struct image_info *info)
{
struct lib_info libinfo[MAX_SHARED_LIBS];
- abi_ulong p = bprm->p;
+ abi_ulong p;
abi_ulong stack_len;
abi_ulong start_addr;
abi_ulong sp;
diff --git a/qemu/linux-user/i386/syscall_nr.h b/qemu/linux-user/i386/syscall_nr.h
index c8f730219..bc1bc233e 100644
--- a/qemu/linux-user/i386/syscall_nr.h
+++ b/qemu/linux-user/i386/syscall_nr.h
@@ -324,7 +324,7 @@
#define TARGET_NR_epoll_pwait 319
#define TARGET_NR_utimensat 320
#define TARGET_NR_signalfd 321
-#define TARGET_NR_timerfd 322
+#define TARGET_NR_timerfd_create 322
#define TARGET_NR_eventfd 323
#define TARGET_NR_fallocate 324
#define TARGET_NR_timerfd_settime 325
@@ -353,3 +353,30 @@
#define TARGET_NR_process_vm_writev 348
#define TARGET_NR_kcmp 349
#define TARGET_NR_finit_module 350
+#define TARGET_NR_sched_setattr 351
+#define TARGET_NR_sched_getattr 352
+#define TARGET_NR_renameat2 353
+#define TARGET_NR_seccomp 354
+#define TARGET_NR_getrandom 355
+#define TARGET_NR_memfd_create 356
+#define TARGET_NR_bpf 357
+#define TARGET_NR_execveat 358
+#define TARGET_NR_socket 359
+#define TARGET_NR_socketpair 360
+#define TARGET_NR_bind 361
+#define TARGET_NR_connect 362
+#define TARGET_NR_listen 363
+#define TARGET_NR_accept4 364
+#define TARGET_NR_getsockopt 365
+#define TARGET_NR_setsockopt 366
+#define TARGET_NR_getsockname 367
+#define TARGET_NR_getpeername 368
+#define TARGET_NR_sendto 369
+#define TARGET_NR_sendmsg 370
+#define TARGET_NR_recvfrom 371
+#define TARGET_NR_recvmsg 372
+#define TARGET_NR_shutdown 373
+#define TARGET_NR_userfaultfd 374
+#define TARGET_NR_membarrier 375
+#define TARGET_NR_mlock2 376
+#define TARGET_NR_copy_file_range 377
diff --git a/qemu/linux-user/i386/syscall.h b/qemu/linux-user/i386/target_syscall.h
index 906aaac0b..0ac84dc02 100644
--- a/qemu/linux-user/i386/syscall.h
+++ b/qemu/linux-user/i386/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
/* default linux values for the selectors */
#define __USER_CS (0x23)
#define __USER_DS (0x2B)
@@ -150,3 +153,5 @@ struct target_vm86plus_struct {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/linuxload.c b/qemu/linux-user/linuxload.c
index 506e837ae..6f0d6054c 100644
--- a/qemu/linux-user/linuxload.c
+++ b/qemu/linux-user/linuxload.c
@@ -1,12 +1,6 @@
/* Code for loading Linux executables. Mostly linux kernel code. */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "qemu.h"
@@ -135,10 +129,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
struct linux_binprm *bprm)
{
int retval;
- int i;
- bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
- memset(bprm->page, 0, sizeof(bprm->page));
bprm->fd = fdexec;
bprm->filename = (char *)filename;
bprm->argc = count(argv);
@@ -172,9 +163,5 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
return retval;
}
- /* Something went wrong, return the inode and free the argument pages*/
- for (i=0 ; i<MAX_ARG_PAGES ; i++) {
- g_free(bprm->page[i]);
- }
return(retval);
}
diff --git a/qemu/linux-user/m68k-sim.c b/qemu/linux-user/m68k-sim.c
index 1994e4000..34d332d8b 100644
--- a/qemu/linux-user/m68k-sim.c
+++ b/qemu/linux-user/m68k-sim.c
@@ -17,14 +17,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
+#include "qemu/osdep.h"
#include "qemu.h"
diff --git a/qemu/linux-user/m68k/syscall_nr.h b/qemu/linux-user/m68k/syscall_nr.h
index 25f8521ec..4b50fb29b 100644
--- a/qemu/linux-user/m68k/syscall_nr.h
+++ b/qemu/linux-user/m68k/syscall_nr.h
@@ -317,7 +317,7 @@
#define TARGET_NR_epoll_pwait 315
#define TARGET_NR_utimensat 316
#define TARGET_NR_signalfd 317
-#define TARGET_NR_timerfd 318
+#define TARGET_NR_timerfd_create 318
#define TARGET_NR_eventfd 319
#define TARGET_NR_fallocate 320
#define TARGET_NR_timerfd_settime 321
@@ -349,3 +349,30 @@
#define TARGET_NR_process_vm_writev 346
#define TARGET_NR_kcmp 347
#define TARGET_NR_finit_module 348
+#define TARGET_NR_sched_setattr 349
+#define TARGET_NR_sched_getattr 350
+#define TARGET_NR_renameat2 351
+#define TARGET_NR_getrandom 352
+#define TARGET_NR_memfd_create 353
+#define TARGET_NR_bpf 354
+#define TARGET_NR_execveat 355
+#define TARGET_NR_socket 356
+#define TARGET_NR_socketpair 357
+#define TARGET_NR_bind 358
+#define TARGET_NR_connect 359
+#define TARGET_NR_listen 360
+#define TARGET_NR_accept4 361
+#define TARGET_NR_getsockopt 362
+#define TARGET_NR_setsockopt 363
+#define TARGET_NR_getsockname 364
+#define TARGET_NR_getpeername 365
+#define TARGET_NR_sendto 366
+#define TARGET_NR_sendmsg 367
+#define TARGET_NR_recvfrom 368
+#define TARGET_NR_recvmsg 369
+#define TARGET_NR_shutdown 370
+#define TARGET_NR_recvmmsg 371
+#define TARGET_NR_sendmmsg 372
+#define TARGET_NR_userfaultfd 373
+#define TARGET_NR_membarrier 374
+#define TARGET_NR_mlock2 375
diff --git a/qemu/linux-user/m68k/syscall.h b/qemu/linux-user/m68k/target_syscall.h
index 9218493a4..97a4cc0cb 100644
--- a/qemu/linux-user/m68k/syscall.h
+++ b/qemu/linux-user/m68k/target_syscall.h
@@ -1,3 +1,5 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
@@ -23,3 +25,5 @@ struct target_pt_regs {
#define TARGET_MLOCKALL_MCL_FUTURE 2
void do_m68k_simcall(CPUM68KState *, int);
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/main.c b/qemu/linux-user/main.c
index fdee98135..5f3ec9747 100644
--- a/qemu/linux-user/main.c
+++ b/qemu/linux-user/main.c
@@ -16,36 +16,45 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
+#include "qemu/osdep.h"
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include "qemu.h"
-#include "qemu-common.h"
+#include "qemu/path.h"
+#include "qemu/cutils.h"
+#include "qemu/help_option.h"
#include "cpu.h"
#include "tcg.h"
#include "qemu/timer.h"
#include "qemu/envlist.h"
#include "elf.h"
+#include "exec/log.h"
char *exec_path;
int singlestep;
-const char *filename;
-const char *argv0;
-int gdbstub_port;
-envlist_t *envlist;
+static const char *filename;
+static const char *argv0;
+static int gdbstub_port;
+static envlist_t *envlist;
static const char *cpu_model;
unsigned long mmap_min_addr;
-#if defined(CONFIG_USE_GUEST_BASE)
unsigned long guest_base;
int have_guest_base;
+
+#define EXCP_DUMP(env, fmt, ...) \
+do { \
+ CPUState *cs = ENV_GET_CPU(env); \
+ fprintf(stderr, fmt , ## __VA_ARGS__); \
+ cpu_dump_state(cs, stderr, fprintf, 0); \
+ if (qemu_log_separate()) { \
+ qemu_log(fmt, ## __VA_ARGS__); \
+ log_cpu_state(cs, 0); \
+ } \
+} while (0)
+
#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
/*
* When running 32-on-64 we should make sure we can fit all of the possible
@@ -63,9 +72,8 @@ unsigned long reserved_va = 0xf7000000;
#else
unsigned long reserved_va;
#endif
-#endif
-static void usage(void);
+static void usage(int exitcode);
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
const char *qemu_uname_release;
@@ -107,7 +115,7 @@ static int pending_cpus;
/* Make sure everything is in a consistent state for calling fork(). */
void fork_start(void)
{
- pthread_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
+ qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
pthread_mutex_lock(&exclusive_lock);
mmap_fork_start();
}
@@ -129,11 +137,11 @@ void fork_end(int child)
pthread_mutex_init(&cpu_list_mutex, NULL);
pthread_cond_init(&exclusive_cond, NULL);
pthread_cond_init(&exclusive_resume, NULL);
- pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL);
+ qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
gdbserver_fork(thread_cpu);
} else {
pthread_mutex_unlock(&exclusive_lock);
- pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
+ qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
}
}
@@ -217,7 +225,7 @@ void cpu_list_unlock(void)
uint64_t cpu_get_tsc(CPUX86State *env)
{
- return cpu_get_real_ticks();
+ return cpu_get_host_ticks();
}
static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
@@ -418,8 +426,8 @@ void cpu_loop(CPUX86State *env)
break;
default:
pc = env->segs[R_CS].base + env->eip;
- fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
- (long)pc, trapnr);
+ EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
+ (long)pc, trapnr);
abort();
}
process_pending_signals(env);
@@ -429,22 +437,54 @@ void cpu_loop(CPUX86State *env)
#ifdef TARGET_ARM
-#define get_user_code_u32(x, gaddr, doswap) \
+#define get_user_code_u32(x, gaddr, env) \
({ abi_long __r = get_user_u32((x), (gaddr)); \
- if (!__r && (doswap)) { \
+ if (!__r && bswap_code(arm_sctlr_b(env))) { \
(x) = bswap32(x); \
} \
__r; \
})
-#define get_user_code_u16(x, gaddr, doswap) \
+#define get_user_code_u16(x, gaddr, env) \
({ abi_long __r = get_user_u16((x), (gaddr)); \
- if (!__r && (doswap)) { \
+ if (!__r && bswap_code(arm_sctlr_b(env))) { \
(x) = bswap16(x); \
} \
__r; \
})
+#define get_user_data_u32(x, gaddr, env) \
+ ({ abi_long __r = get_user_u32((x), (gaddr)); \
+ if (!__r && arm_cpu_bswap_data(env)) { \
+ (x) = bswap32(x); \
+ } \
+ __r; \
+ })
+
+#define get_user_data_u16(x, gaddr, env) \
+ ({ abi_long __r = get_user_u16((x), (gaddr)); \
+ if (!__r && arm_cpu_bswap_data(env)) { \
+ (x) = bswap16(x); \
+ } \
+ __r; \
+ })
+
+#define put_user_data_u32(x, gaddr, env) \
+ ({ typeof(x) __x = (x); \
+ if (arm_cpu_bswap_data(env)) { \
+ __x = bswap32(__x); \
+ } \
+ put_user_u32(__x, (gaddr)); \
+ })
+
+#define put_user_data_u16(x, gaddr, env) \
+ ({ typeof(x) __x = (x); \
+ if (arm_cpu_bswap_data(env)) { \
+ __x = bswap16(__x); \
+ } \
+ put_user_u16(__x, (gaddr)); \
+ })
+
#ifdef TARGET_ABI32
/* Commpage handling -- there is no commpage for AArch64 */
@@ -507,7 +547,7 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
env->regs[0] = -1;
cpsr &= ~CPSR_C;
}
- cpsr_write(env, cpsr, CPSR_C);
+ cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
end_exclusive();
return;
@@ -556,7 +596,7 @@ do_kernel_trap(CPUARMState *env)
env->regs[0] = -1;
cpsr &= ~CPSR_C;
}
- cpsr_write(env, cpsr, CPSR_C);
+ cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
end_exclusive();
break;
case 0xffff0fe0: /* __kernel_get_tls */
@@ -604,11 +644,11 @@ static int do_strex(CPUARMState *env)
segv = get_user_u8(val, addr);
break;
case 1:
- segv = get_user_u16(val, addr);
+ segv = get_user_data_u16(val, addr, env);
break;
case 2:
case 3:
- segv = get_user_u32(val, addr);
+ segv = get_user_data_u32(val, addr, env);
break;
default:
abort();
@@ -619,12 +659,16 @@ static int do_strex(CPUARMState *env)
}
if (size == 3) {
uint32_t valhi;
- segv = get_user_u32(valhi, addr + 4);
+ segv = get_user_data_u32(valhi, addr + 4, env);
if (segv) {
env->exception.vaddress = addr + 4;
goto done;
}
- val = deposit64(val, 32, 32, valhi);
+ if (arm_cpu_bswap_data(env)) {
+ val = deposit64((uint64_t)valhi, 32, 32, val);
+ } else {
+ val = deposit64(val, 32, 32, valhi);
+ }
}
if (val != env->exclusive_val) {
goto fail;
@@ -636,11 +680,11 @@ static int do_strex(CPUARMState *env)
segv = put_user_u8(val, addr);
break;
case 1:
- segv = put_user_u16(val, addr);
+ segv = put_user_data_u16(val, addr, env);
break;
case 2:
case 3:
- segv = put_user_u32(val, addr);
+ segv = put_user_data_u32(val, addr, env);
break;
}
if (segv) {
@@ -649,7 +693,7 @@ static int do_strex(CPUARMState *env)
}
if (size == 3) {
val = env->regs[(env->exclusive_info >> 12) & 0xf];
- segv = put_user_u32(val, addr + 4);
+ segv = put_user_data_u32(val, addr + 4, env);
if (segv) {
env->exception.vaddress = addr + 4;
goto done;
@@ -686,7 +730,7 @@ void cpu_loop(CPUARMState *env)
/* we handle the FPU emulation here, as Linux */
/* we get the opcode */
/* FIXME - what to do if get_user() fails? */
- get_user_code_u32(opcode, env->regs[15], env->bswap_code);
+ get_user_code_u32(opcode, env->regs[15], env);
rc = EmulateAll(opcode, &ts->fpa, env);
if (rc == 0) { /* illegal instruction */
@@ -756,25 +800,23 @@ void cpu_loop(CPUARMState *env)
if (trapnr == EXCP_BKPT) {
if (env->thumb) {
/* FIXME - what to do if get_user() fails? */
- get_user_code_u16(insn, env->regs[15], env->bswap_code);
+ get_user_code_u16(insn, env->regs[15], env);
n = insn & 0xff;
env->regs[15] += 2;
} else {
/* FIXME - what to do if get_user() fails? */
- get_user_code_u32(insn, env->regs[15], env->bswap_code);
+ get_user_code_u32(insn, env->regs[15], env);
n = (insn & 0xf) | ((insn >> 4) & 0xff0);
env->regs[15] += 4;
}
} else {
if (env->thumb) {
/* FIXME - what to do if get_user() fails? */
- get_user_code_u16(insn, env->regs[15] - 2,
- env->bswap_code);
+ get_user_code_u16(insn, env->regs[15] - 2, env);
n = insn & 0xff;
} else {
/* FIXME - what to do if get_user() fails? */
- get_user_code_u32(insn, env->regs[15] - 4,
- env->bswap_code);
+ get_user_code_u32(insn, env->regs[15] - 4, env);
n = insn & 0xffffff;
}
}
@@ -865,11 +907,12 @@ void cpu_loop(CPUARMState *env)
if (do_kernel_trap(env))
goto error;
break;
+ case EXCP_YIELD:
+ /* nothing to do here for user-mode, just resume guest code */
+ break;
default:
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -1054,10 +1097,14 @@ void cpu_loop(CPUARMState *env)
queue_signal(env, info.si_signo, &info);
}
break;
+ case EXCP_SEMIHOST:
+ env->xregs[0] = do_arm_semihosting(env);
+ break;
+ case EXCP_YIELD:
+ /* nothing to do here for user-mode, just resume guest code */
+ break;
default:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -1147,8 +1194,7 @@ void cpu_loop(CPUUniCore32State *env)
}
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
#endif
@@ -1413,7 +1459,7 @@ void cpu_loop (CPUSPARCState *env)
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit (1);
+ exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
@@ -1424,7 +1470,7 @@ void cpu_loop (CPUSPARCState *env)
#ifdef TARGET_PPC
static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
{
- return cpu_get_real_ticks();
+ return cpu_get_host_ticks();
}
uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
@@ -1466,17 +1512,6 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
return -1;
}
-#define EXCP_DUMP(env, fmt, ...) \
-do { \
- CPUState *cs = ENV_GET_CPU(env); \
- fprintf(stderr, fmt , ## __VA_ARGS__); \
- cpu_dump_state(cs, stderr, fprintf, 0); \
- qemu_log(fmt, ## __VA_ARGS__); \
- if (qemu_log_enabled()) { \
- log_cpu_state(cs, 0); \
- } \
-} while (0)
-
static int do_store_exclusive(CPUPPCState *env)
{
target_ulong addr;
@@ -1649,7 +1684,7 @@ void cpu_loop(CPUPPCState *env)
info.si_signo = TARGET_SIGBUS;
info.si_errno = 0;
info.si_code = TARGET_BUS_ADRALN;
- info._sifields._sigfault._addr = env->nip - 4;
+ info._sifields._sigfault._addr = env->nip;
queue_signal(env, info.si_signo, &info);
break;
case POWERPC_EXCP_PROGRAM: /* Program exception */
@@ -2635,9 +2670,7 @@ done_syscall:
break;
default:
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -2660,11 +2693,11 @@ void cpu_loop(CPUOpenRISCState *env)
switch (trapnr) {
case EXCP_RESET:
- qemu_log("\nReset request, exit, pc is %#x\n", env->pc);
- exit(1);
+ qemu_log_mask(CPU_LOG_INT, "\nReset request, exit, pc is %#x\n", env->pc);
+ exit(EXIT_FAILURE);
break;
case EXCP_BUSERR:
- qemu_log("\nBus error, exit, pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nBus error, exit, pc is %#x\n", env->pc);
gdbsig = TARGET_SIGBUS;
break;
case EXCP_DPF:
@@ -2673,25 +2706,25 @@ void cpu_loop(CPUOpenRISCState *env)
gdbsig = TARGET_SIGSEGV;
break;
case EXCP_TICK:
- qemu_log("\nTick time interrupt pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nTick time interrupt pc is %#x\n", env->pc);
break;
case EXCP_ALIGN:
- qemu_log("\nAlignment pc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nAlignment pc is %#x\n", env->pc);
gdbsig = TARGET_SIGBUS;
break;
case EXCP_ILLEGAL:
- qemu_log("\nIllegal instructionpc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nIllegal instructionpc is %#x\n", env->pc);
gdbsig = TARGET_SIGILL;
break;
case EXCP_INT:
- qemu_log("\nExternal interruptpc is %#x\n", env->pc);
+ qemu_log_mask(CPU_LOG_INT, "\nExternal interruptpc is %#x\n", env->pc);
break;
case EXCP_DTLBMISS:
case EXCP_ITLBMISS:
- qemu_log("\nTLB miss\n");
+ qemu_log_mask(CPU_LOG_INT, "\nTLB miss\n");
break;
case EXCP_RANGE:
- qemu_log("\nRange\n");
+ qemu_log_mask(CPU_LOG_INT, "\nRange\n");
gdbsig = TARGET_SIGSEGV;
break;
case EXCP_SYSCALL:
@@ -2706,26 +2739,25 @@ void cpu_loop(CPUOpenRISCState *env)
env->gpr[8], 0, 0);
break;
case EXCP_FPE:
- qemu_log("\nFloating point error\n");
+ qemu_log_mask(CPU_LOG_INT, "\nFloating point error\n");
break;
case EXCP_TRAP:
- qemu_log("\nTrap\n");
+ qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
gdbsig = TARGET_SIGTRAP;
break;
case EXCP_NR:
- qemu_log("\nNR\n");
+ qemu_log_mask(CPU_LOG_INT, "\nNR\n");
break;
default:
- qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
+ EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
gdbsig = TARGET_SIGILL;
break;
}
if (gdbsig) {
gdb_handlesig(cs, gdbsig);
if (gdbsig != TARGET_SIGTRAP) {
- exit(1);
+ exit(EXIT_FAILURE);
}
}
@@ -2790,7 +2822,7 @@ void cpu_loop(CPUSH4State *env)
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit (1);
+ exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
@@ -2851,7 +2883,7 @@ void cpu_loop(CPUCRISState *env)
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit (1);
+ exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
@@ -2932,7 +2964,7 @@ void cpu_loop(CPUMBState *env)
printf ("Unhandled hw-exception: 0x%x\n",
env->sregs[SR_ESR] & ESR_EC_MASK);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit (1);
+ exit(EXIT_FAILURE);
break;
}
break;
@@ -2953,7 +2985,7 @@ void cpu_loop(CPUMBState *env)
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit (1);
+ exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
@@ -3046,9 +3078,7 @@ void cpu_loop(CPUM68KState *env)
}
break;
default:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
- trapnr);
- cpu_dump_state(cs, stderr, fprintf, 0);
+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
@@ -3122,17 +3152,17 @@ void cpu_loop(CPUAlphaState *env)
switch (trapnr) {
case EXCP_RESET:
fprintf(stderr, "Reset requested. Exit\n");
- exit(1);
+ exit(EXIT_FAILURE);
break;
case EXCP_MCHK:
fprintf(stderr, "Machine check exception. Exit\n");
- exit(1);
+ exit(EXIT_FAILURE);
break;
case EXCP_SMP_INTERRUPT:
case EXCP_CLK_INTERRUPT:
case EXCP_DEV_INTERRUPT:
fprintf(stderr, "External interrupt. Exit\n");
- exit(1);
+ exit(EXIT_FAILURE);
break;
case EXCP_MMFAULT:
env->lock_addr = -1;
@@ -3282,7 +3312,7 @@ void cpu_loop(CPUAlphaState *env)
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit (1);
+ exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
@@ -3386,7 +3416,7 @@ void cpu_loop(CPUS390XState *env)
default:
fprintf(stderr, "Unhandled program exception: %#x\n", n);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit(1);
+ exit(EXIT_FAILURE);
}
break;
@@ -3403,7 +3433,7 @@ void cpu_loop(CPUS390XState *env)
default:
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, fprintf, 0);
- exit(1);
+ exit(EXIT_FAILURE);
}
process_pending_signals (env);
}
@@ -3411,6 +3441,252 @@ void cpu_loop(CPUS390XState *env)
#endif /* TARGET_S390X */
+#ifdef TARGET_TILEGX
+
+static void gen_sigill_reg(CPUTLGState *env)
+{
+ target_siginfo_t info;
+
+ info.si_signo = TARGET_SIGILL;
+ info.si_errno = 0;
+ info.si_code = TARGET_ILL_PRVREG;
+ info._sifields._sigfault._addr = env->pc;
+ queue_signal(env, info.si_signo, &info);
+}
+
+static void do_signal(CPUTLGState *env, int signo, int sigcode)
+{
+ target_siginfo_t info;
+
+ info.si_signo = signo;
+ info.si_errno = 0;
+ info._sifields._sigfault._addr = env->pc;
+
+ if (signo == TARGET_SIGSEGV) {
+ /* The passed in sigcode is a dummy; check for a page mapping
+ and pass either MAPERR or ACCERR. */
+ target_ulong addr = env->excaddr;
+ info._sifields._sigfault._addr = addr;
+ if (page_check_range(addr, 1, PAGE_VALID) < 0) {
+ sigcode = TARGET_SEGV_MAPERR;
+ } else {
+ sigcode = TARGET_SEGV_ACCERR;
+ }
+ }
+ info.si_code = sigcode;
+
+ queue_signal(env, info.si_signo, &info);
+}
+
+static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
+{
+ env->excaddr = addr;
+ do_signal(env, TARGET_SIGSEGV, 0);
+}
+
+static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val)
+{
+ if (unlikely(reg >= TILEGX_R_COUNT)) {
+ switch (reg) {
+ case TILEGX_R_SN:
+ case TILEGX_R_ZERO:
+ return;
+ case TILEGX_R_IDN0:
+ case TILEGX_R_IDN1:
+ case TILEGX_R_UDN0:
+ case TILEGX_R_UDN1:
+ case TILEGX_R_UDN2:
+ case TILEGX_R_UDN3:
+ gen_sigill_reg(env);
+ return;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ env->regs[reg] = val;
+}
+
+/*
+ * Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
+ * memory at the address held in the first source register. If the values are
+ * not equal, then no memory operation is performed. If the values are equal,
+ * the 8-byte quantity from the second source register is written into memory
+ * at the address held in the first source register. In either case, the result
+ * of the instruction is the value read from memory. The compare and write to
+ * memory are atomic and thus can be used for synchronization purposes. This
+ * instruction only operates for addresses aligned to a 8-byte boundary.
+ * Unaligned memory access causes an Unaligned Data Reference interrupt.
+ *
+ * Functional Description (64-bit)
+ * uint64_t memVal = memoryReadDoubleWord (rf[SrcA]);
+ * rf[Dest] = memVal;
+ * if (memVal == SPR[CmpValueSPR])
+ * memoryWriteDoubleWord (rf[SrcA], rf[SrcB]);
+ *
+ * Functional Description (32-bit)
+ * uint64_t memVal = signExtend32 (memoryReadWord (rf[SrcA]));
+ * rf[Dest] = memVal;
+ * if (memVal == signExtend32 (SPR[CmpValueSPR]))
+ * memoryWriteWord (rf[SrcA], rf[SrcB]);
+ *
+ *
+ * This function also processes exch and exch4 which need not process SPR.
+ */
+static void do_exch(CPUTLGState *env, bool quad, bool cmp)
+{
+ target_ulong addr;
+ target_long val, sprval;
+
+ start_exclusive();
+
+ addr = env->atomic_srca;
+ if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
+ goto sigsegv_maperr;
+ }
+
+ if (cmp) {
+ if (quad) {
+ sprval = env->spregs[TILEGX_SPR_CMPEXCH];
+ } else {
+ sprval = sextract64(env->spregs[TILEGX_SPR_CMPEXCH], 0, 32);
+ }
+ }
+
+ if (!cmp || val == sprval) {
+ target_long valb = env->atomic_srcb;
+ if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
+ goto sigsegv_maperr;
+ }
+ }
+
+ set_regval(env, env->atomic_dstr, val);
+ end_exclusive();
+ return;
+
+ sigsegv_maperr:
+ end_exclusive();
+ gen_sigsegv_maperr(env, addr);
+}
+
+static void do_fetch(CPUTLGState *env, int trapnr, bool quad)
+{
+ int8_t write = 1;
+ target_ulong addr;
+ target_long val, valb;
+
+ start_exclusive();
+
+ addr = env->atomic_srca;
+ valb = env->atomic_srcb;
+ if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
+ goto sigsegv_maperr;
+ }
+
+ switch (trapnr) {
+ case TILEGX_EXCP_OPCODE_FETCHADD:
+ case TILEGX_EXCP_OPCODE_FETCHADD4:
+ valb += val;
+ break;
+ case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
+ valb += val;
+ if (valb < 0) {
+ write = 0;
+ }
+ break;
+ case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
+ valb += val;
+ if ((int32_t)valb < 0) {
+ write = 0;
+ }
+ break;
+ case TILEGX_EXCP_OPCODE_FETCHAND:
+ case TILEGX_EXCP_OPCODE_FETCHAND4:
+ valb &= val;
+ break;
+ case TILEGX_EXCP_OPCODE_FETCHOR:
+ case TILEGX_EXCP_OPCODE_FETCHOR4:
+ valb |= val;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (write) {
+ if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
+ goto sigsegv_maperr;
+ }
+ }
+
+ set_regval(env, env->atomic_dstr, val);
+ end_exclusive();
+ return;
+
+ sigsegv_maperr:
+ end_exclusive();
+ gen_sigsegv_maperr(env, addr);
+}
+
+void cpu_loop(CPUTLGState *env)
+{
+ CPUState *cs = CPU(tilegx_env_get_cpu(env));
+ int trapnr;
+
+ while (1) {
+ cpu_exec_start(cs);
+ trapnr = cpu_tilegx_exec(cs);
+ cpu_exec_end(cs);
+ switch (trapnr) {
+ case TILEGX_EXCP_SYSCALL:
+ env->regs[TILEGX_R_RE] = do_syscall(env, env->regs[TILEGX_R_NR],
+ env->regs[0], env->regs[1],
+ env->regs[2], env->regs[3],
+ env->regs[4], env->regs[5],
+ env->regs[6], env->regs[7]);
+ env->regs[TILEGX_R_ERR] = TILEGX_IS_ERRNO(env->regs[TILEGX_R_RE])
+ ? - env->regs[TILEGX_R_RE]
+ : 0;
+ break;
+ case TILEGX_EXCP_OPCODE_EXCH:
+ do_exch(env, true, false);
+ break;
+ case TILEGX_EXCP_OPCODE_EXCH4:
+ do_exch(env, false, false);
+ break;
+ case TILEGX_EXCP_OPCODE_CMPEXCH:
+ do_exch(env, true, true);
+ break;
+ case TILEGX_EXCP_OPCODE_CMPEXCH4:
+ do_exch(env, false, true);
+ break;
+ case TILEGX_EXCP_OPCODE_FETCHADD:
+ case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
+ case TILEGX_EXCP_OPCODE_FETCHAND:
+ case TILEGX_EXCP_OPCODE_FETCHOR:
+ do_fetch(env, trapnr, true);
+ break;
+ case TILEGX_EXCP_OPCODE_FETCHADD4:
+ case TILEGX_EXCP_OPCODE_FETCHADDGEZ4:
+ case TILEGX_EXCP_OPCODE_FETCHAND4:
+ case TILEGX_EXCP_OPCODE_FETCHOR4:
+ do_fetch(env, trapnr, false);
+ break;
+ case TILEGX_EXCP_SIGNAL:
+ do_signal(env, env->signo, env->sigcode);
+ break;
+ case TILEGX_EXCP_REG_IDN_ACCESS:
+ case TILEGX_EXCP_REG_UDN_ACCESS:
+ gen_sigill_reg(env);
+ break;
+ default:
+ fprintf(stderr, "trapnr is %d[0x%x].\n", trapnr, trapnr);
+ g_assert_not_reached();
+ }
+ process_pending_signals(env);
+ }
+}
+
+#endif
+
THREAD CPUState *thread_cpu;
void task_settid(TaskState *ts)
@@ -3472,7 +3748,7 @@ CPUArchState *cpu_copy(CPUArchState *env)
static void handle_arg_help(const char *arg)
{
- usage();
+ usage(EXIT_SUCCESS);
}
static void handle_arg_log(const char *arg)
@@ -3482,7 +3758,7 @@ static void handle_arg_log(const char *arg)
mask = qemu_str_to_log_mask(arg);
if (!mask) {
qemu_print_log_usage(stdout);
- exit(1);
+ exit(EXIT_FAILURE);
}
qemu_set_log(mask);
}
@@ -3498,7 +3774,7 @@ static void handle_arg_set_env(const char *arg)
r = p = strdup(arg);
while ((token = strsep(&p, ",")) != NULL) {
if (envlist_setenv(envlist, token) != 0) {
- usage();
+ usage(EXIT_FAILURE);
}
}
free(r);
@@ -3510,7 +3786,7 @@ static void handle_arg_unset_env(const char *arg)
r = p = strdup(arg);
while ((token = strsep(&p, ",")) != NULL) {
if (envlist_unsetenv(envlist, token) != 0) {
- usage();
+ usage(EXIT_FAILURE);
}
}
free(r);
@@ -3526,7 +3802,7 @@ static void handle_arg_stack_size(const char *arg)
char *p;
guest_stack_size = strtoul(arg, &p, 0);
if (guest_stack_size == 0) {
- usage();
+ usage(EXIT_FAILURE);
}
if (*p == 'M') {
@@ -3547,7 +3823,7 @@ static void handle_arg_pagesize(const char *arg)
if (qemu_host_page_size == 0 ||
(qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
fprintf(stderr, "page size must be a power of two\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
}
@@ -3557,7 +3833,7 @@ static void handle_arg_randseed(const char *arg)
if (parse_uint_full(arg, &seed, 0) != 0 || seed > UINT_MAX) {
fprintf(stderr, "Invalid seed number: %s\n", arg);
- exit(1);
+ exit(EXIT_FAILURE);
}
srand(seed);
}
@@ -3580,11 +3856,10 @@ static void handle_arg_cpu(const char *arg)
#if defined(cpu_list)
cpu_list(stdout, &fprintf);
#endif
- exit(1);
+ exit(EXIT_FAILURE);
}
}
-#if defined(CONFIG_USE_GUEST_BASE)
static void handle_arg_guest_base(const char *arg)
{
guest_base = strtol(arg, NULL, 0);
@@ -3618,15 +3893,14 @@ static void handle_arg_reserved_va(const char *arg)
#endif
) {
fprintf(stderr, "Reserved virtual address too big\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
}
if (*p) {
fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
- exit(1);
+ exit(EXIT_FAILURE);
}
}
-#endif
static void handle_arg_singlestep(const char *arg)
{
@@ -3642,7 +3916,7 @@ static void handle_arg_version(const char *arg)
{
printf("qemu-" TARGET_NAME " version " QEMU_VERSION QEMU_PKGVERSION
", Copyright (c) 2003-2008 Fabrice Bellard\n");
- exit(0);
+ exit(EXIT_SUCCESS);
}
struct qemu_argument {
@@ -3657,6 +3931,8 @@ struct qemu_argument {
static const struct qemu_argument arg_table[] = {
{"h", "", false, handle_arg_help,
"", "print this help"},
+ {"help", "", false, handle_arg_help,
+ "", ""},
{"g", "QEMU_GDB", true, handle_arg_gdb,
"port", "wait gdb connection to 'port'"},
{"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix,
@@ -3673,12 +3949,10 @@ static const struct qemu_argument arg_table[] = {
"argv0", "forces target process argv[0] to be 'argv0'"},
{"r", "QEMU_UNAME", true, handle_arg_uname,
"uname", "set qemu uname release string to 'uname'"},
-#if defined(CONFIG_USE_GUEST_BASE)
{"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base,
"address", "set guest_base address to 'address'"},
{"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
"size", "reserve 'size' bytes for guest virtual address space"},
-#endif
{"d", "QEMU_LOG", true, handle_arg_log,
"item[,...]", "enable logging of specified items "
"(use '-d help' for a list of items)"},
@@ -3697,7 +3971,7 @@ static const struct qemu_argument arg_table[] = {
{NULL, NULL, false, NULL, NULL, NULL}
};
-static void usage(void)
+static void usage(int exitcode)
{
const struct qemu_argument *arginfo;
int maxarglen;
@@ -3764,7 +4038,7 @@ static void usage(void)
"Note that if you provide several changes to a single variable\n"
"the last change will stay in effect.\n");
- exit(1);
+ exit(exitcode);
}
static int parse_args(int argc, char **argv)
@@ -3798,12 +4072,18 @@ static int parse_args(int argc, char **argv)
if (!strcmp(r, "-")) {
break;
}
+ /* Treat --foo the same as -foo. */
+ if (r[0] == '-') {
+ r++;
+ }
for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
if (!strcmp(r, arginfo->argv)) {
if (arginfo->has_arg) {
if (optind >= argc) {
- usage();
+ (void) fprintf(stderr,
+ "qemu: missing argument for option '%s'\n", r);
+ exit(EXIT_FAILURE);
}
arginfo->handle_opt(argv[optind]);
optind++;
@@ -3816,12 +4096,14 @@ static int parse_args(int argc, char **argv)
/* no option matched the current argv */
if (arginfo->handle_opt == NULL) {
- usage();
+ (void) fprintf(stderr, "qemu: unknown option '%s'\n", r);
+ exit(EXIT_FAILURE);
}
}
if (optind >= argc) {
- usage();
+ (void) fprintf(stderr, "qemu: no user program specified\n");
+ exit(EXIT_FAILURE);
}
filename = argv[optind];
@@ -3850,7 +4132,7 @@ int main(int argc, char **argv, char **envp)
if ((envlist = envlist_create()) == NULL) {
(void) fprintf(stderr, "Unable to allocate envlist\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
/* add current environment into the list */
@@ -3920,7 +4202,7 @@ int main(int argc, char **argv, char **envp)
cpu_model = "or1200";
#elif defined(TARGET_PPC)
# ifdef TARGET_PPC64
- cpu_model = "POWER7";
+ cpu_model = "POWER8";
# else
cpu_model = "750";
# endif
@@ -3936,7 +4218,7 @@ int main(int argc, char **argv, char **envp)
cpu = cpu_init(cpu_model);
if (!cpu) {
fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
env = cpu->env_ptr;
cpu_reset(cpu);
@@ -3954,7 +4236,6 @@ int main(int argc, char **argv, char **envp)
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
-#if defined(CONFIG_USE_GUEST_BASE)
/*
* Now that page sizes are configured in cpu_init() we can do
* proper page alignment for guest_base.
@@ -3969,14 +4250,13 @@ int main(int argc, char **argv, char **envp)
"space for use as guest address space (check your virtual "
"memory ulimit setting or reserve less using -R option)\n",
reserved_va);
- exit(1);
+ exit(EXIT_FAILURE);
}
if (reserved_va) {
mmap_next_start = reserved_va;
}
}
-#endif /* CONFIG_USE_GUEST_BASE */
/*
* Read in mmap_min_addr kernel parameter. This value is used
@@ -3990,7 +4270,7 @@ int main(int argc, char **argv, char **envp)
unsigned long tmp;
if (fscanf(fp, "%lu", &tmp) == 1) {
mmap_min_addr = tmp;
- qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
+ qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
}
fclose(fp);
}
@@ -4003,7 +4283,7 @@ int main(int argc, char **argv, char **envp)
target_argv = calloc(target_argc + 1, sizeof (char *));
if (target_argv == NULL) {
(void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
/*
@@ -4019,7 +4299,7 @@ int main(int argc, char **argv, char **envp)
}
target_argv[target_argc] = NULL;
- ts = g_malloc0 (sizeof(TaskState));
+ ts = g_new0(TaskState, 1);
init_task_state(ts);
/* build Task State */
ts->info = info;
@@ -4032,7 +4312,7 @@ int main(int argc, char **argv, char **envp)
execfd = open(filename, O_RDONLY);
if (execfd < 0) {
printf("Error while loading %s: %s\n", filename, strerror(errno));
- _exit(1);
+ _exit(EXIT_FAILURE);
}
}
@@ -4040,7 +4320,7 @@ int main(int argc, char **argv, char **envp)
info, &bprm);
if (ret != 0) {
printf("Error while loading %s: %s\n", filename, strerror(-ret));
- _exit(1);
+ _exit(EXIT_FAILURE);
}
for (wrk = target_environ; *wrk; wrk++) {
@@ -4049,10 +4329,8 @@ int main(int argc, char **argv, char **envp)
free(target_environ);
- if (qemu_log_enabled()) {
-#if defined(CONFIG_USE_GUEST_BASE)
+ if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
qemu_log("guest_base 0x%lx\n", guest_base);
-#endif
log_page_dump();
qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
@@ -4072,12 +4350,10 @@ int main(int argc, char **argv, char **envp)
syscall_init();
signal_init();
-#if defined(CONFIG_USE_GUEST_BASE)
/* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account. */
tcg_prologue_init(&tcg_ctx);
-#endif
#if defined(TARGET_I386)
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
@@ -4090,7 +4366,7 @@ int main(int argc, char **argv, char **envp)
/* enable 64 bit mode if possible */
if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
env->cr[4] |= CR4_PAE_MASK;
env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
@@ -4200,7 +4476,7 @@ int main(int argc, char **argv, char **envp)
if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
fprintf(stderr,
"The selected ARM CPU does not support 64 bit mode\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
for (i = 0; i < 31; i++) {
@@ -4212,15 +4488,21 @@ int main(int argc, char **argv, char **envp)
#elif defined(TARGET_ARM)
{
int i;
- cpsr_write(env, regs->uregs[16], 0xffffffff);
+ cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
+ CPSRWriteByInstr);
for(i = 0; i < 16; i++) {
env->regs[i] = regs->uregs[i];
}
+#ifdef TARGET_WORDS_BIGENDIAN
/* Enable BE8. */
if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
&& (info->elf_flags & EF_ARM_BE8)) {
- env->bswap_code = 1;
+ env->uncached_cpsr |= CPSR_E;
+ env->cp15.sctlr_el[1] |= SCTLR_E0E;
+ } else {
+ env->cp15.sctlr_el[1] |= SCTLR_B;
}
+#endif
}
#elif defined(TARGET_UNICORE32)
{
@@ -4386,6 +4668,17 @@ int main(int argc, char **argv, char **envp)
env->psw.mask = regs->psw.mask;
env->psw.addr = regs->psw.addr;
}
+#elif defined(TARGET_TILEGX)
+ {
+ int i;
+ for (i = 0; i < TILEGX_R_COUNT; i++) {
+ env->regs[i] = regs->regs[i];
+ }
+ for (i = 0; i < TILEGX_SPR_COUNT; i++) {
+ env->spregs[i] = 0;
+ }
+ env->pc = regs->pc;
+ }
#else
#error unsupported target CPU
#endif
@@ -4401,7 +4694,7 @@ int main(int argc, char **argv, char **envp)
if (gdbserver_start(gdbstub_port) < 0) {
fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
gdbstub_port);
- exit(1);
+ exit(EXIT_FAILURE);
}
gdb_handlesig(cpu, 0);
}
diff --git a/qemu/linux-user/microblaze/syscall_nr.h b/qemu/linux-user/microblaze/syscall_nr.h
index 6f530f9d1..0704449ba 100644
--- a/qemu/linux-user/microblaze/syscall_nr.h
+++ b/qemu/linux-user/microblaze/syscall_nr.h
@@ -382,3 +382,11 @@
#define TARGET_NR_process_vm_writev 378
#define TARGET_NR_kcmp 379
#define TARGET_NR_finit_module 380
+#define TARGET_NR_sched_setattr 381
+#define TARGET_NR_sched_getattr 382
+#define TARGET_NR_renameat2 383
+#define TARGET_NR_seccomp 384
+#define TARGET_NR_getrandom 385
+#define TARGET_NR_memfd_create 386
+#define TARGET_NR_bpf 387
+#define TARGET_NR_execveat 388
diff --git a/qemu/linux-user/microblaze/syscall.h b/qemu/linux-user/microblaze/target_syscall.h
index 3c1ed27c0..3c1ed27c0 100644
--- a/qemu/linux-user/microblaze/syscall.h
+++ b/qemu/linux-user/microblaze/target_syscall.h
diff --git a/qemu/linux-user/mips/syscall_nr.h b/qemu/linux-user/mips/syscall_nr.h
index 2d1a13ee2..6819f865e 100644
--- a/qemu/linux-user/mips/syscall_nr.h
+++ b/qemu/linux-user/mips/syscall_nr.h
@@ -351,3 +351,15 @@
#define TARGET_NR_process_vm_writev (TARGET_NR_Linux + 346)
#define TARGET_NR_kcmp (TARGET_NR_Linux + 347)
#define TARGET_NR_finit_module (TARGET_NR_Linux + 348)
+
+#define TARGET_NR_sched_setattr (TARGET_NR_Linux + 349)
+#define TARGET_NR_sched_getattr (TARGET_NR_Linux + 350)
+#define TARGET_NR_renameat2 (TARGET_NR_Linux + 351)
+#define TARGET_NR_seccomp (TARGET_NR_Linux + 352)
+#define TARGET_NR_getrandom (TARGET_NR_Linux + 353)
+#define TARGET_NR_memfd_create (TARGET_NR_Linux + 354)
+#define TARGET_NR_bpf (TARGET_NR_Linux + 355)
+#define TARGET_NR_execveat (TARGET_NR_Linux + 356)
+#define TARGET_NR_userfaultfd (TARGET_NR_Linux + 357)
+#define TARGET_NR_membarrier (TARGET_NR_Linux + 358)
+#define TARGET_NR_mlock2 (TARGET_NR_Linux + 359)
diff --git a/qemu/linux-user/mips/syscall.h b/qemu/linux-user/mips/target_syscall.h
index 35ca23b16..68db160e5 100644
--- a/qemu/linux-user/mips/syscall.h
+++ b/qemu/linux-user/mips/target_syscall.h
@@ -1,3 +1,5 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
@@ -231,3 +233,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/mips64/syscall_nr.h b/qemu/linux-user/mips64/syscall_nr.h
index 004232a8a..746cc267e 100644
--- a/qemu/linux-user/mips64/syscall_nr.h
+++ b/qemu/linux-user/mips64/syscall_nr.h
@@ -316,6 +316,18 @@
#define TARGET_NR_process_vm_writev (TARGET_NR_Linux + 310)
#define TARGET_NR_kcmp (TARGET_NR_Linux + 311)
#define TARGET_NR_finit_module (TARGET_NR_Linux + 312)
+#define TARGET_NR_sched_setattr (TARGET_NR_Linux + 313)
+#define TARGET_NR_sched_getattr (TARGET_NR_Linux + 314)
+#define TARGET_NR_renameat2 (TARGET_NR_Linux + 315)
+#define TARGET_NR_seccomp (TARGET_NR_Linux + 316)
+#define TARGET_NR_getrandom (TARGET_NR_Linux + 317)
+#define TARGET_NR_memfd_create (TARGET_NR_Linux + 318)
+#define TARGET_NR_bpf (TARGET_NR_Linux + 319)
+#define TARGET_NR_execveat (TARGET_NR_Linux + 320)
+#define TARGET_NR_userfaultfd (TARGET_NR_Linux + 321)
+#define TARGET_NR_membarrier (TARGET_NR_Linux + 322)
+#define TARGET_NR_mlock2 (TARGET_NR_Linux + 323)
+
#else
/*
* Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -630,4 +642,15 @@
#define TARGET_NR_kcmp (TARGET_NR_Linux + 306)
#define TARGET_NR_finit_module (TARGET_NR_Linux + 307)
#define TARGET_NR_getdents64 (TARGET_NR_Linux + 308)
+#define TARGET_NR_sched_setattr (TARGET_NR_Linux + 309)
+#define TARGET_NR_sched_getattr (TARGET_NR_Linux + 310)
+#define TARGET_NR_renameat2 (TARGET_NR_Linux + 311)
+#define TARGET_NR_seccomp (TARGET_NR_Linux + 312)
+#define TARGET_NR_getrandom (TARGET_NR_Linux + 313)
+#define TARGET_NR_memfd_create (TARGET_NR_Linux + 314)
+#define TARGET_NR_bpf (TARGET_NR_Linux + 315)
+#define TARGET_NR_execveat (TARGET_NR_Linux + 316)
+#define TARGET_NR_userfaultfd (TARGET_NR_Linux + 317)
+#define TARGET_NR_membarrier (TARGET_NR_Linux + 318)
+#define TARGET_NR_mlock2 (TARGET_NR_Linux + 319)
#endif
diff --git a/qemu/linux-user/mips64/syscall.h b/qemu/linux-user/mips64/target_syscall.h
index 6733107dd..0e0c2d232 100644
--- a/qemu/linux-user/mips64/syscall.h
+++ b/qemu/linux-user/mips64/target_syscall.h
@@ -1,3 +1,5 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
@@ -228,3 +230,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/mmap.c b/qemu/linux-user/mmap.c
index 78e1b2df4..3519147bc 100644
--- a/qemu/linux-user/mmap.c
+++ b/qemu/linux-user/mmap.c
@@ -16,14 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include "qemu/osdep.h"
#include <sys/mman.h>
#include <linux/mman.h>
#include <linux/unistd.h>
@@ -186,10 +179,12 @@ static int mmap_frag(abi_ulong real_start,
if (prot_new != (prot1 | PROT_WRITE))
mprotect(host_start, qemu_host_page_size, prot_new);
} else {
- /* just update the protection */
if (prot_new != prot1) {
mprotect(host_start, qemu_host_page_size, prot_new);
}
+ if (prot_new & PROT_WRITE) {
+ memset(g2h(start), 0, end - start);
+ }
}
return 0;
}
@@ -206,7 +201,6 @@ abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
unsigned long last_brk;
-#ifdef CONFIG_USE_GUEST_BASE
/* Subroutine of mmap_find_vma, used when we have pre-allocated a chunk
of guest address space. */
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
@@ -216,14 +210,14 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
int prot;
int looped = 0;
- if (size > RESERVED_VA) {
+ if (size > reserved_va) {
return (abi_ulong)-1;
}
size = HOST_PAGE_ALIGN(size);
end_addr = start + size;
- if (end_addr > RESERVED_VA) {
- end_addr = RESERVED_VA;
+ if (end_addr > reserved_va) {
+ end_addr = reserved_va;
}
addr = end_addr - qemu_host_page_size;
@@ -232,7 +226,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
if (looped) {
return (abi_ulong)-1;
}
- end_addr = RESERVED_VA;
+ end_addr = reserved_va;
addr = end_addr - qemu_host_page_size;
looped = 1;
continue;
@@ -253,7 +247,6 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
return addr;
}
-#endif
/*
* Find and reserve a free memory area of size 'size'. The search
@@ -276,11 +269,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
size = HOST_PAGE_ALIGN(size);
-#ifdef CONFIG_USE_GUEST_BASE
- if (RESERVED_VA) {
+ if (reserved_va) {
return mmap_find_vma_reserved(start, size);
}
-#endif
addr = start;
wrapped = repeat = 0;
@@ -448,9 +439,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/* If so, truncate the file map at eof aligned with
the hosts real pagesize. Additional anonymous maps
will be created beyond EOF. */
- len = (sb.st_size - offset);
- len += qemu_real_host_page_size - 1;
- len &= ~(qemu_real_host_page_size - 1);
+ len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);
}
}
@@ -518,10 +507,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
goto fail;
if (!(prot & PROT_WRITE)) {
ret = target_mprotect(start, len, prot);
- if (ret != 0) {
- start = ret;
- goto the_end;
- }
+ assert(ret == 0);
}
goto the_end;
}
@@ -545,7 +531,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
/* handle the end of the mapping */
if (end < real_end) {
ret = mmap_frag(real_end - qemu_host_page_size,
- real_end - qemu_host_page_size, real_end,
+ real_end - qemu_host_page_size, end,
prot, flags, fd,
offset + real_end - qemu_host_page_size - start);
if (ret == -1)
@@ -671,7 +657,7 @@ int target_munmap(abi_ulong start, abi_ulong len)
ret = 0;
/* unmap what we can */
if (real_start < real_end) {
- if (RESERVED_VA) {
+ if (reserved_va) {
mmap_reserve(real_start, real_end - real_start);
} else {
ret = munmap(g2h(real_start), real_end - real_start);
@@ -701,7 +687,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
flags,
g2h(new_addr));
- if (RESERVED_VA && host_addr != MAP_FAILED) {
+ if (reserved_va && host_addr != MAP_FAILED) {
/* If new and old addresses overlap then the above mremap will
already have failed with EINVAL. */
mmap_reserve(old_addr, old_size);
@@ -719,13 +705,13 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
old_size, new_size,
flags | MREMAP_FIXED,
g2h(mmap_start));
- if ( RESERVED_VA ) {
+ if (reserved_va) {
mmap_reserve(old_addr, old_size);
}
}
} else {
int prot = 0;
- if (RESERVED_VA && old_size < new_size) {
+ if (reserved_va && old_size < new_size) {
abi_ulong addr;
for (addr = old_addr + old_size;
addr < old_addr + new_size;
@@ -735,7 +721,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
}
if (prot == 0) {
host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
- if (host_addr != MAP_FAILED && RESERVED_VA && old_size > new_size) {
+ if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) {
mmap_reserve(old_addr + old_size, new_size - old_size);
}
} else {
diff --git a/qemu/linux-user/openrisc/syscall_nr.h b/qemu/linux-user/openrisc/syscall_nr.h
index 4c386eae9..6b1c7d265 100644
--- a/qemu/linux-user/openrisc/syscall_nr.h
+++ b/qemu/linux-user/openrisc/syscall_nr.h
@@ -382,9 +382,18 @@
#define TARGET_NR_process_vm_writev 271
#define TARGET_NR_kcmp 272
#define TARGET_NR_finit_module 273
-
-#undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls 274
+#define TARGET_NR_sched_setattr 274
+#define TARGET_NR_sched_getattr 275
+#define TARGET_NR_renameat2 276
+#define TARGET_NR_seccomp 277
+#define TARGET_NR_getrandom 278
+#define TARGET_NR_memfd_create 279
+#define TARGET_NR_bpf 280
+#define TARGET_NR_execveat 281
+#define TARGET_NR_userfaultfd 282
+#define TARGET_NR_membarrier 283
+#define TARGET_NR_mlock2 284
+#define TARGET_NR_copy_file_range 285
/*
* All syscalls below here should go away really,
@@ -411,9 +420,6 @@
#define TARGET_NR_3264_stat 1038
#define TARGET_NR_3264_lstat 1039
-#undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls (TARGET_NR_3264_lstat+1)
-
#define TARGET_NR_pipe 1040
#define TARGET_NR_dup2 1041
#define TARGET_NR_epoll_create 1042
@@ -421,10 +427,6 @@
#define TARGET_NR_eventfd 1044
#define TARGET_NR_signalfd 1045
-#undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls (TARGET_NR_signalfd+1)
-
-
#define TARGET_NR_sendfile 1046
#define TARGET_NR_ftruncate 1047
#define TARGET_NR_truncate 1048
@@ -441,9 +443,6 @@
#define TARGET_NR_lseek 1057
#define TARGET_NR_mmap 1058
-#undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls (TARGET_NR_mmap+1)
-
#define TARGET_NR_alarm 1059
#define __ARCH_WANT_SYS_ALARM
#define TARGET_NR_getpgrp 1060
@@ -477,9 +476,6 @@
#define TARGET_NR_fork 1079
-#undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls (TARGET_NR_fork+1)
-
/*
* 32 bit systems traditionally used different
diff --git a/qemu/linux-user/openrisc/syscall.h b/qemu/linux-user/openrisc/target_syscall.h
index 8ac03656d..19aeffc95 100644
--- a/qemu/linux-user/openrisc/syscall.h
+++ b/qemu/linux-user/openrisc/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
struct target_pt_regs {
union {
struct {
@@ -27,3 +30,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/ppc/syscall_nr.h b/qemu/linux-user/ppc/syscall_nr.h
index 1e1736e11..46ed8a68c 100644
--- a/qemu/linux-user/ppc/syscall_nr.h
+++ b/qemu/linux-user/ppc/syscall_nr.h
@@ -319,7 +319,7 @@
#define TARGET_NR_epoll_pwait 303
#define TARGET_NR_utimensat 304
#define TARGET_NR_signalfd 305
-#define TARGET_NR_timerfd 306
+#define TARGET_NR_timerfd_create 306
#define TARGET_NR_eventfd 307
#define TARGET_NR_sync_file_range2 308
#define TARGET_NR_fallocate 309
@@ -368,3 +368,27 @@
#define TARGET_NR_process_vm_writev 352
#define TARGET_NR_finit_module 353
#define TARGET_NR_kcmp 354
+#define TARGET_NR_sched_setattr 355
+#define TARGET_NR_sched_getattr 356
+#define TARGET_NR_renameat2 357
+#define TARGET_NR_seccomp 358
+#define TARGET_NR_getrandom 359
+#define TARGET_NR_memfd_create 360
+#define TARGET_NR_bpf 361
+#define TARGET_NR_execveat 362
+#define TARGET_NR_switch_endian 363
+#define TARGET_NR_userfaultfd 364
+#define TARGET_NR_membarrier 365
+#define TARGET_NR_semop 366
+#define TARGET_NR_semget 367
+#define TARGET_NR_semctl 368
+#define TARGET_NR_semtimedop 369
+#define TARGET_NR_msgsnd 370
+#define TARGET_NR_msgrcv 371
+#define TARGET_NR_msgget 372
+#define TARGET_NR_msgctl 373
+#define TARGET_NR_shmat 374
+#define TARGET_NR_shmdt 375
+#define TARGET_NR_shmget 376
+#define TARGET_NR_shmctl 377
+#define TARGET_NR_mlock2 378
diff --git a/qemu/linux-user/ppc/syscall.h b/qemu/linux-user/ppc/target_syscall.h
index 0daf5cd2d..35cab5946 100644
--- a/qemu/linux-user/ppc/syscall.h
+++ b/qemu/linux-user/ppc/target_syscall.h
@@ -17,6 +17,9 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
/* XXX: ABSOLUTELY BUGGY:
* for now, this is quite just a cut-and-paste from i386 target...
*/
@@ -73,3 +76,5 @@ struct target_revectored_struct {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/qemu.h b/qemu/linux-user/qemu.h
index 8012cc2f5..26b0ba273 100644
--- a/qemu/linux-user/qemu.h
+++ b/qemu/linux-user/qemu.h
@@ -1,22 +1,19 @@
#ifndef QEMU_H
#define QEMU_H
-#include <signal.h>
-#include <string.h>
#include "cpu.h"
#include "exec/cpu_ldst.h"
#undef DEBUG_REMAP
#ifdef DEBUG_REMAP
-#include <stdlib.h>
#endif /* DEBUG_REMAP */
#include "exec/user/abitypes.h"
#include "exec/user/thunk.h"
#include "syscall_defs.h"
-#include "syscall.h"
+#include "target_syscall.h"
#include "exec/gdbstub.h"
#include "qemu/queue.h"
@@ -36,8 +33,6 @@ struct image_info {
abi_ulong start_brk;
abi_ulong brk;
abi_ulong start_mmap;
- abi_ulong mmap;
- abi_ulong rss;
abi_ulong start_stack;
abi_ulong stack_limit;
abi_ulong entry;
@@ -145,12 +140,6 @@ extern const char *qemu_uname_release;
extern unsigned long mmap_min_addr;
/* ??? See if we can avoid exposing so much of the loader internals. */
-/*
- * MAX_ARG_PAGES defines the number of pages allocated for arguments
- * and envelope for the new program. 32 should suffice, this gives
- * a maximum env+arg of 128kB w/4KB pages!
- */
-#define MAX_ARG_PAGES 33
/* Read a good amount of data initially, to hopefully get all the
program headers loaded. */
@@ -162,7 +151,6 @@ extern unsigned long mmap_min_addr;
*/
struct linux_binprm {
char buf[BPRM_BUF_SIZE] __attribute__((aligned));
- void *page[MAX_ARG_PAGES];
abi_ulong p;
int fd;
int e_uid, e_gid;
@@ -261,8 +249,6 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
int target_msync(abi_ulong start, abi_ulong len, int flags);
extern unsigned long last_brk;
extern abi_ulong mmap_next_start;
-void mmap_lock(void);
-void mmap_unlock(void);
abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
void cpu_list_lock(void);
void cpu_list_unlock(void);
diff --git a/qemu/linux-user/s390x/syscall_nr.h b/qemu/linux-user/s390x/syscall_nr.h
index 7c0b8b2ea..1a66c5561 100644
--- a/qemu/linux-user/s390x/syscall_nr.h
+++ b/qemu/linux-user/s390x/syscall_nr.h
@@ -271,6 +271,36 @@
#define TARGET_NR_s390_runtime_instr 342
#define TARGET_NR_kcmp 343
#define TARGET_NR_finit_module 344
+#define TARGET_NR_sched_setattr 345
+#define TARGET_NR_sched_getattr 346
+#define TARGET_NR_renameat2 347
+#define TARGET_NR_seccomp 348
+#define TARGET_NR_getrandom 349
+#define TARGET_NR_memfd_create 350
+#define TARGET_NR_bpf 351
+#define TARGET_NR_s390_pci_mmio_write 352
+#define TARGET_NR_s390_pci_mmio_read 353
+#define TARGET_NR_execveat 354
+#define TARGET_NR_userfaultfd 355
+#define TARGET_NR_membarrier 356
+#define TARGET_NR_recvmmsg 357
+#define TARGET_NR_sendmmsg 358
+#define TARGET_NR_socket 359
+#define TARGET_NR_socketpair 360
+#define TARGET_NR_bind 361
+#define TARGET_NR_connect 362
+#define TARGET_NR_listen 363
+#define TARGET_NR_accept4 364
+#define TARGET_NR_getsockopt 365
+#define TARGET_NR_setsockopt 366
+#define TARGET_NR_getsockname 367
+#define TARGET_NR_getpeername 368
+#define TARGET_NR_sendto 369
+#define TARGET_NR_sendmsg 370
+#define TARGET_NR_recvfrom 371
+#define TARGET_NR_recvmsg 372
+#define TARGET_NR_shutdown 373
+#define TARGET_NR_mlock2 374
/*
* There are some system calls that are not present on 64 bit, some
diff --git a/qemu/linux-user/s390x/syscall.h b/qemu/linux-user/s390x/target_syscall.h
index 35f170af2..02061efc7 100644
--- a/qemu/linux-user/s390x/syscall.h
+++ b/qemu/linux-user/s390x/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
/* this typedef defines how a Program Status Word looks like */
typedef struct {
abi_ulong mask;
@@ -27,3 +30,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/sh4/syscall_nr.h b/qemu/linux-user/sh4/syscall_nr.h
index bdf8742c6..50099846d 100644
--- a/qemu/linux-user/sh4/syscall_nr.h
+++ b/qemu/linux-user/sh4/syscall_nr.h
@@ -323,7 +323,7 @@
#define TARGET_NR_epoll_pwait 319
#define TARGET_NR_utimensat 320
#define TARGET_NR_signalfd 321
-#define TARGET_NR_timerfd 322
+#define TARGET_NR_timerfd_create 322
#define TARGET_NR_eventfd 323
#define TARGET_NR_fallocate 324
#define TARGET_NR_timerfd_settime 325
diff --git a/qemu/linux-user/sh4/syscall.h b/qemu/linux-user/sh4/target_syscall.h
index 7aa4f239c..9f3381bc9 100644
--- a/qemu/linux-user/sh4/syscall.h
+++ b/qemu/linux-user/sh4/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
struct target_pt_regs {
unsigned long regs[16];
unsigned long pc;
@@ -15,3 +18,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/signal.c b/qemu/linux-user/signal.c
index 9d4cef409..96e86c0a2 100644
--- a/qemu/linux-user/signal.c
+++ b/qemu/linux-user/signal.c
@@ -16,21 +16,14 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
+#include "qemu/osdep.h"
#include <sys/ucontext.h>
#include <sys/resource.h>
#include "qemu.h"
#include "qemu-common.h"
#include "target_signal.h"
-
-//#define DEBUG_SIGNAL
+#include "trace.h"
static struct target_sigaltstack target_sigaltstack_used = {
.ss_sp = 0,
@@ -445,7 +438,9 @@ static void QEMU_NORETURN force_sig(int target_sig)
TaskState *ts = (TaskState *)cpu->opaque;
int host_sig, core_dumped = 0;
struct sigaction act;
+
host_sig = target_to_host_signal(target_sig);
+ trace_user_force_sig(env, target_sig, host_sig);
gdb_signalled(env, target_sig);
/* dump core if supported by target binary format */
@@ -500,10 +495,7 @@ int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
abi_ulong handler;
int queue;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "queue_signal: sig=%d\n",
- sig);
-#endif
+ trace_user_queue_signal(env, sig);
k = &ts->sigtab[sig - 1];
queue = gdb_queuesig ();
handler = sigact_table[sig - 1]._sa_handler;
@@ -588,9 +580,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
sig = host_to_target_signal(host_signum);
if (sig < 1 || sig > TARGET_NSIG)
return;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "qemu: got signal %d\n", sig);
-#endif
+ trace_user_host_signal(env, host_signum, sig);
host_to_target_siginfo_noswap(&tinfo, info);
if (queue_signal(env, sig, &tinfo) == 1) {
/* interrupt the virtual CPU as soon as possible */
@@ -683,10 +673,6 @@ int do_sigaction(int sig, const struct target_sigaction *act,
if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
return -EINVAL;
k = &sigact_table[sig - 1];
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
- sig, act, oact);
-#endif
if (oact) {
__put_user(k->_sa_handler, &oact->_sa_handler);
__put_user(k->sa_flags, &oact->sa_flags);
@@ -910,6 +896,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -971,6 +958,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -1082,9 +1070,7 @@ long do_sigreturn(CPUX86State *env)
sigset_t set;
int eax, i;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
-#endif
+ trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
/* set blocked signals */
@@ -1116,6 +1102,7 @@ long do_rt_sigreturn(CPUX86State *env)
int eax;
frame_addr = env->regs[R_ESP] - 4;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
@@ -1319,6 +1306,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
abi_ulong frame_addr, return_addr;
frame_addr = get_sigframe(ka, env);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -1378,6 +1366,7 @@ long do_rt_sigreturn(CPUARMState *env)
struct target_rt_sigframe *frame = NULL;
abi_ulong frame_addr = env->xregs[31];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (frame_addr & 15) {
goto badframe;
}
@@ -1547,82 +1536,84 @@ static void
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
CPUARMState *env, abi_ulong mask)
{
- __put_user(env->regs[0], &sc->arm_r0);
- __put_user(env->regs[1], &sc->arm_r1);
- __put_user(env->regs[2], &sc->arm_r2);
- __put_user(env->regs[3], &sc->arm_r3);
- __put_user(env->regs[4], &sc->arm_r4);
- __put_user(env->regs[5], &sc->arm_r5);
- __put_user(env->regs[6], &sc->arm_r6);
- __put_user(env->regs[7], &sc->arm_r7);
- __put_user(env->regs[8], &sc->arm_r8);
- __put_user(env->regs[9], &sc->arm_r9);
- __put_user(env->regs[10], &sc->arm_r10);
- __put_user(env->regs[11], &sc->arm_fp);
- __put_user(env->regs[12], &sc->arm_ip);
- __put_user(env->regs[13], &sc->arm_sp);
- __put_user(env->regs[14], &sc->arm_lr);
- __put_user(env->regs[15], &sc->arm_pc);
+ __put_user(env->regs[0], &sc->arm_r0);
+ __put_user(env->regs[1], &sc->arm_r1);
+ __put_user(env->regs[2], &sc->arm_r2);
+ __put_user(env->regs[3], &sc->arm_r3);
+ __put_user(env->regs[4], &sc->arm_r4);
+ __put_user(env->regs[5], &sc->arm_r5);
+ __put_user(env->regs[6], &sc->arm_r6);
+ __put_user(env->regs[7], &sc->arm_r7);
+ __put_user(env->regs[8], &sc->arm_r8);
+ __put_user(env->regs[9], &sc->arm_r9);
+ __put_user(env->regs[10], &sc->arm_r10);
+ __put_user(env->regs[11], &sc->arm_fp);
+ __put_user(env->regs[12], &sc->arm_ip);
+ __put_user(env->regs[13], &sc->arm_sp);
+ __put_user(env->regs[14], &sc->arm_lr);
+ __put_user(env->regs[15], &sc->arm_pc);
#ifdef TARGET_CONFIG_CPU_32
- __put_user(cpsr_read(env), &sc->arm_cpsr);
+ __put_user(cpsr_read(env), &sc->arm_cpsr);
#endif
- __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
- __put_user(/* current->thread.error_code */ 0, &sc->error_code);
- __put_user(/* current->thread.address */ 0, &sc->fault_address);
- __put_user(mask, &sc->oldmask);
+ __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
+ __put_user(/* current->thread.error_code */ 0, &sc->error_code);
+ __put_user(/* current->thread.address */ 0, &sc->fault_address);
+ __put_user(mask, &sc->oldmask);
}
static inline abi_ulong
get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
{
- unsigned long sp = regs->regs[13];
+ unsigned long sp = regs->regs[13];
- /*
- * This is the X/Open sanctioned signal stack switching.
- */
- if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
- sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
- /*
- * ATPCS B01 mandates 8-byte alignment
- */
- return (sp - framesize) & ~7;
+ /*
+ * This is the X/Open sanctioned signal stack switching.
+ */
+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
+ /*
+ * ATPCS B01 mandates 8-byte alignment
+ */
+ return (sp - framesize) & ~7;
}
static void
setup_return(CPUARMState *env, struct target_sigaction *ka,
abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
{
- abi_ulong handler = ka->_sa_handler;
- abi_ulong retcode;
- int thumb = handler & 1;
- uint32_t cpsr = cpsr_read(env);
+ abi_ulong handler = ka->_sa_handler;
+ abi_ulong retcode;
+ int thumb = handler & 1;
+ uint32_t cpsr = cpsr_read(env);
- cpsr &= ~CPSR_IT;
- if (thumb) {
- cpsr |= CPSR_T;
- } else {
- cpsr &= ~CPSR_T;
- }
+ cpsr &= ~CPSR_IT;
+ if (thumb) {
+ cpsr |= CPSR_T;
+ } else {
+ cpsr &= ~CPSR_T;
+ }
- if (ka->sa_flags & TARGET_SA_RESTORER) {
- retcode = ka->sa_restorer;
- } else {
- unsigned int idx = thumb;
+ if (ka->sa_flags & TARGET_SA_RESTORER) {
+ retcode = ka->sa_restorer;
+ } else {
+ unsigned int idx = thumb;
- if (ka->sa_flags & TARGET_SA_SIGINFO)
- idx += 2;
+ if (ka->sa_flags & TARGET_SA_SIGINFO) {
+ idx += 2;
+ }
__put_user(retcodes[idx], rc);
- retcode = rc_addr + thumb;
- }
+ retcode = rc_addr + thumb;
+ }
- env->regs[0] = usig;
- env->regs[13] = frame_addr;
- env->regs[14] = retcode;
- env->regs[15] = handler & (thumb ? ~1 : ~3);
- cpsr_write(env, cpsr, 0xffffffff);
+ env->regs[0] = usig;
+ env->regs[13] = frame_addr;
+ env->regs[14] = retcode;
+ env->regs[15] = handler & (thumb ? ~1 : ~3);
+ cpsr_write(env, cpsr, CPSR_IT | CPSR_T, CPSRWriteByInstr);
}
static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
@@ -1704,6 +1695,7 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
int i;
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return;
@@ -1725,6 +1717,7 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
struct sigframe_v2 *frame;
abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return;
@@ -1757,6 +1750,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
int i;
abi_ulong info_addr, uc_addr;
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return /* 1 */;
@@ -1797,6 +1791,7 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
abi_ulong info_addr, uc_addr;
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return /* 1 */;
@@ -1850,7 +1845,7 @@ restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
__get_user(env->regs[15], &sc->arm_pc);
#ifdef TARGET_CONFIG_CPU_32
__get_user(cpsr, &sc->arm_cpsr);
- cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
+ cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
#endif
err |= !valid_user_regs(env);
@@ -1872,6 +1867,7 @@ static long do_sigreturn_v1(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2008,6 +2004,7 @@ static long do_sigreturn_v2(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2048,6 +2045,7 @@ static long do_rt_sigreturn_v1(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2089,6 +2087,7 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
* not, then the user is trying to mess with us.
*/
frame_addr = env->regs[13];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (frame_addr & 7) {
goto badframe;
}
@@ -2284,13 +2283,13 @@ static void setup_frame(int sig, struct target_sigaction *ka,
sigframe_size = NF_ALIGNEDSZ;
sf_addr = get_sigframe(ka, env, sigframe_size);
+ trace_user_setup_frame(env, sf_addr);
sf = lock_user(VERIFY_WRITE, sf_addr,
sizeof(struct target_signal_frame), 0);
if (!sf)
goto sigsegv;
- //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
#if 0
if (invalid_frame_pointer(sf, sigframe_size))
goto sigill_and_return;
@@ -2357,7 +2356,6 @@ sigill_and_return:
force_sig(TARGET_SIGILL);
#endif
sigsegv:
- //fprintf(stderr, "force_sig\n");
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
force_sig(TARGET_SIGSEGV);
}
@@ -2379,13 +2377,9 @@ long do_sigreturn(CPUSPARCState *env)
int err=0, i;
sf_addr = env->regwptr[UREG_FP];
+ trace_user_do_sigreturn(env, sf_addr);
if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
goto segv_and_exit;
-#if 0
- fprintf(stderr, "sigreturn\n");
- fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
-#endif
- //cpu_dump_state(env, stderr, fprintf, 0);
/* 1. Make sure we are not getting garbage from the user */
@@ -2444,6 +2438,7 @@ segv_and_exit:
long do_rt_sigreturn(CPUSPARCState *env)
{
+ trace_user_do_rt_sigreturn(env, 0);
fprintf(stderr, "do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@@ -2903,6 +2898,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
int i;
frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -2949,10 +2945,8 @@ long do_sigreturn(CPUMIPSState *regs)
target_sigset_t target_set;
int i;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
-#endif
frame_addr = regs->active_tc.gpr[29];
+ trace_user_do_sigreturn(regs, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -2999,6 +2993,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -3056,10 +3051,8 @@ long do_rt_sigreturn(CPUMIPSState *env)
abi_ulong frame_addr;
sigset_t blocked;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_rt_sigreturn\n");
-#endif
frame_addr = env->active_tc.gpr[29];
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -3214,9 +3207,9 @@ static void setup_frame(int sig, struct target_sigaction *ka,
struct target_sigframe *frame;
abi_ulong frame_addr;
int i;
- int err = 0;
frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
+ trace_user_setup_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -3232,15 +3225,14 @@ static void setup_frame(int sig, struct target_sigaction *ka,
regs->pr = (unsigned long) ka->sa_restorer;
} else {
/* Generate return code (system call to sigreturn) */
+ abi_ulong retcode_addr = frame_addr +
+ offsetof(struct target_sigframe, retcode);
__put_user(MOVW(2), &frame->retcode[0]);
__put_user(TRAP_NOARG, &frame->retcode[1]);
__put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
- regs->pr = (unsigned long) frame->retcode;
+ regs->pr = (unsigned long) retcode_addr;
}
- if (err)
- goto give_sigsegv;
-
/* Set up registers for signal handler */
regs->gregs[15] = frame_addr;
regs->gregs[4] = sig; /* Arg for signal handler */
@@ -3263,9 +3255,9 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
struct target_rt_sigframe *frame;
abi_ulong frame_addr;
int i;
- int err = 0;
frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
+ trace_user_setup_rt_frame(regs, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -3292,15 +3284,14 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
regs->pr = (unsigned long) ka->sa_restorer;
} else {
/* Generate return code (system call to sigreturn) */
+ abi_ulong retcode_addr = frame_addr +
+ offsetof(struct target_rt_sigframe, retcode);
__put_user(MOVW(2), &frame->retcode[0]);
__put_user(TRAP_NOARG, &frame->retcode[1]);
__put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
- regs->pr = (unsigned long) frame->retcode;
+ regs->pr = (unsigned long) retcode_addr;
}
- if (err)
- goto give_sigsegv;
-
/* Set up registers for signal handler */
regs->gregs[15] = frame_addr;
regs->gregs[4] = sig; /* Arg for signal handler */
@@ -3326,10 +3317,8 @@ long do_sigreturn(CPUSH4State *regs)
int i;
int err = 0;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
-#endif
frame_addr = regs->gregs[15];
+ trace_user_do_sigreturn(regs, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -3362,10 +3351,8 @@ long do_rt_sigreturn(CPUSH4State *regs)
sigset_t blocked;
target_ulong r0;
-#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_rt_sigreturn\n");
-#endif
frame_addr = regs->gregs[15];
+ trace_user_do_rt_sigreturn(regs, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -3515,6 +3502,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof *frame);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto badframe;
@@ -3580,6 +3568,7 @@ long do_sigreturn(CPUMBState *env)
int i;
frame_addr = env->regs[R_SP];
+ trace_user_do_sigreturn(env, frame_addr);
/* Make sure the guest isn't playing games. */
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
goto badframe;
@@ -3605,6 +3594,7 @@ long do_sigreturn(CPUMBState *env)
long do_rt_sigreturn(CPUMBState *env)
{
+ trace_user_do_rt_sigreturn(env, 0);
fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@@ -3694,6 +3684,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(env, sizeof *frame);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto badframe;
@@ -3747,6 +3738,7 @@ long do_sigreturn(CPUCRISState *env)
int i;
frame_addr = env->regs[R_SP];
+ trace_user_do_sigreturn(env, frame_addr);
/* Make sure the guest isn't playing games. */
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
goto badframe;
@@ -3768,6 +3760,7 @@ long do_sigreturn(CPUCRISState *env)
long do_rt_sigreturn(CPUCRISState *env)
{
+ trace_user_do_rt_sigreturn(env, 0);
fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@@ -3901,12 +3894,6 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka,
return sp;
}
-static void setup_frame(int sig, struct target_sigaction *ka,
- target_sigset_t *set, CPUOpenRISCState *env)
-{
- qemu_log("Not implement.\n");
-}
-
static void setup_rt_frame(int sig, struct target_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUOpenRISCState *env)
@@ -3918,6 +3905,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
abi_ulong info_addr, uc_addr;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -3979,14 +3967,15 @@ give_sigsegv:
long do_sigreturn(CPUOpenRISCState *env)
{
-
- qemu_log("do_sigreturn: not implemented\n");
+ trace_user_do_sigreturn(env, 0);
+ fprintf(stderr, "do_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
long do_rt_sigreturn(CPUOpenRISCState *env)
{
- qemu_log("do_rt_sigreturn: not implemented\n");
+ trace_user_do_rt_sigreturn(env, 0);
+ fprintf(stderr, "do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
/* TARGET_OPENRISC */
@@ -4109,13 +4098,11 @@ static void setup_frame(int sig, struct target_sigaction *ka,
abi_ulong frame_addr;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
- qemu_log("%s: 1\n", __FUNCTION__);
__put_user(set->sig[0], &frame->sc.oldmask[0]);
save_sigregs(env, &frame->sregs);
@@ -4156,7 +4143,6 @@ static void setup_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- qemu_log("%s: give_sigsegv\n", __FUNCTION__);
force_sig(TARGET_SIGSEGV);
}
@@ -4169,13 +4155,11 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
abi_ulong frame_addr;
frame_addr = get_sigframe(ka, env, sizeof *frame);
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
- qemu_log("%s: 1\n", __FUNCTION__);
tswap_siginfo(&frame->info, info);
/* Create the ucontext. */
@@ -4214,7 +4198,6 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- qemu_log("%s: give_sigsegv\n", __FUNCTION__);
force_sig(TARGET_SIGSEGV);
}
@@ -4229,9 +4212,8 @@ restore_sigregs(CPUS390XState *env, target_sigregs *sc)
}
__get_user(env->psw.mask, &sc->regs.psw.mask);
- qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
- __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
- (unsigned long long)env->psw.addr);
+ trace_user_s390x_restore_sigregs(env, (unsigned long long)sc->regs.psw.addr,
+ (unsigned long long)env->psw.addr);
__get_user(env->psw.addr, &sc->regs.psw.addr);
/* FIXME: 31-bit -> | PSW_ADDR_AMODE */
@@ -4249,11 +4231,10 @@ long do_sigreturn(CPUS390XState *env)
{
sigframe *frame;
abi_ulong frame_addr = env->regs[15];
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
target_sigset_t target_set;
sigset_t set;
+ trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -4278,10 +4259,9 @@ long do_rt_sigreturn(CPUS390XState *env)
{
rt_sigframe *frame;
abi_ulong frame_addr = env->regs[15];
- qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
- (unsigned long long)frame_addr);
sigset_t set;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -4666,6 +4646,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
#endif
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
goto sigsegv;
sc = &frame->sctx;
@@ -4730,7 +4711,6 @@ static void setup_frame(int sig, struct target_sigaction *ka,
sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- qemu_log("segfaulting from setup_frame\n");
force_sig(TARGET_SIGSEGV);
}
@@ -4826,7 +4806,6 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- qemu_log("segfaulting from setup_rt_frame\n");
force_sig(TARGET_SIGSEGV);
}
@@ -4864,7 +4843,6 @@ long do_sigreturn(CPUPPCState *env)
sigsegv:
unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1);
- qemu_log("segfaulting from do_sigreturn\n");
force_sig(TARGET_SIGSEGV);
return 0;
}
@@ -4920,7 +4898,6 @@ long do_rt_sigreturn(CPUPPCState *env)
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- qemu_log("segfaulting from do_rt_sigreturn\n");
force_sig(TARGET_SIGSEGV);
return 0;
}
@@ -5044,6 +5021,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof *frame);
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -5160,6 +5138,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i;
frame_addr = get_sigframe(ka, env, sizeof *frame);
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
@@ -5227,6 +5206,7 @@ long do_sigreturn(CPUM68KState *env)
sigset_t set;
int d0, i;
+ trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -5261,6 +5241,7 @@ long do_rt_sigreturn(CPUM68KState *env)
sigset_t set;
int d0;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
@@ -5400,6 +5381,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
int err = 0;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -5444,6 +5426,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
int i, err = 0;
frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -5522,6 +5505,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
struct target_rt_sigframe *frame;
sigset_t set;
+ trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
@@ -5544,6 +5528,165 @@ long do_rt_sigreturn(CPUAlphaState *env)
force_sig(TARGET_SIGSEGV);
}
+#elif defined(TARGET_TILEGX)
+
+struct target_sigcontext {
+ union {
+ /* General-purpose registers. */
+ abi_ulong gregs[56];
+ struct {
+ abi_ulong __gregs[53];
+ abi_ulong tp; /* Aliases gregs[TREG_TP]. */
+ abi_ulong sp; /* Aliases gregs[TREG_SP]. */
+ abi_ulong lr; /* Aliases gregs[TREG_LR]. */
+ };
+ };
+ abi_ulong pc; /* Program counter. */
+ abi_ulong ics; /* In Interrupt Critical Section? */
+ abi_ulong faultnum; /* Fault number. */
+ abi_ulong pad[5];
+};
+
+struct target_ucontext {
+ abi_ulong tuc_flags;
+ abi_ulong tuc_link;
+ target_stack_t tuc_stack;
+ struct target_sigcontext tuc_mcontext;
+ target_sigset_t tuc_sigmask; /* mask last for extensibility */
+};
+
+struct target_rt_sigframe {
+ unsigned char save_area[16]; /* caller save area */
+ struct target_siginfo info;
+ struct target_ucontext uc;
+};
+
+static void setup_sigcontext(struct target_sigcontext *sc,
+ CPUArchState *env, int signo)
+{
+ int i;
+
+ for (i = 0; i < TILEGX_R_COUNT; ++i) {
+ __put_user(env->regs[i], &sc->gregs[i]);
+ }
+
+ __put_user(env->pc, &sc->pc);
+ __put_user(0, &sc->ics);
+ __put_user(signo, &sc->faultnum);
+}
+
+static void restore_sigcontext(CPUTLGState *env, struct target_sigcontext *sc)
+{
+ int i;
+
+ for (i = 0; i < TILEGX_R_COUNT; ++i) {
+ __get_user(env->regs[i], &sc->gregs[i]);
+ }
+
+ __get_user(env->pc, &sc->pc);
+}
+
+static abi_ulong get_sigframe(struct target_sigaction *ka, CPUArchState *env,
+ size_t frame_size)
+{
+ unsigned long sp = env->regs[TILEGX_R_SP];
+
+ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) {
+ return -1UL;
+ }
+
+ if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
+
+ sp -= frame_size;
+ sp &= -16UL;
+ return sp;
+}
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUArchState *env)
+{
+ abi_ulong frame_addr;
+ struct target_rt_sigframe *frame;
+ unsigned long restorer;
+
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+ goto give_sigsegv;
+ }
+
+ /* Always write at least the signal number for the stack backtracer. */
+ if (ka->sa_flags & TARGET_SA_SIGINFO) {
+ /* At sigreturn time, restore the callee-save registers too. */
+ tswap_siginfo(&frame->info, info);
+ /* regs->flags |= PT_FLAGS_RESTORE_REGS; FIXME: we can skip it? */
+ } else {
+ __put_user(info->si_signo, &frame->info.si_signo);
+ }
+
+ /* Create the ucontext. */
+ __put_user(0, &frame->uc.tuc_flags);
+ __put_user(0, &frame->uc.tuc_link);
+ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
+ __put_user(sas_ss_flags(env->regs[TILEGX_R_SP]),
+ &frame->uc.tuc_stack.ss_flags);
+ __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+ setup_sigcontext(&frame->uc.tuc_mcontext, env, info->si_signo);
+
+ restorer = (unsigned long) do_rt_sigreturn;
+ if (ka->sa_flags & TARGET_SA_RESTORER) {
+ restorer = (unsigned long) ka->sa_restorer;
+ }
+ env->pc = (unsigned long) ka->_sa_handler;
+ env->regs[TILEGX_R_SP] = (unsigned long) frame;
+ env->regs[TILEGX_R_LR] = restorer;
+ env->regs[0] = (unsigned long) sig;
+ env->regs[1] = (unsigned long) &frame->info;
+ env->regs[2] = (unsigned long) &frame->uc;
+ /* regs->flags |= PT_FLAGS_CALLER_SAVES; FIXME: we can skip it? */
+
+ unlock_user_struct(frame, frame_addr, 1);
+ return;
+
+give_sigsegv:
+ if (sig == TARGET_SIGSEGV) {
+ ka->_sa_handler = TARGET_SIG_DFL;
+ }
+ force_sig(TARGET_SIGSEGV /* , current */);
+}
+
+long do_rt_sigreturn(CPUTLGState *env)
+{
+ abi_ulong frame_addr = env->regs[TILEGX_R_SP];
+ struct target_rt_sigframe *frame;
+ sigset_t set;
+
+ trace_user_do_rt_sigreturn(env, frame_addr);
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
+ goto badframe;
+ }
+ target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
+ do_sigprocmask(SIG_SETMASK, &set, NULL);
+
+ restore_sigcontext(env, &frame->uc.tuc_mcontext);
+ if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
+ uc.tuc_stack),
+ 0, env->regs[TILEGX_R_SP]) == -EFAULT) {
+ goto badframe;
+ }
+
+ unlock_user_struct(frame, frame_addr, 0);
+ return env->regs[TILEGX_R_RE];
+
+
+ badframe:
+ unlock_user_struct(frame, frame_addr, 0);
+ force_sig(TARGET_SIGSEGV);
+}
+
#else
static void setup_frame(int sig, struct target_sigaction *ka,
@@ -5600,9 +5743,7 @@ void process_pending_signals(CPUArchState *cpu_env)
return;
handle_signal:
-#ifdef DEBUG_SIGNAL
- fprintf(stderr, "qemu: process signal %d\n", sig);
-#endif
+ trace_user_handle_signal(cpu_env, sig);
/* dequeue signal */
q = k->first;
k->first = q->next;
@@ -5663,7 +5804,8 @@ void process_pending_signals(CPUArchState *cpu_env)
}
#endif
/* prepare the stack frame of the virtual CPU */
-#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
+#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \
+ || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)
/* These targets do not have traditional signals. */
setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
#else
diff --git a/qemu/linux-user/sparc/syscall_nr.h b/qemu/linux-user/sparc/syscall_nr.h
index 181cd3265..732b1052a 100644
--- a/qemu/linux-user/sparc/syscall_nr.h
+++ b/qemu/linux-user/sparc/syscall_nr.h
@@ -278,7 +278,7 @@
#define TARGET_NR_epoll_pwait 309
#define TARGET_NR_utimensat 310
#define TARGET_NR_signalfd 311
-#define TARGET_NR_timerfd 312
+#define TARGET_NR_timerfd_create 312
#define TARGET_NR_eventfd 313
#define TARGET_NR_fallocate 314
#define TARGET_NR_timerfd_settime 315
@@ -309,3 +309,17 @@
#define TARGET_NR_kern_features 340
#define TARGET_NR_kcmp 341
#define TARGET_NR_finit_module 342
+#define TARGET_NR_sched_setattr 343
+#define TARGET_NR_sched_getattr 344
+#define TARGET_NR_renameat2 345
+#define TARGET_NR_seccomp 346
+#define TARGET_NR_getrandom 347
+#define TARGET_NR_memfd_create 348
+#define TARGET_NR_bpf 349
+#define TARGET_NR_execveat 350
+#define TARGET_NR_membarrier 351
+#define TARGET_NR_userfaultfd 352
+#define TARGET_NR_bind 353
+#define TARGET_NR_listen 354
+#define TARGET_NR_setsockopt 355
+#define TARGET_NR_mlock2 356
diff --git a/qemu/linux-user/sparc/syscall.h b/qemu/linux-user/sparc/target_syscall.h
index 58573b92e..a73fa6dae 100644
--- a/qemu/linux-user/sparc/syscall.h
+++ b/qemu/linux-user/sparc/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
struct target_pt_regs {
abi_ulong psr;
abi_ulong pc;
@@ -18,3 +21,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 4096
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/sparc64/syscall_nr.h b/qemu/linux-user/sparc64/syscall_nr.h
index 34a984cc8..2b49ead26 100644
--- a/qemu/linux-user/sparc64/syscall_nr.h
+++ b/qemu/linux-user/sparc64/syscall_nr.h
@@ -341,3 +341,17 @@
#define TARGET_NR_kern_features 340
#define TARGET_NR_kcmp 341
#define TARGET_NR_finit_module 342
+#define TARGET_NR_sched_setattr 343
+#define TARGET_NR_sched_getattr 344
+#define TARGET_NR_renameat2 345
+#define TARGET_NR_seccomp 346
+#define TARGET_NR_getrandom 347
+#define TARGET_NR_memfd_create 348
+#define TARGET_NR_bpf 349
+#define TARGET_NR_execveat 350
+#define TARGET_NR_membarrier 351
+#define TARGET_NR_userfaultfd 352
+#define TARGET_NR_bind 353
+#define TARGET_NR_listen 354
+#define TARGET_NR_setsockopt 355
+#define TARGET_NR_mlock2 356
diff --git a/qemu/linux-user/sparc64/syscall.h b/qemu/linux-user/sparc64/target_syscall.h
index 8398d3f46..eb827fcac 100644
--- a/qemu/linux-user/sparc64/syscall.h
+++ b/qemu/linux-user/sparc64/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
struct target_pt_regs {
abi_ulong u_regs[16];
abi_ulong tstate;
@@ -19,3 +22,5 @@ struct target_pt_regs {
#define TARGET_MINSIGSTKSZ 4096
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
+
+#endif /* TARGET_SYSCALL_H */
diff --git a/qemu/linux-user/strace.c b/qemu/linux-user/strace.c
index ea6c1d24e..0810c85fb 100644
--- a/qemu/linux-user/strace.c
+++ b/qemu/linux-user/strace.c
@@ -1,13 +1,11 @@
-#include <stdio.h>
+#include "qemu/osdep.h"
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/select.h>
-#include <sys/types.h>
#include <sys/mount.h>
#include <sys/mman.h>
-#include <unistd.h>
#include <sched.h>
#include "qemu.h"
diff --git a/qemu/linux-user/syscall.c b/qemu/linux-user/syscall.c
index f62c69894..032d33886 100644
--- a/qemu/linux-user/syscall.c
+++ b/qemu/linux-user/syscall.c
@@ -17,24 +17,15 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#define _ATFILE_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/path.h"
#include <elf.h>
#include <endian.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <limits.h>
#include <grp.h>
-#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
-#include <sys/time.h>
-#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/file.h>
#include <sys/fsuid.h>
@@ -44,7 +35,6 @@
#include <sys/mman.h>
#include <sys/swap.h>
#include <linux/capability.h>
-#include <signal.h>
#include <sched.h>
#ifdef __ia64__
int __clone2(int (*fn)(void *), void *child_stack_base,
@@ -60,6 +50,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <sys/statfs.h>
#include <utime.h>
#include <sys/sysinfo.h>
+#include <sys/signalfd.h>
//#include <sys/user.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
@@ -213,7 +204,7 @@ static int gettid(void) {
return -ENOSYS;
}
#endif
-#ifdef __NR_getdents
+#if defined(TARGET_NR_getdents) && defined(__NR_getdents)
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
#endif
#if !defined(__NR_getdents) || \
@@ -260,6 +251,9 @@ _syscall2(int, ioprio_get, int, which, int, who)
#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
_syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
#endif
+#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
+_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
+#endif
static bitmask_transtbl fcntl_flags_tbl[] = {
{ TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
@@ -294,6 +288,64 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
{ 0, 0, 0, 0 }
};
+typedef abi_long (*TargetFdDataFunc)(void *, size_t);
+typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
+typedef struct TargetFdTrans {
+ TargetFdDataFunc host_to_target_data;
+ TargetFdDataFunc target_to_host_data;
+ TargetFdAddrFunc target_to_host_addr;
+} TargetFdTrans;
+
+static TargetFdTrans **target_fd_trans;
+
+static unsigned int target_fd_max;
+
+static TargetFdDataFunc fd_trans_host_to_target_data(int fd)
+{
+ if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
+ return target_fd_trans[fd]->host_to_target_data;
+ }
+ return NULL;
+}
+
+static TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
+{
+ if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
+ return target_fd_trans[fd]->target_to_host_addr;
+ }
+ return NULL;
+}
+
+static void fd_trans_register(int fd, TargetFdTrans *trans)
+{
+ unsigned int oldmax;
+
+ if (fd >= target_fd_max) {
+ oldmax = target_fd_max;
+ target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */
+ target_fd_trans = g_renew(TargetFdTrans *,
+ target_fd_trans, target_fd_max);
+ memset((void *)(target_fd_trans + oldmax), 0,
+ (target_fd_max - oldmax) * sizeof(TargetFdTrans *));
+ }
+ target_fd_trans[fd] = trans;
+}
+
+static void fd_trans_unregister(int fd)
+{
+ if (fd >= 0 && fd < target_fd_max) {
+ target_fd_trans[fd] = NULL;
+ }
+}
+
+static void fd_trans_dup(int oldfd, int newfd)
+{
+ fd_trans_unregister(newfd);
+ if (oldfd < target_fd_max && target_fd_trans[oldfd]) {
+ fd_trans_register(newfd, target_fd_trans[oldfd]);
+ }
+}
+
static int sys_getcwd1(char *buf, size_t size)
{
if (getcwd(buf, size) == NULL) {
@@ -457,6 +509,7 @@ static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
* minus the errnos that are not actually generic to all archs.
*/
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
+ [EAGAIN] = TARGET_EAGAIN,
[EIDRM] = TARGET_EIDRM,
[ECHRNG] = TARGET_ECHRNG,
[EL2NSYNC] = TARGET_EL2NSYNC,
@@ -1112,7 +1165,7 @@ static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
return 0;
}
-static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
+static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
abi_ulong target_addr,
socklen_t len)
{
@@ -1120,6 +1173,10 @@ static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
sa_family_t sa_family;
struct target_sockaddr *target_saddr;
+ if (fd_trans_target_to_host_addr(fd)) {
+ return fd_trans_target_to_host_addr(fd)(addr, target_addr, len);
+ }
+
target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
if (!target_saddr)
return -TARGET_EFAULT;
@@ -1181,7 +1238,7 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
abi_long msg_controllen;
abi_ulong target_cmsg_addr;
- struct target_cmsghdr *target_cmsg;
+ struct target_cmsghdr *target_cmsg, *target_cmsg_start;
socklen_t space = 0;
msg_controllen = tswapal(target_msgh->msg_controllen);
@@ -1189,6 +1246,7 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
goto the_end;
target_cmsg_addr = tswapal(target_msgh->msg_control);
target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
+ target_cmsg_start = target_cmsg;
if (!target_cmsg)
return -TARGET_EFAULT;
@@ -1247,7 +1305,8 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
}
cmsg = CMSG_NXTHDR(msgh, cmsg);
- target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
+ target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
+ target_cmsg_start);
}
unlock_user(target_cmsg, target_cmsg_addr, 0);
the_end:
@@ -1261,7 +1320,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
abi_long msg_controllen;
abi_ulong target_cmsg_addr;
- struct target_cmsghdr *target_cmsg;
+ struct target_cmsghdr *target_cmsg, *target_cmsg_start;
socklen_t space = 0;
msg_controllen = tswapal(target_msgh->msg_controllen);
@@ -1269,6 +1328,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
goto the_end;
target_cmsg_addr = tswapal(target_msgh->msg_control);
target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
+ target_cmsg_start = target_cmsg;
if (!target_cmsg)
return -TARGET_EFAULT;
@@ -1382,14 +1442,15 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
}
target_cmsg->cmsg_len = tswapal(tgt_len);
- tgt_space = TARGET_CMSG_SPACE(tgt_len);
+ tgt_space = TARGET_CMSG_SPACE(len);
if (msg_controllen < tgt_space) {
tgt_space = msg_controllen;
}
msg_controllen -= tgt_space;
space += tgt_space;
cmsg = CMSG_NXTHDR(msgh, cmsg);
- target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
+ target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
+ target_cmsg_start);
}
unlock_user(target_cmsg, target_cmsg_addr, space);
the_end:
@@ -1554,7 +1615,7 @@ set_timeout:
}
fprog.len = tswap16(tfprog->len);
- filter = malloc(fprog.len * sizeof(*filter));
+ filter = g_try_new(struct sock_filter, fprog.len);
if (filter == NULL) {
unlock_user_struct(tfilter, tfprog->filter, 1);
unlock_user_struct(tfprog, optval_addr, 1);
@@ -1570,7 +1631,7 @@ set_timeout:
ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
- free(filter);
+ g_free(filter);
unlock_user_struct(tfilter, tfprog->filter, 1);
unlock_user_struct(tfprog, optval_addr, 1);
@@ -1591,7 +1652,8 @@ set_timeout:
addr_ifname = alloca(IFNAMSIZ);
memcpy(addr_ifname, dev_ifname, optlen);
addr_ifname[optlen] = 0;
- ret = get_errno(setsockopt(sockfd, level, optname, addr_ifname, optlen));
+ ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
+ addr_ifname, optlen));
unlock_user (dev_ifname, optval_addr, 0);
return ret;
}
@@ -1881,7 +1943,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
return NULL;
}
- vec = calloc(count, sizeof(struct iovec));
+ vec = g_try_new0(struct iovec, count);
if (vec == NULL) {
errno = ENOMEM;
return NULL;
@@ -1945,7 +2007,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
}
unlock_user(target_vec, target_addr, 0);
fail2:
- free(vec);
+ g_free(vec);
errno = err;
return NULL;
}
@@ -1970,7 +2032,7 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
unlock_user(target_vec, target_addr, 0);
}
- free(vec);
+ g_free(vec);
}
static inline int target_to_host_sock_type(int *type)
@@ -2022,6 +2084,30 @@ static int sock_flags_fixup(int fd, int target_type)
return fd;
}
+static abi_long packet_target_to_host_sockaddr(void *host_addr,
+ abi_ulong target_addr,
+ socklen_t len)
+{
+ struct sockaddr *addr = host_addr;
+ struct target_sockaddr *target_saddr;
+
+ target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
+ if (!target_saddr) {
+ return -TARGET_EFAULT;
+ }
+
+ memcpy(addr, target_saddr, len);
+ addr->sa_family = tswap16(target_saddr->sa_family);
+ /* spkt_protocol is big-endian */
+
+ unlock_user(target_saddr, target_addr, 0);
+ return 0;
+}
+
+static TargetFdTrans target_packet_trans = {
+ .target_to_host_addr = packet_target_to_host_sockaddr,
+};
+
/* do_socket() Must return target values and target errnos. */
static abi_long do_socket(int domain, int type, int protocol)
{
@@ -2035,9 +2121,21 @@ static abi_long do_socket(int domain, int type, int protocol)
if (domain == PF_NETLINK)
return -TARGET_EAFNOSUPPORT;
+
+ if (domain == AF_PACKET ||
+ (domain == AF_INET && type == SOCK_PACKET)) {
+ protocol = tswap16(protocol);
+ }
+
ret = get_errno(socket(domain, type, protocol));
if (ret >= 0) {
ret = sock_flags_fixup(ret, target_type);
+ if (type == SOCK_PACKET) {
+ /* Manage an obsolete case :
+ * if socket type is SOCK_PACKET, bind by name
+ */
+ fd_trans_register(ret, &target_packet_trans);
+ }
}
return ret;
}
@@ -2055,7 +2153,7 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr,
addr = alloca(addrlen+1);
- ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+ ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
if (ret)
return ret;
@@ -2075,7 +2173,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr,
addr = alloca(addrlen+1);
- ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+ ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
if (ret)
return ret;
@@ -2095,8 +2193,9 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
if (msgp->msg_name) {
msg.msg_namelen = tswap32(msgp->msg_namelen);
msg.msg_name = alloca(msg.msg_namelen+1);
- ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
- msg.msg_namelen);
+ ret = target_to_host_sockaddr(fd, msg.msg_name,
+ tswapal(msgp->msg_name),
+ msg.msg_namelen);
if (ret) {
goto out2;
}
@@ -2166,7 +2265,6 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
return ret;
}
-#ifdef TARGET_NR_sendmmsg
/* We don't rely on the C library to have sendmmsg/recvmmsg support,
* so it might not have this *mmsg-specific flag either.
*/
@@ -2213,7 +2311,6 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
}
return ret;
}
-#endif
/* If we don't have a system accept4() then just call accept.
* The callsites to do_accept4() will ensure that they don't
@@ -2358,7 +2455,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
return -TARGET_EFAULT;
if (target_addr) {
addr = alloca(addrlen+1);
- ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+ ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
if (ret) {
unlock_user(host_msg, msg, 0);
return ret;
@@ -2436,6 +2533,8 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
[SOCKOP_shutdown] = 2, /* sockfd, how */
[SOCKOP_sendmsg] = 3, /* sockfd, msg, flags */
[SOCKOP_recvmsg] = 3, /* sockfd, msg, flags */
+ [SOCKOP_sendmmsg] = 4, /* sockfd, msgvec, vlen, flags */
+ [SOCKOP_recvmmsg] = 4, /* sockfd, msgvec, vlen, flags */
[SOCKOP_setsockopt] = 5, /* sockfd, level, optname, optval, optlen */
[SOCKOP_getsockopt] = 5, /* sockfd, level, optname, optval, optlen */
};
@@ -2486,6 +2585,10 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
return do_sendrecvmsg(a[0], a[1], a[2], 1);
case SOCKOP_recvmsg: /* sockfd, msg, flags */
return do_sendrecvmsg(a[0], a[1], a[2], 0);
+ case SOCKOP_sendmmsg: /* sockfd, msgvec, vlen, flags */
+ return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
+ case SOCKOP_recvmmsg: /* sockfd, msgvec, vlen, flags */
+ return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
case SOCKOP_setsockopt: /* sockfd, level, optname, optval, optlen */
return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
case SOCKOP_getsockopt: /* sockfd, level, optname, optval, optlen */
@@ -2500,8 +2603,9 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
#define N_SHM_REGIONS 32
static struct shm_region {
- abi_ulong start;
- abi_ulong size;
+ abi_ulong start;
+ abi_ulong size;
+ bool in_use;
} shm_regions[N_SHM_REGIONS];
struct target_semid_ds
@@ -2672,14 +2776,14 @@ static inline abi_long target_to_host_semarray(int semid, unsigned short **host_
nsems = semid_ds.sem_nsems;
- *host_array = malloc(nsems*sizeof(unsigned short));
+ *host_array = g_try_new(unsigned short, nsems);
if (!*host_array) {
return -TARGET_ENOMEM;
}
array = lock_user(VERIFY_READ, target_addr,
nsems*sizeof(unsigned short), 1);
if (!array) {
- free(*host_array);
+ g_free(*host_array);
return -TARGET_EFAULT;
}
@@ -2716,15 +2820,16 @@ static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
for(i=0; i<nsems; i++) {
__put_user((*host_array)[i], &array[i]);
}
- free(*host_array);
+ g_free(*host_array);
unlock_user(array, target_addr, 1);
return 0;
}
static inline abi_long do_semctl(int semid, int semnum, int cmd,
- union target_semun target_su)
+ abi_ulong target_arg)
{
+ union target_semun target_su = { .buf = target_arg };
union semun arg;
struct semid_ds dsarg;
unsigned short *array = NULL;
@@ -2975,7 +3080,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
return -TARGET_EFAULT;
- host_mb = malloc(msgsz+sizeof(long));
+ host_mb = g_try_malloc(msgsz + sizeof(long));
if (!host_mb) {
unlock_user_struct(target_mb, msgp, 0);
return -TARGET_ENOMEM;
@@ -2983,7 +3088,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
memcpy(host_mb->mtext, target_mb->mtext, msgsz);
ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
- free(host_mb);
+ g_free(host_mb);
unlock_user_struct(target_mb, msgp, 0);
return ret;
@@ -3192,7 +3297,8 @@ static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
for (i = 0; i < N_SHM_REGIONS; i++) {
- if (shm_regions[i].start == 0) {
+ if (!shm_regions[i].in_use) {
+ shm_regions[i].in_use = true;
shm_regions[i].start = raddr;
shm_regions[i].size = shm_info.shm_segsz;
break;
@@ -3209,8 +3315,8 @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
int i;
for (i = 0; i < N_SHM_REGIONS; ++i) {
- if (shm_regions[i].start == shmaddr) {
- shm_regions[i].start = 0;
+ if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
+ shm_regions[i].in_use = false;
page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
break;
}
@@ -3246,8 +3352,7 @@ static abi_long do_ipc(unsigned int call, abi_long first,
* ptr argument. */
abi_ulong atptr;
get_user_ual(atptr, ptr);
- ret = do_semctl(first, second, third,
- (union target_semun) atptr);
+ ret = do_semctl(first, second, third, atptr);
break;
}
@@ -3411,7 +3516,7 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
/* We can't fit all the extents into the fixed size buffer.
* Allocate one that is large enough and use it instead.
*/
- fm = malloc(outbufsz);
+ fm = g_try_malloc(outbufsz);
if (!fm) {
return -TARGET_ENOMEM;
}
@@ -3446,7 +3551,7 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
}
}
if (free_fm) {
- free(fm);
+ g_free(fm);
}
return ret;
}
@@ -3939,7 +4044,6 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
break;
case TYPE_PTRVOID:
case TYPE_INT:
- /* int argment */
ret = get_errno(ioctl(fd, ie->host_cmd, arg));
break;
case TYPE_PTR:
@@ -4513,6 +4617,7 @@ static void *clone_func(void *arg)
CPUState *cpu;
TaskState *ts;
+ rcu_register_thread();
env = info->env;
cpu = ENV_GET_CPU(env);
thread_cpu = cpu;
@@ -4561,7 +4666,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
new_thread_info info;
pthread_attr_t attr;
- ts = g_malloc0(sizeof(TaskState));
+ ts = g_new0(TaskState, 1);
init_task_state(ts);
/* we create a new CPU instance. */
new_env = cpu_copy(env);
@@ -4622,8 +4727,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
pthread_mutex_unlock(&clone_lock);
} else {
/* if no CLONE_VM, we consider it is a fork */
- if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
- return -EINVAL;
+ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
+ return -TARGET_EINVAL;
+ }
fork_start();
ret = fork();
if (ret == 0) {
@@ -5130,7 +5236,6 @@ static inline int target_to_host_mlockall_arg(int arg)
}
#endif
-#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
static inline abi_long host_to_target_stat64(void *cpu_env,
abi_ulong target_addr,
struct stat *host_st)
@@ -5193,7 +5298,6 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
return 0;
}
-#endif
/* ??? Using host futex calls even when target atomic operations
are not really atomic probably breaks things. However implementing
@@ -5246,6 +5350,179 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
return -TARGET_ENOSYS;
}
}
+#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
+static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
+ abi_long handle, abi_long mount_id,
+ abi_long flags)
+{
+ struct file_handle *target_fh;
+ struct file_handle *fh;
+ int mid = 0;
+ abi_long ret;
+ char *name;
+ unsigned int size, total_size;
+
+ if (get_user_s32(size, handle)) {
+ return -TARGET_EFAULT;
+ }
+
+ name = lock_user_string(pathname);
+ if (!name) {
+ return -TARGET_EFAULT;
+ }
+
+ total_size = sizeof(struct file_handle) + size;
+ target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
+ if (!target_fh) {
+ unlock_user(name, pathname, 0);
+ return -TARGET_EFAULT;
+ }
+
+ fh = g_malloc0(total_size);
+ fh->handle_bytes = size;
+
+ ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
+ unlock_user(name, pathname, 0);
+
+ /* man name_to_handle_at(2):
+ * Other than the use of the handle_bytes field, the caller should treat
+ * the file_handle structure as an opaque data type
+ */
+
+ memcpy(target_fh, fh, total_size);
+ target_fh->handle_bytes = tswap32(fh->handle_bytes);
+ target_fh->handle_type = tswap32(fh->handle_type);
+ g_free(fh);
+ unlock_user(target_fh, handle, total_size);
+
+ if (put_user_s32(mid, mount_id)) {
+ return -TARGET_EFAULT;
+ }
+
+ return ret;
+
+}
+#endif
+
+#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
+static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
+ abi_long flags)
+{
+ struct file_handle *target_fh;
+ struct file_handle *fh;
+ unsigned int size, total_size;
+ abi_long ret;
+
+ if (get_user_s32(size, handle)) {
+ return -TARGET_EFAULT;
+ }
+
+ total_size = sizeof(struct file_handle) + size;
+ target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
+ if (!target_fh) {
+ return -TARGET_EFAULT;
+ }
+
+ fh = g_memdup(target_fh, total_size);
+ fh->handle_bytes = size;
+ fh->handle_type = tswap32(target_fh->handle_type);
+
+ ret = get_errno(open_by_handle_at(mount_fd, fh,
+ target_to_host_bitmask(flags, fcntl_flags_tbl)));
+
+ g_free(fh);
+
+ unlock_user(target_fh, handle, total_size);
+
+ return ret;
+}
+#endif
+
+#if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
+
+/* signalfd siginfo conversion */
+
+static void
+host_to_target_signalfd_siginfo(struct signalfd_siginfo *tinfo,
+ const struct signalfd_siginfo *info)
+{
+ int sig = host_to_target_signal(info->ssi_signo);
+
+ /* linux/signalfd.h defines a ssi_addr_lsb
+ * not defined in sys/signalfd.h but used by some kernels
+ */
+
+#ifdef BUS_MCEERR_AO
+ if (tinfo->ssi_signo == SIGBUS &&
+ (tinfo->ssi_code == BUS_MCEERR_AR ||
+ tinfo->ssi_code == BUS_MCEERR_AO)) {
+ uint16_t *ssi_addr_lsb = (uint16_t *)(&info->ssi_addr + 1);
+ uint16_t *tssi_addr_lsb = (uint16_t *)(&tinfo->ssi_addr + 1);
+ *tssi_addr_lsb = tswap16(*ssi_addr_lsb);
+ }
+#endif
+
+ tinfo->ssi_signo = tswap32(sig);
+ tinfo->ssi_errno = tswap32(tinfo->ssi_errno);
+ tinfo->ssi_code = tswap32(info->ssi_code);
+ tinfo->ssi_pid = tswap32(info->ssi_pid);
+ tinfo->ssi_uid = tswap32(info->ssi_uid);
+ tinfo->ssi_fd = tswap32(info->ssi_fd);
+ tinfo->ssi_tid = tswap32(info->ssi_tid);
+ tinfo->ssi_band = tswap32(info->ssi_band);
+ tinfo->ssi_overrun = tswap32(info->ssi_overrun);
+ tinfo->ssi_trapno = tswap32(info->ssi_trapno);
+ tinfo->ssi_status = tswap32(info->ssi_status);
+ tinfo->ssi_int = tswap32(info->ssi_int);
+ tinfo->ssi_ptr = tswap64(info->ssi_ptr);
+ tinfo->ssi_utime = tswap64(info->ssi_utime);
+ tinfo->ssi_stime = tswap64(info->ssi_stime);
+ tinfo->ssi_addr = tswap64(info->ssi_addr);
+}
+
+static abi_long host_to_target_data_signalfd(void *buf, size_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i += sizeof(struct signalfd_siginfo)) {
+ host_to_target_signalfd_siginfo(buf + i, buf + i);
+ }
+
+ return len;
+}
+
+static TargetFdTrans target_signalfd_trans = {
+ .host_to_target_data = host_to_target_data_signalfd,
+};
+
+static abi_long do_signalfd4(int fd, abi_long mask, int flags)
+{
+ int host_flags;
+ target_sigset_t *target_mask;
+ sigset_t host_mask;
+ abi_long ret;
+
+ if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
+ return -TARGET_EINVAL;
+ }
+ if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
+ return -TARGET_EFAULT;
+ }
+
+ target_to_host_sigset(&host_mask, target_mask);
+
+ host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
+
+ ret = get_errno(signalfd(fd, &host_mask, host_flags));
+ if (ret >= 0) {
+ fd_trans_register(ret, &target_signalfd_trans);
+ }
+
+ unlock_user_struct(target_mask, mask, 0);
+
+ return ret;
+}
+#endif
/* Map host to target signal numbers for the wait family of syscalls.
Assume all other status bits are the same. */
@@ -5614,6 +5891,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
thread_cpu = NULL;
object_unref(OBJECT(cpu));
g_free(ts);
+ rcu_unregister_thread();
pthread_exit(NULL);
}
#ifdef TARGET_GPROF
@@ -5630,6 +5908,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
goto efault;
ret = get_errno(read(arg1, p, arg3));
+ if (ret >= 0 &&
+ fd_trans_host_to_target_data(arg1)) {
+ ret = fd_trans_host_to_target_data(arg1)(p, ret);
+ }
unlock_user(p, arg2, ret);
}
break;
@@ -5639,31 +5921,49 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(write(arg1, p, arg3));
unlock_user(p, arg2, 0);
break;
+#ifdef TARGET_NR_open
case TARGET_NR_open:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
target_to_host_bitmask(arg2, fcntl_flags_tbl),
arg3));
+ fd_trans_unregister(ret);
unlock_user(p, arg1, 0);
break;
+#endif
case TARGET_NR_openat:
if (!(p = lock_user_string(arg2)))
goto efault;
ret = get_errno(do_openat(cpu_env, arg1, p,
target_to_host_bitmask(arg3, fcntl_flags_tbl),
arg4));
+ fd_trans_unregister(ret);
unlock_user(p, arg2, 0);
break;
+#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
+ case TARGET_NR_name_to_handle_at:
+ ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
+ break;
+#endif
+#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
+ case TARGET_NR_open_by_handle_at:
+ ret = do_open_by_handle_at(arg1, arg2, arg3);
+ fd_trans_unregister(ret);
+ break;
+#endif
case TARGET_NR_close:
+ fd_trans_unregister(arg1);
ret = get_errno(close(arg1));
break;
case TARGET_NR_brk:
ret = do_brk(arg1);
break;
+#ifdef TARGET_NR_fork
case TARGET_NR_fork:
ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
break;
+#endif
#ifdef TARGET_NR_waitpid
case TARGET_NR_waitpid:
{
@@ -5695,9 +5995,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(creat(p, arg2));
+ fd_trans_unregister(ret);
unlock_user(p, arg1, 0);
break;
#endif
+#ifdef TARGET_NR_link
case TARGET_NR_link:
{
void * p2;
@@ -5711,6 +6013,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
}
break;
+#endif
#if defined(TARGET_NR_linkat)
case TARGET_NR_linkat:
{
@@ -5728,12 +6031,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_unlink
case TARGET_NR_unlink:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(unlink(p));
unlock_user(p, arg1, 0);
break;
+#endif
#if defined(TARGET_NR_unlinkat)
case TARGET_NR_unlinkat:
if (!(p = lock_user_string(arg2)))
@@ -5799,12 +6104,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
*q = NULL;
- /* This case will not be caught by the host's execve() if its
- page size is bigger than the target's. */
- if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
- ret = -TARGET_E2BIG;
- goto execve_end;
- }
if (!(p = lock_user_string(arg1)))
goto execve_efault;
ret = get_errno(execve(p, argp, envp));
@@ -5850,12 +6149,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_mknod
case TARGET_NR_mknod:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(mknod(p, arg2, arg3));
unlock_user(p, arg1, 0);
break;
+#endif
#if defined(TARGET_NR_mknodat)
case TARGET_NR_mknodat:
if (!(p = lock_user_string(arg2)))
@@ -5864,12 +6165,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg2, 0);
break;
#endif
+#ifdef TARGET_NR_chmod
case TARGET_NR_chmod:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(chmod(p, arg2));
unlock_user(p, arg1, 0);
break;
+#endif
#ifdef TARGET_NR_break
case TARGET_NR_break:
goto unimplemented;
@@ -6004,6 +6307,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_utimes
case TARGET_NR_utimes:
{
struct timeval *tvp, tv[2];
@@ -6022,6 +6326,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
}
break;
+#endif
#if defined(TARGET_NR_futimesat)
case TARGET_NR_futimesat:
{
@@ -6050,12 +6355,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_gtty:
goto unimplemented;
#endif
+#ifdef TARGET_NR_access
case TARGET_NR_access:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(access(path(p), arg2));
unlock_user(p, arg1, 0);
break;
+#endif
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
case TARGET_NR_faccessat:
if (!(p = lock_user_string(arg2)))
@@ -6080,6 +6387,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_kill:
ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
break;
+#ifdef TARGET_NR_rename
case TARGET_NR_rename:
{
void *p2;
@@ -6093,6 +6401,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
}
break;
+#endif
#if defined(TARGET_NR_renameat)
case TARGET_NR_renameat:
{
@@ -6108,12 +6417,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_mkdir
case TARGET_NR_mkdir:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(mkdir(p, arg2));
unlock_user(p, arg1, 0);
break;
+#endif
#if defined(TARGET_NR_mkdirat)
case TARGET_NR_mkdirat:
if (!(p = lock_user_string(arg2)))
@@ -6122,18 +6433,25 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg2, 0);
break;
#endif
+#ifdef TARGET_NR_rmdir
case TARGET_NR_rmdir:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(rmdir(p));
unlock_user(p, arg1, 0);
break;
+#endif
case TARGET_NR_dup:
ret = get_errno(dup(arg1));
+ if (ret >= 0) {
+ fd_trans_dup(arg1, ret);
+ }
break;
+#ifdef TARGET_NR_pipe
case TARGET_NR_pipe:
ret = do_pipe(cpu_env, arg1, 0, 0);
break;
+#endif
#ifdef TARGET_NR_pipe2
case TARGET_NR_pipe2:
ret = do_pipe(cpu_env, arg1,
@@ -6218,14 +6536,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(chroot(p));
unlock_user(p, arg1, 0);
break;
+#ifdef TARGET_NR_ustat
case TARGET_NR_ustat:
goto unimplemented;
+#endif
+#ifdef TARGET_NR_dup2
case TARGET_NR_dup2:
ret = get_errno(dup2(arg1, arg2));
+ if (ret >= 0) {
+ fd_trans_dup(arg1, arg2);
+ }
break;
+#endif
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
case TARGET_NR_dup3:
ret = get_errno(dup3(arg1, arg2, arg3));
+ if (ret >= 0) {
+ fd_trans_dup(arg1, arg2);
+ }
break;
#endif
#ifdef TARGET_NR_getppid /* not on alpha */
@@ -6233,9 +6561,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(getppid());
break;
#endif
+#ifdef TARGET_NR_getpgrp
case TARGET_NR_getpgrp:
ret = get_errno(getpgrp());
break;
+#endif
case TARGET_NR_setsid:
ret = get_errno(setsid());
break;
@@ -6811,6 +7141,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_symlink
case TARGET_NR_symlink:
{
void *p2;
@@ -6824,6 +7155,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
}
break;
+#endif
#if defined(TARGET_NR_symlinkat)
case TARGET_NR_symlinkat:
{
@@ -6843,6 +7175,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_oldlstat:
goto unimplemented;
#endif
+#ifdef TARGET_NR_readlink
case TARGET_NR_readlink:
{
void *p2;
@@ -6873,6 +7206,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
}
break;
+#endif
#if defined(TARGET_NR_readlinkat)
case TARGET_NR_readlinkat:
{
@@ -7212,9 +7546,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(shutdown(arg1, arg2));
break;
#endif
+#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
+ case TARGET_NR_getrandom:
+ p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
+ if (!p) {
+ goto efault;
+ }
+ ret = get_errno(getrandom(p, arg2, arg3));
+ unlock_user(p, arg1, ret);
+ break;
+#endif
#ifdef TARGET_NR_socket
case TARGET_NR_socket:
ret = do_socket(arg1, arg2, arg3);
+ fd_trans_unregister(ret);
break;
#endif
#ifdef TARGET_NR_socketpair
@@ -7272,22 +7617,28 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
}
break;
+#ifdef TARGET_NR_stat
case TARGET_NR_stat:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(stat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat;
+#endif
+#ifdef TARGET_NR_lstat
case TARGET_NR_lstat:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(lstat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat;
+#endif
case TARGET_NR_fstat:
{
ret = get_errno(fstat(arg1, &st));
+#if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat)
do_stat:
+#endif
if (!is_error(ret)) {
struct target_stat *target_st;
@@ -7411,7 +7762,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_semctl
case TARGET_NR_semctl:
- ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
+ ret = do_semctl(arg1, arg2, arg3, arg4);
break;
#endif
#ifdef TARGET_NR_msgctl
@@ -7575,6 +7926,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_getdents
case TARGET_NR_getdents:
#ifdef __NR_getdents
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
@@ -7583,8 +7935,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
struct linux_dirent *dirp;
abi_long count = arg3;
- dirp = malloc(count);
- if (!dirp) {
+ dirp = g_try_malloc(count);
+ if (!dirp) {
ret = -TARGET_ENOMEM;
goto fail;
}
@@ -7620,7 +7972,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = count1;
unlock_user(target_dirp, arg2, ret);
}
- free(dirp);
+ g_free(dirp);
}
#else
{
@@ -7705,6 +8057,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
#endif
break;
+#endif /* TARGET_NR_getdents */
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
case TARGET_NR_getdents64:
{
@@ -7752,14 +8105,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
struct pollfd *pfd;
unsigned int i;
- target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
- if (!target_pfd)
- goto efault;
+ pfd = NULL;
+ target_pfd = NULL;
+ if (nfds) {
+ target_pfd = lock_user(VERIFY_WRITE, arg1,
+ sizeof(struct target_pollfd) * nfds, 1);
+ if (!target_pfd) {
+ goto efault;
+ }
- pfd = alloca(sizeof(struct pollfd) * nfds);
- for(i = 0; i < nfds; i++) {
- pfd[i].fd = tswap32(target_pfd[i].fd);
- pfd[i].events = tswap16(target_pfd[i].events);
+ pfd = alloca(sizeof(struct pollfd) * nfds);
+ for (i = 0; i < nfds; i++) {
+ pfd[i].fd = tswap32(target_pfd[i].fd);
+ pfd[i].events = tswap16(target_pfd[i].events);
+ }
}
# ifdef TARGET_NR_ppoll
@@ -7844,11 +8203,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(fdatasync(arg1));
break;
#endif
+#ifdef TARGET_NR__sysctl
case TARGET_NR__sysctl:
/* We don't implement this, but ENOTDIR is always a safe
return value. */
ret = -TARGET_ENOTDIR;
break;
+#endif
case TARGET_NR_sched_getaffinity:
{
unsigned int mask_size;
@@ -8150,14 +8511,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
}
case TARGET_NR_sigaltstack:
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
- defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
- defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
break;
-#else
- goto unimplemented;
-#endif
#ifdef CONFIG_SENDFILE
case TARGET_NR_sendfile:
@@ -8295,12 +8650,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = host_to_target_stat64(cpu_env, arg3, &st);
break;
#endif
+#ifdef TARGET_NR_lchown
case TARGET_NR_lchown:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
unlock_user(p, arg1, 0);
break;
+#endif
#ifdef TARGET_NR_getuid
case TARGET_NR_getuid:
ret = get_errno(high2lowuid(getuid()));
@@ -8423,12 +8780,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
+#ifdef TARGET_NR_chown
case TARGET_NR_chown:
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
unlock_user(p, arg1, 0);
break;
+#endif
case TARGET_NR_setuid:
ret = get_errno(setuid(low2highuid(arg1)));
break;
@@ -9454,6 +9813,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#if defined(TARGET_NR_eventfd)
case TARGET_NR_eventfd:
ret = get_errno(eventfd(arg1, 0));
+ fd_trans_unregister(ret);
break;
#endif
#if defined(TARGET_NR_eventfd2)
@@ -9467,6 +9827,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
host_flags |= O_CLOEXEC;
}
ret = get_errno(eventfd(arg1, host_flags));
+ fd_trans_unregister(ret);
break;
}
#endif
@@ -9509,6 +9870,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
#endif
+#if defined(TARGET_NR_signalfd4)
+ case TARGET_NR_signalfd4:
+ ret = do_signalfd4(arg1, arg2, arg4);
+ break;
+#endif
+#if defined(TARGET_NR_signalfd)
+ case TARGET_NR_signalfd:
+ ret = do_signalfd4(arg1, arg2, 0);
+ break;
+#endif
#if defined(CONFIG_EPOLL)
#if defined(TARGET_NR_epoll_create)
case TARGET_NR_epoll_create:
@@ -9780,6 +10151,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_getoverrun(htimer));
}
+ fd_trans_unregister(ret);
break;
}
#endif
diff --git a/qemu/linux-user/syscall_defs.h b/qemu/linux-user/syscall_defs.h
index edd5f3c80..9e2b3c200 100644
--- a/qemu/linux-user/syscall_defs.h
+++ b/qemu/linux-user/syscall_defs.h
@@ -28,6 +28,8 @@
#define SOCKOP_sendmsg 16
#define SOCKOP_recvmsg 17
#define SOCKOP_accept4 18
+#define SOCKOP_recvmmsg 19
+#define SOCKOP_sendmmsg 20
#define IPCOP_semop 1
#define IPCOP_semget 2
@@ -64,8 +66,9 @@
#endif
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
- || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \
- || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ || defined(TARGET_M68K) || defined(TARGET_CRIS) \
+ || defined(TARGET_UNICORE32) || defined(TARGET_S390X) \
+ || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)
#define TARGET_IOC_SIZEBITS 14
#define TARGET_IOC_DIRBITS 2
@@ -234,7 +237,8 @@ struct target_cmsghdr {
};
#define TARGET_CMSG_DATA(cmsg) ((unsigned char *) ((struct target_cmsghdr *) (cmsg) + 1))
-#define TARGET_CMSG_NXTHDR(mhdr, cmsg) __target_cmsg_nxthdr (mhdr, cmsg)
+#define TARGET_CMSG_NXTHDR(mhdr, cmsg, cmsg_start) \
+ __target_cmsg_nxthdr(mhdr, cmsg, cmsg_start)
#define TARGET_CMSG_ALIGN(len) (((len) + sizeof (abi_long) - 1) \
& (size_t) ~(sizeof (abi_long) - 1))
#define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN (len) \
@@ -242,17 +246,20 @@ struct target_cmsghdr {
#define TARGET_CMSG_LEN(len) (TARGET_CMSG_ALIGN (sizeof (struct target_cmsghdr)) + (len))
static __inline__ struct target_cmsghdr *
-__target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr *__cmsg)
+__target_cmsg_nxthdr(struct target_msghdr *__mhdr,
+ struct target_cmsghdr *__cmsg,
+ struct target_cmsghdr *__cmsg_start)
{
struct target_cmsghdr *__ptr;
__ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg
+ TARGET_CMSG_ALIGN (tswapal(__cmsg->cmsg_len)));
- if ((unsigned long)((char *)(__ptr+1) - (char *)(size_t)tswapal(__mhdr->msg_control))
- > tswapal(__mhdr->msg_controllen))
+ if ((unsigned long)((char *)(__ptr+1) - (char *)__cmsg_start)
+ > tswapal(__mhdr->msg_controllen)) {
/* No more entries. */
return (struct target_cmsghdr *)0;
- return __cmsg;
+ }
+ return __ptr;
}
struct target_mmsghdr {
@@ -365,7 +372,8 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|| defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \
|| defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
|| defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
- || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
+ || defined(TARGET_TILEGX)
#if defined(TARGET_SPARC)
#define TARGET_SA_NOCLDSTOP 8u
@@ -742,6 +750,10 @@ typedef struct target_siginfo {
#define TARGET_ILL_PRVREG (6) /* privileged register */
#define TARGET_ILL_COPROC (7) /* coprocessor error */
#define TARGET_ILL_BADSTK (8) /* internal stack error */
+#ifdef TARGET_TILEGX
+#define TARGET_ILL_DBLFLT (9) /* double fault */
+#define TARGET_ILL_HARDWALL (10) /* user networks hardwall violation */
+#endif
/*
* SIGFPE si_codes
@@ -761,6 +773,7 @@ typedef struct target_siginfo {
*/
#define TARGET_SEGV_MAPERR (1) /* address not mapped to object */
#define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped object */
+#define TARGET_SEGV_BNDERR (3) /* failed address bound checks */
/*
* SIGBUS si_codes
@@ -768,12 +781,18 @@ typedef struct target_siginfo {
#define TARGET_BUS_ADRALN (1) /* invalid address alignment */
#define TARGET_BUS_ADRERR (2) /* non-existent physical address */
#define TARGET_BUS_OBJERR (3) /* object specific hardware error */
+/* hardware memory error consumed on a machine check: action required */
+#define TARGET_BUS_MCEERR_AR (4)
+/* hardware memory error detected in process but not consumed: action optional*/
+#define TARGET_BUS_MCEERR_AO (5)
/*
* SIGTRAP si_codes
*/
#define TARGET_TRAP_BRKPT (1) /* process breakpoint */
#define TARGET_TRAP_TRACE (2) /* process trace trap */
+#define TARGET_TRAP_BRANCH (3) /* process taken branch trap */
+#define TARGET_TRAP_HWBKPT (4) /* hardware breakpoint/watchpoint */
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) */
@@ -969,7 +988,7 @@ struct target_pollfd {
(struct cdrom_multisession) */
#define TARGET_CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
if available (struct cdrom_mcn) */
-#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is depricated,
+#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is deprecated,
but here anyway for compatibility */
#define TARGET_CDROMRESET 0x5312 /* hard-reset the drive */
#define TARGET_CDROMVOLREAD 0x5313 /* Get the drive's volume setting
@@ -1871,7 +1890,7 @@ struct target_stat {
abi_ulong target_st_ctime_nsec;
unsigned int __unused[2];
};
-#elif defined(TARGET_OPENRISC)
+#elif defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)
/* These are the asm-generic versions of the stat and stat64 structures */
@@ -2264,7 +2283,9 @@ struct target_flock {
struct target_flock64 {
short l_type;
short l_whence;
-#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) || defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined (TARGET_MICROBLAZE)
+#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) \
+ || defined(TARGET_SPARC) || defined(TARGET_HPPA) \
+ || defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX)
int __pad;
#endif
unsigned long long l_start;
@@ -2289,7 +2310,7 @@ struct target_f_owner_ex {
};
/* soundcard defines */
-/* XXX: convert them all to arch indepedent entries */
+/* XXX: convert them all to arch independent entries */
#define TARGET_SNDCTL_COPR_HALT TARGET_IOWR('C', 7, int);
#define TARGET_SNDCTL_COPR_LOAD 0xcfb04301
#define TARGET_SNDCTL_COPR_RCODE 0xc0144303
@@ -2495,20 +2516,23 @@ struct target_mq_attr {
#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
#ifdef CONFIG_EPOLL
+#if defined(TARGET_X86_64)
+#define TARGET_EPOLL_PACKED QEMU_PACKED
+#else
+#define TARGET_EPOLL_PACKED
+#endif
+
typedef union target_epoll_data {
abi_ulong ptr;
- abi_ulong fd;
- uint32_t u32;
- uint64_t u64;
+ abi_int fd;
+ abi_uint u32;
+ abi_ullong u64;
} target_epoll_data_t;
struct target_epoll_event {
- uint32_t events;
-#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_MIPS64)
- uint32_t __pad;
-#endif
+ abi_uint events;
target_epoll_data_t data;
-} QEMU_PACKED;
+} TARGET_EPOLL_PACKED;
#endif
struct target_rlimit64 {
uint64_t rlim_cur;
diff --git a/qemu/linux-user/tilegx/syscall_nr.h b/qemu/linux-user/tilegx/syscall_nr.h
new file mode 100644
index 000000000..87fb72c55
--- /dev/null
+++ b/qemu/linux-user/tilegx/syscall_nr.h
@@ -0,0 +1,328 @@
+#ifndef TILEGX_SYSCALL_NR
+#define TILEGX_SYSCALL_NR
+
+/*
+ * Copy from linux kernel asm-generic/unistd.h, which tilegx uses.
+ */
+#define TARGET_NR_io_setup 0
+#define TARGET_NR_io_destroy 1
+#define TARGET_NR_io_submit 2
+#define TARGET_NR_io_cancel 3
+#define TARGET_NR_io_getevents 4
+#define TARGET_NR_setxattr 5
+#define TARGET_NR_lsetxattr 6
+#define TARGET_NR_fsetxattr 7
+#define TARGET_NR_getxattr 8
+#define TARGET_NR_lgetxattr 9
+#define TARGET_NR_fgetxattr 10
+#define TARGET_NR_listxattr 11
+#define TARGET_NR_llistxattr 12
+#define TARGET_NR_flistxattr 13
+#define TARGET_NR_removexattr 14
+#define TARGET_NR_lremovexattr 15
+#define TARGET_NR_fremovexattr 16
+#define TARGET_NR_getcwd 17
+#define TARGET_NR_lookup_dcookie 18
+#define TARGET_NR_eventfd2 19
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait 22
+#define TARGET_NR_dup 23
+#define TARGET_NR_dup3 24
+#define TARGET_NR_fcntl 25
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch 28
+#define TARGET_NR_ioctl 29
+#define TARGET_NR_ioprio_set 30
+#define TARGET_NR_ioprio_get 31
+#define TARGET_NR_flock 32
+#define TARGET_NR_mknodat 33
+#define TARGET_NR_mkdirat 34
+#define TARGET_NR_unlinkat 35
+#define TARGET_NR_symlinkat 36
+#define TARGET_NR_linkat 37
+#define TARGET_NR_renameat 38
+#define TARGET_NR_umount2 39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root 41
+#define TARGET_NR_nfsservctl 42
+#define TARGET_NR_statfs 43
+#define TARGET_NR_fstatfs 44
+#define TARGET_NR_truncate 45
+#define TARGET_NR_ftruncate 46
+#define TARGET_NR_fallocate 47
+#define TARGET_NR_faccessat 48
+#define TARGET_NR_chdir 49
+#define TARGET_NR_fchdir 50
+#define TARGET_NR_chroot 51
+#define TARGET_NR_fchmod 52
+#define TARGET_NR_fchmodat 53
+#define TARGET_NR_fchownat 54
+#define TARGET_NR_fchown 55
+#define TARGET_NR_openat 56
+#define TARGET_NR_close 57
+#define TARGET_NR_vhangup 58
+#define TARGET_NR_pipe2 59
+#define TARGET_NR_quotactl 60
+#define TARGET_NR_getdents64 61
+#define TARGET_NR_lseek 62
+#define TARGET_NR_read 63
+#define TARGET_NR_write 64
+#define TARGET_NR_readv 65
+#define TARGET_NR_writev 66
+#define TARGET_NR_pread64 67
+#define TARGET_NR_pwrite64 68
+#define TARGET_NR_preadv 69
+#define TARGET_NR_pwritev 70
+#define TARGET_NR_sendfile 71
+#define TARGET_NR_pselect6 72
+#define TARGET_NR_ppoll 73
+#define TARGET_NR_signalfd4 74
+#define TARGET_NR_vmsplice 75
+#define TARGET_NR_splice 76
+#define TARGET_NR_tee 77
+#define TARGET_NR_readlinkat 78
+#define TARGET_NR_fstatat64 79 /* let syscall.c known */
+#define TARGET_NR_fstat 80
+#define TARGET_NR_sync 81
+#define TARGET_NR_fsync 82
+#define TARGET_NR_fdatasync 83
+#define TARGET_NR_sync_file_range 84 /* For tilegx, no range2 */
+#define TARGET_NR_timerfd_create 85
+#define TARGET_NR_timerfd_settime 86
+#define TARGET_NR_timerfd_gettime 87
+#define TARGET_NR_utimensat 88
+#define TARGET_NR_acct 89
+#define TARGET_NR_capget 90
+#define TARGET_NR_capset 91
+#define TARGET_NR_personality 92
+#define TARGET_NR_exit 93
+#define TARGET_NR_exit_group 94
+#define TARGET_NR_waitid 95
+#define TARGET_NR_set_tid_address 96
+#define TARGET_NR_unshare 97
+#define TARGET_NR_futex 98
+#define TARGET_NR_set_robust_list 99
+#define TARGET_NR_get_robust_list 100
+#define TARGET_NR_nanosleep 101
+#define TARGET_NR_getitimer 102
+#define TARGET_NR_setitimer 103
+#define TARGET_NR_kexec_load 104
+#define TARGET_NR_init_module 105
+#define TARGET_NR_delete_module 106
+#define TARGET_NR_timer_create 107
+#define TARGET_NR_timer_gettime 108
+#define TARGET_NR_timer_getoverrun 109
+#define TARGET_NR_timer_settime 110
+#define TARGET_NR_timer_delete 111
+#define TARGET_NR_clock_settime 112
+#define TARGET_NR_clock_gettime 113
+#define TARGET_NR_clock_getres 114
+#define TARGET_NR_clock_nanosleep 115
+#define TARGET_NR_syslog 116
+#define TARGET_NR_ptrace 117
+#define TARGET_NR_sched_setparam 118
+#define TARGET_NR_sched_setscheduler 119
+#define TARGET_NR_sched_getscheduler 120
+#define TARGET_NR_sched_getparam 121
+#define TARGET_NR_sched_setaffinity 122
+#define TARGET_NR_sched_getaffinity 123
+#define TARGET_NR_sched_yield 124
+#define TARGET_NR_sched_get_priority_max 125
+#define TARGET_NR_sched_get_priority_min 126
+#define TARGET_NR_sched_rr_get_interval 127
+#define TARGET_NR_restart_syscall 128
+#define TARGET_NR_kill 129
+#define TARGET_NR_tkill 130
+#define TARGET_NR_tgkill 131
+#define TARGET_NR_sigaltstack 132
+#define TARGET_NR_rt_sigsuspend 133
+#define TARGET_NR_rt_sigaction 134
+#define TARGET_NR_rt_sigprocmask 135
+#define TARGET_NR_rt_sigpending 136
+#define TARGET_NR_rt_sigtimedwait 137
+#define TARGET_NR_rt_sigqueueinfo 138
+#define TARGET_NR_rt_sigreturn 139
+#define TARGET_NR_setpriority 140
+#define TARGET_NR_getpriority 141
+#define TARGET_NR_reboot 142
+#define TARGET_NR_setregid 143
+#define TARGET_NR_setgid 144
+#define TARGET_NR_setreuid 145
+#define TARGET_NR_setuid 146
+#define TARGET_NR_setresuid 147
+#define TARGET_NR_getresuid 148
+#define TARGET_NR_setresgid 149
+#define TARGET_NR_getresgid 150
+#define TARGET_NR_setfsuid 151
+#define TARGET_NR_setfsgid 152
+#define TARGET_NR_times 153
+#define TARGET_NR_setpgid 154
+#define TARGET_NR_getpgid 155
+#define TARGET_NR_getsid 156
+#define TARGET_NR_setsid 157
+#define TARGET_NR_getgroups 158
+#define TARGET_NR_setgroups 159
+#define TARGET_NR_uname 160
+#define TARGET_NR_sethostname 161
+#define TARGET_NR_setdomainname 162
+#define TARGET_NR_getrlimit 163
+#define TARGET_NR_setrlimit 164
+#define TARGET_NR_getrusage 165
+#define TARGET_NR_umask 166
+#define TARGET_NR_prctl 167
+#define TARGET_NR_getcpu 168
+#define TARGET_NR_gettimeofday 169
+#define TARGET_NR_settimeofday 170
+#define TARGET_NR_adjtimex 171
+#define TARGET_NR_getpid 172
+#define TARGET_NR_getppid 173
+#define TARGET_NR_getuid 174
+#define TARGET_NR_geteuid 175
+#define TARGET_NR_getgid 176
+#define TARGET_NR_getegid 177
+#define TARGET_NR_gettid 178
+#define TARGET_NR_sysinfo 179
+#define TARGET_NR_mq_open 180
+#define TARGET_NR_mq_unlink 181
+#define TARGET_NR_mq_timedsend 182
+#define TARGET_NR_mq_timedreceive 183
+#define TARGET_NR_mq_notify 184
+#define TARGET_NR_mq_getsetattr 185
+#define TARGET_NR_msgget 186
+#define TARGET_NR_msgctl 187
+#define TARGET_NR_msgrcv 188
+#define TARGET_NR_msgsnd 189
+#define TARGET_NR_semget 190
+#define TARGET_NR_semctl 191
+#define TARGET_NR_semtimedop 192
+#define TARGET_NR_semop 193
+#define TARGET_NR_shmget 194
+#define TARGET_NR_shmctl 195
+#define TARGET_NR_shmat 196
+#define TARGET_NR_shmdt 197
+#define TARGET_NR_socket 198
+#define TARGET_NR_socketpair 199
+#define TARGET_NR_bind 200
+#define TARGET_NR_listen 201
+#define TARGET_NR_accept 202
+#define TARGET_NR_connect 203
+#define TARGET_NR_getsockname 204
+#define TARGET_NR_getpeername 205
+#define TARGET_NR_sendto 206
+#define TARGET_NR_recvfrom 207
+#define TARGET_NR_setsockopt 208
+#define TARGET_NR_getsockopt 209
+#define TARGET_NR_shutdown 210
+#define TARGET_NR_sendmsg 211
+#define TARGET_NR_recvmsg 212
+#define TARGET_NR_readahead 213
+#define TARGET_NR_brk 214
+#define TARGET_NR_munmap 215
+#define TARGET_NR_mremap 216
+#define TARGET_NR_add_key 217
+#define TARGET_NR_request_key 218
+#define TARGET_NR_keyctl 219
+#define TARGET_NR_clone 220
+#define TARGET_NR_execve 221
+#define TARGET_NR_mmap 222
+#define TARGET_NR_fadvise64 223
+#define TARGET_NR_swapon 224
+#define TARGET_NR_swapoff 225
+#define TARGET_NR_mprotect 226
+#define TARGET_NR_msync 227
+#define TARGET_NR_mlock 228
+#define TARGET_NR_munlock 229
+#define TARGET_NR_mlockall 230
+#define TARGET_NR_munlockall 231
+#define TARGET_NR_mincore 232
+#define TARGET_NR_madvise 233
+#define TARGET_NR_remap_file_pages 234
+#define TARGET_NR_mbind 235
+#define TARGET_NR_get_mempolicy 236
+#define TARGET_NR_set_mempolicy 237
+#define TARGET_NR_migrate_pages 238
+#define TARGET_NR_move_pages 239
+#define TARGET_NR_rt_tgsigqueueinfo 240
+#define TARGET_NR_perf_event_open 241
+#define TARGET_NR_accept4 242
+#define TARGET_NR_recvmmsg 243
+
+#define TARGET_NR_arch_specific_syscall 244
+#define TARGET_NR_cacheflush 245 /* tilegx own syscall */
+
+#define TARGET_NR_wait4 260
+#define TARGET_NR_prlimit64 261
+#define TARGET_NR_fanotify_init 262
+#define TARGET_NR_fanotify_mark 263
+#define TARGET_NR_name_to_handle_at 264
+#define TARGET_NR_open_by_handle_at 265
+#define TARGET_NR_clock_adjtime 266
+#define TARGET_NR_syncfs 267
+#define TARGET_NR_setns 268
+#define TARGET_NR_sendmmsg 269
+#define TARGET_NR_process_vm_readv 270
+#define TARGET_NR_process_vm_writev 271
+#define TARGET_NR_kcmp 272
+#define TARGET_NR_finit_module 273
+#define TARGET_NR_sched_setattr 274
+#define TARGET_NR_sched_getattr 275
+#define TARGET_NR_renameat2 276
+#define TARGET_NR_seccomp 277
+#define TARGET_NR_getrandom 278
+#define TARGET_NR_memfd_create 279
+#define TARGET_NR_bpf 280
+#define TARGET_NR_execveat 281
+#define TARGET_NR_userfaultfd 282
+#define TARGET_NR_membarrier 283
+#define TARGET_NR_mlock2 284
+#define TARGET_NR_copy_file_range 285
+
+#define TARGET_NR_open 1024
+#define TARGET_NR_link 1025
+#define TARGET_NR_unlink 1026
+#define TARGET_NR_mknod 1027
+#define TARGET_NR_chmod 1028
+#define TARGET_NR_chown 1029
+#define TARGET_NR_mkdir 1030
+#define TARGET_NR_rmdir 1031
+#define TARGET_NR_lchown 1032
+#define TARGET_NR_access 1033
+#define TARGET_NR_rename 1034
+#define TARGET_NR_readlink 1035
+#define TARGET_NR_symlink 1036
+#define TARGET_NR_utimes 1037
+#define TARGET_NR_stat64 1038 /* let syscall.c known */
+#define TARGET_NR_lstat 1039
+
+#define TARGET_NR_pipe 1040
+#define TARGET_NR_dup2 1041
+#define TARGET_NR_epoll_create 1042
+#define TARGET_NR_inotify_init 1043
+#define TARGET_NR_eventfd 1044
+#define TARGET_NR_signalfd 1045
+
+#define TARGET_NR_alarm 1059
+#define TARGET_NR_getpgrp 1060
+#define TARGET_NR_pause 1061
+#define TARGET_NR_time 1062
+#define TARGET_NR_utime 1063
+#define TARGET_NR_creat 1064
+#define TARGET_NR_getdents 1065
+#define TARGET_NR_futimesat 1066
+#define TARGET_NR_select 1067
+#define TARGET_NR_poll 1068
+#define TARGET_NR_epoll_wait 1069
+#define TARGET_NR_ustat 1070
+#define TARGET_NR_vfork 1071
+#define TARGET_NR_oldwait4 1072
+#define TARGET_NR_recv 1073
+#define TARGET_NR_send 1074
+#define TARGET_NR_bdflush 1075
+#define TARGET_NR_umount 1076
+#define TARGET_NR_uselib 1077
+#define TARGET_NR__sysctl 1078
+#define TARGET_NR_fork 1079
+
+#endif
diff --git a/qemu/linux-user/tilegx/target_cpu.h b/qemu/linux-user/tilegx/target_cpu.h
new file mode 100644
index 000000000..c96e81d05
--- /dev/null
+++ b/qemu/linux-user/tilegx/target_cpu.h
@@ -0,0 +1,35 @@
+/*
+ * TILE-Gx specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUTLGState *env, target_ulong newsp)
+{
+ if (newsp) {
+ env->regs[TILEGX_R_SP] = newsp;
+ }
+ env->regs[TILEGX_R_RE] = 0;
+}
+
+static inline void cpu_set_tls(CPUTLGState *env, target_ulong newtls)
+{
+ env->regs[TILEGX_R_TP] = newtls;
+}
+
+#endif
diff --git a/qemu/linux-user/tilegx/target_signal.h b/qemu/linux-user/tilegx/target_signal.h
new file mode 100644
index 000000000..b595f985c
--- /dev/null
+++ b/qemu/linux-user/tilegx/target_signal.h
@@ -0,0 +1,28 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
+} target_stack_t;
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK 1
+#define TARGET_SS_DISABLE 2
+
+#define TARGET_MINSIGSTKSZ 2048
+#define TARGET_SIGSTKSZ 8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUTLGState *state)
+{
+ return state->regs[TILEGX_R_SP];
+}
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/qemu/linux-user/tilegx/target_structs.h b/qemu/linux-user/tilegx/target_structs.h
new file mode 100644
index 000000000..7d3ff782f
--- /dev/null
+++ b/qemu/linux-user/tilegx/target_structs.h
@@ -0,0 +1,46 @@
+/*
+ * TILE-Gx specific structures for linux-user
+ *
+ * Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+ abi_int __key; /* Key. */
+ abi_uint uid; /* Owner's user ID. */
+ abi_uint gid; /* Owner's group ID. */
+ abi_uint cuid; /* Creator's user ID. */
+ abi_uint cgid; /* Creator's group ID. */
+ abi_uint mode; /* Read/write permission. */
+ abi_ushort __seq; /* Sequence number. */
+};
+
+struct target_shmid_ds {
+ struct target_ipc_perm shm_perm; /* operation permission struct */
+ abi_long shm_segsz; /* size of segment in bytes */
+ abi_ulong shm_atime; /* time of last shmat() */
+ abi_ulong shm_dtime; /* time of last shmdt() */
+ abi_ulong shm_ctime; /* time of last change by shmctl() */
+ abi_int shm_cpid; /* pid of creator */
+ abi_int shm_lpid; /* pid of last shmop */
+ abi_ushort shm_nattch; /* number of current attaches */
+ abi_ushort shm_unused; /* compatibility */
+ abi_ulong __unused4;
+ abi_ulong __unused5;
+};
+
+#endif
diff --git a/qemu/linux-user/tilegx/target_syscall.h b/qemu/linux-user/tilegx/target_syscall.h
new file mode 100644
index 000000000..a938d4e90
--- /dev/null
+++ b/qemu/linux-user/tilegx/target_syscall.h
@@ -0,0 +1,43 @@
+#ifndef TILEGX_SYSCALLS_H
+#define TILEGX_SYSCALLS_H
+
+#define UNAME_MACHINE "tilegx"
+#define UNAME_MINIMUM_RELEASE "3.19"
+
+#define MMAP_SHIFT TARGET_PAGE_BITS
+
+#define TILEGX_IS_ERRNO(ret) \
+ ((ret) > 0xfffffffffffff000ULL) /* errno is 0 -- 4096 */
+
+typedef uint64_t tilegx_reg_t;
+
+struct target_pt_regs {
+
+ union {
+ /* Saved main processor registers; 56..63 are special. */
+ tilegx_reg_t regs[56];
+ struct {
+ tilegx_reg_t __regs[53];
+ tilegx_reg_t tp; /* aliases regs[TREG_TP] */
+ tilegx_reg_t sp; /* aliases regs[TREG_SP] */
+ tilegx_reg_t lr; /* aliases regs[TREG_LR] */
+ };
+ };
+
+ /* Saved special registers. */
+ tilegx_reg_t pc; /* stored in EX_CONTEXT_K_0 */
+ tilegx_reg_t ex1; /* stored in EX_CONTEXT_K_1 (PL and ICS bit) */
+ tilegx_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */
+ tilegx_reg_t orig_r0; /* r0 at syscall entry, else zero */
+ tilegx_reg_t flags; /* flags (see below) */
+ tilegx_reg_t cmpexch; /* value of CMPEXCH_VALUE SPR at interrupt */
+ tilegx_reg_t pad[2];
+};
+
+#define TARGET_MLOCKALL_MCL_CURRENT 1
+#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+/* For faultnum */
+#define TARGET_INT_SWINT_1 14
+
+#endif
diff --git a/qemu/linux-user/tilegx/termbits.h b/qemu/linux-user/tilegx/termbits.h
new file mode 100644
index 000000000..91ec23654
--- /dev/null
+++ b/qemu/linux-user/tilegx/termbits.h
@@ -0,0 +1,274 @@
+#ifndef TILEGX_TERMBITS_H
+#define TILEGX_TERMBITS_H
+
+/* From asm-generic/termbits.h, which is used by tilegx */
+
+#define TARGET_NCCS 19
+struct target_termios {
+ unsigned int c_iflag; /* input mode flags */
+ unsigned int c_oflag; /* output mode flags */
+ unsigned int c_cflag; /* control mode flags */
+ unsigned int c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[TARGET_NCCS]; /* control characters */
+};
+
+struct target_termios2 {
+ unsigned int c_iflag; /* input mode flags */
+ unsigned int c_oflag; /* output mode flags */
+ unsigned int c_cflag; /* control mode flags */
+ unsigned int c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[TARGET_NCCS]; /* control characters */
+ unsigned int c_ispeed; /* input speed */
+ unsigned int c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+#define TARGET_VINTR 0
+#define TARGET_VQUIT 1
+#define TARGET_VERASE 2
+#define TARGET_VKILL 3
+#define TARGET_VEOF 4
+#define TARGET_VTIME 5
+#define TARGET_VMIN 6
+#define TARGET_VSWTC 7
+#define TARGET_VSTART 8
+#define TARGET_VSTOP 9
+#define TARGET_VSUSP 10
+#define TARGET_VEOL 11
+#define TARGET_VREPRINT 12
+#define TARGET_VDISCARD 13
+#define TARGET_VWERASE 14
+#define TARGET_VLNEXT 15
+#define TARGET_VEOL2 16
+
+/* c_iflag bits */
+#define TARGET_IGNBRK 0000001
+#define TARGET_BRKINT 0000002
+#define TARGET_IGNPAR 0000004
+#define TARGET_PARMRK 0000010
+#define TARGET_INPCK 0000020
+#define TARGET_ISTRIP 0000040
+#define TARGET_INLCR 0000100
+#define TARGET_IGNCR 0000200
+#define TARGET_ICRNL 0000400
+#define TARGET_IUCLC 0001000
+#define TARGET_IXON 0002000
+#define TARGET_IXANY 0004000
+#define TARGET_IXOFF 0010000
+#define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8 0040000
+
+/* c_oflag bits */
+#define TARGET_OPOST 0000001
+#define TARGET_OLCUC 0000002
+#define TARGET_ONLCR 0000004
+#define TARGET_OCRNL 0000010
+#define TARGET_ONOCR 0000020
+#define TARGET_ONLRET 0000040
+#define TARGET_OFILL 0000100
+#define TARGET_OFDEL 0000200
+#define TARGET_NLDLY 0000400
+#define TARGET_NL0 0000000
+#define TARGET_NL1 0000400
+#define TARGET_CRDLY 0003000
+#define TARGET_CR0 0000000
+#define TARGET_CR1 0001000
+#define TARGET_CR2 0002000
+#define TARGET_CR3 0003000
+#define TARGET_TABDLY 0014000
+#define TARGET_TAB0 0000000
+#define TARGET_TAB1 0004000
+#define TARGET_TAB2 0010000
+#define TARGET_TAB3 0014000
+#define TARGET_XTABS 0014000
+#define TARGET_BSDLY 0020000
+#define TARGET_BS0 0000000
+#define TARGET_BS1 0020000
+#define TARGET_VTDLY 0040000
+#define TARGET_VT0 0000000
+#define TARGET_VT1 0040000
+#define TARGET_FFDLY 0100000
+#define TARGET_FF0 0000000
+#define TARGET_FF1 0100000
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD 0010017
+#define TARGET_B0 0000000 /* hang up */
+#define TARGET_B50 0000001
+#define TARGET_B75 0000002
+#define TARGET_B110 0000003
+#define TARGET_B134 0000004
+#define TARGET_B150 0000005
+#define TARGET_B200 0000006
+#define TARGET_B300 0000007
+#define TARGET_B600 0000010
+#define TARGET_B1200 0000011
+#define TARGET_B1800 0000012
+#define TARGET_B2400 0000013
+#define TARGET_B4800 0000014
+#define TARGET_B9600 0000015
+#define TARGET_B19200 0000016
+#define TARGET_B38400 0000017
+#define TARGET_EXTA TARGET_B19200
+#define TARGET_EXTB TARGET_B38400
+#define TARGET_CSIZE 0000060
+#define TARGET_CS5 0000000
+#define TARGET_CS6 0000020
+#define TARGET_CS7 0000040
+#define TARGET_CS8 0000060
+#define TARGET_CSTOPB 0000100
+#define TARGET_CREAD 0000200
+#define TARGET_PARENB 0000400
+#define TARGET_PARODD 0001000
+#define TARGET_HUPCL 0002000
+#define TARGET_CLOCAL 0004000
+#define TARGET_CBAUDEX 0010000
+#define TARGET_BOTHER 0010000
+#define TARGET_B57600 0010001
+#define TARGET_B115200 0010002
+#define TARGET_B230400 0010003
+#define TARGET_B460800 0010004
+#define TARGET_B500000 0010005
+#define TARGET_B576000 0010006
+#define TARGET_B921600 0010007
+#define TARGET_B1000000 0010010
+#define TARGET_B1152000 0010011
+#define TARGET_B1500000 0010012
+#define TARGET_B2000000 0010013
+#define TARGET_B2500000 0010014
+#define TARGET_B3000000 0010015
+#define TARGET_B3500000 0010016
+#define TARGET_B4000000 0010017
+#define TARGET_CIBAUD 002003600000 /* input baud rate */
+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
+#define TARGET_CRTSCTS 020000000000 /* flow control */
+
+#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
+/* c_lflag bits */
+#define TARGET_ISIG 0000001
+#define TARGET_ICANON 0000002
+#define TARGET_XCASE 0000004
+#define TARGET_ECHO 0000010
+#define TARGET_ECHOE 0000020
+#define TARGET_ECHOK 0000040
+#define TARGET_ECHONL 0000100
+#define TARGET_NOFLSH 0000200
+#define TARGET_TOSTOP 0000400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE 0004000
+#define TARGET_FLUSHO 0010000
+#define TARGET_PENDIN 0040000
+#define TARGET_IEXTEN 0100000
+#define TARGET_EXTPROC 0200000
+
+/* tcflow() and TCXONC use these */
+#define TARGET_TCOOFF 0
+#define TARGET_TCOON 1
+#define TARGET_TCIOFF 2
+#define TARGET_TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TARGET_TCIFLUSH 0
+#define TARGET_TCOFLUSH 1
+#define TARGET_TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TARGET_TCSANOW 0
+#define TARGET_TCSADRAIN 1
+#define TARGET_TCSAFLUSH 2
+
+/* From asm-generic/ioctls.h, which is used by tilegx */
+
+#define TARGET_TCGETS 0x5401
+#define TARGET_TCSETS 0x5402
+#define TARGET_TCSETSW 0x5403
+#define TARGET_TCSETSF 0x5404
+#define TARGET_TCGETA 0x5405
+#define TARGET_TCSETA 0x5406
+#define TARGET_TCSETAW 0x5407
+#define TARGET_TCSETAF 0x5408
+#define TARGET_TCSBRK 0x5409
+#define TARGET_TCXONC 0x540A
+#define TARGET_TCFLSH 0x540B
+#define TARGET_TIOCEXCL 0x540C
+#define TARGET_TIOCNXCL 0x540D
+#define TARGET_TIOCSCTTY 0x540E
+#define TARGET_TIOCGPGRP 0x540F
+#define TARGET_TIOCSPGRP 0x5410
+#define TARGET_TIOCOUTQ 0x5411
+#define TARGET_TIOCSTI 0x5412
+#define TARGET_TIOCGWINSZ 0x5413
+#define TARGET_TIOCSWINSZ 0x5414
+#define TARGET_TIOCMGET 0x5415
+#define TARGET_TIOCMBIS 0x5416
+#define TARGET_TIOCMBIC 0x5417
+#define TARGET_TIOCMSET 0x5418
+#define TARGET_TIOCGSOFTCAR 0x5419
+#define TARGET_TIOCSSOFTCAR 0x541A
+#define TARGET_FIONREAD 0x541B
+#define TARGET_TIOCINQ TARGET_FIONREAD
+#define TARGET_TIOCLINUX 0x541C
+#define TARGET_TIOCCONS 0x541D
+#define TARGET_TIOCGSERIAL 0x541E
+#define TARGET_TIOCSSERIAL 0x541F
+#define TARGET_TIOCPKT 0x5420
+#define TARGET_FIONBIO 0x5421
+#define TARGET_TIOCNOTTY 0x5422
+#define TARGET_TIOCSETD 0x5423
+#define TARGET_TIOCGETD 0x5424
+#define TARGET_TCSBRKP 0x5425
+#define TARGET_TIOCSBRK 0x5427
+#define TARGET_TIOCCBRK 0x5428
+#define TARGET_TIOCGSID 0x5429
+#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct termios2)
+#define TARGET_TIOCGRS485 0x542E
+#define TARGET_TIOCSRS485 0x542F
+#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int)
+#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int)
+#define TARGET_TIOCGDEV TARGET_IOR('T', 0x32, unsigned int)
+#define TARGET_TCGETX 0x5432
+#define TARGET_TCSETX 0x5433
+#define TARGET_TCSETXF 0x5434
+#define TARGET_TCSETXW 0x5435
+#define TARGET_TIOCSIG TARGET_IOW('T', 0x36, int)
+#define TARGET_TIOCVHANGUP 0x5437
+#define TARGET_TIOCGPKT TARGET_IOR('T', 0x38, int)
+#define TARGET_TIOCGPTLCK TARGET_IOR('T', 0x39, int)
+#define TARGET_TIOCGEXCL TARGET_IOR('T', 0x40, int)
+
+#define TARGET_FIONCLEX 0x5450
+#define TARGET_FIOCLEX 0x5451
+#define TARGET_FIOASYNC 0x5452
+#define TARGET_TIOCSERCONFIG 0x5453
+#define TARGET_TIOCSERGWILD 0x5454
+#define TARGET_TIOCSERSWILD 0x5455
+#define TARGET_TIOCGLCKTRMIOS 0x5456
+#define TARGET_TIOCSLCKTRMIOS 0x5457
+#define TARGET_TIOCSERGSTRUCT 0x5458
+#define TARGET_TIOCSERGETLSR 0x5459
+#define TARGET_TIOCSERGETMULTI 0x545A
+#define TARGET_TIOCSERSETMULTI 0x545B
+
+#define TARGET_TIOCMIWAIT 0x545C
+#define TARGET_TIOCGICOUNT 0x545D
+#define TARGET_FIOQSIZE 0x5460
+
+#define TARGET_TIOCPKT_DATA 0
+#define TARGET_TIOCPKT_FLUSHREAD 1
+#define TARGET_TIOCPKT_FLUSHWRITE 2
+#define TARGET_TIOCPKT_STOP 4
+#define TARGET_TIOCPKT_START 8
+#define TARGET_TIOCPKT_NOSTOP 16
+#define TARGET_TIOCPKT_DOSTOP 32
+#define TARGET_TIOCPKT_IOCTL 64
+
+#define TARGET_TIOCSER_TEMT 0x01
+
+#endif
diff --git a/qemu/linux-user/uaccess.c b/qemu/linux-user/uaccess.c
index a4d108c2f..0a5c0b0b2 100644
--- a/qemu/linux-user/uaccess.c
+++ b/qemu/linux-user/uaccess.c
@@ -1,6 +1,6 @@
/* User memory access */
-#include <stdio.h>
-#include <string.h>
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "qemu.h"
diff --git a/qemu/linux-user/uname.c b/qemu/linux-user/uname.c
index 1e6560d72..313b79dba 100644
--- a/qemu/linux-user/uname.c
+++ b/qemu/linux-user/uname.c
@@ -17,7 +17,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
+#include "qemu/osdep.h"
#include "qemu.h"
//#include "qemu-common.h"
diff --git a/qemu/linux-user/unicore32/target_signal.h b/qemu/linux-user/unicore32/target_signal.h
index 8b255c455..7c442381a 100644
--- a/qemu/linux-user/unicore32/target_signal.h
+++ b/qemu/linux-user/unicore32/target_signal.h
@@ -21,6 +21,10 @@ typedef struct target_sigaltstack {
#define TARGET_SS_ONSTACK 1
#define TARGET_SS_DISABLE 2
-#define get_sp_from_cpustate(cpustate) (cpustate->regs[29])
+static inline abi_ulong get_sp_from_cpustate(CPUUniCore32State *state)
+{
+ return state->regs[29];
+}
+
#endif /* TARGET_SIGNAL_H */
diff --git a/qemu/linux-user/unicore32/syscall.h b/qemu/linux-user/unicore32/target_syscall.h
index 385a97562..385a97562 100644
--- a/qemu/linux-user/unicore32/syscall.h
+++ b/qemu/linux-user/unicore32/target_syscall.h
diff --git a/qemu/linux-user/vm86.c b/qemu/linux-user/vm86.c
index 22a4eb962..3829b9a67 100644
--- a/qemu/linux-user/vm86.c
+++ b/qemu/linux-user/vm86.c
@@ -16,12 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
+#include "qemu/osdep.h"
#include "qemu.h"
diff --git a/qemu/linux-user/x86_64/syscall_nr.h b/qemu/linux-user/x86_64/syscall_nr.h
index 7c59e3a09..16397b3e8 100644
--- a/qemu/linux-user/x86_64/syscall_nr.h
+++ b/qemu/linux-user/x86_64/syscall_nr.h
@@ -281,7 +281,7 @@
#define TARGET_NR_utimensat 280
#define TARGET_NR_epoll_pwait 281
#define TARGET_NR_signalfd 282
-#define TARGET_NR_timerfd 283
+#define TARGET_NR_timerfd_create 283
#define TARGET_NR_eventfd 284
#define TARGET_NR_fallocate 285
#define TARGET_NR_timerfd_settime 286
@@ -312,3 +312,16 @@
#define TARGET_NR_process_vm_writev 311
#define TARGET_NR_kcmp 312
#define TARGET_NR_finit_module 313
+#define TARGET_NR_sched_setattr 314
+#define TARGET_NR_sched_getattr 315
+#define TARGET_NR_renameat2 316
+#define TARGET_NR_seccomp 317
+#define TARGET_NR_getrandom 318
+#define TARGET_NR_memfd_create 319
+#define TARGET_NR_kexec_file_load 320
+#define TARGET_NR_bpf 321
+#define TARGET_NR_execveat 322
+#define TARGET_NR_userfaultfd 323
+#define TARGET_NR_membarrier 324
+#define TARGET_NR_mlock2 325
+#define TARGET_NR_copy_file_range 326
diff --git a/qemu/linux-user/x86_64/syscall.h b/qemu/linux-user/x86_64/target_syscall.h
index 88b3c3fe3..feecd32d5 100644
--- a/qemu/linux-user/x86_64/syscall.h
+++ b/qemu/linux-user/x86_64/target_syscall.h
@@ -1,3 +1,6 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
#define __USER_CS (0x33)
#define __USER_DS (0x2B)
@@ -100,3 +103,5 @@ struct target_msqid64_ds {
#define TARGET_MINSIGSTKSZ 2048
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+
+#endif /* TARGET_SYSCALL_H */