qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

bsd-user: FreeBSD update

basic FreeBSD sysarch(2) handling
fixed syscall errno return

Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>

authored by

Juergen Lock and committed by
Blue Swirl
78cfb07f 976b2037

+462 -31
+9 -1
bsd-user/elfload.c
··· 126 126 regs->rax = 0; 127 127 regs->rsp = infop->start_stack; 128 128 regs->rip = infop->entry; 129 + if (bsd_type == target_freebsd) { 130 + regs->rdi = infop->start_stack; 131 + } 129 132 } 130 133 131 134 #else ··· 249 252 #else 250 253 if (personality(infop->personality) == PER_LINUX32) 251 254 regs->u_regs[14] = infop->start_stack - 16 * 4; 252 - else 255 + else { 253 256 regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; 257 + if (bsd_type == target_freebsd) { 258 + regs->u_regs[8] = infop->start_stack; 259 + regs->u_regs[11] = infop->start_stack; 260 + } 261 + } 254 262 #endif 255 263 } 256 264
+1
bsd-user/freebsd/strace.list
··· 39 39 { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, 40 40 { TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL }, 41 41 { TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL }, 42 + { TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL }, 42 43 { TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL }, 43 44 { TARGET_FREEBSD_NR_geteuid, "geteuid", "%s()", NULL, NULL }, 44 45 { TARGET_FREEBSD_NR_getfh, "getfh", NULL, NULL, NULL },
+14
bsd-user/i386/syscall.h
··· 143 143 struct target_vm86plus_info_struct vm86plus; 144 144 }; 145 145 146 + /* FreeBSD sysarch(2) */ 147 + #define TARGET_FREEBSD_I386_GET_LDT 0 148 + #define TARGET_FREEBSD_I386_SET_LDT 1 149 + /* I386_IOPL */ 150 + #define TARGET_FREEBSD_I386_GET_IOPERM 3 151 + #define TARGET_FREEBSD_I386_SET_IOPERM 4 152 + /* xxxxx */ 153 + #define TARGET_FREEBSD_I386_VM86 6 154 + #define TARGET_FREEBSD_I386_GET_FSBASE 7 155 + #define TARGET_FREEBSD_I386_SET_FSBASE 8 156 + #define TARGET_FREEBSD_I386_GET_GSBASE 9 157 + #define TARGET_FREEBSD_I386_SET_GSBASE 10 158 + 159 + 146 160 #define UNAME_MACHINE "i386" 147 161
+94 -22
bsd-user/main.c
··· 46 46 static const char *interp_prefix = CONFIG_QEMU_PREFIX; 47 47 const char *qemu_uname_release = CONFIG_UNAME_RELEASE; 48 48 extern char **environ; 49 + enum BSDType bsd_type; 49 50 50 51 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so 51 52 we allocate a bigger stack. Need a better solution, for example ··· 168 169 } 169 170 #endif 170 171 171 - void cpu_loop(CPUX86State *env, enum BSDType bsd_type) 172 + void cpu_loop(CPUX86State *env) 172 173 { 173 174 int trapnr; 174 175 abi_ulong pc; ··· 179 180 switch(trapnr) { 180 181 case 0x80: 181 182 /* syscall from int $0x80 */ 182 - env->regs[R_EAX] = do_openbsd_syscall(env, 183 - env->regs[R_EAX], 184 - env->regs[R_EBX], 185 - env->regs[R_ECX], 186 - env->regs[R_EDX], 187 - env->regs[R_ESI], 188 - env->regs[R_EDI], 189 - env->regs[R_EBP]); 183 + if (bsd_type == target_freebsd) { 184 + abi_ulong params = (abi_ulong) env->regs[R_ESP] + 185 + sizeof(int32_t); 186 + int32_t syscall_nr = env->regs[R_EAX]; 187 + int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; 188 + 189 + if (syscall_nr == TARGET_FREEBSD_NR_syscall) { 190 + get_user_s32(syscall_nr, params); 191 + params += sizeof(int32_t); 192 + } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) { 193 + get_user_s32(syscall_nr, params); 194 + params += sizeof(int64_t); 195 + } 196 + get_user_s32(arg1, params); 197 + params += sizeof(int32_t); 198 + get_user_s32(arg2, params); 199 + params += sizeof(int32_t); 200 + get_user_s32(arg3, params); 201 + params += sizeof(int32_t); 202 + get_user_s32(arg4, params); 203 + params += sizeof(int32_t); 204 + get_user_s32(arg5, params); 205 + params += sizeof(int32_t); 206 + get_user_s32(arg6, params); 207 + params += sizeof(int32_t); 208 + get_user_s32(arg7, params); 209 + params += sizeof(int32_t); 210 + get_user_s32(arg8, params); 211 + env->regs[R_EAX] = do_freebsd_syscall(env, 212 + syscall_nr, 213 + arg1, 214 + arg2, 215 + arg3, 216 + arg4, 217 + arg5, 218 + arg6, 219 + arg7, 220 + arg8); 221 + } else { //if (bsd_type == target_openbsd) 222 + env->regs[R_EAX] = do_openbsd_syscall(env, 223 + env->regs[R_EAX], 224 + env->regs[R_EBX], 225 + env->regs[R_ECX], 226 + env->regs[R_EDX], 227 + env->regs[R_ESI], 228 + env->regs[R_EDI], 229 + env->regs[R_EBP]); 230 + } 231 + if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { 232 + env->regs[R_EAX] = -env->regs[R_EAX]; 233 + env->eflags |= CC_C; 234 + } else { 235 + env->eflags &= ~CC_C; 236 + } 190 237 break; 191 238 #ifndef TARGET_ABI32 192 239 case EXCP_SYSCALL: 193 - /* linux syscall from syscall intruction */ 194 - env->regs[R_EAX] = do_openbsd_syscall(env, 195 - env->regs[R_EAX], 196 - env->regs[R_EDI], 197 - env->regs[R_ESI], 198 - env->regs[R_EDX], 199 - env->regs[10], 200 - env->regs[8], 201 - env->regs[9]); 240 + /* syscall from syscall intruction */ 241 + if (bsd_type == target_freebsd) 242 + env->regs[R_EAX] = do_freebsd_syscall(env, 243 + env->regs[R_EAX], 244 + env->regs[R_EDI], 245 + env->regs[R_ESI], 246 + env->regs[R_EDX], 247 + env->regs[R_ECX], 248 + env->regs[8], 249 + env->regs[9], 0, 0); 250 + else { //if (bsd_type == target_openbsd) 251 + env->regs[R_EAX] = do_openbsd_syscall(env, 252 + env->regs[R_EAX], 253 + env->regs[R_EDI], 254 + env->regs[R_ESI], 255 + env->regs[R_EDX], 256 + env->regs[10], 257 + env->regs[8], 258 + env->regs[9]); 259 + } 202 260 env->eip = env->exception_next_eip; 261 + if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { 262 + env->regs[R_EAX] = -env->regs[R_EAX]; 263 + env->eflags |= CC_C; 264 + } else { 265 + env->eflags &= ~CC_C; 266 + } 203 267 break; 204 268 #endif 205 269 #if 0 ··· 446 510 #endif 447 511 } 448 512 449 - void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type) 513 + void cpu_loop(CPUSPARCState *env) 450 514 { 451 515 int trapnr, ret, syscall_nr; 452 516 //target_siginfo_t info; ··· 458 522 #ifndef TARGET_SPARC64 459 523 case 0x80: 460 524 #else 525 + /* FreeBSD uses 0x141 for syscalls too */ 526 + case 0x141: 527 + if (bsd_type != target_freebsd) 528 + goto badtrap; 461 529 case 0x100: 462 530 #endif 463 531 syscall_nr = env->gregs[1]; ··· 465 533 ret = do_freebsd_syscall(env, syscall_nr, 466 534 env->regwptr[0], env->regwptr[1], 467 535 env->regwptr[2], env->regwptr[3], 468 - env->regwptr[4], env->regwptr[5]); 536 + env->regwptr[4], env->regwptr[5], 0, 0); 469 537 else if (bsd_type == target_netbsd) 470 538 ret = do_netbsd_syscall(env, syscall_nr, 471 539 env->regwptr[0], env->regwptr[1], ··· 482 550 env->regwptr[4], env->regwptr[5]); 483 551 } 484 552 if ((unsigned int)ret >= (unsigned int)(-515)) { 553 + ret = -ret; 485 554 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 486 555 env->xcc |= PSR_CARRY; 487 556 #else ··· 587 656 } 588 657 break; 589 658 default: 659 + #ifdef TARGET_SPARC64 660 + badtrap: 661 + #endif 590 662 printf ("Unhandled trap: 0x%x\n", trapnr); 591 663 cpu_dump_state(env, stderr, fprintf, 0); 592 664 exit (1); ··· 668 740 int gdbstub_port = 0; 669 741 char **target_environ, **wrk; 670 742 envlist_t *envlist = NULL; 671 - enum BSDType bsd_type = target_openbsd; 743 + bsd_type = target_openbsd; 672 744 673 745 if (argc <= 1) 674 746 usage(); ··· 1033 1105 gdbserver_start (gdbstub_port); 1034 1106 gdb_handlesig(env, 0); 1035 1107 } 1036 - cpu_loop(env, bsd_type); 1108 + cpu_loop(env); 1037 1109 /* never exits */ 1038 1110 return 0; 1039 1111 }
+4 -2
bsd-user/qemu.h
··· 18 18 target_netbsd, 19 19 target_openbsd, 20 20 }; 21 + extern enum BSDType bsd_type; 21 22 22 23 #include "syscall_defs.h" 23 24 #include "syscall.h" ··· 130 131 void syscall_init(void); 131 132 abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, 132 133 abi_long arg2, abi_long arg3, abi_long arg4, 133 - abi_long arg5, abi_long arg6); 134 + abi_long arg5, abi_long arg6, abi_long arg7, 135 + abi_long arg8); 134 136 abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, 135 137 abi_long arg2, abi_long arg3, abi_long arg4, 136 138 abi_long arg5, abi_long arg6); ··· 139 141 abi_long arg5, abi_long arg6); 140 142 void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); 141 143 extern THREAD CPUState *thread_env; 142 - void cpu_loop(CPUState *env, enum BSDType bsd_type); 144 + void cpu_loop(CPUState *env); 143 145 char *target_strerror(int err); 144 146 int get_osversion(void); 145 147 void fork_start(void);
+291 -4
bsd-user/syscall.c
··· 29 29 #include <sys/types.h> 30 30 #include <sys/mman.h> 31 31 #include <sys/syscall.h> 32 + #include <sys/sysctl.h> 32 33 #include <signal.h> 33 34 #include <utime.h> 34 35 ··· 40 41 static abi_ulong target_brk; 41 42 static abi_ulong target_original_brk; 42 43 43 - #define get_errno(x) (x) 44 + static inline abi_long get_errno(abi_long ret) 45 + { 46 + if (ret == -1) 47 + /* XXX need to translate host -> target errnos here */ 48 + return -(errno); 49 + else 50 + return ret; 51 + } 52 + 44 53 #define target_to_host_bitmask(x, tbl) (x) 45 54 55 + static inline int is_error(abi_long ret) 56 + { 57 + return (abi_ulong)ret >= (abi_ulong)(-4096); 58 + } 59 + 46 60 void target_set_brk(abi_ulong new_brk) 47 61 { 48 62 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); 49 63 } 50 64 65 + /* do_obreak() must return target errnos. */ 66 + static abi_long do_obreak(abi_ulong new_brk) 67 + { 68 + abi_ulong brk_page; 69 + abi_long mapped_addr; 70 + int new_alloc_size; 71 + 72 + if (!new_brk) 73 + return 0; 74 + if (new_brk < target_original_brk) 75 + return -TARGET_EINVAL; 76 + 77 + brk_page = HOST_PAGE_ALIGN(target_brk); 78 + 79 + /* If the new brk is less than this, set it and we're done... */ 80 + if (new_brk < brk_page) { 81 + target_brk = new_brk; 82 + return 0; 83 + } 84 + 85 + /* We need to allocate more memory after the brk... */ 86 + new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); 87 + mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, 88 + PROT_READ|PROT_WRITE, 89 + MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)); 90 + 91 + if (!is_error(mapped_addr)) 92 + target_brk = new_brk; 93 + else 94 + return mapped_addr; 95 + 96 + return 0; 97 + } 98 + 99 + #if defined(TARGET_I386) 100 + static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms) 101 + { 102 + abi_long ret = 0; 103 + abi_ulong val; 104 + int idx; 105 + 106 + switch(op) { 107 + #ifdef TARGET_ABI32 108 + case TARGET_FREEBSD_I386_SET_GSBASE: 109 + case TARGET_FREEBSD_I386_SET_FSBASE: 110 + if (op == TARGET_FREEBSD_I386_SET_GSBASE) 111 + #else 112 + case TARGET_FREEBSD_AMD64_SET_GSBASE: 113 + case TARGET_FREEBSD_AMD64_SET_FSBASE: 114 + if (op == TARGET_FREEBSD_AMD64_SET_GSBASE) 115 + #endif 116 + idx = R_GS; 117 + else 118 + idx = R_FS; 119 + if (get_user(val, parms, abi_ulong)) 120 + return -TARGET_EFAULT; 121 + cpu_x86_load_seg(env, idx, 0); 122 + env->segs[idx].base = val; 123 + break; 124 + #ifdef TARGET_ABI32 125 + case TARGET_FREEBSD_I386_GET_GSBASE: 126 + case TARGET_FREEBSD_I386_GET_FSBASE: 127 + if (op == TARGET_FREEBSD_I386_GET_GSBASE) 128 + #else 129 + case TARGET_FREEBSD_AMD64_GET_GSBASE: 130 + case TARGET_FREEBSD_AMD64_GET_FSBASE: 131 + if (op == TARGET_FREEBSD_AMD64_GET_GSBASE) 132 + #endif 133 + idx = R_GS; 134 + else 135 + idx = R_FS; 136 + val = env->segs[idx].base; 137 + if (put_user(val, parms, abi_ulong)) 138 + return -TARGET_EFAULT; 139 + break; 140 + /* XXX handle the others... */ 141 + default: 142 + ret = -TARGET_EINVAL; 143 + break; 144 + } 145 + return ret; 146 + } 147 + #endif 148 + 149 + #ifdef TARGET_SPARC 150 + static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) 151 + { 152 + /* XXX handle 153 + * TARGET_FREEBSD_SPARC_UTRAP_INSTALL, 154 + * TARGET_FREEBSD_SPARC_SIGTRAMP_INSTALL 155 + */ 156 + return -TARGET_EINVAL; 157 + } 158 + #endif 159 + 160 + #ifdef __FreeBSD__ 161 + /* 162 + * XXX this uses the undocumented oidfmt interface to find the kind of 163 + * a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt() 164 + * (this is mostly copied from src/sbin/sysctl/sysctl.c) 165 + */ 166 + static int 167 + oidfmt(int *oid, int len, char *fmt, uint32_t *kind) 168 + { 169 + int qoid[CTL_MAXNAME+2]; 170 + uint8_t buf[BUFSIZ]; 171 + int i; 172 + size_t j; 173 + 174 + qoid[0] = 0; 175 + qoid[1] = 4; 176 + memcpy(qoid + 2, oid, len * sizeof(int)); 177 + 178 + j = sizeof(buf); 179 + i = sysctl(qoid, len + 2, buf, &j, 0, 0); 180 + if (i) 181 + return i; 182 + 183 + if (kind) 184 + *kind = *(uint32_t *)buf; 185 + 186 + if (fmt) 187 + strcpy(fmt, (char *)(buf + sizeof(uint32_t))); 188 + return (0); 189 + } 190 + 191 + /* 192 + * try and convert sysctl return data for the target. 193 + * XXX doesn't handle CTLTYPE_OPAQUE and CTLTYPE_STRUCT. 194 + */ 195 + static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind) 196 + { 197 + switch (kind & CTLTYPE) { 198 + case CTLTYPE_INT: 199 + case CTLTYPE_UINT: 200 + *(uint32_t *)holdp = tswap32(*(uint32_t *)holdp); 201 + break; 202 + #ifdef TARGET_ABI32 203 + case CTLTYPE_LONG: 204 + case CTLTYPE_ULONG: 205 + *(uint32_t *)holdp = tswap32(*(long *)holdp); 206 + break; 207 + #else 208 + case CTLTYPE_LONG: 209 + *(uint64_t *)holdp = tswap64(*(long *)holdp); 210 + case CTLTYPE_ULONG: 211 + *(uint64_t *)holdp = tswap64(*(unsigned long *)holdp); 212 + break; 213 + #endif 214 + case CTLTYPE_QUAD: 215 + *(uint64_t *)holdp = tswap64(*(uint64_t *)holdp); 216 + break; 217 + case CTLTYPE_STRING: 218 + break; 219 + default: 220 + /* XXX unhandled */ 221 + return -1; 222 + } 223 + return 0; 224 + } 225 + 226 + /* XXX this needs to be emulated on non-FreeBSD hosts... */ 227 + static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong oldp, 228 + abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen) 229 + { 230 + abi_long ret; 231 + void *hnamep, *holdp, *hnewp = NULL; 232 + size_t holdlen; 233 + abi_ulong oldlen = 0; 234 + int32_t *snamep = qemu_malloc(sizeof(int32_t) * namelen), *p, *q, i; 235 + uint32_t kind = 0; 236 + 237 + if (oldlenp) 238 + get_user_ual(oldlen, oldlenp); 239 + if (!(hnamep = lock_user(VERIFY_READ, namep, namelen, 1))) 240 + return -TARGET_EFAULT; 241 + if (newp && !(hnewp = lock_user(VERIFY_READ, newp, newlen, 1))) 242 + return -TARGET_EFAULT; 243 + if (!(holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0))) 244 + return -TARGET_EFAULT; 245 + holdlen = oldlen; 246 + for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++) 247 + *q++ = tswap32(*p); 248 + oidfmt(snamep, namelen, NULL, &kind); 249 + /* XXX swap hnewp */ 250 + ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen)); 251 + if (!ret) 252 + sysctl_oldcvt(holdp, holdlen, kind); 253 + put_user_ual(holdlen, oldlenp); 254 + unlock_user(hnamep, namep, 0); 255 + unlock_user(holdp, oldp, holdlen); 256 + if (hnewp) 257 + unlock_user(hnewp, newp, 0); 258 + qemu_free(snamep); 259 + return ret; 260 + } 261 + #endif 262 + 263 + /* FIXME 264 + * lock_iovec()/unlock_iovec() have a return code of 0 for success where 265 + * other lock functions have a return code of 0 for failure. 266 + */ 267 + static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, 268 + int count, int copy) 269 + { 270 + struct target_iovec *target_vec; 271 + abi_ulong base; 272 + int i; 273 + 274 + target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); 275 + if (!target_vec) 276 + return -TARGET_EFAULT; 277 + for(i = 0;i < count; i++) { 278 + base = tswapl(target_vec[i].iov_base); 279 + vec[i].iov_len = tswapl(target_vec[i].iov_len); 280 + if (vec[i].iov_len != 0) { 281 + vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); 282 + /* Don't check lock_user return value. We must call writev even 283 + if a element has invalid base address. */ 284 + } else { 285 + /* zero length pointer is ignored */ 286 + vec[i].iov_base = NULL; 287 + } 288 + } 289 + unlock_user (target_vec, target_addr, 0); 290 + return 0; 291 + } 292 + 293 + static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, 294 + int count, int copy) 295 + { 296 + struct target_iovec *target_vec; 297 + abi_ulong base; 298 + int i; 299 + 300 + target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); 301 + if (!target_vec) 302 + return -TARGET_EFAULT; 303 + for(i = 0;i < count; i++) { 304 + if (target_vec[i].iov_base) { 305 + base = tswapl(target_vec[i].iov_base); 306 + unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); 307 + } 308 + } 309 + unlock_user (target_vec, target_addr, 0); 310 + 311 + return 0; 312 + } 313 + 51 314 /* do_syscall() should always have a single exit point at the end so 52 315 that actions, such as logging of syscall results, can be performed. 53 316 All errnos that do_syscall() returns must be -TARGET_<errcode>. */ 54 317 abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, 55 318 abi_long arg2, abi_long arg3, abi_long arg4, 56 - abi_long arg5, abi_long arg6) 319 + abi_long arg5, abi_long arg6, abi_long arg7, 320 + abi_long arg8) 57 321 { 58 322 abi_long ret; 59 323 void *p; ··· 86 350 ret = get_errno(write(arg1, p, arg3)); 87 351 unlock_user(p, arg2, 0); 88 352 break; 353 + case TARGET_FREEBSD_NR_writev: 354 + { 355 + int count = arg3; 356 + struct iovec *vec; 357 + 358 + vec = alloca(count * sizeof(struct iovec)); 359 + if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) 360 + goto efault; 361 + ret = get_errno(writev(arg1, vec, count)); 362 + unlock_iovec(vec, arg2, count, 0); 363 + } 364 + break; 89 365 case TARGET_FREEBSD_NR_open: 90 366 if (!(p = lock_user_string(arg1))) 91 367 goto efault; ··· 103 379 case TARGET_FREEBSD_NR_mprotect: 104 380 ret = get_errno(target_mprotect(arg1, arg2, arg3)); 105 381 break; 382 + case TARGET_FREEBSD_NR_break: 383 + ret = do_obreak(arg1); 384 + break; 385 + #ifdef __FreeBSD__ 386 + case TARGET_FREEBSD_NR___sysctl: 387 + ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6); 388 + break; 389 + #endif 390 + case TARGET_FREEBSD_NR_sysarch: 391 + ret = do_freebsd_sysarch(cpu_env, arg1, arg2); 392 + break; 106 393 case TARGET_FREEBSD_NR_syscall: 107 394 case TARGET_FREEBSD_NR___syscall: 108 - ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); 395 + ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0); 109 396 break; 110 397 default: 111 - ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); 398 + ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); 112 399 break; 113 400 } 114 401 fail:
+6
bsd-user/syscall_defs.h
··· 106 106 #include "freebsd/syscall_nr.h" 107 107 #include "netbsd/syscall_nr.h" 108 108 #include "openbsd/syscall_nr.h" 109 + 110 + struct target_iovec { 111 + abi_long iov_base; /* Starting address */ 112 + abi_long iov_len; /* Number of bytes */ 113 + }; 114 +
+18
bsd-user/x86_64/syscall.h
··· 90 90 abi_ulong __unused5; 91 91 }; 92 92 93 + /* FreeBSD sysarch(2) */ 94 + #define TARGET_FREEBSD_I386_GET_LDT 0 95 + #define TARGET_FREEBSD_I386_SET_LDT 1 96 + /* I386_IOPL */ 97 + #define TARGET_FREEBSD_I386_GET_IOPERM 3 98 + #define TARGET_FREEBSD_I386_SET_IOPERM 4 99 + /* xxxxx */ 100 + #define TARGET_FREEBSD_I386_GET_FSBASE 7 101 + #define TARGET_FREEBSD_I386_SET_FSBASE 8 102 + #define TARGET_FREEBSD_I386_GET_GSBASE 9 103 + #define TARGET_FREEBSD_I386_SET_GSBASE 10 104 + 105 + #define TARGET_FREEBSD_AMD64_GET_FSBASE 128 106 + #define TARGET_FREEBSD_AMD64_SET_FSBASE 129 107 + #define TARGET_FREEBSD_AMD64_GET_GSBASE 130 108 + #define TARGET_FREEBSD_AMD64_SET_GSBASE 131 109 + 110 + 93 111 #define UNAME_MACHINE "x86_64" 94 112 95 113 #define TARGET_ARCH_SET_GS 0x1001
+25 -2
cpu-exec.c
··· 805 805 # define TRAP_sig(context) ((context)->uc_mcontext->es.trapno) 806 806 # define ERROR_sig(context) ((context)->uc_mcontext->es.err) 807 807 # define MASK_sig(context) ((context)->uc_sigmask) 808 + #elif defined (__NetBSD__) 809 + # include <ucontext.h> 810 + 811 + # define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP]) 812 + # define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) 813 + # define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) 814 + # define MASK_sig(context) ((context)->uc_sigmask) 815 + #elif defined (__FreeBSD__) || defined(__DragonFly__) 816 + # include <ucontext.h> 817 + 818 + # define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_eip)) 819 + # define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno) 820 + # define ERROR_sig(context) ((context)->uc_mcontext.mc_err) 821 + # define MASK_sig(context) ((context)->uc_sigmask) 808 822 #elif defined(__OpenBSD__) 809 823 # define EIP_sig(context) ((context)->sc_eip) 810 824 # define TRAP_sig(context) ((context)->sc_trapno) ··· 821 835 void *puc) 822 836 { 823 837 siginfo_t *info = pinfo; 824 - #if defined(__OpenBSD__) 838 + #if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__) 839 + ucontext_t *uc = puc; 840 + #elif defined(__OpenBSD__) 825 841 struct sigcontext *uc = puc; 826 842 #else 827 843 struct ucontext *uc = puc; ··· 855 871 #define TRAP_sig(context) ((context)->sc_trapno) 856 872 #define ERROR_sig(context) ((context)->sc_err) 857 873 #define MASK_sig(context) ((context)->sc_mask) 874 + #elif defined (__FreeBSD__) || defined(__DragonFly__) 875 + #include <ucontext.h> 876 + 877 + #define PC_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_rip)) 878 + #define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno) 879 + #define ERROR_sig(context) ((context)->uc_mcontext.mc_err) 880 + #define MASK_sig(context) ((context)->uc_sigmask) 858 881 #else 859 882 #define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP]) 860 883 #define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) ··· 867 890 { 868 891 siginfo_t *info = pinfo; 869 892 unsigned long pc; 870 - #ifdef __NetBSD__ 893 + #if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__) 871 894 ucontext_t *uc = puc; 872 895 #elif defined(__OpenBSD__) 873 896 struct sigcontext *uc = puc;