ports/emulators/qemu-devel/files/patch-z9b-bsd-user-sson003b
Juergen Lock 45aa9370f0 - Update net/usbredir to 0.6 .
- Update emulators/qemu-devel to 1.4.0 with preliminary bsd-user patches.

Thanx to:	sson, cognet, and others for much improved bsd-user support -
		it now runs at least quite a few mips64 and single-threaded
		arm binaries, see:

	https://wiki.freebsd.org/QemuUserModeHowTo
2013-03-29 17:40:38 +00:00

332 lines
11 KiB
Text

diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h
index 0427244..24dca00 100644
--- a/bsd-user/arm/target_vmparam.h
+++ b/bsd-user/arm/target_vmparam.h
@@ -20,6 +20,10 @@ struct target_ps_strings {
#define TARGET_SZSIGCODE 0
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
#else
#define TARGET_USRSTACK 0
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 0c48f5a..f5f652f 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -715,9 +715,13 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
/* Create enough stack to hold everything. If we don't use
* it for args, we'll use it for something else...
*/
+#ifdef TARGET_STACK_SIZE
+ size = TARGET_STACK_SIZE;
+#else
size = x86_stack_size;
if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
+#endif
#ifdef TARGET_USRSTACK
stack_base = TARGET_USRSTACK - size;
@@ -738,7 +742,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
#if defined(__FreeBSD__)
/*
- * The inital FreeBSD stack looks like follows:
+ * The inital FreeBSD stack is as follows:
* (see kern/kern_exec.c exec_copyout_strings() )
*
* Hi Address -> char **ps_argvstr (struct ps_strings for ps, w, etc.)
diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
index bcdd931..c66dcfa 100644
--- a/bsd-user/freebsd/strace.list
+++ b/bsd-user/freebsd/strace.list
@@ -118,6 +118,7 @@
{ TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL },
{ TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
diff --git a/bsd-user/i386/target_vmparam.h b/bsd-user/i386/target_vmparam.h
index 8fc98d5..ea7546c 100644
--- a/bsd-user/i386/target_vmparam.h
+++ b/bsd-user/i386/target_vmparam.h
@@ -19,6 +19,10 @@ struct target_ps_strings {
#define TARGET_SZSIGCODE 0
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
#else
#define TARGET_USRSTACK 0
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 7cc77aa..32bd3e5 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -855,7 +855,9 @@ void cpu_loop(CPUARMState *env)
goto do_segv;
}
break;
+#if 0
error:
+#endif
default:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h
index 9fca7f3..8abc26c 100644
--- a/bsd-user/mips/target_vmparam.h
+++ b/bsd-user/mips/target_vmparam.h
@@ -21,6 +21,10 @@ struct target_ps_strings {
#define TARGET_SZSIGCODE 0
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
#else
#define TARGET_USRSTACK 0
diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h
index 47c2267..55ed254 100644
--- a/bsd-user/mips64/target_vmparam.h
+++ b/bsd-user/mips64/target_vmparam.h
@@ -20,6 +20,10 @@ struct target_ps_strings {
#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings))
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
#else
#define TARGET_USRSTACK 0
diff --git a/bsd-user/sparc/target_vmparam.h b/bsd-user/sparc/target_vmparam.h
index 9494c46..82c29ed 100644
--- a/bsd-user/sparc/target_vmparam.h
+++ b/bsd-user/sparc/target_vmparam.h
@@ -1,8 +1,6 @@
#ifndef _TARGET_VMPARAM_H_
#define _TARGET_VMPARAM_H_
-#define TARGET_USRSTACK 0
-
#ifdef __FreeBSD__
struct target_ps_strings {
abi_ulong ps_argvstr;
@@ -14,9 +12,22 @@ struct target_ps_strings {
#define TARGET_SPACE_USRSPACE 4096
#define TARGET_ARG_MAX 262144
+/* XXX */
+#define TARGET_VM_MAXUSER_ADDRESS (0xc0000000 - (512 * 1024 * 1024))
+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS
+
#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings))
#define TARGET_SZSIGCODE 0
+
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
+#else
+
+#define TARGET_USRSTACK 0
+
#endif /* __FreeBSD__ */
#endif /* _TARGET_VMPARAM_H_ */
diff --git a/bsd-user/sparc64/target_vmparam.h b/bsd-user/sparc64/target_vmparam.h
index 12af063..7f2b464 100644
--- a/bsd-user/sparc64/target_vmparam.h
+++ b/bsd-user/sparc64/target_vmparam.h
@@ -21,6 +21,10 @@ struct target_ps_strings {
#define TARGET_SZSIGCODE 0
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
#else
#define TARGET_USRSTACK 0
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index a40d7ce..8565ae8 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -409,19 +409,44 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++)
*q++ = tswap32(*p);
oidfmt(snamep, namelen, NULL, &kind);
- /* XXX swap hnewp */
-#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
- /* XXX there may be more sysctls that differ */
- if (namelen == 2 &&
- snamep[0] == CTL_KERN && snamep[1] == KERN_USRSTACK &&
- holdlen && holdlen == 4 && hnewp == NULL) {
- (*(uint32_t *)holdp) = 0xfffff000U;
- ret = 0;
- } else
+
+ /* Handle some arch/emulator dependent sysctl()'s here. */
+ if (CTL_KERN == snamep[0]) {
+ switch(snamep[1]) {
+ case KERN_USRSTACK:
+#if defined(TARGET_ARM) && HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
+ (*(uint32_t *)holdp) = 0xfffff000U;
+ holdlen = sizeof(uint32_t);
+ ret = 0;
+#elif TARGET_USRSTACK != 0
+ (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK);
+ holdlen = sizeof(abi_ulong);
+ ret = 0;
+#else
+ ret = -TARGET_ENOENT;
+#endif
+ goto out;
+
+ case KERN_PS_STRINGS:
+#if defined(TARGET_PS_STRINGS)
+ (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS);
+ holdlen = sizeof(abi_ulong);
+ ret = 0;
+#else
+ ret = -TARGET_ENOENT;
#endif
+ goto out;
+
+ default:
+ break;
+ }
+ }
+
ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
if (!ret)
sysctl_oldcvt(holdp, holdlen, kind);
+
+out:
put_user_ual(holdlen, oldlenp);
unlock_user(hnamep, namep, 0);
unlock_user(holdp, oldp, holdlen);
@@ -3293,6 +3318,47 @@ host_to_target_fhandle(abi_ulong target_addr, fhandle_t *host_fh)
}
static inline abi_long
+target_to_host_rtprio(struct rtprio *host_rtp, abi_ulong target_addr)
+{
+ struct target_rtprio *target_rtp;
+
+ if (!lock_user_struct(VERIFY_READ, target_rtp, target_addr, 1))
+ return (-TARGET_EFAULT);
+ __get_user(host_rtp->type, &target_rtp->type);
+ __get_user(host_rtp->prio, &target_rtp->prio);
+ unlock_user_struct(target_rtp, target_addr, 0);
+ return (0);
+}
+
+static inline abi_long
+host_to_target_rtprio(abi_ulong target_addr, struct rtprio *host_rtp)
+{
+ struct target_rtprio *target_rtp;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_rtp, target_addr, 0))
+ return (-TARGET_EFAULT);
+ __put_user(host_rtp->type, &target_rtp->type);
+ __put_user(host_rtp->prio, &target_rtp->prio);
+ unlock_user_struct(target_rtp, target_addr, 1);
+ return (0);
+}
+
+static inline abi_long
+do_rtprio_thread(int function, lwpid_t lwpid, abi_ulong target_addr)
+{
+ int ret;
+ struct rtprio rtp;
+
+ ret = target_to_host_rtprio(&rtp, target_addr);
+ if (0 == ret)
+ ret = get_errno(rtprio_thread(function, lwpid, &rtp));
+ if (0 == ret)
+ ret = host_to_target_rtprio(target_addr, &rtp);
+
+ return (ret);
+}
+
+static inline abi_long
target_to_host_sched_param(struct sched_param *host_sp, abi_ulong target_addr)
{
struct target_sched_param *target_sp;
@@ -4617,12 +4683,17 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
struct target_rlimit *target_rlim;
struct rlimit rlim;
- if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
- goto efault;
- rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
- rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
- unlock_user_struct(target_rlim, arg2, 0);
- ret = get_errno(setrlimit(resource, &rlim));
+ if (RLIMIT_STACK == resource) {
+ /* XXX We should, maybe, allow the stack size to shrink */
+ ret = -TARGET_EPERM;
+ } else {
+ if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
+ goto efault;
+ rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
+ rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
+ unlock_user_struct(target_rlim, arg2, 0);
+ ret = get_errno(setrlimit(resource, &rlim));
+ }
}
break;
@@ -4633,7 +4704,12 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
struct target_rlimit *target_rlim;
struct rlimit rlim;
- ret = get_errno(getrlimit(resource, &rlim));
+ /* Return the target stack size */
+ if (RLIMIT_STACK == resource) {
+ rlim.rlim_cur = rlim.rlim_max = TARGET_STACK_SIZE;
+ ret = 0;
+ } else
+ ret = get_errno(getrlimit(resource, &rlim));
if (!is_error(ret)) {
if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2,
0))
@@ -6148,7 +6224,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
break;
case TARGET_FREEBSD_NR_rtprio_thread:
- ret = 0;
+ ret = do_rtprio_thread(arg1, arg2, arg3);
break;
case TARGET_FREEBSD_NR_getcontext:
diff --git a/bsd-user/x86_64/target_vmparam.h b/bsd-user/x86_64/target_vmparam.h
index aa5e0e0..ff9f534 100644
--- a/bsd-user/x86_64/target_vmparam.h
+++ b/bsd-user/x86_64/target_vmparam.h
@@ -20,6 +20,10 @@ struct target_ps_strings {
#define TARGET_SZSIGCODE 0
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
#else
#define TARGET_USRSTACK 0