/* FIXME * lock_iovec()/unlock_iovec() have a return code of 0 for success where * other lock functions have a return code of 0 for failure. */ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, int count, int copy) { struct target_iovec *target_vec; abi_ulong base; int i; target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); if (!target_vec) return -TARGET_EFAULT; for(i = 0;i < count; i++) { base = tswapl(target_vec[i].iov_base); vec[i].iov_len = tswapl(target_vec[i].iov_len); if (vec[i].iov_len != 0) { vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); /* Don't check lock_user return value. We must call writev even if a element has invalid base address. */ } else { /* zero length pointer is ignored */ vec[i].iov_base = NULL; } } unlock_user (target_vec, target_addr, 0); return 0; }
static void print_execve(const struct syscallname *name, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) { abi_ulong arg_ptr_addr; char *s; if (!(s = lock_user_string(arg1))) return; gemu_log("%s(\"%s\",{", name->name, s); unlock_user(s, arg1, 0); for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) { abi_ulong *arg_ptr, arg_addr, s_addr; arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); if (!arg_ptr) return; arg_addr = tswapl(*arg_ptr); unlock_user(arg_ptr, arg_ptr_addr, 0); if (!arg_addr) break; if ((s = lock_user_string(arg_addr))) { gemu_log("\"%s\",", s); unlock_user(s, s_addr, 0); } } gemu_log("NULL})"); }
int do_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { struct emulated_sigaction *k; struct sigaction act1; int host_sig; if (sig < 1 || sig > NSIG) return -EINVAL; k = &sigact_table[sig - 1]; #if defined(DEBUG_SIGNAL) fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n", sig, (int)act, (int)oact); #endif if (oact) { #if defined(DEBUG_SIGNAL) fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n", sig, (int)act, (int)oact); #endif oact->sa_handler = tswapl(k->sa.sa_handler); oact->sa_flags = tswapl(k->sa.sa_flags); oact->sa_mask = tswapl(k->sa.sa_mask); } if (act) { #if defined(DEBUG_SIGNAL) fprintf(stderr, "sigaction handler 0x%x flag 0x%x mask 0x%x\n", act->sa_handler, act->sa_flags, act->sa_mask); #endif k->sa.sa_handler = tswapl(act->sa_handler); k->sa.sa_flags = tswapl(act->sa_flags); k->sa.sa_mask = tswapl(act->sa_mask); /* we update the host signal state */ host_sig = target_to_host_signal(sig); if (host_sig != SIGSEGV && host_sig != SIGBUS) { #if defined(DEBUG_SIGNAL) fprintf(stderr, "sigaction handler going to call sigaction\n"); #endif sigfillset(&act1.sa_mask); act1.sa_flags = SA_SIGINFO; if (k->sa.sa_flags & SA_RESTART) act1.sa_flags |= SA_RESTART; /* NOTE: it is important to update the host kernel signal ignore state to avoid getting unexpected interrupted syscalls */ if (k->sa.sa_handler == SIG_IGN) { act1.sa_sigaction = (void *)SIG_IGN; } else if (k->sa.sa_handler == SIG_DFL) { act1.sa_sigaction = (void *)SIG_DFL; } else { act1.sa_sigaction = host_signal_handler; } sigaction(host_sig, &act1, NULL); } } return 0; }
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count, int copy) { struct target_iovec *target_vec; abi_ulong base; int i; target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); if (!target_vec) return -TARGET_EFAULT; for(i = 0;i < count; i++) { if (target_vec[i].iov_base) { base = tswapl(target_vec[i].iov_base); unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); } } unlock_user (target_vec, target_addr, 0); return 0; }
long do_sigreturn(CPUState *env, int num) { int i = 0; struct target_sigcontext *scp = get_int_arg(&i, env); /* XXX Get current signal number */ /* XXX Adjust accordin to sc_onstack, sc_mask */ if(tswapl(scp->sc_onstack) & 0x1) target_sigaltstack_used.ss_flags |= ~SA_DISABLE; else target_sigaltstack_used.ss_flags &= SA_DISABLE; int set = tswapl(scp->sc_eax); sigprocmask(SIG_SETMASK, &set, NULL); fprintf(stderr, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp->sc_mask, tswapl(scp->sc_eax), tswapl(scp->sc_ebx)); fprintf(stderr, "ECX:%x EDX:%x EDI:%x\n", scp->sc_ecx, tswapl(scp->sc_edx), tswapl(scp->sc_edi)); fprintf(stderr, "EIP:%x\n", tswapl(scp->sc_eip)); env->regs[R_EAX] = tswapl(scp->sc_eax); env->regs[R_EBX] = tswapl(scp->sc_ebx); env->regs[R_ECX] = tswapl(scp->sc_ecx); env->regs[R_EDX] = tswapl(scp->sc_edx); env->regs[R_EDI] = tswapl(scp->sc_edi); env->regs[R_ESI] = tswapl(scp->sc_esi); env->regs[R_EBP] = tswapl(scp->sc_ebp); env->regs[R_ESP] = tswapl(scp->sc_esp); env->segs[R_SS].selector = (void*)tswapl(scp->sc_ss); env->eflags = tswapl(scp->sc_eflags); env->eip = tswapl(scp->sc_eip); env->segs[R_CS].selector = (void*)tswapl(scp->sc_cs); env->segs[R_DS].selector = (void*)tswapl(scp->sc_ds); env->segs[R_ES].selector = (void*)tswapl(scp->sc_es); env->segs[R_FS].selector = (void*)tswapl(scp->sc_fs); env->segs[R_GS].selector = (void*)tswapl(scp->sc_gs); /* Again, because our caller's caller will reset EAX */ return env->regs[R_EAX]; }