Loading bsd-user/elfload.c +9 −1 Original line number Diff line number Diff line Loading @@ -126,6 +126,9 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i regs->rax = 0; regs->rsp = infop->start_stack; regs->rip = infop->entry; if (bsd_type == target_freebsd) { regs->rdi = infop->start_stack; } } #else Loading Loading @@ -249,8 +252,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #else if (personality(infop->personality) == PER_LINUX32) regs->u_regs[14] = infop->start_stack - 16 * 4; else else { regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; if (bsd_type == target_freebsd) { regs->u_regs[8] = infop->start_stack; regs->u_regs[11] = infop->start_stack; } } #endif } Loading bsd-user/freebsd/strace.list +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_futimes, "futimes", 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 }, { TARGET_FREEBSD_NR_geteuid, "geteuid", "%s()", NULL, NULL }, { TARGET_FREEBSD_NR_getfh, "getfh", NULL, NULL, NULL }, Loading bsd-user/i386/syscall.h +14 −0 Original line number Diff line number Diff line Loading @@ -143,5 +143,19 @@ struct target_vm86plus_struct { struct target_vm86plus_info_struct vm86plus; }; /* FreeBSD sysarch(2) */ #define TARGET_FREEBSD_I386_GET_LDT 0 #define TARGET_FREEBSD_I386_SET_LDT 1 /* I386_IOPL */ #define TARGET_FREEBSD_I386_GET_IOPERM 3 #define TARGET_FREEBSD_I386_SET_IOPERM 4 /* xxxxx */ #define TARGET_FREEBSD_I386_VM86 6 #define TARGET_FREEBSD_I386_GET_FSBASE 7 #define TARGET_FREEBSD_I386_SET_FSBASE 8 #define TARGET_FREEBSD_I386_GET_GSBASE 9 #define TARGET_FREEBSD_I386_SET_GSBASE 10 #define UNAME_MACHINE "i386" bsd-user/main.c +94 −22 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ int have_guest_base; static const char *interp_prefix = CONFIG_QEMU_PREFIX; const char *qemu_uname_release = CONFIG_UNAME_RELEASE; extern char **environ; enum BSDType bsd_type; /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so we allocate a bigger stack. Need a better solution, for example Loading Loading @@ -168,7 +169,7 @@ static void set_idt(int n, unsigned int dpl) } #endif void cpu_loop(CPUX86State *env, enum BSDType bsd_type) void cpu_loop(CPUX86State *env) { int trapnr; abi_ulong pc; Loading @@ -179,6 +180,45 @@ void cpu_loop(CPUX86State *env, enum BSDType bsd_type) switch(trapnr) { case 0x80: /* syscall from int $0x80 */ if (bsd_type == target_freebsd) { abi_ulong params = (abi_ulong) env->regs[R_ESP] + sizeof(int32_t); int32_t syscall_nr = env->regs[R_EAX]; int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; if (syscall_nr == TARGET_FREEBSD_NR_syscall) { get_user_s32(syscall_nr, params); params += sizeof(int32_t); } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) { get_user_s32(syscall_nr, params); params += sizeof(int64_t); } get_user_s32(arg1, params); params += sizeof(int32_t); get_user_s32(arg2, params); params += sizeof(int32_t); get_user_s32(arg3, params); params += sizeof(int32_t); get_user_s32(arg4, params); params += sizeof(int32_t); get_user_s32(arg5, params); params += sizeof(int32_t); get_user_s32(arg6, params); params += sizeof(int32_t); get_user_s32(arg7, params); params += sizeof(int32_t); get_user_s32(arg8, params); env->regs[R_EAX] = do_freebsd_syscall(env, syscall_nr, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } else { //if (bsd_type == target_openbsd) env->regs[R_EAX] = do_openbsd_syscall(env, env->regs[R_EAX], env->regs[R_EBX], Loading @@ -187,10 +227,27 @@ void cpu_loop(CPUX86State *env, enum BSDType bsd_type) env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP]); } if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { env->regs[R_EAX] = -env->regs[R_EAX]; env->eflags |= CC_C; } else { env->eflags &= ~CC_C; } break; #ifndef TARGET_ABI32 case EXCP_SYSCALL: /* linux syscall from syscall intruction */ /* syscall from syscall intruction */ if (bsd_type == target_freebsd) env->regs[R_EAX] = do_freebsd_syscall(env, env->regs[R_EAX], env->regs[R_EDI], env->regs[R_ESI], env->regs[R_EDX], env->regs[R_ECX], env->regs[8], env->regs[9], 0, 0); else { //if (bsd_type == target_openbsd) env->regs[R_EAX] = do_openbsd_syscall(env, env->regs[R_EAX], env->regs[R_EDI], Loading @@ -199,7 +256,14 @@ void cpu_loop(CPUX86State *env, enum BSDType bsd_type) env->regs[10], env->regs[8], env->regs[9]); } env->eip = env->exception_next_eip; if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { env->regs[R_EAX] = -env->regs[R_EAX]; env->eflags |= CC_C; } else { env->eflags &= ~CC_C; } break; #endif #if 0 Loading Loading @@ -446,7 +510,7 @@ static void flush_windows(CPUSPARCState *env) #endif } void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) void cpu_loop(CPUSPARCState *env) { int trapnr, ret, syscall_nr; //target_siginfo_t info; Loading @@ -458,6 +522,10 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) #ifndef TARGET_SPARC64 case 0x80: #else /* FreeBSD uses 0x141 for syscalls too */ case 0x141: if (bsd_type != target_freebsd) goto badtrap; case 0x100: #endif syscall_nr = env->gregs[1]; Loading @@ -465,7 +533,7 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) ret = do_freebsd_syscall(env, syscall_nr, env->regwptr[0], env->regwptr[1], env->regwptr[2], env->regwptr[3], env->regwptr[4], env->regwptr[5]); env->regwptr[4], env->regwptr[5], 0, 0); else if (bsd_type == target_netbsd) ret = do_netbsd_syscall(env, syscall_nr, env->regwptr[0], env->regwptr[1], Loading @@ -482,6 +550,7 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) env->regwptr[4], env->regwptr[5]); } if ((unsigned int)ret >= (unsigned int)(-515)) { ret = -ret; #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc |= PSR_CARRY; #else Loading Loading @@ -587,6 +656,9 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) } break; default: #ifdef TARGET_SPARC64 badtrap: #endif printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(env, stderr, fprintf, 0); exit (1); Loading Loading @@ -668,7 +740,7 @@ int main(int argc, char **argv) int gdbstub_port = 0; char **target_environ, **wrk; envlist_t *envlist = NULL; enum BSDType bsd_type = target_openbsd; bsd_type = target_openbsd; if (argc <= 1) usage(); Loading Loading @@ -1033,7 +1105,7 @@ int main(int argc, char **argv) gdbserver_start (gdbstub_port); gdb_handlesig(env, 0); } cpu_loop(env, bsd_type); cpu_loop(env); /* never exits */ return 0; } bsd-user/qemu.h +4 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ enum BSDType { target_netbsd, target_openbsd, }; extern enum BSDType bsd_type; #include "syscall_defs.h" #include "syscall.h" Loading Loading @@ -130,7 +131,8 @@ abi_long do_brk(abi_ulong new_brk); void syscall_init(void); abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6); abi_long arg5, abi_long arg6, abi_long arg7, abi_long arg8); abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6); Loading @@ -139,7 +141,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg5, abi_long arg6); void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); extern THREAD CPUState *thread_env; void cpu_loop(CPUState *env, enum BSDType bsd_type); void cpu_loop(CPUState *env); char *target_strerror(int err); int get_osversion(void); void fork_start(void); Loading Loading
bsd-user/elfload.c +9 −1 Original line number Diff line number Diff line Loading @@ -126,6 +126,9 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i regs->rax = 0; regs->rsp = infop->start_stack; regs->rip = infop->entry; if (bsd_type == target_freebsd) { regs->rdi = infop->start_stack; } } #else Loading Loading @@ -249,8 +252,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #else if (personality(infop->personality) == PER_LINUX32) regs->u_regs[14] = infop->start_stack - 16 * 4; else else { regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; if (bsd_type == target_freebsd) { regs->u_regs[8] = infop->start_stack; regs->u_regs[11] = infop->start_stack; } } #endif } Loading
bsd-user/freebsd/strace.list +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_futimes, "futimes", 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 }, { TARGET_FREEBSD_NR_geteuid, "geteuid", "%s()", NULL, NULL }, { TARGET_FREEBSD_NR_getfh, "getfh", NULL, NULL, NULL }, Loading
bsd-user/i386/syscall.h +14 −0 Original line number Diff line number Diff line Loading @@ -143,5 +143,19 @@ struct target_vm86plus_struct { struct target_vm86plus_info_struct vm86plus; }; /* FreeBSD sysarch(2) */ #define TARGET_FREEBSD_I386_GET_LDT 0 #define TARGET_FREEBSD_I386_SET_LDT 1 /* I386_IOPL */ #define TARGET_FREEBSD_I386_GET_IOPERM 3 #define TARGET_FREEBSD_I386_SET_IOPERM 4 /* xxxxx */ #define TARGET_FREEBSD_I386_VM86 6 #define TARGET_FREEBSD_I386_GET_FSBASE 7 #define TARGET_FREEBSD_I386_SET_FSBASE 8 #define TARGET_FREEBSD_I386_GET_GSBASE 9 #define TARGET_FREEBSD_I386_SET_GSBASE 10 #define UNAME_MACHINE "i386"
bsd-user/main.c +94 −22 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ int have_guest_base; static const char *interp_prefix = CONFIG_QEMU_PREFIX; const char *qemu_uname_release = CONFIG_UNAME_RELEASE; extern char **environ; enum BSDType bsd_type; /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so we allocate a bigger stack. Need a better solution, for example Loading Loading @@ -168,7 +169,7 @@ static void set_idt(int n, unsigned int dpl) } #endif void cpu_loop(CPUX86State *env, enum BSDType bsd_type) void cpu_loop(CPUX86State *env) { int trapnr; abi_ulong pc; Loading @@ -179,6 +180,45 @@ void cpu_loop(CPUX86State *env, enum BSDType bsd_type) switch(trapnr) { case 0x80: /* syscall from int $0x80 */ if (bsd_type == target_freebsd) { abi_ulong params = (abi_ulong) env->regs[R_ESP] + sizeof(int32_t); int32_t syscall_nr = env->regs[R_EAX]; int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; if (syscall_nr == TARGET_FREEBSD_NR_syscall) { get_user_s32(syscall_nr, params); params += sizeof(int32_t); } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) { get_user_s32(syscall_nr, params); params += sizeof(int64_t); } get_user_s32(arg1, params); params += sizeof(int32_t); get_user_s32(arg2, params); params += sizeof(int32_t); get_user_s32(arg3, params); params += sizeof(int32_t); get_user_s32(arg4, params); params += sizeof(int32_t); get_user_s32(arg5, params); params += sizeof(int32_t); get_user_s32(arg6, params); params += sizeof(int32_t); get_user_s32(arg7, params); params += sizeof(int32_t); get_user_s32(arg8, params); env->regs[R_EAX] = do_freebsd_syscall(env, syscall_nr, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } else { //if (bsd_type == target_openbsd) env->regs[R_EAX] = do_openbsd_syscall(env, env->regs[R_EAX], env->regs[R_EBX], Loading @@ -187,10 +227,27 @@ void cpu_loop(CPUX86State *env, enum BSDType bsd_type) env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP]); } if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { env->regs[R_EAX] = -env->regs[R_EAX]; env->eflags |= CC_C; } else { env->eflags &= ~CC_C; } break; #ifndef TARGET_ABI32 case EXCP_SYSCALL: /* linux syscall from syscall intruction */ /* syscall from syscall intruction */ if (bsd_type == target_freebsd) env->regs[R_EAX] = do_freebsd_syscall(env, env->regs[R_EAX], env->regs[R_EDI], env->regs[R_ESI], env->regs[R_EDX], env->regs[R_ECX], env->regs[8], env->regs[9], 0, 0); else { //if (bsd_type == target_openbsd) env->regs[R_EAX] = do_openbsd_syscall(env, env->regs[R_EAX], env->regs[R_EDI], Loading @@ -199,7 +256,14 @@ void cpu_loop(CPUX86State *env, enum BSDType bsd_type) env->regs[10], env->regs[8], env->regs[9]); } env->eip = env->exception_next_eip; if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { env->regs[R_EAX] = -env->regs[R_EAX]; env->eflags |= CC_C; } else { env->eflags &= ~CC_C; } break; #endif #if 0 Loading Loading @@ -446,7 +510,7 @@ static void flush_windows(CPUSPARCState *env) #endif } void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) void cpu_loop(CPUSPARCState *env) { int trapnr, ret, syscall_nr; //target_siginfo_t info; Loading @@ -458,6 +522,10 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) #ifndef TARGET_SPARC64 case 0x80: #else /* FreeBSD uses 0x141 for syscalls too */ case 0x141: if (bsd_type != target_freebsd) goto badtrap; case 0x100: #endif syscall_nr = env->gregs[1]; Loading @@ -465,7 +533,7 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) ret = do_freebsd_syscall(env, syscall_nr, env->regwptr[0], env->regwptr[1], env->regwptr[2], env->regwptr[3], env->regwptr[4], env->regwptr[5]); env->regwptr[4], env->regwptr[5], 0, 0); else if (bsd_type == target_netbsd) ret = do_netbsd_syscall(env, syscall_nr, env->regwptr[0], env->regwptr[1], Loading @@ -482,6 +550,7 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) env->regwptr[4], env->regwptr[5]); } if ((unsigned int)ret >= (unsigned int)(-515)) { ret = -ret; #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc |= PSR_CARRY; #else Loading Loading @@ -587,6 +656,9 @@ void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) } break; default: #ifdef TARGET_SPARC64 badtrap: #endif printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(env, stderr, fprintf, 0); exit (1); Loading Loading @@ -668,7 +740,7 @@ int main(int argc, char **argv) int gdbstub_port = 0; char **target_environ, **wrk; envlist_t *envlist = NULL; enum BSDType bsd_type = target_openbsd; bsd_type = target_openbsd; if (argc <= 1) usage(); Loading Loading @@ -1033,7 +1105,7 @@ int main(int argc, char **argv) gdbserver_start (gdbstub_port); gdb_handlesig(env, 0); } cpu_loop(env, bsd_type); cpu_loop(env); /* never exits */ return 0; }
bsd-user/qemu.h +4 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ enum BSDType { target_netbsd, target_openbsd, }; extern enum BSDType bsd_type; #include "syscall_defs.h" #include "syscall.h" Loading Loading @@ -130,7 +131,8 @@ abi_long do_brk(abi_ulong new_brk); void syscall_init(void); abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6); abi_long arg5, abi_long arg6, abi_long arg7, abi_long arg8); abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6); Loading @@ -139,7 +141,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg5, abi_long arg6); void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); extern THREAD CPUState *thread_env; void cpu_loop(CPUState *env, enum BSDType bsd_type); void cpu_loop(CPUState *env); char *target_strerror(int err); int get_osversion(void); void fork_start(void); Loading