mirror of
https://git.freebsd.org/ports.git
synced 2025-06-25 06:30:29 -04:00
- Update emulators/qemu-devel to 1.4.0 with preliminary bsd-user patches. Thanx to: sson, cognet, and others for much improved bsd-user support - it now runs at least quite a few mips64 and single-threaded arm binaries, see: https://wiki.freebsd.org/QemuUserModeHowTo
1151 lines
36 KiB
Text
1151 lines
36 KiB
Text
diff --git a/bsd-user/arm/syscall.h b/bsd-user/arm/syscall.h
|
|
index bd54b37..4d98841 100644
|
|
--- a/bsd-user/arm/syscall.h
|
|
+++ b/bsd-user/arm/syscall.h
|
|
@@ -22,4 +22,7 @@ struct target_pt_regs {
|
|
|
|
#define ARM_SYSCALL_BASE 0 /* XXX: FreeBSD only */
|
|
|
|
-#define TARGET_FREEBSD_ARM_SET_TP 2
|
|
+#define TARGET_FREEBSD_ARM_SYNC_ICACHE 0
|
|
+#define TARGET_FREEBSD_ARM_DRAIN_WRITEBUF 1
|
|
+#define TARGET_FREEBSD_ARM_SET_TP 2
|
|
+#define TARGET_FREEBSD_ARM_GET_TP 3
|
|
diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h
|
|
index 4a9e518..05c9d1c 100644
|
|
--- a/bsd-user/arm/target_signal.h
|
|
+++ b/bsd-user/arm/target_signal.h
|
|
@@ -26,8 +26,6 @@
|
|
#define TARGET_REG_LR TARGET_REG_R14
|
|
#define TARGET_REG_PC TARGET_REG_R15
|
|
|
|
-#define TARGET_GET_MC_CLEAR_RET 1
|
|
-
|
|
#define TARGET_MINSIGSTKSZ (1024 * 4)
|
|
#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
|
|
#define TARGET__NGREG 17
|
|
@@ -109,7 +107,7 @@ get_sp_from_cpustate(CPUARMState *state)
|
|
* Compare to arm/arm/machdep.c sendsig()
|
|
* Assumes that the target stack frame memory is locked.
|
|
*/
|
|
-static inline int
|
|
+static inline abi_ulong
|
|
set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame,
|
|
abi_ulong frame_addr, struct target_sigaction *ka)
|
|
{
|
|
@@ -141,42 +139,89 @@ set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame,
|
|
}
|
|
|
|
/* Compare to arm/arm/machdep.c get_mcontext() */
|
|
-static inline int
|
|
+static inline abi_long
|
|
get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int clear_ret)
|
|
{
|
|
- int i, err = 0;
|
|
+ int err = 0;
|
|
uint32_t *gr = mcp->__gregs;
|
|
|
|
|
|
- if (clear_ret & TARGET_GET_MC_CLEAR_RET)
|
|
+ if (clear_ret & TARGET_MC_GET_CLEAR_RET)
|
|
gr[TARGET_REG_R0] = 0;
|
|
else
|
|
gr[TARGET_REG_R0] = tswap32(regs->regs[0]);
|
|
- for(i = 1; i < 12; i++)
|
|
- gr[i] = tswap32(regs->regs[i]);
|
|
+
|
|
+ gr[TARGET_REG_R1 ] = tswap32(regs->regs[ 1]);
|
|
+ gr[TARGET_REG_R2 ] = tswap32(regs->regs[ 2]);
|
|
+ gr[TARGET_REG_R3 ] = tswap32(regs->regs[ 3]);
|
|
+ gr[TARGET_REG_R4 ] = tswap32(regs->regs[ 4]);
|
|
+ gr[TARGET_REG_R5 ] = tswap32(regs->regs[ 5]);
|
|
+ gr[TARGET_REG_R6 ] = tswap32(regs->regs[ 6]);
|
|
+ gr[TARGET_REG_R7 ] = tswap32(regs->regs[ 7]);
|
|
+ gr[TARGET_REG_R8 ] = tswap32(regs->regs[ 8]);
|
|
+ gr[TARGET_REG_R9 ] = tswap32(regs->regs[ 9]);
|
|
+ gr[TARGET_REG_R10] = tswap32(regs->regs[10]);
|
|
+ gr[TARGET_REG_R11] = tswap32(regs->regs[11]);
|
|
+ gr[TARGET_REG_R12] = tswap32(regs->regs[12]);
|
|
+
|
|
gr[TARGET_REG_SP] = tswap32(regs->regs[13]);
|
|
gr[TARGET_REG_LR] = tswap32(regs->regs[14]);
|
|
gr[TARGET_REG_PC] = tswap32(regs->regs[15]);
|
|
- gr[TARGET_REG_CPSR] = tswap32(regs->spsr);
|
|
+ gr[TARGET_REG_CPSR] = tswap32(cpsr_read(regs));
|
|
|
|
return (err);
|
|
}
|
|
|
|
/* Compare to arm/arm/machdep.c set_mcontext() */
|
|
-static inline int
|
|
-set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int flags)
|
|
+static inline abi_long
|
|
+set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int srflag)
|
|
{
|
|
- int i, err = 0;
|
|
+ int err = 0;
|
|
const uint32_t *gr = mcp->__gregs;
|
|
+ uint32_t cpsr;
|
|
+
|
|
+ regs->regs[ 0] = tswap32(gr[TARGET_REG_R0 ]);
|
|
+ regs->regs[ 1] = tswap32(gr[TARGET_REG_R1 ]);
|
|
+ regs->regs[ 2] = tswap32(gr[TARGET_REG_R2 ]);
|
|
+ regs->regs[ 3] = tswap32(gr[TARGET_REG_R3 ]);
|
|
+ regs->regs[ 4] = tswap32(gr[TARGET_REG_R4 ]);
|
|
+ regs->regs[ 5] = tswap32(gr[TARGET_REG_R5 ]);
|
|
+ regs->regs[ 6] = tswap32(gr[TARGET_REG_R6 ]);
|
|
+ regs->regs[ 7] = tswap32(gr[TARGET_REG_R7 ]);
|
|
+ regs->regs[ 8] = tswap32(gr[TARGET_REG_R8 ]);
|
|
+ regs->regs[ 9] = tswap32(gr[TARGET_REG_R9 ]);
|
|
+ regs->regs[10] = tswap32(gr[TARGET_REG_R10]);
|
|
+ regs->regs[11] = tswap32(gr[TARGET_REG_R11]);
|
|
+ regs->regs[12] = tswap32(gr[TARGET_REG_R12]);
|
|
|
|
- for(i = 0; i < 12; i++)
|
|
- regs->regs[i] = tswap32(gr[i]);
|
|
regs->regs[13] = tswap32(gr[TARGET_REG_SP]);
|
|
regs->regs[14] = tswap32(gr[TARGET_REG_LR]);
|
|
regs->regs[15] = tswap32(gr[TARGET_REG_PC]);
|
|
- regs->spsr = tswap32(gr[TARGET_REG_CPSR]);
|
|
+ cpsr = tswap32(gr[TARGET_REG_CPSR]);
|
|
+ cpsr_write(regs, cpsr, CPSR_USER | CPSR_EXEC);
|
|
|
|
return (err);
|
|
}
|
|
|
|
+/* Compare to arm/arm/machdep.c sys_sigreturn() */
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUARMState *regs, abi_ulong sf_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ struct target_sigframe *sf;
|
|
+ uint32_t cpsr = cpsr_read(regs);
|
|
+
|
|
+ if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR ||
|
|
+ (cpsr & (CPSR_I | CPSR_F)) != 0)
|
|
+ return (-TARGET_EINVAL);
|
|
+
|
|
+ if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 0))
|
|
+ return (-TARGET_EFAULT);
|
|
+
|
|
+ *locked_addr = sf;
|
|
+ *ucontext = (target_ucontext_t *)g2h(tswapal(sf_addr +
|
|
+ offsetof(struct target_sigframe, sf_uc)));
|
|
+ return (0);
|
|
+}
|
|
+
|
|
#endif /* TARGET_SIGNAL_H */
|
|
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
|
|
index 76681e1..7a7c3eb 100644
|
|
--- a/bsd-user/elfload.c
|
|
+++ b/bsd-user/elfload.c
|
|
@@ -13,6 +13,7 @@
|
|
|
|
#include "qemu.h"
|
|
#include "disas/disas.h"
|
|
+#include "target_signal.h"
|
|
|
|
#ifdef _ARCH_PPC64
|
|
#undef ARCH_DLINFO
|
|
diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h
|
|
index 1efa502..7f2e0ca 100644
|
|
--- a/bsd-user/errno_defs.h
|
|
+++ b/bsd-user/errno_defs.h
|
|
@@ -147,3 +147,7 @@
|
|
#define TARGET_EIDRM 89 /* Identifier removed */
|
|
#define TARGET_ENOMSG 90 /* No message of desired type */
|
|
#define TARGET_ELAST 90 /* Must be equal largest errno */
|
|
+
|
|
+/* pseudo-errors just used in the kernel/emulator: */
|
|
+#define TARGET_ERESTART 255 /* restart syscall */
|
|
+#define TARGET_EJUSTRETURN 254 /* Don't modify regs, just ret */
|
|
diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
|
|
index 8270c37..1f8ee10 100644
|
|
--- a/bsd-user/freebsd/strace.list
|
|
+++ b/bsd-user/freebsd/strace.list
|
|
@@ -33,6 +33,7 @@
|
|
{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(%s,%#x)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL },
|
|
{ TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL },
|
|
@@ -51,7 +52,7 @@
|
|
{ TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL },
|
|
-{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL },
|
|
{ TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL },
|
|
@@ -185,7 +186,7 @@
|
|
{ TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL },
|
|
-{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL },
|
|
diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h
|
|
index 28481ce..51a2a7b 100644
|
|
--- a/bsd-user/i386/target_signal.h
|
|
+++ b/bsd-user/i386/target_signal.h
|
|
@@ -3,11 +3,6 @@
|
|
|
|
#include "cpu.h"
|
|
|
|
-static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
|
|
-{
|
|
- return state->regs[R_ESP];
|
|
-}
|
|
-
|
|
#define TARGET_MINSIGSTKSZ (512 * 4)
|
|
#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
|
|
|
|
@@ -22,18 +17,32 @@ typedef struct target_ucontext {
|
|
int32_t __spare__[4];
|
|
} target_ucontext_t;
|
|
|
|
-static inline int
|
|
+static inline abi_ulong
|
|
+get_sp_from_cpustate(CPUX86State *state)
|
|
+{
|
|
+ return state->regs[R_ESP];
|
|
+}
|
|
+
|
|
+static inline abi_long
|
|
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
|
|
+static inline abi_long
|
|
set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
|
|
{
|
|
fprintf(stderr, "i386 doesn't have support for set_mcontext()\n");
|
|
return (-TARGET_ENOSYS);
|
|
}
|
|
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ fprintf(stderr, "i386 doesn't have support for do_sigreturn()\n");
|
|
+ return (-TARGET_ENOSYS);
|
|
+}
|
|
+
|
|
#endif /* TARGET_SIGNAL_H */
|
|
diff --git a/bsd-user/main.c b/bsd-user/main.c
|
|
index b6aaa7e..b248a91 100644
|
|
--- a/bsd-user/main.c
|
|
+++ b/bsd-user/main.c
|
|
@@ -35,6 +35,7 @@
|
|
#include "tcg.h"
|
|
#include "qemu/timer.h"
|
|
#include "qemu/envlist.h"
|
|
+#include "target_signal.h"
|
|
|
|
#if defined(CONFIG_USE_NPTL) && defined(__FreeBSD__)
|
|
#include <sys/thr.h>
|
|
@@ -813,15 +814,25 @@ void cpu_loop(CPUARMState *env)
|
|
arg6,
|
|
arg7,
|
|
arg8);
|
|
- if ((unsigned int)ret >= (unsigned int)(-515)) {
|
|
- ret = -ret;
|
|
- cpsr_write(env, CPSR_C, CPSR_C);
|
|
- env->regs[0] = ret;
|
|
- } else {
|
|
- cpsr_write(env, 0, CPSR_C);
|
|
- env->regs[0] = ret; // XXX need to handle lseek()?
|
|
- // env->regs[1] = 0;
|
|
- }
|
|
+ /* Compare to arm/arm/vm_machdep.c cpu_set_syscall_retval() */
|
|
+ /* XXX armeb may need some extra magic here */
|
|
+ if (-TARGET_EJUSTRETURN == ret) {
|
|
+ /*
|
|
+ * Returning from a successful sigreturn syscall.
|
|
+ * Avoid clobbering register state.
|
|
+ */
|
|
+ break;
|
|
+ }
|
|
+ /* XXX Need to handle ERESTART. Backup the PC by 1 instruction*/
|
|
+ if ((unsigned int)ret >= (unsigned int)(-515)) {
|
|
+ ret = -ret;
|
|
+ cpsr_write(env, CPSR_C, CPSR_C);
|
|
+ env->regs[0] = ret;
|
|
+ } else {
|
|
+ cpsr_write(env, 0, CPSR_C);
|
|
+ env->regs[0] = ret; // XXX need to handle lseek()?
|
|
+ // env->regs[1] = 0;
|
|
+ }
|
|
} else {
|
|
// XXX is this correct?
|
|
env->regs[0] = do_openbsd_syscall(env,
|
|
@@ -1068,13 +1079,20 @@ void cpu_loop(CPUMIPSState *env)
|
|
}
|
|
}
|
|
/* done_syscall: */
|
|
- if (-TARGET_QEMU_ESIGRETURN == ret) {
|
|
+ /*
|
|
+ * Compare to mips/mips/vm_machdep.c
|
|
+ * cpu_set_syscall_retval()
|
|
+ *
|
|
+ * XXX need to handle lseek here.
|
|
+ */
|
|
+ if (-TARGET_EJUSTRETURN == ret) {
|
|
/*
|
|
* Returning from a successful sigreturn
|
|
* syscall. Avoid clobbering register state.
|
|
*/
|
|
break;
|
|
}
|
|
+ /* XXX need to handle ERESTART */
|
|
if ((unsigned int)ret >= (unsigned int)(-1133)) {
|
|
env->active_tc.gpr[7] = 1;
|
|
ret = -ret;
|
|
diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h
|
|
index 484cfd8..0f57f0f 100644
|
|
--- a/bsd-user/mips/target_signal.h
|
|
+++ b/bsd-user/mips/target_signal.h
|
|
@@ -61,7 +61,7 @@ get_sp_from_cpustate(CPUMIPSState *state)
|
|
* Compare to mips/mips/pm_machdep.c sendsig()
|
|
* Assumes that "frame" memory is locked.
|
|
*/
|
|
-static inline int
|
|
+static inline abi_long
|
|
set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
|
|
abi_ulong frame_addr, struct target_sigaction *ka)
|
|
{
|
|
@@ -98,7 +98,7 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
|
|
* Compare to mips/mips/pm_machdep.c get_mcontext()
|
|
* Assumes that the memory is locked if mcp points to user memory.
|
|
*/
|
|
-static inline int
|
|
+static inline abi_long
|
|
get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
{
|
|
int i, err = 0;
|
|
@@ -152,8 +152,8 @@ get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
}
|
|
|
|
/* Compare to mips/mips/pm_machdep.c set_mcontext() */
|
|
-static inline int
|
|
-set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
+static inline abi_long
|
|
+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int srflag)
|
|
{
|
|
int i, err = 0;
|
|
|
|
@@ -184,9 +184,27 @@ set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
regs->active_tc.HI[0] = tswapal(mcp->mulhi);
|
|
regs->tls_value = tswapal(mcp->mc_tls);
|
|
|
|
+ if (srflag) {
|
|
+ /* doing sigreturn() */
|
|
+ regs->active_tc.PC = regs->CP0_EPC;
|
|
+ regs->CP0_EPC = 0; /* XXX for nested signals ? */
|
|
+ }
|
|
+
|
|
/* Don't do any of the status and cause registers. */
|
|
|
|
return (err);
|
|
}
|
|
|
|
+/* mips/mips/pm_machdep.c sys_sigreturn() */
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ if (!lock_user_struct(VERIFY_READ, *ucontext, uc_addr, 0))
|
|
+ return (-TARGET_EFAULT);
|
|
+
|
|
+ *locked_addr = *ucontext;
|
|
+ return (0);
|
|
+}
|
|
+
|
|
#endif /* TARGET_SIGNAL_H */
|
|
diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h
|
|
index f657909..3fee772 100644
|
|
--- a/bsd-user/mips64/target_signal.h
|
|
+++ b/bsd-user/mips64/target_signal.h
|
|
@@ -58,7 +58,7 @@ get_sp_from_cpustate(CPUMIPSState *state)
|
|
#define TARGET_SZSIGCODE (4 * 4)
|
|
|
|
/* Compare to mips/mips/locore.S sigcode() */
|
|
-static inline int
|
|
+static inline abi_long
|
|
install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned sys_sigreturn)
|
|
{
|
|
int i;
|
|
@@ -79,7 +79,7 @@ install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned sys_sigreturn)
|
|
* Compare to mips/mips/pm_machdep.c sendsig()
|
|
* Assumes that target stack frame memory is locked.
|
|
*/
|
|
-static inline int
|
|
+static inline abi_long
|
|
set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
|
|
abi_ulong frame_addr, struct target_sigaction *ka)
|
|
{
|
|
@@ -117,7 +117,7 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
|
|
* Compare to mips/mips/pm_machdep.c get_mcontext()
|
|
* Assumes that the memory is locked if mcp points to user memory.
|
|
*/
|
|
-static inline int
|
|
+static inline abi_long
|
|
get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
{
|
|
int i, err = 0;
|
|
@@ -171,8 +171,8 @@ get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
}
|
|
|
|
/* Compare to mips/mips/pm_machdep.c set_mcontext() */
|
|
-static inline int
|
|
-set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
+static inline abi_long
|
|
+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int srflag)
|
|
{
|
|
int i, err = 0;
|
|
|
|
@@ -203,10 +203,28 @@ set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags)
|
|
regs->active_tc.HI[0] = tswapal(mcp->mulhi);
|
|
regs->tls_value = tswapal(mcp->mc_tls);
|
|
|
|
+ if (srflag) {
|
|
+ /* doing sigreturn() */
|
|
+ regs->active_tc.PC = regs->CP0_EPC;
|
|
+ regs->CP0_EPC = 0; /* XXX for nested signals ? */
|
|
+ }
|
|
+
|
|
/* Don't do any of the status and cause registers. */
|
|
|
|
return (err);
|
|
}
|
|
|
|
+/* mips/mips/pm_machdep.c sys_sigreturn() */
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ if (!lock_user_struct(VERIFY_READ, *ucontext, uc_addr, 0))
|
|
+ return (-TARGET_EFAULT);
|
|
+
|
|
+ *locked_addr = *ucontext;
|
|
+ return (0);
|
|
+}
|
|
+
|
|
#endif /* TARGET_SIGNAL_H */
|
|
|
|
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
|
|
index d51f50c..fbcdd6c 100644
|
|
--- a/bsd-user/qemu.h
|
|
+++ b/bsd-user/qemu.h
|
|
@@ -27,7 +27,6 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
|
|
#include "syscall_defs.h"
|
|
#include "syscall.h"
|
|
#include "target_vmparam.h"
|
|
-#include "target_signal.h"
|
|
#include "exec/gdbstub.h"
|
|
|
|
#if defined(CONFIG_USE_NPTL)
|
|
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
|
|
index b04e874..e7e9e41 100644
|
|
--- a/bsd-user/signal.c
|
|
+++ b/bsd-user/signal.c
|
|
@@ -101,6 +101,9 @@ static struct target_sigaction sigact_table[TARGET_NSIG];
|
|
|
|
static void host_signal_handler(int host_signum, siginfo_t *info, void *puc);
|
|
|
|
+static void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s);
|
|
+void QEMU_NORETURN force_sig(int target_sig);
|
|
+
|
|
static inline int
|
|
on_sig_stack(unsigned long sp)
|
|
{
|
|
@@ -315,7 +318,7 @@ free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q)
|
|
}
|
|
|
|
/* Abort execution with signal. */
|
|
-static void QEMU_NORETURN
|
|
+void QEMU_NORETURN
|
|
force_sig(int target_sig)
|
|
{
|
|
TaskState *ts = (TaskState *)thread_env->opaque;
|
|
@@ -728,194 +731,20 @@ give_sigsegv:
|
|
force_sig(TARGET_SIGSEGV);
|
|
}
|
|
|
|
-long
|
|
-do_sigreturn(CPUArchState *regs, abi_ulong uc_addr)
|
|
-{
|
|
- target_ucontext_t *ucontext;
|
|
- sigset_t blocked;
|
|
- target_sigset_t target_set;
|
|
- int i;
|
|
-
|
|
-#if defined(DEBUG_SIGNAL)
|
|
- fprintf(stderr, "do_sigreturn\n");
|
|
-#endif
|
|
- if (!lock_user_struct(VERIFY_READ, ucontext, uc_addr, 1))
|
|
- goto badframe;
|
|
-
|
|
- for(i = 0; i < TARGET_NSIG_WORDS; i++) {
|
|
- if (__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i]))
|
|
- goto badframe;
|
|
- }
|
|
-
|
|
- if (set_mcontext(regs, &ucontext->uc_mcontext, 0))
|
|
- goto badframe;
|
|
-
|
|
- target_to_host_sigset_internal(&blocked, &target_set);
|
|
- sigprocmask(SIG_SETMASK, &blocked, NULL);
|
|
-
|
|
-#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:
|
|
- force_sig(TARGET_SIGSEGV);
|
|
- return (0);
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-/* #elif defined(TARGET_SPARC64) */
|
|
-#if 0
|
|
-
|
|
-#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_qsr 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_tnpc ureg_i0
|
|
-#define ureg_tpc ureg_i1
|
|
-
|
|
-#define TARGET_FPRS_FEF (1 << 2)
|
|
-#define TARGET_MC_VERSION 1L
|
|
-
|
|
-/* compare to sparc64/sparc64/machdep.c set_mcontext() */
|
|
-static inline int
|
|
-restore_sigmcontext(CPUSPARCState *regs, target_mcontext_t *mc)
|
|
-{
|
|
- int err = 0;
|
|
-
|
|
- err |= __get_user(regs->gregs[1], &mc->mc_global[1]);
|
|
- err |= __get_user(regs->gregs[2], &mc->mc_global[2]);
|
|
- err |= __get_user(regs->gregs[3], &mc->mc_global[3]);
|
|
- err |= __get_user(regs->gregs[4], &mc->mc_global[4]);
|
|
- err |= __get_user(regs->gregs[5], &mc->mc_global[5]);
|
|
- err |= __get_user(regs->gregs[6], &mc->mc_global[6]);
|
|
-
|
|
- err |= __get_user(regs->ureg_o0, &mc->mc_out[0]);
|
|
- err |= __get_user(regs->ureg_o1, &mc->mc_out[1]);
|
|
- err |= __get_user(regs->ureg_o2, &mc->mc_out[2]);
|
|
- err |= __get_user(regs->ureg_o3, &mc->mc_out[3]);
|
|
- err |= __get_user(regs->ureg_o4, &mc->mc_out[4]);
|
|
- err |= __get_user(regs->ureg_o5, &mc->mc_out[5]);
|
|
- err |= __get_user(regs->ureg_o6, &mc->mc_out[6]);
|
|
- err |= __get_user(regs->ureg_o7, &mc->mc_out[0]);
|
|
-
|
|
- err |= __get_user(regs->ureg_l0, &mc->mc_fprs); /* mc_local[0] */
|
|
- err |= __get_user(regs->ureg_l1, &mc->mc_fsr); /* mc_local[1] */
|
|
- err |= __get_user(regs->ureg_l2, &mc->mc_qsr); /* mc_local[2] */
|
|
-
|
|
- err |= __get_user(regs->ureg_i0, &mc->mc_tnpc); /* mc_in[0] */
|
|
- err |= __get_user(regs->ureg_i1, &mc->mc_tpc); /* mc_in[1] */
|
|
- err |= __get_user(regs->ureg_i2, &mc->mc_tstate);/* mc_in[2] */
|
|
-
|
|
- err |= __get_user(regs->ureg_i4, &mc->mc_y); /* mc_in[4] */
|
|
-
|
|
- /* XXX
|
|
- if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) {
|
|
- regs->ureg_l0 = 0;
|
|
- for(i = 0; i < 64; i++)
|
|
- err |= __get_user(regs->fpr[i], &mc->mc_fp[i]);
|
|
- }
|
|
- */
|
|
-
|
|
- return (err);
|
|
-}
|
|
+#else
|
|
|
|
-/* compare to sparc64/sparc64/machdep.c get_mcontext() */
|
|
-static inline int
|
|
-setup_sigmcontext(CPUSPARCState *regs, target_mcontext_t *mc)
|
|
+static void
|
|
+setup_frame(int sig, int code, struct target_sigaction *ka, target_sigset_t *set,
|
|
+ target_siginfo_t *tinfo, CPUArchState *env)
|
|
{
|
|
- int err = 0;
|
|
- abi_ulong ver = TARGET_MC_VERSION;
|
|
-
|
|
- err |= __put_user(ver, &mc->mc_flags); /* aka. mc_global[0] */
|
|
- err |= __put_user(regs->gregs[1], &mc->mc_global[1]);
|
|
- err |= __put_user(regs->gregs[2], &mc->mc_global[2]);
|
|
- err |= __put_user(regs->gregs[3], &mc->mc_global[3]);
|
|
- err |= __put_user(regs->gregs[4], &mc->mc_global[4]);
|
|
- err |= __put_user(regs->gregs[5], &mc->mc_global[5]);
|
|
- err |= __put_user(regs->gregs[6], &mc->mc_global[6]);
|
|
- /* skip %g7 since it is used as the userland TLS register */
|
|
-
|
|
- err |= __put_user(regs->ureg_o0, &mc->mc_out[0]);
|
|
- err |= __put_user(regs->ureg_o1, &mc->mc_out[1]);
|
|
- err |= __put_user(regs->ureg_o2, &mc->mc_out[2]);
|
|
- err |= __put_user(regs->ureg_o3, &mc->mc_out[3]);
|
|
- err |= __put_user(regs->ureg_o4, &mc->mc_out[4]);
|
|
- err |= __put_user(regs->ureg_o5, &mc->mc_out[5]);
|
|
- err |= __put_user(regs->ureg_o6, &mc->mc_out[6]);
|
|
- err |= __put_user(regs->ureg_o7, &mc->mc_out[7]);
|
|
-
|
|
- err |= __put_user(regs->ureg_l0, &mc->mc_fprs); /* mc_local[0] */
|
|
- err |= __put_user(regs->ureg_l1, &mc->mc_fsr); /* mc_local[1] */
|
|
- err |= __put_user(regs->ureg_l2, &mc->mc_qsr); /* mc_local[2] */
|
|
|
|
- err |= __put_user(regs->ureg_i0, &mc->mc_tnpc); /* mc_in[0] */
|
|
- err |= __put_user(regs->ureg_i1, &mc->mc_tpc); /* mc_in[1] */
|
|
- err |= __put_user(regs->ureg_i2, &mc->mc_tstate);/* mc_in[2] */
|
|
-
|
|
- err |= __put_user(regs->ureg_i4, &mc->mc_y); /* mc_in[4] */
|
|
-
|
|
- /* XXX
|
|
- if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) {
|
|
- for(i = 0; i < 64; i++)
|
|
- err |= __put_user(regs->fpr[i], &mc->mc_fp[i]);
|
|
- }
|
|
- */
|
|
-
|
|
- return (err);
|
|
+ fprintf(stderr, "setup_frame: not implemented\n");
|
|
}
|
|
|
|
-static inline abi_ulong
|
|
-get_sigframe(struct target_sigaction *ka, CPUSPARCState *regs, size_t frame_size)
|
|
-{
|
|
- abi_ulong sp;
|
|
+#endif /* ! TARGET_ARM && TARGET_MIPS */
|
|
|
|
- /* Use default user stack */
|
|
- sp = regs->ureg_sp;
|
|
-
|
|
- if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
|
|
- sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
|
- }
|
|
-
|
|
- return (sp - frame_size);
|
|
-}
|
|
|
|
+#if 0
|
|
/* compare to sparc64/sparc64/machdep.c sendsig() */
|
|
static void setup_frame(int sig, int code, struct target_sigaction *ka,
|
|
target_sigset_t *set, target_siginfo_t *tinfo, CPUSPARCState *regs)
|
|
@@ -974,64 +803,60 @@ give_sigsegv:
|
|
unlock_user_struct(frame, frame_addr, 1);
|
|
force_sig(TARGET_SIGSEGV);
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
-long do_sigreturn(CPUSPARCState *regs, abi_ulong uc_addr)
|
|
+static int
|
|
+reset_signal_mask(target_ucontext_t *ucontext)
|
|
{
|
|
- target_ucontext_t *ucontext;
|
|
+ int i;
|
|
sigset_t blocked;
|
|
target_sigset_t target_set;
|
|
- int i;
|
|
|
|
-#if defined(DEBUG_SIGNAL)
|
|
- fprintf(stderr, "do_sigreturn\n");
|
|
-#endif
|
|
- if (!lock_user_struct(VERIFY_READ, ucontext, uc_addr, 1))
|
|
- goto badframe;
|
|
+ for(i = 0; i < TARGET_NSIG_WORDS; i++)
|
|
+ if (__get_user(target_set.__bits[i],
|
|
+ &ucontext->uc_sigmask.__bits[i])) {
|
|
+ return (-TARGET_EFAULT);
|
|
+ }
|
|
+ target_to_host_sigset_internal(&blocked, &target_set);
|
|
+ sigprocmask(SIG_SETMASK, &blocked, NULL);
|
|
|
|
- for(i = 0; i < TARGET_NSIG_WORDS; i++) {
|
|
- if (__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i]))
|
|
+ return (0);
|
|
+}
|
|
+
|
|
+long
|
|
+do_sigreturn(CPUArchState *regs, abi_ulong addr)
|
|
+{
|
|
+ int ret;
|
|
+ target_ucontext_t *ucontext;
|
|
+ void *locked_addr = NULL;
|
|
+
|
|
+ /* Lock the memory and get the ucontext ptr from the stack frame */
|
|
+ ret = get_ucontext_sigreturn(regs, addr, &ucontext, &locked_addr);
|
|
+ if (ret) {
|
|
+ if (-TARGET_EFAULT == ret)
|
|
goto badframe;
|
|
+ else
|
|
+ return (ret);
|
|
}
|
|
|
|
- if (restore_sigmcontext(regs, &ucontext->uc_mcontext))
|
|
+ /* Set the register state back to before the signal. */
|
|
+ if (set_mcontext(regs, &ucontext->uc_mcontext, 1))
|
|
goto badframe;
|
|
|
|
- target_to_host_sigset_internal(&blocked, &target_set);
|
|
- sigprocmask(SIG_SETMASK, &blocked, NULL);
|
|
+ /* And reset the signal mask. */
|
|
+ if (reset_signal_mask(ucontext))
|
|
+ goto badframe;
|
|
|
|
- return (-TARGET_QEMU_ESIGRETURN);
|
|
+ unlock_user_struct(locked_addr, addr, 0);
|
|
+ return (-TARGET_EJUSTRETURN);
|
|
|
|
badframe:
|
|
+ if (locked_addr != NULL)
|
|
+ unlock_user_struct(locked_addr, addr, 0);
|
|
force_sig(TARGET_SIGSEGV);
|
|
- return (0);
|
|
-}
|
|
-#endif
|
|
-
|
|
-#else
|
|
-
|
|
-static void
|
|
-setup_frame(int sig, int code, struct target_sigaction *ka, target_sigset_t *set,
|
|
- target_siginfo_t *tinfo, CPUArchState *env)
|
|
-{
|
|
- fprintf(stderr, "setup_frame: not implemented\n");
|
|
-}
|
|
-
|
|
-long
|
|
-do_sigreturn(CPUArchState *env, abi_ulong uc_addr)
|
|
-{
|
|
- fprintf(stderr,"do_sigreturn: not implemented\n");
|
|
- return (-TARGET_ENOSYS);
|
|
+ return (-TARGET_EFAULT);
|
|
}
|
|
|
|
-long
|
|
-do_rt_sigreturn(CPUArchState *env)
|
|
-{
|
|
- fprintf(stderr, "do_rt_sigreturn: not implemented\n");
|
|
- return (-TARGET_ENOSYS);
|
|
-}
|
|
-#endif
|
|
-
|
|
void
|
|
signal_init(void)
|
|
{
|
|
diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h
|
|
index e2fe79c..65d315a 100644
|
|
--- a/bsd-user/sparc/target_signal.h
|
|
+++ b/bsd-user/sparc/target_signal.h
|
|
@@ -43,4 +43,12 @@ set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
|
|
return (-TARGET_ENOSYS);
|
|
}
|
|
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ fprintf(stderr, "SPARC doesn't have support for do_sigreturn()\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 1bc7c96..fa8edb8 100644
|
|
--- a/bsd-user/sparc64/target_signal.h
|
|
+++ b/bsd-user/sparc64/target_signal.h
|
|
@@ -245,4 +245,12 @@ set_mcontext(CPUSPARCState *regs, target_mcontext_t *mcp, int flags)
|
|
return (0);
|
|
}
|
|
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ fprintf(stderr, "SPARC64 doesn't have support for do_sigreturn()\n");
|
|
+ return (-TARGET_ENOSYS);
|
|
+}
|
|
+
|
|
#endif /* TARGET_SIGNAL_H */
|
|
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
|
|
index 636083a..2d97a23 100644
|
|
--- a/bsd-user/syscall.c
|
|
+++ b/bsd-user/syscall.c
|
|
@@ -90,12 +90,12 @@
|
|
|
|
#include "qemu.h"
|
|
#include "qemu-common.h"
|
|
+#include "target_signal.h"
|
|
#ifdef __FreeBSD__
|
|
#include "freebsd/ttycom.h"
|
|
#include "freebsd/filio.h"
|
|
#endif
|
|
|
|
-
|
|
//#define DEBUG
|
|
|
|
static abi_ulong target_brk;
|
|
@@ -346,32 +346,47 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
|
|
#endif
|
|
|
|
#ifdef TARGET_ARM
|
|
-static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
|
|
+static abi_long do_freebsd_sysarch(CPUARMState *env, int op, abi_ulong parms)
|
|
{
|
|
+ int ret = 0;
|
|
|
|
switch (op) {
|
|
+ case TARGET_FREEBSD_ARM_SYNC_ICACHE:
|
|
+ case TARGET_FREEBSD_ARM_DRAIN_WRITEBUF:
|
|
+ break;
|
|
+
|
|
case TARGET_FREEBSD_ARM_SET_TP:
|
|
cpu_set_tls(env, parms);
|
|
- return 0;
|
|
+ break;
|
|
+
|
|
+ case TARGET_FREEBSD_ARM_GET_TP:
|
|
+ /* XXX Need a cpu_get_tls() */
|
|
+ if (put_user(env->cp15.c13_tls2, parms, abi_ulong))
|
|
+ ret = -TARGET_EFAULT;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ ret = -TARGET_EINVAL;
|
|
+ break;
|
|
}
|
|
|
|
- return -TARGET_EINVAL;
|
|
+ return (ret);
|
|
}
|
|
#endif
|
|
|
|
#ifdef TARGET_MIPS
|
|
-static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
|
|
+static abi_long do_freebsd_sysarch(CPUMIPSState *env, int op, abi_ulong parms)
|
|
{
|
|
int ret = 0;
|
|
- CPUMIPSState *mips_env = (CPUMIPSState *)env;
|
|
|
|
switch(op) {
|
|
case TARGET_MIPS_SET_TLS:
|
|
- mips_env->tls_value = parms;
|
|
+ cpu_set_tls(env, parms);
|
|
break;
|
|
|
|
case TARGET_MIPS_GET_TLS:
|
|
- if (put_user(mips_env->tls_value, parms, abi_ulong))
|
|
+ /* XXX Need a cpu_get_tls() */
|
|
+ if (put_user(env->tls_value, parms, abi_ulong))
|
|
ret = -TARGET_EFAULT;
|
|
break;
|
|
default:
|
|
@@ -671,7 +686,7 @@ target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr,
|
|
if (!target_saddr)
|
|
return -TARGET_EFAULT;
|
|
|
|
- sa_family = tswap16(target_saddr->sa_family);
|
|
+ sa_family = target_saddr->sa_family;
|
|
|
|
/*
|
|
* Oops. The caller might send a incomplete sun_path; sun_path
|
|
@@ -680,7 +695,7 @@ target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr,
|
|
* "strlen(x->sun_path)" while it should be "strlen(...) + 1". We will
|
|
* fix that here if needed.
|
|
*/
|
|
- if (sa_family == AF_UNIX) {
|
|
+ if (target_saddr->sa_family == AF_UNIX) {
|
|
if (len < unix_maxlen && len > 0) {
|
|
char *cp = (char*)target_saddr;
|
|
|
|
@@ -692,7 +707,8 @@ target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr,
|
|
}
|
|
|
|
memcpy(addr, target_saddr, len);
|
|
- addr->sa_family = sa_family;
|
|
+ addr->sa_family = sa_family; /* type uint8_t */
|
|
+ addr->sa_len = target_saddr->sa_len; /* type uint8_t */
|
|
unlock_user(target_saddr, target_addr, 0);
|
|
|
|
return (0);
|
|
@@ -708,7 +724,8 @@ host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr,
|
|
if (!target_saddr)
|
|
return (-TARGET_EFAULT);
|
|
memcpy(target_saddr, addr, len);
|
|
- target_saddr->sa_family = tswap16(addr->sa_family);
|
|
+ target_saddr->sa_family = addr->sa_family; /* type uint8_t */
|
|
+ target_saddr->sa_len = addr->sa_len; /* type uint8_t */
|
|
unlock_user(target_saddr, target_addr, len);
|
|
|
|
return (0);
|
|
@@ -1427,7 +1444,7 @@ static abi_long
|
|
do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr,
|
|
socklen_t addrlen)
|
|
{
|
|
- void *addr;
|
|
+ struct sockaddr *saddr;
|
|
void *host_msg;
|
|
abi_long ret;
|
|
|
|
@@ -1437,13 +1454,13 @@ do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr,
|
|
if (!host_msg)
|
|
return (-TARGET_EFAULT);
|
|
if (target_addr) {
|
|
- addr = alloca(addrlen);
|
|
- ret = target_to_host_sockaddr(addr, target_addr, addrlen);
|
|
+ saddr = alloca(addrlen);
|
|
+ ret = target_to_host_sockaddr(saddr, target_addr, addrlen);
|
|
if (ret) {
|
|
unlock_user(host_msg, msg, 0);
|
|
return (ret);
|
|
}
|
|
- ret = get_errno(sendto(fd, host_msg, len, flags, addr,
|
|
+ ret = get_errno(sendto(fd, host_msg, len, flags, saddr,
|
|
addrlen));
|
|
} else {
|
|
ret = get_errno(send(fd, host_msg, len, flags));
|
|
@@ -1458,7 +1475,7 @@ do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr,
|
|
abi_ulong target_addrlen)
|
|
{
|
|
socklen_t addrlen;
|
|
- void *addr;
|
|
+ struct sockaddr *saddr;
|
|
void *host_msg;
|
|
abi_long ret;
|
|
|
|
@@ -1474,16 +1491,16 @@ do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr,
|
|
ret = (-TARGET_EINVAL);
|
|
goto fail;
|
|
}
|
|
- addr = alloca(addrlen);
|
|
- ret = get_errno(recvfrom(fd, host_msg, len, flags, addr,
|
|
+ saddr = alloca(addrlen);
|
|
+ ret = get_errno(recvfrom(fd, host_msg, len, flags, saddr,
|
|
&addrlen));
|
|
} else {
|
|
- addr = NULL; /* To keep compiler quiet. */
|
|
+ saddr = NULL; /* To keep compiler quiet. */
|
|
ret = get_errno(qemu_recv(fd, host_msg, len, flags));
|
|
}
|
|
if (!is_error(ret)) {
|
|
if (target_addr) {
|
|
- host_to_target_sockaddr(target_addr, addr, addrlen);
|
|
+ host_to_target_sockaddr(target_addr, saddr, addrlen);
|
|
if (put_user_u32(addrlen, target_addrlen)) {
|
|
ret = -TARGET_EFAULT;
|
|
goto fail;
|
|
@@ -5670,8 +5687,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
|
return (-TARGET_EFAULT);
|
|
fl.l_type = tswap16(target_fl->l_type);
|
|
fl.l_whence = tswap16(target_fl->l_whence);
|
|
- fl.l_start = tswapal(target_fl->l_start);
|
|
- fl.l_len = tswapal(target_fl->l_len);
|
|
+ fl.l_start = tswap64(target_fl->l_start);
|
|
+ fl.l_len = tswap64(target_fl->l_len);
|
|
fl.l_pid = tswap32(target_fl->l_pid);
|
|
fl.l_sysid = tswap32(target_fl->l_sysid);
|
|
unlock_user_struct(target_fl, arg3, 0);
|
|
@@ -5682,8 +5699,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
|
return (-TARGET_EFAULT);
|
|
target_fl->l_type = tswap16(fl.l_type);
|
|
target_fl->l_whence = tswap16(fl.l_whence);
|
|
- target_fl->l_start = tswapal(fl.l_start);
|
|
- target_fl->l_len = tswapal(fl.l_len);
|
|
+ target_fl->l_start = tswap64(fl.l_start);
|
|
+ target_fl->l_len = tswap64(fl.l_len);
|
|
target_fl->l_pid = tswap32(fl.l_pid);
|
|
target_fl->l_sysid = tswap32(fl.l_sysid);
|
|
unlock_user_struct(target_fl, arg3, 1);
|
|
@@ -5694,8 +5711,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
|
case TARGET_F_SETLKW:
|
|
if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
|
|
return (-TARGET_EFAULT);
|
|
- fl.l_start = tswapal(target_fl->l_start);
|
|
- fl.l_len = tswapal(target_fl->l_len);
|
|
+ fl.l_start = tswap64(target_fl->l_start);
|
|
+ fl.l_len = tswap64(target_fl->l_len);
|
|
fl.l_pid = tswap32(target_fl->l_pid);
|
|
fl.l_type = tswap16(target_fl->l_type);
|
|
fl.l_whence = tswap16(target_fl->l_whence);
|
|
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
|
|
index 8a92403..eb804b3 100644
|
|
--- a/bsd-user/syscall_defs.h
|
|
+++ b/bsd-user/syscall_defs.h
|
|
@@ -132,8 +132,8 @@
|
|
#define TARGET_TRAP_TRACE (2) /* process trace trap */
|
|
|
|
struct target_rlimit {
|
|
- abi_ulong rlim_cur;
|
|
- abi_ulong rlim_max;
|
|
+ uint64_t rlim_cur;
|
|
+ uint64_t rlim_max;
|
|
};
|
|
|
|
#if defined(TARGET_ALPHA)
|
|
@@ -203,8 +203,8 @@ struct target_pollfd {
|
|
#include "openbsd/syscall_nr.h"
|
|
|
|
struct target_flock {
|
|
- abi_long l_start;
|
|
- abi_long l_len;
|
|
+ int64_t l_start;
|
|
+ int64_t l_len;
|
|
int32_t l_pid;
|
|
int16_t l_type;
|
|
int16_t l_whence;
|
|
@@ -260,19 +260,29 @@ __target_cmsg_nxthdr (struct target_msghdr *__mhdr,
|
|
}
|
|
|
|
struct target_sockaddr {
|
|
- uint16_t sa_family;
|
|
+ uint8_t sa_len;
|
|
+ uint8_t sa_family;
|
|
uint8_t sa_data[14];
|
|
-};
|
|
+} QEMU_PACKED;
|
|
|
|
struct target_in_addr {
|
|
uint32_t s_addr; /* big endian */
|
|
};
|
|
|
|
+/*
|
|
+ * FreeBSD/{arm, mips} uses a 64bits time_t, even in 32bits mode,
|
|
+ * so we have to add a special case here.
|
|
+ */
|
|
+#if defined(TARGET_ARM) || defined(TARGET_MIPS)
|
|
+typedef int64_t target_freebsd_time_t;
|
|
+#else
|
|
+typedef abi_long target_freebsd_time_t;
|
|
+#endif
|
|
|
|
struct target_timeval {
|
|
- abi_long tv_sec;
|
|
+ target_freebsd_time_t tv_sec;
|
|
abi_long tv_usec;
|
|
-};
|
|
+} QEMU_PACKED;
|
|
|
|
typedef abi_long target_clock_t;
|
|
|
|
@@ -304,21 +314,13 @@ struct target_kevent {
|
|
abi_ulong udata;
|
|
} __packed;
|
|
|
|
-/*
|
|
- * FreeBSD/arm uses a 64bits time_t, even in 32bits mode, so we have to
|
|
- * add a special case here.
|
|
- */
|
|
-#if defined(TARGET_ARM)
|
|
-typedef uint64_t target_freebsd_time_t;
|
|
-#else
|
|
-typedef long target_freebsd_time_t;
|
|
-#endif
|
|
|
|
struct target_freebsd_timespec {
|
|
target_freebsd_time_t tv_sec; /* seconds */
|
|
abi_long tv_nsec; /* and nanoseconds */
|
|
} __packed;
|
|
|
|
+/* XXX We have target_*_timeval defined twice. */
|
|
struct target_freebsd_timeval {
|
|
target_freebsd_time_t tv_sec;
|
|
abi_long tv_usec;
|
|
@@ -672,7 +674,7 @@ struct target_statfs {
|
|
uint64_t f_asyncreads; /* count of async reads since mount */
|
|
uint64_t f_spare[10]; /* unused spare */
|
|
uint32_t f_namemax; /* maximum filename length */
|
|
- uid_t f_owner; /* user that mounted the filesystem */
|
|
+ uint32_t f_owner; /* user that mounted the filesystem */
|
|
target_fsid_t f_fsid; /* filesystem id */
|
|
char f_charspare[80]; /* spare string space */
|
|
char f_fstypename[TARGET_MFSNAMELEN]; /* filesys type name */
|
|
diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h
|
|
index a14e0b9..72df2f0 100644
|
|
--- a/bsd-user/x86_64/target_signal.h
|
|
+++ b/bsd-user/x86_64/target_signal.h
|
|
@@ -3,7 +3,8 @@
|
|
|
|
#include "cpu.h"
|
|
|
|
-static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
|
|
+static inline abi_ulong
|
|
+get_sp_from_cpustate(CPUX86State *state)
|
|
{
|
|
return state->regs[R_ESP];
|
|
}
|
|
@@ -26,18 +27,26 @@ typedef struct target_ucontext {
|
|
int32_t __spare__[4];
|
|
} target_ucontext_t;
|
|
|
|
-static inline int
|
|
+static inline abi_long
|
|
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
|
|
+static inline abi_long
|
|
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);
|
|
}
|
|
|
|
+static inline abi_long
|
|
+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
|
|
+ target_ucontext_t **ucontext, void **locked_addr)
|
|
+{
|
|
+ fprintf(stderr, "x86_64 doesn't have support for do_sigreturn()\n");
|
|
+ return (-TARGET_ENOSYS);
|
|
+}
|
|
+
|
|
#endif /* TARGET_SIGNAL_H */
|