diff options
| author | Blue Swirl <blauwirbel@gmail.com> | 2012-04-07 11:45:25 +0000 |
|---|---|---|
| committer | Blue Swirl <blauwirbel@gmail.com> | 2012-04-07 11:45:25 +0000 |
| commit | adcd61f7fcd5a24e65b2ec087bfae2356805993b (patch) | |
| tree | a74ea7fff914a0237e5190d5c97866bef1b3d21b /linux-user/main.c | |
| parent | 6375e09e79964fa6eac3e8426d25c8b759185482 (diff) | |
| parent | d8fd2954996255ba6ad610917e7849832d0120b7 (diff) | |
| download | focaccia-qemu-adcd61f7fcd5a24e65b2ec087bfae2356805993b.tar.gz focaccia-qemu-adcd61f7fcd5a24e65b2ec087bfae2356805993b.zip | |
Merge branch 'linux-user-for-upstream' of git://git.linaro.org/people/rikuvoipio/qemu
* 'linux-user-for-upstream' of git://git.linaro.org/people/rikuvoipio/qemu: Userspace ARM BE8 support elf.h: Update EF_ARM_ constants to newer ABI versions arm-linux-user: fix elfload.c's AT_HWCAP to reflect cpu features. linux-user/arm/syscall_nr.h: Add syscall number for ppoll linux-user: Add support for prctl PR_GET_NAME and PR_SET_NAME linux-user/syscall.c: Fix indentation in prctl handling linux-user: reserve 4GB of vmem for 32-on-64 linux-user: resolve reserved_va vma downwards linux-user: take RESERVED_VA into account for g2h_valid() linux-user: fix fallocate linux-user: Add ioctl for BLKBSZGET linux-user: add BLKSSZGET ioctl wrapper linux-user: fix BLK ioctl arguments linux-user: add struct old_dev_t compat linux-user: implement device mapper ioctls linux-user: target_argv is placed on ts->bprm->argv and can't be freed() linux-user: improve fake /proc/self/stat making `ps` not segfault.
Diffstat (limited to 'linux-user/main.c')
| -rw-r--r-- | linux-user/main.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index 962677e01d..191b75060d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -33,6 +33,7 @@ #include "tcg.h" #include "qemu-timer.h" #include "envlist.h" +#include "elf.h" #define DEBUG_LOGFILE "/tmp/qemu.log" @@ -48,8 +49,19 @@ unsigned long mmap_min_addr; #if defined(CONFIG_USE_GUEST_BASE) unsigned long guest_base; int have_guest_base; +#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64) +/* + * When running 32-on-64 we should make sure we can fit all of the possible + * guest address space into a contiguous chunk of virtual host memory. + * + * This way we will never overlap with our own libraries or binaries or stack + * or anything else that QEMU maps. + */ +unsigned long reserved_va = 0xf7000000; +#else unsigned long reserved_va; #endif +#endif static void usage(void); @@ -463,6 +475,22 @@ void cpu_loop(CPUX86State *env) #ifdef TARGET_ARM +#define get_user_code_u32(x, gaddr, doswap) \ + ({ abi_long __r = get_user_u32((x), (gaddr)); \ + if (!__r && (doswap)) { \ + (x) = bswap32(x); \ + } \ + __r; \ + }) + +#define get_user_code_u16(x, gaddr, doswap) \ + ({ abi_long __r = get_user_u16((x), (gaddr)); \ + if (!__r && (doswap)) { \ + (x) = bswap16(x); \ + } \ + __r; \ + }) + /* * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt * Input: @@ -696,7 +724,7 @@ void cpu_loop(CPUARMState *env) /* we handle the FPU emulation here, as Linux */ /* we get the opcode */ /* FIXME - what to do if get_user() fails? */ - get_user_u32(opcode, env->regs[15]); + get_user_code_u32(opcode, env->regs[15], env->bswap_code); rc = EmulateAll(opcode, &ts->fpa, env); if (rc == 0) { /* illegal instruction */ @@ -766,23 +794,25 @@ void cpu_loop(CPUARMState *env) if (trapnr == EXCP_BKPT) { if (env->thumb) { /* FIXME - what to do if get_user() fails? */ - get_user_u16(insn, env->regs[15]); + get_user_code_u16(insn, env->regs[15], env->bswap_code); n = insn & 0xff; env->regs[15] += 2; } else { /* FIXME - what to do if get_user() fails? */ - get_user_u32(insn, env->regs[15]); + get_user_code_u32(insn, env->regs[15], env->bswap_code); n = (insn & 0xf) | ((insn >> 4) & 0xff0); env->regs[15] += 4; } } else { if (env->thumb) { /* FIXME - what to do if get_user() fails? */ - get_user_u16(insn, env->regs[15] - 2); + get_user_code_u16(insn, env->regs[15] - 2, + env->bswap_code); n = insn & 0xff; } else { /* FIXME - what to do if get_user() fails? */ - get_user_u32(insn, env->regs[15] - 4); + get_user_code_u32(insn, env->regs[15] - 4, + env->bswap_code); n = insn & 0xffffff; } } @@ -3420,6 +3450,7 @@ int main(int argc, char **argv, char **envp) guest_base = HOST_PAGE_ALIGN((unsigned long)p); } qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va); + mmap_next_start = reserved_va; } if (reserved_va || have_guest_base) { @@ -3486,11 +3517,6 @@ int main(int argc, char **argv, char **envp) _exit(1); } - for (i = 0; i < target_argc; i++) { - free(target_argv[i]); - } - free(target_argv); - for (wrk = target_environ; *wrk; wrk++) { free(*wrk); } @@ -3650,6 +3676,11 @@ int main(int argc, char **argv, char **envp) for(i = 0; i < 16; i++) { env->regs[i] = regs->uregs[i]; } + /* Enable BE8. */ + if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4 + && (info->elf_flags & EF_ARM_BE8)) { + env->bswap_code = 1; + } } #elif defined(TARGET_UNICORE32) { |