virtualization/app-emulation/qemu/files/qemu-arm-eabi-0.10.5.patch

621 lines
21 KiB
Diff

diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/ioctls.h ./linux-user/ioctls.h
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/ioctls.h 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/ioctls.h 2009-07-17 08:28:45.000000000 +0200
@@ -74,7 +74,7 @@
IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
#endif
- IOCTL(SIOCATMARK, 0, TYPE_NULL)
+ IOCTL(SIOCATMARK, 0, MK_PTR(TYPE_INT))
IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/main.c ./linux-user/main.c
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/main.c 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/main.c 2009-07-17 08:29:22.000000000 +0200
@@ -1004,7 +1004,7 @@
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
- exit (1);
+ _exit (1);
}
process_pending_signals (env);
}
@@ -1933,7 +1933,7 @@
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
- exit (1);
+ _exit (1);
}
process_pending_signals (env);
}
@@ -2240,6 +2240,7 @@
TaskState ts1, *ts = &ts1;
CPUState *env;
int optind;
+ int argskip=0;
const char *r;
int gdbstub_port = 0;
char **target_environ, **wrk;
@@ -2289,7 +2290,7 @@
for(item = cpu_log_items; item->mask != 0; item++) {
printf("%-10s %s\n", item->name, item->help);
}
- exit(1);
+ _exit(1);
}
cpu_set_log(mask);
} else if (!strcmp(r, "E")) {
@@ -2320,8 +2321,10 @@
if (qemu_host_page_size == 0 ||
(qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
fprintf(stderr, "page size must be a power of two\n");
- exit(1);
+ _exit(1);
}
+ } else if (!strcmp(r,"-sbox-call")) {
+ argskip++;
} else if (!strcmp(r, "g")) {
if (optind >= argc)
break;
@@ -2368,7 +2371,7 @@
cpu_model = "qemu32";
#endif
#elif defined(TARGET_ARM)
- cpu_model = "arm926";
+ cpu_model = "any";
#elif defined(TARGET_M68K)
cpu_model = "any";
#elif defined(TARGET_SPARC)
@@ -2410,7 +2413,7 @@
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
- if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+ if (loader_exec(filename, argv+optind+argskip, target_environ, regs, info) != 0) {
printf("Error loading %s\n", filename);
_exit(1);
}
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/signal.c ./linux-user/signal.c
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/signal.c 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/signal.c 2009-07-17 08:28:54.000000000 +0200
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <signal.h>
#include <errno.h>
+#include <assert.h>
#include <sys/ucontext.h>
#include "qemu.h"
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall.c ./linux-user/syscall.c
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall.c 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/syscall.c 2009-07-17 08:28:51.000000000 +0200
@@ -44,12 +44,14 @@
#include <sched.h>
#include <sys/socket.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <sys/poll.h>
#include <sys/times.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
#include <utime.h>
+#include <sys/sysctl.h>
#include <sys/sysinfo.h>
//#include <sys/user.h>
#include <netinet/ip.h>
@@ -299,6 +301,7 @@
extern int setfsuid(int);
extern int setfsgid(int);
extern int setgroups(int, gid_t *);
+extern int uselib(const char*);
#define ERRNO_TABLE_SIZE 1200
@@ -690,14 +693,17 @@
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
abi_ulong target_addr,
- socklen_t len)
+ socklen_t *target_len)
{
+ const socklen_t len = sizeof (struct sockaddr_un);
struct target_sockaddr *target_saddr;
- target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
+ target_saddr = lock_user(VERIFY_READ, target_addr, *target_len, 1);
if (!target_saddr)
return -TARGET_EFAULT;
- memcpy(addr, target_saddr, len);
+ if (target_saddr->sa_family == AF_UNIX && *target_len > len)
+ *target_len = len;
+ memcpy(addr, target_saddr, *target_len);
addr->sa_family = tswap16(target_saddr->sa_family);
unlock_user(target_saddr, target_addr, 0);
@@ -833,6 +839,32 @@
return 0;
}
+static inline abi_long host_to_target_linger(target_ulong target_addr,
+ struct linger *host_l)
+{
+ struct target_linger *target_l;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_l, target_addr, 0))
+ return -TARGET_EFAULT;
+ target_l->l_onoff = tswapl(host_l->l_onoff);
+ target_l->l_linger = tswapl(host_l->l_linger);
+ unlock_user_struct(target_l, target_addr, 1);
+ return 0;
+}
+
+static inline abi_long target_to_host_linger(struct linger *host_l,
+ target_ulong target_addr)
+{
+ struct target_linger *target_l;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_l, target_addr, 1))
+ return -TARGET_EFAULT;
+ host_l->l_onoff = tswapl(target_l->l_onoff);
+ host_l->l_linger = tswapl(target_l->l_linger);
+ unlock_user_struct(target_l, target_addr, 0);
+ return 0;
+}
+
/* do_setsockopt() Must return target values and target errnos. */
static abi_long do_setsockopt(int sockfd, int level, int optname,
abi_ulong optval_addr, socklen_t optlen)
@@ -883,7 +915,6 @@
break;
case TARGET_SOL_SOCKET:
switch (optname) {
- /* Options with 'int' argument. */
case TARGET_SO_DEBUG:
optname = SO_DEBUG;
break;
@@ -940,16 +971,44 @@
case TARGET_SO_SNDTIMEO:
optname = SO_SNDTIMEO;
break;
- break;
+ case TARGET_SO_LINGER:
+ optname = SO_LINGER;
+ break;
default:
goto unimplemented;
}
- if (optlen < sizeof(uint32_t))
- return -TARGET_EINVAL;
-
- if (get_user_u32(val, optval_addr))
- return -TARGET_EFAULT;
- ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
+ switch (optname) {
+ /* Options with non-'int' argument. */
+ case SO_RCVTIMEO:
+ case SO_SNDTIMEO:
+ {
+ struct timeval tval;
+ if(optlen < sizeof(struct target_timeval))
+ return -TARGET_EINVAL;
+ copy_from_user_timeval(&tval,optval_addr);
+ ret = get_errno(setsockopt(sockfd, level, optname, &tval,sizeof(tval)));
+ }
+ break;
+ case SO_LINGER:
+ {
+ struct linger tmp;
+ if (optlen < sizeof(struct target_linger))
+ return -TARGET_EINVAL;
+ optname = SO_LINGER;
+ target_to_host_linger(&tmp,optval_addr);
+ ret = get_errno(setsockopt(sockfd, level, optname, &tmp, sizeof(tmp)));
+ }
+ break;
+ /* All remaning options take an 'int' argument. */
+ default:
+ {
+ if (optlen < sizeof(uint32_t))
+ return -TARGET_EINVAL;
+ val = get_user_u32(val, optval_addr);
+ ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
+ }
+ break;
+ }
break;
default:
unimplemented:
@@ -971,10 +1030,55 @@
case TARGET_SOL_SOCKET:
level = SOL_SOCKET;
switch (optname) {
- case TARGET_SO_LINGER:
+ case TARGET_SO_LINGER: {
+ if (get_user_u32(len, optlen))
+ return -TARGET_EFAULT;
+ if(len < sizeof(struct target_linger))
+ return -TARGET_EINVAL;
+ struct linger l;
+ len=sizeof(l);
+
+ ret = get_errno(getsockopt(sockfd, level, optname, &l, &len));
+ host_to_target_linger(optval_addr,&l);
+ if (put_user_u32(sizeof(struct target_linger), optlen))
+ return -TARGET_EFAULT;
+ }
+ break;
+
case TARGET_SO_RCVTIMEO:
- case TARGET_SO_SNDTIMEO:
- case TARGET_SO_PEERCRED:
+ case TARGET_SO_SNDTIMEO: {
+ if (get_user_u32(len, optlen))
+ return -TARGET_EFAULT;
+
+ if(len < sizeof(struct target_timeval))
+ return -TARGET_EINVAL;
+ struct timeval tval;
+ len=sizeof(tval);
+
+ ret = get_errno(getsockopt(sockfd, level, optname, &tval, &len));
+ if (copy_to_user_timeval(optval_addr,&tval))
+ return -TARGET_EFAULT;
+
+ if (put_user_u32(sizeof(struct target_timeval), optlen))
+ return -TARGET_EFAULT;
+ }
+ break;
+
+ case TARGET_SO_PEERCRED: {
+ struct ucred caller;
+ socklen_t optlen = sizeof (caller);
+ ret = get_errno(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED,
+ &caller, &optlen));
+
+ if (optlen != 0 && optval_addr != 0) {
+ if (put_user_u32(caller.pid, optval_addr + 0) ||
+ put_user_u32(caller.uid, optval_addr + 4) ||
+ put_user_u32(caller.gid, optval_addr + 8))
+ return -TARGET_EFAULT;
+ }
+ }
+ break;
+
case TARGET_SO_PEERNAME:
/* These don't just return a single integer */
goto unimplemented;
@@ -1154,7 +1258,7 @@
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ target_to_host_sockaddr(addr, target_addr, &addrlen);
return get_errno(bind(sockfd, addr, addrlen));
}
@@ -1169,7 +1273,7 @@
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ target_to_host_sockaddr(addr, target_addr, &addrlen);
return get_errno(connect(sockfd, addr, addrlen));
}
@@ -1193,8 +1297,10 @@
if (msgp->msg_name) {
msg.msg_namelen = tswap32(msgp->msg_namelen);
msg.msg_name = alloca(msg.msg_namelen);
- target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
- msg.msg_namelen);
+ ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
+ &msg.msg_namelen);
+ if (is_error(ret))
+ goto fail;
} else {
msg.msg_name = NULL;
msg.msg_namelen = 0;
@@ -1224,6 +1330,7 @@
}
}
unlock_iovec(vec, target_vec, count, !send);
+fail:
unlock_user_struct(msgp, target_msg, send ? 0 : 1);
return ret;
}
@@ -1237,7 +1344,10 @@
abi_long ret;
if (get_user_u32(addrlen, target_addrlen_addr))
- return -TARGET_EFAULT;
+ return -TARGET_EINVAL;
+
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
+ return -TARGET_EINVAL;
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
return -TARGET_EINVAL;
@@ -1267,12 +1377,15 @@
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
return -TARGET_EINVAL;
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
+ return -TARGET_EINVAL;
+
addr = alloca(addrlen);
ret = get_errno(getpeername(fd, addr, &addrlen));
if (!is_error(ret)) {
- host_to_target_sockaddr(target_addr, addr, addrlen);
- if (put_user_u32(addrlen, target_addrlen_addr))
+ if ((host_to_target_sockaddr(target_addr, addr, addrlen) < 0) ||
+ (put_user_u32(addrlen, target_addrlen_addr)))
ret = -TARGET_EFAULT;
}
return ret;
@@ -1299,8 +1412,8 @@
ret = get_errno(getsockname(fd, addr, &addrlen));
if (!is_error(ret)) {
- host_to_target_sockaddr(target_addr, addr, addrlen);
- if (put_user_u32(addrlen, target_addrlen_addr))
+ if ((host_to_target_sockaddr(target_addr, addr, addrlen) < 0) ||
+ (put_user_u32(addrlen, target_addrlen_addr)))
ret = -TARGET_EFAULT;
}
return ret;
@@ -1333,13 +1446,17 @@
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
return -TARGET_EINVAL;
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
+ return -TARGET_EINVAL;
+
host_msg = lock_user(VERIFY_READ, msg, len, 1);
if (!host_msg)
return -TARGET_EFAULT;
if (target_addr) {
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
- ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
+ ret = target_to_host_sockaddr(addr, target_addr, &addrlen);
+ if (!is_error(ret))
+ ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
} else {
ret = get_errno(send(fd, host_msg, len, flags));
}
@@ -1369,6 +1486,10 @@
ret = -TARGET_EINVAL;
goto fail;
}
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
+ ret = -TARGET_EINVAL;
+ goto fail;
+ }
addr = alloca(addrlen);
ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
} else {
@@ -2856,6 +2977,7 @@
pthread_cond_t cond;
pthread_t thread;
uint32_t tid;
+ unsigned int flags;
abi_ulong child_tidptr;
abi_ulong parent_tidptr;
sigset_t sigmask;
@@ -2869,9 +2991,11 @@
env = info->env;
thread_env = env;
info->tid = gettid();
- if (info->child_tidptr)
+ if (info->flags & CLONE_CHILD_SETTID)
put_user_u32(info->tid, info->child_tidptr);
- if (info->parent_tidptr)
+ if (info->flags & CLONE_CHILD_CLEARTID)
+ set_tid_address(g2h(info->child_tidptr));
+ if (info->flags & CLONE_PARENT_SETTID)
put_user_u32(info->tid, info->parent_tidptr);
/* Enable signals. */
sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
@@ -2936,7 +3060,6 @@
nptl_flags = flags;
flags &= ~CLONE_NPTL_FLAGS2;
- /* TODO: Implement CLONE_CHILD_CLEARTID. */
if (nptl_flags & CLONE_SETTLS)
cpu_set_tls (new_env, newtls);
@@ -2948,7 +3071,9 @@
pthread_mutex_lock(&info.mutex);
pthread_cond_init(&info.cond, NULL);
info.env = new_env;
- if (nptl_flags & CLONE_CHILD_SETTID)
+ info.flags = nptl_flags;
+ if (nptl_flags & CLONE_CHILD_SETTID ||
+ nptl_flags & CLONE_CHILD_CLEARTID)
info.child_tidptr = child_tidptr;
if (nptl_flags & CLONE_PARENT_SETTID)
info.parent_tidptr = parent_tidptr;
@@ -4446,7 +4571,8 @@
#endif
#ifdef TARGET_NR_uselib
case TARGET_NR_uselib:
- goto unimplemented;
+ ret = get_errno(uselib(path((const char*)arg1)));
+ break;
#endif
#ifdef TARGET_NR_swapon
case TARGET_NR_swapon:
@@ -5191,9 +5317,35 @@
break;
#endif
case TARGET_NR__sysctl:
- /* We don't implement this, but ENOTDIR is always a safe
- return value. */
- ret = -TARGET_ENOTDIR;
+ {
+ struct __sysctl_args *args = (struct __sysctl_args *) arg1;
+ int *name_target, *name, nlen, *oldlenp, oldlen, newlen, i;
+ void *oldval, *newval;
+
+ name_target = (int *) tswapl((long) args->name);
+ nlen = tswapl(args->nlen);
+ oldval = (void *) tswapl((long) args->oldval);
+ oldlenp = (int *) tswapl((long) args->oldlenp);
+ oldlen = tswapl(*oldlenp);
+ newval = (void *) tswapl((long) args->newval);
+ newlen = tswapl(args->newlen);
+
+ name = alloca(nlen * sizeof (int));
+ for (i = 0; i < nlen; i++)
+ name[i] = tswapl(name_target[i]);
+
+ if (nlen == 2 && name[0] == CTL_KERN && name[1] == KERN_VERSION) {
+ ret = get_errno(
+ sysctl(name, nlen, oldval, &oldlen, newval, newlen));
+ if (!is_error(ret)) {
+ *oldlenp = tswapl(oldlen);
+ }
+ } else {
+ gemu_log("qemu: Unsupported sysctl name\n");
+ ret = -ENOSYS;
+ }
+ }
+ break;
break;
case TARGET_NR_sched_setparam:
{
@@ -6051,9 +6203,15 @@
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
case TARGET_NR_utimensat:
{
- struct timespec ts[2];
- target_to_host_timespec(ts, arg3);
- target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
+ struct timespec * ts = NULL;
+
+ if (arg3) {
+ struct timespec ts_[2];
+ ts = ts_;
+ target_to_host_timespec(ts, arg3);
+ target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
+ }
+
if (!arg2)
ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
else {
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall_defs.h ./linux-user/syscall_defs.h
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall_defs.h 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/syscall_defs.h 2009-07-17 08:28:13.000000000 +0200
@@ -114,6 +114,11 @@
abi_long tv_nsec;
};
+struct target_linger {
+ target_long l_onoff;
+ target_long l_linger;
+};
+
struct target_itimerval {
struct target_timeval it_interval;
struct target_timeval it_value;
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/target-arm/translate.c ./target-arm/translate.c
--- /home/ogra/Devel/packages/qemu-0.10.5/target-arm/translate.c 2009-05-20 22:47:00.000000000 +0200
+++ ./target-arm/translate.c 2009-07-17 08:28:13.000000000 +0200
@@ -5757,7 +5757,7 @@
}
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
/* srs */
- uint32_t offset;
+ int32_t offset;
if (IS_USER(s))
goto illegal_op;
ARCH(6);
@@ -5771,8 +5771,8 @@
i = (insn >> 23) & 3;
switch (i) {
case 0: offset = -4; break; /* DA */
- case 1: offset = -8; break; /* DB */
- case 2: offset = 0; break; /* IA */
+ case 1: offset = 0; break; /* IA */
+ case 2: offset = -8; break; /* DB */
case 3: offset = 4; break; /* IB */
default: abort();
}
@@ -5780,32 +5780,33 @@
tcg_gen_addi_i32(addr, addr, offset);
tmp = load_reg(s, 14);
gen_st32(tmp, addr, 0);
- tmp = new_tmp();
- gen_helper_cpsr_read(tmp);
+ tmp = load_cpu_field(spsr);
tcg_gen_addi_i32(addr, addr, 4);
gen_st32(tmp, addr, 0);
if (insn & (1 << 21)) {
/* Base writeback. */
switch (i) {
case 0: offset = -8; break;
- case 1: offset = -4; break;
- case 2: offset = 4; break;
+ case 1: offset = 4; break;
+ case 2: offset = -4; break;
case 3: offset = 0; break;
default: abort();
}
if (offset)
- tcg_gen_addi_i32(addr, tmp, offset);
+ tcg_gen_addi_i32(addr, addr, offset);
if (op1 == (env->uncached_cpsr & CPSR_M)) {
- gen_movl_reg_T1(s, 13);
+ store_reg(s, 13, addr);
} else {
- gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
+ gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), addr);
+ dead_tmp(addr);
}
} else {
dead_tmp(addr);
}
+ return;
} else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
/* rfe */
- uint32_t offset;
+ int32_t offset;
if (IS_USER(s))
goto illegal_op;
ARCH(6);
@@ -5814,8 +5815,8 @@
i = (insn >> 23) & 3;
switch (i) {
case 0: offset = -4; break; /* DA */
- case 1: offset = -8; break; /* DB */
- case 2: offset = 0; break; /* IA */
+ case 1: offset = 0; break; /* IA */
+ case 2: offset = -8; break; /* DB */
case 3: offset = 4; break; /* IB */
default: abort();
}
@@ -5829,8 +5830,8 @@
/* Base writeback. */
switch (i) {
case 0: offset = -8; break;
- case 1: offset = -4; break;
- case 2: offset = 4; break;
+ case 1: offset = 4; break;
+ case 2: offset = -4; break;
case 3: offset = 0; break;
default: abort();
}
@@ -5841,6 +5842,7 @@
dead_tmp(addr);
}
gen_rfe(s, tmp, tmp2);
+ return;
} else if ((insn & 0x0e000000) == 0x0a000000) {
/* branch link and change to thumb (blx <offset>) */
int32_t offset;