mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 19:33:39 +08:00
linux-user changes since 2.7 release
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUAV+PJ7bRIkN7ePJvAAQjvYRAAnX95B4PPTzCCImLUOsAWg/B6ImlZ1YFG d7SVCXyjbyCvoP4/tgHuajYUTHiIQ9H7mCyZXJWSkqO/h23TFrbtxofN0e+dWl1s t+Hot7y/WqRKnuZoXy+ww8Oc0uyEQYoPMlhaPz8CqNxnKPaihBVVWbWFn+yDp0k9 DMfsEqUWQ+/kLkaMpOzInDbuZDAq8/36MUE/cw1+rFZ3MYYs9TSHwVxgXZjX89Cs d2xyNj8hxlQDfcG9rWWS7UrqzYqejD9j3cuvP7Q874aXdIPDIHkEbRGPVIPdYen7 QaIJ0xOpryaOqRmGW5+sLkoQFDTo6FOOxGB0MsKOghSSdv8ET+W0+Y+hTC637FEO Eqj2OtrKvN/TlTRV6fDqfov5NXbM63N1rRQdondLUopSnGal7FBIkZL7WfSyYzif DTkLwtff3dNiOM7gLPC3tP9BTSdQuXvSXHeqDVHvtopQa04IwE3LD4DbBQdMj5BU MzmdVgwW2kkWej5BKlIrG3JzhKe6u2E/S3MPd3z6lJzERdaIgJIoZv1W2lJOSAaO aw0E1BOcQLMGSjdh2Gj+La3YVZeMqu2gMyqPS6vjd6UzyTfu8i1AR1bGtYeacZSz jEfFcMESo7WjpbsrA5V8ch5Hw95s0YU3qhsG3AsDjj9ChE9QKj7v3wYJY2l9Fi4t UY3zOajB0eY= =w4/p -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160915' into staging linux-user changes since 2.7 release # gpg: Signature made Thu 22 Sep 2016 13:09:17 BST # gpg: using RSA key 0xB44890DEDE3C9BC0 # gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>" # gpg: aka "Riku Voipio <riku.voipio@linaro.org>" # Primary key fingerprint: FF82 03C8 C391 98AE 0581 41EF B448 90DE DE3C 9BC0 * remotes/riku/tags/pull-linux-user-20160915: (26 commits) linux-user: fix TARGET_NR_select linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2 linux-user: Sanity check clone flags linux-user: Remove unnecessary nptl_flags variable from do_fork() linux-user: Implement force_sigsegv() via force_sig() linux-user: SIGSEGV from sigreturn need not be fatal linux-user: ARM: Give SIGSEGV if signal frame setup fails linux-user: SIGSEGV on signal entry need not be fatal linux-user: Pass si_type information to queue_signal() explicitly linux-user: Recheck for pending synchronous signals too linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU linux-user: Use correct target SHMLBA in shmat() linux-user: Use glib malloc functions in load_symbols() linux-user: Check dump_write() return in elf_core_dump() linux-user: Fix error handling in flatload.c target_pread() linux-user: Fix incorrect use of host errno in do_ioctl_dm() linux-user: Check lock_user() return value for NULL linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call linux-user: report signals being taken in strace output linux-user: Range check the nfds argument to ppoll syscall ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
430da7a81d
@ -32,5 +32,13 @@ struct target_pt_regs {
|
||||
#define TARGET_MINSIGSTKSZ 2048
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
#define TARGET_WANT_OLD_SYS_SELECT
|
||||
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUARMState *env)
|
||||
{
|
||||
return 4 * 4096;
|
||||
}
|
||||
|
||||
#endif /* ARM_TARGET_SYSCALL_H */
|
||||
|
@ -2111,19 +2111,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||
|
||||
found:
|
||||
/* Now know where the strtab and symtab are. Snarf them. */
|
||||
s = malloc(sizeof(*s));
|
||||
s = g_try_new(struct syminfo, 1);
|
||||
if (!s) {
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
i = shdr[str_idx].sh_size;
|
||||
s->disas_strtab = strings = malloc(i);
|
||||
s->disas_strtab = strings = g_try_malloc(i);
|
||||
if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
i = shdr[sym_idx].sh_size;
|
||||
syms = malloc(i);
|
||||
syms = g_try_malloc(i);
|
||||
if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {
|
||||
goto give_up;
|
||||
}
|
||||
@ -2157,7 +2157,7 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||
that we threw away. Whether or not this has any effect on the
|
||||
memory allocation depends on the malloc implementation and how
|
||||
many symbols we managed to discard. */
|
||||
new_syms = realloc(syms, nsyms * sizeof(*syms));
|
||||
new_syms = g_try_renew(struct elf_sym, syms, nsyms);
|
||||
if (new_syms == NULL) {
|
||||
goto give_up;
|
||||
}
|
||||
@ -2178,9 +2178,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||
return;
|
||||
|
||||
give_up:
|
||||
free(s);
|
||||
free(strings);
|
||||
free(syms);
|
||||
g_free(s);
|
||||
g_free(strings);
|
||||
g_free(syms);
|
||||
}
|
||||
|
||||
int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
|
||||
@ -2233,7 +2233,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
|
||||
we do not have the power to recompile these, we emulate
|
||||
the SVr4 behavior. Sigh. */
|
||||
target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
|
||||
MAP_FIXED | MAP_PRIVATE, -1, 0);
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3050,7 +3050,9 @@ static int elf_core_dump(int signr, const CPUArchState *env)
|
||||
phdr.p_align = ELF_EXEC_PAGESIZE;
|
||||
|
||||
bswap_phdr(&phdr, 1);
|
||||
dump_write(fd, &phdr, sizeof (phdr));
|
||||
if (dump_write(fd, &phdr, sizeof(phdr)) != 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -95,7 +95,13 @@ static int target_pread(int fd, abi_ulong ptr, abi_ulong len,
|
||||
int ret;
|
||||
|
||||
buf = lock_user(VERIFY_WRITE, ptr, len, 0);
|
||||
if (!buf) {
|
||||
return -EFAULT;
|
||||
}
|
||||
ret = pread(fd, buf, len, offset);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
}
|
||||
unlock_user(buf, ptr, len);
|
||||
return ret;
|
||||
}
|
||||
|
@ -153,5 +153,6 @@ struct target_vm86plus_struct {
|
||||
#define TARGET_MINSIGSTKSZ 2048
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
#define TARGET_WANT_OLD_SYS_SELECT
|
||||
|
||||
#endif /* I386_TARGET_SYSCALL_H */
|
||||
|
@ -120,6 +120,9 @@
|
||||
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
|
||||
#endif
|
||||
|
||||
IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT))
|
||||
|
||||
IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||
|
@ -24,6 +24,8 @@ struct target_pt_regs {
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#define TARGET_WANT_OLD_SYS_SELECT
|
||||
|
||||
void do_m68k_simcall(CPUM68KState *, int);
|
||||
|
||||
#endif /* M68K_TARGET_SYSCALL_H */
|
||||
|
@ -339,7 +339,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SI_KERNEL;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP0D_GPF:
|
||||
/* XXX: potential problem if ABI32 */
|
||||
@ -353,7 +353,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SI_KERNEL;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP0E_PAGE:
|
||||
@ -364,7 +364,7 @@ void cpu_loop(CPUX86State *env)
|
||||
else
|
||||
info.si_code = TARGET_SEGV_ACCERR;
|
||||
info._sifields._sigfault._addr = env->cr[2];
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP00_DIVZ:
|
||||
#ifndef TARGET_X86_64
|
||||
@ -378,7 +378,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_INTDIV;
|
||||
info._sifields._sigfault._addr = env->eip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP01_DB:
|
||||
@ -398,7 +398,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_code = TARGET_SI_KERNEL;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
}
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP04_INTO:
|
||||
@ -413,7 +413,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SI_KERNEL;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP06_ILLOP:
|
||||
@ -421,7 +421,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->eip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
@ -436,7 +436,7 @@ void cpu_loop(CPUX86State *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -576,7 +576,7 @@ segv:
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->exception.vaddress;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
/* Handle a jump to the kernel code page. */
|
||||
@ -755,7 +755,7 @@ void cpu_loop(CPUARMState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->regs[15];
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
} else if (rc < 0) { /* FP exception */
|
||||
int arm_fpe=0;
|
||||
|
||||
@ -786,7 +786,7 @@ void cpu_loop(CPUARMState *env)
|
||||
if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
|
||||
|
||||
info._sifields._sigfault._addr = env->regs[15];
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
} else {
|
||||
env->regs[15] += 4;
|
||||
}
|
||||
@ -907,7 +907,7 @@ void cpu_loop(CPUARMState *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = addr;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
@ -921,7 +921,7 @@ void cpu_loop(CPUARMState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1099,7 +1099,7 @@ void cpu_loop(CPUARMState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_STREX:
|
||||
if (!do_strex_a64(env)) {
|
||||
@ -1113,7 +1113,7 @@ void cpu_loop(CPUARMState *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->exception.vaddress;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
case EXCP_BKPT:
|
||||
@ -1122,7 +1122,7 @@ void cpu_loop(CPUARMState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_SEMIHOST:
|
||||
@ -1202,7 +1202,7 @@ void cpu_loop(CPUUniCore32State *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
@ -1216,7 +1216,7 @@ void cpu_loop(CPUUniCore32State *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1431,7 +1431,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->mmuregs[4];
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
@ -1452,7 +1452,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||
info._sifields._sigfault._addr = env->dmmuregs[4];
|
||||
else
|
||||
info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
#ifndef TARGET_ABI32
|
||||
@ -1475,7 +1475,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPC;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
@ -1488,7 +1488,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1679,7 +1679,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_ISI: /* Instruction storage exception */
|
||||
/* XXX: check this */
|
||||
@ -1705,7 +1705,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_EXTERNAL: /* External input */
|
||||
cpu_abort(cs, "External interrupt while in user mode. "
|
||||
@ -1717,7 +1717,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_BUS_ADRALN;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_PROGRAM: /* Program exception */
|
||||
case POWERPC_EXCP_HV_EMU: /* HV emulation */
|
||||
@ -1808,14 +1808,14 @@ void cpu_loop(CPUPPCState *env)
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_SYSCALL: /* System call exception */
|
||||
cpu_abort(cs, "Syscall exception while in user mode. "
|
||||
@ -1826,7 +1826,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
||||
cpu_abort(cs, "Decrementer interrupt while in user mode. "
|
||||
@ -1853,7 +1853,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
|
||||
cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
|
||||
@ -1916,7 +1916,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
|
||||
cpu_abort(cs, "Programmable interval timer interrupt "
|
||||
@ -2010,7 +2010,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
@ -2022,7 +2022,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2456,13 +2456,13 @@ static int do_break(CPUMIPSState *env, target_siginfo_t *info,
|
||||
info->si_signo = TARGET_SIGFPE;
|
||||
info->si_errno = 0;
|
||||
info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
|
||||
queue_signal(env, info->si_signo, &*info);
|
||||
queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
info->si_signo = TARGET_SIGTRAP;
|
||||
info->si_errno = 0;
|
||||
queue_signal(env, info->si_signo, &*info);
|
||||
queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@ -2560,14 +2560,14 @@ done_syscall:
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->CP0_BadVAddr;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_CpU:
|
||||
case EXCP_RI:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
@ -2582,7 +2582,7 @@ done_syscall:
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2592,14 +2592,14 @@ done_syscall:
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->active_tc.PC;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_DSPDIS:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPC;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
/* The code below was inspired by the MIPS Linux kernel trap
|
||||
* handling code in arch/mips/kernel/traps.c.
|
||||
@ -2850,7 +2850,7 @@ void cpu_loop(CPUSH4State *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2860,7 +2860,7 @@ void cpu_loop(CPUSH4State *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->tea;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2892,7 +2892,7 @@ void cpu_loop(CPUCRISState *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->pregs[PR_EDA];
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
@ -2924,7 +2924,7 @@ void cpu_loop(CPUCRISState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2957,7 +2957,7 @@ void cpu_loop(CPUMBState *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
@ -3006,7 +3006,7 @@ void cpu_loop(CPUMBState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_FLTDIV;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case ESR_EC_FPU:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
@ -3018,7 +3018,7 @@ void cpu_loop(CPUMBState *env)
|
||||
info.si_code = TARGET_FPE_FLTDIV;
|
||||
}
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
default:
|
||||
printf ("Unhandled hw-exception: 0x%x\n",
|
||||
@ -3038,7 +3038,7 @@ void cpu_loop(CPUMBState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3092,7 +3092,7 @@ void cpu_loop(CPUM68KState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_TRAP0:
|
||||
{
|
||||
@ -3126,7 +3126,7 @@ void cpu_loop(CPUM68KState *env)
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = env->mmu.ar;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
@ -3139,7 +3139,7 @@ void cpu_loop(CPUM68KState *env)
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3195,7 +3195,7 @@ static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = addr;
|
||||
queue_signal(env, TARGET_SIGSEGV, &info);
|
||||
queue_signal(env, TARGET_SIGSEGV, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
void cpu_loop(CPUAlphaState *env)
|
||||
@ -3237,7 +3237,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
|
||||
? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
|
||||
info._sifields._sigfault._addr = env->trap_arg0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_UNALIGN:
|
||||
env->lock_addr = -1;
|
||||
@ -3245,7 +3245,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_BUS_ADRALN;
|
||||
info._sifields._sigfault._addr = env->trap_arg0;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_OPCDEC:
|
||||
do_sigill:
|
||||
@ -3254,7 +3254,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPC;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_ARITH:
|
||||
env->lock_addr = -1;
|
||||
@ -3262,7 +3262,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_FLTINV;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_FEN:
|
||||
/* No-op. Linux simply re-enables the FPU. */
|
||||
@ -3276,7 +3276,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case 0x81:
|
||||
/* BUGCHK */
|
||||
@ -3284,7 +3284,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case 0x83:
|
||||
/* CALLSYS */
|
||||
@ -3356,7 +3356,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
}
|
||||
info.si_errno = 0;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
default:
|
||||
goto do_sigill;
|
||||
@ -3368,7 +3368,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
env->lock_addr = -1;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_STL_C:
|
||||
@ -3502,7 +3502,7 @@ void cpu_loop(CPUS390XState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = n;
|
||||
info._sifields._sigfault._addr = addr;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3526,7 +3526,7 @@ static void gen_sigill_reg(CPUTLGState *env)
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_PRVREG;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
static void do_signal(CPUTLGState *env, int signo, int sigcode)
|
||||
@ -3550,7 +3550,7 @@ static void do_signal(CPUTLGState *env, int signo, int sigcode)
|
||||
}
|
||||
info.si_code = sigcode;
|
||||
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
|
||||
@ -4615,10 +4615,11 @@ int main(int argc, char **argv, char **envp)
|
||||
int i;
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF;
|
||||
#if defined(TARGET_ABI32)
|
||||
env->msr &= ~((target_ulong)1 << MSR_SF);
|
||||
env->msr &= ~((target_ulong)1 << flag);
|
||||
#else
|
||||
env->msr |= (target_ulong)1 << MSR_SF;
|
||||
env->msr |= (target_ulong)1 << flag;
|
||||
#endif
|
||||
#endif
|
||||
env->nip = regs->nip;
|
||||
|
@ -53,4 +53,6 @@ struct target_pt_regs {
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#define TARGET_WANT_NI_OLD_SELECT
|
||||
|
||||
#endif
|
||||
|
@ -230,4 +230,11 @@ struct target_pt_regs {
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUMIPSState *env)
|
||||
{
|
||||
return 0x40000;
|
||||
}
|
||||
|
||||
#endif /* MIPS_TARGET_SYSCALL_H */
|
||||
|
@ -227,4 +227,11 @@ struct target_pt_regs {
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUMIPSState *env)
|
||||
{
|
||||
return 0x40000;
|
||||
}
|
||||
|
||||
#endif /* MIPS64_TARGET_SYSCALL_H */
|
||||
|
@ -459,8 +459,6 @@
|
||||
#define TARGET_NR_getdents 1065
|
||||
#define __ARCH_WANT_SYS_GETDENTS
|
||||
#define TARGET_NR_futimesat 1066
|
||||
#define TARGET_NR_select 1067
|
||||
#define __ARCH_WANT_SYS_SELECT
|
||||
#define TARGET_NR_poll 1068
|
||||
#define TARGET_NR_epoll_wait 1069
|
||||
#define TARGET_NR_ustat 1070
|
||||
|
@ -74,5 +74,6 @@ struct target_revectored_struct {
|
||||
#define TARGET_MINSIGSTKSZ 2048
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
|
||||
#define TARGET_WANT_NI_OLD_SELECT
|
||||
|
||||
#endif /* PPC_TARGET_SYSCALL_H */
|
||||
|
@ -362,12 +362,23 @@ void print_syscall(int num,
|
||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
||||
abi_long arg4, abi_long arg5, abi_long arg6);
|
||||
void print_syscall_ret(int num, abi_long arg1);
|
||||
/**
|
||||
* print_taken_signal:
|
||||
* @target_signum: target signal being taken
|
||||
* @tinfo: target_siginfo_t which will be passed to the guest for the signal
|
||||
*
|
||||
* Print strace output indicating that this signal is being taken by the guest,
|
||||
* in a format similar to:
|
||||
* --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
|
||||
*/
|
||||
void print_taken_signal(int target_signum, const target_siginfo_t *tinfo);
|
||||
extern int do_strace;
|
||||
|
||||
/* signal.c */
|
||||
void process_pending_signals(CPUArchState *cpu_env);
|
||||
void signal_init(void);
|
||||
int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
|
||||
int queue_signal(CPUArchState *env, int sig, int si_type,
|
||||
target_siginfo_t *info);
|
||||
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
|
||||
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
|
||||
int target_to_host_signal(int sig);
|
||||
|
@ -84,7 +84,7 @@
|
||||
#define TARGET_NR_settimeofday 79
|
||||
#define TARGET_NR_getgroups 80
|
||||
#define TARGET_NR_setgroups 81
|
||||
#define TARGET_NR_select 82
|
||||
/* 82 was sys_oldselect */
|
||||
#define TARGET_NR_symlink 83
|
||||
#define TARGET_NR_oldlstat 84
|
||||
#define TARGET_NR_readlink 85
|
||||
|
@ -19,4 +19,11 @@ struct target_pt_regs {
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUSH4State *env)
|
||||
{
|
||||
return 0x4000;
|
||||
}
|
||||
|
||||
#endif /* SH4_TARGET_SYSCALL_H */
|
||||
|
@ -512,9 +512,43 @@ void signal_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if !(defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
|
||||
/* Force a synchronously taken signal. The kernel force_sig() function
|
||||
* also forces the signal to "not blocked, not ignored", but for QEMU
|
||||
* that work is done in process_pending_signals().
|
||||
*/
|
||||
static void force_sig(int sig)
|
||||
{
|
||||
CPUState *cpu = thread_cpu;
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
target_siginfo_t info;
|
||||
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SI_KERNEL;
|
||||
info._sifields._kill._pid = 0;
|
||||
info._sifields._kill._uid = 0;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
|
||||
}
|
||||
|
||||
/* Force a SIGSEGV if we couldn't write to memory trying to set
|
||||
* up the signal frame. oldsig is the signal we were trying to handle
|
||||
* at the point of failure.
|
||||
*/
|
||||
static void force_sigsegv(int oldsig)
|
||||
{
|
||||
if (oldsig == SIGSEGV) {
|
||||
/* Make sure we don't try to deliver the signal again; this will
|
||||
* end up with handle_pending_signal() calling dump_core_and_abort().
|
||||
*/
|
||||
sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* abort execution with signal */
|
||||
static void QEMU_NORETURN force_sig(int target_sig)
|
||||
static void QEMU_NORETURN dump_core_and_abort(int target_sig)
|
||||
{
|
||||
CPUState *cpu = thread_cpu;
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
@ -569,19 +603,15 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
|
||||
/* queue a signal so that it will be send to the virtual CPU as soon
|
||||
as possible */
|
||||
int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
|
||||
int queue_signal(CPUArchState *env, int sig, int si_type,
|
||||
target_siginfo_t *info)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
TaskState *ts = cpu->opaque;
|
||||
|
||||
trace_user_queue_signal(env, sig);
|
||||
|
||||
/* Currently all callers define siginfo structures which
|
||||
* use the _sifields._sigfault union member, so we can
|
||||
* set the type here. If that changes we should push this
|
||||
* out so the si_type is passed in by callers.
|
||||
*/
|
||||
info->si_code = deposit32(info->si_code, 16, 16, QEMU_SI_FAULT);
|
||||
info->si_code = deposit32(info->si_code, 16, 16, si_type);
|
||||
|
||||
ts->sync_signal.info = *info;
|
||||
ts->sync_signal.pending = sig;
|
||||
@ -1015,10 +1045,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
if (sig == TARGET_SIGSEGV) {
|
||||
ka->_sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
|
||||
@ -1088,10 +1115,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
if (sig == TARGET_SIGSEGV) {
|
||||
ka->_sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1165,7 +1189,7 @@ long do_sigreturn(CPUX86State *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUX86State *env)
|
||||
@ -1196,7 +1220,7 @@ long do_rt_sigreturn(CPUX86State *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_AARCH64)
|
||||
@ -1420,7 +1444,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -1466,7 +1490,7 @@ long do_rt_sigreturn(CPUARMState *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUARMState *env)
|
||||
@ -1772,7 +1796,7 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
|
||||
|
||||
trace_user_setup_frame(regs, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
return;
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
setup_sigcontext(&frame->sc, regs, set->sig[0]);
|
||||
@ -1785,6 +1809,9 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
|
||||
frame_addr + offsetof(struct sigframe_v1, retcode));
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
static void setup_frame_v2(int usig, struct target_sigaction *ka,
|
||||
@ -1795,7 +1822,7 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
|
||||
|
||||
trace_user_setup_frame(regs, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
return;
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
setup_sigframe_v2(&frame->uc, set, regs);
|
||||
@ -1804,6 +1831,9 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
|
||||
frame_addr + offsetof(struct sigframe_v2, retcode));
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
static void setup_frame(int usig, struct target_sigaction *ka,
|
||||
@ -1829,7 +1859,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
|
||||
|
||||
trace_user_setup_rt_frame(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
return /* 1 */;
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
|
||||
@ -1859,6 +1889,9 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
|
||||
env->regs[2] = uc_addr;
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
|
||||
@ -1871,7 +1904,7 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
|
||||
|
||||
trace_user_setup_rt_frame(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
return /* 1 */;
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
|
||||
@ -1887,6 +1920,9 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
|
||||
env->regs[2] = uc_addr;
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int usig, struct target_sigaction *ka,
|
||||
@ -1976,8 +2012,8 @@ static long do_sigreturn_v1(CPUARMState *env)
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
return 0;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
|
||||
@ -2035,7 +2071,8 @@ static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
|
||||
return (abi_ulong*)(iwmmxtframe + 1);
|
||||
}
|
||||
|
||||
static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
|
||||
static int do_sigframe_return_v2(CPUARMState *env,
|
||||
target_ulong context_addr,
|
||||
struct target_ucontext_v2 *uc)
|
||||
{
|
||||
sigset_t host_set;
|
||||
@ -2062,8 +2099,11 @@ static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
|
||||
}
|
||||
}
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
|
||||
if (do_sigaltstack(context_addr
|
||||
+ offsetof(struct target_ucontext_v2, tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Send SIGTRAP if we're single-stepping */
|
||||
@ -2094,7 +2134,10 @@ static long do_sigreturn_v2(CPUARMState *env)
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {
|
||||
if (do_sigframe_return_v2(env,
|
||||
frame_addr
|
||||
+ offsetof(struct sigframe_v2, uc),
|
||||
&frame->uc)) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
@ -2103,8 +2146,8 @@ static long do_sigreturn_v2(CPUARMState *env)
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
return 0;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUARMState *env)
|
||||
@ -2157,8 +2200,8 @@ static long do_rt_sigreturn_v1(CPUARMState *env)
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
return 0;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
static long do_rt_sigreturn_v2(CPUARMState *env)
|
||||
@ -2181,7 +2224,10 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {
|
||||
if (do_sigframe_return_v2(env,
|
||||
frame_addr
|
||||
+ offsetof(struct rt_sigframe_v2, uc),
|
||||
&frame->uc)) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
@ -2190,8 +2236,8 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
return 0;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUARMState *env)
|
||||
@ -2445,7 +2491,7 @@ sigill_and_return:
|
||||
#endif
|
||||
sigsegv:
|
||||
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -2525,6 +2571,7 @@ long do_sigreturn(CPUSPARCState *env)
|
||||
segv_and_exit:
|
||||
unlock_user_struct(sf, sf_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUSPARCState *env)
|
||||
@ -3037,7 +3084,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sig(TARGET_SIGSEGV/*, current*/);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUMIPSState *regs)
|
||||
@ -3082,8 +3129,8 @@ long do_sigreturn(CPUMIPSState *regs)
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV/*, current*/);
|
||||
return 0;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
# endif /* O32 */
|
||||
|
||||
@ -3146,7 +3193,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV/*, current*/);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUMIPSState *env)
|
||||
@ -3179,8 +3226,8 @@ long do_rt_sigreturn(CPUMIPSState *env)
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV/*, current*/);
|
||||
return 0;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_SH4)
|
||||
@ -3349,7 +3396,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -3409,7 +3456,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUSH4State *regs)
|
||||
@ -3446,7 +3493,7 @@ long do_sigreturn(CPUSH4State *regs)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUSH4State *regs)
|
||||
@ -3478,7 +3525,7 @@ long do_rt_sigreturn(CPUSH4State *regs)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
#elif defined(TARGET_MICROBLAZE)
|
||||
|
||||
@ -3656,7 +3703,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -3697,6 +3744,7 @@ long do_sigreturn(CPUMBState *env)
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUMBState *env)
|
||||
@ -3826,7 +3874,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -3864,6 +3912,7 @@ long do_sigreturn(CPUCRISState *env)
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUCRISState *env)
|
||||
@ -4065,10 +4114,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
if (sig == TARGET_SIGSEGV) {
|
||||
ka->_sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUOpenRISCState *env)
|
||||
@ -4249,7 +4295,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -4304,7 +4350,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4358,7 +4404,7 @@ long do_sigreturn(CPUS390XState *env)
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUS390XState *env)
|
||||
@ -4389,7 +4435,7 @@ long do_rt_sigreturn(CPUS390XState *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_PPC)
|
||||
@ -4815,7 +4861,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
@ -4910,7 +4956,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
sigsegv:
|
||||
unlock_user_struct(rt_sf, rt_sf_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
|
||||
}
|
||||
|
||||
@ -4948,7 +4994,7 @@ sigsegv:
|
||||
unlock_user_struct(sr, sr_addr, 1);
|
||||
unlock_user_struct(sc, sc_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
/* See arch/powerpc/kernel/signal_32.c. */
|
||||
@ -5003,7 +5049,7 @@ long do_rt_sigreturn(CPUPPCState *env)
|
||||
sigsegv:
|
||||
unlock_user_struct(rt_sf, rt_sf_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_M68K)
|
||||
@ -5159,7 +5205,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
|
||||
@ -5298,7 +5344,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUM68KState *env)
|
||||
@ -5333,7 +5379,7 @@ long do_sigreturn(CPUM68KState *env)
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUM68KState *env)
|
||||
@ -5366,7 +5412,7 @@ long do_rt_sigreturn(CPUM68KState *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_ALPHA)
|
||||
@ -5505,10 +5551,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
if (err) {
|
||||
give_sigsegv:
|
||||
if (sig == TARGET_SIGSEGV) {
|
||||
ka->_sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
|
||||
env->ir[IR_RA] = r26;
|
||||
@ -5562,10 +5606,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
if (err) {
|
||||
give_sigsegv:
|
||||
if (sig == TARGET_SIGSEGV) {
|
||||
ka->_sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
|
||||
env->ir[IR_RA] = r26;
|
||||
@ -5599,6 +5641,7 @@ long do_sigreturn(CPUAlphaState *env)
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUAlphaState *env)
|
||||
@ -5628,6 +5671,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_TILEGX)
|
||||
@ -5762,10 +5806,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
if (sig == TARGET_SIGSEGV) {
|
||||
ka->_sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
force_sig(TARGET_SIGSEGV /* , current */);
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUTLGState *env)
|
||||
@ -5795,6 +5836,7 @@ long do_rt_sigreturn(CPUTLGState *env)
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -5849,6 +5891,10 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
|
||||
handler = sa->_sa_handler;
|
||||
}
|
||||
|
||||
if (do_strace) {
|
||||
print_taken_signal(sig, &k->info);
|
||||
}
|
||||
|
||||
if (handler == TARGET_SIG_DFL) {
|
||||
/* default handler : ignore some signal. The other are job control or fatal */
|
||||
if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
|
||||
@ -5857,12 +5903,12 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
|
||||
sig != TARGET_SIGURG &&
|
||||
sig != TARGET_SIGWINCH &&
|
||||
sig != TARGET_SIGCONT) {
|
||||
force_sig(sig);
|
||||
dump_core_and_abort(sig);
|
||||
}
|
||||
} else if (handler == TARGET_SIG_IGN) {
|
||||
/* ignore sig */
|
||||
} else if (handler == TARGET_SIG_ERR) {
|
||||
force_sig(sig);
|
||||
dump_core_and_abort(sig);
|
||||
} else {
|
||||
/* compute the blocked signals during the handler execution */
|
||||
sigset_t *blocked_set;
|
||||
@ -5921,6 +5967,7 @@ void process_pending_signals(CPUArchState *cpu_env)
|
||||
sigfillset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, 0);
|
||||
|
||||
restart_scan:
|
||||
sig = ts->sync_signal.pending;
|
||||
if (sig) {
|
||||
/* Synchronous signals are forced,
|
||||
@ -5948,8 +5995,10 @@ void process_pending_signals(CPUArchState *cpu_env)
|
||||
(!sigismember(blocked_set,
|
||||
target_to_host_signal_table[sig]))) {
|
||||
handle_pending_signal(cpu_env, sig, &ts->sigtab[sig - 1]);
|
||||
/* Restart scan from the beginning */
|
||||
sig = 1;
|
||||
/* Restart scan from the beginning, as handle_pending_signal
|
||||
* might have resulted in a new synchronous signal (eg SIGSEGV).
|
||||
*/
|
||||
goto restart_scan;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,4 +22,20 @@ struct target_pt_regs {
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 0x4000
|
||||
|
||||
/* For SPARC SHMLBA is determined at runtime in the kernel, and
|
||||
* libc has to runtime-detect it using the hwcaps (see glibc
|
||||
* sysdeps/unix/sysv/linux/sparc/getshmlba; we follow the same
|
||||
* logic here, though we know we're not the sparc v9 64-bit case).
|
||||
*/
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUSPARCState *env)
|
||||
{
|
||||
if (!(env->def->features & CPU_FEATURE_FLUSH)) {
|
||||
return 64 * 1024;
|
||||
} else {
|
||||
return 256 * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SPARC_TARGET_SYSCALL_H */
|
||||
|
@ -154,6 +154,100 @@ print_signal(abi_ulong arg, int last)
|
||||
gemu_log("%s%s", signal_name, get_comma(last));
|
||||
}
|
||||
|
||||
static void print_si_code(int arg)
|
||||
{
|
||||
const char *codename = NULL;
|
||||
|
||||
switch (arg) {
|
||||
case SI_USER:
|
||||
codename = "SI_USER";
|
||||
break;
|
||||
case SI_KERNEL:
|
||||
codename = "SI_KERNEL";
|
||||
break;
|
||||
case SI_QUEUE:
|
||||
codename = "SI_QUEUE";
|
||||
break;
|
||||
case SI_TIMER:
|
||||
codename = "SI_TIMER";
|
||||
break;
|
||||
case SI_MESGQ:
|
||||
codename = "SI_MESGQ";
|
||||
break;
|
||||
case SI_ASYNCIO:
|
||||
codename = "SI_ASYNCIO";
|
||||
break;
|
||||
case SI_SIGIO:
|
||||
codename = "SI_SIGIO";
|
||||
break;
|
||||
case SI_TKILL:
|
||||
codename = "SI_TKILL";
|
||||
break;
|
||||
default:
|
||||
gemu_log("%d", arg);
|
||||
return;
|
||||
}
|
||||
gemu_log("%s", codename);
|
||||
}
|
||||
|
||||
static void print_siginfo(const target_siginfo_t *tinfo)
|
||||
{
|
||||
/* Print a target_siginfo_t in the format desired for printing
|
||||
* signals being taken. We assume the target_siginfo_t is in the
|
||||
* internal form where the top 16 bits of si_code indicate which
|
||||
* part of the union is valid, rather than in the guest-visible
|
||||
* form where the bottom 16 bits are sign-extended into the top 16.
|
||||
*/
|
||||
int si_type = extract32(tinfo->si_code, 16, 16);
|
||||
int si_code = sextract32(tinfo->si_code, 0, 16);
|
||||
|
||||
gemu_log("{si_signo=");
|
||||
print_signal(tinfo->si_signo, 1);
|
||||
gemu_log(", si_code=");
|
||||
print_si_code(si_code);
|
||||
|
||||
switch (si_type) {
|
||||
case QEMU_SI_KILL:
|
||||
gemu_log(", si_pid = %u, si_uid = %u",
|
||||
(unsigned int)tinfo->_sifields._kill._pid,
|
||||
(unsigned int)tinfo->_sifields._kill._uid);
|
||||
break;
|
||||
case QEMU_SI_TIMER:
|
||||
gemu_log(", si_timer1 = %u, si_timer2 = %u",
|
||||
tinfo->_sifields._timer._timer1,
|
||||
tinfo->_sifields._timer._timer2);
|
||||
break;
|
||||
case QEMU_SI_POLL:
|
||||
gemu_log(", si_band = %d, si_fd = %d",
|
||||
tinfo->_sifields._sigpoll._band,
|
||||
tinfo->_sifields._sigpoll._fd);
|
||||
break;
|
||||
case QEMU_SI_FAULT:
|
||||
gemu_log(", si_addr = ");
|
||||
print_pointer(tinfo->_sifields._sigfault._addr, 1);
|
||||
break;
|
||||
case QEMU_SI_CHLD:
|
||||
gemu_log(", si_pid = %u, si_uid = %u, si_status = %d"
|
||||
", si_utime=" TARGET_ABI_FMT_ld
|
||||
", si_stime=" TARGET_ABI_FMT_ld,
|
||||
(unsigned int)(tinfo->_sifields._sigchld._pid),
|
||||
(unsigned int)(tinfo->_sifields._sigchld._uid),
|
||||
tinfo->_sifields._sigchld._status,
|
||||
tinfo->_sifields._sigchld._utime,
|
||||
tinfo->_sifields._sigchld._stime);
|
||||
break;
|
||||
case QEMU_SI_RT:
|
||||
gemu_log(", si_pid = %u, si_uid = %u, si_sigval = " TARGET_ABI_FMT_ld,
|
||||
(unsigned int)tinfo->_sifields._rt._pid,
|
||||
(unsigned int)tinfo->_sifields._rt._uid,
|
||||
tinfo->_sifields._rt._sigval.sival_ptr);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
gemu_log("}");
|
||||
}
|
||||
|
||||
static void
|
||||
print_sockaddr(abi_ulong addr, abi_long addrlen)
|
||||
{
|
||||
@ -2190,3 +2284,15 @@ print_syscall_ret(int num, abi_long ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void print_taken_signal(int target_signum, const target_siginfo_t *tinfo)
|
||||
{
|
||||
/* Print the strace output for a signal being taken:
|
||||
* --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
|
||||
*/
|
||||
gemu_log("--- ");
|
||||
print_signal(target_signum, 1);
|
||||
gemu_log(" ");
|
||||
print_siginfo(tinfo);
|
||||
gemu_log(" ---\n");
|
||||
}
|
||||
|
@ -112,8 +112,56 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
|
||||
|
||||
#include "qemu.h"
|
||||
|
||||
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
|
||||
CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
|
||||
#ifndef CLONE_IO
|
||||
#define CLONE_IO 0x80000000 /* Clone io context */
|
||||
#endif
|
||||
|
||||
/* We can't directly call the host clone syscall, because this will
|
||||
* badly confuse libc (breaking mutexes, for example). So we must
|
||||
* divide clone flags into:
|
||||
* * flag combinations that look like pthread_create()
|
||||
* * flag combinations that look like fork()
|
||||
* * flags we can implement within QEMU itself
|
||||
* * flags we can't support and will return an error for
|
||||
*/
|
||||
/* For thread creation, all these flags must be present; for
|
||||
* fork, none must be present.
|
||||
*/
|
||||
#define CLONE_THREAD_FLAGS \
|
||||
(CLONE_VM | CLONE_FS | CLONE_FILES | \
|
||||
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
|
||||
|
||||
/* These flags are ignored:
|
||||
* CLONE_DETACHED is now ignored by the kernel;
|
||||
* CLONE_IO is just an optimisation hint to the I/O scheduler
|
||||
*/
|
||||
#define CLONE_IGNORED_FLAGS \
|
||||
(CLONE_DETACHED | CLONE_IO)
|
||||
|
||||
/* Flags for fork which we can implement within QEMU itself */
|
||||
#define CLONE_OPTIONAL_FORK_FLAGS \
|
||||
(CLONE_SETTLS | CLONE_PARENT_SETTID | \
|
||||
CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
|
||||
|
||||
/* Flags for thread creation which we can implement within QEMU itself */
|
||||
#define CLONE_OPTIONAL_THREAD_FLAGS \
|
||||
(CLONE_SETTLS | CLONE_PARENT_SETTID | \
|
||||
CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
|
||||
|
||||
#define CLONE_INVALID_FORK_FLAGS \
|
||||
(~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
|
||||
|
||||
#define CLONE_INVALID_THREAD_FLAGS \
|
||||
(~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS | \
|
||||
CLONE_IGNORED_FLAGS))
|
||||
|
||||
/* CLONE_VFORK is special cased early in do_fork(). The other flag bits
|
||||
* have almost all been allocated. We cannot support any of
|
||||
* CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
|
||||
* CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
|
||||
* The checks against the invalid thread masks above will catch these.
|
||||
* (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
|
||||
*/
|
||||
|
||||
//#define DEBUG
|
||||
/* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
|
||||
@ -520,16 +568,7 @@ static int sys_getcwd1(char *buf, size_t size)
|
||||
}
|
||||
|
||||
#ifdef TARGET_NR_utimensat
|
||||
#ifdef CONFIG_UTIMENSAT
|
||||
static int sys_utimensat(int dirfd, const char *pathname,
|
||||
const struct timespec times[2], int flags)
|
||||
{
|
||||
if (pathname == NULL)
|
||||
return futimens(dirfd, times);
|
||||
else
|
||||
return utimensat(dirfd, pathname, times, flags);
|
||||
}
|
||||
#elif defined(__NR_utimensat)
|
||||
#if defined(__NR_utimensat)
|
||||
#define __NR_sys_utimensat __NR_utimensat
|
||||
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
|
||||
const struct timespec *,tsp,int,flags)
|
||||
@ -1405,6 +1444,29 @@ static abi_long do_select(int n,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(TARGET_WANT_OLD_SYS_SELECT)
|
||||
static abi_long do_old_select(abi_ulong arg1)
|
||||
{
|
||||
struct target_sel_arg_struct *sel;
|
||||
abi_ulong inp, outp, exp, tvp;
|
||||
long nsel;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
nsel = tswapal(sel->n);
|
||||
inp = tswapal(sel->inp);
|
||||
outp = tswapal(sel->outp);
|
||||
exp = tswapal(sel->exp);
|
||||
tvp = tswapal(sel->tvp);
|
||||
|
||||
unlock_user_struct(sel, arg1, 0);
|
||||
|
||||
return do_select(nsel, inp, outp, exp, tvp);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static abi_long do_pipe2(int host_pipe[], int flags)
|
||||
@ -3119,7 +3181,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
|
||||
}
|
||||
|
||||
static struct iovec *lock_iovec(int type, abi_ulong target_addr,
|
||||
int count, int copy)
|
||||
abi_ulong count, int copy)
|
||||
{
|
||||
struct target_iovec *target_vec;
|
||||
struct iovec *vec;
|
||||
@ -3132,7 +3194,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (count < 0 || count > IOV_MAX) {
|
||||
if (count > IOV_MAX) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
@ -3207,7 +3269,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
|
||||
}
|
||||
|
||||
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
|
||||
int count, int copy)
|
||||
abi_ulong count, int copy)
|
||||
{
|
||||
struct target_iovec *target_vec;
|
||||
int i;
|
||||
@ -3462,7 +3524,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
{
|
||||
abi_long ret, len;
|
||||
struct msghdr msg;
|
||||
int count;
|
||||
abi_ulong count;
|
||||
struct iovec *vec;
|
||||
abi_ulong target_vec;
|
||||
|
||||
@ -3472,7 +3534,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
ret = target_to_host_sockaddr(fd, msg.msg_name,
|
||||
tswapal(msgp->msg_name),
|
||||
msg.msg_namelen);
|
||||
if (ret) {
|
||||
if (ret == -TARGET_EFAULT) {
|
||||
/* For connected sockets msg_name and msg_namelen must
|
||||
* be ignored, so returning EFAULT immediately is wrong.
|
||||
* Instead, pass a bad msg_name to the host kernel, and
|
||||
* let it decide whether to return EFAULT or not.
|
||||
*/
|
||||
msg.msg_name = (void *)-1;
|
||||
} else if (ret) {
|
||||
goto out2;
|
||||
}
|
||||
} else {
|
||||
@ -3485,6 +3554,15 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
|
||||
count = tswapal(msgp->msg_iovlen);
|
||||
target_vec = tswapal(msgp->msg_iov);
|
||||
|
||||
if (count > IOV_MAX) {
|
||||
/* sendrcvmsg returns a different errno for this condition than
|
||||
* readv/writev, so we must catch it here before lock_iovec() does.
|
||||
*/
|
||||
ret = -TARGET_EMSGSIZE;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
|
||||
target_vec, count, send);
|
||||
if (vec == NULL) {
|
||||
@ -3525,7 +3603,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
}
|
||||
if (!is_error(ret)) {
|
||||
msgp->msg_namelen = tswap32(msg.msg_namelen);
|
||||
if (msg.msg_name != NULL) {
|
||||
if (msg.msg_name != NULL && msg.msg_name != (void *)-1) {
|
||||
ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
|
||||
msg.msg_name, msg.msg_namelen);
|
||||
if (ret) {
|
||||
@ -4568,12 +4646,34 @@ static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
|
||||
#ifndef TARGET_FORCE_SHMLBA
|
||||
/* For most architectures, SHMLBA is the same as the page size;
|
||||
* some architectures have larger values, in which case they should
|
||||
* define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
|
||||
* This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
|
||||
* and defining its own value for SHMLBA.
|
||||
*
|
||||
* The kernel also permits SHMLBA to be set by the architecture to a
|
||||
* value larger than the page size without setting __ARCH_FORCE_SHMLBA;
|
||||
* this means that addresses are rounded to the large size if
|
||||
* SHM_RND is set but addresses not aligned to that size are not rejected
|
||||
* as long as they are at least page-aligned. Since the only architecture
|
||||
* which uses this is ia64 this code doesn't provide for that oddity.
|
||||
*/
|
||||
static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
|
||||
{
|
||||
return TARGET_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline abi_ulong do_shmat(CPUArchState *cpu_env,
|
||||
int shmid, abi_ulong shmaddr, int shmflg)
|
||||
{
|
||||
abi_long raddr;
|
||||
void *host_raddr;
|
||||
struct shmid_ds shm_info;
|
||||
int i,ret;
|
||||
abi_ulong shmlba;
|
||||
|
||||
/* find out the length of the shared memory segment */
|
||||
ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
|
||||
@ -4582,6 +4682,16 @@ static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
shmlba = target_shmlba(cpu_env);
|
||||
|
||||
if (shmaddr & (shmlba - 1)) {
|
||||
if (shmflg & SHM_RND) {
|
||||
shmaddr &= ~(shmlba - 1);
|
||||
} else {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
mmap_lock();
|
||||
|
||||
if (shmaddr)
|
||||
@ -4640,7 +4750,8 @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
|
||||
#ifdef TARGET_NR_ipc
|
||||
/* ??? This only works with linear mappings. */
|
||||
/* do_ipc() must return target values and target errnos. */
|
||||
static abi_long do_ipc(unsigned int call, abi_long first,
|
||||
static abi_long do_ipc(CPUArchState *cpu_env,
|
||||
unsigned int call, abi_long first,
|
||||
abi_long second, abi_long third,
|
||||
abi_long ptr, abi_long fifth)
|
||||
{
|
||||
@ -4709,7 +4820,7 @@ static abi_long do_ipc(unsigned int call, abi_long first,
|
||||
default:
|
||||
{
|
||||
abi_ulong raddr;
|
||||
raddr = do_shmat(first, ptr, second);
|
||||
raddr = do_shmat(cpu_env, first, ptr, second);
|
||||
if (is_error(raddr))
|
||||
return get_errno(raddr);
|
||||
if (put_user_ual(raddr, third))
|
||||
@ -4994,13 +5105,18 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
|
||||
|
||||
guest_data = arg + host_dm->data_start;
|
||||
if ((guest_data - arg) < 0) {
|
||||
ret = -EINVAL;
|
||||
ret = -TARGET_EINVAL;
|
||||
goto out;
|
||||
}
|
||||
guest_data_size = host_dm->data_size - host_dm->data_start;
|
||||
host_data = (char*)host_dm + host_dm->data_start;
|
||||
|
||||
argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
|
||||
if (!argptr) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (ie->host_cmd) {
|
||||
case DM_REMOVE_ALL:
|
||||
case DM_LIST_DEVICES:
|
||||
@ -5966,9 +6082,10 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
TaskState *ts;
|
||||
CPUState *new_cpu;
|
||||
CPUArchState *new_env;
|
||||
unsigned int nptl_flags;
|
||||
sigset_t sigmask;
|
||||
|
||||
flags &= ~CLONE_IGNORED_FLAGS;
|
||||
|
||||
/* Emulate vfork() with fork() */
|
||||
if (flags & CLONE_VFORK)
|
||||
flags &= ~(CLONE_VFORK | CLONE_VM);
|
||||
@ -5978,6 +6095,11 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
new_thread_info info;
|
||||
pthread_attr_t attr;
|
||||
|
||||
if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
|
||||
(flags & CLONE_INVALID_THREAD_FLAGS)) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
ts = g_new0(TaskState, 1);
|
||||
init_task_state(ts);
|
||||
/* we create a new CPU instance. */
|
||||
@ -5989,15 +6111,14 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
ts->bprm = parent_ts->bprm;
|
||||
ts->info = parent_ts->info;
|
||||
ts->signal_mask = parent_ts->signal_mask;
|
||||
nptl_flags = flags;
|
||||
flags &= ~CLONE_NPTL_FLAGS2;
|
||||
|
||||
if (nptl_flags & CLONE_CHILD_CLEARTID) {
|
||||
if (flags & CLONE_CHILD_CLEARTID) {
|
||||
ts->child_tidptr = child_tidptr;
|
||||
}
|
||||
|
||||
if (nptl_flags & CLONE_SETTLS)
|
||||
if (flags & CLONE_SETTLS) {
|
||||
cpu_set_tls (new_env, newtls);
|
||||
}
|
||||
|
||||
/* Grab a mutex so that thread setup appears atomic. */
|
||||
pthread_mutex_lock(&clone_lock);
|
||||
@ -6007,10 +6128,12 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
pthread_mutex_lock(&info.mutex);
|
||||
pthread_cond_init(&info.cond, NULL);
|
||||
info.env = new_env;
|
||||
if (nptl_flags & CLONE_CHILD_SETTID)
|
||||
if (flags & CLONE_CHILD_SETTID) {
|
||||
info.child_tidptr = child_tidptr;
|
||||
if (nptl_flags & CLONE_PARENT_SETTID)
|
||||
}
|
||||
if (flags & CLONE_PARENT_SETTID) {
|
||||
info.parent_tidptr = parent_tidptr;
|
||||
}
|
||||
|
||||
ret = pthread_attr_init(&attr);
|
||||
ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
|
||||
@ -6029,8 +6152,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
/* Wait for the child to initialize. */
|
||||
pthread_cond_wait(&info.cond, &info.mutex);
|
||||
ret = info.tid;
|
||||
if (flags & CLONE_PARENT_SETTID)
|
||||
put_user_u32(ret, parent_tidptr);
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
@ -6040,7 +6161,12 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
pthread_mutex_unlock(&clone_lock);
|
||||
} else {
|
||||
/* if no CLONE_VM, we consider it is a fork */
|
||||
if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
|
||||
if (flags & CLONE_INVALID_FORK_FLAGS) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
/* We can't support custom termination signals */
|
||||
if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
@ -8565,24 +8691,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
break;
|
||||
#if defined(TARGET_NR_select)
|
||||
case TARGET_NR_select:
|
||||
#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
|
||||
ret = do_select(arg1, arg2, arg3, arg4, arg5);
|
||||
#if defined(TARGET_WANT_NI_OLD_SELECT)
|
||||
/* some architectures used to have old_select here
|
||||
* but now ENOSYS it.
|
||||
*/
|
||||
ret = -TARGET_ENOSYS;
|
||||
#elif defined(TARGET_WANT_OLD_SYS_SELECT)
|
||||
ret = do_old_select(arg1);
|
||||
#else
|
||||
{
|
||||
struct target_sel_arg_struct *sel;
|
||||
abi_ulong inp, outp, exp, tvp;
|
||||
long nsel;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
|
||||
goto efault;
|
||||
nsel = tswapal(sel->n);
|
||||
inp = tswapal(sel->inp);
|
||||
outp = tswapal(sel->outp);
|
||||
exp = tswapal(sel->exp);
|
||||
tvp = tswapal(sel->tvp);
|
||||
unlock_user_struct(sel, arg1, 0);
|
||||
ret = do_select(nsel, inp, outp, exp, tvp);
|
||||
}
|
||||
ret = do_select(arg1, arg2, arg3, arg4, arg5);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
@ -9292,8 +9409,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
break;
|
||||
#ifdef TARGET_NR_ipc
|
||||
case TARGET_NR_ipc:
|
||||
ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
break;
|
||||
ret = do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_semget
|
||||
case TARGET_NR_semget:
|
||||
@ -9342,7 +9459,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
#endif
|
||||
#ifdef TARGET_NR_shmat
|
||||
case TARGET_NR_shmat:
|
||||
ret = do_shmat(arg1, arg2, arg3);
|
||||
ret = do_shmat(cpu_env, arg1, arg2, arg3);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_shmdt
|
||||
@ -9654,6 +9771,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
pfd = NULL;
|
||||
target_pfd = NULL;
|
||||
if (nfds) {
|
||||
if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
target_pfd = lock_user(VERIFY_WRITE, arg1,
|
||||
sizeof(struct target_pollfd) * nfds, 1);
|
||||
if (!target_pfd) {
|
||||
@ -10527,7 +10649,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
info.si_code = si_code;
|
||||
info._sifields._sigfault._addr
|
||||
= ((CPUArchState *)cpu_env)->pc;
|
||||
queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
|
||||
queue_signal((CPUArchState *)cpu_env, info.si_signo,
|
||||
QEMU_SI_FAULT, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -11259,6 +11382,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
|
||||
case TARGET_NR_mq_unlink:
|
||||
p = lock_user_string(arg1 - 1);
|
||||
if (!p) {
|
||||
ret = -TARGET_EFAULT;
|
||||
break;
|
||||
}
|
||||
ret = get_errno(mq_unlink(p));
|
||||
unlock_user (p, arg1, 0);
|
||||
break;
|
||||
@ -11494,6 +11621,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
int maxevents = arg3;
|
||||
int timeout = arg4;
|
||||
|
||||
if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
target_ep = lock_user(VERIFY_WRITE, arg2,
|
||||
maxevents * sizeof(struct target_epoll_event), 1);
|
||||
if (!target_ep) {
|
||||
@ -11606,7 +11738,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = arg6;
|
||||
queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
|
||||
queue_signal((CPUArchState *)cpu_env, info.si_signo,
|
||||
QEMU_SI_FAULT, &info);
|
||||
ret = 0xdeadbeef;
|
||||
|
||||
}
|
||||
|
@ -998,6 +998,12 @@ struct target_pollfd {
|
||||
|
||||
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
|
||||
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
|
||||
/* Note that the ioctl numbers claim type "long" but the actual type
|
||||
* used by the kernel is "int".
|
||||
*/
|
||||
#define TARGET_FS_IOC_GETFLAGS TARGET_IOR('f', 1, long)
|
||||
#define TARGET_FS_IOC_SETFLAGS TARGET_IOW('f', 2, long)
|
||||
|
||||
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
|
||||
|
||||
/* cdrom commands */
|
||||
@ -2579,6 +2585,9 @@ struct target_epoll_event {
|
||||
abi_uint events;
|
||||
target_epoll_data_t data;
|
||||
} TARGET_EPOLL_PACKED;
|
||||
|
||||
#define TARGET_EP_MAX_EVENTS (INT_MAX / sizeof(struct target_epoll_event))
|
||||
|
||||
#endif
|
||||
struct target_rlimit64 {
|
||||
uint64_t rlim_cur;
|
||||
|
@ -311,7 +311,6 @@
|
||||
#define TARGET_NR_creat 1064
|
||||
#define TARGET_NR_getdents 1065
|
||||
#define TARGET_NR_futimesat 1066
|
||||
#define TARGET_NR_select 1067
|
||||
#define TARGET_NR_poll 1068
|
||||
#define TARGET_NR_epoll_wait 1069
|
||||
#define TARGET_NR_ustat 1070
|
||||
|
Loading…
Reference in New Issue
Block a user