aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2009-12-09 15:56:29 -0800
committerAurelien Jarno <aurelien@aurel32.net>2009-12-13 20:32:36 +0100
commitba0e276db4b51bd2255a5d5ff8902c70d32ade40 (patch)
tree7366b9dcf6b064f59e4879bc517906c3af5fbdb2 /linux-user
parent990b3e19013ebd36b3fb9af97aaa67f7bc490c15 (diff)
target-alpha: Fixes for alpha-linux syscalls.
1. Add correct definitions of error numbers. 2. Implement SYS_osf_sigprocmask 3. Implement SYS_osf_get/setsysinfo for IEEE_FP_CONTROL. This last requires exposing the FPCR value to do_syscall. Since this value is actually split up into the float_status, expose routines from helper.c to access it. Finally, also add a float_exception_mask field to float_status. We don't actually use it to control delivery of exceptions to the emulator yet, but simply hold the value that we placed there when loading/storing the FPCR. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/alpha/syscall.h212
-rw-r--r--linux-user/syscall.c137
2 files changed, 339 insertions, 10 deletions
diff --git a/linux-user/alpha/syscall.h b/linux-user/alpha/syscall.h
index 394afec56c..15a0100335 100644
--- a/linux-user/alpha/syscall.h
+++ b/linux-user/alpha/syscall.h
@@ -39,3 +39,215 @@ struct target_pt_regs {
};
#define UNAME_MACHINE "alpha"
+
+#undef TARGET_EDEADLK
+#define TARGET_EDEADLK 11
+#undef TARGET_EAGAIN
+#define TARGET_EAGAIN 35
+#undef TARGET_EINPROGRESS
+#define TARGET_EINPROGRESS 36
+#undef TARGET_EALREADY
+#define TARGET_EALREADY 37
+#undef TARGET_ENOTSOCK
+#define TARGET_ENOTSOCK 38
+#undef TARGET_EDESTADDRREQ
+#define TARGET_EDESTADDRREQ 39
+#undef TARGET_EMSGSIZE
+#define TARGET_EMSGSIZE 40
+#undef TARGET_EPROTOTYPE
+#define TARGET_EPROTOTYPE 41
+#undef TARGET_ENOPROTOOPT
+#define TARGET_ENOPROTOOPT 42
+#undef TARGET_EPROTONOSUPPORT
+#define TARGET_EPROTONOSUPPORT 43
+#undef TARGET_ESOCKTNOSUPPORT
+#define TARGET_ESOCKTNOSUPPORT 44
+#undef TARGET_EOPNOTSUPP
+#define TARGET_EOPNOTSUPP 45
+#undef TARGET_EPFNOSUPPORT
+#define TARGET_EPFNOSUPPORT 46
+#undef TARGET_EAFNOSUPPORT
+#define TARGET_EAFNOSUPPORT 47
+#undef TARGET_EADDRINUSE
+#define TARGET_EADDRINUSE 48
+#undef TARGET_EADDRNOTAVAIL
+#define TARGET_EADDRNOTAVAIL 49
+#undef TARGET_ENETDOWN
+#define TARGET_ENETDOWN 50
+#undef TARGET_ENETUNREACH
+#define TARGET_ENETUNREACH 51
+#undef TARGET_ENETRESET
+#define TARGET_ENETRESET 52
+#undef TARGET_ECONNABORTED
+#define TARGET_ECONNABORTED 53
+#undef TARGET_ECONNRESET
+#define TARGET_ECONNRESET 54
+#undef TARGET_ENOBUFS
+#define TARGET_ENOBUFS 55
+#undef TARGET_EISCONN
+#define TARGET_EISCONN 56
+#undef TARGET_ENOTCONN
+#define TARGET_ENOTCONN 57
+#undef TARGET_ESHUTDOWN
+#define TARGET_ESHUTDOWN 58
+#undef TARGET_ETOOMANYREFS
+#define TARGET_ETOOMANYREFS 59
+#undef TARGET_ETIMEDOUT
+#define TARGET_ETIMEDOUT 60
+#undef TARGET_ECONNREFUSED
+#define TARGET_ECONNREFUSED 61
+#undef TARGET_ELOOP
+#define TARGET_ELOOP 62
+#undef TARGET_ENAMETOOLONG
+#define TARGET_ENAMETOOLONG 63
+#undef TARGET_EHOSTDOWN
+#define TARGET_EHOSTDOWN 64
+#undef TARGET_EHOSTUNREACH
+#define TARGET_EHOSTUNREACH 65
+#undef TARGET_ENOTEMPTY
+#define TARGET_ENOTEMPTY 66
+// Unused 67
+#undef TARGET_EUSERS
+#define TARGET_EUSERS 68
+#undef TARGET_EDQUOT
+#define TARGET_EDQUOT 69
+#undef TARGET_ESTALE
+#define TARGET_ESTALE 70
+#undef TARGET_EREMOTE
+#define TARGET_EREMOTE 71
+// Unused 72-76
+#undef TARGET_ENOLCK
+#define TARGET_ENOLCK 77
+#undef TARGET_ENOSYS
+#define TARGET_ENOSYS 78
+// Unused 79
+#undef TARGET_ENOMSG
+#define TARGET_ENOMSG 80
+#undef TARGET_EIDRM
+#define TARGET_EIDRM 81
+#undef TARGET_ENOSR
+#define TARGET_ENOSR 82
+#undef TARGET_ETIME
+#define TARGET_ETIME 83
+#undef TARGET_EBADMSG
+#define TARGET_EBADMSG 84
+#undef TARGET_EPROTO
+#define TARGET_EPROTO 85
+#undef TARGET_ENODATA
+#define TARGET_ENODATA 86
+#undef TARGET_ENOSTR
+#define TARGET_ENOSTR 87
+#undef TARGET_ECHRNG
+#define TARGET_ECHRNG 88
+#undef TARGET_EL2NSYNC
+#define TARGET_EL2NSYNC 89
+#undef TARGET_EL3HLT
+#define TARGET_EL3HLT 90
+#undef TARGET_EL3RST
+#define TARGET_EL3RST 91
+#undef TARGET_ENOPKG
+#define TARGET_ENOPKG 92
+#undef TARGET_ELNRNG
+#define TARGET_ELNRNG 93
+#undef TARGET_EUNATCH
+#define TARGET_EUNATCH 94
+#undef TARGET_ENOCSI
+#define TARGET_ENOCSI 95
+#undef TARGET_EL2HLT
+#define TARGET_EL2HLT 96
+#undef TARGET_EBADE
+#define TARGET_EBADE 97
+#undef TARGET_EBADR
+#define TARGET_EBADR 98
+#undef TARGET_EXFULL
+#define TARGET_EXFULL 99
+#undef TARGET_ENOANO
+#define TARGET_ENOANO 100
+#undef TARGET_EBADRQC
+#define TARGET_EBADRQC 101
+#undef TARGET_EBADSLT
+#define TARGET_EBADSLT 102
+// Unused 103
+#undef TARGET_EBFONT
+#define TARGET_EBFONT 104
+#undef TARGET_ENONET
+#define TARGET_ENONET 105
+#undef TARGET_ENOLINK
+#define TARGET_ENOLINK 106
+#undef TARGET_EADV
+#define TARGET_EADV 107
+#undef TARGET_ESRMNT
+#define TARGET_ESRMNT 108
+#undef TARGET_ECOMM
+#define TARGET_ECOMM 109
+#undef TARGET_EMULTIHOP
+#define TARGET_EMULTIHOP 110
+#undef TARGET_EDOTDOT
+#define TARGET_EDOTDOT 111
+#undef TARGET_EOVERFLOW
+#define TARGET_EOVERFLOW 112
+#undef TARGET_ENOTUNIQ
+#define TARGET_ENOTUNIQ 113
+#undef TARGET_EBADFD
+#define TARGET_EBADFD 114
+#undef TARGET_EREMCHG
+#define TARGET_EREMCHG 115
+#undef TARGET_EILSEQ
+#define TARGET_EILSEQ 116
+
+// Same as default 117-121
+
+#undef TARGET_ELIBACC
+#define TARGET_ELIBACC 122
+#undef TARGET_ELIBBAD
+#define TARGET_ELIBBAD 123
+#undef TARGET_ELIBSCN
+#define TARGET_ELIBSCN 124
+#undef TARGET_ELIBMAX
+#define TARGET_ELIBMAX 125
+#undef TARGET_ELIBEXEC
+#define TARGET_ELIBEXEC 126
+#undef TARGET_ERESTART
+#define TARGET_ERESTART 127
+#undef TARGET_ESTRPIPE
+#define TARGET_ESTRPIPE 128
+#undef TARGET_ENOMEDIUM
+#define TARGET_ENOMEDIUM 129
+#undef TARGET_EMEDIUMTYPE
+#define TARGET_EMEDIUMTYPE 130
+#undef TARGET_ECANCELED
+#define TARGET_ECANCELED 131
+#undef TARGET_ENOKEY
+#define TARGET_ENOKEY 132
+#undef TARGET_EKEYEXPIRED
+#define TARGET_EKEYEXPIRED 133
+#undef TARGET_EKEYREVOKED
+#define TARGET_EKEYREVOKED 134
+#undef TARGET_EKEYREJECTED
+#define TARGET_EKEYREJECTED 135
+#undef TARGET_EOWNERDEAD
+#define TARGET_EOWNERDEAD 136
+#undef TARGET_ENOTRECOVERABLE
+#define TARGET_ENOTRECOVERABLE 137
+#undef TARGET_ERFKILL
+#define TARGET_ERFKILL 138
+
+// For sys_osf_getsysinfo
+#define TARGET_GSI_UACPROC 8
+#define TARGET_GSI_IEEE_FP_CONTROL 45
+#define TARGET_GSI_IEEE_STATE_AT_SIGNAL 46
+#define TARGET_GSI_PROC_TYPE 60
+#define TARGET_GSI_GET_HWRPB 101
+
+// For sys_ofs_setsysinfo
+#define TARGET_SSI_NVPAIRS 1
+#define TARGET_SSI_IEEE_FP_CONTROL 14
+#define TARGET_SSI_IEEE_STATE_AT_SIGNAL 15
+#define TARGET_SSI_IEEE_IGNORE_STATE_AT_SIGNAL 16
+#define TARGET_SSI_IEEE_RAISE_EXCEPTION 1001
+
+#define TARGET_SSIN_UACPROC 6
+
+#define TARGET_UAC_NOPRINT 1
+#define TARGET_UAC_NOFIX 2
+#define TARGET_UAC_SIGBUS 4
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e38552ca1c..1acf1f5b64 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6390,25 +6390,142 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
/* Alpha specific */
case TARGET_NR_getxuid:
- {
- uid_t euid;
- euid=geteuid();
- ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
- }
+ {
+ uid_t euid;
+ euid=geteuid();
+ ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
+ }
ret = get_errno(getuid());
break;
#endif
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
/* Alpha specific */
case TARGET_NR_getxgid:
- {
- uid_t egid;
- egid=getegid();
- ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
- }
+ {
+ uid_t egid;
+ egid=getegid();
+ ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
+ }
ret = get_errno(getgid());
break;
#endif
+#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
+ /* Alpha specific */
+ case TARGET_NR_osf_getsysinfo:
+ ret = -TARGET_EOPNOTSUPP;
+ switch (arg1) {
+ case TARGET_GSI_IEEE_FP_CONTROL:
+ {
+ uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
+
+ /* Copied from linux ieee_fpcr_to_swcr. */
+ swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
+ swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
+ swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
+ | SWCR_TRAP_ENABLE_DZE
+ | SWCR_TRAP_ENABLE_OVF);
+ swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
+ | SWCR_TRAP_ENABLE_INE);
+ swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
+ swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
+
+ if (put_user_u64 (swcr, arg2))
+ goto efault;
+ ret = 0;
+ }
+ break;
+
+ /* case GSI_IEEE_STATE_AT_SIGNAL:
+ -- Not implemented in linux kernel.
+ case GSI_UACPROC:
+ -- Retrieves current unaligned access state; not much used.
+ case GSI_PROC_TYPE:
+ -- Retrieves implver information; surely not used.
+ case GSI_GET_HWRPB:
+ -- Grabs a copy of the HWRPB; surely not used.
+ */
+ }
+ break;
+#endif
+#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
+ /* Alpha specific */
+ case TARGET_NR_osf_setsysinfo:
+ ret = -TARGET_EOPNOTSUPP;
+ switch (arg1) {
+ case TARGET_SSI_IEEE_FP_CONTROL:
+ case TARGET_SSI_IEEE_RAISE_EXCEPTION:
+ {
+ uint64_t swcr, fpcr, orig_fpcr;
+
+ if (get_user_u64 (swcr, arg2))
+ goto efault;
+ orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
+ fpcr = orig_fpcr & FPCR_DYN_MASK;
+
+ /* Copied from linux ieee_swcr_to_fpcr. */
+ fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
+ fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
+ fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
+ | SWCR_TRAP_ENABLE_DZE
+ | SWCR_TRAP_ENABLE_OVF)) << 48;
+ fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
+ | SWCR_TRAP_ENABLE_INE)) << 57;
+ fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
+ fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
+
+ cpu_alpha_store_fpcr (cpu_env, fpcr);
+ ret = 0;
+
+ if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
+ /* Old exceptions are not signaled. */
+ fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
+
+ /* If any exceptions set by this call, and are unmasked,
+ send a signal. */
+ /* ??? FIXME */
+ }
+ }
+ break;
+
+ /* case SSI_NVPAIRS:
+ -- Used with SSIN_UACPROC to enable unaligned accesses.
+ case SSI_IEEE_STATE_AT_SIGNAL:
+ case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
+ -- Not implemented in linux kernel
+ */
+ }
+ break;
+#endif
+#ifdef TARGET_NR_osf_sigprocmask
+ /* Alpha specific. */
+ case TARGET_NR_osf_sigprocmask:
+ {
+ abi_ulong mask;
+ int how = arg1;
+ sigset_t set, oldset;
+
+ switch(arg1) {
+ case TARGET_SIG_BLOCK:
+ how = SIG_BLOCK;
+ break;
+ case TARGET_SIG_UNBLOCK:
+ how = SIG_UNBLOCK;
+ break;
+ case TARGET_SIG_SETMASK:
+ how = SIG_SETMASK;
+ break;
+ default:
+ ret = -TARGET_EINVAL;
+ goto fail;
+ }
+ mask = arg2;
+ target_to_host_old_sigset(&set, &mask);
+ sigprocmask(arg1, &set, &oldset);
+ host_to_target_old_sigset(&mask, &oldset);
+ ret = mask;
+ }
+ break;
+#endif
#ifdef TARGET_NR_getgid32
case TARGET_NR_getgid32: