diff options
-rw-r--r-- | docs/user/main.rst | 61 | ||||
-rw-r--r-- | linux-user/alpha/target_fcntl.h | 1 | ||||
-rw-r--r-- | linux-user/alpha/target_signal.h | 6 | ||||
-rw-r--r-- | linux-user/elfload.c | 30 | ||||
-rw-r--r-- | linux-user/generic/signal.h | 6 | ||||
-rw-r--r-- | linux-user/generic/sockbits.h | 3 | ||||
-rw-r--r-- | linux-user/hppa/target_fcntl.h | 4 | ||||
-rw-r--r-- | linux-user/hppa/target_signal.h | 5 | ||||
-rw-r--r-- | linux-user/mips/sockbits.h | 2 | ||||
-rw-r--r-- | linux-user/mips/target_signal.h | 6 | ||||
-rw-r--r-- | linux-user/mips64/syscall_nr.h | 5 | ||||
-rw-r--r-- | linux-user/mips64/target_elf.h | 3 | ||||
-rw-r--r-- | linux-user/mips64/target_signal.h | 9 | ||||
-rw-r--r-- | linux-user/mmap.c | 4 | ||||
-rw-r--r-- | linux-user/signal.c | 3 | ||||
-rw-r--r-- | linux-user/sparc/target_signal.h | 6 | ||||
-rw-r--r-- | linux-user/syscall.c | 18 |
17 files changed, 93 insertions, 79 deletions
diff --git a/docs/user/main.rst b/docs/user/main.rst index 8dfe232a3a..e08d4be63b 100644 --- a/docs/user/main.rst +++ b/docs/user/main.rst @@ -45,67 +45,6 @@ emulator. Linux User space emulator ------------------------- -Quick Start -~~~~~~~~~~~ - -In order to launch a Linux process, QEMU needs the process executable -itself and all the target (x86) dynamic libraries used by it. - -- On x86, you can just try to launch any process by using the native - libraries:: - - qemu-i386 -L / /bin/ls - - ``-L /`` tells that the x86 dynamic linker must be searched with a - ``/`` prefix. - -- Since QEMU is also a linux process, you can launch QEMU with QEMU - (NOTE: you can only do that if you compiled QEMU from the sources):: - - qemu-i386 -L / qemu-i386 -L / /bin/ls - -- On non x86 CPUs, you need first to download at least an x86 glibc - (``qemu-runtime-i386-XXX-.tar.gz`` on the QEMU web page). Ensure that - ``LD_LIBRARY_PATH`` is not set:: - - unset LD_LIBRARY_PATH - - Then you can launch the precompiled ``ls`` x86 executable:: - - qemu-i386 tests/i386/ls - - You can look at ``scripts/qemu-binfmt-conf.sh`` so that QEMU is - automatically launched by the Linux kernel when you try to launch x86 - executables. It requires the ``binfmt_misc`` module in the Linux - kernel. - -- The x86 version of QEMU is also included. You can try weird things - such as:: - - qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 \ - /usr/local/qemu-i386/bin/ls-i386 - -Wine launch -~~~~~~~~~~~ - -- Ensure that you have a working QEMU with the x86 glibc distribution - (see previous section). In order to verify it, you must be able to - do:: - - qemu-i386 /usr/local/qemu-i386/bin/ls-i386 - -- Download the binary x86 Wine install (``qemu-XXX-i386-wine.tar.gz`` - on the QEMU web page). - -- Configure Wine on your account. Look at the provided script - ``/usr/local/qemu-i386/bin/wine-conf.sh``. Your previous - ``${HOME}/.wine`` directory is saved to ``${HOME}/.wine.org``. - -- Then you can try the example ``putty.exe``:: - - qemu-i386 /usr/local/qemu-i386/wine/bin/wine \ - /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe - Command line options ~~~~~~~~~~~~~~~~~~~~ diff --git a/linux-user/alpha/target_fcntl.h b/linux-user/alpha/target_fcntl.h index e16ed1d415..99774d7317 100644 --- a/linux-user/alpha/target_fcntl.h +++ b/linux-user/alpha/target_fcntl.h @@ -23,6 +23,7 @@ #define TARGET_O_CLOEXEC 010000000 #define TARGET___O_SYNC 020000000 #define TARGET_O_PATH 040000000 +#define TARGET___O_TMPFILE 0100000000 #define TARGET_F_GETLK 7 #define TARGET_F_SETLK 8 diff --git a/linux-user/alpha/target_signal.h b/linux-user/alpha/target_signal.h index b83797281c..0b90d3a897 100644 --- a/linux-user/alpha/target_signal.h +++ b/linux-user/alpha/target_signal.h @@ -92,4 +92,10 @@ typedef struct target_sigaltstack { #define TARGET_GEN_SUBRNG7 -25 #define TARGET_ARCH_HAS_SETUP_FRAME + +/* bit-flags */ +#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */ +/* mask for all SS_xxx flags */ +#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM + #endif /* ALPHA_TARGET_SIGNAL_H */ diff --git a/linux-user/elfload.c b/linux-user/elfload.c index a64050713f..f5bd4076fc 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2805,14 +2805,16 @@ static void load_elf_image(const char *image_name, int image_fd, vaddr = load_bias + eppnt->p_vaddr; vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); vaddr_ps = TARGET_ELF_PAGESTART(vaddr); - vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_filesz + vaddr_po); + + vaddr_ef = vaddr + eppnt->p_filesz; + vaddr_em = vaddr + eppnt->p_memsz; /* - * Some segments may be completely empty without any backing file - * segment, in that case just let zero_bss allocate an empty buffer - * for it. + * Some segments may be completely empty, with a non-zero p_memsz + * but no backing file segment. */ if (eppnt->p_filesz != 0) { + vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_filesz + vaddr_po); error = target_mmap(vaddr_ps, vaddr_len, elf_prot, MAP_PRIVATE | MAP_FIXED, image_fd, eppnt->p_offset - vaddr_po); @@ -2820,14 +2822,22 @@ static void load_elf_image(const char *image_name, int image_fd, if (error == -1) { goto exit_mmap; } - } - vaddr_ef = vaddr + eppnt->p_filesz; - vaddr_em = vaddr + eppnt->p_memsz; + /* + * If the load segment requests extra zeros (e.g. bss), map it. + */ + if (eppnt->p_filesz < eppnt->p_memsz) { + zero_bss(vaddr_ef, vaddr_em, elf_prot); + } + } else if (eppnt->p_memsz != 0) { + vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_memsz + vaddr_po); + error = target_mmap(vaddr_ps, vaddr_len, elf_prot, + MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, + -1, 0); - /* If the load segment requests extra zeros (e.g. bss), map it. */ - if (vaddr_ef < vaddr_em) { - zero_bss(vaddr_ef, vaddr_em, elf_prot); + if (error == -1) { + goto exit_mmap; + } } /* Find the full program boundaries. */ diff --git a/linux-user/generic/signal.h b/linux-user/generic/signal.h index e1083f8fba..943bc1a1e2 100644 --- a/linux-user/generic/signal.h +++ b/linux-user/generic/signal.h @@ -54,4 +54,10 @@ #define TARGET_SIG_BLOCK 0 /* for blocking signals */ #define TARGET_SIG_UNBLOCK 1 /* for unblocking signals */ #define TARGET_SIG_SETMASK 2 /* for setting the signal mask */ + +/* bit-flags */ +#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */ +/* mask for all SS_xxx flags */ +#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM + #endif diff --git a/linux-user/generic/sockbits.h b/linux-user/generic/sockbits.h index e44733c601..b3b4a8e44c 100644 --- a/linux-user/generic/sockbits.h +++ b/linux-user/generic/sockbits.h @@ -55,4 +55,7 @@ #define TARGET_SO_ACCEPTCONN 30 #define TARGET_SO_PEERSEC 31 + +#define TARGET_SO_PROTOCOL 38 +#define TARGET_SO_DOMAIN 39 #endif diff --git a/linux-user/hppa/target_fcntl.h b/linux-user/hppa/target_fcntl.h index bd966a59b8..4eb0ec98e2 100644 --- a/linux-user/hppa/target_fcntl.h +++ b/linux-user/hppa/target_fcntl.h @@ -8,7 +8,8 @@ #ifndef HPPA_TARGET_FCNTL_H #define HPPA_TARGET_FCNTL_H -#define TARGET_O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ +#define TARGET_O_NONBLOCK 000200000 +#define TARGET_O_NONBLOCK_MASK 000200004 /* includes old HP-UX NDELAY flag */ #define TARGET_O_APPEND 000000010 #define TARGET_O_CREAT 000000400 /* not fcntl */ #define TARGET_O_EXCL 000002000 /* not fcntl */ @@ -21,6 +22,7 @@ #define TARGET_O_CLOEXEC 010000000 #define TARGET___O_SYNC 000100000 #define TARGET_O_PATH 020000000 +#define TARGET___O_TMPFILE 040000000 #define TARGET_F_RDLCK 1 #define TARGET_F_WRLCK 2 diff --git a/linux-user/hppa/target_signal.h b/linux-user/hppa/target_signal.h index c52a3ea579..7f525362e9 100644 --- a/linux-user/hppa/target_signal.h +++ b/linux-user/hppa/target_signal.h @@ -66,4 +66,9 @@ typedef struct target_sigaltstack { #define TARGET_MINSIGSTKSZ 2048 #define TARGET_SIGSTKSZ 8192 +/* bit-flags */ +#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */ +/* mask for all SS_xxx flags */ +#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM + #endif /* HPPA_TARGET_SIGNAL_H */ diff --git a/linux-user/mips/sockbits.h b/linux-user/mips/sockbits.h index 0f022cd598..562cad88e2 100644 --- a/linux-user/mips/sockbits.h +++ b/linux-user/mips/sockbits.h @@ -40,6 +40,8 @@ #define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ #define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ #define TARGET_SO_ACCEPTCONN 0x1009 +#define TARGET_SO_PROTOCOL 0x1028 /* protocol type */ +#define TARGET_SO_DOMAIN 0x1029 /* domain/socket family */ /* linux-specific, might as well be the same as on i386 */ #define TARGET_SO_NO_CHECK 11 diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h index fa4084a99d..d521765f6b 100644 --- a/linux-user/mips/target_signal.h +++ b/linux-user/mips/target_signal.h @@ -73,4 +73,10 @@ typedef struct target_sigaltstack { /* compare linux/arch/mips/kernel/signal.c:setup_frame() */ #define TARGET_ARCH_HAS_SETUP_FRAME #endif + +/* bit-flags */ +#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */ +/* mask for all SS_xxx flags */ +#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM + #endif /* MIPS_TARGET_SIGNAL_H */ diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h index 672f2fa51c..6579421fa6 100644 --- a/linux-user/mips64/syscall_nr.h +++ b/linux-user/mips64/syscall_nr.h @@ -1,4 +1,7 @@ -#ifdef TARGET_ABI_MIPSN32 +#if defined(TARGET_ABI_MIPSO32) +#define TARGET_SYSCALL_OFFSET 4000 +#include "syscall_o32_nr.h" +#elif defined(TARGET_ABI_MIPSN32) #define TARGET_SYSCALL_OFFSET 6000 #include "syscall_n32_nr.h" #else diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h index ec55d8542a..5f2f2df29f 100644 --- a/linux-user/mips64/target_elf.h +++ b/linux-user/mips64/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) { return "I6400"; } + if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { + return "R5900"; + } return "5KEf"; } #endif diff --git a/linux-user/mips64/target_signal.h b/linux-user/mips64/target_signal.h index 799f7a668c..d857c55e4c 100644 --- a/linux-user/mips64/target_signal.h +++ b/linux-user/mips64/target_signal.h @@ -67,4 +67,13 @@ typedef struct target_sigaltstack { #define TARGET_MINSIGSTKSZ 2048 #define TARGET_SIGSTKSZ 8192 +/* bit-flags */ +#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */ +/* mask for all SS_xxx flags */ +#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM + +#if defined(TARGET_ABI_MIPSO32) +/* compare linux/arch/mips/kernel/signal.c:setup_frame() */ +#define TARGET_ARCH_HAS_SETUP_FRAME +#endif #endif /* MIPS64_TARGET_SIGNAL_H */ diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 810653c503..1c9faef476 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -724,7 +724,9 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, if (!guest_range_valid(old_addr, old_size) || ((flags & MREMAP_FIXED) && - !guest_range_valid(new_addr, new_size))) { + !guest_range_valid(new_addr, new_size)) || + ((flags & MREMAP_MAYMOVE) == 0 && + !guest_range_valid(old_addr, new_size))) { errno = ENOMEM; return -1; } diff --git a/linux-user/signal.c b/linux-user/signal.c index 73de934c65..7eecec46c4 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -349,8 +349,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, case TARGET_SIGCHLD: tinfo->_sifields._sigchld._pid = info->si_pid; tinfo->_sifields._sigchld._uid = info->si_uid; - tinfo->_sifields._sigchld._status - = host_to_target_waitstatus(info->si_status); + tinfo->_sifields._sigchld._status = info->si_status; tinfo->_sifields._sigchld._utime = info->si_utime; tinfo->_sifields._sigchld._stime = info->si_stime; si_type = QEMU_SI_CHLD; diff --git a/linux-user/sparc/target_signal.h b/linux-user/sparc/target_signal.h index 1b10d1490f..911a3f5af5 100644 --- a/linux-user/sparc/target_signal.h +++ b/linux-user/sparc/target_signal.h @@ -68,4 +68,10 @@ typedef struct target_sigaltstack { #define TARGET_SIGSTKSZ 16384 #define TARGET_ARCH_HAS_SETUP_FRAME + +/* bit-flags */ +#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */ +/* mask for all SS_xxx flags */ +#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM + #endif /* SPARC_TARGET_SIGNAL_H */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 34760779c8..36b0901055 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -277,6 +277,11 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #define TARGET_NR__llseek TARGET_NR_llseek #endif +/* some platforms need to mask more bits than just TARGET_O_NONBLOCK */ +#ifndef TARGET_O_NONBLOCK_MASK +#define TARGET_O_NONBLOCK_MASK TARGET_O_NONBLOCK +#endif + #define __NR_sys_gettid __NR_gettid _syscall0(int, sys_gettid) @@ -2832,6 +2837,12 @@ get_timeout: case TARGET_SO_ACCEPTCONN: optname = SO_ACCEPTCONN; goto int_case; + case TARGET_SO_PROTOCOL: + optname = SO_PROTOCOL; + goto int_case; + case TARGET_SO_DOMAIN: + optname = SO_DOMAIN; + goto int_case; default: goto int_case; } @@ -4909,6 +4920,7 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, struct ifconf *host_ifconf; uint32_t outbufsz; const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) }; + const argtype ifreq_max_type[] = { MK_STRUCT(STRUCT_ifmap_ifreq) }; int target_ifreq_size; int nb_ifreq; int free_buf = 0; @@ -4932,7 +4944,7 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, host_ifconf = (struct ifconf *)(unsigned long)buf_temp; target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; - target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); + target_ifreq_size = thunk_type_size(ifreq_max_type, 0); if (target_ifc_buf != 0) { target_ifc_len = host_ifconf->ifc_len; @@ -7777,7 +7789,7 @@ static abi_long do_signalfd4(int fd, abi_long mask, int flags) sigset_t host_mask; abi_long ret; - if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) { + if (flags & ~(TARGET_O_NONBLOCK_MASK | TARGET_O_CLOEXEC)) { return -TARGET_EINVAL; } if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) { @@ -12566,7 +12578,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_eventfd2) case TARGET_NR_eventfd2: { - int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)); + int host_flags = arg2 & (~(TARGET_O_NONBLOCK_MASK | TARGET_O_CLOEXEC)); if (arg2 & TARGET_O_NONBLOCK) { host_flags |= O_NONBLOCK; } |