qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] TARGET_PAGE_SIZE > host page size


From: Edgar E. Iglesias
Subject: Re: [Qemu-devel] TARGET_PAGE_SIZE > host page size
Date: Sat, 22 Sep 2007 09:34:25 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

On Fri, Sep 21, 2007 at 04:43:37PM +0100, Paul Brook wrote:
> On Friday 21 September 2007, Edgar E. Iglesias wrote:
> > Hello,
> >
> > I'm working on a new target port and the linux-user emulation is fairly
> > functional and passing quite extensive test-suites.
> >
> > I've got a problem though, my target has 8K page sizes, so for example when
> > running on a x86 host TARGET_PAGE_SIZE > host page size.
> >
> > I'm not very familiar with linux-user/mmap.c, but I though I'd let you know
> > that with this patch things seem to be working fine for me. I am not sure
> > if the patch is correct so if anyone with more experience sees an obvious
> > flaw I'd appreciate to know.
> 
> qemu_host_page_size is always >= TARGET_PAGE_SIZE. See exec.c.
> There are several existing target that have >4k page sizes.

Hi again,

I had a look at this last night and it seems to be a combination of the elf 
loader for linux-user and target_mmap that are causing the problems I am seeing.

target_mmap is (as it is coded now) allowed to return addresses that are not 
aligned to the target page size but it (correctly) does not allow the request 
of fixed mappings for unaligned addresses. IMO things would be simpler if we 
made sure target_mmap always returns target pagesize aligned addresses.

If target_mmap returns a target pagesize unaligned address when the elf loader 
is loading the ELF interpreter, more specifically when mapping the load address 
of the interpreter, subsequent calls for mapping each segment will be made for 
MAP_FIXED areas of the unaligned load_addr + segment offsets. This offsets may 
not be target pagesize aligned and target_mmap will correctly fail to mmap the 
segments. See load_elf_interp in elfload.c.

The patch I sent in previous emails makes target_mmap return target page 
aligned addresses and avoids this issue.

I attach output from a debug run further down.

Thanks.

[snip]
mmap: start=0x0 len=0x2000000 prot=--- flags=MAP_ANON MAP_PRIVATE fd=-1 offset=0
target_mmap target_mmap returns an ualigned address b5cb9000.
ret=0xb5cb9000
start    end      size     prot
00080000-00082000 00002000 r-x
00082000-00084000 00002000 rw-
b5cb8000-b7cba000 02002000 ---
b7cba000-b7d3c000 00082000 rw-

load_elf_interp ELF interp at unaligned target addr b5cb9000.
ELF loader map b5cb9000 fixed=16
mmap: start=0xb5cb9000 len=0xedeb prot=r-x flags=MAP_FIXED MAP_PRIVATE fd=5 
offset=0
target_mmap fixed mapping of target-unaligned addr=b5cb9000 denied.
Unable to load interpreter

------
These are the elf program headers for my dynamic loader:
laped:test % readelf-cris --segments 
/usr/local/cris/r63v32/crisv32-axis-linux-gnu/lib/ld.so.1

Elf file type is DYN (Shared object file)
Entry point 0x1378
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x0edeb 0x0edeb R E 0x2000
  LOAD           0x00ee00 0x00010e00 0x00010e00 0x002a4 0x00640 RW  0x2000
  DYNAMIC        0x00eea4 0x00010ea4 0x00010ea4 0x000b0 0x000b0 RW  0x4

 Section to Segment mapping:
  Segment Sections...
   00     .hash .dynsym .dynstr .gnu.version .gnu.version_d .rela.data 
.rela.got .rela.plt .plt .text .rodata
   01     .data .dynamic .got .bss
   02     .dynamic

------
This is what I used to debug:
Index: mmap.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/mmap.c,v
retrieving revision 1.14
diff -u -p -b -u -p -r1.14 mmap.c
--- mmap.c      17 Sep 2007 08:09:49 -0000      1.14
+++ mmap.c      22 Sep 2007 07:03:57 -0000
@@ -27,7 +27,7 @@
 
 #include "qemu.h"
 
-//#define DEBUG_MMAP
+#define DEBUG_MMAP
 
 /* NOTE: all the constants are the HOST ones, but addresses are target. */
 int target_mprotect(target_ulong start, target_ulong len, int prot)
@@ -246,6 +246,8 @@ abort();
     }
 
     if (start & ~TARGET_PAGE_MASK) {
+        printf ("%s fixed mapping of target-unaligned addr=%x denied.\n",
+               __func__, start);
         errno = EINVAL;
         return -1;
     }
@@ -320,6 +322,10 @@ abort();
     page_set_flags(start, start + len, prot | PAGE_VALID);
  the_end:
 #ifdef DEBUG_MMAP
+    if (start & ~TARGET_PAGE_MASK) {
+        printf ("%s target_mmap returns an ualigned address %x.\n",
+               __func__, start);
+    }
     printf("ret=0x%lx\n", (long)start);
     page_dump(stdout);
     printf("\n");
Index: elfload.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/elfload.c,v
retrieving revision 1.46
diff -u -p -b -u -p -r1.46 elfload.c
--- elfload.c   17 Sep 2007 08:09:49 -0000      1.46
+++ elfload.c   22 Sep 2007 07:03:57 -0000
@@ -333,6 +333,27 @@ static inline void init_thread(struct ta
 
 #endif
 
+#ifdef TARGET_CRIS
+
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ( (x) == EM_CRIS )
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA  ELFDATA2LSB
+#define ELF_ARCH  EM_CRIS
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
+{
+  /* Check other registers XXXXX */
+  regs->erp = infop->entry;
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE        8192
+
+#endif
+
 #ifdef TARGET_M68K
 
 #define ELF_START_MMAP 0x80000000
@@ -810,6 +831,10 @@ static unsigned long load_elf_interp(str
             }
             load_addr = error;
             load_addr_set = 1;
+           if (load_addr & ~TARGET_PAGE_MASK) {
+                   printf ("%s ELF interp at unaligned target addr %x.\n",
+                           __func__, load_addr);
+           }       
         }
 
        eppnt = elf_phdata;
@@ -827,6 +852,9 @@ static unsigned long load_elf_interp(str
                elf_type |= MAP_FIXED;
                vaddr = eppnt->p_vaddr;
            }
+           printf ("ELF loader map %x fixed=%d\n", 
+                   load_addr+TARGET_ELF_PAGESTART(vaddr),
+                   elf_type & MAP_FIXED);
            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
                 elf_prot,



-- 
Edgar E. Iglesias
Axis Communications AB




reply via email to

[Prev in Thread] Current Thread [Next in Thread]