linux-user errno mapping, by Stuart Anderson.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2908 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 64cd5da..1ec81ce5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -181,10 +181,117 @@
 extern int getresgid(gid_t *, gid_t *, gid_t *);
 extern int setgroups(int, gid_t *);
 
+/*
+ * This list is the union of errno values overidden in asm-<arch>/errno.h
+ * minus the errnos that are not actually generic to all archs.
+ */
+static uint16_t host_to_target_errno_table[1200] = {
+    [EIDRM]		= TARGET_EIDRM,
+    [ECHRNG]		= TARGET_ECHRNG,
+    [EL2NSYNC]		= TARGET_EL2NSYNC,
+    [EL3HLT]		= TARGET_EL3HLT,
+    [EL3RST]		= TARGET_EL3RST,
+    [ELNRNG]		= TARGET_ELNRNG,
+    [EUNATCH]		= TARGET_EUNATCH,
+    [ENOCSI]		= TARGET_ENOCSI,
+    [EL2HLT]		= TARGET_EL2HLT,
+    [EDEADLK]		= TARGET_EDEADLK,
+    [ENOLCK]		= TARGET_ENOLCK,
+    [EBADE]		= TARGET_EBADE,
+    [EBADR]		= TARGET_EBADR,
+    [EXFULL]		= TARGET_EXFULL,
+    [ENOANO]		= TARGET_ENOANO,
+    [EBADRQC]		= TARGET_EBADRQC,
+    [EBADSLT]		= TARGET_EBADSLT,
+    [EBFONT]		= TARGET_EBFONT,
+    [ENOSTR]		= TARGET_ENOSTR,
+    [ENODATA]		= TARGET_ENODATA,
+    [ETIME]		= TARGET_ETIME,
+    [ENOSR]		= TARGET_ENOSR,
+    [ENONET]		= TARGET_ENONET,
+    [ENOPKG]		= TARGET_ENOPKG,
+    [EREMOTE]		= TARGET_EREMOTE,
+    [ENOLINK]		= TARGET_ENOLINK,
+    [EADV]		= TARGET_EADV,
+    [ESRMNT]		= TARGET_ESRMNT,
+    [ECOMM]		= TARGET_ECOMM,
+    [EPROTO]		= TARGET_EPROTO,
+    [EDOTDOT]		= TARGET_EDOTDOT,
+    [EMULTIHOP]		= TARGET_EMULTIHOP,
+    [EBADMSG]		= TARGET_EBADMSG,
+    [ENAMETOOLONG]	= TARGET_ENAMETOOLONG,
+    [EOVERFLOW]		= TARGET_EOVERFLOW,
+    [ENOTUNIQ]		= TARGET_ENOTUNIQ,
+    [EBADFD]		= TARGET_EBADFD,
+    [EREMCHG]		= TARGET_EREMCHG,
+    [ELIBACC]		= TARGET_ELIBACC,
+    [ELIBBAD]		= TARGET_ELIBBAD,
+    [ELIBSCN]		= TARGET_ELIBSCN,
+    [ELIBMAX]		= TARGET_ELIBMAX,
+    [ELIBEXEC]		= TARGET_ELIBEXEC,
+    [EILSEQ]		= TARGET_EILSEQ,
+    [ENOSYS]		= TARGET_ENOSYS,
+    [ELOOP]		= TARGET_ELOOP,
+    [ERESTART]		= TARGET_ERESTART,
+    [ESTRPIPE]		= TARGET_ESTRPIPE,
+    [ENOTEMPTY]		= TARGET_ENOTEMPTY,
+    [EUSERS]		= TARGET_EUSERS,
+    [ENOTSOCK]		= TARGET_ENOTSOCK,
+    [EDESTADDRREQ]	= TARGET_EDESTADDRREQ,
+    [EMSGSIZE]		= TARGET_EMSGSIZE,
+    [EPROTOTYPE]	= TARGET_EPROTOTYPE,
+    [ENOPROTOOPT]	= TARGET_ENOPROTOOPT,
+    [EPROTONOSUPPORT]	= TARGET_EPROTONOSUPPORT,
+    [ESOCKTNOSUPPORT]	= TARGET_ESOCKTNOSUPPORT,
+    [EOPNOTSUPP]	= TARGET_EOPNOTSUPP,
+    [EPFNOSUPPORT]	= TARGET_EPFNOSUPPORT,
+    [EAFNOSUPPORT]	= TARGET_EAFNOSUPPORT,
+    [EADDRINUSE]	= TARGET_EADDRINUSE,
+    [EADDRNOTAVAIL]	= TARGET_EADDRNOTAVAIL,
+    [ENETDOWN]		= TARGET_ENETDOWN,
+    [ENETUNREACH]	= TARGET_ENETUNREACH,
+    [ENETRESET]		= TARGET_ENETRESET,
+    [ECONNABORTED]	= TARGET_ECONNABORTED,
+    [ECONNRESET]	= TARGET_ECONNRESET,
+    [ENOBUFS]		= TARGET_ENOBUFS,
+    [EISCONN]		= TARGET_EISCONN,
+    [ENOTCONN]		= TARGET_ENOTCONN,
+    [EUCLEAN]		= TARGET_EUCLEAN,
+    [ENOTNAM]		= TARGET_ENOTNAM,
+    [ENAVAIL]		= TARGET_ENAVAIL,
+    [EISNAM]		= TARGET_EISNAM,
+    [EREMOTEIO]		= TARGET_EREMOTEIO,
+    [ESHUTDOWN]		= TARGET_ESHUTDOWN,
+    [ETOOMANYREFS]	= TARGET_ETOOMANYREFS,
+    [ETIMEDOUT]		= TARGET_ETIMEDOUT,
+    [ECONNREFUSED]	= TARGET_ECONNREFUSED,
+    [EHOSTDOWN]		= TARGET_EHOSTDOWN,
+    [EHOSTUNREACH]	= TARGET_EHOSTUNREACH,
+    [EALREADY]		= TARGET_EALREADY,
+    [EINPROGRESS]	= TARGET_EINPROGRESS,
+    [ESTALE]		= TARGET_ESTALE,
+    [ECANCELED]		= TARGET_ECANCELED,
+    [ENOMEDIUM]		= TARGET_ENOMEDIUM,
+    [EMEDIUMTYPE]	= TARGET_EMEDIUMTYPE,
+    [ENOKEY]		= TARGET_ENOKEY,
+    [EKEYEXPIRED]	= TARGET_EKEYEXPIRED,
+    [EKEYREVOKED]	= TARGET_EKEYREVOKED,
+    [EKEYREJECTED]	= TARGET_EKEYREJECTED,
+    [EOWNERDEAD]	= TARGET_EOWNERDEAD,
+    [ENOTRECOVERABLE]	= TARGET_ENOTRECOVERABLE,
+	};
+
+static inline int host_to_target_errno(int err)
+{
+    if(host_to_target_errno_table[err])
+        return host_to_target_errno_table[err];
+    return err;
+}
+
 static inline long get_errno(long ret)
 {
     if (ret == -1)
-        return -errno;
+        return -host_to_target_errno(errno);
     else
         return ret;
 }