5544c1
From 707f294ca28977968fb85bf36f10c6b37b16f557 Mon Sep 17 00:00:00 2001
5544c1
From: Max Filippov <jcmvbkbc@gmail.com>
5544c1
Date: Wed, 29 Aug 2012 23:54:25 +0400
5544c1
Subject: [PATCH] target-xtensa: convert host errno values to guest
5544c1
5544c1
Guest errno values are taken from the newlib. Convert only those errno
5544c1
values that can be returned from used system calls.
5544c1
5544c1
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
5544c1
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
5544c1
---
5544c1
 target-xtensa/xtensa-semi.c | 106 ++++++++++++++++++++++++++++++++++++++++----
5544c1
 1 file changed, 98 insertions(+), 8 deletions(-)
5544c1
5544c1
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
5544c1
index 6d001c2..e745bef 100644
5544c1
--- a/target-xtensa/xtensa-semi.c
5544c1
+++ b/target-xtensa/xtensa-semi.c
5544c1
@@ -54,6 +54,96 @@ enum {
5544c1
     SELECT_ONE_EXCEPT = 3,
5544c1
 };
5544c1
 
5544c1
+enum {
5544c1
+    TARGET_EPERM        =  1,
5544c1
+    TARGET_ENOENT       =  2,
5544c1
+    TARGET_ESRCH        =  3,
5544c1
+    TARGET_EINTR        =  4,
5544c1
+    TARGET_EIO          =  5,
5544c1
+    TARGET_ENXIO        =  6,
5544c1
+    TARGET_E2BIG        =  7,
5544c1
+    TARGET_ENOEXEC      =  8,
5544c1
+    TARGET_EBADF        =  9,
5544c1
+    TARGET_ECHILD       = 10,
5544c1
+    TARGET_EAGAIN       = 11,
5544c1
+    TARGET_ENOMEM       = 12,
5544c1
+    TARGET_EACCES       = 13,
5544c1
+    TARGET_EFAULT       = 14,
5544c1
+    TARGET_ENOTBLK      = 15,
5544c1
+    TARGET_EBUSY        = 16,
5544c1
+    TARGET_EEXIST       = 17,
5544c1
+    TARGET_EXDEV        = 18,
5544c1
+    TARGET_ENODEV       = 19,
5544c1
+    TARGET_ENOTDIR      = 20,
5544c1
+    TARGET_EISDIR       = 21,
5544c1
+    TARGET_EINVAL       = 22,
5544c1
+    TARGET_ENFILE       = 23,
5544c1
+    TARGET_EMFILE       = 24,
5544c1
+    TARGET_ENOTTY       = 25,
5544c1
+    TARGET_ETXTBSY      = 26,
5544c1
+    TARGET_EFBIG        = 27,
5544c1
+    TARGET_ENOSPC       = 28,
5544c1
+    TARGET_ESPIPE       = 29,
5544c1
+    TARGET_EROFS        = 30,
5544c1
+    TARGET_EMLINK       = 31,
5544c1
+    TARGET_EPIPE        = 32,
5544c1
+    TARGET_EDOM         = 33,
5544c1
+    TARGET_ERANGE       = 34,
5544c1
+    TARGET_ENOSYS       = 88,
5544c1
+    TARGET_ELOOP        = 92,
5544c1
+};
5544c1
+
5544c1
+static uint32_t errno_h2g(int host_errno)
5544c1
+{
5544c1
+    static const uint32_t guest_errno[] = {
5544c1
+        [EPERM]         = TARGET_EPERM,
5544c1
+        [ENOENT]        = TARGET_ENOENT,
5544c1
+        [ESRCH]         = TARGET_ESRCH,
5544c1
+        [EINTR]         = TARGET_EINTR,
5544c1
+        [EIO]           = TARGET_EIO,
5544c1
+        [ENXIO]         = TARGET_ENXIO,
5544c1
+        [E2BIG]         = TARGET_E2BIG,
5544c1
+        [ENOEXEC]       = TARGET_ENOEXEC,
5544c1
+        [EBADF]         = TARGET_EBADF,
5544c1
+        [ECHILD]        = TARGET_ECHILD,
5544c1
+        [EAGAIN]        = TARGET_EAGAIN,
5544c1
+        [ENOMEM]        = TARGET_ENOMEM,
5544c1
+        [EACCES]        = TARGET_EACCES,
5544c1
+        [EFAULT]        = TARGET_EFAULT,
5544c1
+        [ENOTBLK]       = TARGET_ENOTBLK,
5544c1
+        [EBUSY]         = TARGET_EBUSY,
5544c1
+        [EEXIST]        = TARGET_EEXIST,
5544c1
+        [EXDEV]         = TARGET_EXDEV,
5544c1
+        [ENODEV]        = TARGET_ENODEV,
5544c1
+        [ENOTDIR]       = TARGET_ENOTDIR,
5544c1
+        [EISDIR]        = TARGET_EISDIR,
5544c1
+        [EINVAL]        = TARGET_EINVAL,
5544c1
+        [ENFILE]        = TARGET_ENFILE,
5544c1
+        [EMFILE]        = TARGET_EMFILE,
5544c1
+        [ENOTTY]        = TARGET_ENOTTY,
5544c1
+        [ETXTBSY]       = TARGET_ETXTBSY,
5544c1
+        [EFBIG]         = TARGET_EFBIG,
5544c1
+        [ENOSPC]        = TARGET_ENOSPC,
5544c1
+        [ESPIPE]        = TARGET_ESPIPE,
5544c1
+        [EROFS]         = TARGET_EROFS,
5544c1
+        [EMLINK]        = TARGET_EMLINK,
5544c1
+        [EPIPE]         = TARGET_EPIPE,
5544c1
+        [EDOM]          = TARGET_EDOM,
5544c1
+        [ERANGE]        = TARGET_ERANGE,
5544c1
+        [ENOSYS]        = TARGET_ENOSYS,
5544c1
+        [ELOOP]         = TARGET_ELOOP,
5544c1
+    };
5544c1
+
5544c1
+    if (host_errno == 0) {
5544c1
+        return 0;
5544c1
+    } else if (host_errno > 0 && host_errno < ARRAY_SIZE(guest_errno) &&
5544c1
+            guest_errno[host_errno]) {
5544c1
+        return guest_errno[host_errno];
5544c1
+    } else {
5544c1
+        return TARGET_EINVAL;
5544c1
+    }
5544c1
+}
5544c1
+
5544c1
 void HELPER(simcall)(CPUXtensaState *env)
5544c1
 {
5544c1
     uint32_t *regs = env->regs;
5544c1
@@ -87,14 +177,14 @@ void HELPER(simcall)(CPUXtensaState *env)
5544c1
                     regs[2] = is_write ?
5544c1
                         write(fd, buf, io_sz) :
5544c1
                         read(fd, buf, io_sz);
5544c1
-                    regs[3] = errno;
5544c1
+                    regs[3] = errno_h2g(errno);
5544c1
                     cpu_physical_memory_unmap(buf, sz, is_write, sz);
5544c1
                     if (regs[2] == -1) {
5544c1
                         break;
5544c1
                     }
5544c1
                 } else {
5544c1
                     regs[2] = -1;
5544c1
-                    regs[3] = EINVAL;
5544c1
+                    regs[3] = TARGET_EINVAL;
5544c1
                     break;
5544c1
                 }
5544c1
             }
5544c1
@@ -117,10 +207,10 @@ void HELPER(simcall)(CPUXtensaState *env)
5544c1
 
5544c1
             if (rc == 0 && i < ARRAY_SIZE(name)) {
5544c1
                 regs[2] = open(name, regs[4], regs[5]);
5544c1
-                regs[3] = errno;
5544c1
+                regs[3] = errno_h2g(errno);
5544c1
             } else {
5544c1
                 regs[2] = -1;
5544c1
-                regs[3] = EINVAL;
5544c1
+                regs[3] = TARGET_EINVAL;
5544c1
             }
5544c1
         }
5544c1
         break;
5544c1
@@ -130,13 +220,13 @@ void HELPER(simcall)(CPUXtensaState *env)
5544c1
             regs[2] = regs[3] = 0;
5544c1
         } else {
5544c1
             regs[2] = close(regs[3]);
5544c1
-            regs[3] = errno;
5544c1
+            regs[3] = errno_h2g(errno);
5544c1
         }
5544c1
         break;
5544c1
 
5544c1
     case TARGET_SYS_lseek:
5544c1
         regs[2] = lseek(regs[3], (off_t)(int32_t)regs[4], regs[5]);
5544c1
-        regs[3] = errno;
5544c1
+        regs[3] = errno_h2g(errno);
5544c1
         break;
5544c1
 
5544c1
     case TARGET_SYS_select_one:
5544c1
@@ -163,7 +253,7 @@ void HELPER(simcall)(CPUXtensaState *env)
5544c1
                     rq == SELECT_ONE_WRITE  ? &fdset : NULL,
5544c1
                     rq == SELECT_ONE_EXCEPT ? &fdset : NULL,
5544c1
                     target_tv ? &tv : NULL);
5544c1
-            regs[3] = errno;
5544c1
+            regs[3] = errno_h2g(errno);
5544c1
         }
5544c1
         break;
5544c1
 
5544c1
@@ -219,7 +309,7 @@ void HELPER(simcall)(CPUXtensaState *env)
5544c1
     default:
5544c1
         qemu_log("%s(%d): not implemented\n", __func__, regs[2]);
5544c1
         regs[2] = -1;
5544c1
-        regs[3] = ENOSYS;
5544c1
+        regs[3] = TARGET_ENOSYS;
5544c1
         break;
5544c1
     }
5544c1
 }