svn commit: r316527 - in head/emulators/qemu-devel: . files

Juergen Lock nox at FreeBSD.org
Thu Apr 25 19:34:22 UTC 2013


Author: nox
Date: Thu Apr 25 19:34:20 2013
New Revision: 316527
URL: http://svnweb.freebsd.org/changeset/ports/316527

Log:
  - Update to sson's latest bsd-user patches.
  - Turns out qemu 1.4.x now builds with clang (almost) as is, so remove
    CLANG_HACK. [1]
  - Add workaround for clang/i386 that doesn't define bit_CMOV in <cpuid.h>.
  
  Submitted by:	Brad Smith <brad at comstyle.com> [1]

Added:
  head/emulators/qemu-devel/files/patch-tcg-i386-tcg-target.c   (contents, props changed)
  head/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b   (contents, props changed)
Modified:
  head/emulators/qemu-devel/Makefile
  head/emulators/qemu-devel/files/patch-za-bsd-user-8fix

Modified: head/emulators/qemu-devel/Makefile
==============================================================================
--- head/emulators/qemu-devel/Makefile	Thu Apr 25 18:39:26 2013	(r316526)
+++ head/emulators/qemu-devel/Makefile	Thu Apr 25 19:34:20 2013	(r316527)
@@ -3,6 +3,7 @@
 
 PORTNAME=	qemu
 PORTVERSION=	1.4.0
+PORTREVISION=	1
 CATEGORIES=	emulators
 MASTER_SITES=	http://wiki.qemu.org/download/:release \
 		LOCAL/nox:snapshot
@@ -31,7 +32,7 @@ CONFLICTS_INSTALL=	qemu-[0-9]*
 MAKE_JOBS_SAFE=	yes
 
 OPTIONS_DEFINE=	SAMBA SDL OPENGL GNUTLS SASL JPEG PNG CDROM_DMA PCAP \
-		USBREDIR GNS3 ADD_AUDIO CLANG_HACK X86_TARGETS BSD_USER \
+		USBREDIR GNS3 ADD_AUDIO X86_TARGETS BSD_USER \
 		STATIC_LINK DOCS
 SAMBA_DESC=		samba dependency (for -smb)
 GNUTLS_DESC=		gnutls dependency (vnc encryption)
@@ -44,7 +45,6 @@ SEABIOS_GIT_DESC=	add seabios snapshot (
 USBREDIR_DESC=		usb device network redirection (experimental!)
 GNS3_DESC=		gns3 patches (promiscuous multicast)
 ADD_AUDIO_DESC=		Emulate more audio hardware (experimental!)
-CLANG_HACK_DESC=		clang workaround (result slow and less stable!)
 X86_TARGETS_DESC=	Don't build non-x86 system targets
 BSD_USER_DESC=		Also build bsd-user targets (for testing)
 STATIC_LINK_DESC=	Statically link the executables
@@ -55,16 +55,6 @@ OPTIONS_DEFAULT=SDL OPENGL GNUTLS SASL J
 CONFIGURE_ARGS+=	--extra-ldflags=-L${LOCALBASE}/lib
 PORTDOCS=	docs qemu-doc.html qemu-tech.html qmp-commands.txt
 
-# XXX this fixes build with clang but --enable-tcg-interpreter that's
-# needed to avoid global register usage that clang doesn't support
-# causes the result to be slow and less stable.
-.if ${PORT_OPTIONS:MCLANG_HACK}
-CONFIGURE_ARGS+=	--enable-tcg-interpreter
-CLANG_CFLAGS_AS+=	-no-integrated-as
-.else
-USE_GCC=	any
-.endif
-
 .if ${PORT_OPTIONS:MX86_TARGETS}
 .if ${PORT_OPTIONS:MBSD_USER}
 .if ${ARCH} != "amd64"
@@ -230,9 +220,6 @@ post-patch:
 		-e "s|^(LDFLAGS=).*|\1${LDFLAGS}|" \
 		${WRKSRC}/Makefile
 	@${REINPLACE_CMD} -E \
-		-e "s|^(CFLAGS[ 	]*:=.*)|\1 ${CLANG_CFLAGS_AS}|" \
-		${WRKSRC}/pc-bios/optionrom/Makefile
-	@${REINPLACE_CMD} -E \
 		-e "1s|^(#! )/usr/bin/perl|\1${PERL}|" \
 		${WRKSRC}/scripts/texi2pod.pl
 

Added: head/emulators/qemu-devel/files/patch-tcg-i386-tcg-target.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/emulators/qemu-devel/files/patch-tcg-i386-tcg-target.c	Thu Apr 25 19:34:20 2013	(r316527)
@@ -0,0 +1,13 @@
+--- a/tcg/i386/tcg-target.c
++++ b/tcg/i386/tcg-target.c
+@@ -104,6 +104,10 @@ static const int tcg_target_call_oarg_re
+ # define have_cmov 1
+ #elif defined(CONFIG_CPUID_H)
+ #include <cpuid.h>
++#ifndef bit_CMOV
++/* clang's <cpuid.h> doesn't define bit_* */
++#define bit_CMOV	(1 << 15)
++#endif
+ static bool have_cmov;
+ #else
+ # define have_cmov 0

Modified: head/emulators/qemu-devel/files/patch-za-bsd-user-8fix
==============================================================================
--- head/emulators/qemu-devel/files/patch-za-bsd-user-8fix	Thu Apr 25 18:39:26 2013	(r316526)
+++ head/emulators/qemu-devel/files/patch-za-bsd-user-8fix	Thu Apr 25 19:34:20 2013	(r316527)
@@ -1,28 +1,12 @@
 --- a/bsd-user/syscall.c
 +++ b/bsd-user/syscall.c
-@@ -123,6 +123,7 @@ get_filename_from_fd(pid_t pid, int fd, 
- 	struct filestat *fst;
- 	char *ret = NULL;
- 
+@@ -106,7 +106,9 @@ static char *get_filename_from_fd(pid_t 
+ #ifdef __FreeBSD__
+ #include <sys/queue.h>
+ #include <sys/user.h>
 +#if defined(__FreeBSD_version) && __FreeBSD_version > 900000
- 	procstat = procstat_open_sysctl();
- 	if (NULL == procstat)
- 		goto out;
-@@ -152,6 +153,7 @@ out:
- 		procstat_freeprocs(procstat, kipp);
- 	if (procstat != NULL)
- 		procstat_close(procstat);
+ #include <libprocstat.h>
 +#endif
- 	return (ret);
- }
  
-@@ -1739,7 +1741,9 @@ int_case:
- 		case IP_RECVDSTADDR:
  
- 		case IP_RETOPTS:
-+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000
- 		case IP_RECVTOS:
-+#endif
- 		case IP_MULTICAST_TTL:
- 		case IP_MULTICAST_LOOP:
- 		case IP_PORTRANGE:
+ /*

Added: head/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b	Thu Apr 25 19:34:20 2013	(r316527)
@@ -0,0 +1,1048 @@
+diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h
+index 05c9d1c..214d691 100644
+--- a/bsd-user/arm/target_signal.h
++++ b/bsd-user/arm/target_signal.h
+@@ -67,6 +67,29 @@ struct target_sigframe {
+ 	target_ucontext_t	sf_uc;	/* saved ucontext */
+ };
+ 
++/* compare to sys/arm/include/frame.h */
++typedef struct target_trapframe {
++	abi_ulong tf_spsr; /* Zero on arm26 */
++	abi_ulong tf_r0;
++	abi_ulong tf_r1;
++	abi_ulong tf_r2;
++	abi_ulong tf_r3;
++	abi_ulong tf_r4;
++	abi_ulong tf_r5;
++	abi_ulong tf_r6;
++	abi_ulong tf_r7;
++	abi_ulong tf_r8;
++	abi_ulong tf_r9;
++	abi_ulong tf_r10;
++	abi_ulong tf_r11;
++	abi_ulong tf_r12;
++	abi_ulong tf_usr_sp;
++	abi_ulong tf_usr_lr;
++	abi_ulong tf_svc_sp; /* Not used on arm26 */
++	abi_ulong tf_svc_lr; /* Not used on arm26 */
++	abi_ulong tf_pc;
++} target_trapframe_t;
++
+ #define	TARGET_SZSIGCODE	(8 * 4)
+ 
+ /* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */
+@@ -224,4 +247,22 @@ get_ucontext_sigreturn(CPUARMState *regs, abi_ulong sf_addr,
+ 	return (0);
+ }
+ 
++/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
++/* XXX crashes on first shared lib call */
++static inline void
++thread_set_upcall(CPUARMState *regs, abi_ulong entry, abi_ulong arg,
++    abi_ulong stack_base, abi_ulong stack_size)
++{
++	abi_ulong sp;
++
++	sp = ((stack_base + stack_size) & (8 - 1)) - sizeof(struct target_trapframe);
++
++	/* fp = sp = stack base */
++	regs->regs[11] = regs->regs[13] = sp;
++	/* pc = start function entry */
++	regs->regs[15] = regs->regs[14] = entry & 0xfffffffe;
++	/* r0 = arg */
++	regs->regs[0] = arg;
++}
++
+ #endif /* TARGET_SIGNAL_H */
+diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h
+index bc50fbb..2186c68 100644
+--- a/bsd-user/arm/target_vmparam.h
++++ b/bsd-user/arm/target_vmparam.h
+@@ -1,7 +1,19 @@
+ #ifndef _TARGET_VMPARAM_H_
+ #define _TARGET_VMPARAM_H_
+ 
++#define	TARGET_HW_MACHINE	"arm"
++#define	TARGET_HW_MACHINE_ARCH	"armv6"
++
+ #if defined(__FreeBSD__)
++
++/* compare to arm/include/vmparam.h */
++#define	TARGET_MAXTSIZ		(64UL*1024*1024)	/* max text size */
++#define	TARGET_DFLDSIZ		(128UL*1024*1024)	/* initial data size limit */
++#define	TARGET_MAXDSIZ		(512UL*1024*1024)	/* max data size */
++#define	TARGET_DFLSSIZ		(2UL*1024*1024)		/* initial stack size limit */
++#define	TARGET_MAXSSIZ		(8UL*1024*1024)		/* max stack size */
++#define	TARGET_SGROWSIZ		(128UL*1024)		/* amount to grow stack */
++
+ 					/* KERNBASE - 512 MB */
+ #define TARGET_VM_MAXUSER_ADDRESS	(0xc0000000 - (512 * 1024 * 1024))
+ #define TARGET_USRSTACK			TARGET_VM_MAXUSER_ADDRESS
+@@ -18,10 +30,6 @@ 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/elfload.c b/bsd-user/elfload.c
+index 7a7c3eb..da9ad73 100644
+--- a/bsd-user/elfload.c
++++ b/bsd-user/elfload.c
+@@ -701,13 +701,7 @@ 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
++    size = target_dflssiz;
+ 
+ #ifdef TARGET_USRSTACK
+     stack_base = TARGET_USRSTACK - size;
+diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h
+index 51a2a7b..034b455 100644
+--- a/bsd-user/i386/target_signal.h
++++ b/bsd-user/i386/target_signal.h
+@@ -45,4 +45,12 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
+ 	return (-TARGET_ENOSYS);
+ }
+ 
++/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
++static inline void
++thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
++        abi_ulong stack_base, abi_ulong stack_size)
++{
++	fprintf(stderr, "i386 doesn't have support for thread_set_upcall()\n");
++}
++
+ #endif /* TARGET_SIGNAL_H */
+diff --git a/bsd-user/i386/target_vmparam.h b/bsd-user/i386/target_vmparam.h
+index ea7546c..fb8493f 100644
+--- a/bsd-user/i386/target_vmparam.h
++++ b/bsd-user/i386/target_vmparam.h
+@@ -1,8 +1,19 @@
+ #ifndef _TARGET_VMPARAM_H_
+ #define _TARGET_VMPARAM_H_
+ 
++#define	TARGET_HW_MACHINE	"i386"
++#define	TARGET_HW_MACHINE_ARCH	"i386"
++
+ #if defined(__FreeBSD__)
+ 
++/* compare to i386/include/vmparam.h */
++#define	TARGET_MAXTSIZ	(128UL*1024*1024)	/* max text size */
++#define	TARGET_DFLDSIZ	(128UL*1024*1024)	/* initial data size limit */
++#define	TARGET_MAXDSIZ	(512UL*1024*1024)	/* max data size */
++#define	TARGET_DFLSSIZ	(8UL*1024*1024)		/* initial stack size limit */
++#define	TARGET_MAXSSIZ	(64UL*1024*1024)	/* max stack size */
++#define	TARGET_SGROWSIZ	(128UL*1024)		/* amount to grow stack */
++
+ #define	TARGET_USRSTACK	(0xbfc00000)
+ 
+ struct target_ps_strings {
+@@ -19,10 +30,6 @@ 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 b248a91..99b94c1 100644
+--- a/bsd-user/main.c
++++ b/bsd-user/main.c
+@@ -56,10 +56,15 @@ const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
+ extern char **environ;
+ enum BSDType bsd_type;
+ 
++unsigned long target_maxtsiz = TARGET_MAXTSIZ;	/* max text size */
++unsigned long target_dfldsiz = TARGET_DFLDSIZ;	/* initial data size limit */
++unsigned long target_maxdsiz = TARGET_MAXDSIZ;	/* max data size */
+ /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
+    we allocate a bigger stack. Need a better solution, for example
+    by remapping the process stack directly at the right place */
+-unsigned long x86_stack_size = 512 * 1024;
++unsigned long target_dflssiz = TARGET_DFLSSIZ;	/* initial data size limit */
++unsigned long target_maxssiz = TARGET_MAXSSIZ;	/* max stack size */
++unsigned long target_sgrowsiz = TARGET_SGROWSIZ;/* amount to grow stack */
+ 
+ static void save_proc_pathname(void);
+ char qemu_proc_pathname[PATH_MAX];
+@@ -126,7 +131,7 @@ static int pending_cpus;
+ /* Make sure everything is in a consistent state for calling fork(). */
+ void fork_start(void)
+ {
+-	pthread_mutex_lock(&tb_lock);
++	spin_lock(&tb_lock);
+ 	pthread_mutex_lock(&exclusive_lock);
+ 	mmap_fork_start();
+ }
+@@ -146,11 +151,11 @@ void fork_end(int child)
+ 		pthread_mutex_init(&cpu_list_mutex, NULL);
+ 		pthread_cond_init(&exclusive_cond, NULL);
+ 		pthread_cond_init(&exclusive_resume, NULL);
+-		pthread_mutex_init(&tb_lock, NULL);
++		spin_lock_init(&tb_lock);
+ 		gdbserver_fork(thread_env);
+ 	} else {
+ 		pthread_mutex_unlock(&exclusive_lock);
+-		pthread_mutex_unlock(&tb_lock);
++		spin_unlock(&tb_lock);
+ 	}
+ }
+ 
+@@ -1012,10 +1017,7 @@ void cpu_loop(CPUMIPSState *env)
+ 
+ 	for(;;) {
+ 		cpu_exec_start(env);
+-		/* XXX there is a concurrency problem - giant lock for now */
+-		pthread_mutex_lock(&exclusive_lock); /* XXX */
+ 		trapnr = cpu_mips_exec(env);
+-		pthread_mutex_unlock(&exclusive_lock); /* XXX */
+ 		cpu_exec_end(env);
+ 		switch(trapnr) {
+ 		case EXCP_SYSCALL: /* syscall exception */
+@@ -1481,7 +1483,7 @@ static void usage(void)
+            ,
+            TARGET_ARCH,
+            interp_prefix,
+-           x86_stack_size,
++           target_dflssiz,
+            DEBUG_LOGFILE);
+     exit(1);
+ }
+@@ -1603,13 +1605,15 @@ int main(int argc, char **argv)
+                 usage();
+         } else if (!strcmp(r, "s")) {
+             r = argv[optind++];
+-            x86_stack_size = strtol(r, (char **)&r, 0);
+-            if (x86_stack_size <= 0)
++            target_dflssiz = strtol(r, (char **)&r, 0);
++            if (target_dflssiz <= 0)
+                 usage();
+             if (*r == 'M')
+-                x86_stack_size *= 1024 * 1024;
++                target_dflssiz *= 1024 * 1024;
+             else if (*r == 'k' || *r == 'K')
+-                x86_stack_size *= 1024;
++                target_dflssiz *= 1024;
++	    if (target_dflssiz > target_maxssiz)
++		    usage();
+         } else if (!strcmp(r, "L")) {
+             interp_prefix = argv[optind++];
+         } else if (!strcmp(r, "p")) {
+@@ -1797,7 +1801,7 @@ int main(int argc, char **argv)
+         qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
+     }
+ 
+-    target_set_brk(info->brk);
++    target_set_brk(info->start_data, info->brk, info->end_data);
+     syscall_init();
+     signal_init();
+ 
+diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h
+index 0f57f0f..abe4587 100644
+--- a/bsd-user/mips/target_signal.h
++++ b/bsd-user/mips/target_signal.h
+@@ -6,6 +6,10 @@
+ #define	TARGET_MINSIGSTKSZ	(512 * 4)
+ #define	TARGET_SIGSTKSZ		(TARGET_MINSIGSTKSZ + 32768)
+ 
++/* compare to sys/mips/include/asm.h */
++#define	TARGET_SZREG		4
++#define	TARGET_CALLFRAME_SIZ	(TARGET_SZREG * 4)
++
+ struct target_sigcontext {
+ 	target_sigset_t	sc_mask;        /* signal mask to retstore */
+ 	int32_t		sc_onstack;     /* sigstack state to restore */
+@@ -207,4 +211,27 @@ get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr,
+ 	return (0);
+ }
+ 
++/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */
++static inline void
++thread_set_upcall(CPUMIPSState *regs, abi_ulong entry,
++    abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size)
++{
++	abi_ulong sp;
++
++	/*
++	 * At the point where a function is called, sp must be 8
++	 * byte aligned[for compatibility with 64-bit CPUs]
++	 * in ``See MIPS Run'' by D. Sweetman, p. 269
++	 * align stack
++	 */
++	sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ;
++
++	/* t9 = pc = start function entry */
++	regs->active_tc.gpr[25] = regs->active_tc.PC = entry;
++	/* a0 = arg */
++	regs->active_tc.gpr[ 4] = arg;
++	/* sp = top of the stack */
++	regs->active_tc.gpr[29] = sp;
++}
++
+ #endif /* TARGET_SIGNAL_H */
+diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h
+index 8abc26c..6eca54f 100644
+--- a/bsd-user/mips/target_vmparam.h
++++ b/bsd-user/mips/target_vmparam.h
+@@ -1,7 +1,19 @@
+ #ifndef _TARGET_VMPARAM_H_
+ #define _TARGET_VMPARAM_H_
+ 
++#define	TARGET_HW_MACHINE	"mips"
++#define	TARGET_HW_MACHINE_ARCH	"mips"
++
+ #if defined(__FreeBSD__)
++
++/* compare to sys/mips/include/vmparam.h */
++#define	TARGET_MAXTSIZ		(128UL*1024*1024)	/* max text size */
++#define	TARGET_DFLDSIZ		(128UL*1024*1024)	/* initial data size limit */
++#define	TARGET_MAXDSIZ		(1*1024UL*1024*1024)	/* max data size */
++#define	TARGET_DFLSSIZ		(8UL*1024*1024)		/* initial stack size limit */
++#define	TARGET_MAXSSIZ		(64UL*1024*1024)	/* max stack size */
++#define	TARGET_SGROWSIZ		(128UL*1024)		/* amount to grow stack */
++
+ #define	TARGET_VM_MINUSER_ADDRESS	(0x00000000)
+ #define	TARGET_VM_MAXUSER_ADDRESS	(0x80000000)
+ 
+@@ -21,10 +33,6 @@ 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_signal.h b/bsd-user/mips64/target_signal.h
+index 3fee772..60105ec 100644
+--- a/bsd-user/mips64/target_signal.h
++++ b/bsd-user/mips64/target_signal.h
+@@ -6,6 +6,10 @@
+ #define	TARGET_MINSIGSTKSZ	(512 * 4)
+ #define	TARGET_SIGSTKSZ		(TARGET_MINSIGSTKSZ + 32768)
+ 
++/* compare to sys/mips/include/asm.h */
++#define	TARGET_SZREG		8
++#define	TARGET_CALLFRAME_SIZ	(TARGET_SZREG * 4)
++
+ struct target_sigcontext {
+ 	target_sigset_t	sc_mask;        /* signal mask to retstore */
+ 	int32_t		sc_onstack;     /* sigstack state to restore */
+@@ -226,5 +230,28 @@ get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr,
+ 	return (0);
+ }
+ 
++/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */
++static inline void
++thread_set_upcall(CPUMIPSState *regs, abi_ulong entry,
++    abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size)
++{
++	abi_ulong sp;
++
++	/*
++	 * At the point where a function is called, sp must be 8
++	 * byte aligned[for compatibility with 64-bit CPUs]
++	 * in ``See MIPS Run'' by D. Sweetman, p. 269
++	 * align stack
++	 */
++	sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ;
++
++	/* t9 = pc = start function entry */
++	regs->active_tc.gpr[25] = regs->active_tc.PC = entry;
++	/* a0 = arg */
++	regs->active_tc.gpr[ 4] = arg;
++	/* sp = top of the stack */
++	regs->active_tc.gpr[29] = sp;
++}
++
+ #endif /* TARGET_SIGNAL_H */
+ 
+diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h
+index 55ed254..3fe93fb 100644
+--- a/bsd-user/mips64/target_vmparam.h
++++ b/bsd-user/mips64/target_vmparam.h
+@@ -1,8 +1,19 @@
+ #ifndef _TARGET_VMPARAM_H_
+ #define _TARGET_VMPARAM_H_
+ 
++#define	TARGET_HW_MACHINE	"mips"
++#define	TARGET_HW_MACHINE_ARCH	"mips64"
++
+ #if defined(__FreeBSD__)
+ 
++/* compare to sys/mips/include/vmparam.h */
++#define	TARGET_MAXTSIZ		(128UL*1024*1024)	/* max text size */
++#define	TARGET_DFLDSIZ		(128UL*1024*1024)	/* initial data size limit */
++#define	TARGET_MAXDSIZ		(1*1024UL*1024*1024)	/* max data size */
++#define	TARGET_DFLSSIZ		(8UL*1024*1024)		/* initial stack size limit */
++#define	TARGET_MAXSSIZ		(64UL*1024*1024)	/* max stack size */
++#define	TARGET_SGROWSIZ		(128UL*1024)		/* amount to grow stack */
++
+ #define	TARGET_VM_MINUSER_ADDRESS	(0x0000000000000000UL)
+ #define	TARGET_VM_MAXUSER_ADDRESS	(0x0000008000000000UL)
+ 
+@@ -20,10 +31,6 @@ 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/mmap.c b/bsd-user/mmap.c
+index 495f0ec..1ed597a 100644
+--- a/bsd-user/mmap.c
++++ b/bsd-user/mmap.c
+@@ -31,8 +31,8 @@
+ //#define DEBUG_MMAP
+ 
+ #if defined(CONFIG_USE_NPTL)
+-pthread_mutex_t mmap_mutex;
+-static int __thread mmap_lock_count;
++pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
++static __thread int mmap_lock_count;
+ 
+ void mmap_lock(void)
+ {
+@@ -348,6 +348,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
+         case MAP_SHARED:
+             printf("MAP_SHARED ");
+             break;
++	case MAP_STACK:
++	    printf("MAP_STACK ");
++	    break;
+         default:
+             printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK);
+             break;
+@@ -356,6 +359,14 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
+     }
+ #endif
+ 
++    if (flags & MAP_STACK) {
++	    if ((fd != -1) ||
++		((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE))) {
++		    errno = EINVAL;
++		    goto fail;
++	    }
++    }
++
+     if (offset & ~TARGET_PAGE_MASK) {
+         errno = EINVAL;
+         goto fail;
+diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
+index fbcdd6c..4c20e48 100644
+--- a/bsd-user/qemu.h
++++ b/bsd-user/qemu.h
+@@ -147,7 +147,7 @@ int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
+                     struct image_info * info);
+ int is_target_elf_binary(int fd);
+ 
+-void target_set_brk(abi_ulong new_brk);
++void target_set_brk(abi_ulong start_brk, abi_ulong cur_brk, abi_ulong end_brk);
+ abi_long do_brk(abi_ulong new_brk);
+ void syscall_init(void);
+ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
+@@ -221,7 +221,12 @@ void mmap_fork_end(int child);
+ #endif
+ 
+ /* main.c */
+-extern unsigned long x86_stack_size;
++extern unsigned long target_maxtsiz;
++extern unsigned long target_dfldsiz;
++extern unsigned long target_maxdsiz;
++extern unsigned long target_dflssiz;
++extern unsigned long target_maxssiz;
++extern unsigned long target_sgrowsiz;
+ extern char qemu_proc_pathname[];
+ extern char target_proc_pathname[];
+ 
+diff --git a/bsd-user/signal.c b/bsd-user/signal.c
+index e7e9e41..c4e8440 100644
+--- a/bsd-user/signal.c
++++ b/bsd-user/signal.c
+@@ -631,7 +631,7 @@ get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size)
+ 		    target_sigaltstack_used.ss_size;
+ 	}
+ 
+-#if defined(TARGET_MIPS)
++#if defined(TARGET_MIPS) || defined(TARGET_ARM)
+ 	return ((sp - frame_size) & ~7);
+ #else
+ 	return (sp - frame_size);
+diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h
+index 65d315a..20630d7 100644
+--- a/bsd-user/sparc/target_signal.h
++++ b/bsd-user/sparc/target_signal.h
+@@ -51,4 +51,12 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
+ 	return (-TARGET_ENOSYS);
+ }
+ 
++/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
++static inline void
++thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
++        abi_ulong stack_base, abi_ulong stack_size)
++{
++	fprintf(stderr, "SPARC doesn't have support for thread_set_upcall()\n");
++}
++
+ #endif /* TARGET_SIGNAL_H */
+diff --git a/bsd-user/sparc/target_vmparam.h b/bsd-user/sparc/target_vmparam.h
+index 82c29ed..b8dcd0d 100644
+--- a/bsd-user/sparc/target_vmparam.h
++++ b/bsd-user/sparc/target_vmparam.h
+@@ -1,7 +1,18 @@
+ #ifndef _TARGET_VMPARAM_H_
+ #define _TARGET_VMPARAM_H_
+ 
++#define	TARGET_HW_MACHINE	"sparc"
++#define	TARGET_HW_MACHINE_ARCH	"sparc"
++
+ #ifdef __FreeBSD__
++
++#define	TARGET_MAXTSIZ	(1*1024*1024*1024)	/* max text size */
++#define	TARGET_DFLDSIZ	(128*1024*1024)		/* initial data size limit */
++#define	TARGET_MAXDSIZ	(1*1024*1024*1024)	/* max data size */
++#define	TARGET_DFLSSIZ	(128*1024*1024)		/* initial stack size limit */
++#define	TARGET_MAXSSIZ	(1*1024*1024*1024)	/* max stack size */
++#define	TARGET_SGROWSIZ	(128*1024)		/* amount to grow stack */
++
+ struct target_ps_strings {
+         abi_ulong ps_argvstr;
+         uint32_t ps_nargvstr;
+@@ -20,10 +31,6 @@ 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/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h
+index fa8edb8..67378a5 100644
+--- a/bsd-user/sparc64/target_signal.h
++++ b/bsd-user/sparc64/target_signal.h
+@@ -253,4 +253,12 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
+ 	return (-TARGET_ENOSYS);
+ }
+ 
++/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
++static inline void
++thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
++        abi_ulong stack_base, abi_ulong stack_size)
++{
++	fprintf(stderr, "SPARC64 doesn't have support for thread_set_upcall()\n");
++}
++
+ #endif /* TARGET_SIGNAL_H */
+diff --git a/bsd-user/sparc64/target_vmparam.h b/bsd-user/sparc64/target_vmparam.h
+index 7f2b464..b8dbf2c 100644
+--- a/bsd-user/sparc64/target_vmparam.h
++++ b/bsd-user/sparc64/target_vmparam.h
+@@ -1,7 +1,19 @@
+ #ifndef _TARGET_VMPARAM_H_
+ #define _TARGET_VMPARAM_H_
+ 
++#define	TARGET_HW_MACHINE	"sparc"
++#define	TARGET_HW_MACHINE_ARCH  "sparc64"
++
+ #if defined(__FreeBSD__)
++
++/* compare to amd64/include/vmparam.h */
++#define	TARGET_MAXTSIZ	(1*1024*1024*1024)	/* max text size */
++#define	TARGET_DFLDSIZ	(128*1024*1024)		/* initial data size limit */
++#define	TARGET_MAXDSIZ	(1*1024*1024*1024)	/* max data size */
++#define	TARGET_DFLSSIZ	(128*1024*1024)		/* initial stack size limit */
++#define	TARGET_MAXSSIZ	(1*1024*1024*1024)	/* max stack size */
++#define	TARGET_SGROWSIZ	(128*1024)		/* amount to grow stack */
++
+ #define	TARGET_VM_MINUSER_ADDRESS	(0x0000000000000000UL)
+ #define	TARGET_VM_MAXUSER_ADDRESS	(0x000007fe00000000UL)
+ 
+@@ -21,10 +33,6 @@ 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 2d97a23..0f337e2 100644
+--- a/bsd-user/syscall.c
++++ b/bsd-user/syscall.c
+@@ -98,8 +98,7 @@
+ 
+ //#define DEBUG
+ 
+-static abi_ulong target_brk;
+-static abi_ulong target_original_brk;
++static abi_ulong target_brk_start, target_brk_cur, target_brk_end;
+ 
+ static char *get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len);
+ 
+@@ -123,6 +122,7 @@ get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len)
+ 	struct filestat *fst;
+ 	char *ret = NULL;
+ 
++#if defined(__FreeBSD_version) && __FreeBSD_version > 900000
+ 	procstat = procstat_open_sysctl();
+ 	if (NULL == procstat)
+ 		goto out;
+@@ -152,6 +152,7 @@ out:
+ 		procstat_freeprocs(procstat, kipp);
+ 	if (procstat != NULL)
+ 		procstat_close(procstat);
++#endif
+ 	return (ret);
+ }
+ 
+@@ -188,41 +189,45 @@ static inline int is_error(abi_long ret)
+     return (abi_ulong)ret >= (abi_ulong)(-4096);
+ }
+ 
+-void target_set_brk(abi_ulong new_brk)
++void target_set_brk(abi_ulong start_brk, abi_ulong cur_brk, abi_ulong end_brk)
+ {
+-    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
++    target_brk_start = HOST_PAGE_ALIGN(start_brk);
++    target_brk_cur = cur_brk;
++    target_brk_end = HOST_PAGE_ALIGN(end_brk);
+ }
+ 
+ /* do_obreak() must return target errnos. */
+ static abi_long do_obreak(abi_ulong new_brk)
+ {
+-    abi_ulong brk_page;
+     abi_long mapped_addr;
+-    int new_alloc_size;
++    abi_ulong new_alloc_size;
++
++    return -TARGET_EINVAL;	// XXX Temporary disable obreak() until it can be properly fixed
+ 
+     if (!new_brk)
+         return 0;
+-    if (new_brk < target_original_brk)
++    if (new_brk < target_brk_cur) {
+         return -TARGET_EINVAL;
+-
+-    brk_page = HOST_PAGE_ALIGN(target_brk);
++    }
+ 
+     /* If the new brk is less than this, set it and we're done... */
+-    if (new_brk < brk_page) {
+-        target_brk = new_brk;
++    if (new_brk < target_brk_end) {
++        target_brk_cur = new_brk;
+         return 0;
+     }
+ 
+     /* We need to allocate more memory after the brk... */
+-    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
+-    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
++    new_alloc_size = HOST_PAGE_ALIGN(new_brk - target_brk_end + 1);
++    mapped_addr = get_errno(target_mmap(target_brk_end, new_alloc_size,
+                                         PROT_READ|PROT_WRITE,
+                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0));
+ 
+-    if (!is_error(mapped_addr))
+-        target_brk = new_brk;
+-    else
++    if (!is_error(mapped_addr)) {
++        target_brk_cur = new_brk;
++	target_brk_end += new_alloc_size;
++    } else {
+         return mapped_addr;
++    }
+ 
+     return 0;
+ }
+@@ -520,11 +525,7 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
+     case CTL_KERN:
+ 	    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
++#if TARGET_USRSTACK != 0
+ 		    (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK);
+ 		    holdlen = sizeof(abi_ulong);
+ 		    ret = 0;
+@@ -568,6 +569,22 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
+ 	    }
+             break;
+ 
++    case CTL_HW:
++	    switch(snamep[1]) {
++	    case HW_MACHINE:
++		strlcpy(holdp, TARGET_HW_MACHINE, oldlen);
++		ret = 0;
++		goto out;
++
++	    case HW_MACHINE_ARCH:
++		strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen);
++		ret = 0;
++		goto out;
++
++	    default:
++		break;
++	    }
++
+     default:
+ 	    break;
+     }
+@@ -1736,7 +1753,9 @@ int_case:
+ 		case IP_RECVDSTADDR:
+ 
+ 		case IP_RETOPTS:
++#if defined(__FreeBSD_version) && __FreeBSD_version > 900000
+ 		case IP_RECVTOS:
++#endif
+ 		case IP_MULTICAST_TTL:
+ 		case IP_MULTICAST_LOOP:
+ 		case IP_PORTRANGE:
+@@ -2553,7 +2572,7 @@ do_fork(CPUArchState *env, int num, int flags, int *fdp)
+ static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+ typedef struct {
+ 	CPUArchState *env;
+-	long tid;
++	long parent_tid;
+ 	pthread_mutex_t mutex;
+ 	pthread_cond_t cond;
+ 	pthread_t thread;
+@@ -2571,24 +2590,23 @@ new_thread_start(void *arg)
+ 
+ 	env = info->env;
+ 	thread_env = env;
++	fork_end(1);
++
+ 	ts = (TaskState *)thread_env->opaque;
+ 	(void)thr_self(&tid);
+-	info->tid = tid;
+ 	task_settid(ts);
+ 
+ 	/* copy out the TID info */
+ 	if (info->param.child_tid)
+ 		put_user(tid, info->param.child_tid, abi_long);
+ 	if (info->param.parent_tid)
+-		put_user(tid, info->param.parent_tid, abi_long);
++		put_user(info->parent_tid, info->param.parent_tid, abi_long);
+ 
+-#ifdef TARGET_MIPS64
+-	CPUMIPSState *regs = env;
+-	regs->active_tc.gpr[25] = regs->active_tc.PC = info->param.start_func;
+-	regs->active_tc.gpr[ 4] = info->param.arg;
+-	regs->active_tc.gpr[29] = info->param.stack_base;
+-#endif
+-	/* Eenable signals */
++	/* Set arch dependent registers to start thread. */
++	thread_set_upcall(env, info->param.start_func, info->param.arg,
++	    info->param.stack_base, info->param.stack_size);
++
++	/* Enable signals */
+ 	sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
+ 	/* Signal to the parent that we're ready. */
+ 	pthread_mutex_lock(&info->mutex);
+@@ -2662,9 +2680,12 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
+ 	info.param.tls_size = tswapal(target_param->tls_size);
+ 	info.param.child_tid = tswapal(target_param->child_tid);
+ 	info.param.parent_tid = tswapal(target_param->parent_tid);
++	info.param.flags = tswap32(target_param->flags);
+ 	target_rtp_addr = info.param.rtp = tswapal(target_param->rtp);
+ 	unlock_user(target_param, target_param_addr, 0);
+ 
++	thr_self(&info.parent_tid);
++
+ 	if (target_rtp_addr) {
+ 		if (!lock_user_struct(VERIFY_READ, target_rtp, target_rtp_addr,
+ 			1))
+@@ -2678,6 +2699,7 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
+ 	}
+ 
+ 	/* Create a new CPU instance. */
++	fork_start();
+ 	ts = g_malloc0(sizeof(TaskState));
+ 	init_task_state(ts);
+ 	new_env = cpu_copy(env);
+@@ -2691,9 +2713,8 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
+ 	ts->bprm = parent_ts->bprm;
+ 	ts->info = parent_ts->info;
+ 
+-#if defined(TARGET_MIPS)
+-	env->tls_value = info.param.tls_base;
+-	/* cpu_set_tls(new_env, info.param.tls_base); */
++#if defined(TARGET_MIPS) || defined(TARGET_ARM)
++	cpu_set_tls(env, info.param.tls_base);
+ #endif
+ 
+ 	/* Grab a mutex so that thread setup appears atomic. */
+@@ -2725,6 +2746,8 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
+ 	ret = pthread_create(&info.thread, &attr, new_thread_start, &info);
+ 	/* XXX Free new CPU state if thread creation fails. */
+ 
++	fork_end(0);
++
+ 	sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
+ 	pthread_attr_destroy(&attr);
+ 	if (0 == ret) {
+@@ -2791,6 +2814,9 @@ do_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr)
+ 		g_free(ts);
+ 		pthread_exit(NULL);
+ 	}
++
++	gdb_exit(cpu_env, 0);	/* XXX need to put in the correct exit status here? */
++	_exit(0);
+ }
+ 
+ static int
+@@ -3010,7 +3036,7 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts,
+     int mode)
+ {
+ 	uint32_t owner, flags;
+-	int ret;
++	int ret = 0;
+ 
+ 	for (;;) {
+ 		struct target_umutex *target_umutex;
+@@ -3058,7 +3084,6 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts,
+ 		}
+ 
+ 		__get_user(flags, &target_umutex->m_flags);
+-		flags = tswap32(flags);
+ 		if ((flags & TARGET_UMUTEX_ERROR_CHECK) != 0 &&
+ 		    (owner & ~TARGET_UMUTEX_CONTESTED) == id) {
+ 			unlock_user_struct(target_umutex, target_addr, 1);
+@@ -3070,6 +3095,15 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts,
+ 			return (-TARGET_EBUSY);
+ 		}
+ 
++		/*
++		 * If we caught a signal, we have retried and now
++		 * exit immediately.
++		 */
++		if (ret) {
++			unlock_user_struct(target_umutex, target_addr, 1);
++			return (ret);
++		}
++
+ 		/* Set the contested bit and sleep. */
+ 		if (!tcmpset_32(&target_umutex->m_owner, owner,
+ 			owner | TARGET_UMUTEX_CONTESTED)) {
+@@ -3084,8 +3118,6 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts,
+ 		owner = tswap32(owner);
+ 		ret = get_errno(_umtx_op(target_umutex, UMTX_OP_WAIT_UINT, owner,
+ 			0, ts));
+-		if (ret)
+-			return (ret);
+ 	}
+ 
+ 	return (0);
+@@ -4841,8 +4873,9 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
+     case TARGET_FREEBSD_NR_fstat:
+         {
+ 	    struct stat st;
++
+             ret = get_errno(fstat(arg1, &st));
+-	    if (! ret)
++	    if (!is_error(ret))
+ 		    ret = host_to_target_stat(arg2, &st);
+ 	}
+         break;
+@@ -4851,10 +4884,12 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
+ 	 {
+ 		 struct timespec req, rem;
+ 
+-		 target_to_host_timespec(&req, arg1);
+-		 ret = get_errno(nanosleep(&req, &rem));
+-		 if (is_error(ret) && arg2)
+-			 host_to_target_timespec(arg2, &rem);
++		 ret = target_to_host_timespec(&req, arg1);
++		 if (!is_error(ret)) {
++		     ret = get_errno(nanosleep(&req, &rem));

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-ports-all mailing list