From patchwork Sat Apr 7 18:44:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Blue Swirl X-Patchwork-Id: 151313 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3D2B5B70A1 for ; Sun, 8 Apr 2012 04:44:58 +1000 (EST) Received: from localhost ([::1]:57913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SGad4-0001BA-U7 for incoming@patchwork.ozlabs.org; Sat, 07 Apr 2012 14:44:54 -0400 Received: from eggs.gnu.org ([208.118.235.92]:59312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SGacw-0001Aa-Ds for qemu-devel@nongnu.org; Sat, 07 Apr 2012 14:44:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SGact-0004nw-VR for qemu-devel@nongnu.org; Sat, 07 Apr 2012 14:44:45 -0400 Received: from mail-iy0-f173.google.com ([209.85.210.173]:61549) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SGact-0004np-M8 for qemu-devel@nongnu.org; Sat, 07 Apr 2012 14:44:43 -0400 Received: by iafj26 with SMTP id j26so5196077iaf.4 for ; Sat, 07 Apr 2012 11:44:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:content-type; bh=mq+mVPEAS1I4ayZwNiKxUhfauWxhNJf8FWUYgLVHkS4=; b=FM8Uqe4/Kusfz01CeFo3Q+fE4hqV7h84eXix07oW03T3oj5d8mhJdjtkcAz+KXJCyZ iuQ9D+G6OixY71N6x+WtLJgQoj4BlVVD+MP9g0ggoHCwN0cHTXjYUcwRLRt+6bfG10Lf Q45whHCWl1J3fXwPdtT7JqB4f69/qXKigkLxUNF5jPn6TzCIcVztEzxAjhm/shF4CNl/ YjO7fH+h3LucMLt6FYXMqWpdNIDQT2ozOoDh+BDJDNv5ecrB6ekYUYjt0IZ3whSgbMhj UgVOYyzxWS3MASBr0HYU3MwQilcckxURLgJEDZq7pFe2Mh3HGErfxvL7WM7rSMh79sty qkdQ== Received: by 10.50.212.97 with SMTP id nj1mr1454799igc.65.1333824281702; Sat, 07 Apr 2012 11:44:41 -0700 (PDT) MIME-Version: 1.0 Received: by 10.50.197.194 with HTTP; Sat, 7 Apr 2012 11:44:21 -0700 (PDT) From: Blue Swirl Date: Sat, 7 Apr 2012 18:44:21 +0000 Message-ID: To: qemu-devel X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.210.173 Subject: [Qemu-devel] [PATCH, RFC] x32-linux-user: initial commit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add experimental support for x32 (x86_64 CPU, 32 bit ABI) user emulator. Signed-off-by: Blue Swirl --- A hand constructed (possibly incorrect) helloworld program prints the greeting but crashes. /src/qemu/obj-amd64/x32-linux-user/qemu-x32 -strace -d in_asm,op,out_asm helloworld_x86_x32 ERROR: ioctl(BLKGETSIZE64): target=0x80041272 host=0x80081272 ERROR: ioctl(BLKBSZGET): target=0x80041270 host=0x80081270 ERROR: ioctl(SNDCTL_DSP_MAPINBUF): target=0x80085013 host=0x80105013 ERROR: ioctl(SNDCTL_DSP_MAPOUTBUF): target=0x80085014 host=0x80105014 ERROR: ioctl(VFAT_IOCTL_READDIR_BOTH): target=0x82187201 host=0x82307201 ERROR: ioctl(VFAT_IOCTL_READDIR_SHORT): target=0x82187202 host=0x82307202 19617 stat(0x00000002,0x080480b7) = -1 errno=14 (Bad address) 19617 write(0,0x80480b7,13)Hello World! = 13 qemu: uncaught target signal 11 (Segmentation fault) - core dumped Segmentation fault $ file helloworld_x86_x32 helloworld_x86_x32: ELF 32-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped --- configure | 11 ++++++++++- default-configs/x32-linux-user.mak | 1 + linux-user/elfload.c | 8 ++++++++ linux-user/main.c | 8 ++++---- linux-user/signal.c | 2 +- linux-user/syscall.c | 2 +- qemu-tech.texi | 2 ++ 7 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 default-configs/x32-linux-user.mak From da26c80e168c3e1159542415f9df73ddae28de7f Mon Sep 17 00:00:00 2001 Message-Id: From: Blue Swirl Date: Sat, 7 Apr 2012 18:34:04 +0000 Subject: [PATCH] x32-linux-user: initial commit Add experimental support for x32 (x86_64 CPU, 32 bit ABI) user emulator. Signed-off-by: Blue Swirl --- configure | 11 ++++++++++- default-configs/x32-linux-user.mak | 1 + linux-user/elfload.c | 8 ++++++++ linux-user/main.c | 8 ++++---- linux-user/signal.c | 2 +- linux-user/syscall.c | 2 +- qemu-tech.texi | 2 ++ 7 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 default-configs/x32-linux-user.mak diff --git a/configure b/configure index 671b232..3cb29cd 100755 --- a/configure +++ b/configure @@ -942,6 +942,7 @@ if [ "$linux_user" = "yes" ] ; then default_target_list="${default_target_list}\ i386-linux-user \ x86_64-linux-user \ +x32-linux-user \ alpha-linux-user \ arm-linux-user \ armeb-linux-user \ @@ -3497,6 +3498,14 @@ case "$target_arch2" in target_phys_bits=64 target_long_alignment=8 ;; + x32) + TARGET_ARCH=x86_64 + TARGET_BASE_ARCH=i386 + TARGET_ABI_DIR=x86_64 + echo "TARGET_ABI32=y" >> $config_target_mak + target_phys_bits=64 + target_long_alignment=8 # ??? Not specified in x32-abi + ;; alpha) target_phys_bits=64 target_long_alignment=8 @@ -3770,7 +3779,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_HPPA_DIS=y" >> $config_target_mak echo "CONFIG_HPPA_DIS=y" >> $libdis_config_mak ;; - i386|x86_64) + i386|x86_64|x32) echo "CONFIG_I386_DIS=y" >> $config_target_mak echo "CONFIG_I386_DIS=y" >> $libdis_config_mak ;; diff --git a/default-configs/x32-linux-user.mak b/default-configs/x32-linux-user.mak new file mode 100644 index 0000000..44c5e23 --- /dev/null +++ b/default-configs/x32-linux-user.mak @@ -0,0 +1 @@ +# Default configuration for x32-linux-user diff --git a/linux-user/elfload.c b/linux-user/elfload.c index f3b1552..d4c0c34 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -134,10 +134,18 @@ static uint32_t get_elf_hwcap(void) } #ifdef TARGET_X86_64 +#ifdef TARGET_ABI32 +#define ELF_START_MMAP 0x80000000 +/* ??? */ +#define elf_check_arch(x) (((x) == ELF_ARCH)) + +#define ELF_CLASS ELFCLASS32 +#else #define ELF_START_MMAP 0x2aaaaab000ULL #define elf_check_arch(x) ( ((x) == ELF_ARCH) ) #define ELF_CLASS ELFCLASS64 +#endif #define ELF_ARCH EM_X86_64 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) diff --git a/linux-user/main.c b/linux-user/main.c index 191b750..fc45371 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -282,7 +282,7 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit, } static uint64_t *idt_table; -#ifdef TARGET_X86_64 +#if defined(TARGET_X86_64) && !defined(TARGET_ABI32) static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, uint64_t addr, unsigned int sel) { @@ -3577,7 +3577,7 @@ int main(int argc, char **argv, char **envp) env->eflags |= IF_MASK; /* linux register setup */ -#ifndef TARGET_ABI32 +#ifdef TARGET_X86_64 env->regs[R_EAX] = regs->rax; env->regs[R_EBX] = regs->rbx; env->regs[R_ECX] = regs->rcx; @@ -3639,7 +3639,7 @@ int main(int argc, char **argv, char **envp) MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; gdt_table = g2h(env->gdt.base); -#ifdef TARGET_ABI32 +#ifdef TARGET_X86_64 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); @@ -3656,7 +3656,7 @@ int main(int argc, char **argv, char **envp) } cpu_x86_load_seg(env, R_CS, __USER_CS); cpu_x86_load_seg(env, R_SS, __USER_DS); -#ifdef TARGET_ABI32 +#ifdef TARGET_X86_64 cpu_x86_load_seg(env, R_DS, __USER_DS); cpu_x86_load_seg(env, R_ES, __USER_DS); cpu_x86_load_seg(env, R_FS, __USER_DS); diff --git a/linux-user/signal.c b/linux-user/signal.c index b1e139d..a75affb 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -649,7 +649,7 @@ static inline int current_exec_domain_sig(int sig) && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig; } -#if defined(TARGET_I386) && TARGET_ABI_BITS == 32 +#if defined(TARGET_I386) && !defined(TARGET_X86_64) /* from the Linux kernel */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8a92162..c079448 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7935,7 +7935,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(0); break; #endif -#if TARGET_ABI_BITS == 32 +#if TARGET_ABI_BITS == 32 && !defined(TARGET_X86_64) /* ??? */ case TARGET_NR_fcntl64: { int cmd; diff --git a/qemu-tech.texi b/qemu-tech.texi index 5676fb7..67663e3 100644 --- a/qemu-tech.texi +++ b/qemu-tech.texi @@ -168,6 +168,8 @@ Current QEMU limitations: @item Limited x86-64 support. +@item Experimental x32 user (x86-64 CPU, 32 bit ABI) emulator support. + @item IPC syscalls are missing. @item The x86 segment limits and access rights are not tested at every -- 1.7.2.5