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