diff options
| author | Juergen Lock <nox@FreeBSD.org> | 2013-08-20 22:03:10 +0000 |
|---|---|---|
| committer | Juergen Lock <nox@FreeBSD.org> | 2013-08-20 22:03:10 +0000 |
| commit | f2f3e3e60ae9a4520c8bdb2c66d879ab7a9923df (patch) | |
| tree | 6e410f147aab5715db036270b661a814dc7a0536 /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-002c | 2300 |
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 - ;; |
