diff options
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/arm/nwfpe/double_cpdo.c | 2 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/extended_cpdo.c | 2 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/fpa11.h | 2 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/fpa11_cpdt.c | 2 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/fpa11_cprt.c | 2 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/fpopcode.c | 2 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/single_cpdo.c | 2 | ||||
-rw-r--r-- | linux-user/arm/syscall_nr.h | 4 | ||||
-rw-r--r-- | linux-user/cris/syscall.h | 5 | ||||
-rw-r--r-- | linux-user/elfload.c | 2 | ||||
-rw-r--r-- | linux-user/i386/syscall_nr.h | 4 | ||||
-rw-r--r-- | linux-user/main.c | 153 | ||||
-rw-r--r-- | linux-user/microblaze/syscall.h | 6 | ||||
-rw-r--r-- | linux-user/qemu-types.h | 36 | ||||
-rw-r--r-- | linux-user/qemu.h | 73 | ||||
-rw-r--r-- | linux-user/s390x/syscall.h | 2 | ||||
-rw-r--r-- | linux-user/signal.c | 28 | ||||
-rw-r--r-- | linux-user/sparc/syscall_nr.h | 4 | ||||
-rw-r--r-- | linux-user/strace.c | 2 | ||||
-rw-r--r-- | linux-user/strace.list | 6 | ||||
-rw-r--r-- | linux-user/syscall.c | 120 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 26 | ||||
-rw-r--r-- | linux-user/unicore32/syscall_nr.h | 4 |
23 files changed, 274 insertions, 215 deletions
diff --git a/linux-user/arm/nwfpe/double_cpdo.c b/linux-user/arm/nwfpe/double_cpdo.c index 8e9b28f..41c28f3 100644 --- a/linux-user/arm/nwfpe/double_cpdo.c +++ b/linux-user/arm/nwfpe/double_cpdo.c @@ -19,7 +19,7 @@ */ #include "fpa11.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #include "fpopcode.h" float64 float64_exp(float64 Fm); diff --git a/linux-user/arm/nwfpe/extended_cpdo.c b/linux-user/arm/nwfpe/extended_cpdo.c index 880ce03..48eca3b 100644 --- a/linux-user/arm/nwfpe/extended_cpdo.c +++ b/linux-user/arm/nwfpe/extended_cpdo.c @@ -19,7 +19,7 @@ */ #include "fpa11.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #include "fpopcode.h" floatx80 floatx80_exp(floatx80 Fm); diff --git a/linux-user/arm/nwfpe/fpa11.h b/linux-user/arm/nwfpe/fpa11.h index 002b3cb..bb9ac65 100644 --- a/linux-user/arm/nwfpe/fpa11.h +++ b/linux-user/arm/nwfpe/fpa11.h @@ -43,7 +43,7 @@ extern CPUARMState *user_registers; /* includes */ #include "fpsr.h" /* FP control and status register definitions */ -#include "softfloat.h" +#include "fpu/softfloat.h" #define typeNone 0x00 #define typeSingle 0x01 diff --git a/linux-user/arm/nwfpe/fpa11_cpdt.c b/linux-user/arm/nwfpe/fpa11_cpdt.c index 3e7a938..007a3d6 100644 --- a/linux-user/arm/nwfpe/fpa11_cpdt.c +++ b/linux-user/arm/nwfpe/fpa11_cpdt.c @@ -20,7 +20,7 @@ */ #include "fpa11.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #include "fpopcode.h" //#include "fpmodule.h" //#include "fpmodule.inl" diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c index 8011897..7be93fa 100644 --- a/linux-user/arm/nwfpe/fpa11_cprt.c +++ b/linux-user/arm/nwfpe/fpa11_cprt.c @@ -20,7 +20,7 @@ */ #include "fpa11.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #include "fpopcode.h" #include "fpa11.inl" //#include "fpmodule.h" diff --git a/linux-user/arm/nwfpe/fpopcode.c b/linux-user/arm/nwfpe/fpopcode.c index 82ac92f..0dc5c9c 100644 --- a/linux-user/arm/nwfpe/fpopcode.c +++ b/linux-user/arm/nwfpe/fpopcode.c @@ -19,7 +19,7 @@ */ #include "fpa11.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #include "fpopcode.h" #include "fpsr.h" //#include "fpmodule.h" diff --git a/linux-user/arm/nwfpe/single_cpdo.c b/linux-user/arm/nwfpe/single_cpdo.c index 26168e2..2bfb359 100644 --- a/linux-user/arm/nwfpe/single_cpdo.c +++ b/linux-user/arm/nwfpe/single_cpdo.c @@ -19,7 +19,7 @@ */ #include "fpa11.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #include "fpopcode.h" float32 float32_exp(float32 Fm); diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h index 5356395..42d6855 100644 --- a/linux-user/arm/syscall_nr.h +++ b/linux-user/arm/syscall_nr.h @@ -182,8 +182,8 @@ #define TARGET_NR_rt_sigtimedwait (177) #define TARGET_NR_rt_sigqueueinfo (178) #define TARGET_NR_rt_sigsuspend (179) -#define TARGET_NR_pread (180) -#define TARGET_NR_pwrite (181) +#define TARGET_NR_pread64 (180) +#define TARGET_NR_pwrite64 (181) #define TARGET_NR_chown (182) #define TARGET_NR_getcwd (183) #define TARGET_NR_capget (184) diff --git a/linux-user/cris/syscall.h b/linux-user/cris/syscall.h index 24f92ba..50e50b4 100644 --- a/linux-user/cris/syscall.h +++ b/linux-user/cris/syscall.h @@ -1,3 +1,6 @@ +#ifndef CRIS_SYSCALL_H +#define CRIS_SYSCALL_H 1 + #define UNAME_MACHINE "cris" @@ -34,3 +37,5 @@ struct target_pt_regs { unsigned long exs; unsigned long eda; }; + +#endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 1d8bcb4..89db49c 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -14,7 +14,7 @@ #include <time.h> #include "qemu.h" -#include "disas.h" +#include "disas/disas.h" #ifdef _ARCH_PPC64 #undef ARCH_DLINFO diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h index 74abfca..f080305 100644 --- a/linux-user/i386/syscall_nr.h +++ b/linux-user/i386/syscall_nr.h @@ -182,8 +182,8 @@ #define TARGET_NR_rt_sigtimedwait 177 #define TARGET_NR_rt_sigqueueinfo 178 #define TARGET_NR_rt_sigsuspend 179 -#define TARGET_NR_pread 180 -#define TARGET_NR_pwrite 181 +#define TARGET_NR_pread64 180 +#define TARGET_NR_pwrite64 181 #define TARGET_NR_chown 182 #define TARGET_NR_getcwd 183 #define TARGET_NR_capget 184 diff --git a/linux-user/main.c b/linux-user/main.c index 25e35cd..3df8aa2 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -28,11 +28,11 @@ #include "qemu.h" #include "qemu-common.h" -#include "cache-utils.h" +#include "qemu/cache-utils.h" #include "cpu.h" #include "tcg.h" -#include "qemu-timer.h" -#include "envlist.h" +#include "qemu/timer.h" +#include "qemu/envlist.h" #include "elf.h" #define DEBUG_LOGFILE "/tmp/qemu.log" @@ -57,7 +57,12 @@ int have_guest_base; * This way we will never overlap with our own libraries or binaries or stack * or anything else that QEMU maps. */ +# ifdef TARGET_MIPS +/* MIPS only supports 31 bits of virtual address space for user space */ +unsigned long reserved_va = 0x77000000; +# else unsigned long reserved_va = 0xf7000000; +# endif #else unsigned long reserved_va; #endif @@ -2933,71 +2938,115 @@ void cpu_loop(CPUAlphaState *env) #ifdef TARGET_S390X void cpu_loop(CPUS390XState *env) { - int trapnr; + int trapnr, n, sig; target_siginfo_t info; + target_ulong addr; while (1) { - trapnr = cpu_s390x_exec (env); - + trapnr = cpu_s390x_exec(env); switch (trapnr) { case EXCP_INTERRUPT: - /* just indicate that signals should be handled asap */ + /* Just indicate that signals should be handled asap. */ break; - case EXCP_DEBUG: - { - int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); - if (sig) { - info.si_signo = sig; - info.si_errno = 0; - info.si_code = TARGET_TRAP_BRKPT; - queue_signal(env, info.si_signo, &info); - } + case EXCP_SVC: + n = env->int_svc_code; + if (!n) { + /* syscalls > 255 */ + n = env->regs[1]; } + env->psw.addr += env->int_svc_ilen; + env->regs[2] = do_syscall(env, n, env->regs[2], env->regs[3], + env->regs[4], env->regs[5], + env->regs[6], env->regs[7], 0, 0); break; - case EXCP_SVC: - { - int n = env->int_svc_code; - if (!n) { - /* syscalls > 255 */ - n = env->regs[1]; - } - env->psw.addr += env->int_svc_ilc; - env->regs[2] = do_syscall(env, n, - env->regs[2], - env->regs[3], - env->regs[4], - env->regs[5], - env->regs[6], - env->regs[7], - 0, 0); + + case EXCP_DEBUG: + sig = gdb_handlesig(env, TARGET_SIGTRAP); + if (sig) { + n = TARGET_TRAP_BRKPT; + goto do_signal_pc; } break; - case EXCP_ADDR: - { - info.si_signo = SIGSEGV; - info.si_errno = 0; + case EXCP_PGM: + n = env->int_pgm_code; + switch (n) { + case PGM_OPERATION: + case PGM_PRIVILEGED: + sig = SIGILL; + n = TARGET_ILL_ILLOPC; + goto do_signal_pc; + case PGM_PROTECTION: + case PGM_ADDRESSING: + sig = SIGSEGV; /* XXX: check env->error_code */ - info.si_code = TARGET_SEGV_MAPERR; - info._sifields._sigfault._addr = env->__excp_addr; - queue_signal(env, info.si_signo, &info); + n = TARGET_SEGV_MAPERR; + addr = env->__excp_addr; + goto do_signal; + case PGM_EXECUTE: + case PGM_SPECIFICATION: + case PGM_SPECIAL_OP: + case PGM_OPERAND: + do_sigill_opn: + sig = SIGILL; + n = TARGET_ILL_ILLOPN; + goto do_signal_pc; + + case PGM_FIXPT_OVERFLOW: + sig = SIGFPE; + n = TARGET_FPE_INTOVF; + goto do_signal_pc; + case PGM_FIXPT_DIVIDE: + sig = SIGFPE; + n = TARGET_FPE_INTDIV; + goto do_signal_pc; + + case PGM_DATA: + n = (env->fpc >> 8) & 0xff; + if (n == 0xff) { + /* compare-and-trap */ + goto do_sigill_opn; + } else { + /* An IEEE exception, simulated or otherwise. */ + if (n & 0x80) { + n = TARGET_FPE_FLTINV; + } else if (n & 0x40) { + n = TARGET_FPE_FLTDIV; + } else if (n & 0x20) { + n = TARGET_FPE_FLTOVF; + } else if (n & 0x10) { + n = TARGET_FPE_FLTUND; + } else if (n & 0x08) { + n = TARGET_FPE_FLTRES; + } else { + /* ??? Quantum exception; BFP, DFP error. */ + goto do_sigill_opn; + } + sig = SIGFPE; + goto do_signal_pc; + } + + default: + fprintf(stderr, "Unhandled program exception: %#x\n", n); + cpu_dump_state(env, stderr, fprintf, 0); + exit(1); } break; - case EXCP_SPEC: - { - fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4)); - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_code = TARGET_ILL_ILLOPC; - info._sifields._sigfault._addr = env->__excp_addr; - queue_signal(env, info.si_signo, &info); - } + + do_signal_pc: + addr = env->psw.addr; + do_signal: + info.si_signo = sig; + info.si_errno = 0; + info.si_code = n; + info._sifields._sigfault._addr = addr; + queue_signal(env, info.si_signo, &info); break; + default: - printf ("Unhandled trap: 0x%x\n", trapnr); + fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(env, stderr, fprintf, 0); - exit (1); + exit(1); } process_pending_signals (env); } @@ -3491,7 +3540,7 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } -#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) +#if defined(TARGET_SPARC) || defined(TARGET_PPC) cpu_reset(ENV_GET_CPU(env)); #endif diff --git a/linux-user/microblaze/syscall.h b/linux-user/microblaze/syscall.h index db1f98a..c3e5c55 100644 --- a/linux-user/microblaze/syscall.h +++ b/linux-user/microblaze/syscall.h @@ -1,3 +1,7 @@ +#ifndef MICROBLAZE_SYSCALLS_H +#define MICROBLAZE_SYSCALLS_H 1 + + #define UNAME_MACHINE "microblaze" /* We use microblaze_reg_t to keep things similar to the kernel sources. */ @@ -43,3 +47,5 @@ struct target_pt_regs { microblaze_reg_t fsr; uint32_t kernel_mode; }; + +#endif diff --git a/linux-user/qemu-types.h b/linux-user/qemu-types.h deleted file mode 100644 index fe7f662..0000000 --- a/linux-user/qemu-types.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef QEMU_TYPES_H -#define QEMU_TYPES_H -#include "cpu.h" - -#ifdef TARGET_ABI32 -typedef uint32_t abi_ulong; -typedef int32_t abi_long; -#define TARGET_ABI_FMT_lx "%08x" -#define TARGET_ABI_FMT_ld "%d" -#define TARGET_ABI_FMT_lu "%u" -#define TARGET_ABI_BITS 32 - -static inline abi_ulong tswapal(abi_ulong v) -{ - return tswap32(v); -} - -#else -typedef target_ulong abi_ulong; -typedef target_long abi_long; -#define TARGET_ABI_FMT_lx TARGET_FMT_lx -#define TARGET_ABI_FMT_ld TARGET_FMT_ld -#define TARGET_ABI_FMT_lu TARGET_FMT_lu -#define TARGET_ABI_BITS TARGET_LONG_BITS -/* for consistency, define ABI32 too */ -#if TARGET_ABI_BITS == 32 -#define TARGET_ABI32 1 -#endif - -static inline abi_ulong tswapal(abi_ulong v) -{ - return tswapl(v); -} - -#endif -#endif diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 5e53dca..b10e957 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -11,14 +11,14 @@ #include <stdlib.h> #endif /* DEBUG_REMAP */ -#include "qemu-types.h" +#include "exec/user/abitypes.h" -#include "thunk.h" +#include "exec/user/thunk.h" #include "syscall_defs.h" #include "syscall.h" #include "target_signal.h" -#include "gdbstub.h" -#include "qemu-queue.h" +#include "exec/gdbstub.h" +#include "qemu/queue.h" #if defined(CONFIG_USE_NPTL) #define THREAD __thread @@ -217,7 +217,7 @@ unsigned long init_guest_space(unsigned long host_start, unsigned long guest_start, bool fixed); -#include "qemu-log.h" +#include "qemu/log.h" /* syscall.c */ int host_to_target_waitstatus(int status); @@ -287,36 +287,39 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size) (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0; } -/* NOTE __get_user and __put_user use host pointers and don't check access. */ -/* These are usually used to access struct data members once the - * struct has been locked - usually with lock_user_struct(). - */ -#define __put_user(x, hptr)\ -({ __typeof(*hptr) pu_ = (x);\ - switch(sizeof(*hptr)) {\ - case 1: break;\ - case 2: pu_ = tswap16(pu_); break; \ - case 4: pu_ = tswap32(pu_); break; \ - case 8: pu_ = tswap64(pu_); break; \ - default: abort();\ - }\ - memcpy(hptr, &pu_, sizeof(pu_)); \ - 0;\ -}) - -#define __get_user(x, hptr) \ -({ __typeof(*hptr) gu_; \ - memcpy(&gu_, hptr, sizeof(gu_)); \ - switch(sizeof(*hptr)) {\ - case 1: break; \ - case 2: gu_ = tswap16(gu_); break; \ - case 4: gu_ = tswap32(gu_); break; \ - case 8: gu_ = tswap64(gu_); break; \ - default: abort();\ - }\ - (x) = gu_; \ - 0;\ -}) +/* NOTE __get_user and __put_user use host pointers and don't check access. + These are usually used to access struct data members once the struct has + been locked - usually with lock_user_struct. */ + +/* Tricky points: + - Use __builtin_choose_expr to avoid type promotion from ?:, + - Invalid sizes result in a compile time error stemming from + the fact that abort has no parameters. + - It's easier to use the endian-specific unaligned load/store + functions than host-endian unaligned load/store plus tswapN. */ + +#define __put_user_e(x, hptr, e) \ + (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \ + ((hptr), (x)), 0) + +#define __get_user_e(x, hptr, e) \ + ((x) = (typeof(*hptr))( \ + __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \ + (hptr)), 0) + +#ifdef TARGET_WORDS_BIGENDIAN +# define __put_user(x, hptr) __put_user_e(x, hptr, be) +# define __get_user(x, hptr) __get_user_e(x, hptr, be) +#else +# define __put_user(x, hptr) __put_user_e(x, hptr, le) +# define __get_user(x, hptr) __get_user_e(x, hptr, le) +#endif /* put_user()/get_user() take a guest address and check access */ /* These are usually used to access an atomic data type, such as an int, diff --git a/linux-user/s390x/syscall.h b/linux-user/s390x/syscall.h index c2ea151..e4603b7 100644 --- a/linux-user/s390x/syscall.h +++ b/linux-user/s390x/syscall.h @@ -16,7 +16,7 @@ struct target_pt_regs { target_psw_t psw; abi_ulong gprs[TARGET_NUM_GPRS]; abi_ulong orig_gpr2; - unsigned short ilc; + unsigned short ilen; unsigned short trap; }; diff --git a/linux-user/signal.c b/linux-user/signal.c index 95e2ffa..67c2311 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -607,28 +607,22 @@ int do_sigaction(int sig, const struct target_sigaction *act, sig, act, oact); #endif if (oact) { - oact->_sa_handler = tswapal(k->_sa_handler); -#if defined(TARGET_MIPS) || defined (TARGET_ALPHA) - oact->sa_flags = bswap32(k->sa_flags); -#else - oact->sa_flags = tswapal(k->sa_flags); -#endif + __put_user(k->_sa_handler, &oact->_sa_handler); + __put_user(k->sa_flags, &oact->sa_flags); #if !defined(TARGET_MIPS) - oact->sa_restorer = tswapal(k->sa_restorer); + __put_user(k->sa_restorer, &oact->sa_restorer); #endif + /* Not swapped. */ oact->sa_mask = k->sa_mask; } if (act) { /* FIXME: This is not threadsafe. */ - k->_sa_handler = tswapal(act->_sa_handler); -#if defined(TARGET_MIPS) || defined (TARGET_ALPHA) - k->sa_flags = bswap32(act->sa_flags); -#else - k->sa_flags = tswapal(act->sa_flags); -#endif + __get_user(k->_sa_handler, &act->_sa_handler); + __get_user(k->sa_flags, &act->sa_flags); #if !defined(TARGET_MIPS) - k->sa_restorer = tswapal(act->sa_restorer); + __get_user(k->sa_restorer, &act->sa_restorer); #endif + /* To be swapped in target_to_host_sigset. */ k->sa_mask = act->sa_mask; /* we update the host linux signal state */ @@ -4584,7 +4578,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, signal = current_exec_domain_sig(sig); - err |= __put_user(h2g(ka->_sa_handler), &sc->handler); + err |= __put_user(ka->_sa_handler, &sc->handler); err |= __put_user(set->sig[0], &sc->oldmask); #if defined(TARGET_PPC64) err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]); @@ -4606,7 +4600,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, /* Create a stack frame for the caller of the handler. */ newsp = frame_addr - SIGNAL_FRAMESIZE; - err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp); + err |= put_user(env->gpr[1], newsp, target_ulong); if (err) goto sigsegv; @@ -4614,7 +4608,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, /* Set up registers for signal handler. */ env->gpr[1] = newsp; env->gpr[3] = signal; - env->gpr[4] = (target_ulong) h2g(sc); + env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx); env->nip = (target_ulong) ka->_sa_handler; /* Signal handlers are entered in big-endian mode. */ env->msr &= ~MSR_LE; diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h index f201f9f..061711c 100644 --- a/linux-user/sparc/syscall_nr.h +++ b/linux-user/sparc/syscall_nr.h @@ -62,8 +62,8 @@ #define TARGET_NR_getpagesize 64 /* Common */ #define TARGET_NR_msync 65 /* Common in newer 1.3.x revs... */ #define TARGET_NR_vfork 66 /* Common */ -#define TARGET_NR_pread 67 /* Linux Specific */ -#define TARGET_NR_pwrite 68 /* Linux Specific */ +#define TARGET_NR_pread64 67 /* Linux Specific */ +#define TARGET_NR_pwrite64 68 /* Linux Specific */ #define TARGET_NR_geteuid32 69 /* Linux sparc32, sbrk under SunOS */ #define TARGET_NR_getegid32 70 /* Linux sparc32, sstk under SunOS */ #define TARGET_NR_mmap 71 /* Common */ diff --git a/linux-user/strace.c b/linux-user/strace.c index 6ec90e8..4e91a6e 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -682,7 +682,7 @@ print_timeval(abi_ulong tv_addr, int last) if (!tv) return; gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}%s", - tv->tv_sec, tv->tv_usec, get_comma(last)); + tswapal(tv->tv_sec), tswapal(tv->tv_usec), get_comma(last)); unlock_user(tv, tv_addr, 0); } else gemu_log("NULL%s", get_comma(last)); diff --git a/linux-user/strace.list b/linux-user/strace.list index af3c6a0..08f115d 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -972,9 +972,6 @@ #ifdef TARGET_NR_prctl { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pread -{ TARGET_NR_pread, "pread" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_pread64 { TARGET_NR_pread64, "pread64" , NULL, NULL, NULL }, #endif @@ -993,9 +990,6 @@ #ifdef TARGET_NR_putpmsg { TARGET_NR_putpmsg, "putpmsg" , NULL, NULL, NULL }, #endif -#ifdef TARGET_NR_pwrite -{ TARGET_NR_pwrite, "pwrite" , NULL, NULL, NULL }, -#endif #ifdef TARGET_NR_pwrite64 { TARGET_NR_pwrite64, "pwrite64" , NULL, NULL, NULL }, #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e4291ed..9e31ea7 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -28,6 +28,7 @@ #include <fcntl.h> #include <time.h> #include <limits.h> +#include <grp.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> @@ -35,6 +36,9 @@ #include <sys/time.h> #include <sys/stat.h> #include <sys/mount.h> +#include <sys/file.h> +#include <sys/fsuid.h> +#include <sys/personality.h> #include <sys/prctl.h> #include <sys/resource.h> #include <sys/mman.h> @@ -72,7 +76,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include <sys/epoll.h> #endif #ifdef CONFIG_ATTR -#include "qemu-xattr.h" +#include "qemu/xattr.h" #endif #define termios host_termios @@ -97,6 +101,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include <linux/fb.h> #include <linux/vt.h> #include <linux/dm-ioctl.h> +#include <linux/reboot.h> #include "linux_loop.h" #include "cpu-uname.h" @@ -580,12 +585,6 @@ _syscall4(int, sys_prlimit64, pid_t, pid, int, resource, struct host_rlimit64 *, old_limit) #endif -extern int personality(int); -extern int flock(int, int); -extern int setfsuid(int); -extern int setfsgid(int); -extern int setgroups(int, gid_t *); - /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */ #ifdef TARGET_ARM static inline int regpairs_aligned(void *cpu_env) { @@ -1491,6 +1490,28 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, break; case TARGET_SOL_SOCKET: switch (optname) { + case TARGET_SO_RCVTIMEO: + { + struct timeval tv; + + optname = SO_RCVTIMEO; + +set_timeout: + if (optlen != sizeof(struct target_timeval)) { + return -TARGET_EINVAL; + } + + if (copy_from_user_timeval(&tv, optval_addr)) { + return -TARGET_EFAULT; + } + + ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, + &tv, sizeof(tv))); + return ret; + } + case TARGET_SO_SNDTIMEO: + optname = SO_SNDTIMEO; + goto set_timeout; /* Options with 'int' argument. */ case TARGET_SO_DEBUG: optname = SO_DEBUG; @@ -1542,12 +1563,6 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, case TARGET_SO_RCVLOWAT: optname = SO_RCVLOWAT; break; - case TARGET_SO_RCVTIMEO: - optname = SO_RCVTIMEO; - break; - case TARGET_SO_SNDTIMEO: - optname = SO_SNDTIMEO; - break; break; default: goto unimplemented; @@ -2899,7 +2914,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, return -TARGET_EFAULT; host_mb = g_malloc(msgsz+sizeof(long)); - ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg)); + ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg)); if (ret > 0) { abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); @@ -3191,7 +3206,7 @@ static abi_long do_ipc(unsigned int call, int first, break; } - ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third); + ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third); unlock_user_struct(tmp, ptr, 0); break; @@ -4514,6 +4529,16 @@ static int target_to_host_fcntl_cmd(int cmd) return -TARGET_EINVAL; } +#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a } +static const bitmask_transtbl flock_tbl[] = { + TRANSTBL_CONVERT(F_RDLCK), + TRANSTBL_CONVERT(F_WRLCK), + TRANSTBL_CONVERT(F_UNLCK), + TRANSTBL_CONVERT(F_EXLCK), + TRANSTBL_CONVERT(F_SHLCK), + { 0, 0, 0, 0 } +}; + static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) { struct flock fl; @@ -4530,7 +4555,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) case TARGET_F_GETLK: if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1)) return -TARGET_EFAULT; - fl.l_type = tswap16(target_fl->l_type); + fl.l_type = + target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl); fl.l_whence = tswap16(target_fl->l_whence); fl.l_start = tswapal(target_fl->l_start); fl.l_len = tswapal(target_fl->l_len); @@ -4540,7 +4566,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) if (ret == 0) { if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0)) return -TARGET_EFAULT; - target_fl->l_type = tswap16(fl.l_type); + target_fl->l_type = + host_to_target_bitmask(tswap16(fl.l_type), flock_tbl); target_fl->l_whence = tswap16(fl.l_whence); target_fl->l_start = tswapal(fl.l_start); target_fl->l_len = tswapal(fl.l_len); @@ -4553,7 +4580,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) case TARGET_F_SETLKW: if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1)) return -TARGET_EFAULT; - fl.l_type = tswap16(target_fl->l_type); + fl.l_type = + target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl); fl.l_whence = tswap16(target_fl->l_whence); fl.l_start = tswapal(target_fl->l_start); fl.l_len = tswapal(target_fl->l_len); @@ -4565,7 +4593,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) case TARGET_F_GETLK64: if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1)) return -TARGET_EFAULT; - fl64.l_type = tswap16(target_fl64->l_type) >> 1; + fl64.l_type = + target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1; fl64.l_whence = tswap16(target_fl64->l_whence); fl64.l_start = tswap64(target_fl64->l_start); fl64.l_len = tswap64(target_fl64->l_len); @@ -4575,7 +4604,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) if (ret == 0) { if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0)) return -TARGET_EFAULT; - target_fl64->l_type = tswap16(fl64.l_type) >> 1; + target_fl64->l_type = + host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1; target_fl64->l_whence = tswap16(fl64.l_whence); target_fl64->l_start = tswap64(fl64.l_start); target_fl64->l_len = tswap64(fl64.l_len); @@ -4587,7 +4617,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) case TARGET_F_SETLKW64: if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1)) return -TARGET_EFAULT; - fl64.l_type = tswap16(target_fl64->l_type) >> 1; + fl64.l_type = + target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1; fl64.l_whence = tswap16(target_fl64->l_whence); fl64.l_start = tswap64(target_fl64->l_start); fl64.l_len = tswap64(target_fl64->l_len); @@ -5188,7 +5219,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, NULL, NULL, 0); } thread_env = NULL; - object_delete(OBJECT(ENV_GET_CPU(cpu_env))); + object_unref(OBJECT(ENV_GET_CPU(cpu_env))); g_free(ts); pthread_exit(NULL); } @@ -6213,8 +6244,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(settimeofday(&tv, NULL)); } break; -#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390) +#if defined(TARGET_NR_select) case TARGET_NR_select: +#if defined(TARGET_S390X) || defined(TARGET_ALPHA) + ret = do_select(arg1, arg2, arg3, arg4, arg5); +#else { struct target_sel_arg_struct *sel; abi_ulong inp, outp, exp, tvp; @@ -6230,6 +6264,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user_struct(sel, arg1, 0); ret = do_select(nsel, inp, outp, exp, tvp); } +#endif break; #endif #ifdef TARGET_NR_pselect6 @@ -6417,10 +6452,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif case TARGET_NR_reboot: - if (!(p = lock_user_string(arg4))) - goto efault; - ret = reboot(arg1, arg2, arg3, p); - unlock_user(p, arg4, 0); + if (arg3 == LINUX_REBOOT_CMD_RESTART2) { + /* arg4 must be ignored in all other cases */ + p = lock_user_string(arg4); + if (!p) { + goto efault; + } + ret = get_errno(reboot(arg1, arg2, arg3, p)); + unlock_user(p, arg4, 0); + } else { + ret = get_errno(reboot(arg1, arg2, arg3, NULL)); + } break; #ifdef TARGET_NR_readdir case TARGET_NR_readdir: @@ -7153,12 +7195,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; #endif /* TARGET_NR_getdents64 */ -#if defined(TARGET_NR__newselect) || defined(TARGET_S390X) -#ifdef TARGET_S390X - case TARGET_NR_select: -#else +#if defined(TARGET_NR__newselect) case TARGET_NR__newselect: -#endif ret = do_select(arg1, arg2, arg3, arg4, arg5); break; #endif @@ -7449,24 +7487,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto unimplemented; #endif #endif -#ifdef TARGET_NR_pread - case TARGET_NR_pread: - if (regpairs_aligned(cpu_env)) - arg4 = arg5; - if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) - goto efault; - ret = get_errno(pread(arg1, p, arg3, arg4)); - unlock_user(p, arg2, ret); - break; - case TARGET_NR_pwrite: - if (regpairs_aligned(cpu_env)) - arg4 = arg5; - if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) - goto efault; - ret = get_errno(pwrite(arg1, p, arg3, arg4)); - unlock_user(p, arg2, 0); - break; -#endif #ifdef TARGET_NR_pread64 case TARGET_NR_pread64: if (regpairs_aligned(cpu_env)) { diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index a98cbf7..92c01a9 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -4,6 +4,10 @@ most of them stay the same, so we handle it by putting ifdefs if necessary */ +#ifndef SYSCALL_DEFS_H +#define SYSCALL_DEFS_H 1 + + #include "syscall_nr.h" #define SOCKOP_socket 1 @@ -540,7 +544,7 @@ int do_sigaction(int sig, const struct target_sigaction *act, struct target_old_sigaction { abi_ulong _sa_handler; abi_ulong sa_mask; - abi_ulong sa_flags; + int32_t sa_flags; }; struct target_rt_sigaction { @@ -2013,6 +2017,12 @@ struct target_statfs64 { #define TARGET_F_SETLKW 9 #define TARGET_F_SETOWN 5 /* for sockets. */ #define TARGET_F_GETOWN 6 /* for sockets. */ + +#define TARGET_F_RDLCK 1 +#define TARGET_F_WRLCK 2 +#define TARGET_F_UNLCK 8 +#define TARGET_F_EXLCK 16 +#define TARGET_F_SHLCK 32 #elif defined(TARGET_MIPS) #define TARGET_F_GETLK 14 #define TARGET_F_SETLK 6 @@ -2027,6 +2037,18 @@ struct target_statfs64 { #define TARGET_F_GETOWN 9 /* for sockets. */ #endif +#ifndef TARGET_F_RDLCK +#define TARGET_F_RDLCK 0 +#define TARGET_F_WRLCK 1 +#define TARGET_F_UNLCK 2 +#endif + +#ifndef TARGET_F_EXLCK +#define TARGET_F_EXLCK 4 +#define TARGET_F_SHLCK 8 +#endif + + #define TARGET_F_SETSIG 10 /* for sockets. */ #define TARGET_F_GETSIG 11 /* for sockets. */ @@ -2425,3 +2447,5 @@ struct target_ucred { uint32_t uid; uint32_t gid; }; + +#endif diff --git a/linux-user/unicore32/syscall_nr.h b/linux-user/unicore32/syscall_nr.h index 9c72d84..486b8c4 100644 --- a/linux-user/unicore32/syscall_nr.h +++ b/linux-user/unicore32/syscall_nr.h @@ -187,8 +187,8 @@ #define TARGET_NR_rt_sigtimedwait 177 #define TARGET_NR_rt_sigqueueinfo 178 #define TARGET_NR_rt_sigsuspend 179 -#define TARGET_NR_pread 180 -#define TARGET_NR_pwrite 181 +#define TARGET_NR_pread64 180 +#define TARGET_NR_pwrite64 181 #define TARGET_NR_chown 182 #define TARGET_NR_getcwd 183 #define TARGET_NR_capget 184 |