All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt
@ 2011-02-07  6:05 Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 2/9] linux-user/elfload: add FDPIC support Mike Frysinger
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 linux-user/syscall.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 499c4d7..6116ab5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1448,7 +1448,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
             return -TARGET_EFAULT;
         if (len < 0)
             return -TARGET_EINVAL;
-        lv = sizeof(int);
+        lv = sizeof(lv);
         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
         if (ret < 0)
             return ret;
@@ -1485,7 +1485,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
                 return -TARGET_EFAULT;
             if (len < 0)
                 return -TARGET_EINVAL;
-            lv = sizeof(int);
+            lv = sizeof(lv);
             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
             if (ret < 0)
                 return ret;
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 2/9] linux-user/elfload: add FDPIC support
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 3/9] linux-user: add ppoll syscall support Mike Frysinger
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 elf.h                |   19 +++++++++++++
 linux-user/elfload.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++
 linux-user/qemu.h    |    7 +++++
 3 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/elf.h b/elf.h
index 7067c90..d2f24f4 100644
--- a/elf.h
+++ b/elf.h
@@ -1191,6 +1191,25 @@ typedef struct elf64_note {
   Elf64_Word n_type;	/* Content type */
 } Elf64_Nhdr;
 
+
+/* This data structure represents a PT_LOAD segment.  */
+struct elf32_fdpic_loadseg {
+  /* Core address to which the segment is mapped.  */
+  Elf32_Addr addr;
+  /* VMA recorded in the program header.  */
+  Elf32_Addr p_vaddr;
+  /* Size of this segment in memory.  */
+  Elf32_Word p_memsz;
+};
+struct elf32_fdpic_loadmap {
+  /* Protocol version number, must be zero.  */
+  Elf32_Half version;
+  /* Number of segments in this map.  */
+  Elf32_Half nsegs;
+  /* The actual memory map.  */
+  struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
 #ifdef ELF_CLASS
 #if ELF_CLASS == ELFCLASS32
 
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 33d776d..8c6d448 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1075,6 +1075,33 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot)
     }
 }
 
+#ifdef CONFIG_USE_FDPIC
+static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong sp)
+{
+    uint16_t n;
+    struct elf32_fdpic_loadseg *loadsegs = info->loadsegs;
+
+    /* elf32_fdpic_loadseg */
+    n = info->nsegs;
+    while (n--) {
+        sp -= 12;
+        put_user_u32(loadsegs[n].addr, sp+0);
+        put_user_u32(loadsegs[n].p_vaddr, sp+4);
+        put_user_u32(loadsegs[n].p_memsz, sp+8);
+    }
+
+    /* elf32_fdpic_loadmap */
+    sp -= 4;
+    put_user_u16(0, sp+0); /* version */
+    put_user_u16(info->nsegs, sp+2); /* nsegs */
+
+    info->personality = PER_LINUX_FDPIC;
+    info->loadmap_addr = sp;
+
+    return sp;
+}
+#endif
+
 static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
                                    struct elfhdr *exec,
                                    struct image_info *info,
@@ -1087,6 +1114,21 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     const int n = sizeof(elf_addr_t);
 
     sp = p;
+
+#ifdef CONFIG_USE_FDPIC
+    /* Needs to be before we load the env/argc/... */
+    if (elf_is_fdpic(exec)) {
+        /* Need 4 byte alignment for these structs */
+        sp &= ~3;
+        sp = loader_build_fdpic_loadmap(info, sp);
+        info->other_info = interp_info;
+        if (interp_info) {
+            interp_info->other_info = info;
+            sp = loader_build_fdpic_loadmap(interp_info, sp);
+        }
+    }
+#endif
+
     u_platform = 0;
     k_platform = ELF_PLATFORM;
     if (k_platform) {
@@ -1197,6 +1239,11 @@ static void load_elf_image(const char *image_name, int image_fd,
     }
     bswap_phdr(phdr, ehdr->e_phnum);
 
+#ifdef CONFIG_USE_FDPIC
+    info->nsegs = 0;
+    info->pt_dynamic_addr = 0;
+#endif
+
     /* Find the maximum size of the image and allocate an appropriate
        amount of memory to handle that.  */
     loaddr = -1, hiaddr = 0;
@@ -1210,6 +1257,9 @@ static void load_elf_image(const char *image_name, int image_fd,
             if (a > hiaddr) {
                 hiaddr = a;
             }
+#ifdef CONFIG_USE_FDPIC
+            ++info->nsegs;
+#endif
         }
     }
 
@@ -1290,6 +1340,27 @@ static void load_elf_image(const char *image_name, int image_fd,
     }
     load_bias = load_addr - loaddr;
 
+#ifdef CONFIG_USE_FDPIC
+    {
+        struct elf32_fdpic_loadseg *loadsegs = info->loadsegs =
+            qemu_malloc(sizeof(*loadsegs) * info->nsegs);
+
+        for (i = 0; i < ehdr->e_phnum; ++i) {
+            switch (phdr[i].p_type) {
+            case PT_DYNAMIC:
+                info->pt_dynamic_addr = phdr[i].p_vaddr + load_bias;
+                break;
+            case PT_LOAD:
+                loadsegs->addr = phdr[i].p_vaddr + load_bias;
+                loadsegs->p_vaddr = phdr[i].p_vaddr;
+                loadsegs->p_memsz = phdr[i].p_memsz;
+                ++loadsegs;
+                break;
+            }
+        }
+    }
+#endif
+
     info->load_bias = load_bias;
     info->load_addr = load_addr;
     info->entry = ehdr->e_entry + load_bias;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 32de241..250814d 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -51,6 +51,13 @@ struct image_info {
         abi_ulong       arg_start;
         abi_ulong       arg_end;
 	int		personality;
+#ifdef CONFIG_USE_FDPIC
+        abi_ulong       loadmap_addr;
+        uint16_t        nsegs;
+        void           *loadsegs;
+        abi_ulong       pt_dynamic_addr;
+        struct image_info *other_info;
+#endif
 };
 
 #ifdef TARGET_I386
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 3/9] linux-user: add ppoll syscall support
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 2/9] linux-user/elfload: add FDPIC support Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 4/9] linux-user: decode MAP_{UNINITIALIZED, EXECUTABLE} in strace Mike Frysinger
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

Some architectures (like Blackfin) only implement ppoll (and skip poll).
So add support for it using existing poll code.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 linux-user/syscall.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6116ab5..bb6ef43 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -529,6 +529,15 @@ static int sys_inotify_init1(int flags)
 #undef TARGET_NR_inotify_rm_watch
 #endif /* CONFIG_INOTIFY  */
 
+#if defined(TARGET_NR_ppoll)
+#ifndef __NR_ppoll
+# define __NR_ppoll -1
+#endif
+#define __NR_sys_ppoll __NR_ppoll
+_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
+          struct timespec *, timeout, const __sigset_t *, sigmask,
+          size_t, sigsetsize)
+#endif
 
 extern int personality(int);
 extern int flock(int, int);
@@ -6230,8 +6239,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = do_select(arg1, arg2, arg3, arg4, arg5);
         break;
 #endif
-#ifdef TARGET_NR_poll
+#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
+# ifdef TARGET_NR_poll
     case TARGET_NR_poll:
+# endif
+# ifdef TARGET_NR_ppoll
+    case TARGET_NR_ppoll:
+# endif
         {
             struct target_pollfd *target_pfd;
             unsigned int nfds = arg2;
@@ -6242,12 +6256,51 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
             if (!target_pfd)
                 goto efault;
+
             pfd = alloca(sizeof(struct pollfd) * nfds);
             for(i = 0; i < nfds; i++) {
                 pfd[i].fd = tswap32(target_pfd[i].fd);
                 pfd[i].events = tswap16(target_pfd[i].events);
             }
-            ret = get_errno(poll(pfd, nfds, timeout));
+
+# ifdef TARGET_NR_ppoll
+            if (num == TARGET_NR_ppoll) {
+                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
+                target_sigset_t *target_set;
+                sigset_t _set, *set = &_set;
+
+                if (arg3) {
+                    if (target_to_host_timespec(timeout_ts, arg3)) {
+                        unlock_user(target_pfd, arg1, 0);
+                        goto efault;
+                    }
+                } else {
+                    timeout_ts = NULL;
+                }
+
+                if (arg4) {
+                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
+                    if (!target_set) {
+                        unlock_user(target_pfd, arg1, 0);
+                        goto efault;
+                    }
+                    target_to_host_sigset(set, target_set);
+                } else {
+                    set = NULL;
+                }
+
+                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
+
+                if (!is_error(ret) && arg3) {
+                    host_to_target_timespec(arg3, timeout_ts);
+                }
+                if (arg4) {
+                    unlock_user(target_set, arg4, 0);
+                }
+            } else
+# endif
+                ret = get_errno(poll(pfd, nfds, timeout));
+
             if (!is_error(ret)) {
                 for(i = 0; i < nfds; i++) {
                     target_pfd[i].revents = tswap16(pfd[i].revents);
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 4/9] linux-user: decode MAP_{UNINITIALIZED, EXECUTABLE} in strace
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 2/9] linux-user/elfload: add FDPIC support Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 3/9] linux-user: add ppoll syscall support Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 5/9] linux-user/FLAT: fix auto-stack sizing Mike Frysinger
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 linux-user/strace.c       |    4 ++++
 linux-user/syscall_defs.h |    1 +
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index bf9a0d9..a8786bb 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -398,6 +398,7 @@ UNUSED static struct flags mmap_flags[] = {
     FLAG_TARGET(MAP_DENYWRITE),
     FLAG_TARGET(MAP_FIXED),
     FLAG_TARGET(MAP_GROWSDOWN),
+    FLAG_TARGET(MAP_EXECUTABLE),
 #ifdef MAP_LOCKED
     FLAG_TARGET(MAP_LOCKED),
 #endif
@@ -408,6 +409,9 @@ UNUSED static struct flags mmap_flags[] = {
 #ifdef MAP_POPULATE
     FLAG_TARGET(MAP_POPULATE),
 #endif
+#ifdef TARGET_MAP_UNINITIALIZED
+    FLAG_TARGET(MAP_UNINITIALIZED),
+#endif
     FLAG_END,
 };
 
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index d02a9bf..4742ac0 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -999,6 +999,7 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE	0x4000		/* don't check for reservations */
 #define TARGET_MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
 #define TARGET_MAP_NONBLOCK	0x10000		/* do not block on IO */
+#define TARGET_MAP_UNINITIALIZED 0x4000000	/* for anonymous mmap, memory could be uninitialized */
 #endif
 
 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_CRIS)
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 5/9] linux-user/FLAT: fix auto-stack sizing
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
                   ` (2 preceding siblings ...)
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 4/9] linux-user: decode MAP_{UNINITIALIZED, EXECUTABLE} in strace Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 6/9] linux-user/FLAT: allow targets to override FLAT processing Mike Frysinger
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

The current auto-stack sizing works like it does on a NOMMU system; the
problem is that this only works if the envp/argv arrays are fairly slim.
On a desktop system, this is rarely the case, and can easily blow past
the stack and into data/text regions as the default stack for FLAT progs
is a mere 4KiB.  So rather than rely on the NOMMU calculation (which is
only there because NOMMU can't easily allocate gobs of contiguous mem),
calc the full space actually needed and let the MMU host make space.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 linux-user/flatload.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index 8f9f4a5..d8b4476 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -733,8 +733,15 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
      * pedantic and include space for the argv/envp array as it may have
      * a lot of entries.
      */
-#define TOP_OF_ARGS (TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *))
-    stack_len = TOP_OF_ARGS - bprm->p;             /* the strings */
+    stack_len = 0;
+    for (i = 0; i < bprm->argc; ++i) {
+        /* the argv strings */
+        stack_len += strlen(bprm->argv[i]);
+    }
+    for (i = 0; i < bprm->envc; ++i) {
+        /* the envp strings */
+        stack_len += strlen(bprm->envp[i]);
+    }
     stack_len += (bprm->argc + 1) * 4; /* the argv array */
     stack_len += (bprm->envc + 1) * 4; /* the envp array */
 
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 6/9] linux-user/FLAT: allow targets to override FLAT processing
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
                   ` (3 preceding siblings ...)
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 5/9] linux-user/FLAT: fix auto-stack sizing Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 7/9] linux-user: implement sched_{g, s}etaffinity Mike Frysinger
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

This brings flatload.c more in line with the current Linux FLAT loader
which allows targets to handle various FLAT aspects in their own way.
For the common behavior, the new functions get stubbed out.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 Makefile.target          |    2 +-
 linux-user/flatload.c    |   27 +++++++++++----------------
 linux-user/target_flat.h |   10 ++++++++++
 3 files changed, 22 insertions(+), 17 deletions(-)
 create mode 100644 linux-user/target_flat.h

diff --git a/Makefile.target b/Makefile.target
index b0ba95f..48e6c00 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -107,7 +107,7 @@ ifdef CONFIG_LINUX_USER
 
 $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR))
 
-QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
+QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
 obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
       elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
       qemu-malloc.o $(oslib-obj-y)
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index d8b4476..cd7af7c 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -41,6 +41,8 @@
 
 #include "qemu.h"
 #include "flat.h"
+#define ntohl(x) be32_to_cpu(x)
+#include <target_flat.h>
 
 //#define DEBUG
 
@@ -50,14 +52,6 @@
 #define	DBG_FLT(...)
 #endif
 
-#define flat_reloc_valid(reloc, size)             ((reloc) <= (size))
-#define flat_old_ram_flag(flag)                   (flag)
-#ifdef TARGET_WORDS_BIGENDIAN
-#define flat_get_relocate_addr(relval)            (relval)
-#else
-#define flat_get_relocate_addr(relval)            bswap32(relval)
-#endif
-
 #define RELOC_FAILED 0xff00ff01		/* Relocation incorrect somewhere */
 #define UNLOADED_LIB 0x7ff000ff		/* Placeholder for unused library */
 
@@ -78,8 +72,6 @@ static int load_flat_shared_library(int id, struct lib_info *p);
 
 struct linux_binprm;
 
-#define ntohl(x) be32_to_cpu(x)
-
 /****************************************************************************/
 /*
  * create_flat_tables() parses the env- and arg-strings in new user
@@ -625,6 +617,7 @@ static int load_flat_file(struct linux_binprm * bprm,
      * __start to address 4 so that is okay).
      */
     if (rev > OLD_FLAT_VERSION) {
+        abi_ulong persistent = 0;
         for (i = 0; i < relocs; i++) {
             abi_ulong addr, relval;
 
@@ -633,6 +626,9 @@ static int load_flat_file(struct linux_binprm * bprm,
                relocated first).  */
             if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))
                 return -EFAULT;
+            relval = ntohl(relval);
+            if (flat_set_persistent(relval, &persistent))
+                continue;
             addr = flat_get_relocate_addr(relval);
             rp = calc_reloc(addr, libinfo, id, 1);
             if (rp == RELOC_FAILED)
@@ -641,22 +637,20 @@ static int load_flat_file(struct linux_binprm * bprm,
             /* Get the pointer's value.  */
             if (get_user_ual(addr, rp))
                 return -EFAULT;
+            addr = flat_get_addr_from_rp(rp, relval, flags, &persistent);
             if (addr != 0) {
                 /*
                  * Do the relocation.  PIC relocs in the data section are
                  * already in target order
                  */
-
-#ifndef TARGET_WORDS_BIGENDIAN
                 if ((flags & FLAT_FLAG_GOTPIC) == 0)
-                    addr = bswap32(addr);
-#endif
+                    addr = ntohl(addr);
                 addr = calc_reloc(addr, libinfo, id, 0);
                 if (addr == RELOC_FAILED)
                     return -ENOEXEC;
 
                 /* Write back the relocated pointer.  */
-                if (put_user_ual(addr, rp))
+                if (flat_put_addr_at_rp(rp, addr, relval))
                     return -EFAULT;
             }
         }
@@ -782,7 +776,8 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
     stack_len *= sizeof(abi_ulong);
     if ((sp + stack_len) & 15)
         sp -= 16 - ((sp + stack_len) & 15);
-    sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, 1);
+    sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p,
+                             flat_argvp_envp_on_stack());
 
     /* Fake some return addresses to ensure the call chain will
      * initialise library in order for us.  We are required to call
diff --git a/linux-user/target_flat.h b/linux-user/target_flat.h
new file mode 100644
index 0000000..0ba6bdd
--- /dev/null
+++ b/linux-user/target_flat.h
@@ -0,0 +1,10 @@
+/* If your arch needs to do custom stuff, create your own target_flat.h
+ * header file in linux-user/<your arch>/
+ */
+#define flat_argvp_envp_on_stack()                           1
+#define flat_reloc_valid(reloc, size)                        ((reloc) <= (size))
+#define flat_old_ram_flag(flag)                              (flag)
+#define flat_get_relocate_addr(relval)                       (relval)
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) (rp)
+#define flat_set_persistent(relval, persistent)              (*persistent)
+#define flat_put_addr_at_rp(rp, addr, relval)                put_user_ual(addr, rp)
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 7/9] linux-user: implement sched_{g, s}etaffinity
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
                   ` (4 preceding siblings ...)
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 6/9] linux-user/FLAT: allow targets to override FLAT processing Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 8/9] user: speed up init_paths a bit Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 9/9] linux-user: fix build errors for mmap2-only ports Mike Frysinger
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 linux-user/syscall.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb6ef43..4412a9b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -235,6 +235,12 @@ _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
           const struct timespec *,timeout,int *,uaddr2,int,val3)
 #endif
 #endif
+#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
+_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
+          unsigned long *, user_mask_ptr);
+#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
+_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
+          unsigned long *, user_mask_ptr);
 
 static bitmask_transtbl fcntl_flags_tbl[] = {
   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
@@ -6354,6 +6360,67 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
            return value. */
         ret = -TARGET_ENOTDIR;
         break;
+    case TARGET_NR_sched_getaffinity:
+        {
+            unsigned int mask_size;
+            unsigned long *mask;
+
+            /*
+             * sched_getaffinity needs multiples of ulong, so need to take
+             * care of mismatches between target ulong and host ulong sizes.
+             */
+            if (arg2 & (sizeof(abi_ulong) - 1)) {
+                ret = -TARGET_EINVAL;
+                break;
+            }
+            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
+
+            mask = alloca(mask_size);
+            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
+
+            if (!is_error(ret)) {
+                if (arg2 > ret) {
+                    /* Zero out any extra space kernel didn't fill */
+                    unsigned long zero = arg2 - ret;
+                    p = alloca(zero);
+                    memset(p, 0, zero);
+                    if (copy_to_user(arg3 + zero, p, zero)) {
+                        goto efault;
+                    }
+                    arg2 = ret;
+                }
+                if (copy_to_user(arg3, mask, arg2)) {
+                    goto efault;
+                }
+                ret = arg2;
+            }
+        }
+        break;
+    case TARGET_NR_sched_setaffinity:
+        {
+            unsigned int mask_size;
+            unsigned long *mask;
+
+            /*
+             * sched_setaffinity needs multiples of ulong, so need to take
+             * care of mismatches between target ulong and host ulong sizes.
+             */
+            if (arg2 & (sizeof(abi_ulong) - 1)) {
+                ret = -TARGET_EINVAL;
+                break;
+            }
+            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
+
+            mask = alloca(mask_size);
+            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
+                goto efault;
+            }
+            memcpy(mask, p, arg2);
+            unlock_user_struct(p, arg2, 0);
+
+            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
+        }
+        break;
     case TARGET_NR_sched_setparam:
         {
             struct sched_param *target_schp;
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 8/9] user: speed up init_paths a bit
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
                   ` (5 preceding siblings ...)
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 7/9] linux-user: implement sched_{g, s}etaffinity Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 9/9] linux-user: fix build errors for mmap2-only ports Mike Frysinger
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

The current init_paths code will attempt to opendir() every single file it
finds.  This can obviously generated a huge number of syscalls with even a
moderately small sysroot that will fail.  Since the readdir() call provides
the file type in the struct itself, use it.  On my system, this prevents
over 1000 syscalls from being made at every invocation of a target binary,
and I only have a C library installed.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 path.c |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/path.c b/path.c
index 0d2bf14..ef3f277 100644
--- a/path.c
+++ b/path.c
@@ -38,7 +38,8 @@ static int strneq(const char *s1, unsigned int n, const char *s2)
     return s2[i] == 0;
 }
 
-static struct pathelem *add_entry(struct pathelem *root, const char *name);
+static struct pathelem *add_entry(struct pathelem *root, const char *name,
+                                  unsigned char type);
 
 static struct pathelem *new_entry(const char *root,
                                   struct pathelem *parent,
@@ -56,6 +57,15 @@ static struct pathelem *new_entry(const char *root,
 
 #define streq(a,b) (strcmp((a), (b)) == 0)
 
+/* Not all systems provide this feature */
+#if defined(DT_DIR) && defined(DT_UNKNOWN)
+# define dirent_type(dirent) ((dirent)->d_type)
+# define is_dir_maybe(type)  ((type) == DT_DIR || (type) == DT_UNKNOWN)
+#else
+# define dirent_type(dirent) (1)
+# define is_dir_maybe(type)  (type)
+#endif
+
 static struct pathelem *add_dir_maybe(struct pathelem *path)
 {
     DIR *dir;
@@ -65,7 +75,7 @@ static struct pathelem *add_dir_maybe(struct pathelem *path)
 
         while ((dirent = readdir(dir)) != NULL) {
             if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
-                path = add_entry(path, dirent->d_name);
+                path = add_entry(path, dirent->d_name, dirent_type(dirent));
             }
         }
         closedir(dir);
@@ -73,16 +83,22 @@ static struct pathelem *add_dir_maybe(struct pathelem *path)
     return path;
 }
 
-static struct pathelem *add_entry(struct pathelem *root, const char *name)
+static struct pathelem *add_entry(struct pathelem *root, const char *name,
+                                  unsigned char type)
 {
+    struct pathelem **e;
+
     root->num_entries++;
 
     root = realloc(root, sizeof(*root)
                    + sizeof(root->entries[0])*root->num_entries);
+    e = &root->entries[root->num_entries-1];
+
+    *e = new_entry(root->pathname, root, name);
+    if (is_dir_maybe(type)) {
+        *e = add_dir_maybe(*e);
+    }
 
-    root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);
-    root->entries[root->num_entries-1]
-        = add_dir_maybe(root->entries[root->num_entries-1]);
     return root;
 }
 
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 9/9] linux-user: fix build errors for mmap2-only ports
  2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
                   ` (6 preceding siblings ...)
  2011-02-07  6:05 ` [Qemu-devel] [PATCH 8/9] user: speed up init_paths a bit Mike Frysinger
@ 2011-02-07  6:05 ` Mike Frysinger
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2011-02-07  6:05 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio

The current print_mmap func is only enabled when the target supports the
mmap syscall, but both mmap and mmap2 syscalls use it.  This leads to a
build failure when the target supports mmap2 but not mmap.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 linux-user/strace.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index a8786bb..1836666 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1203,7 +1203,7 @@ print_utimensat(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_mmap
+#if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2)
 static void
 print_mmap(const struct syscallname *name,
     abi_long arg0, abi_long arg1, abi_long arg2,
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-02-07  6:15 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-07  6:05 [Qemu-devel] [PATCH 1/9] linux-user: fix sizeof handling for getsockopt Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 2/9] linux-user/elfload: add FDPIC support Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 3/9] linux-user: add ppoll syscall support Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 4/9] linux-user: decode MAP_{UNINITIALIZED, EXECUTABLE} in strace Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 5/9] linux-user/FLAT: fix auto-stack sizing Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 6/9] linux-user/FLAT: allow targets to override FLAT processing Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 7/9] linux-user: implement sched_{g, s}etaffinity Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 8/9] user: speed up init_paths a bit Mike Frysinger
2011-02-07  6:05 ` [Qemu-devel] [PATCH 9/9] linux-user: fix build errors for mmap2-only ports Mike Frysinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.