From patchwork Thu Jun 16 06:14:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khansa Butt X-Patchwork-Id: 100590 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9E0C0B6F90 for ; Thu, 16 Jun 2011 16:17:02 +1000 (EST) Received: from localhost ([::1]:40308 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QX5sv-000384-Oh for incoming@patchwork.ozlabs.org; Thu, 16 Jun 2011 02:16:57 -0400 Received: from eggs.gnu.org ([140.186.70.92]:52277) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QX5qM-00037U-91 for qemu-devel@nongnu.org; Thu, 16 Jun 2011 02:14:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QX5qJ-00007i-UK for qemu-devel@nongnu.org; Thu, 16 Jun 2011 02:14:18 -0400 Received: from mail-fx0-f45.google.com ([209.85.161.45]:52136) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QX5qJ-00007D-Gd for qemu-devel@nongnu.org; Thu, 16 Jun 2011 02:14:15 -0400 Received: by fxm2 with SMTP id 2so1012853fxm.4 for ; Wed, 15 Jun 2011 23:14:12 -0700 (PDT) MIME-Version: 1.0 Received: by 10.223.143.20 with SMTP id s20mr614762fau.10.1308204852641; Wed, 15 Jun 2011 23:14:12 -0700 (PDT) Received: by 10.223.111.142 with HTTP; Wed, 15 Jun 2011 23:14:12 -0700 (PDT) In-Reply-To: <20110429090156.GA20604@volta.aurel32.net> References: <20110412213219.GA19996@volta.aurel32.net> <20110429090156.GA20604@volta.aurel32.net> Date: Thu, 16 Jun 2011 11:14:12 +0500 Message-ID: From: Khansa Butt To: Aurelien Jarno , Riku Voipio X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.161.45 Cc: qemu-devel@nongnu.org Subject: Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 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 This is the case for 64 bit guest user mode static binary on 32 bit host. Dynamically linked binary has not this problem see in elfload.c:load_elf_image() for (i = 0; i < ehdr->e_phnum; ++i) { if(phdr[i].p_type == PT_INTERP) dyn_link = 1; if (phdr[i].p_type == PT_LOAD) { abi_ulong a = phdr[i].p_vaddr; if (a < loaddr) { loaddr = a; } a += phdr[i].p_memsz; if (a > hiaddr) { hiaddr = a; } #ifdef CONFIG_USE_FDPIC ++info->nsegs; #endif } } load_addr = loaddr; at this point load_addr has 64 bit value. if (!have_guest_base && !reserved_va) { unsigned long host_start, real_start, host_size; /* Round addresses to page boundaries. */ loaddr &= qemu_host_page_mask; hiaddr = HOST_PAGE_ALIGN(hiaddr); because of above loaddr is rounded to 32 bit value and load_bias = load_addr - loaddr; now load_addr has a big value which is added to entry point address which causes problem. for my MIPS64 bit statically linked ELF the variables loaddr and hiaddr have 36 bit values. for probing guest_base these values are rounded to 32 bit as my underlying OS is 32 bit Fedore13 because of this load_bais has value = 0x100000000 this load_bias is then added to entry point address and mem and file size of the segment. and the addresses which are starting from 0x120000000 are now changed to 0x220000000. because of this when lladdr comes to SCD instruction in do_store_exclusive() it does not get valid l1_map entry. and because of which we made a fake page which was not correct way to do although it was working. so we did another workaround as follows linux-user/elfload.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) /* First of all, some simple consistency checks */ @@ -1341,6 +1341,8 @@ static void load_elf_image(const char *image_name, int image_fd, amount of memory to handle that. */ loaddr = -1, hiaddr = 0; for (i = 0; i < ehdr->e_phnum; ++i) { + if(phdr[i].p_type == PT_INTERP) /* Is the ELF dynamically linked? + dyn_link = 1; if (phdr[i].p_type == PT_LOAD) { abi_ulong a = phdr[i].p_vaddr; if (a < loaddr) { @@ -1395,6 +1397,8 @@ static void load_elf_image(const char *image_name, int image_fd, } } host_size = hiaddr - loaddr; + if (!dyn_link) + /* ELF is statically linked */ + load_addr = loaddr; while (1) { /* Do not use mmap_find_vma here because that is limited to the guest address space. We are going to make the diff --git a/linux-user/elfload.c b/linux-user/elfload.c index dcfeb7a..9ab3296 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1307,7 +1307,7 @@ static void load_elf_image(const char *image_name, int image_fd, struct elfhdr *ehdr = (struct elfhdr *)bprm_buf; struct elf_phdr *phdr; abi_ulong load_addr, load_bias, loaddr, hiaddr, error; - int i, retval; + int i, retval, dyn_link; const char *errmsg;