ports/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b
Juergen Lock b179b768b4 - Update to 1.5.0, announce message is here:
https://lists.gnu.org/archive/html/qemu-devel/2013-05/msg02557.html

  Full changelog:

	http://wiki.qemu.org/ChangeLog/1.5

  The new libusb host code needs recent 10-current; for older releases you
  can still try the net/usbredir support knob, see pkg-message for details.

- Update pkg-message a bit.

Thanx to:	emaste for some suggestions
2013-05-29 18:01:53 +00:00

1048 lines
33 KiB
Text

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
@@ -54,10 +54,15 @@ const char *qemu_uname_release = CONFIG_
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];
@@ -124,7 +129,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();
}
@@ -144,11 +149,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);
}
}
@@ -1010,10 +1015,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 */
@@ -1480,7 +1482,7 @@ static void usage(void)
,
TARGET_ARCH,
interp_prefix,
- x86_stack_size);
+ target_dflssiz);
exit(1);
}
@@ -1601,13 +1603,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")) {
@@ -1791,7 +1795,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));
+ if (!is_error(ret) && arg2)
+ host_to_target_timespec(arg2, &rem);
+ }
}
break;
@@ -5119,12 +5154,23 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
struct target_rlimit *target_rlim;
struct rlimit rlim;
- /* Return the target stack size */
- if (RLIMIT_STACK == resource) {
- rlim.rlim_cur = rlim.rlim_max = TARGET_STACK_SIZE;
+ switch (resource) {
+ case RLIMIT_STACK:
+ rlim.rlim_cur = target_dflssiz;
+ rlim.rlim_max = target_maxssiz;
ret = 0;
- } else
+ break;
+
+ case RLIMIT_DATA:
+ rlim.rlim_cur = target_dfldsiz;
+ rlim.rlim_max = target_maxdsiz;
+ ret = 0;
+ break;
+
+ default:
ret = get_errno(getrlimit(resource, &rlim));
+ break;
+ }
if (!is_error(ret)) {
if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2,
0))
@@ -7260,11 +7306,28 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
#if defined(__FreeBSD_version) && __FreeBSD_version > 900000
case TARGET_UMTX_OP_NWAKE_PRIVATE:
- if (! access_ok(VERIFY_READ, obj,
- val * sizeof(uint32_t)))
- goto efault;
- ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE,
- val, NULL, NULL));
+ {
+ int i;
+ abi_ulong *uaddr;
+
+ if (! access_ok(VERIFY_READ, obj,
+ val * sizeof(uint32_t)))
+ goto efault;
+
+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE,
+ val, NULL, NULL));
+
+ uaddr = (abi_ulong *)g2h(obj);
+ ret = 0;
+ for(i = 0; i < (int32_t)val; i++) {
+ ret = get_errno(_umtx_op(g2h(tswapal(uaddr[i])),
+ UMTX_OP_WAKE_PRIVATE, tswap32(INT_MAX),
+ NULL, NULL));
+ if (ret)
+ break;
+ }
+
+ }
break;
#endif
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
index eb804b3..c2e78bd 100644
--- a/bsd-user/syscall_defs.h
+++ b/bsd-user/syscall_defs.h
@@ -544,6 +544,7 @@ struct target_thr_param {
abi_ulong tls_size; /* tls size. */
abi_ulong child_tid; /* address to store new TID. */
abi_ulong parent_tid; /* parent access the new TID here. */
+ int32_t flags; /* thread flags. */
abi_ulong rtp; /* Real-time scheduling priority. */
abi_ulong spare[3]; /* spares. */
};
diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h
index 72df2f0..51e32bf 100644
--- a/bsd-user/x86_64/target_signal.h
+++ b/bsd-user/x86_64/target_signal.h
@@ -49,4 +49,13 @@ 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, "x86_64 doesn't have support for thread_set_upcall()\n");
+}
+
+
#endif /* TARGET_SIGNAL_H */
diff --git a/bsd-user/x86_64/target_vmparam.h b/bsd-user/x86_64/target_vmparam.h
index ff9f534..70891a1 100644
--- a/bsd-user/x86_64/target_vmparam.h
+++ b/bsd-user/x86_64/target_vmparam.h
@@ -1,7 +1,19 @@
#ifndef _TARGET_VMPARAM_H_
#define _TARGET_VMPARAM_H_
+#define TARGET_HW_MACHINE "amd64"
+#define TARGET_HW_MACHINE_ARCH "amd64"
+
#if defined(__FreeBSD__)
+
+/* compare to amd64/include/vmparam.h */
+#define TARGET_MAXTSIZ (128UL*1024*1024) /* max text size */
+#define TARGET_DFLDSIZ (32768UL*1024*1024) /* initial data size limit */
+#define TARGET_MAXDSIZ (32768UL*1024*1024) /* max data size */
+#define TARGET_DFLSSIZ (8UL*1024*1024) /* initial stack size limit */
+#define TARGET_MAXSSIZ (512UL*1024*1024) /* max stack size */
+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */
+
#define TARGET_VM_MAXUSER_ADDRESS (0x0000800000000000UL)
#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE)
@@ -20,10 +32,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/include/exec/spinlock.h b/include/exec/spinlock.h
index a72edda..fc1f808 100644
--- a/include/exec/spinlock.h
+++ b/include/exec/spinlock.h
@@ -24,6 +24,7 @@
#include <pthread.h>
#define spin_lock pthread_mutex_lock
#define spin_unlock pthread_mutex_unlock
+#define spin_lock_init(mtx) pthread_mutex_init(mtx, NULL)
#define spinlock_t pthread_mutex_t
#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
diff --git a/include/qemu/tls.h b/include/qemu/tls.h
index b92ea9d..ae7d79d 100644
--- a/include/qemu/tls.h
+++ b/include/qemu/tls.h
@@ -38,7 +38,7 @@
* TODO: proper implementations via Win32 .tls sections and
* POSIX pthread_getspecific.
*/
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
#define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x)
#define DEFINE_TLS(type, x) __thread __typeof__(type) tls__##x
#define tls_var(x) tls__##x