Message ID | 1302881578-5357-3-git-send-email-agraf@suse.de |
---|---|
State | New |
Headers | show |
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 <uli@suse.de> > > This patch adds support for running s390x binaries in the linux-user emulation > code. > > Signed-off-by: Ulrich Hecht <uli@suse.de> > Signed-off-by: Alexander Graf <agraf@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 >
On 18.04.2011, at 13:38, Riku Voipio wrote: > 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. Sure - what exactly would you like there? I can easily compile a few. Do you want to have them added to the tests/ directory? Alex
On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > 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. > > Sure - what exactly would you like there? I can easily compile a few. Do you want to have them added to the tests/ directory? busybox has so far been most useful. Riku
Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: > On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > > 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. > > > > Sure - what exactly would you like there? I can easily compile a few. Do > > you want to have them added to the tests/ directory? > > busybox has so far been most useful. > Good idea, what about adding a collection of static busybox for the different arches? Not everyone testing has the compiler around for $ARCH . Best, Jan-Simon
On 18.04.2011, at 15:21, Jan-Simon Möller wrote: > Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: >> On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: >>>> 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. >>> >>> Sure - what exactly would you like there? I can easily compile a few. Do >>> you want to have them added to the tests/ directory? >> >> busybox has so far been most useful. >> > > Good idea, what about adding a collection of static busybox for the different > arches? Not everyone testing has the compiler around for $ARCH . It'd probably make more sense to help the busybox guys to build an s390 version automatically. The others are already available: http://www.busybox.net/downloads/binaries/latest/ Alex
On Mon, Apr 18, 2011 at 03:21:54PM +0200, Jan-Simon Möller wrote: > Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: > > On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > > > 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. > > > > > > Sure - what exactly would you like there? I can easily compile a few. Do > > > you want to have them added to the tests/ directory? > > > > busybox has so far been most useful. > > > > Good idea, what about adding a collection of static busybox for the different > arches? Not everyone testing has the compiler around for $ARCH . > It's something that already exists [1]. It would actually make sense to add s390x binaries there. Also it might be a good idea to provide a minimal system image as on other architectures. [1] http://wiki.qemu.org/Download
On 18.04.2011, at 15:36, Aurelien Jarno wrote: > On Mon, Apr 18, 2011 at 03:21:54PM +0200, Jan-Simon Möller wrote: >> Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: >>> On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: >>>>> 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. >>>> >>>> Sure - what exactly would you like there? I can easily compile a few. Do >>>> you want to have them added to the tests/ directory? >>> >>> busybox has so far been most useful. >>> >> >> Good idea, what about adding a collection of static busybox for the different >> arches? Not everyone testing has the compiler around for $ARCH . >> > > It's something that already exists [1]. It would actually make sense to > add s390x binaries there. Also it might be a good idea to provide a > minimal system image as on other architectures. > > [1] http://wiki.qemu.org/Download I find the minimal systems rather useless, but love your Debian images. So if you could create one of those for s390, that'd be awesome! :) Alex
On Mon, Apr 18, 2011 at 03:42:25PM +0200, Alexander Graf wrote: > > On 18.04.2011, at 15:36, Aurelien Jarno wrote: > > > On Mon, Apr 18, 2011 at 03:21:54PM +0200, Jan-Simon Möller wrote: > >> Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: > >>> On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > >>>>> 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. > >>>> > >>>> Sure - what exactly would you like there? I can easily compile a few. Do > >>>> you want to have them added to the tests/ directory? > >>> > >>> busybox has so far been most useful. > >>> > >> > >> Good idea, what about adding a collection of static busybox for the different > >> arches? Not everyone testing has the compiler around for $ARCH . > >> > > > > It's something that already exists [1]. It would actually make sense to > > add s390x binaries there. Also it might be a good idea to provide a > > minimal system image as on other architectures. > > > > [1] http://wiki.qemu.org/Download > > I find the minimal systems rather useless, but love your Debian images. So if you could create one of those for s390, that'd be awesome! :) > Once I get qemu-system-s390x fully working, it looks my scripts to produce images should work with minor changes for s390.
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