summaryrefslogtreecommitdiff
path: root/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c
diff options
context:
space:
mode:
authorJuergen Lock <nox@FreeBSD.org>2013-08-20 22:03:10 +0000
committerJuergen Lock <nox@FreeBSD.org>2013-08-20 22:03:10 +0000
commitf2f3e3e60ae9a4520c8bdb2c66d879ab7a9923df (patch)
tree6e410f147aab5715db036270b661a814dc7a0536 /emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c
parent- Update sysutils/rsyslog7 to 7.4.3 (diff)
- Update to 1.6.0 - announce message is here:
https://lists.gnu.org/archive/html/qemu-devel/2013-08/msg02245.html - Remove bsd-user support as sson's patches no longer apply, you can still use his (older) git tree or my port of it on redports as described here: https://wiki.freebsd.org/QemuUserModeHowTo
Diffstat (limited to 'emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c')
-rw-r--r--emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c2300
1 files changed, 0 insertions, 2300 deletions
diff --git a/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c b/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c
deleted file mode 100644
index 0c1d7720f3bb..000000000000
--- a/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c
+++ /dev/null
@@ -1,2300 +0,0 @@
-diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h
-index 19cc188..6b7bb67 100644
---- a/bsd-user/arm/target_signal.h
-+++ b/bsd-user/arm/target_signal.h
-@@ -11,4 +11,29 @@ static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
- #define TARGET_MINSIGSTKSZ (1024 * 4)
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-
-+typedef target_ulong target_mcontext_t; /* dummy */
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
-+static inline int
-+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "ARM doesn't have support for get_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
-+static inline int
-+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "ARM doesn't have support for set_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
-index 1edf412..b09f766 100644
---- a/bsd-user/freebsd/strace.list
-+++ b/bsd-user/freebsd/strace.list
-@@ -38,6 +38,7 @@
- { TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_getcontext, "getcontext", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL },
-@@ -123,6 +124,7 @@
- { TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_setcontext, "setcontext", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL },
-@@ -160,6 +162,15 @@
- { TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_create, "thr_create", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_new, "thr_new", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_self, "thr_self", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", NULL, NULL, NULL },
-+{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL },
- { TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL },
- { TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL },
-diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h
-index 285e7f9..28481ce 100644
---- a/bsd-user/i386/target_signal.h
-+++ b/bsd-user/i386/target_signal.h
-@@ -11,4 +11,29 @@ static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
- #define TARGET_MINSIGSTKSZ (512 * 4)
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-
-+typedef target_ulong target_mcontext_t; /* dummy */
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
-+static inline int
-+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "i386 doesn't have support for get_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
-+static inline int
-+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "i386 doesn't have support for set_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-diff --git a/bsd-user/main.c b/bsd-user/main.c
-index 146f022..7a99537 100644
---- a/bsd-user/main.c
-+++ b/bsd-user/main.c
-@@ -34,6 +34,10 @@
- #include "qemu/timer.h"
- #include "qemu/envlist.h"
-
-+#if defined(CONFIG_USE_NPTL) && defined(__FreeBSD__)
-+#include <sys/thr.h>
-+#endif
-+
- int singlestep;
- #if defined(CONFIG_USE_GUEST_BASE)
- unsigned long mmap_min_addr;
-@@ -68,41 +72,185 @@ int cpu_get_pic_interrupt(CPUX86State *e
- }
- #endif
-
--/* These are no-ops because we are not threadsafe. */
--static inline void cpu_exec_start(CPUArchState *env)
-+#if defined(CONFIG_USE_NPTL)
-+/* Helper routines for implementing atomic operations. */
-+
-+/*
-+ * To implement exclusive operations we force all cpus to synchronize.
-+ * We don't require a full sync, only that no cpus are executing guest code.
-+ * The alternative is to map target atomic ops onto host eqivalents,
-+ * which requires quite a lot of per host/target work.
-+ */
-+static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-+static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
-+static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
-+static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
-+static int pending_cpus;
-+
-+/* Make sure everything is in a consistent state for calling fork(). */
-+void fork_start(void)
- {
-+ pthread_mutex_lock(&tb_lock);
-+ pthread_mutex_lock(&exclusive_lock);
-+ mmap_fork_start();
- }
-
--static inline void cpu_exec_end(CPUArchState *env)
-+void fork_end(int child)
- {
-+ mmap_fork_end(child);
-+ if (child) {
-+ /*
-+ * Child processes created by fork() only have a single thread.
-+ * Discard information about the parent threads.
-+ */
-+ first_cpu = thread_env;
-+ thread_env->next_cpu = NULL;
-+ pending_cpus = 0;
-+ pthread_mutex_init(&exclusive_lock, NULL);
-+ 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);
-+ gdbserver_fork(thread_env);
-+ } else {
-+ pthread_mutex_unlock(&exclusive_lock);
-+ pthread_mutex_unlock(&tb_lock);
-+ }
- }
-
--static inline void start_exclusive(void)
-+/*
-+ * Wait for pending exclusive operations to complete. The exclusive lock
-+ * must be held.
-+ */
-+static inline void
-+exclusive_idle(void)
- {
-+ while (pending_cpus) {
-+ pthread_cond_wait(&exclusive_resume, &exclusive_lock);
-+ }
- }
-
--static inline void end_exclusive(void)
-+/* Start an exclusive operation. Must only be called outside of cpu_exec. */
-+static inline void
-+start_exclusive(void)
-+{
-+ CPUArchState *other;
-+
-+ pthread_mutex_lock(&exclusive_lock);
-+ exclusive_idle();
-+
-+ pending_cpus = 1;
-+ /* Make all other cpus stop executing. */
-+ for (other = first_cpu; other; other = other->next_cpu) {
-+ if (other->running) {
-+ pending_cpus++;
-+ cpu_exit(other);
-+ }
-+ }
-+ if (pending_cpus > 1) {
-+ pthread_cond_wait(&exclusive_cond, &exclusive_lock);
-+ }
-+}
-+
-+/* Finish an exclusive operation. */
-+static inline void
-+end_exclusive(void)
-+{
-+ pending_cpus = 0;
-+ pthread_cond_broadcast(&exclusive_resume);
-+ pthread_mutex_unlock(&exclusive_lock);
-+}
-+
-+/* Wait for exclusive ops to finish, and begin cpu execution. */
-+static inline void
-+cpu_exec_start(CPUArchState *env)
-+{
-+ pthread_mutex_lock(&exclusive_lock);
-+ exclusive_idle();
-+ env->running = 1;
-+ pthread_mutex_unlock(&exclusive_lock);
-+}
-+
-+/* Mark cpu as not excuting, and release pending exclusive ops. */
-+static inline void
-+cpu_exec_end(CPUArchState *env)
-+{
-+ pthread_mutex_lock(&exclusive_lock);
-+ env->running = 0;
-+ if (pending_cpus > 1) {
-+ pending_cpus--;
-+ if (pending_cpus == 1) {
-+ pthread_cond_signal(&exclusive_cond);
-+ }
-+ }
-+ exclusive_idle();
-+ pthread_mutex_unlock(&exclusive_lock);
-+}
-+
-+void
-+cpu_list_lock(void)
- {
-+ pthread_mutex_lock(&cpu_list_mutex);
- }
-
--void fork_start(void)
-+void
-+cpu_list_unlock(void)
- {
-+ pthread_mutex_unlock(&cpu_list_mutex);
- }
-
--void fork_end(int child)
-+#else /* ! CONFIG_USE_NPTL */
-+
-+/* These are no-ops because we are not threadsafe. */
-+void
-+fork_start(void)
-+{
-+}
-+
-+void
-+fork_end(int child)
- {
- if (child) {
- gdbserver_fork(thread_env);
- }
- }
-
--void cpu_list_lock(void)
-+static inline void
-+exclusive_idle(void)
-+{
-+}
-+
-+static inline void
-+start_exclusive(void)
-+{
-+}
-+
-+static inline void
-+end_exclusive(void)
-+{
-+}
-+
-+static inline void
-+cpu_exec_start(CPUArchState *env)
- {
- }
-
--void cpu_list_unlock(void)
-+
-+static inline void
-+cpu_exec_end(CPUArchState *env)
-+{
-+}
-+
-+void
-+cpu_list_lock(void)
-+{
-+}
-+
-+void
-+cpu_list_unlock(void)
- {
- }
-+#endif /* CONFIG_USE_NPTL */
-
- #ifdef TARGET_I386
- /***********************************************************/
-@@ -738,7 +886,10 @@ 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 */
-@@ -1204,6 +1355,18 @@ static void usage(void)
-
- THREAD CPUArchState *thread_env;
-
-+void task_settid(TaskState *ts)
-+{
-+ if (0 == ts->ts_tid) {
-+#ifdef CONFIG_USE_NPTL
-+ (void)thr_self(&ts->ts_tid);
-+#else
-+ /* When no threads then just use PID */
-+ ts->ts_tid = getpid();
-+#endif
-+ }
-+}
-+
- void stop_all_tasks(void)
- {
- /*
-diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h
-index 28871c3..484cfd8 100644
---- a/bsd-user/mips/target_signal.h
-+++ b/bsd-user/mips/target_signal.h
-@@ -6,9 +6,187 @@
- #define TARGET_MINSIGSTKSZ (512 * 4)
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-
--static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
-+struct target_sigcontext {
-+ target_sigset_t sc_mask; /* signal mask to retstore */
-+ int32_t sc_onstack; /* sigstack state to restore */
-+ abi_long sc_pc; /* pc at time of signal */
-+ abi_long sc_reg[32]; /* processor regs 0 to 31 */
-+ abi_long mullo, mulhi; /* mullo and mulhi registers */
-+ int32_t sc_fpused; /* fp has been used */
-+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */
-+ abi_long sc_fpc_eir; /* fp exception instr reg */
-+ /* int32_t reserved[8]; */
-+};
-+
-+typedef struct target_mcontext {
-+ int32_t mc_onstack; /* sigstack state to restore */
-+ abi_long mc_pc; /* pc at time of signal */
-+ abi_long mc_regs[32]; /* process regs 0 to 31 */
-+ abi_long sr; /* status register */
-+ abi_long mullo, mulhi;
-+ int32_t mc_fpused; /* fp has been used */
-+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */
-+ abi_long mc_fpc_eir; /* fp exception instr reg */
-+ abi_ulong mc_tls; /* pointer to TLS area */
-+} target_mcontext_t;
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
-+struct target_sigframe {
-+ abi_ulong sf_signum;
-+ abi_ulong sf_siginfo; /* code or pointer to sf_si */
-+ abi_ulong sf_ucontext; /* points to sf_uc */
-+ abi_ulong sf_addr; /* undocumented 4th arg */
-+ target_ucontext_t sf_uc; /* = *sf_uncontext */
-+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/
-+ uint32_t __spare__[2];
-+};
-+
-+
-+/* Get the stack pointer. */
-+static inline abi_ulong
-+get_sp_from_cpustate(CPUMIPSState *state)
- {
- return state->active_tc.gpr[29];
- }
-
-+/*
-+ * Compare to mips/mips/pm_machdep.c sendsig()
-+ * Assumes that "frame" memory is locked.
-+ */
-+static inline int
-+set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
-+ abi_ulong frame_addr, struct target_sigaction *ka)
-+{
-+
-+ frame->sf_signum = sig;
-+ frame->sf_siginfo = 0;
-+ frame->sf_ucontext = 0;
-+
-+ frame->sf_si.si_signo = sig;
-+ frame->sf_si.si_code = TARGET_SA_SIGINFO;
-+ frame->sf_si.si_addr = regs->CP0_BadVAddr;
-+
-+ /*
-+ * Arguments to signal handler:
-+ * a0 ($4) = signal number
-+ * a1 ($5) = siginfo pointer
-+ * a2 ($6) = ucontext pointer
-+ * PC = signal handler pointer
-+ * t9 ($25) = signal handler pointer
-+ * $29 = point to sigframe struct
-+ * ra ($31) = sigtramp at base of user stack
-+ */
-+ regs->active_tc.gpr[ 4] = sig;
-+ regs->active_tc.gpr[ 5] = frame_addr +
-+ offsetof(struct target_sigframe, sf_si);
-+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler;
-+ regs->active_tc.gpr[29] = frame_addr;
-+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
-+
-+ return (0);
-+}
-+
-+/*
-+ * Compare to mips/mips/pm_machdep.c get_mcontext()
-+ * Assumes that the memory is locked if mcp points to user memory.
-+ */
-+static inline int
-+get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ int i, err = 0;
-+
-+ if (flags & TARGET_MC_ADD_MAGIC) {
-+ mcp->mc_regs[0] = tswapal(TARGET_UCONTEXT_MAGIC);
-+ } else {
-+ mcp->mc_regs[0] = 0;
-+ }
-+
-+ if (flags & TARGET_MC_SET_ONSTACK) {
-+ mcp->mc_onstack = tswapal(1);
-+ } else {
-+ mcp->mc_onstack = 0;
-+ }
-+
-+ for(i = 1; i < 32; i++)
-+ mcp->mc_regs[i] = tswapal(regs->active_tc.gpr[i]);
-+
-+#if 0 /* XXX FP is not used right now. */
-+ abi_ulong used_fp = used_math() ? TARGET_MDTD_FPUSED : 0;
-+
-+ mcp->mc_fpused = used_fp;
-+ if (used_fp) {
-+ preempt_disable();
-+ if (!is_fpu_owner()) {
-+ own_fpu();
-+ for(i = 0; i < 33; i++)
-+ mcp->mc_fpregs[i] = tswapal(regs->active_fpu.fpr[i]);
-+ }
-+ preempt_enable();
-+ }
-+#else
-+ mcp->mc_fpused = 0;
-+#endif
-+
-+ if (flags & TARGET_MC_GET_CLEAR_RET) {
-+ mcp->mc_regs[2] = 0; /* v0 = 0 */
-+ mcp->mc_regs[3] = 0; /* v1 = 0 */
-+ mcp->mc_regs[7] = 0; /* a3 = 0 */
-+ }
-+
-+ mcp->mc_pc = tswapal(regs->active_tc.PC);
-+ mcp->mullo = tswapal(regs->active_tc.LO[0]);
-+ mcp->mulhi = tswapal(regs->active_tc.HI[0]);
-+ mcp->mc_tls = tswapal(regs->tls_value);
-+
-+ /* Don't do any of the status and cause registers. */
-+
-+ return (err);
-+}
-+
-+/* Compare to mips/mips/pm_machdep.c set_mcontext() */
-+static inline int
-+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ int i, err = 0;
-+
-+ for(i = 1; i < 32; i++)
-+ regs->active_tc.gpr[i] = tswapal(mcp->mc_regs[i]);
-+
-+#if 0 /* XXX FP is not used right now */
-+ abi_ulong used_fp = 0;
-+
-+ used_fp = tswapal(mcp->mc_fpused)
-+ conditional_used_math(used_fp);
-+
-+ preempt_disabled();
-+ if (used_math()) {
-+ /* restore fpu context if we have used it before */
-+ own_fpu();
-+ for (i = 0; i < 32; i++)
-+ regs->active_fpu.fpr[i] = tswapal(mcp->mc_fpregs[i]);
-+ } else {
-+ /* Signal handler may have used FPU. Give it up. */
-+ lose_fpu();
-+ }
-+ preempt_enable();
-+#endif
-+
-+ regs->CP0_EPC = tswapal(mcp->mc_pc);
-+ regs->active_tc.LO[0] = tswapal(mcp->mullo);
-+ regs->active_tc.HI[0] = tswapal(mcp->mulhi);
-+ regs->tls_value = tswapal(mcp->mc_tls);
-+
-+ /* Don't do any of the status and cause registers. */
-+
-+ return (err);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h
-index d671f4e..e9c8a9f 100644
---- a/bsd-user/mips64/target_signal.h
-+++ b/bsd-user/mips64/target_signal.h
-@@ -7,11 +7,186 @@
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
- #define TARGET_SZSIGCODE 16
-
--#define TARGET_UCONTEXT_MAGIC 0xACEDBADE
-+struct target_sigcontext {
-+ target_sigset_t sc_mask; /* signal mask to retstore */
-+ int32_t sc_onstack; /* sigstack state to restore */
-+ abi_long sc_pc; /* pc at time of signal */
-+ abi_long sc_reg[32]; /* processor regs 0 to 31 */
-+ abi_long mullo, mulhi; /* mullo and mulhi registers */
-+ int32_t sc_fpused; /* fp has been used */
-+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */
-+ abi_long sc_fpc_eir; /* fp exception instr reg */
-+ /* int32_t reserved[8]; */
-+};
-
--static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
-+typedef struct target_mcontext {
-+ int32_t mc_onstack; /* sigstack state to restore */
-+ abi_long mc_pc; /* pc at time of signal */
-+ abi_long mc_regs[32]; /* process regs 0 to 31 */
-+ abi_long sr; /* status register */
-+ abi_long mullo, mulhi;
-+ int32_t mc_fpused; /* fp has been used */
-+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */
-+ abi_long mc_fpc_eir; /* fp exception instr reg */
-+ abi_ulong mc_tls; /* pointer to TLS area */
-+} target_mcontext_t;
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
-+struct target_sigframe {
-+ abi_ulong sf_signum;
-+ abi_ulong sf_siginfo; /* code or pointer to sf_si */
-+ abi_ulong sf_ucontext; /* points to sf_uc */
-+ abi_ulong sf_addr; /* undocumented 4th arg */
-+ target_ucontext_t sf_uc; /* = *sf_uncontext */
-+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/
-+ uint32_t __spare__[2];
-+};
-+
-+static inline abi_ulong
-+get_sp_from_cpustate(CPUMIPSState *state)
- {
- return state->active_tc.gpr[29];
- }
-
-+/*
-+ * Compare to mips/mips/pm_machdep.c sendsig()
-+ * Assumes that "frame" memory is locked.
-+ */
-+static inline int
-+set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
-+ abi_ulong frame_addr, struct target_sigaction *ka)
-+{
-+
-+ frame->sf_signum = sig;
-+ frame->sf_siginfo = 0;
-+ frame->sf_ucontext = 0;
-+
-+ frame->sf_si.si_signo = sig;
-+ frame->sf_si.si_code = TARGET_SA_SIGINFO;
-+ frame->sf_si.si_addr = regs->CP0_BadVAddr;
-+
-+ /*
-+ * Arguments to signal handler:
-+ * a0 ($4) = signal number
-+ * a1 ($5) = siginfo pointer
-+ * a2 ($6) = ucontext pointer
-+ * PC = signal handler pointer
-+ * t9 ($25) = signal handler pointer
-+ * $29 = point to sigframe struct
-+ * ra ($31) = sigtramp at base of user stack
-+ */
-+ regs->active_tc.gpr[ 4] = sig;
-+ regs->active_tc.gpr[ 5] = frame_addr +
-+ offsetof(struct target_sigframe, sf_si);
-+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler;
-+ regs->active_tc.gpr[29] = frame_addr;
-+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
-+
-+ return (0);
-+}
-+
-+/*
-+ * Compare to mips/mips/pm_machdep.c get_mcontext()
-+ * Assumes that the memory is locked if mcp points to user memory.
-+ */
-+static inline int
-+get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ int i, err = 0;
-+
-+ if (flags & TARGET_MC_ADD_MAGIC) {
-+ mcp->mc_regs[0] = tswapal(TARGET_UCONTEXT_MAGIC);
-+ } else {
-+ mcp->mc_regs[0] = 0;
-+ }
-+
-+ if (flags & TARGET_MC_SET_ONSTACK) {
-+ mcp->mc_onstack = tswapal(1);
-+ } else {
-+ mcp->mc_onstack = 0;
-+ }
-+
-+ for(i = 1; i < 32; i++)
-+ mcp->mc_regs[i] = tswapal(regs->active_tc.gpr[i]);
-+
-+#if 0 /* XXX FP is not used right now */
-+ abi_ulong used_fp = used_math() ? TARGET_MDTD_FPUSED : 0;
-+
-+ mcp->mc_fpused = used_fp;
-+ if (used_fp) {
-+ preempt_disable();
-+ if (!is_fpu_owner()) {
-+ own_fpu();
-+ for(i = 0; i < 33; i++)
-+ mcp->mc_fpregs[i] = tswapal(regs->active_fpu.fpr[i]);
-+ }
-+ preempt_enable();
-+ }
-+#else
-+ mcp->mc_fpused = 0;
-+#endif
-+
-+ if (flags & TARGET_MC_GET_CLEAR_RET) {
-+ mcp->mc_regs[2] = 0; /* v0 = 0 */
-+ mcp->mc_regs[3] = 0; /* v1 = 0 */
-+ mcp->mc_regs[7] = 0; /* a3 = 0 */
-+ }
-+
-+ mcp->mc_pc = tswapal(regs->active_tc.PC);
-+ mcp->mullo = tswapal(regs->active_tc.LO[0]);
-+ mcp->mulhi = tswapal(regs->active_tc.HI[0]);
-+ mcp->mc_tls = tswapal(regs->tls_value);
-+
-+ /* Don't do any of the status and cause registers. */
-+
-+ return (err);
-+}
-+
-+/* Compare to mips/mips/pm_machdep.c set_mcontext() */
-+static inline int
-+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ int i, err = 0;
-+
-+ for(i = 1; i < 32; i++)
-+ regs->active_tc.gpr[i] = tswapal(mcp->mc_regs[i]);
-+
-+#if 0 /* XXX FP is not used right now */
-+ abi_ulong used_fp = 0;
-+
-+ used_fp = tswapal(mcp->mc_fpused)
-+ conditional_used_math(used_fp);
-+
-+ preempt_disabled();
-+ if (used_math()) {
-+ /* restore fpu context if we have used it before */
-+ own_fpu();
-+ for (i = 0; i < 32; i++)
-+ regs->active_fpu.fpr[i] = tswapal(mcp->mc_fpregs[i]);
-+ } else {
-+ /* Signal handler may have used FPU. Give it up. */
-+ lose_fpu();
-+ }
-+ preempt_enable();
-+#endif
-+
-+ regs->CP0_EPC = tswapal(mcp->mc_pc);
-+ regs->active_tc.LO[0] = tswapal(mcp->mullo);
-+ regs->active_tc.HI[0] = tswapal(mcp->mulhi);
-+ regs->tls_value = tswapal(mcp->mc_tls);
-+
-+ /* Don't do any of the status and cause registers. */
-+
-+ return (err);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-+
-diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
---- a/bsd-user/mmap.c
-+++ b/bsd-user/mmap.c
-@@ -74,6 +74,8 @@ void mmap_unlock(void)
- }
- #endif
-
-+#if 0 /* XXX not sure why we need our own g_malloc() and friends.
-+ g_strdup(), however, has serious problems with this g_malloc/g_free */
- static void *bsd_vmalloc(size_t size)
- {
- void *p;
-@@ -133,6 +135,7 @@ void *g_realloc(void *ptr, size_t size)
- g_free(ptr);
- return new_ptr;
- }
-+#endif
-
- /* NOTE: all the constants are the HOST ones, but addresses are target. */
- int target_mprotect(abi_ulong start, abi_ulong len, int prot)
-diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
-index ab7e18c..9d4edbf 100644
---- a/bsd-user/qemu.h
-+++ b/bsd-user/qemu.h
-@@ -80,7 +80,7 @@ struct emulated_sigtable {
- typedef struct TaskState {
- struct TaskState *next;
- int used; /* non zero if used */
--#if 1
-+ long ts_tid; /* tid (or pid) of this task */
- #ifdef TARGET_ARM
- int swi_errno;
- #endif
-@@ -90,7 +90,6 @@ typedef struct TaskState {
- uint32_t heap_limit;
- #endif
- uint32_t stack_base;
--#endif
- struct image_info *info;
- struct bsd_binprm *bprm;
-
-diff --git a/bsd-user/signal.c b/bsd-user/signal.c
-index 52441c4..d56837b 100644
---- a/bsd-user/signal.c
-+++ b/bsd-user/signal.c
-@@ -31,7 +31,7 @@
- #include "qemu.h"
- #include "target_signal.h"
-
--//#define DEBUG_SIGNAL
-+// #define DEBUG_SIGNAL
-
- #ifndef _NSIG
- #define _NSIG 128
-@@ -606,101 +606,31 @@ do_sigaction(int sig, const struct target_sigaction *act,
- return (ret);
- }
-
--#if defined(TARGET_MIPS64)
--static inline int
--restore_sigmcontext(CPUMIPSState *regs, target_mcontext_t *mc)
--{
-- int i, err = 0;
--
-- for(i = 1; i < 32; i++)
-- err |= __get_user(regs->active_tc.gpr[i],
-- &mc->mc_regs[i]);
-- err |= __get_user(regs->CP0_EPC, &mc->mc_pc);
-- err |= __get_user(regs->active_tc.LO[0], &mc->mullo);
-- err |= __get_user(regs->active_tc.HI[0], &mc->mulhi);
-- err |= __get_user(regs->tls_value, &mc->mc_tls); /* XXX thread tls */
--
--#if 0 /* XXX */
-- int used_fp = 0;
--
-- err |= __get_user(used_fp, &mc->mc_fpused);
-- conditional_used_math(used_fp);
--
-- preempt_disabled();
-- if (used_math()) {
-- /* restore fpu context if we have used it before */
-- own_fpu();
-- err |= restore_fp_context(mc);
-- } else {
-- /* signal handler may have used FPU. Give it up. */
-- lose_fpu();
-- }
-- preempt_enable();
--#endif
--
-- return (err);
--}
--
--static inline int
--setup_sigmcontext(CPUMIPSState *regs, target_mcontext_t *mc, int32_t oonstack)
--{
-- int i, err = 0;
-- abi_long ucontext_magic = TARGET_UCONTEXT_MAGIC;
--
-- err = __put_user(oonstack ? 1 : 0, &mc->mc_onstack);
-- err |= __put_user(regs->active_tc.PC, &mc->mc_pc);
-- err |= __put_user(regs->active_tc.LO[0], &mc->mullo);
-- err |= __put_user(regs->active_tc.HI[0], &mc->mulhi);
-- err |= __put_user(regs->tls_value, &mc->mc_tls); /* XXX thread tls */
--
-- err |= __put_user(ucontext_magic, &mc->mc_regs[0]);
-- for(i = 1; i < 32; i++)
-- err |= __put_user(regs->active_tc.gpr[i], &mc->mc_regs[i]);
--
-- err |= __put_user(0, &mc->mc_fpused);
--
--#if 0 /* XXX */
-- err |= __put_user(used_math(), &mc->mc_fpused);
-- if (used_math())
-- goto out;
--
-- /*
-- * Save FPU state to signal context. Signal handler will "inherit"
-- * current FPU state.
-- */
-- preempt_disable();
--
-- if (!is_fpu_owner()) {
-- own_fpu();
-- for(i = 0; i < 33; i++)
-- err |= __put_user(regs->active_tc.fpregs[i], &mc->mc_fpregs[i]);
-- }
-- err |= save_fp_context(fg);
--
-- preempt_enable();
--out:
--#endif
-- return (err);
--}
-+#if defined(TARGET_MIPS) || defined(TARGET_SPARC64)
-
- static inline abi_ulong
--get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
-+get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size)
- {
- abi_ulong sp;
-
- /* Use default user stack */
-- sp = regs->active_tc.gpr[29];
-+ sp = get_sp_from_cpustate(regs);
-
- if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
-- sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
-+ sp = target_sigaltstack_used.ss_sp +
-+ target_sigaltstack_used.ss_size;
- }
-
-+#if defined(TARGET_MIPS)
- return ((sp - frame_size) & ~7);
-+#else
-+ return (sp - frame_size);
-+#endif
- }
-
--/* compare to mips/mips/pm_machdep.c sendsig() */
-+/* compare to mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c sendsig() */
- static void setup_frame(int sig, struct target_sigaction *ka,
-- target_sigset_t *set, CPUMIPSState *regs)
-+ target_sigset_t *set, CPUArchState *regs)
- {
- struct target_sigframe *frame;
- abi_ulong frame_addr;
-@@ -709,54 +639,36 @@ static void setup_frame(int sig, struct target_sigaction *ka,
- #ifdef DEBUG_SIGNAL
- fprintf(stderr, "setup_frame()\n");
- #endif
-+#if defined(TARGET_SPARC64)
-+ if (!sparc_user_sigtramp) {
-+ /* No signal trampoline... kill the process. */
-+ fprintf(stderr, "setup_frame(): no sigtramp\n");
-+ force_sig(TARGET_SIGKILL);
-+ }
-+#endif
-
- frame_addr = get_sigframe(ka, regs, sizeof(*frame));
- if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
- goto give_sigsegv;
-
-- if (setup_sigmcontext(regs, &frame->sf_uc.uc_mcontext,
-- ! on_sig_stack(frame_addr)))
-+#if defined(TARGET_MIPS)
-+ int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC :
-+ TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC;
-+#else
-+ int mflags = 0;
-+#endif
-+ if (get_mcontext(regs, &frame->sf_uc.uc_mcontext, mflags))
- goto give_sigsegv;
-
- for(i = 0; i < TARGET_NSIG_WORDS; i++) {
-- if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i]))
-+ if (__put_user(set->__bits[i],
-+ &frame->sf_uc.uc_sigmask.__bits[i]))
- goto give_sigsegv;
- }
-
-- /* fill in sigframe structure */
-- if (__put_user(sig, &frame->sf_signum))
-- goto give_sigsegv;
-- if (__put_user(0, &frame->sf_siginfo))
-- goto give_sigsegv;
-- if (__put_user(0, &frame->sf_ucontext))
-+ if (set_sigtramp_args(regs, sig, frame, frame_addr, ka))
- goto give_sigsegv;
-
-- /* fill in siginfo structure */
-- if (__put_user(sig, &frame->sf_si.si_signo))
-- goto give_sigsegv;
-- if (__put_user(TARGET_SA_SIGINFO, &frame->sf_si.si_code))
-- goto give_sigsegv;
-- if (__put_user(regs->CP0_BadVAddr, &frame->sf_si.si_addr))
-- goto give_sigsegv;
--
-- /*
-- * Arguments to signal handler:
-- * a0 ($4) = signal number
-- * a1 ($5) = siginfo pointer
-- * a2 ($6) = ucontext pointer
-- * PC = signal handler pointer
-- * t9 ($25) = signal handler pointer
-- * $29 = point to sigframe struct
-- * ra ($31) = sigtramp at base of user stack
-- */
-- regs->active_tc.gpr[ 4] = sig;
-- regs->active_tc.gpr[ 5] = frame_addr +
-- offsetof(struct target_sigframe, sf_si);
-- regs->active_tc.gpr[ 6] = frame_addr +
-- offsetof(struct target_sigframe, sf_uc);
-- regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler;
-- regs->active_tc.gpr[29] = frame_addr;
-- regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
- unlock_user_struct(frame, frame_addr, 1);
- return;
-
-@@ -766,7 +678,7 @@ give_sigsegv:
- }
-
- long
--do_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr)
-+do_sigreturn(CPUArchState *regs, abi_ulong uc_addr)
- {
- target_ucontext_t *ucontext;
- sigset_t blocked;
-@@ -784,14 +696,17 @@ do_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr)
- goto badframe;
- }
-
-- if (restore_sigmcontext(regs, &ucontext->uc_mcontext))
-+ if (set_mcontext(regs, &ucontext->uc_mcontext, 0))
- goto badframe;
-
- target_to_host_sigset_internal(&blocked, &target_set);
- sigprocmask(SIG_SETMASK, &blocked, NULL);
-
-- regs->active_tc.PC = regs->CP0_EPC;
-- regs->CP0_EPC = 0; /* XXX for nested signals ? */
-+#if defined(TARGET_MIPS)
-+ CPUMIPSState *mips_regs = (CPUMIPSState *)regs;
-+ mips_regs->active_tc.PC = mips_regs->CP0_EPC;
-+ mips_regs->CP0_EPC = 0; /* XXX for nested signals ? */
-+#endif
- return (-TARGET_QEMU_ESIGRETURN);
-
- badframe:
-@@ -799,9 +714,10 @@ badframe:
- return (0);
- }
-
--#elif defined(TARGET_SPARC64)
-
--extern abi_ulong sparc_user_sigtramp;
-+
-+/* #elif defined(TARGET_SPARC64) */
-+#if 0
-
- #define mc_flags mc_global[0]
- #define mc_sp mc_out[6]
-@@ -1039,6 +955,7 @@ badframe:
- force_sig(TARGET_SIGSEGV);
- return (0);
- }
-+#endif
-
- #else
-
-diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h
-index 79dfc1e..e2fe79c 100644
---- a/bsd-user/sparc/target_signal.h
-+++ b/bsd-user/sparc/target_signal.h
-@@ -13,9 +13,34 @@
- #define TARGET_MINSIGSTKSZ (512 * 4)
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-
-+typedef target_ulong target_mcontext_t; /* dummy */
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
- static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
- {
- return state->regwptr[UREG_FP];
- }
-
-+static inline int
-+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "SPARC doesn't have support for get_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
-+static inline int
-+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "SPARC doesn't have support for set_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h
-index d3e58bb..1bc7c96 100644
---- a/bsd-user/sparc64/target_signal.h
-+++ b/bsd-user/sparc64/target_signal.h
-@@ -10,12 +10,239 @@
- #define UREG_FP UREG_I6
- #endif
-
-+#define mc_flags mc_global[0]
-+#define mc_sp mc_out[6]
-+#define mc_fprs mc_local[0]
-+#define mc_fsr mc_local[1]
-+#define mc_gsr mc_local[2]
-+#define mc_tnpc mc_in[0]
-+#define mc_tpc mc_in[1]
-+#define mc_tstate mc_in[2]
-+#define mc_y mc_in[4]
-+#define mc_wstate mc_in[5]
-+
-+#define ureg_i0 regwptr[0 ]
-+#define ureg_i1 regwptr[1 ]
-+#define ureg_i2 regwptr[2 ]
-+#define ureg_i3 regwptr[3 ]
-+#define ureg_i4 regwptr[4 ]
-+#define ureg_i5 regwptr[5 ]
-+#define ureg_i6 regwptr[6 ]
-+#define ureg_i7 regwptr[7 ]
-+#define ureg_l0 regwptr[8 ]
-+#define ureg_l1 regwptr[9 ]
-+#define ureg_l2 regwptr[10]
-+#define ureg_l3 regwptr[11]
-+#define ureg_l4 regwptr[12]
-+#define ureg_l5 regwptr[13]
-+#define ureg_l6 regwptr[14]
-+#define ureg_l7 regwptr[15]
-+#define ureg_o0 regwptr[16]
-+#define ureg_o1 regwptr[17]
-+#define ureg_o2 regwptr[18]
-+#define ureg_o3 regwptr[19]
-+#define ureg_o4 regwptr[20]
-+#define ureg_o5 regwptr[21]
-+#define ureg_o6 regwptr[22]
-+#define ureg_o7 regwptr[23]
-+#define ureg_fp ureg_i6
-+#define ureg_sp ureg_o6
-+#define ureg_fprs fprs
-+#define ureg_fsr fsr
-+#define ureg_gsr gsr
-+#define ureg_tnpc npc
-+#define ureg_tpc pc
-+#define ureg_y y
-+
-+#define TARGET_FPRS_FEF (1 << 2)
-+#define TARGET_MC_VERSION 1L
-+
- #define TARGET_MINSIGSTKSZ (1024 * 4)
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-
--static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
-+#define TARGET_STACK_BIAS 2047 /* AKA. SPOFF */
-+
-+struct target_mcontext {
-+ uint64_t mc_global[8];
-+ uint64_t mc_out[8];
-+ uint64_t mc_local[8];
-+ uint64_t mc_in[8];
-+ uint32_t mc_fp[64];
-+} __aligned(64);
-+
-+typedef struct target_mcontext target_mcontext_t;
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
-+struct target_sigframe {
-+ target_ucontext_t sf_uc;
-+ target_siginfo_t sf_si;
-+};
-+
-+extern abi_ulong sparc_user_sigtramp;
-+
-+static inline int
-+set_sigtramp_args(CPUSPARCState *regs, int sig, struct target_sigframe *frame,
-+ abi_ulong frame_addr, struct target_sigaction *ka)
- {
-+
-+ frame->sf_si.si_signo = sig;
-+ frame->sf_si.si_code = TARGET_SA_SIGINFO;
-+
-+ /* Arguments to signal handler:
-+ *
-+ * i0 = signal number
-+ * i1 = pointer to siginfo struct
-+ * i2 = pointer to ucontext struct
-+ * i3 = (not used in new style)
-+ * i4 = signal handler address (called by sigtramp)
-+ */
-+ regs->ureg_i0 = sig;
-+ regs->ureg_i1 = frame_addr +
-+ offsetof(struct target_sigframe, sf_si);
-+ regs->ureg_i2 = frame_addr +
-+ offsetof(struct target_sigframe, sf_uc);
-+ /* env->ureg_o3 used in the Old FreeBSD-style arguments. */
-+ regs->ureg_i4 = ka->_sa_handler;
-+ regs->ureg_tpc = sparc_user_sigtramp;
-+ regs->ureg_tnpc = (regs->ureg_tpc + 4);
-+ regs->ureg_sp = frame_addr - TARGET_STACK_BIAS;
-+
-+ return (0);
-+}
-+
-+static inline abi_ulong
-+get_sp_from_cpustate(CPUSPARCState *state)
-+{
-+
- return state->regwptr[UREG_FP];
- }
-
-+/* compare to sparc64/sparc64/machdep.c get_mcontext() */
-+static inline int
-+get_mcontext(CPUSPARCState *regs, target_mcontext_t *mcp, int flags)
-+{
-+
-+ /* Skip over the trap instruction, first. */
-+ regs->pc = regs->npc;
-+ regs->npc += 4;
-+
-+ mcp->mc_flags = TARGET_MC_VERSION; /* mc_global[0] */
-+ mcp->mc_global[1] = tswapal(regs->gregs[1]);
-+ mcp->mc_global[2] = tswapal(regs->gregs[2]);
-+ mcp->mc_global[3] = tswapal(regs->gregs[3]);
-+ mcp->mc_global[4] = tswapal(regs->gregs[4]);
-+ mcp->mc_global[5] = tswapal(regs->gregs[5]);
-+ mcp->mc_global[6] = tswapal(regs->gregs[6]);
-+ /* skip %g7 since it is used as the userland TLS register */
-+
-+ if (flags & TARGET_MC_GET_CLEAR_RET) {
-+ mcp->mc_out[0] = 0;
-+ mcp->mc_out[1] = 0;
-+ } else {
-+ mcp->mc_out[0] = tswapal(regs->ureg_i0);
-+ mcp->mc_out[1] = tswapal(regs->ureg_i1);
-+ }
-+ mcp->mc_out[2] = tswapal(regs->ureg_i2);
-+ mcp->mc_out[3] = tswapal(regs->ureg_i3);
-+ mcp->mc_out[4] = tswapal(regs->ureg_i4);
-+ mcp->mc_out[5] = tswapal(regs->ureg_i5);
-+ mcp->mc_out[6] = tswapal(regs->ureg_i6);
-+ mcp->mc_out[7] = tswapal(regs->ureg_i7);
-+
-+ mcp->mc_fprs = tswapal(regs->fprs); /* mc_local[0] */
-+ mcp->mc_fsr = tswapal(regs->fsr); /* mc_local[1] */
-+ mcp->mc_gsr = tswapal(regs->gsr); /* mc_local[2] */
-+
-+ mcp->mc_tnpc = tswapal(regs->npc); /* mc_in[0] */
-+ mcp->mc_tpc = tswapal(regs->pc); /* mc_in[1] */
-+#if 0
-+ mcp->mc_tstate = tswapal(regs->ureg_tstate); /* mc_in[2] */
-+#else
-+ abi_ulong cwp64 = cpu_get_cwp64(regs);
-+ abi_ulong ccr = cpu_get_ccr(regs) << 32;
-+ abi_ulong asi = (regs->asi & 0xff) << 24;
-+ mcp->mc_tstate = tswapal(ccr | asi | cwp64);
-+#endif
-+
-+ mcp->mc_y = tswapal(regs->y); /* mc_in[4] */
-+
-+ /* XXX
-+ if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) {
-+ int i;
-+
-+ for(i = 0; i < 64; i++)
-+ mcp->mc_fp[i] = tswapal(regs->fpr[i]);
-+ }
-+ */
-+
-+ return (0);
-+}
-+
-+extern void helper_flushw(CPUSPARCState *env);
-+
-+/* compare to sparc64/sparc64/machdep.c set_mcontext() */
-+static inline int
-+set_mcontext(CPUSPARCState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ /* XXX need to add version check here. */
-+
-+ /* Make sure the windows are spilled first. */
-+ helper_flushw(regs);
-+
-+ regs->gregs[1] = tswapal(mcp->mc_global[1]);
-+ regs->gregs[2] = tswapal(mcp->mc_global[2]);
-+ regs->gregs[3] = tswapal(mcp->mc_global[3]);
-+ regs->gregs[4] = tswapal(mcp->mc_global[4]);
-+ regs->gregs[5] = tswapal(mcp->mc_global[5]);
-+ regs->gregs[6] = tswapal(mcp->mc_global[6]);
-+
-+ regs->ureg_i0 = tswapal(mcp->mc_out[0]);
-+ regs->ureg_i1 = tswapal(mcp->mc_out[1]);
-+ regs->ureg_i2 = tswapal(mcp->mc_out[2]);
-+ regs->ureg_i3 = tswapal(mcp->mc_out[3]);
-+ regs->ureg_i4 = tswapal(mcp->mc_out[4]);
-+ regs->ureg_i5 = tswapal(mcp->mc_out[5]);
-+ regs->ureg_i6 = tswapal(mcp->mc_out[6]);
-+ regs->ureg_i7 = tswapal(mcp->mc_out[7]);
-+
-+ regs->fprs = tswapal(mcp->mc_fprs); /* mc_local[0] */
-+ regs->fsr = tswapal(mcp->mc_fsr); /* mc_local[1] */
-+ regs->gsr = tswapal(mcp->mc_gsr); /* mc_local[2] */
-+
-+ regs->npc = tswapal(mcp->mc_tnpc); /* mc_in[0] */
-+ regs->pc = tswapal(mcp->mc_tpc); /* mc_in[1] */
-+
-+#if 0
-+ regs->ureg_tstate = tswapal(mcp->mc_tstate); /* mc_in[2] */
-+#else
-+ abi_ulong tstate = tswapal(mcp->mc_tstate); /* mc_in[2] */
-+
-+ regs->asi = (tstate >> 24) & 0xff;
-+ cpu_put_ccr(regs, tstate >> 32);
-+ cpu_put_cwp64(regs, tstate & 0x1f);
-+
-+#endif
-+ regs->ureg_y = tswapal(mcp->mc_y); /* mc_in[4] */
-+
-+ /* XXX
-+ if ((regs->ureg_fprs & TARGET_FPRS_FEF) != 0) {
-+ int i;
-+
-+ regs->ureg_l0 = 0;
-+ for(i = 0; i < 64; i++)
-+ regs->fpr[i] = tswapal(mcp->mc_fp[i]);
-+ }
-+ */
-+
-+ return (0);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
-index 625c3cf..4deb0db 100644
---- a/bsd-user/syscall.c
-+++ b/bsd-user/syscall.c
-@@ -43,6 +43,12 @@
- #ifdef __FreeBSD__
- #include <sys/regression.h>
- #include <sys/procdesc.h>
-+#include <sys/ucontext.h>
-+#include <sys/thr.h>
-+#include <sys/rtprio.h>
-+#include <sys/umtx.h>
-+#include <pthread.h>
-+#include <machine/atomic.h>
- #endif
- #include <sys/un.h>
- #include <sys/ipc.h>
-@@ -251,7 +257,24 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
- #ifdef TARGET_MIPS
- static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
- {
-- return -TARGET_EINVAL;
-+ int ret = 0;
-+ CPUMIPSState *mips_env = (CPUMIPSState *)env;
-+
-+ switch(op) {
-+ case TARGET_MIPS_SET_TLS:
-+ if (get_user(mips_env->tls_value, parms, abi_ulong))
-+ ret = -TARGET_EFAULT;
-+ break;
-+ case TARGET_MIPS_GET_TLS:
-+ if (put_user(mips_env->tls_value, parms, abi_ulong))
-+ ret = -TARGET_EFAULT;
-+ break;
-+ default:
-+ ret = -TARGET_EINVAL;
-+ break;
-+ }
-+
-+ return (ret);
- }
- #endif
-
-@@ -2119,6 +2142,383 @@ do_fork(CPUArchState *env, int num, int flags, int *fdp)
- return (ret);
- }
-
-+#if defined(CONFIG_USE_NPTL)
-+
-+#define NEW_STACK_SIZE (0x40000)
-+
-+static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER;
-+typedef struct {
-+ CPUArchState *env;
-+ long tid;
-+ pthread_mutex_t mutex;
-+ pthread_cond_t cond;
-+ pthread_t thread;
-+ sigset_t sigmask;
-+ struct target_thr_param param;
-+} new_thread_info_t;
-+
-+static void *
-+new_thread_start(void *arg)
-+{
-+ new_thread_info_t *info = arg;
-+ CPUArchState *env;
-+ TaskState *ts;
-+ long tid;
-+
-+ env = info->env;
-+ thread_env = env;
-+ 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);
-+
-+#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 */
-+ sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
-+ /* Signal to the parent that we're ready. */
-+ pthread_mutex_lock(&info->mutex);
-+ pthread_cond_broadcast(&info->cond);
-+ pthread_mutex_unlock(&info->mutex);
-+ /* Wait until the parent has finished initializing the TLS state. */
-+ pthread_mutex_lock(&new_thread_lock);
-+ pthread_mutex_unlock(&new_thread_lock);
-+
-+ cpu_loop(env);
-+ /* never exits */
-+
-+ return (NULL);
-+}
-+
-+static void
-+rtp_to_schedparam(const struct rtprio *rtp, int *policy, struct sched_param *param)
-+{
-+
-+ switch(rtp->type) {
-+ case RTP_PRIO_REALTIME:
-+ *policy = SCHED_RR;
-+ param->sched_priority = RTP_PRIO_MAX - rtp->prio;
-+ break;
-+
-+ case RTP_PRIO_FIFO:
-+ *policy = SCHED_FIFO;
-+ param->sched_priority = RTP_PRIO_MAX - rtp->prio;
-+ break;
-+
-+ default:
-+ *policy = SCHED_OTHER;
-+ param->sched_priority = 0;
-+ break;
-+ }
-+}
-+
-+static int
-+do_thr_create(CPUArchState *env, ucontext_t *ctx, long *id, int flags)
-+{
-+
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_create));
-+}
-+
-+static int
-+do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
-+{
-+ new_thread_info_t info;
-+ pthread_attr_t attr;
-+ TaskState *ts;
-+ CPUArchState *new_env;
-+ struct target_thr_param *target_param;
-+ abi_ulong target_rtp_addr;
-+ struct target_rtprio *target_rtp;
-+ struct rtprio *rtp_ptr, rtp;
-+ TaskState *parent_ts = (TaskState *)env->opaque;
-+ sigset_t sigmask;
-+ struct sched_param sched_param;
-+ int sched_policy;
-+ int ret = 0;
-+
-+ memset(&info, 0, sizeof(info));
-+
-+ if (!lock_user_struct(VERIFY_READ, target_param, target_param_addr, 1))
-+ return (-TARGET_EFAULT);
-+ info.param.start_func = tswapal(target_param->start_func);
-+ info.param.arg = tswapal(target_param->arg);
-+ info.param.stack_base = tswapal(target_param->stack_base);
-+ info.param.stack_size = tswapal(target_param->stack_size);
-+ info.param.tls_base = tswapal(target_param->tls_base);
-+ 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);
-+ target_rtp_addr = info.param.rtp = tswapal(target_param->rtp);
-+ unlock_user(target_param, target_param_addr, 0);
-+
-+ if (target_rtp_addr) {
-+ if (!lock_user_struct(VERIFY_READ, target_rtp, target_rtp_addr,
-+ 1))
-+ return (-TARGET_EFAULT);
-+ rtp.type = tswap16(target_rtp->type);
-+ rtp.prio = tswap16(target_rtp->prio);
-+ unlock_user(target_rtp, target_rtp_addr, 0);
-+ rtp_ptr = &rtp;
-+ } else {
-+ rtp_ptr = NULL;
-+ }
-+
-+ /* Create a new CPU instance. */
-+ ts = g_malloc0(sizeof(TaskState));
-+ init_task_state(ts);
-+ new_env = cpu_copy(env);
-+#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
-+ cpu_reset(ENV_GET_CPU(new_env));
-+#endif
-+
-+ /* init regs that differ from the parent thread. */
-+ cpu_clone_regs(new_env, info.param.stack_base);
-+ new_env->opaque = ts;
-+ 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); */
-+#endif
-+
-+ /* Grab a mutex so that thread setup appears atomic. */
-+ pthread_mutex_lock(&new_thread_lock);
-+
-+ pthread_mutex_init(&info.mutex, NULL);
-+ pthread_mutex_lock(&info.mutex);
-+ pthread_cond_init(&info.cond, NULL);
-+ info.env = new_env;
-+
-+ /* XXX return value needs to be checked... */
-+ pthread_attr_init(&attr);
-+ pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
-+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-+ if (rtp_ptr) {
-+ rtp_to_schedparam(&rtp, &sched_policy, &sched_param);
-+ pthread_attr_setschedpolicy(&attr, sched_policy);
-+ pthread_attr_setschedparam(&attr, &sched_param);
-+ }
-+
-+ /*
-+ * It is not safe to deliver signals until the child has finished
-+ * initializing, so temporarily block all signals.
-+ */
-+ sigfillset(&sigmask);
-+ sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
-+
-+ /* XXX return value needs to be checked... */
-+ ret = pthread_create(&info.thread, &attr, new_thread_start, &info);
-+ /* XXX Free new CPU state if thread creation fails. */
-+
-+ sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
-+ pthread_attr_destroy(&attr);
-+ if (0 == ret) {
-+ /* Wait for the child to initialize. */
-+ pthread_cond_wait(&info.cond, &info.mutex);
-+ } else {
-+ /* pthread_create failed. */
-+ }
-+
-+ pthread_mutex_unlock(&info.mutex);
-+ pthread_cond_destroy(&info.cond);
-+ pthread_mutex_destroy(&info.mutex);
-+ pthread_mutex_unlock(&new_thread_lock);
-+
-+ return (ret);
-+}
-+
-+static int
-+do_thr_self(long *id)
-+{
-+
-+ return (get_errno(thr_self(id)));
-+}
-+
-+static void
-+do_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr)
-+{
-+
-+ if (first_cpu->next_cpu) {
-+ TaskState *ts;
-+ CPUArchState **lastp, *p;
-+
-+ /*
-+ * *XXX This probably breaks if a signal arrives.
-+ * We should disable signals.
-+ */
-+ cpu_list_lock();
-+ lastp = &first_cpu;
-+ p = first_cpu;
-+ while (p && p != (CPUArchState *)cpu_env) {
-+ lastp = &p->next_cpu;
-+ p = p->next_cpu;
-+ }
-+ /*
-+ * if we didn't find the CPU for this thread then something
-+ * is horribly wrong.
-+ */
-+ if (!p)
-+ abort();
-+ /* Remove the CPU from the list. */
-+ *lastp = p->next_cpu;
-+ cpu_list_unlock();
-+ ts = ((CPUArchState *)cpu_env)->opaque;
-+
-+ if (tid_addr) {
-+ /* Signal target userland that it can free the stack. */
-+ if (! put_user_u32(1, tid_addr))
-+ _umtx_op(g2h(tid_addr), UMTX_OP_WAKE, INT_MAX,
-+ NULL, NULL);
-+ }
-+
-+ thread_env = NULL;
-+ object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
-+ g_free(ts);
-+ pthread_exit(NULL);
-+ }
-+}
-+
-+static int
-+do_thr_kill(long id, int sig)
-+{
-+
-+ return (get_errno(thr_kill(id, sig)));
-+}
-+
-+static int
-+do_thr_kill2(pid_t pid, long id, int sig)
-+{
-+
-+ return (get_errno(thr_kill2(pid, id, sig)));
-+}
-+
-+static int
-+do_thr_suspend(const struct timespec *timeout)
-+{
-+
-+ return (get_errno(thr_suspend(timeout)));
-+}
-+
-+static int
-+do_thr_wake(long tid)
-+{
-+
-+ return (get_errno(thr_wake(tid)));
-+}
-+
-+static int
-+do_thr_set_name(long tid, char *name)
-+{
-+
-+ return (get_errno(thr_set_name(tid, name)));
-+}
-+
-+
-+#else /* ! CONFIG_USE_NPTL */
-+
-+static int
-+do_thr_create(CPUArchState *env, ucontext_t *ctx, long *id, int flags)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_create));
-+}
-+
-+static int
-+do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_new));
-+}
-+
-+static int
-+do_thr_self(long *tid)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_self));
-+}
-+
-+static void
-+do_thr_exit(CPUArchState *cpu_env, abi_ulong state_addr)
-+{
-+}
-+
-+static int
-+do_thr_kill(long tid, int sig)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_kill2));
-+}
-+
-+static int
-+do_thr_kill2(pid_t pid, long tid, int sig)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_kill2));
-+}
-+
-+static int
-+do_thr_suspend(const struct timespec *timeout)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_suspend));
-+}
-+
-+static int
-+do_thr_wake(long tid)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_wake));
-+}
-+
-+static int
-+do_thr_set_name(long tid, char *name)
-+{
-+ return (unimplemented(TARGET_FREEBSD_NR_thr_set_name));
-+}
-+
-+#endif /* CONFIG_USE_NPTL */
-+
-+static int
-+do_umtx_lock(abi_ulong umtx_addr, uint32_t id)
-+{
-+ int ret = 0;
-+
-+ for (;;) {
-+ ret = get_errno(_umtx_op(g2h(umtx_addr +
-+ offsetof(struct target_umtx, u_owner)),
-+ UMTX_OP_MUTEX_WAIT, UMTX_UNOWNED, 0, 0));
-+ if (ret)
-+ return (ret);
-+ if (atomic_cmpset_acq_32(g2h(umtx_addr +
-+ offsetof(struct target_umtx, u_owner)),
-+ UMTX_UNOWNED, id))
-+ return (0);
-+ }
-+}
-+
-+static int
-+do_umtx_unlock(abi_ulong umtx_addr, uint32 id)
-+{
-+ uint32_t owner;
-+
-+ do {
-+ if (get_user_u32(owner, umtx_addr +
-+ offsetof(struct target_umtx, u_owner)))
-+ return (-TARGET_EFAULT);
-+ if (owner != id)
-+ return (-TARGET_EPERM);
-+ } while (!atomic_cmpset_rel_32(g2h(umtx_addr +
-+ offsetof(struct target_umtx, u_owner)), owner,
-+ UMUTEX_UNOWNED));
-+
-+ return (0);
-+}
-+
-+
- /* do_syscall() should always have a single exit point at the end so
- that actions, such as logging of syscall results, can be performed.
- All errnos that do_syscall() returns must be -TARGET_<errcode>. */
-@@ -4091,6 +4491,23 @@ do_stat:
- break;
- #endif
-
-+#ifdef TARGET_FREEBSD_NR_getdomainname
-+ case TARGET_FREEBSD_NR_getdomainname:
-+ ret = unimplemented(num);
-+ break;
-+#endif
-+#ifdef TARGET_FREEBSD_NR_setdomainname
-+ case TARGET_FREEBSD_NR_setdomainname:
-+ ret = unimplemented(num);
-+ break;
-+#endif
-+#ifdef TARGET_FREEBSD_NR_uname
-+ case TARGET_FREEBSD_NR_uname:
-+ ret = unimplemented(num);
-+ break;
-+#endif
-+
-+
- #if 0 /* XXX not supported in libc yet, it seems (10.0 addition). */
- case TARGET_FREEBSD_NR_posix_fadvise:
- {
-@@ -4136,6 +4553,211 @@ do_stat:
- break;
- #endif
-
-+ case TARGET_FREEBSD_NR_thr_new:
-+ ret = do_thr_new(cpu_env, arg1, arg2);
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_create:
-+ {
-+ ucontext_t ucxt;
-+ long tid;
-+
-+ ret = do_thr_create(cpu_env, &ucxt, &tid, arg3);
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_set_name:
-+ if (!(p = lock_user_string(arg2)))
-+ goto efault;
-+ ret = do_thr_set_name(arg1, p);
-+ unlock_user(p, arg2, 0);
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_self:
-+ {
-+ long tid;
-+
-+ if ((ret = do_thr_self(&tid)) == 0) {
-+ if (put_user((abi_long)tid, arg1, abi_long))
-+ goto efault;
-+ }
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_suspend:
-+ {
-+ struct timespec ts;
-+
-+ if (target_to_host_timespec(&ts, arg1))
-+ goto efault;
-+
-+ ret = do_thr_suspend(&ts);
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_wake:
-+ ret = do_thr_wake(arg1);
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_kill:
-+ ret = do_thr_kill(arg1, arg2);
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_kill2:
-+ ret = do_thr_kill2(arg1, arg2, arg3);
-+ break;
-+
-+ case TARGET_FREEBSD_NR_thr_exit:
-+ ret = 0; /* suspress compile warning */
-+ do_thr_exit(cpu_env, arg1);
-+ /* Shouldn't be reached. */
-+ break;
-+
-+ case TARGET_FREEBSD_NR_rtprio_thread:
-+ ret = 0;
-+ break;
-+
-+ case TARGET_FREEBSD_NR_getcontext:
-+ {
-+ target_ucontext_t *ucp;
-+ sigset_t sigmask;
-+
-+ if (0 == arg1) {
-+ ret = -TARGET_EINVAL;
-+ } else {
-+ ret = get_errno(sigprocmask(0, NULL, &sigmask));
-+ if (!is_error(ret)) {
-+ if (!(ucp = lock_user(VERIFY_WRITE, arg1,
-+ sizeof(target_ucontext_t), 0)))
-+ goto efault;
-+ ret = get_mcontext(cpu_env, &ucp->uc_mcontext,
-+ TARGET_MC_GET_CLEAR_RET);
-+ host_to_target_sigset(&ucp->uc_sigmask,
-+ &sigmask);
-+ memset(ucp->__spare__, 0,
-+ sizeof(ucp->__spare__));
-+ unlock_user(ucp, arg1,
-+ sizeof(target_ucontext_t));
-+ }
-+ }
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR_setcontext:
-+ {
-+ target_ucontext_t *ucp;
-+ sigset_t sigmask;
-+
-+ if (0 == arg1) {
-+ ret = -TARGET_EINVAL;
-+ } else {
-+ if (!(ucp = lock_user(VERIFY_READ, arg1,
-+ sizeof(target_ucontext_t), 1)))
-+ goto efault;
-+ ret = set_mcontext(cpu_env, &ucp->uc_mcontext, 0);
-+ target_to_host_sigset(&sigmask, &ucp->uc_sigmask);
-+ unlock_user(ucp, arg1, sizeof(target_ucontext_t));
-+ if (0 == ret)
-+ (void)sigprocmask(SIG_SETMASK, &sigmask, NULL);
-+ }
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR_swapcontext:
-+ /*
-+ * XXX Does anything besides old implementations of
-+ * setjmp()/longjmp() uses these?
-+ */
-+ ret = unimplemented(num);
-+ break;
-+
-+ case TARGET_FREEBSD_NR__umtx_lock:
-+ {
-+ long tid;
-+
-+ thr_self(&tid);
-+ ret = do_umtx_lock(arg1, tswap32(tid));
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR__umtx_unlock:
-+ {
-+ long tid;
-+
-+ thr_self(&tid);
-+ ret = do_umtx_unlock(arg1, tswap32(tid));
-+ }
-+ break;
-+
-+ case TARGET_FREEBSD_NR__umtx_op:
-+ {
-+ struct timespec ts;
-+ void *object = NULL;
-+ int operation;
-+ void *addr = NULL;
-+ void *addr2 = NULL;
-+
-+
-+ /* int _umtx_op(void *obj, int op, u_long val,
-+ * void *uaddr, void *uaddr2); */
-+
-+ abi_ulong obj = arg1;
-+ int op = (int)arg2;
-+ u_long val = arg3;
-+ /* abi_ulong uaddr = arg4; */
-+ abi_ulong uaddr2 = arg5;
-+
-+ switch(op) {
-+ case TARGET_UMTX_OP_LOCK:
-+ ret = do_umtx_lock(obj, tswap32((uint32_t)val));
-+ break;
-+
-+ case TARGET_UMTX_OP_UNLOCK:
-+ ret = do_umtx_unlock(obj, tswap32((uint32_t)val));
-+ break;
-+
-+ case TARGET_UMTX_OP_WAIT:
-+ if (uaddr2) {
-+ if (target_to_host_timespec(&ts, uaddr2))
-+ goto efault;
-+ addr2 = (void *)&ts;
-+ }
-+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT,
-+ tswap32(val), addr, addr2));
-+ break;
-+
-+ case TARGET_UMTX_OP_WAKE:
-+ operation = UMTX_OP_WAKE;
-+ object = g2h(obj);
-+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE,
-+ val, 0, 0));
-+ break;
-+
-+ case TARGET_UMTX_OP_MUTEX_TRYLOCK:
-+ case TARGET_UMTX_OP_MUTEX_LOCK:
-+ case TARGET_UMTX_OP_MUTEX_UNLOCK:
-+ case TARGET_UMTX_OP_SET_CEILING:
-+ case TARGET_UMTX_OP_CV_WAIT:
-+ case TARGET_UMTX_OP_CV_SIGNAL:
-+ case TARGET_UMTX_OP_CV_BROADCAST:
-+ case TARGET_UMTX_OP_WAIT_UINT:
-+ case TARGET_UMTX_OP_RW_RDLOCK:
-+ case TARGET_UMTX_OP_RW_WRLOCK:
-+ case TARGET_UMTX_OP_RW_UNLOCK:
-+ case TARGET_UMTX_OP_WAIT_UINT_PRIVATE:
-+ case TARGET_UMTX_OP_WAKE_PRIVATE:
-+ case TARGET_UMTX_OP_MUTEX_WAIT:
-+ case TARGET_UMTX_OP_MUTEX_WAKE:
-+ case TARGET_UMTX_OP_SEM_WAIT:
-+ case TARGET_UMTX_OP_SEM_WAKE:
-+ case TARGET_UMTX_OP_NWAKE_PRIVATE:
-+ default:
-+ ret = -TARGET_EINVAL;
-+ break;
-+ }
-+ }
-+ break;
-+
- case TARGET_FREEBSD_NR_yield:
- case TARGET_FREEBSD_NR_sched_setparam:
- case TARGET_FREEBSD_NR_sched_getparam:
-@@ -4146,36 +4768,18 @@ do_stat:
- case TARGET_FREEBSD_NR_sched_get_priority_min:
- case TARGET_FREEBSD_NR_sched_rr_get_interval:
-
--
- case TARGET_FREEBSD_NR_reboot:
- case TARGET_FREEBSD_NR_shutdown:
-
- case TARGET_FREEBSD_NR_swapon:
- case TARGET_FREEBSD_NR_swapoff:
-
-- case TARGET_FREEBSD_NR_thr_create:
-- case TARGET_FREEBSD_NR_thr_exit:
-- case TARGET_FREEBSD_NR_thr_self:
-- case TARGET_FREEBSD_NR_thr_suspend:
-- case TARGET_FREEBSD_NR_thr_wake:
-- case TARGET_FREEBSD_NR_thr_new:
-- case TARGET_FREEBSD_NR_thr_set_name:
-- case TARGET_FREEBSD_NR_thr_kill2:
--
-- case TARGET_FREEBSD_NR_getcontext:
-- case TARGET_FREEBSD_NR_setcontext:
-- case TARGET_FREEBSD_NR_swapcontext:
--
-- case TARGET_FREEBSD_NR_rtprio_thread:
- case TARGET_FREEBSD_NR_cpuset:
- case TARGET_FREEBSD_NR_cpuset_getid:
- case TARGET_FREEBSD_NR_cpuset_setid:
- case TARGET_FREEBSD_NR_cpuset_getaffinity:
- case TARGET_FREEBSD_NR_cpuset_setaffinity:
-
-- case TARGET_FREEBSD_NR__umtx_lock:
-- case TARGET_FREEBSD_NR__umtx_unlock:
--
- case TARGET_FREEBSD_NR_rctl_get_racct:
- case TARGET_FREEBSD_NR_rctl_get_rules:
- case TARGET_FREEBSD_NR_rctl_add_rule:
-@@ -4185,16 +4789,6 @@ do_stat:
- case TARGET_FREEBSD_NR_ntp_adjtime:
- case TARGET_FREEBSD_NR_ntp_gettime:
-
--#ifdef TARGET_FREEBSD_NR_getdomainname
-- case TARGET_FREEBSD_NR_getdomainname:
--#endif
--#ifdef TARGET_FREEBSD_NR_setdomainname
-- case TARGET_FREEBSD_NR_setdomainname:
--#endif
--#ifdef TARGET_FREEBSD_NR_uname
-- case TARGET_FREEBSD_NR_uname:
--#endif
--
- case TARGET_FREEBSD_NR_sctp_peeloff:
- case TARGET_FREEBSD_NR_sctp_generic_sendmsg:
- case TARGET_FREEBSD_NR_sctp_generic_recvmsg:
-diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
-index ea1d25d..2879d83 100644
---- a/bsd-user/syscall_defs.h
-+++ b/bsd-user/syscall_defs.h
-@@ -416,6 +416,11 @@ struct target_shmid_ds {
- abi_ulong shm_ctime; /* time of last change by shmctl() */
- };
-
-+#define TARGET_UCONTEXT_MAGIC 0xACEDBADE
-+#define TARGET_MC_GET_CLEAR_RET 0x0001
-+#define TARGET_MC_ADD_MAGIC 0x0002
-+#define TARGET_MC_SET_ONSTACK 0x0004
-+
- /* this struct defines a stack used during syscall handling */
- typedef struct target_sigaltstack {
- abi_long ss_sp;
-@@ -477,95 +482,6 @@ typedef struct target_siginfo {
- } _reason;
- } target_siginfo_t;
-
--#if defined(TARGET_MIPS)
--
--struct target_sigcontext {
-- target_sigset_t sc_mask; /* signal mask to retstore */
-- int32_t sc_onstack; /* sigstack state to restore */
-- abi_long sc_pc; /* pc at time of signal */
-- abi_long sc_reg[32]; /* processor regs 0 to 31 */
-- abi_long mullo, mulhi; /* mullo and mulhi registers */
-- int32_t sc_fpused; /* fp has been used */
-- abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */
-- abi_long sc_fpc_eir; /* fp exception instr reg */
-- /* int32_t reserved[8]; */
--};
--
--typedef struct target_mcontext {
-- int32_t mc_onstack; /* sigstack state to restore */
-- abi_long mc_pc; /* pc at time of signal */
-- abi_long mc_regs[32]; /* process regs 0 to 31 */
-- abi_long sr; /* status register */
-- abi_long mullo, mulhi;
-- int32_t mc_fpused; /* fp has been used */
-- abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */
-- abi_long mc_fpc_eir; /* fp exception instr reg */
-- abi_ulong mc_tls; /* pointer to TLS area */
--} target_mcontext_t;
--
--typedef struct target_ucontext {
-- target_sigset_t uc_sigmask;
-- target_mcontext_t uc_mcontext;
-- target_ulong uc_link;
-- target_stack_t uc_stack;
-- int32_t uc_flags;
-- int32_t __space__[8];
--} target_ucontext_t;
--
--struct target_sigframe {
-- abi_ulong sf_signum;
-- abi_ulong sf_siginfo; /* code or pointer to sf_si */
-- abi_ulong sf_ucontext; /* points to sf_uc */
-- abi_ulong sf_addr; /* undocumented 4th arg */
-- target_ucontext_t sf_uc; /* = *sf_uncontext */
-- target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/
-- uint32_t __spare__[2];
--};
--
--#elif defined(TARGET_SPARC64)
--
--struct target_mcontext {
-- uint64_t mc_global[8];
-- uint64_t mc_out[8];
-- uint64_t mc_local[8];
-- uint64_t mc_in[8];
-- uint32_t mc_fp[64];
--} __aligned(64);
--
--typedef struct target_mcontext target_mcontext_t;
--
--typedef struct target_ucontext {
-- target_sigset_t uc_sigmask;
-- target_mcontext_t uc_mcontext;
-- target_ulong uc_link;
-- target_stack_t uc_stack;
-- int32_t uc_flags;
-- int32_t __space__[8];
--} target_ucontext_t;
--
--struct target_sigframe {
-- target_ucontext_t sf_uc;
-- target_siginfo_t sf_si;
--};
--
--#else
--
--typedef target_ulong target_mcontext_t; /* dummy */
--
--#endif
--
--/* XXX where did this come from?
--typedef struct target_ucontext {
-- target_ulong uc_flags;
-- target_ulong uc_link;
-- target_stack_t uc_stack;
-- target_mcontext_t uc_mcontext;
-- target_ulong uc_filer[80];
-- target_sigset_t uc_sigmask;
--} target_ucontext_t;
--*/
--
--
- #ifdef BSWAP_NEEDED
- static inline void
- tswap_sigset(target_sigset_t *d, const target_sigset_t *s)
-@@ -603,3 +519,101 @@ void host_to_target_old_sigset(abi_ulong *old_sigset, const sigset_t *sigset);
- void target_to_host_old_sigset(sigset_t *sigset, const abi_ulong *old_sigset);
- int do_sigaction(int sig, const struct target_sigaction *act,
- struct target_sigaction *oact);
-+
-+
-+/*
-+ * FreeBSD thread support.
-+ */
-+
-+#define TARGET_THR_SUSPENDED 0x0001
-+#define TARGET_THR_SYSTEM_SCOPE 0x0002
-+
-+/* sysarch() ops */
-+#define TARGET_MIPS_SET_TLS 1
-+#define TARGET_MIPS_GET_TLS 2
-+
-+struct target_thr_param {
-+ abi_ulong start_func; /* thread entry function. */
-+ abi_ulong arg; /* argument for entry function. */
-+ abi_ulong stack_base; /* stack base address. */
-+ abi_ulong stack_size; /* stack size. */
-+ abi_ulong tls_base; /* tls base address. */
-+ 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. */
-+ abi_ulong rtp; /* Real-time scheduling priority. */
-+ abi_ulong spare[3]; /* spares. */
-+};
-+
-+struct target_rtprio {
-+ uint16_t type;
-+ uint16_t prio;
-+};
-+
-+/*
-+ * sys/_umtx.h
-+ */
-+
-+struct target_umtx {
-+ uint32_t u_owner; /* Owner of the mutex. */
-+};
-+
-+struct target_umutex {
-+ uint32_t m_owner; /* Owner of the mutex */
-+ uint32_t m_flags; /* Flags of the mutex */
-+ uint32_t m_ceiling[2]; /* Priority protect ceiling */
-+ uint32_t m_spare[4];
-+};
-+
-+struct target_ucond {
-+ uint32_t c_has_waiters; /* Has waiters in kernel */
-+ uint32_t c_flags; /* Flags of the condition variable */
-+ uint32_t c_clockid; /* Clock id */
-+ uint32_t c_spare[1];
-+};
-+
-+struct target_urwlock {
-+ int32_t rw_state;
-+ uint32_t rw_flags;
-+ uint32_t rw_blocked_readers;
-+ uint32_t rw_blocked_writers;
-+ uint32_t rw_spare[4];
-+};
-+
-+struct target__usem {
-+ uint32_t _has_waiters;
-+ uint32_t _count;
-+ uint32_t _flags;
-+};
-+
-+/*
-+ * sys/utmx.h
-+ */
-+
-+/* op code for _umtx_op */
-+#define TARGET_UMTX_OP_LOCK 0
-+#define TARGET_UMTX_OP_UNLOCK 1
-+#define TARGET_UMTX_OP_WAIT 2
-+#define TARGET_UMTX_OP_WAKE 3
-+#define TARGET_UMTX_OP_MUTEX_TRYLOCK 4
-+#define TARGET_UMTX_OP_MUTEX_LOCK 5
-+#define TARGET_UMTX_OP_MUTEX_UNLOCK 6
-+#define TARGET_UMTX_OP_SET_CEILING 7
-+#define TARGET_UMTX_OP_CV_WAIT 8
-+#define TARGET_UMTX_OP_CV_SIGNAL 9
-+#define TARGET_UMTX_OP_CV_BROADCAST 10
-+#define TARGET_UMTX_OP_WAIT_UINT 11
-+#define TARGET_UMTX_OP_RW_RDLOCK 12
-+#define TARGET_UMTX_OP_RW_WRLOCK 13
-+#define TARGET_UMTX_OP_RW_UNLOCK 14
-+#define TARGET_UMTX_OP_WAIT_UINT_PRIVATE 15
-+#define TARGET_UMTX_OP_WAKE_PRIVATE 16
-+#define TARGET_UMTX_OP_MUTEX_WAIT 17
-+#define TARGET_UMTX_OP_MUTEX_WAKE 18
-+#define TARGET_UMTX_OP_SEM_WAIT 19
-+#define TARGET_UMTX_OP_SEM_WAKE 20
-+#define TARGET_UMTX_OP_NWAKE_PRIVATE 21
-+#define TARGET_UMTX_OP_MAX 22
-+
-+/* flags for UMTX_OP_CV_WAIT */
-+#define TARGET_CHECK_UNPARKING 0x01
-diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h
-index ea89f5a..a14e0b9 100644
---- a/bsd-user/x86_64/target_signal.h
-+++ b/bsd-user/x86_64/target_signal.h
-@@ -15,4 +15,29 @@ static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
- #define TARGET_MINSIGSTKSZ (512 * 4)
- #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-
-+typedef target_ulong target_mcontext_t; /* dummy */
-+
-+typedef struct target_ucontext {
-+ target_sigset_t uc_sigmask;
-+ target_mcontext_t uc_mcontext;
-+ abi_ulong uc_link;
-+ target_stack_t uc_stack;
-+ int32_t uc_flags;
-+ int32_t __spare__[4];
-+} target_ucontext_t;
-+
-+static inline int
-+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "x86_64 doesn't have support for get_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
-+static inline int
-+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
-+{
-+ fprintf(stderr, "x86_64 doesn't have support for set_mcontext()\n");
-+ return (-TARGET_ENOSYS);
-+}
-+
- #endif /* TARGET_SIGNAL_H */
-diff --git a/configure b/configure
-index 34eca43..be75584 100755
---- a/configure
-+++ b/configure
-@@ -1386,6 +1386,11 @@ fi
-
- if test "$nptl" != "no" ; then
- cat > $TMPC <<EOF
-+#ifdef __FreeBSD__
-+int main(void) {
-+ return (0);
-+}
-+#else
- #include <sched.h>
- #include <linux/futex.h>
- int main(void) {
-@@ -1394,6 +1399,7 @@ int main(void) {
- #endif
- return 0;
- }
-+#endif
- EOF
-
- if compile_object ; then
-@@ -3751,5 +3757,6 @@ case "$target_arch2" in
- TARGET_ARCH=mips64
- TARGET_BASE_ARCH=mips
- echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
-+ target_nptl="yes"
- target_long_alignment=8
- ;;