Hi, The patch looks OK, but I'd like to have a try with some s390x static binaries. Such binaries are also useful for me to test that new patches for linxu-user don't break targets I don't usually use.
Riku On Fri, Apr 15, 2011 at 05:32:43PM +0200, Alexander Graf wrote: > From: Ulrich Hecht <u...@suse.de> > > This patch adds support for running s390x binaries in the linux-user emulation > code. > > Signed-off-by: Ulrich Hecht <u...@suse.de> > Signed-off-by: Alexander Graf <ag...@suse.de> > > --- > > v1 -> v2: > > - always set 64bit flag for s390x binaries in elf loader > - remove redundant EXECUTE_SVC > - advance psw.addr in syscall execution path > > v3 -> v4: > > - fix 32bit hosts > - fix coding style (except for header files shared with Linux) > --- > linux-user/elfload.c | 19 ++ > linux-user/main.c | 83 +++++++++ > linux-user/s390x/syscall.h | 23 +++ > linux-user/s390x/syscall_nr.h | 349 > ++++++++++++++++++++++++++++++++++++++ > linux-user/s390x/target_signal.h | 26 +++ > linux-user/s390x/termbits.h | 283 ++++++++++++++++++++++++++++++ > linux-user/signal.c | 333 ++++++++++++++++++++++++++++++++++++ > linux-user/syscall.c | 16 ++- > linux-user/syscall_defs.h | 55 ++++++- > scripts/qemu-binfmt-conf.sh | 4 +- > 10 files changed, 1184 insertions(+), 7 deletions(-) > create mode 100644 linux-user/s390x/syscall.h > create mode 100644 linux-user/s390x/syscall_nr.h > create mode 100644 linux-user/s390x/target_signal.h > create mode 100644 linux-user/s390x/termbits.h > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index 4c399f8..dcfeb7a 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -867,6 +867,25 @@ static inline void init_thread(struct target_pt_regs > *regs, > > #endif /* TARGET_ALPHA */ > > +#ifdef TARGET_S390X > + > +#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 > + > +static inline void init_thread(struct target_pt_regs *regs, struct > image_info *infop) > +{ > + regs->psw.addr = infop->entry; > + regs->psw.mask = PSW_MASK_64 | PSW_MASK_32; > + regs->gprs[15] = infop->start_stack; > +} > + > +#endif /* TARGET_S390X */ > + > #ifndef ELF_PLATFORM > #define ELF_PLATFORM (NULL) > #endif > diff --git a/linux-user/main.c b/linux-user/main.c > index a1e37e4..82aaf9d 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -2701,6 +2701,80 @@ void cpu_loop (CPUState *env) > } > #endif /* TARGET_ALPHA */ > > +#ifdef TARGET_S390X > +void cpu_loop(CPUS390XState *env) > +{ > + int trapnr; > + target_siginfo_t info; > + > + while (1) { > + trapnr = cpu_s390x_exec (env); > + > + switch (trapnr) { > + case EXCP_INTERRUPT: > + /* just indicate that signals should be handled asap */ > + break; > + case EXCP_DEBUG: > + { > + int sig; > + > + sig = gdb_handlesig (env, TARGET_SIGTRAP); > + if (sig) { > + info.si_signo = sig; > + info.si_errno = 0; > + info.si_code = TARGET_TRAP_BRKPT; > + queue_signal(env, info.si_signo, &info); > + } > + } > + break; > + case EXCP_SVC: > + { > + int n = env->int_svc_code; > + if (!n) { > + /* syscalls > 255 */ > + n = env->regs[1]; > + } > + env->psw.addr += env->int_svc_ilc; > + env->regs[2] = do_syscall(env, n, > + env->regs[2], > + env->regs[3], > + env->regs[4], > + env->regs[5], > + env->regs[6], > + env->regs[7]); > + } > + break; > + case EXCP_ADDR: > + { > + info.si_signo = SIGSEGV; > + info.si_errno = 0; > + /* XXX: check env->error_code */ > + info.si_code = TARGET_SEGV_MAPERR; > + info._sifields._sigfault._addr = env->__excp_addr; > + queue_signal(env, info.si_signo, &info); > + } > + break; > + case EXCP_SPEC: > + { > + fprintf(stderr,"specification exception insn 0x%08x%04x\n", > ldl(env->psw.addr), lduw(env->psw.addr + 4)); > + info.si_signo = SIGILL; > + info.si_errno = 0; > + info.si_code = TARGET_ILL_ILLOPC; > + info._sifields._sigfault._addr = env->__excp_addr; > + queue_signal(env, info.si_signo, &info); > + } > + break; > + default: > + printf ("Unhandled trap: 0x%x\n", trapnr); > + cpu_dump_state(env, stderr, fprintf, 0); > + exit (1); > + } > + process_pending_signals (env); > + } > +} > + > +#endif /* TARGET_S390X */ > + > static void version(void) > { > printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION > @@ -3450,6 +3524,15 @@ int main(int argc, char **argv, char **envp) > env->regs[15] = regs->acr; > env->pc = regs->erp; > } > +#elif defined(TARGET_S390X) > + { > + int i; > + for (i = 0; i < 16; i++) { > + env->regs[i] = regs->gprs[i]; > + } > + env->psw.mask = regs->psw.mask; > + env->psw.addr = regs->psw.addr; > + } > #else > #error unsupported target CPU > #endif > diff --git a/linux-user/s390x/syscall.h b/linux-user/s390x/syscall.h > new file mode 100644 > index 0000000..c2ea151 > --- /dev/null > +++ b/linux-user/s390x/syscall.h > @@ -0,0 +1,23 @@ > +/* this typedef defines how a Program Status Word looks like */ > +typedef struct { > + abi_ulong mask; > + abi_ulong addr; > +} __attribute__ ((aligned(8))) target_psw_t; > + > +/* > + * The pt_regs struct defines the way the registers are stored on > + * the stack during a system call. > + */ > + > +#define TARGET_NUM_GPRS 16 > + > +struct target_pt_regs { > + abi_ulong args[1]; > + target_psw_t psw; > + abi_ulong gprs[TARGET_NUM_GPRS]; > + abi_ulong orig_gpr2; > + unsigned short ilc; > + unsigned short trap; > +}; > + > +#define UNAME_MACHINE "s390x" > diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h > new file mode 100644 > index 0000000..7cc6db2 > --- /dev/null > +++ b/linux-user/s390x/syscall_nr.h > @@ -0,0 +1,349 @@ > +/* > + * This file contains the system call numbers. > + */ > + > +#define TARGET_NR_exit 1 > +#define TARGET_NR_fork 2 > +#define TARGET_NR_read 3 > +#define TARGET_NR_write 4 > +#define TARGET_NR_open 5 > +#define TARGET_NR_close 6 > +#define TARGET_NR_restart_syscall 7 > +#define TARGET_NR_creat 8 > +#define TARGET_NR_link 9 > +#define TARGET_NR_unlink 10 > +#define TARGET_NR_execve 11 > +#define TARGET_NR_chdir 12 > +#define TARGET_NR_mknod 14 > +#define TARGET_NR_chmod 15 > +#define TARGET_NR_lseek 19 > +#define TARGET_NR_getpid 20 > +#define TARGET_NR_mount 21 > +#define TARGET_NR_umount 22 > +#define TARGET_NR_ptrace 26 > +#define TARGET_NR_alarm 27 > +#define TARGET_NR_pause 29 > +#define TARGET_NR_utime 30 > +#define TARGET_NR_access 33 > +#define TARGET_NR_nice 34 > +#define TARGET_NR_sync 36 > +#define TARGET_NR_kill 37 > +#define TARGET_NR_rename 38 > +#define TARGET_NR_mkdir 39 > +#define TARGET_NR_rmdir 40 > +#define TARGET_NR_dup 41 > +#define TARGET_NR_pipe 42 > +#define TARGET_NR_times 43 > +#define TARGET_NR_brk 45 > +#define TARGET_NR_signal 48 > +#define TARGET_NR_acct 51 > +#define TARGET_NR_umount2 52 > +#define TARGET_NR_ioctl 54 > +#define TARGET_NR_fcntl 55 > +#define TARGET_NR_setpgid 57 > +#define TARGET_NR_umask 60 > +#define TARGET_NR_chroot 61 > +#define TARGET_NR_ustat 62 > +#define TARGET_NR_dup2 63 > +#define TARGET_NR_getppid 64 > +#define TARGET_NR_getpgrp 65 > +#define TARGET_NR_setsid 66 > +#define TARGET_NR_sigaction 67 > +#define TARGET_NR_sigsuspend 72 > +#define TARGET_NR_sigpending 73 > +#define TARGET_NR_sethostname 74 > +#define TARGET_NR_setrlimit 75 > +#define TARGET_NR_getrusage 77 > +#define TARGET_NR_gettimeofday 78 > +#define TARGET_NR_settimeofday 79 > +#define TARGET_NR_symlink 83 > +#define TARGET_NR_readlink 85 > +#define TARGET_NR_uselib 86 > +#define TARGET_NR_swapon 87 > +#define TARGET_NR_reboot 88 > +#define TARGET_NR_readdir 89 > +#define TARGET_NR_mmap 90 > +#define TARGET_NR_munmap 91 > +#define TARGET_NR_truncate 92 > +#define TARGET_NR_ftruncate 93 > +#define TARGET_NR_fchmod 94 > +#define TARGET_NR_getpriority 96 > +#define TARGET_NR_setpriority 97 > +#define TARGET_NR_statfs 99 > +#define TARGET_NR_fstatfs 100 > +#define TARGET_NR_socketcall 102 > +#define TARGET_NR_syslog 103 > +#define TARGET_NR_setitimer 104 > +#define TARGET_NR_getitimer 105 > +#define TARGET_NR_stat 106 > +#define TARGET_NR_lstat 107 > +#define TARGET_NR_fstat 108 > +#define TARGET_NR_lookup_dcookie 110 > +#define TARGET_NR_vhangup 111 > +#define TARGET_NR_idle 112 > +#define TARGET_NR_wait4 114 > +#define TARGET_NR_swapoff 115 > +#define TARGET_NR_sysinfo 116 > +#define TARGET_NR_ipc 117 > +#define TARGET_NR_fsync 118 > +#define TARGET_NR_sigreturn 119 > +#define TARGET_NR_clone 120 > +#define TARGET_NR_setdomainname 121 > +#define TARGET_NR_uname 122 > +#define TARGET_NR_adjtimex 124 > +#define TARGET_NR_mprotect 125 > +#define TARGET_NR_sigprocmask 126 > +#define TARGET_NR_create_module 127 > +#define TARGET_NR_init_module 128 > +#define TARGET_NR_delete_module 129 > +#define TARGET_NR_get_kernel_syms 130 > +#define TARGET_NR_quotactl 131 > +#define TARGET_NR_getpgid 132 > +#define TARGET_NR_fchdir 133 > +#define TARGET_NR_bdflush 134 > +#define TARGET_NR_sysfs 135 > +#define TARGET_NR_personality 136 > +#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ > +#define TARGET_NR_getdents 141 > +#define TARGET_NR_flock 143 > +#define TARGET_NR_msync 144 > +#define TARGET_NR_readv 145 > +#define TARGET_NR_writev 146 > +#define TARGET_NR_getsid 147 > +#define TARGET_NR_fdatasync 148 > +#define TARGET_NR__sysctl 149 > +#define TARGET_NR_mlock 150 > +#define TARGET_NR_munlock 151 > +#define TARGET_NR_mlockall 152 > +#define TARGET_NR_munlockall 153 > +#define TARGET_NR_sched_setparam 154 > +#define TARGET_NR_sched_getparam 155 > +#define TARGET_NR_sched_setscheduler 156 > +#define TARGET_NR_sched_getscheduler 157 > +#define TARGET_NR_sched_yield 158 > +#define TARGET_NR_sched_get_priority_max 159 > +#define TARGET_NR_sched_get_priority_min 160 > +#define TARGET_NR_sched_rr_get_interval 161 > +#define TARGET_NR_nanosleep 162 > +#define TARGET_NR_mremap 163 > +#define TARGET_NR_query_module 167 > +#define TARGET_NR_poll 168 > +#define TARGET_NR_nfsservctl 169 > +#define TARGET_NR_prctl 172 > +#define TARGET_NR_rt_sigreturn 173 > +#define TARGET_NR_rt_sigaction 174 > +#define TARGET_NR_rt_sigprocmask 175 > +#define TARGET_NR_rt_sigpending 176 > +#define TARGET_NR_rt_sigtimedwait 177 > +#define TARGET_NR_rt_sigqueueinfo 178 > +#define TARGET_NR_rt_sigsuspend 179 > +#define TARGET_NR_pread64 180 > +#define TARGET_NR_pwrite64 181 > +#define TARGET_NR_getcwd 183 > +#define TARGET_NR_capget 184 > +#define TARGET_NR_capset 185 > +#define TARGET_NR_sigaltstack 186 > +#define TARGET_NR_sendfile 187 > +#define TARGET_NR_getpmsg 188 > +#define TARGET_NR_putpmsg 189 > +#define TARGET_NR_vfork 190 > +#define TARGET_NR_pivot_root 217 > +#define TARGET_NR_mincore 218 > +#define TARGET_NR_madvise 219 > +#define TARGET_NR_getdents64 220 > +#define TARGET_NR_readahead 222 > +#define TARGET_NR_setxattr 224 > +#define TARGET_NR_lsetxattr 225 > +#define TARGET_NR_fsetxattr 226 > +#define TARGET_NR_getxattr 227 > +#define TARGET_NR_lgetxattr 228 > +#define TARGET_NR_fgetxattr 229 > +#define TARGET_NR_listxattr 230 > +#define TARGET_NR_llistxattr 231 > +#define TARGET_NR_flistxattr 232 > +#define TARGET_NR_removexattr 233 > +#define TARGET_NR_lremovexattr 234 > +#define TARGET_NR_fremovexattr 235 > +#define TARGET_NR_gettid 236 > +#define TARGET_NR_tkill 237 > +#define TARGET_NR_futex 238 > +#define TARGET_NR_sched_setaffinity 239 > +#define TARGET_NR_sched_getaffinity 240 > +#define TARGET_NR_tgkill 241 > +/* Number 242 is reserved for tux */ > +#define TARGET_NR_io_setup 243 > +#define TARGET_NR_io_destroy 244 > +#define TARGET_NR_io_getevents 245 > +#define TARGET_NR_io_submit 246 > +#define TARGET_NR_io_cancel 247 > +#define TARGET_NR_exit_group 248 > +#define TARGET_NR_epoll_create 249 > +#define TARGET_NR_epoll_ctl 250 > +#define TARGET_NR_epoll_wait 251 > +#define TARGET_NR_set_tid_address 252 > +#define TARGET_NR_fadvise64 253 > +#define TARGET_NR_timer_create 254 > +#define TARGET_NR_timer_settime (TARGET_NR_timer_create+1) > +#define TARGET_NR_timer_gettime (TARGET_NR_timer_create+2) > +#define TARGET_NR_timer_getoverrun (TARGET_NR_timer_create+3) > +#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4) > +#define TARGET_NR_clock_settime (TARGET_NR_timer_create+5) > +#define TARGET_NR_clock_gettime (TARGET_NR_timer_create+6) > +#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7) > +#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) > +/* Number 263 is reserved for vserver */ > +#define TARGET_NR_statfs64 265 > +#define TARGET_NR_fstatfs64 266 > +#define TARGET_NR_remap_file_pages 267 > +/* Number 268 is reserved for new sys_mbind */ > +/* Number 269 is reserved for new sys_get_mempolicy */ > +/* Number 270 is reserved for new sys_set_mempolicy */ > +#define TARGET_NR_mq_open 271 > +#define TARGET_NR_mq_unlink 272 > +#define TARGET_NR_mq_timedsend 273 > +#define TARGET_NR_mq_timedreceive 274 > +#define TARGET_NR_mq_notify 275 > +#define TARGET_NR_mq_getsetattr 276 > +#define TARGET_NR_kexec_load 277 > +#define TARGET_NR_add_key 278 > +#define TARGET_NR_request_key 279 > +#define TARGET_NR_keyctl 280 > +#define TARGET_NR_waitid 281 > +#define TARGET_NR_ioprio_set 282 > +#define TARGET_NR_ioprio_get 283 > +#define TARGET_NR_inotify_init 284 > +#define TARGET_NR_inotify_add_watch 285 > +#define TARGET_NR_inotify_rm_watch 286 > +/* Number 287 is reserved for new sys_migrate_pages */ > +#define TARGET_NR_openat 288 > +#define TARGET_NR_mkdirat 289 > +#define TARGET_NR_mknodat 290 > +#define TARGET_NR_fchownat 291 > +#define TARGET_NR_futimesat 292 > +#define TARGET_NR_unlinkat 294 > +#define TARGET_NR_renameat 295 > +#define TARGET_NR_linkat 296 > +#define TARGET_NR_symlinkat 297 > +#define TARGET_NR_readlinkat 298 > +#define TARGET_NR_fchmodat 299 > +#define TARGET_NR_faccessat 300 > +#define TARGET_NR_pselect6 301 > +#define TARGET_NR_ppoll 302 > +#define TARGET_NR_unshare 303 > +#define TARGET_NR_set_robust_list 304 > +#define TARGET_NR_get_robust_list 305 > +#define TARGET_NR_splice 306 > +#define TARGET_NR_sync_file_range 307 > +#define TARGET_NR_tee 308 > +#define TARGET_NR_vmsplice 309 > +/* Number 310 is reserved for new sys_move_pages */ > +#define TARGET_NR_getcpu 311 > +#define TARGET_NR_epoll_pwait 312 > +#define TARGET_NR_utimes 313 > +#define TARGET_NR_fallocate 314 > +#define TARGET_NR_utimensat 315 > +#define TARGET_NR_signalfd 316 > +#define TARGET_NR_timerfd 317 > +#define TARGET_NR_eventfd 318 > +#define TARGET_NR_timerfd_create 319 > +#define TARGET_NR_timerfd_settime 320 > +#define TARGET_NR_timerfd_gettime 321 > +#define TARGET_NR_signalfd4 322 > +#define TARGET_NR_eventfd2 323 > +#define TARGET_NR_inotify_init1 324 > +#define TARGET_NR_pipe2 325 > +#define TARGET_NR_dup3 326 > +#define TARGET_NR_epoll_create1 327 > +#undef NR_syscalls > +#define NR_syscalls 328 > + > +/* > + * There are some system calls that are not present on 64 bit, some > + * have a different name although they do the same (e.g. TARGET_NR_chown32 > + * is TARGET_NR_chown on 64 bit). > + */ > +#ifndef TARGET_S390X > + > +#define TARGET_NR_time 13 > +#define TARGET_NR_lchown 16 > +#define TARGET_NR_setuid 23 > +#define TARGET_NR_getuid 24 > +#define TARGET_NR_stime 25 > +#define TARGET_NR_setgid 46 > +#define TARGET_NR_getgid 47 > +#define TARGET_NR_geteuid 49 > +#define TARGET_NR_getegid 50 > +#define TARGET_NR_setreuid 70 > +#define TARGET_NR_setregid 71 > +#define TARGET_NR_getrlimit 76 > +#define TARGET_NR_getgroups 80 > +#define TARGET_NR_setgroups 81 > +#define TARGET_NR_fchown 95 > +#define TARGET_NR_ioperm 101 > +#define TARGET_NR_setfsuid 138 > +#define TARGET_NR_setfsgid 139 > +#define TARGET_NR__llseek 140 > +#define TARGET_NR__newselect 142 > +#define TARGET_NR_setresuid 164 > +#define TARGET_NR_getresuid 165 > +#define TARGET_NR_setresgid 170 > +#define TARGET_NR_getresgid 171 > +#define TARGET_NR_chown 182 > +#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */ > +#define TARGET_NR_mmap2 192 > +#define TARGET_NR_truncate64 193 > +#define TARGET_NR_ftruncate64 194 > +#define TARGET_NR_stat64 195 > +#define TARGET_NR_lstat64 196 > +#define TARGET_NR_fstat64 197 > +#define TARGET_NR_lchown32 198 > +#define TARGET_NR_getuid32 199 > +#define TARGET_NR_getgid32 200 > +#define TARGET_NR_geteuid32 201 > +#define TARGET_NR_getegid32 202 > +#define TARGET_NR_setreuid32 203 > +#define TARGET_NR_setregid32 204 > +#define TARGET_NR_getgroups32 205 > +#define TARGET_NR_setgroups32 206 > +#define TARGET_NR_fchown32 207 > +#define TARGET_NR_setresuid32 208 > +#define TARGET_NR_getresuid32 209 > +#define TARGET_NR_setresgid32 210 > +#define TARGET_NR_getresgid32 211 > +#define TARGET_NR_chown32 212 > +#define TARGET_NR_setuid32 213 > +#define TARGET_NR_setgid32 214 > +#define TARGET_NR_setfsuid32 215 > +#define TARGET_NR_setfsgid32 216 > +#define TARGET_NR_fcntl64 221 > +#define TARGET_NR_sendfile64 223 > +#define TARGET_NR_fadvise64_64 264 > +#define TARGET_NR_fstatat64 293 > + > +#else > + > +#define TARGET_NR_select 142 > +#define TARGET_NR_getrlimit 191 /* SuS compliant getrlimit */ > +#define TARGET_NR_lchown 198 > +#define TARGET_NR_getuid 199 > +#define TARGET_NR_getgid 200 > +#define TARGET_NR_geteuid 201 > +#define TARGET_NR_getegid 202 > +#define TARGET_NR_setreuid 203 > +#define TARGET_NR_setregid 204 > +#define TARGET_NR_getgroups 205 > +#define TARGET_NR_setgroups 206 > +#define TARGET_NR_fchown 207 > +#define TARGET_NR_setresuid 208 > +#define TARGET_NR_getresuid 209 > +#define TARGET_NR_setresgid 210 > +#define TARGET_NR_getresgid 211 > +#define TARGET_NR_chown 212 > +#define TARGET_NR_setuid 213 > +#define TARGET_NR_setgid 214 > +#define TARGET_NR_setfsuid 215 > +#define TARGET_NR_setfsgid 216 > +#define TARGET_NR_newfstatat 293 > + > +#endif > + > diff --git a/linux-user/s390x/target_signal.h > b/linux-user/s390x/target_signal.h > new file mode 100644 > index 0000000..b4816b0 > --- /dev/null > +++ b/linux-user/s390x/target_signal.h > @@ -0,0 +1,26 @@ > +#ifndef TARGET_SIGNAL_H > +#define TARGET_SIGNAL_H > + > +#include "cpu.h" > + > +typedef struct target_sigaltstack { > + abi_ulong ss_sp; > + 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(CPUS390XState *state) > +{ > + return state->regs[15]; > +} > + > +#endif /* TARGET_SIGNAL_H */ > diff --git a/linux-user/s390x/termbits.h b/linux-user/s390x/termbits.h > new file mode 100644 > index 0000000..2a78a05 > --- /dev/null > +++ b/linux-user/s390x/termbits.h > @@ -0,0 +1,283 @@ > +/* > + * include/asm-s390/termbits.h > + * > + * S390 version > + * > + * Derived from "include/asm-i386/termbits.h" > + */ > + > +#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 */ > +}; > + > +struct target_ktermios { > + 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 B19200 > +#define TARGET_EXTB 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 > + > +/* 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 > + > +/* > + * include/asm-s390/ioctls.h > + * > + * S390 version > + * > + * Derived from "include/asm-i386/ioctls.h" > + */ > + > +/* 0x54 is just a magic number to make these relatively unique ('T') */ > + > +#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 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 /* Needed for POSIX > tcsendbreak() */ > +#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ > +#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ > +#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ > +#define TARGET_TCGETS2 _IOR('T',0x2A, struct termios2) > +#define TARGET_TCSETS2 _IOW('T',0x2B, struct termios2) > +#define TARGET_TCSETSW2 _IOW('T',0x2C, struct termios2) > +#define TARGET_TCSETSF2 _IOW('T',0x2D, struct termios2) > +#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number > (of pty-mux device) */ > +#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ > +#define TARGET_TIOCGDEV _IOR('T',0x32, unsigned int) /* Get real dev no > below /dev/console */ > + > +#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ > +#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 /* For debugging only */ > +#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ > +#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ > +#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ > + > +#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input > line(s) */ > +#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt > counts */ > +#define TARGET_FIOQSIZE 0x545E > + > +/* Used for packet mode */ > +#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_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ > + > diff --git a/linux-user/signal.c b/linux-user/signal.c > index ce033e9..42cc62c 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -3614,6 +3614,339 @@ long do_rt_sigreturn(CPUState *env) > return -TARGET_ENOSYS; > } > > +#elif defined(TARGET_S390X) > + > +#define __NUM_GPRS 16 > +#define __NUM_FPRS 16 > +#define __NUM_ACRS 16 > + > +#define S390_SYSCALL_SIZE 2 > +#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */ > + > +#define _SIGCONTEXT_NSIG 64 > +#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */ > +#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) > +#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) > +#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for > 31-bit */ > +#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00) > + > +typedef struct { > + target_psw_t psw; > + target_ulong gprs[__NUM_GPRS]; > + unsigned int acrs[__NUM_ACRS]; > +} target_s390_regs_common; > + > +typedef struct { > + unsigned int fpc; > + double fprs[__NUM_FPRS]; > +} target_s390_fp_regs; > + > +typedef struct { > + target_s390_regs_common regs; > + target_s390_fp_regs fpregs; > +} target_sigregs; > + > +struct target_sigcontext { > + target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; > + target_sigregs *sregs; > +}; > + > +typedef struct { > + uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; > + struct target_sigcontext sc; > + target_sigregs sregs; > + int signo; > + uint8_t retcode[S390_SYSCALL_SIZE]; > +} sigframe; > + > +struct target_ucontext { > + target_ulong uc_flags; > + struct target_ucontext *uc_link; > + target_stack_t uc_stack; > + target_sigregs uc_mcontext; > + target_sigset_t uc_sigmask; /* mask last for extensibility */ > +}; > + > +typedef struct { > + uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; > + uint8_t retcode[S390_SYSCALL_SIZE]; > + struct target_siginfo info; > + struct target_ucontext uc; > +} rt_sigframe; > + > +static inline abi_ulong > +get_sigframe(struct target_sigaction *ka, CPUState *env, size_t frame_size) > +{ > + abi_ulong sp; > + > + /* Default to using normal stack */ > + sp = env->regs[15]; > + > + /* This is the X/Open sanctioned signal stack switching. */ > + if (ka->sa_flags & TARGET_SA_ONSTACK) { > + if (!sas_ss_flags(sp)) { > + sp = target_sigaltstack_used.ss_sp + > + target_sigaltstack_used.ss_size; > + } > + } > + > + /* This is the legacy signal stack switching. */ > + else if (/* FIXME !user_mode(regs) */ 0 && > + !(ka->sa_flags & TARGET_SA_RESTORER) && > + ka->sa_restorer) { > + sp = (abi_ulong) ka->sa_restorer; > + } > + > + return (sp - frame_size) & -8ul; > +} > + > +static void save_sigregs(CPUState *env, target_sigregs *sregs) > +{ > + int i; > + //save_access_regs(current->thread.acrs); FIXME > + > + /* Copy a 'clean' PSW mask to the user to avoid leaking > + information about whether PER is currently on. */ > + __put_user(env->psw.mask, &sregs->regs.psw.mask); > + __put_user(env->psw.addr, &sregs->regs.psw.addr); > + for (i = 0; i < 16; i++) { > + __put_user(env->regs[i], &sregs->regs.gprs[i]); > + } > + for (i = 0; i < 16; i++) { > + __put_user(env->aregs[i], &sregs->regs.acrs[i]); > + } > + /* > + * We have to store the fp registers to current->thread.fp_regs > + * to merge them with the emulated registers. > + */ > + //save_fp_regs(¤t->thread.fp_regs); FIXME > + for (i = 0; i < 16; i++) { > + __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]); > + } > +} > + > +static void setup_frame(int sig, struct target_sigaction *ka, > + target_sigset_t *set, CPUState *env) > +{ > + sigframe *frame; > + 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); > + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { > + goto give_sigsegv; > + } > + > + qemu_log("%s: 1\n", __FUNCTION__); > + if (__put_user(set->sig[0], &frame->sc.oldmask[0])) { > + goto give_sigsegv; > + } > + > + save_sigregs(env, &frame->sregs); > + > + __put_user((abi_ulong)(unsigned long)&frame->sregs, > + (abi_ulong *)&frame->sc.sregs); > + > + /* Set up to return from userspace. If provided, use a stub > + already in userspace. */ > + if (ka->sa_flags & TARGET_SA_RESTORER) { > + env->regs[14] = (unsigned long) > + ka->sa_restorer | PSW_ADDR_AMODE; > + } else { > + env->regs[14] = (unsigned long) > + frame->retcode | PSW_ADDR_AMODE; > + if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, > + (uint16_t *)(frame->retcode))) > + goto give_sigsegv; > + } > + > + /* Set up backchain. */ > + if (__put_user(env->regs[15], (abi_ulong *) frame)) { > + goto give_sigsegv; > + } > + > + /* Set up registers for signal handler */ > + env->regs[15] = (target_ulong)(unsigned long) frame; > + env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; > + > + env->regs[2] = sig; //map_signal(sig); > + env->regs[3] = (target_ulong)(unsigned long) &frame->sc; > + > + /* We forgot to include these in the sigcontext. > + To avoid breaking binary compatibility, they are passed as args. */ > + env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no; > + env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr; > + > + /* Place signal number on stack to allow backtrace from handler. */ > + if (__put_user(env->regs[2], (int *) &frame->signo)) { > + goto give_sigsegv; > + } > + unlock_user_struct(frame, frame_addr, 1); > + return; > + > +give_sigsegv: > + qemu_log("%s: give_sigsegv\n", __FUNCTION__); > + unlock_user_struct(frame, frame_addr, 1); > + force_sig(TARGET_SIGSEGV); > +} > + > +static void setup_rt_frame(int sig, struct target_sigaction *ka, > + target_siginfo_t *info, > + target_sigset_t *set, CPUState *env) > +{ > + int i; > + rt_sigframe *frame; > + 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); > + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { > + goto give_sigsegv; > + } > + > + qemu_log("%s: 1\n", __FUNCTION__); > + if (copy_siginfo_to_user(&frame->info, info)) { > + goto give_sigsegv; > + } > + > + /* Create the ucontext. */ > + __put_user(0, &frame->uc.uc_flags); > + __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.uc_link); > + __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp); > + __put_user(sas_ss_flags(get_sp_from_cpustate(env)), > + &frame->uc.uc_stack.ss_flags); > + __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size); > + save_sigregs(env, &frame->uc.uc_mcontext); > + for (i = 0; i < TARGET_NSIG_WORDS; i++) { > + __put_user((abi_ulong)set->sig[i], > + (abi_ulong *)&frame->uc.uc_sigmask.sig[i]); > + } > + > + /* Set up to return from userspace. If provided, use a stub > + already in userspace. */ > + if (ka->sa_flags & TARGET_SA_RESTORER) { > + env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE; > + } else { > + env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE; > + if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, > + (uint16_t *)(frame->retcode))) { > + goto give_sigsegv; > + } > + } > + > + /* Set up backchain. */ > + if (__put_user(env->regs[15], (abi_ulong *) frame)) { > + goto give_sigsegv; > + } > + > + /* Set up registers for signal handler */ > + env->regs[15] = (target_ulong)(unsigned long) frame; > + env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; > + > + env->regs[2] = sig; //map_signal(sig); > + env->regs[3] = (target_ulong)(unsigned long) &frame->info; > + env->regs[4] = (target_ulong)(unsigned long) &frame->uc; > + return; > + > +give_sigsegv: > + qemu_log("%s: give_sigsegv\n", __FUNCTION__); > + unlock_user_struct(frame, frame_addr, 1); > + force_sig(TARGET_SIGSEGV); > +} > + > +static int > +restore_sigregs(CPUState *env, target_sigregs *sc) > +{ > + int err = 0; > + int i; > + > + for (i = 0; i < 16; i++) { > + err |= __get_user(env->regs[i], &sc->regs.gprs[i]); > + } > + > + err |= __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); > + err |= __get_user(env->psw.addr, &sc->regs.psw.addr); > + /* FIXME: 31-bit -> | PSW_ADDR_AMODE */ > + > + for (i = 0; i < 16; i++) { > + err |= __get_user(env->aregs[i], &sc->regs.acrs[i]); > + } > + for (i = 0; i < 16; i++) { > + err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]); > + } > + > + return err; > +} > + > +long do_sigreturn(CPUState *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; > + > + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { > + goto badframe; > + } > + if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) { > + goto badframe; > + } > + > + target_to_host_sigset_internal(&set, &target_set); > + sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ > + > + if (restore_sigregs(env, &frame->sregs)) { > + goto badframe; > + } > + > + unlock_user_struct(frame, frame_addr, 0); > + return env->regs[2]; > + > +badframe: > + unlock_user_struct(frame, frame_addr, 0); > + force_sig(TARGET_SIGSEGV); > + return 0; > +} > + > +long do_rt_sigreturn(CPUState *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; > + > + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { > + goto badframe; > + } > + target_to_host_sigset(&set, &frame->uc.uc_sigmask); > + > + sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ > + > + if (restore_sigregs(env, &frame->uc.uc_mcontext)) { > + goto badframe; > + } > + > + if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0, > + get_sp_from_cpustate(env)) == -EFAULT) { > + goto badframe; > + } > + unlock_user_struct(frame, frame_addr, 0); > + return env->regs[2]; > + > +badframe: > + unlock_user_struct(frame, frame_addr, 0); > + force_sig(TARGET_SIGSEGV); > + return 0; > +} > + > #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) > > /* FIXME: Many of the structures are defined for both PPC and PPC64, but > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index bb0999d..504b26c 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -5432,7 +5432,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > ret = get_errno(settimeofday(&tv, NULL)); > } > break; > -#ifdef TARGET_NR_select > +#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && > !defined(TARGET_S390) > case TARGET_NR_select: > { > struct target_sel_arg_struct *sel; > @@ -5543,7 +5543,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > #endif > #ifdef TARGET_NR_mmap > case TARGET_NR_mmap: > -#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) > || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) > +#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) > || \ > + defined(TARGET_M68K) || defined(TARGET_CRIS) || > defined(TARGET_MICROBLAZE) \ > + || defined(TARGET_S390X) > { > abi_ulong *v; > abi_ulong v1, v2, v3, v4, v5, v6; > @@ -6039,6 +6041,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4)); > #elif defined(TARGET_CRIS) > ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5)); > +#elif defined(TARGET_S390X) > + ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4)); > #else > ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); > #endif > @@ -6247,8 +6251,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > } > break; > #endif /* TARGET_NR_getdents64 */ > -#ifdef TARGET_NR__newselect > +#if defined(TARGET_NR__newselect) || defined(TARGET_S390X) > +#ifdef TARGET_S390X > + case TARGET_NR_select: > +#else > case TARGET_NR__newselect: > +#endif > ret = do_select(arg1, arg2, arg3, arg4, arg5); > break; > #endif > @@ -6576,7 +6584,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > 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_M68K) || defined(TARGET_S390X) > ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState > *)cpu_env)); > break; > #else > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h > index bde8921..162d88a 100644 > --- a/linux-user/syscall_defs.h > +++ b/linux-user/syscall_defs.h > @@ -55,7 +55,8 @@ > #endif > > #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ > - || defined(TARGET_M68K) || defined(TARGET_CRIS) || > defined(TARGET_UNICORE32) > + || defined(TARGET_M68K) || defined(TARGET_CRIS) || > defined(TARGET_UNICORE32) \ > + || defined(TARGET_S390X) > > #define TARGET_IOC_SIZEBITS 14 > #define TARGET_IOC_DIRBITS 2 > @@ -318,7 +319,8 @@ int do_sigaction(int sig, const struct target_sigaction > *act, > #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ > || 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_MICROBLAZE) || defined(TARGET_UNICORE32) \ > + || defined(TARGET_S390X) > > #if defined(TARGET_SPARC) > #define TARGET_SA_NOCLDSTOP 8u > @@ -1682,6 +1684,27 @@ struct target_stat { > > abi_long __unused[3]; > }; > +#elif defined(TARGET_S390X) > +struct target_stat { > + abi_ulong st_dev; > + abi_ulong st_ino; > + abi_ulong st_nlink; > + unsigned int st_mode; > + unsigned int st_uid; > + unsigned int st_gid; > + unsigned int __pad1; > + abi_ulong st_rdev; > + abi_ulong st_size; > + abi_ulong target_st_atime; > + abi_ulong target_st_atime_nsec; > + abi_ulong target_st_mtime; > + abi_ulong target_st_mtime_nsec; > + abi_ulong target_st_ctime; > + abi_ulong target_st_ctime_nsec; > + abi_ulong st_blksize; > + abi_long st_blocks; > + abi_ulong __unused[3]; > +}; > #else > #error unsupported CPU > #endif > @@ -1768,6 +1791,34 @@ struct target_statfs64 { > abi_long f_frsize; > abi_long f_spare[5]; > }; > +#elif defined(TARGET_S390X) > +struct target_statfs { > + int32_t f_type; > + int32_t f_bsize; > + abi_long f_blocks; > + abi_long f_bfree; > + abi_long f_bavail; > + abi_long f_files; > + abi_long f_ffree; > + kernel_fsid_t f_fsid; > + int32_t f_namelen; > + int32_t f_frsize; > + int32_t f_spare[5]; > +}; > + > +struct target_statfs64 { > + int32_t f_type; > + int32_t f_bsize; > + abi_long f_blocks; > + abi_long f_bfree; > + abi_long f_bavail; > + abi_long f_files; > + abi_long f_ffree; > + kernel_fsid_t f_fsid; > + int32_t f_namelen; > + int32_t f_frsize; > + int32_t f_spare[5]; > +}; > #else > struct target_statfs { > uint32_t f_type; > diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh > index c50beb7..83a44d8 100644 > --- a/scripts/qemu-binfmt-conf.sh > +++ b/scripts/qemu-binfmt-conf.sh > @@ -1,5 +1,5 @@ > #!/bin/sh > -# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC program execution by the > kernel > +# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by > the kernel > > # load the binfmt_misc module > if [ ! -d /proc/sys/fs/binfmt_misc ]; then > @@ -63,4 +63,6 @@ fi > if [ $cpu != "sh" ] ; then > echo > ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > > /proc/sys/fs/binfmt_misc/register > echo > ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > > /proc/sys/fs/binfmt_misc/register > +if [ $cpu != "s390x" ] ; then > + echo > ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > > /proc/sys/fs/binfmt_misc/register > fi > -- > 1.6.0.2 >