#ifdef __NR_gettid
_syscall0(int, gettid)
#else
+/* This is a replacement for the host gettid() and must return a host
+ errno. */
static int gettid(void) {
return -ENOSYS;
}
target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
}
+/* do_brk() must return target values and target errnos. */
abi_long do_brk(abi_ulong new_brk)
{
abi_ulong brk_page;
if (!new_brk)
return target_brk;
if (new_brk < target_original_brk)
- return -ENOMEM;
+ return -TARGET_ENOMEM;
brk_page = HOST_PAGE_ALIGN(target_brk);
}
+/* do_select() must return target values and target errnos. */
static abi_long do_select(int n,
abi_ulong rfd_p, abi_ulong wfd_p,
abi_ulong efd_p, abi_ulong target_tv)
msgh->msg_controllen = tswapl(space);
}
+/* do_setsockopt() Must return target values and target errnos. */
static abi_long do_setsockopt(int sockfd, int level, int optname,
abi_ulong optval, socklen_t optlen)
{
case SOL_TCP:
/* TCP options all take an 'int' value. */
if (optlen < sizeof(uint32_t))
- return -EINVAL;
+ return -TARGET_EINVAL;
val = tget32(optval);
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
goto unimplemented;
}
if (optlen < sizeof(uint32_t))
- return -EINVAL;
+ return -TARGET_EINVAL;
val = tget32(optval);
ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
default:
unimplemented:
gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
}
return ret;
}
+/* do_getsockopt() Must return target values and target errnos. */
static abi_long do_getsockopt(int sockfd, int level, int optname,
abi_ulong optval, abi_ulong optlen)
{
int_case:
len = tget32(optlen);
if (len < 0)
- return -EINVAL;
+ return -TARGET_EINVAL;
lv = sizeof(int);
ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
if (ret < 0)
case IP_MULTICAST_LOOP:
len = tget32(optlen);
if (len < 0)
- return -EINVAL;
+ return -TARGET_EINVAL;
lv = sizeof(int);
ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
if (ret < 0)
unimplemented:
gemu_log("getsockopt level=%d optname=%d not yet supported\n",
level, optname);
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
break;
}
return ret;
unlock_user (target_vec, target_addr, 0);
}
+/* do_socket() Must return target values and target errnos. */
static abi_long do_socket(int domain, int type, int protocol)
{
#if defined(TARGET_MIPS)
return get_errno(socket(domain, type, protocol));
}
+/* do_bind() Must return target values and target errnos. */
static abi_long do_bind(int sockfd, abi_ulong target_addr,
socklen_t addrlen)
{
return get_errno(bind(sockfd, addr, addrlen));
}
+/* do_connect() Must return target values and target errnos. */
static abi_long do_connect(int sockfd, abi_ulong target_addr,
socklen_t addrlen)
{
return get_errno(connect(sockfd, addr, addrlen));
}
+/* do_sendrecvmsg() Must return target values and target errnos. */
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
int flags, int send)
{
return ret;
}
+/* do_accept() Must return target values and target errnos. */
static abi_long do_accept(int fd, abi_ulong target_addr,
abi_ulong target_addrlen)
{
return ret;
}
+/* do_getpeername() Must return target values and target errnos. */
static abi_long do_getpeername(int fd, abi_ulong target_addr,
abi_ulong target_addrlen)
{
return ret;
}
+/* do_getsockname() Must return target values and target errnos. */
static abi_long do_getsockname(int fd, abi_ulong target_addr,
abi_ulong target_addrlen)
{
return ret;
}
+/* do_socketpair() Must return target values and target errnos. */
static abi_long do_socketpair(int domain, int type, int protocol,
abi_ulong target_tab)
{
return ret;
}
+/* do_sendto() Must return target values and target errnos. */
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
abi_ulong target_addr, socklen_t addrlen)
{
return ret;
}
+/* do_recvfrom() Must return target values and target errnos. */
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
abi_ulong target_addr,
abi_ulong target_addrlen)
}
#ifdef TARGET_NR_socketcall
+/* do_socketcall() Must return target values and target errnos. */
static abi_long do_socketcall(int num, abi_ulong vptr)
{
abi_long ret;
break;
default:
gemu_log("Unsupported socketcall: %d\n", num);
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
break;
}
return ret;
}
/* ??? This only works with linear mappings. */
+/* do_ipc() must return target values and target errnos. */
static abi_long do_ipc(unsigned int call, int first,
int second, int third,
abi_long ptr, abi_long fifth)
case IPCOP_semtimedop:
gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
break;
case IPCOP_msgget:
}
}
if (put_user(raddr, (abi_ulong *)third))
- return -EFAULT;
+ return -TARGET_EFAULT;
ret = 0;
break;
case IPCOP_shmdt:
default:
unimplemented:
gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
break;
}
return ret;
};
/* ??? Implement proper locking for ioctls. */
+/* do_ioctl() Must return target values and target errnos. */
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
{
const IOCTLEntry *ie;
for(;;) {
if (ie->target_cmd == 0) {
gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
- return -ENOSYS;
+ return -TARGET_ENOSYS;
}
if (ie->target_cmd == cmd)
break;
default:
gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
(long)cmd, arg_type[0]);
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
break;
}
return ret;
}
/* XXX: add locking support */
+/* write_ldt() returns host errnos */
static int write_ldt(CPUX86State *env,
abi_ulong ptr, unsigned long bytecount, int oldmode)
{
}
/* specific and weird i386 syscalls */
+/* do_modify_ldt() returns host errnos (it is inconsistent with the
+ other do_*() functions which return target errnos). */
int do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, unsigned long bytecount)
{
int ret = -ENOSYS;
return 0;
}
+/* do_fork() Must return host values and target errnos (unlike most
+ do_*() functions). */
int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
{
int ret;
unlock_user_struct(target_ts, target_addr, 1);
}
+/* do_syscall() should always have a single exit point at the end so
+ that actions, such as logging of syscall results, can be performed.
+ All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6)
#if defined(TARGET_NR_openat) && defined(__NR_openat)
case TARGET_NR_openat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_openat(arg1,
path(p),
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
case TARGET_NR_linkat:
if (!arg2 || !arg4) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
- }
+ }
{
void * p2 = NULL;
p = lock_user_string(arg2);
p2 = lock_user_string(arg4);
if (!access_ok(VERIFY_READ, p, 1)
|| !access_ok(VERIFY_READ, p2, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
if (p2)
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
case TARGET_NR_unlinkat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_unlinkat(arg1, p, arg3));
if (p)
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
case TARGET_NR_mknodat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
if (p)
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
case TARGET_NR_faccessat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
if (p)
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
case TARGET_NR_renameat:
if (!arg2 || !arg4) {
- ret = -EFAULT;
- goto fail;
+ ret = -TARGET_EFAULT;
+ goto fail;
}
{
void *p2 = NULL;
p2 = lock_user_string(arg4);
if (!access_ok(VERIFY_READ, p, 1)
|| !access_ok(VERIFY_READ, p2, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_renameat(arg1, p, arg3, p2));
if (p2)
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
case TARGET_NR_mkdirat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_mkdirat(arg1, p, arg3));
if (p)
how = SIG_SETMASK;
break;
default:
- ret = -EINVAL;
+ ret = -TARGET_EINVAL;
goto fail;
}
p = lock_user(arg2, sizeof(target_sigset_t), 1);
how = SIG_SETMASK;
break;
default:
- ret = -EINVAL;
+ ret = -TARGET_EINVAL;
goto fail;
}
p = lock_user(arg2, sizeof(target_sigset_t), 1);
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
case TARGET_NR_symlinkat:
if (!arg1 || !arg3) {
- ret = -EFAULT;
- goto fail;
- }
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
{
void *p2 = NULL;
p = lock_user_string(arg1);
p2 = lock_user_string(arg3);
if (!access_ok(VERIFY_READ, p, 1)
|| !access_ok(VERIFY_READ, p2, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_symlinkat(p, arg2, p2));
if (p2)
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
case TARGET_NR_readlinkat:
if (!arg2 || !arg3) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
- }
+ }
{
void *p2 = NULL;
p = lock_user_string(arg2);
p2 = lock_user(arg3, arg4, 0);
if (!access_ok(VERIFY_READ, p, 1)
|| !access_ok(VERIFY_READ, p2, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
if (p2)
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
case TARGET_NR_fchmodat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
if (p)
abi_long count = arg3;
dirp = malloc(count);
- if (!dirp)
- return -ENOMEM;
+ if (!dirp) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) {
break;
#endif
case TARGET_NR__sysctl:
- /* We don't implement this, but ENODIR is always a safe
+ /* We don't implement this, but ENOTDIR is always a safe
return value. */
- return -ENOTDIR;
+ ret = -TARGET_ENOTDIR;
+ break;
case TARGET_NR_sched_setparam:
{
struct sched_param *target_schp;
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
case TARGET_NR_fchownat:
if (!arg2) {
- ret = -EFAULT;
+ ret = -TARGET_EFAULT;
goto fail;
}
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
if (p)
else {
p = lock_user_string(arg2);
if (!access_ok(VERIFY_READ, p, 1))
- ret = -EFAULT;
+ /* Don't "goto fail" so that cleanup can happen. */
+ ret = -TARGET_EFAULT;
else
ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
if (p)
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
unimplemented_nowarn:
#endif
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
break;
}
fail: