All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa
@ 2021-06-19  3:43 Richard Henderson
  2021-06-19  3:43 ` [PATCH 01/12] linux-user: Fix style problems in linuxload.c Richard Henderson
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Supersedes: 20200519194452.9009-1-richard.henderson@linaro.org
Based-on: 20210618192951.125651-1-richard.henderson@linaro.org
("[PATCH v2 00/23] linux-user: Move signal trampolines to new page")

Previous cover letter:
> The subject of AT_SYSINFO came up on launchpad recently.
> 
> There is definite room for improvement in all of this:
> 
> (1) We could build the vdso binary into qemu instead of really
>     loading it from the file system.  This would obviate the
>     several problems of locating the .so file.  It would also
>     mean that --static builds continue to create a standalone
>     qemu binary.
> 
> (2) We could use our cross-build system to build the vdso.
>     Though we'd still likely want to keep the image in git
>     along side the other rom images for when cross-build is
>     not available.
> 
> (3) There are some ??? comments where some decisions could be made,
>     and other ??? that are merely commenting on weirdness.
> 
> (4) It shouldn't take too much effort to create vdsos for the
>     other architectures.  But we should get this one as clean
>     as we can first.

Amusingly, this patch set has turned 11 years old.
First posted April 4, 2010.

Change since previous:

Point (1) has been addressed: the vdso binary pre-processed,
validating the VDSO image, emitting a C array for the image,
collecting the set of relocations required, and identifying
any signal return trampolines.

Point (2) is still an issue in that the cross-build system is
tied up in tests/ makefiles.  It might be time to bite the bullet
and convert it all to meson.

I think there are fewer ??? than before.


r~


Richard Henderson (12):
  linux-user: Fix style problems in linuxload.c
  linux-user: Introduce imgsrc_read, imgsrc_read_alloc
  linux-user: Tidy loader_exec
  linux-user: Do not clobber bprm_buf swapping ehdr
  linux-user: Use ImageSource in load_elf_image
  linux-user: Use ImageSource in load_symbols
  linux-user: Replace bprm->fd with bprm->src.fd
  linux-user: Introduce imgsrc_mmap
  linux-user: Load vdso image if available
  linux-user: Add gen-vdso tool
  linux-user/x86_64: Add vdso
  linux-user/hppa: Add vdso and use it for rt_sigreturn

 linux-user/qemu.h               |  60 ++++++-
 linux-user/elfload.c            | 305 ++++++++++++++++++--------------
 linux-user/flatload.c           |   8 +-
 linux-user/gen-vdso.c           | 168 ++++++++++++++++++
 linux-user/hppa/signal.c        |   8 +-
 linux-user/linuxload.c          | 171 +++++++++++++-----
 linux-user/gen-vdso-elfn.c.inc  | 299 +++++++++++++++++++++++++++++++
 linux-user/hppa/Makefile.vdso   |   4 +
 linux-user/hppa/meson.build     |   6 +
 linux-user/hppa/vdso.S          | 149 ++++++++++++++++
 linux-user/hppa/vdso.ld         |  75 ++++++++
 linux-user/hppa/vdso.so         | Bin 0 -> 5192 bytes
 linux-user/meson.build          |   6 +-
 linux-user/x86_64/Makefile.vdso |   3 +
 linux-user/x86_64/meson.build   |   6 +
 linux-user/x86_64/vdso.S        | 122 +++++++++++++
 linux-user/x86_64/vdso.ld       |  74 ++++++++
 linux-user/x86_64/vdso.so       | Bin 0 -> 5912 bytes
 18 files changed, 1272 insertions(+), 192 deletions(-)
 create mode 100644 linux-user/gen-vdso.c
 create mode 100644 linux-user/gen-vdso-elfn.c.inc
 create mode 100644 linux-user/hppa/Makefile.vdso
 create mode 100644 linux-user/hppa/vdso.S
 create mode 100644 linux-user/hppa/vdso.ld
 create mode 100755 linux-user/hppa/vdso.so
 create mode 100644 linux-user/x86_64/Makefile.vdso
 create mode 100644 linux-user/x86_64/vdso.S
 create mode 100644 linux-user/x86_64/vdso.ld
 create mode 100755 linux-user/x86_64/vdso.so

-- 
2.25.1



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

* [PATCH 01/12] linux-user: Fix style problems in linuxload.c
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  9:47   ` Philippe Mathieu-Daudé
  2021-06-19  3:43 ` [PATCH 02/12] linux-user: Introduce imgsrc_read, imgsrc_read_alloc Richard Henderson
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/linuxload.c | 42 ++++++++++++++++++++----------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index a27e1d0d8b..9d4eb5e94b 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -1,59 +1,57 @@
 /* Code for loading Linux executables.  Mostly linux kernel code.  */
 
 #include "qemu/osdep.h"
-
 #include "qemu.h"
 
 #define NGROUPS 32
 
 /* ??? This should really be somewhere else.  */
-abi_long memcpy_to_target(abi_ulong dest, const void *src,
-                          unsigned long len)
+abi_long memcpy_to_target(abi_ulong dest, const void *src, unsigned long len)
 {
     void *host_ptr;
 
     host_ptr = lock_user(VERIFY_WRITE, dest, len, 0);
-    if (!host_ptr)
+    if (!host_ptr) {
         return -TARGET_EFAULT;
+    }
     memcpy(host_ptr, src, len);
     unlock_user(host_ptr, dest, 1);
     return 0;
 }
 
-static int count(char ** vec)
+static int count(char **vec)
 {
-    int		i;
+    int i;
 
-    for(i = 0; *vec; i++) {
+    for (i = 0; *vec; i++) {
         vec++;
     }
-
-    return(i);
+    return i;
 }
 
 static int prepare_binprm(struct linux_binprm *bprm)
 {
-    struct stat		st;
+    struct stat st;
     int mode;
     int retval;
 
-    if(fstat(bprm->fd, &st) < 0) {
-        return(-errno);
+    if (fstat(bprm->fd, &st) < 0) {
+        return -errno;
     }
 
     mode = st.st_mode;
-    if(!S_ISREG(mode)) {	/* Must be regular file */
-        return(-EACCES);
+    if (!S_ISREG(mode)) {   /* Must be regular file */
+        return -EACCES;
     }
-    if(!(mode & 0111)) {	/* Must have at least one execute bit set */
-        return(-EACCES);
+    if (!(mode & 0111)) {   /* Must have at least one execute bit set */
+        return -EACCES;
     }
 
     bprm->e_uid = geteuid();
     bprm->e_gid = getegid();
 
     /* Set-uid? */
-    if(mode & S_ISUID) {
+    if (mode & S_ISUID) {
         bprm->e_uid = st.st_uid;
     }
 
@@ -125,8 +123,8 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
 }
 
 int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
-             struct target_pt_regs * regs, struct image_info *infop,
-             struct linux_binprm *bprm)
+                struct target_pt_regs *regs, struct image_info *infop,
+                struct linux_binprm *bprm)
 {
     int retval;
 
@@ -139,7 +137,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
 
     retval = prepare_binprm(bprm);
 
-    if(retval>=0) {
+    if (retval >= 0) {
         if (bprm->buf[0] == 0x7f
                 && bprm->buf[1] == 'E'
                 && bprm->buf[2] == 'L'
@@ -157,11 +155,11 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
         }
     }
 
-    if(retval>=0) {
+    if (retval >= 0) {
         /* success.  Initialize important registers */
         do_init_thread(regs, infop);
         return retval;
     }
 
-    return(retval);
+    return retval;
 }
-- 
2.25.1



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

* [PATCH 02/12] linux-user: Introduce imgsrc_read, imgsrc_read_alloc
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
  2021-06-19  3:43 ` [PATCH 01/12] linux-user: Fix style problems in linuxload.c Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 03/12] linux-user: Tidy loader_exec Richard Henderson
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Introduced and initialized, but not yet really used.
These will tidy the current tests vs BPRM_BUF_SIZE.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/qemu.h      | 50 ++++++++++++++++++++++++++++++++++--------
 linux-user/linuxload.c | 46 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 9e5e2aa499..f4cdfb16b3 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -168,6 +168,37 @@ extern unsigned long mmap_min_addr;
 
 /* ??? See if we can avoid exposing so much of the loader internals.  */
 
+typedef struct {
+    const void *cache;
+    unsigned int cache_size;
+    int fd;
+} ImageSource;
+
+/**
+ * imgsrc_read: Read from ImageSource
+ * @dst: destination for read
+ * @offset: offset within file for read
+ * @len: size of the read
+ * @img: ImageSource to read from
+ * @errp: Error details.
+ *
+ * Read into @dst, using the cache when possible.
+ */
+bool imgsrc_read(void *dst, off_t offset, size_t len,
+                 const ImageSource *img, Error **errp);
+
+/**
+ * imgsrc_read_alloc: Read from ImageSource
+ * @offset: offset within file for read
+ * @size: size of the read
+ * @img: ImageSource to read from
+ * @errp: Error details.
+ *
+ * Read into newly allocated memory, using the cache when possible.
+ */
+void *imgsrc_read_alloc(off_t offset, size_t len,
+                        const ImageSource *img, Error **errp);
+
 /* Read a good amount of data initially, to hopefully get all the
    program headers loaded.  */
 #define BPRM_BUF_SIZE  1024
@@ -177,15 +208,16 @@ extern unsigned long mmap_min_addr;
  * used when loading binaries.
  */
 struct linux_binprm {
-        char buf[BPRM_BUF_SIZE] __attribute__((aligned));
-        abi_ulong p;
-        int fd;
-        int e_uid, e_gid;
-        int argc, envc;
-        char **argv;
-        char **envp;
-        char * filename;        /* Name of binary */
-        int (*core_dump)(int, const CPUArchState *); /* coredump routine */
+    char buf[BPRM_BUF_SIZE] __attribute__((aligned));
+    ImageSource src;
+    abi_ulong p;
+    int fd;
+    int e_uid, e_gid;
+    int argc, envc;
+    char **argv;
+    char **envp;
+    char *filename;  /* Name of binary */
+    int (*core_dump)(int, const CPUArchState *); /* coredump routine */
 };
 
 typedef struct IOCTLEntry IOCTLEntry;
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index 9d4eb5e94b..3b0bafc490 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -2,6 +2,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu.h"
+#include "qapi/error.h"
 
 #define NGROUPS 32
 
@@ -74,6 +75,10 @@ static int prepare_binprm(struct linux_binprm *bprm)
         /* Make sure the rest of the loader won't read garbage.  */
         memset(bprm->buf + retval, 0, BPRM_BUF_SIZE - retval);
     }
+
+    bprm->src.cache = bprm->buf;
+    bprm->src.cache_size = retval;
+
     return retval;
 }
 
@@ -129,6 +134,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
     int retval;
 
     bprm->fd = fdexec;
+    bprm->src.fd = fdexec;
     bprm->filename = (char *)filename;
     bprm->argc = count(argv);
     bprm->argv = argv;
@@ -163,3 +169,43 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
 
     return retval;
 }
+
+bool imgsrc_read(void *dst, off_t offset, size_t len,
+                 const ImageSource *img, Error **errp)
+{
+    ssize_t ret;
+
+    if (offset + len <= img->cache_size) {
+        memcpy(dst, img->cache + offset, len);
+        return true;
+    }
+
+    if (img->fd < 0) {
+        error_setg(errp, "read past end of buffer");
+        return false;
+    }
+
+    ret = pread(img->fd, dst, len, offset);
+    if (ret == len) {
+        return true;
+    }
+    if (ret < 0) {
+        error_setg_errno(errp, errno, "Error reading file header");
+    } else {
+        error_setg(errp, "Incomplete read of file header");
+    }
+    return false;
+}
+
+void *imgsrc_read_alloc(off_t offset, size_t len,
+                        const ImageSource *img, Error **errp)
+{
+    void *alloc = g_malloc(len);
+    bool ok = imgsrc_read(alloc, offset, len, img, errp);
+
+    if (!ok) {
+        g_free(alloc);
+        alloc = NULL;
+    }
+    return alloc;
+}
-- 
2.25.1



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

* [PATCH 03/12] linux-user: Tidy loader_exec
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
  2021-06-19  3:43 ` [PATCH 01/12] linux-user: Fix style problems in linuxload.c Richard Henderson
  2021-06-19  3:43 ` [PATCH 02/12] linux-user: Introduce imgsrc_read, imgsrc_read_alloc Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 04/12] linux-user: Do not clobber bprm_buf swapping ehdr Richard Henderson
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Reorg the if cases to reduce indentation.
Test for 4 bytes in the file before checking the signatures.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/linuxload.c | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index 3b0bafc490..8b93b9704c 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -143,31 +143,31 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
 
     retval = prepare_binprm(bprm);
 
-    if (retval >= 0) {
-        if (bprm->buf[0] == 0x7f
-                && bprm->buf[1] == 'E'
-                && bprm->buf[2] == 'L'
-                && bprm->buf[3] == 'F') {
-            retval = load_elf_binary(bprm, infop);
-#if defined(TARGET_HAS_BFLT)
-        } else if (bprm->buf[0] == 'b'
-                && bprm->buf[1] == 'F'
-                && bprm->buf[2] == 'L'
-                && bprm->buf[3] == 'T') {
-            retval = load_flt_binary(bprm, infop);
-#endif
-        } else {
-            return -ENOEXEC;
-        }
+    if (retval < 4) {
+        return -ENOEXEC;
     }
-
-    if (retval >= 0) {
-        /* success.  Initialize important registers */
-        do_init_thread(regs, infop);
+    if (bprm->buf[0] == 0x7f
+        && bprm->buf[1] == 'E'
+        && bprm->buf[2] == 'L'
+        && bprm->buf[3] == 'F') {
+        retval = load_elf_binary(bprm, infop);
+#if defined(TARGET_HAS_BFLT)
+    } else if (bprm->buf[0] == 'b'
+               && bprm->buf[1] == 'F'
+               && bprm->buf[2] == 'L'
+               && bprm->buf[3] == 'T') {
+        retval = load_flt_binary(bprm, infop);
+#endif
+    } else {
+        return -ENOEXEC;
+    }
+    if (retval < 0) {
         return retval;
     }
 
-    return retval;
+    /* Success.  Initialize important registers. */
+    do_init_thread(regs, infop);
+    return 0;
 }
 
 bool imgsrc_read(void *dst, off_t offset, size_t len,
-- 
2.25.1



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

* [PATCH 04/12] linux-user: Do not clobber bprm_buf swapping ehdr
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (2 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 03/12] linux-user: Tidy loader_exec Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  9:50   ` Philippe Mathieu-Daudé
  2021-06-19  3:43 ` [PATCH 05/12] linux-user: Use ImageSource in load_elf_image Richard Henderson
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Rearrange the allocation of storage for ehdr between load_elf_image
and load_elf_binary.  The same set of copies are done, but we don't
modify bprm_buf, which will be important later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index c0236a0b09..1f9a69703a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2622,16 +2622,17 @@ static bool parse_elf_properties(int image_fd,
    On return: INFO values will be filled in, as necessary or available.  */
 
 static void load_elf_image(const char *image_name, int image_fd,
-                           struct image_info *info, char **pinterp_name,
+                           struct image_info *info, struct elfhdr *ehdr,
+                           char **pinterp_name,
                            char bprm_buf[BPRM_BUF_SIZE])
 {
-    struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
     struct elf_phdr *phdr;
     abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
     int i, retval, prot_exec;
     Error *err = NULL;
 
     /* First of all, some simple consistency checks */
+    memcpy(ehdr, bprm_buf, sizeof(*ehdr));
     if (!elf_check_ident(ehdr)) {
         error_setg(&err, "Invalid ELF image for this architecture");
         goto exit_errmsg;
@@ -2944,6 +2945,7 @@ static void load_elf_image(const char *image_name, int image_fd,
 static void load_elf_interp(const char *filename, struct image_info *info,
                             char bprm_buf[BPRM_BUF_SIZE])
 {
+    struct elfhdr ehdr;
     int fd, retval;
     Error *err = NULL;
 
@@ -2965,7 +2967,7 @@ static void load_elf_interp(const char *filename, struct image_info *info,
         memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
     }
 
-    load_elf_image(filename, fd, info, NULL, bprm_buf);
+    load_elf_image(filename, fd, info, &ehdr, NULL, bprm_buf);
 }
 
 static int symfind(const void *s0, const void *s1)
@@ -3157,8 +3159,14 @@ uint32_t get_elf_eflags(int fd)
 
 int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
 {
+    /*
+     * We need a copy of the elf header for passing to create_elf_tables.
+     * We will have overwritten the original when we re-use bprm->buf
+     * while loading the interpreter.  Allocate the storage for this now
+     * and let elf_load_image do any swapping that may be required.
+     */
+    struct elfhdr ehdr;
     struct image_info interp_info;
-    struct elfhdr elf_ex;
     char *elf_interpreter = NULL;
     char *scratch;
 
@@ -3170,12 +3178,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
     info->start_mmap = (abi_ulong)ELF_START_MMAP;
 
     load_elf_image(bprm->filename, bprm->fd, info,
-                   &elf_interpreter, bprm->buf);
-
-    /* ??? We need a copy of the elf header for passing to create_elf_tables.
-       If we do nothing, we'll have overwritten this when we re-use bprm->buf
-       when we load the interpreter.  */
-    elf_ex = *(struct elfhdr *)bprm->buf;
+                   &ehdr, &elf_interpreter, bprm->buf);
 
     /* Do this so that we can load the interpreter, if need be.  We will
        change some of these later */
@@ -3245,7 +3248,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
         target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC);
     }
 
-    bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
+    bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr,
                                 info, (elf_interpreter ? &interp_info : NULL));
     info->start_stack = bprm->p;
 
-- 
2.25.1



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

* [PATCH 05/12] linux-user: Use ImageSource in load_elf_image
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (3 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 04/12] linux-user: Do not clobber bprm_buf swapping ehdr Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 06/12] linux-user: Use ImageSource in load_symbols Richard Henderson
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Change parse_elf_properties as well, as the bprm_buf argument
ties the two functions closely.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c | 124 ++++++++++++++++---------------------------
 1 file changed, 47 insertions(+), 77 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1f9a69703a..425420f0cc 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2525,10 +2525,9 @@ static bool parse_elf_property(const uint32_t *data, int *off, int datasz,
 }
 
 /* Process NT_GNU_PROPERTY_TYPE_0. */
-static bool parse_elf_properties(int image_fd,
+static bool parse_elf_properties(const ImageSource *src,
                                  struct image_info *info,
                                  const struct elf_phdr *phdr,
-                                 char bprm_buf[BPRM_BUF_SIZE],
                                  Error **errp)
 {
     union {
@@ -2556,14 +2555,8 @@ static bool parse_elf_properties(int image_fd,
         return false;
     }
 
-    if (phdr->p_offset + n <= BPRM_BUF_SIZE) {
-        memcpy(&note, bprm_buf + phdr->p_offset, n);
-    } else {
-        ssize_t len = pread(image_fd, &note, n, phdr->p_offset);
-        if (len != n) {
-            error_setg_errno(errp, errno, "Error reading file header");
-            return false;
-        }
+    if (!imgsrc_read(&note, phdr->p_offset, n, src, errp)) {
+        return false;
     }
 
     /*
@@ -2609,30 +2602,34 @@ static bool parse_elf_properties(int image_fd,
     }
 }
 
-/* Load an ELF image into the address space.
+/**
+ * load_elf_image: Load an ELF image into the address space.
+ * @image_name: the filename of the image, to use in error messages.
+ * @src: the ImageSource from which to read.
+ * @info: info collected from the loaded image.
+ * @ehdr: the ELF header, not yet bswapped.
+ * @pinterp_name: record any PT_INTERP string found.
+ *
+ * On return: @info values will be filled in, as necessary or available.
+ */
 
-   IMAGE_NAME is the filename of the image, to use in error messages.
-   IMAGE_FD is the open file descriptor for the image.
-
-   BPRM_BUF is a copy of the beginning of the file; this of course
-   contains the elf file header at offset 0.  It is assumed that this
-   buffer is sufficiently aligned to present no problems to the host
-   in accessing data at aligned offsets within the buffer.
-
-   On return: INFO values will be filled in, as necessary or available.  */
-
-static void load_elf_image(const char *image_name, int image_fd,
+static void load_elf_image(const char *image_name, const ImageSource *src,
                            struct image_info *info, struct elfhdr *ehdr,
-                           char **pinterp_name,
-                           char bprm_buf[BPRM_BUF_SIZE])
+                           char **pinterp_name)
 {
-    struct elf_phdr *phdr;
+    g_autofree struct elf_phdr *phdr = NULL;
     abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
-    int i, retval, prot_exec;
+    int i, prot_exec;
     Error *err = NULL;
 
-    /* First of all, some simple consistency checks */
-    memcpy(ehdr, bprm_buf, sizeof(*ehdr));
+    /*
+     * First of all, some simple consistency checks.
+     * Note that we rely on the bswapped ehdr staying in bprm_buf,
+     * for later use by load_elf_binary and create_elf_tables.
+     */
+    if (!imgsrc_read(ehdr, 0, sizeof(*ehdr), src, &err)) {
+        goto exit_errmsg;
+    }
     if (!elf_check_ident(ehdr)) {
         error_setg(&err, "Invalid ELF image for this architecture");
         goto exit_errmsg;
@@ -2643,15 +2640,11 @@ static void load_elf_image(const char *image_name, int image_fd,
         goto exit_errmsg;
     }
 
-    i = ehdr->e_phnum * sizeof(struct elf_phdr);
-    if (ehdr->e_phoff + i <= BPRM_BUF_SIZE) {
-        phdr = (struct elf_phdr *)(bprm_buf + ehdr->e_phoff);
-    } else {
-        phdr = (struct elf_phdr *) alloca(i);
-        retval = pread(image_fd, phdr, i, ehdr->e_phoff);
-        if (retval != i) {
-            goto exit_read;
-        }
+    phdr = imgsrc_read_alloc(ehdr->e_phoff,
+                             ehdr->e_phnum * sizeof(struct elf_phdr),
+                             src, &err);
+    if (phdr == NULL) {
+        goto exit_errmsg;
     }
     bswap_phdr(phdr, ehdr->e_phnum);
 
@@ -2687,17 +2680,10 @@ static void load_elf_image(const char *image_name, int image_fd,
                 goto exit_errmsg;
             }
 
-            interp_name = g_malloc(eppnt->p_filesz);
-
-            if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
-                memcpy(interp_name, bprm_buf + eppnt->p_offset,
-                       eppnt->p_filesz);
-            } else {
-                retval = pread(image_fd, interp_name, eppnt->p_filesz,
-                               eppnt->p_offset);
-                if (retval != eppnt->p_filesz) {
-                    goto exit_read;
-                }
+            interp_name = imgsrc_read_alloc(eppnt->p_offset, eppnt->p_filesz,
+                                            src, &err);
+            if (interp_name == NULL) {
+                goto exit_errmsg;
             }
             if (interp_name[eppnt->p_filesz - 1] != 0) {
                 error_setg(&err, "Invalid PT_INTERP entry");
@@ -2705,7 +2691,7 @@ static void load_elf_image(const char *image_name, int image_fd,
             }
             *pinterp_name = g_steal_pointer(&interp_name);
         } else if (eppnt->p_type == PT_GNU_PROPERTY) {
-            if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
+            if (!parse_elf_properties(src, info, eppnt, &err)) {
                 goto exit_errmsg;
             }
         }
@@ -2847,7 +2833,7 @@ static void load_elf_image(const char *image_name, int image_fd,
                 vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_filesz + vaddr_po);
                 error = target_mmap(vaddr_ps, vaddr_len, elf_prot,
                                     MAP_PRIVATE | MAP_FIXED,
-                                    image_fd, eppnt->p_offset - vaddr_po);
+                                    src->fd, eppnt->p_offset - vaddr_po);
 
                 if (error == -1) {
                     goto exit_mmap;
@@ -2893,20 +2879,11 @@ static void load_elf_image(const char *image_name, int image_fd,
 #ifdef TARGET_MIPS
         } else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
             Mips_elf_abiflags_v0 abiflags;
-            if (eppnt->p_filesz < sizeof(Mips_elf_abiflags_v0)) {
-                error_setg(&err, "Invalid PT_MIPS_ABIFLAGS entry");
+
+            if (!imgsrc_read(&abiflags, eppnt->p_offset, sizeof(abiflags),
+                             src, &err)) {
                 goto exit_errmsg;
             }
-            if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
-                memcpy(&abiflags, bprm_buf + eppnt->p_offset,
-                       sizeof(Mips_elf_abiflags_v0));
-            } else {
-                retval = pread(image_fd, &abiflags, sizeof(Mips_elf_abiflags_v0),
-                               eppnt->p_offset);
-                if (retval != sizeof(Mips_elf_abiflags_v0)) {
-                    goto exit_read;
-                }
-            }
             bswap_mips_abiflags(&abiflags);
             info->fp_abi = abiflags.fp_abi;
 #endif
@@ -2919,21 +2896,14 @@ static void load_elf_image(const char *image_name, int image_fd,
     }
 
     if (qemu_log_enabled()) {
-        load_symbols(ehdr, image_fd, load_bias);
+        load_symbols(ehdr, src->fd, load_bias);
     }
 
     mmap_unlock();
 
-    close(image_fd);
+    close(src->fd);
     return;
 
- exit_read:
-    if (retval >= 0) {
-        error_setg(&err, "Incomplete read of file header");
-    } else {
-        error_setg_errno(&err, errno, "Error reading file header");
-    }
-    goto exit_errmsg;
  exit_mmap:
     error_setg_errno(&err, errno, "Error mapping file");
     goto exit_errmsg;
@@ -2946,6 +2916,7 @@ static void load_elf_interp(const char *filename, struct image_info *info,
                             char bprm_buf[BPRM_BUF_SIZE])
 {
     struct elfhdr ehdr;
+    ImageSource src;
     int fd, retval;
     Error *err = NULL;
 
@@ -2963,11 +2934,11 @@ static void load_elf_interp(const char *filename, struct image_info *info,
         exit(-1);
     }
 
-    if (retval < BPRM_BUF_SIZE) {
-        memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
-    }
+    src.fd = fd;
+    src.cache = bprm_buf;
+    src.cache_size = retval;
 
-    load_elf_image(filename, fd, info, &ehdr, NULL, bprm_buf);
+    load_elf_image(filename, &src, info, &ehdr, NULL);
 }
 
 static int symfind(const void *s0, const void *s1)
@@ -3177,8 +3148,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
 
     info->start_mmap = (abi_ulong)ELF_START_MMAP;
 
-    load_elf_image(bprm->filename, bprm->fd, info,
-                   &ehdr, &elf_interpreter, bprm->buf);
+    load_elf_image(bprm->filename, &bprm->src, info, &ehdr, &elf_interpreter);
 
     /* Do this so that we can load the interpreter, if need be.  We will
        change some of these later */
-- 
2.25.1



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

* [PATCH 06/12] linux-user: Use ImageSource in load_symbols
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (4 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 05/12] linux-user: Use ImageSource in load_elf_image Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 07/12] linux-user: Replace bprm->fd with bprm->src.fd Richard Henderson
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Aside from the section headers, we're unlikely to hit the
ImageSource cache on guest executables.  But the interface
for imgsrc_read_* is better.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c | 87 ++++++++++++++++++++++++--------------------
 1 file changed, 48 insertions(+), 39 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 425420f0cc..3c31a5e3b0 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1729,7 +1729,8 @@ static inline void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags) { }
 #ifdef USE_ELF_CORE_DUMP
 static int elf_core_dump(int, const CPUArchState *);
 #endif /* USE_ELF_CORE_DUMP */
-static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias);
+static void load_symbols(struct elfhdr *hdr, const ImageSource *src,
+                         abi_ulong load_bias);
 
 /* Verify the portions of EHDR within E_IDENT for the target.
    This can be performed before bswapping the entire header.  */
@@ -2896,7 +2897,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
     }
 
     if (qemu_log_enabled()) {
-        load_symbols(ehdr, src->fd, load_bias);
+        load_symbols(ehdr, src, load_bias);
     }
 
     mmap_unlock();
@@ -2984,19 +2985,20 @@ static int symcmp(const void *s0, const void *s1)
 }
 
 /* Best attempt to load symbols from this ELF object. */
-static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
+static void load_symbols(struct elfhdr *hdr, const ImageSource *src,
+                         abi_ulong load_bias)
 {
     int i, shnum, nsyms, sym_idx = 0, str_idx = 0;
-    uint64_t segsz;
-    struct elf_shdr *shdr;
+    g_autofree struct elf_shdr *shdr = NULL;
     char *strings = NULL;
-    struct syminfo *s = NULL;
-    struct elf_sym *new_syms, *syms = NULL;
+    struct elf_sym *syms = NULL;
+    struct elf_sym *new_syms;
+    uint64_t segsz;
 
     shnum = hdr->e_shnum;
-    i = shnum * sizeof(struct elf_shdr);
-    shdr = (struct elf_shdr *)alloca(i);
-    if (pread(fd, shdr, i, hdr->e_shoff) != i) {
+    shdr = imgsrc_read_alloc(hdr->e_shoff, shnum * sizeof(struct elf_shdr),
+                             src, NULL);
+    if (shdr == NULL) {
         return;
     }
 
@@ -3014,31 +3016,33 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
 
  found:
     /* Now know where the strtab and symtab are.  Snarf them.  */
-    s = g_try_new(struct syminfo, 1);
-    if (!s) {
-        goto give_up;
-    }
 
     segsz = shdr[str_idx].sh_size;
-    s->disas_strtab = strings = g_try_malloc(segsz);
-    if (!strings ||
-        pread(fd, strings, segsz, shdr[str_idx].sh_offset) != segsz) {
+    strings = g_try_malloc(segsz);
+    if (!strings) {
+        goto give_up;
+    }
+    if (!imgsrc_read(strings, shdr[str_idx].sh_offset, segsz, src, NULL)) {
         goto give_up;
     }
 
     segsz = shdr[sym_idx].sh_size;
-    syms = g_try_malloc(segsz);
-    if (!syms || pread(fd, syms, segsz, shdr[sym_idx].sh_offset) != segsz) {
-        goto give_up;
-    }
-
     if (segsz / sizeof(struct elf_sym) > INT_MAX) {
-        /* Implausibly large symbol table: give up rather than ploughing
-         * on with the number of symbols calculation overflowing
+        /*
+         * Implausibly large symbol table: give up rather than ploughing
+         * on with the number of symbols calculation overflowing.
          */
         goto give_up;
     }
     nsyms = segsz / sizeof(struct elf_sym);
+    syms = g_try_malloc(segsz);
+    if (!syms) {
+        goto give_up;
+    }
+    if (!imgsrc_read(syms, shdr[sym_idx].sh_offset, segsz, src, NULL)) {
+        goto give_up;
+    }
+
     for (i = 0; i < nsyms; ) {
         bswap_sym(syms + i);
         /* Throw away entries which we do not need.  */
@@ -3063,10 +3067,12 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
         goto give_up;
     }
 
-    /* Attempt to free the storage associated with the local symbols
-       that we threw away.  Whether or not this has any effect on the
-       memory allocation depends on the malloc implementation and how
-       many symbols we managed to discard.  */
+    /*
+     * Attempt to free the storage associated with the local symbols
+     * that we threw away.  Whether or not this has any effect on the
+     * memory allocation depends on the malloc implementation and how
+     * many symbols we managed to discard.
+     */
     new_syms = g_try_renew(struct elf_sym, syms, nsyms);
     if (new_syms == NULL) {
         goto give_up;
@@ -3075,20 +3081,23 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
 
     qsort(syms, nsyms, sizeof(*syms), symcmp);
 
-    s->disas_num_syms = nsyms;
-#if ELF_CLASS == ELFCLASS32
-    s->disas_symtab.elf32 = syms;
-#else
-    s->disas_symtab.elf64 = syms;
-#endif
-    s->lookup_symbol = lookup_symbolxx;
-    s->next = syminfos;
-    syminfos = s;
+    {
+        struct syminfo *s = g_new(struct syminfo, 1);
 
+        s->disas_strtab = strings;
+        s->disas_num_syms = nsyms;
+#if ELF_CLASS == ELFCLASS32
+        s->disas_symtab.elf32 = syms;
+#else
+        s->disas_symtab.elf64 = syms;
+#endif
+        s->lookup_symbol = lookup_symbolxx;
+        s->next = syminfos;
+        syminfos = s;
+    }
     return;
 
-give_up:
-    g_free(s);
+ give_up:
     g_free(strings);
     g_free(syms);
 }
-- 
2.25.1



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

* [PATCH 07/12] linux-user: Replace bprm->fd with bprm->src.fd
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (5 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 06/12] linux-user: Use ImageSource in load_symbols Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  9:54   ` Philippe Mathieu-Daudé
  2021-06-19  3:43 ` [PATCH 08/12] linux-user: Introduce imgsrc_mmap Richard Henderson
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

There are only a couple of uses of bprm->fd remaining.
Migrate to the other field.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/qemu.h      | 1 -
 linux-user/flatload.c  | 8 ++++----
 linux-user/linuxload.c | 5 ++---
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index f4cdfb16b3..dafaae6293 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -211,7 +211,6 @@ struct linux_binprm {
     char buf[BPRM_BUF_SIZE] __attribute__((aligned));
     ImageSource src;
     abi_ulong p;
-    int fd;
     int e_uid, e_gid;
     int argc, envc;
     char **argv;
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index 3e5594cf89..58d0d9352c 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -460,7 +460,7 @@ static int load_flat_file(struct linux_binprm * bprm,
         DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
         textpos = target_mmap(0, text_len, PROT_READ|PROT_EXEC,
-                              MAP_PRIVATE, bprm->fd, 0);
+                              MAP_PRIVATE, bprm->src.fd, 0);
         if (textpos == -1) {
             fprintf(stderr, "Unable to mmap process text\n");
             return -1;
@@ -487,7 +487,7 @@ static int load_flat_file(struct linux_binprm * bprm,
         } else
 #endif
         {
-            result = target_pread(bprm->fd, datapos,
+            result = target_pread(bprm->src.fd, datapos,
                                   data_len + (relocs * sizeof(abi_ulong)),
                                   fpos);
         }
@@ -537,10 +537,10 @@ static int load_flat_file(struct linux_binprm * bprm,
         else
 #endif
         {
-            result = target_pread(bprm->fd, textpos,
+            result = target_pread(bprm->src.fd, textpos,
                                   text_len, 0);
             if (result >= 0) {
-                result = target_pread(bprm->fd, datapos,
+                result = target_pread(bprm->src.fd, datapos,
                     data_len + (relocs * sizeof(abi_ulong)),
                     ntohl(hdr->data_start));
             }
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index 8b93b9704c..d0d3f2ed0e 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -36,7 +36,7 @@ static int prepare_binprm(struct linux_binprm *bprm)
     int mode;
     int retval;
 
-    if (fstat(bprm->fd, &st) < 0) {
+    if (fstat(bprm->src.fd, &st) < 0) {
         return -errno;
     }
 
@@ -66,7 +66,7 @@ static int prepare_binprm(struct linux_binprm *bprm)
         bprm->e_gid = st.st_gid;
     }
 
-    retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE);
+    retval = read(bprm->src.fd, bprm->buf, BPRM_BUF_SIZE);
     if (retval < 0) {
         perror("prepare_binprm");
         exit(-1);
@@ -133,7 +133,6 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
 {
     int retval;
 
-    bprm->fd = fdexec;
     bprm->src.fd = fdexec;
     bprm->filename = (char *)filename;
     bprm->argc = count(argv);
-- 
2.25.1



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

* [PATCH 08/12] linux-user: Introduce imgsrc_mmap
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (6 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 07/12] linux-user: Replace bprm->fd with bprm->src.fd Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 09/12] linux-user: Load vdso image if available Richard Henderson
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/qemu.h      | 11 +++++++++++
 linux-user/elfload.c   |  4 ++--
 linux-user/linuxload.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index dafaae6293..255182e133 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -199,6 +199,17 @@ bool imgsrc_read(void *dst, off_t offset, size_t len,
 void *imgsrc_read_alloc(off_t offset, size_t len,
                         const ImageSource *img, Error **errp);
 
+/**
+ * imgsrc_mmap: Map from ImageSource
+ *
+ * If @src has a file descriptor, pass on to target_mmap.  Otherwise,
+ * this is "mapping" from a host buffer, which resolves to memcpy.
+ * Therefore, flags must be MAP_PRIVATE | MAP_FIXED; the argument is
+ * retained for clarity.
+ */
+abi_long imgsrc_mmap(abi_ulong start, abi_ulong len, int prot,
+                     int flags, const ImageSource *src, abi_ulong offset);
+
 /* Read a good amount of data initially, to hopefully get all the
    program headers loaded.  */
 #define BPRM_BUF_SIZE  1024
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 3c31a5e3b0..8a3a7ae3ac 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2832,9 +2832,9 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
              */
             if (eppnt->p_filesz != 0) {
                 vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_filesz + vaddr_po);
-                error = target_mmap(vaddr_ps, vaddr_len, elf_prot,
+                error = imgsrc_mmap(vaddr_ps, vaddr_len, elf_prot,
                                     MAP_PRIVATE | MAP_FIXED,
-                                    src->fd, eppnt->p_offset - vaddr_po);
+                                    src, eppnt->p_offset - vaddr_po);
 
                 if (error == -1) {
                     goto exit_mmap;
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index d0d3f2ed0e..a437a22b49 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -208,3 +208,47 @@ void *imgsrc_read_alloc(off_t offset, size_t len,
     }
     return alloc;
 }
+
+abi_long imgsrc_mmap(abi_ulong start, abi_ulong len, int prot,
+                     int flags, const ImageSource *src, abi_ulong offset)
+{
+    abi_long ret;
+    int prot_write;
+    void *haddr;
+
+    assert(flags == (MAP_PRIVATE | MAP_FIXED));
+
+    if (src->fd >= 0) {
+        return target_mmap(start, len, prot, flags, src->fd, offset);
+    }
+
+    /*
+     * This case is for the vdso; we don't expect bad images.
+     * The mmap may extend beyond the end of the image, especially
+     * to the end of the page.  Zero fill.
+     */
+    assert(offset < src->cache_size);
+
+    prot_write = prot | PROT_WRITE;
+    ret = target_mmap(start, len, prot_write, flags | MAP_ANON, -1, 0);
+    if (ret == -1) {
+        return ret;
+    }
+
+    haddr = lock_user(VERIFY_WRITE, start, len, 0);
+    assert(haddr != NULL);
+    if (offset + len < src->cache_size) {
+        memcpy(haddr, src->cache + offset, len);
+    } else {
+        size_t rest = src->cache_size - offset;
+        memcpy(haddr, src->cache + offset, rest);
+        memset(haddr + rest, 0, len - rest);
+    }
+    unlock_user(haddr, start, len);
+
+    if (prot != prot_write) {
+        target_mprotect(start, len, prot);
+    }
+
+    return ret;
+}
-- 
2.25.1



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

* [PATCH 09/12] linux-user: Load vdso image if available
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (7 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 08/12] linux-user: Introduce imgsrc_mmap Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 10/12] linux-user: Add gen-vdso tool Richard Henderson
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

The vdso image will be pre-processed into a C data array, with
a simple list of relocations to perform, and identifying the
location of signal trampolines.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c | 75 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 8 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 8a3a7ae3ac..a6ad454617 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1966,7 +1966,8 @@ static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong s
 static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
                                    struct elfhdr *exec,
                                    struct image_info *info,
-                                   struct image_info *interp_info)
+                                   struct image_info *interp_info,
+                                   struct image_info *vdso_info)
 {
     abi_ulong sp;
     abi_ulong u_argc, u_argv, u_envp, u_auxv;
@@ -2038,8 +2039,12 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     }
 
     size = (DLINFO_ITEMS + 1) * 2;
-    if (k_platform)
+    if (k_platform) {
         size += 2;
+    }
+    if (vdso_info) {
+        size += 4;
+    }
 #ifdef DLINFO_ARCH_ITEMS
     size += DLINFO_ARCH_ITEMS * 2;
 #endif
@@ -2116,6 +2121,10 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     if (u_platform) {
         NEW_AUX_ENT(AT_PLATFORM, u_platform);
     }
+    if (vdso_info) {
+        NEW_AUX_ENT(AT_SYSINFO, vdso_info->entry);
+        NEW_AUX_ENT(AT_SYSINFO_EHDR, vdso_info->load_addr);
+    }
     NEW_AUX_ENT (AT_NULL, 0);
 #undef NEW_AUX_ENT
 
@@ -2942,6 +2951,53 @@ static void load_elf_interp(const char *filename, struct image_info *info,
     load_elf_image(filename, &src, info, &ehdr, NULL);
 }
 
+#ifndef HAVE_VDSO
+#define HAVE_VDSO 0
+static uint8_t vdso_image[] = { };
+static uint32_t vdso_relocs[] = { };
+#define vdso_sigreturn 0
+#define vdso_rt_sigreturn 0
+#endif
+
+static void load_elf_vdso(struct image_info *info)
+{
+    ImageSource src;
+    struct elfhdr ehdr;
+    abi_ulong load_bias, load_addr;
+
+    src.fd = -1;
+    src.cache = vdso_image;
+    src.cache_size = sizeof(vdso_image);
+
+    load_elf_image("<internal-vdso>", &src, info, &ehdr, NULL);
+    load_addr = info->load_addr;
+    load_bias = info->load_bias;
+
+    /*
+     * We need to relocate the VDSO image.  The one built into the kernel
+     * is built for a fixed address.  The one built for QEMU is not, since
+     * that requires close control of the guest address space.
+     * We pre-processed the image to locate all of the addresses that need
+     * to be updated.
+     */
+    for (size_t i = 0, n = ARRAY_SIZE(vdso_relocs); i < n; i++) {
+        abi_ulong *addr = g2h_untagged(load_addr + vdso_relocs[i]);
+        *addr = tswapal(tswapal(*addr) + load_bias);
+    }
+
+    /* Install signal trampolines, if present. */
+    if (vdso_sigreturn) {
+        default_sigreturn = load_addr + vdso_sigreturn;
+    }
+    if (vdso_rt_sigreturn) {
+        default_rt_sigreturn = load_addr + vdso_rt_sigreturn;
+    }
+
+    /* Mark the VDSO writable segment read-only. */
+    target_mprotect(info->start_data, info->end_data - info->start_data,
+                    PROT_READ);
+}
+
 static int symfind(const void *s0, const void *s1)
 {
     target_ulong addr = *(target_ulong *)s0;
@@ -3146,7 +3202,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
      * and let elf_load_image do any swapping that may be required.
      */
     struct elfhdr ehdr;
-    struct image_info interp_info;
+    struct image_info interp_info, vdso_info;
     char *elf_interpreter = NULL;
     char *scratch;
 
@@ -3216,10 +3272,12 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
     }
 
     /*
-     * TODO: load a vdso, which would also contain the signal trampolines.
-     * Otherwise, allocate a private page to hold them.
+     * Load a vdso if available, which will amongst other things contain the
+     * signal trampolines.  Otherwise, allocate a separate page for them.
      */
-    if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) {
+    if (HAVE_VDSO) {
+        load_elf_vdso(&vdso_info);
+    } else if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) {
         abi_ulong tramp_page = target_mmap(0, TARGET_PAGE_SIZE,
                                            PROT_READ | PROT_WRITE,
                                            MAP_PRIVATE | MAP_ANON, -1, 0);
@@ -3227,8 +3285,9 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
         target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC);
     }
 
-    bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr,
-                                info, (elf_interpreter ? &interp_info : NULL));
+    bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr, info,
+                                elf_interpreter ? &interp_info : NULL,
+                                HAVE_VDSO ? &vdso_info : NULL);
     info->start_stack = bprm->p;
 
     /* If we have an interpreter, set that as the program's entry point.
-- 
2.25.1



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

* [PATCH 10/12] linux-user: Add gen-vdso tool
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (8 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 09/12] linux-user: Load vdso image if available Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 11/12] linux-user/x86_64: Add vdso Richard Henderson
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

This tool will be used for post-processing the linked vdso image,
turning it into something that is easy to include into elfload.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/gen-vdso.c          | 168 ++++++++++++++++++
 linux-user/gen-vdso-elfn.c.inc | 299 +++++++++++++++++++++++++++++++++
 linux-user/meson.build         |   6 +-
 3 files changed, 472 insertions(+), 1 deletion(-)
 create mode 100644 linux-user/gen-vdso.c
 create mode 100644 linux-user/gen-vdso-elfn.c.inc

diff --git a/linux-user/gen-vdso.c b/linux-user/gen-vdso.c
new file mode 100644
index 0000000000..ccbb6c4725
--- /dev/null
+++ b/linux-user/gen-vdso.c
@@ -0,0 +1,168 @@
+/*
+ * Post-process a vdso elf image for inclusion into qemu.
+ *
+ * Copyright 2021 Linaro, Ltd.
+ * 
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <endian.h>
+#include "elf.h"
+
+
+#define bswap_(p)  _Generic(*(p), \
+                            uint16_t: __builtin_bswap16,       \
+                            uint32_t: __builtin_bswap32,       \
+                            uint64_t: __builtin_bswap64,       \
+                            int16_t: __builtin_bswap16,        \
+                            int32_t: __builtin_bswap32,        \
+                            int64_t: __builtin_bswap64)
+#define bswaps(p) (*(p) = bswap_(p)(*(p)))
+
+static void output_reloc(FILE *outf, void *buf, void *loc)
+{
+    fprintf(outf, "    0x%08lx,\n", loc - buf);
+}
+
+#define N 32
+#define elfN(x)  elf32_##x
+#define ElfN(x)  Elf32_##x
+#include "gen-vdso-elfn.c.inc"
+#undef N
+#undef elfN
+#undef ElfN
+
+#define N 64
+#define elfN(x)  elf64_##x
+#define ElfN(x)  Elf64_##x
+#include "gen-vdso-elfn.c.inc"
+#undef N
+#undef elfN
+#undef ElfN
+
+
+int main(int ac, char **av)
+{
+    FILE *inf, *outf;
+    long total_len;
+    const char *inf_name;
+    const char *outf_name;
+    unsigned char *buf;
+    bool need_bswap;
+
+    if (ac != 3) {
+        fprintf(stderr, "usage: input-file output-file\n");
+        return EXIT_FAILURE;
+    }
+    inf_name = av[1];
+    outf_name = av[2];
+
+    /*
+     * Open the input and output files.
+     */
+    inf = fopen(inf_name, "rb");
+    if (inf == NULL) {
+        goto perror_inf;
+    }
+    outf = fopen(outf_name, "w");
+    if (outf == NULL) {
+        goto perror_outf;
+    }
+
+    /*
+     * Read the input file into a buffer.
+     * We expect the vdso to be small, on the order of one page,
+     * therefore we do not expect a partial read.
+     */
+    fseek(inf, 0, SEEK_END);
+    total_len = ftell(inf);
+    fseek(inf, 0, SEEK_SET);
+
+    buf = malloc(total_len);
+    if (buf == NULL) {
+        goto perror_inf;
+    }
+
+    errno = 0;
+    if (fread(buf, 1, total_len, inf) != total_len) {
+        if (errno) {
+            goto perror_inf;
+        }
+        fprintf(stderr, "%s: incomplete read\n", inf_name);
+        return EXIT_FAILURE;
+    }
+    fclose(inf);
+
+    /*
+     * Write out the vdso image now, before we make local changes.
+     */
+
+    fputs("/* Automatically generated from linux-user/gen-vdso.c. */\n"
+          "\n"
+          "static const uint8_t vdso_image[] = {",
+          outf);
+    for (long i = 0; i < total_len; ++i) {
+        if (i % 12 == 0) {
+            fputs("\n   ", outf);
+        }
+        fprintf(outf, " 0x%02x,", buf[i]);
+    }
+    fputs("\n};\n\n", outf);
+
+    /*
+     * Identify which elf flavor we're processing.
+     * The first 16 bytes of the file are e_ident.
+     */
+
+    if (buf[EI_MAG0] != ELFMAG0 || buf[EI_MAG1] != ELFMAG1 ||
+        buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3) {
+        fprintf(stderr, "%s: not an elf file\n", inf_name);
+        return EXIT_FAILURE;
+    }
+    switch (buf[EI_DATA]) {
+    case ELFDATA2LSB:
+        need_bswap = BYTE_ORDER != LITTLE_ENDIAN;
+        break;
+    case ELFDATA2MSB:
+        need_bswap = BYTE_ORDER != BIG_ENDIAN;
+        break;
+    default:
+        fprintf(stderr, "%s: invalid elf EI_DATA (%u)\n",
+                inf_name, buf[EI_DATA]);
+        return EXIT_FAILURE;
+    }
+    switch (buf[EI_CLASS]) {
+    case ELFCLASS32:
+        elf32_process(outf, buf, total_len, need_bswap);
+        break;
+    case ELFCLASS64:
+        elf64_process(outf, buf, total_len, need_bswap);
+        break;
+    default:
+        fprintf(stderr, "%s: invalid elf EI_CLASS (%u)\n",
+                inf_name, buf[EI_CLASS]);
+        return EXIT_FAILURE;
+    }
+
+    /*
+     * Everything should have gone well.
+     */
+    if (fclose(outf)) {
+        goto perror_outf;
+    }
+    return EXIT_SUCCESS;
+
+ perror_inf:
+    perror(inf_name);
+    return EXIT_FAILURE;
+
+ perror_outf:
+    perror(outf_name);
+    return EXIT_FAILURE;
+}
diff --git a/linux-user/gen-vdso-elfn.c.inc b/linux-user/gen-vdso-elfn.c.inc
new file mode 100644
index 0000000000..4e9277aeff
--- /dev/null
+++ b/linux-user/gen-vdso-elfn.c.inc
@@ -0,0 +1,299 @@
+/*
+ * Post-process a vdso elf image for inclusion into qemu.
+ * Elf size specialization.
+ *
+ * Copyright 2021 Linaro, Ltd.
+ * 
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+static void elfN(bswap_ehdr)(ElfN(Ehdr) *ehdr)
+{
+    bswaps(&ehdr->e_type);            /* Object file type */
+    bswaps(&ehdr->e_machine);         /* Architecture */
+    bswaps(&ehdr->e_version);         /* Object file version */
+    bswaps(&ehdr->e_entry);           /* Entry point virtual address */
+    bswaps(&ehdr->e_phoff);           /* Program header table file offset */
+    bswaps(&ehdr->e_shoff);           /* Section header table file offset */
+    bswaps(&ehdr->e_flags);           /* Processor-specific flags */
+    bswaps(&ehdr->e_ehsize);          /* ELF header size in bytes */
+    bswaps(&ehdr->e_phentsize);       /* Program header table entry size */
+    bswaps(&ehdr->e_phnum);           /* Program header table entry count */
+    bswaps(&ehdr->e_shentsize);       /* Section header table entry size */
+    bswaps(&ehdr->e_shnum);           /* Section header table entry count */
+    bswaps(&ehdr->e_shstrndx);        /* Section header string table index */
+}
+
+static void elfN(bswap_phdr)(ElfN(Phdr) *phdr)
+{
+    bswaps(&phdr->p_type);            /* Segment type */
+    bswaps(&phdr->p_flags);           /* Segment flags */
+    bswaps(&phdr->p_offset);          /* Segment file offset */
+    bswaps(&phdr->p_vaddr);           /* Segment virtual address */
+    bswaps(&phdr->p_paddr);           /* Segment physical address */
+    bswaps(&phdr->p_filesz);          /* Segment size in file */
+    bswaps(&phdr->p_memsz);           /* Segment size in memory */
+    bswaps(&phdr->p_align);           /* Segment alignment */
+}
+
+static void elfN(bswap_shdr)(ElfN(Shdr) *shdr)
+{
+    bswaps(&shdr->sh_name);
+    bswaps(&shdr->sh_type);
+    bswaps(&shdr->sh_flags);
+    bswaps(&shdr->sh_addr);
+    bswaps(&shdr->sh_offset);
+    bswaps(&shdr->sh_size);
+    bswaps(&shdr->sh_link);
+    bswaps(&shdr->sh_info);
+    bswaps(&shdr->sh_addralign);
+    bswaps(&shdr->sh_entsize);
+}
+
+static void elfN(bswap_sym)(ElfN(Sym) *sym)
+{
+    bswaps(&sym->st_name);
+    bswaps(&sym->st_value);
+    bswaps(&sym->st_size);
+    bswaps(&sym->st_shndx);
+}
+
+static void elfN(bswap_dyn)(ElfN(Dyn) *dyn)
+{
+    bswaps(&dyn->d_tag);              /* Dynamic type tag */
+    bswaps(&dyn->d_un.d_ptr);         /* Dynamic ptr or val, in union */
+}
+
+static void elfN(process)(FILE *outf, void *buf, long total_len,
+                          bool need_bswap)
+{
+    ElfN(Ehdr) *ehdr = buf;
+    ElfN(Phdr) *phdr;
+    ElfN(Shdr) *shdr;
+    unsigned phnum, shnum;
+    unsigned dynamic_ofs = 0;
+    unsigned dynamic_addr = 0;
+    unsigned dynsym_addr = 0;
+    unsigned sigreturn_addr = 0;
+    unsigned rt_sigreturn_addr = 0;
+    unsigned first_segsz = 0;
+    int errors = 0;
+
+    if (need_bswap) {
+        elfN(bswap_ehdr)(ehdr);
+    }
+
+    phnum = ehdr->e_phnum;
+    phdr = buf + ehdr->e_phoff;
+    if (need_bswap) {
+        for (unsigned i = 0; i < phnum; ++i) {
+            elfN(bswap_phdr)(phdr + i);
+        }
+    }
+
+    shnum = ehdr->e_shnum;
+    shdr = buf + ehdr->e_shoff;
+    if (need_bswap) {
+        for (unsigned i = 0; i < shnum; ++i) {
+            elfN(bswap_shdr)(shdr + i);
+        }
+    }
+
+    /*
+     * Validate the VDSO is created as we expect: that PT_PHDR,
+     * PT_DYNAMIC, and PT_NOTE located in a writable data segment.
+     * PHDR and DYNAMIC require relocation, and NOTE will get the
+     * linux version number.
+     */
+    for (unsigned i = 0; i < phnum; ++i) {
+        if (phdr[i].p_type == PT_LOAD && phdr[i].p_vaddr == 0) {
+            if (first_segsz != 0) {
+                fprintf(stderr, "Multiple load segments covering EHDR\n");
+                errors++;
+            }
+            if (phdr[i].p_offset != 0) {
+                fprintf(stderr, "First vdso segment does not cover EHDR\n");
+                errors++;
+            }
+            if (phdr[i].p_vaddr != 0) {
+                fprintf(stderr, "First vdso segment not loaded at address 0\n");
+                errors++;
+            }
+            if ((phdr[i].p_flags & (PF_R | PF_W)) != (PF_R | PF_W)) {
+                fprintf(stderr, "First vdso segment is not read-write\n");
+                errors++;
+            }
+            first_segsz = phdr[i].p_filesz;
+            if (first_segsz < ehdr->e_phoff + phnum * sizeof(*phdr)) {
+                fprintf(stderr, "First vdso segment does not cover PHDRs\n");
+                errors++;
+            }
+        }
+    }
+    for (unsigned i = 0; i < phnum; ++i) {
+        const char *which;
+
+        switch (phdr[i].p_type) {
+        case PT_PHDR:
+            which = "PT_PHDR";
+            break;
+        case PT_NOTE:
+            which = "PT_NOTE";
+            break;
+        case PT_DYNAMIC:
+            dynamic_ofs = phdr[i].p_offset;
+            dynamic_addr = phdr[i].p_vaddr;
+            which = "PT_DYNAMIC";
+            break;
+        default:
+            continue;
+        }
+        if (first_segsz < phdr[i].p_vaddr + phdr[i].p_filesz) {
+            fprintf(stderr, "First vdso segment does not cover %s\n", which);
+            errors++;
+        }
+    }
+    if (errors) {
+        exit(EXIT_FAILURE);
+    }
+        
+    /*
+     * We need to relocate the VDSO image.  The one built into the kernel
+     * is built for a fixed address.  The one we built for QEMU is not,
+     * since that requires close control of the guest address space.
+     *
+     * ??? One might think that we'd need to relocate ehdr->e_entry,
+     * but for some reason glibc does that one itself, though that
+     * is also available via the AT_SYSINFO entry.
+     *
+     * Output relocation addresses as we go.
+     */
+    fputs("static const unsigned vdso_relocs[] = {\n", outf);
+
+    /* Relocate the program headers. */
+    for (unsigned i = 0; i < phnum; ++i) {
+        output_reloc(outf, buf, &phdr[i].p_vaddr);
+        output_reloc(outf, buf, &phdr[i].p_paddr);
+    }
+
+    /* Relocate the DYNAMIC entries. */
+    if (dynamic_addr) {
+        ElfN(Dyn) *dyn = buf + dynamic_ofs;
+        __typeof(dyn->d_tag) tag;
+
+        do {
+
+            if (need_bswap) {
+                elfN(bswap_dyn)(dyn);
+            }
+            tag = dyn->d_tag;
+
+            switch (tag) {
+            case DT_SYMTAB:
+                dynsym_addr = dyn->d_un.d_val;
+                /* fall through */
+            case DT_HASH:
+            case DT_STRTAB:
+            case DT_VERDEF:
+            case DT_VERSYM:
+            case DT_PLTGOT:
+            case DT_ADDRRNGLO ... DT_ADDRRNGHI:
+                /* These entries store an address in the entry. */
+                output_reloc(outf, buf, &dyn->d_un.d_val);
+                break;
+
+            case DT_NULL:
+            case DT_STRSZ:
+            case DT_SONAME:
+            case DT_DEBUG:
+            case DT_FLAGS:
+            case DT_FLAGS_1:
+            case DT_BIND_NOW:
+            case DT_VERDEFNUM:
+            case DT_VALRNGLO ... DT_VALRNGHI:
+                /* These entries store an integer in the entry. */
+                break;
+
+            case DT_SYMENT:
+                if (dyn->d_un.d_val != sizeof(ElfN(Sym))) {
+                    fprintf(stderr, "VDSO has incorrect dynamic symbol size\n");
+                    errors++;
+                }
+                break;
+
+            case DT_REL:
+            case DT_RELSZ:
+            case DT_RELENT:
+            case DT_RELA:
+            case DT_RELASZ:
+            case DT_RELAENT:
+            case DT_TEXTREL:
+                /*
+                 * These entries indicate that the VDSO was built incorrectly.
+                 * It should not have any real relocations.
+                 */
+                fprintf(stderr, "VDSO has dynamic relocations\n");
+                errors++;
+                break;
+
+            case DT_NEEDED:
+            case DT_VERNEED:
+            case DT_PLTREL:
+            case DT_JMPREL:
+            case DT_RPATH:
+            case DT_RUNPATH:
+                fprintf(stderr, "VDSO has external dependencies\n");
+                errors++;
+                break;
+
+            default:
+                /* This is probably something target specific. */
+                fprintf(stderr, "VDSO has unknown DYNAMIC entry (%lx)\n",
+                        (unsigned long)tag);
+                errors++;
+                break;
+            }
+            dyn++;
+        } while (tag != DT_NULL);
+        if (errors) {
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    if (dynsym_addr) {
+        __typeof(shdr->sh_size) dynsym_n = 0;
+        ElfN(Sym) *sym = NULL;
+        const char *str = NULL;
+
+        for (unsigned i = 0; i < shnum; ++i) {
+            if (shdr[i].sh_addr == dynsym_addr) {
+                dynsym_n = shdr[i].sh_size / sizeof(*sym);
+                sym = buf + shdr[i].sh_offset;
+                str = buf + shdr[shdr[i].sh_link].sh_offset;
+                break;
+            }
+        }
+
+        for (unsigned i = 0; i < dynsym_n; ++i) {
+            if (need_bswap) {
+                elfN(bswap_sym)(sym + i);
+            }
+
+            /* Relocate the dynamic symbol table. */
+            output_reloc(outf, buf, &sym[i].st_value);
+
+            /* Locate the signal return symbols. */
+            const char *name = str + sym[i].st_name;
+            if (strcmp("__kernel_sigreturn", name) == 0) {
+                sigreturn_addr = sym[i].st_value;
+            } else if (strcmp("__kernel_rt_sigreturn", name) == 0) {
+                rt_sigreturn_addr = sym[i].st_value;
+            }
+        }
+    }
+
+    fputs("};\n\n", outf);   /* end vdso_relocs. */
+
+    fprintf(outf, "#define vdso_sigreturn    0x%x\n", sigreturn_addr);
+    fprintf(outf, "#define vdso_rt_sigreturn 0x%x\n", rt_sigreturn_addr);
+}
diff --git a/linux-user/meson.build b/linux-user/meson.build
index 9549f81682..c5e6ab058b 100644
--- a/linux-user/meson.build
+++ b/linux-user/meson.build
@@ -18,9 +18,13 @@ linux_user_ss.add(when: 'TARGET_HAS_BFLT', if_true: files('flatload.c'))
 linux_user_ss.add(when: 'TARGET_I386', if_true: files('vm86.c'))
 linux_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', if_true: files('semihost.c'))
 
-
 syscall_nr_generators = {}
 
+gen_vdso_exe = executable('gen-vdso', 'gen-vdso.c',
+                          native: true, build_by_default: false)
+gen_vdso = generator(gen_vdso_exe, output: '@BASENAME@.c.inc',
+                     arguments: ['@INPUT@', '@OUTPUT@'])
+
 subdir('alpha')
 subdir('arm')
 subdir('hppa')
-- 
2.25.1



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

* [PATCH 11/12] linux-user/x86_64: Add vdso
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (9 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 10/12] linux-user: Add gen-vdso tool Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  3:43 ` [PATCH 12/12] linux-user/hppa: Add vdso and use it for rt_sigreturn Richard Henderson
  2021-06-19  4:06 ` [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa no-reply
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Building the vdso itself is not actually wired up to anything, since
we require a cross-compiler.  Just check in that file for now.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c            |   3 +
 linux-user/x86_64/Makefile.vdso |   3 +
 linux-user/x86_64/meson.build   |   6 ++
 linux-user/x86_64/vdso.S        | 122 ++++++++++++++++++++++++++++++++
 linux-user/x86_64/vdso.ld       |  74 +++++++++++++++++++
 linux-user/x86_64/vdso.so       | Bin 0 -> 5912 bytes
 6 files changed, 208 insertions(+)
 create mode 100644 linux-user/x86_64/Makefile.vdso
 create mode 100644 linux-user/x86_64/vdso.S
 create mode 100644 linux-user/x86_64/vdso.ld
 create mode 100755 linux-user/x86_64/vdso.so

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a6ad454617..b70a5c48a2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -154,6 +154,9 @@ static uint32_t get_elf_hwcap(void)
 #define ELF_CLASS      ELFCLASS64
 #define ELF_ARCH       EM_X86_64
 
+#define HAVE_VDSO 1
+#include "vdso.c.inc"
+
 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
 {
     regs->rax = 0;
diff --git a/linux-user/x86_64/Makefile.vdso b/linux-user/x86_64/Makefile.vdso
new file mode 100644
index 0000000000..6111d6f21c
--- /dev/null
+++ b/linux-user/x86_64/Makefile.vdso
@@ -0,0 +1,3 @@
+vdso.so: vdso.S vdso.ld Makefile.vdso
+	$(CC) -nostdlib -shared -Wl,-T,vdso.ld -Wl,--build-id=none \
+	  -Wl,-h,linux-vdso.so.1 -Wl,--hash-style=both vdso.S -o $@
diff --git a/linux-user/x86_64/meson.build b/linux-user/x86_64/meson.build
index 203af9a60c..f6a0015953 100644
--- a/linux-user/x86_64/meson.build
+++ b/linux-user/x86_64/meson.build
@@ -3,3 +3,9 @@ syscall_nr_generators += {
                       arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
                       output: '@BASENAME@_nr.h')
 }
+
+gen = [
+  gen_vdso.process('vdso.so')
+]
+
+linux_user_ss.add(when: 'TARGET_X86_64', if_true: gen)
diff --git a/linux-user/x86_64/vdso.S b/linux-user/x86_64/vdso.S
new file mode 100644
index 0000000000..7d0d653526
--- /dev/null
+++ b/linux-user/x86_64/vdso.S
@@ -0,0 +1,122 @@
+/*
+ * x86-64 linux replacement vdso.
+ *
+ * Copyright 2021 Linaro, Ltd.
+ * 
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <asm/unistd.h>
+
+	.globl	__vdso_clock_gettime
+	.type	__vdso_clock_gettime, @function
+	.balign	16
+	.cfi_startproc
+__vdso_clock_gettime:
+	mov	$__NR_clock_gettime, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_clock_gettime, . - __vdso_clock_gettime
+
+clock_gettime = __vdso_clock_gettime
+	.weak	clock_gettime
+
+	.globl	__vdso_clock_getres
+	.type	__vdso_clock_getres, @function
+	.balign	16
+	.cfi_startproc
+__vdso_clock_getres:
+	mov	$__NR_clock_getres, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_clock_getres, . - __vdso_clock_getres
+
+clock_getres = __vdso_clock_getres
+	.weak	clock_getres
+
+	.globl	__vdso_gettimeofday
+	.type	__vdso_gettimeofday, @function
+	.balign	16
+	.cfi_startproc
+__vdso_gettimeofday:
+	mov	$__NR_gettimeofday, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_gettimeofday, . - __vdso_gettimeofday
+
+gettimeofday = __vdso_gettimeofday
+	.weak	gettimeofday
+
+
+	.globl	__vdso_time
+	.type	__vdso_time, @function
+	.balign	16
+	.cfi_startproc
+__vdso_time:
+	mov	$__NR_time, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_time, . - __vdso_time
+
+time = __vdso_time
+	.weak	time
+
+
+	.globl	__vdso_getcpu
+	.type	__vdso_getcpu, @function
+	.balign	16
+	.cfi_startproc
+__vdso_getcpu:
+	/*
+         * ??? There is no syscall number for this allocated on x64.
+	 * We can handle this several ways:
+         *
+	 * (1) Invent a syscall number for use within qemu.
+         *     It should be easy enough to pick a number that
+         *     is well out of the way of the kernel numbers.
+         *
+         * (2) Force the emulated cpu to support the rdtscp insn,
+	 *     and initialize the TSC_AUX value the appropriate value.
+         *
+	 * (3) Pretend that we're always running on cpu 0.
+         *
+	 * This last is the one that's implemented here, with the
+	 * tiny bit of extra code to support rdtscp in place.
+         */
+	xor	%ecx, %ecx		/* rdtscp w/ tsc_aux = 0 */
+
+	/* if (cpu != NULL) *cpu = (ecx & 0xfff); */
+	test	%rdi, %rdi
+	jz	1f
+	mov	%ecx, %eax
+	and	$0xfff, %eax
+	mov	%eax, (%rdi)
+
+	/* if (node != NULL) *node = (ecx >> 12); */
+1:	test	%rsi, %rsi
+	jz	2f
+	shr	$12, %ecx
+	mov	%ecx, (%rsi)
+
+2:	xor	%eax, %eax
+	ret
+	.cfi_endproc
+	.size	__vdso_getcpu, . - __vdso_getcpu
+
+getcpu = __vdso_getcpu
+	.weak	getcpu
+
+/*
+ * ??? Perhaps add elf notes.  E.g.
+ *
+ * #include <linux/elfnote.h>
+ * ELFNOTE_START(Linux, 0, "a")
+ *   .long LINUX_VERSION_CODE
+ * ELFNOTE_END
+ *
+ * but what version number would we set for QEMU?
+ */
diff --git a/linux-user/x86_64/vdso.ld b/linux-user/x86_64/vdso.ld
new file mode 100644
index 0000000000..baf261f045
--- /dev/null
+++ b/linux-user/x86_64/vdso.ld
@@ -0,0 +1,74 @@
+/*
+ * Linker script for linux x86-64 replacement vdso.
+ *
+ * Copyright 2021 Linaro, Ltd.
+ * 
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+VERSION {
+        LINUX_2.6 {
+        global:
+                clock_gettime;
+                __vdso_clock_gettime;
+                gettimeofday;
+                __vdso_gettimeofday;
+                getcpu;
+                __vdso_getcpu;
+                time;
+                __vdso_time;
+                clock_getres;
+                __vdso_clock_getres;
+
+        local: *;
+        };
+}
+
+
+PHDRS {
+        phdr            PT_PHDR         FLAGS(4) PHDRS;
+        data            PT_LOAD         FLAGS(6) FILEHDR PHDRS;
+        text            PT_LOAD         FLAGS(5);
+        dynamic         PT_DYNAMIC      FLAGS(4);
+        eh_frame_hdr    PT_GNU_EH_FRAME;
+        note            PT_NOTE         FLAGS(4);
+}
+
+SECTIONS {
+        /* ??? We can't really prelink to any address without knowing
+           something about the virtual memory space of the host, since
+           that leaks over into the available memory space of the guest.  */
+        . = SIZEOF_HEADERS;
+
+        /* The following, including the FILEHDRS and PHDRS, are modified
+           when we relocate the binary.  We want them to be initially
+           writable for the relocation; we'll force them read-only after.  */
+        .note           : { *(.note*) }         :data :note
+        .dynamic        : { *(.dynamic) }       :data :dynamic
+        .dynsym         : { *(.dynsym) }        :data
+        .data           : {
+                /* There ought not be any real read-write data.
+                   But since we manipulated the segment layout,
+                   we have to put these sections somewhere.  */
+                *(.data*)
+                *(.sdata*)
+                *(.got.plt) *(.got)
+                *(.gnu.linkonce.d.*)
+                *(.bss*)
+                *(.dynbss*)
+                *(.gnu.linkonce.b.*)
+        }
+
+        .rodata         : { *(.rodata*) }
+        .hash           : { *(.hash) }
+        .gnu.hash       : { *(.gnu.hash) }
+        .dynstr         : { *(.dynstr) }
+        .gnu.version    : { *(.gnu.version) }
+        .gnu.version_d  : { *(.gnu.version_d) }
+        .gnu.version_r  : { *(.gnu.version_r) }
+        .eh_frame_hdr   : { *(.eh_frame_hdr) }  :data :eh_frame_hdr
+        .eh_frame       : { *(.eh_frame) }      :data
+
+        . = ALIGN(4096);
+        .text           : { *(.text*) }         :text   =0x90909090
+}
diff --git a/linux-user/x86_64/vdso.so b/linux-user/x86_64/vdso.so
new file mode 100755
index 0000000000000000000000000000000000000000..0cdb8f1706893abf221e42d3443d9f5d49fef080
GIT binary patch
literal 5912
zcmeHL&ud&&6h4#5G>PWNw2COv8bm7;9TF)LD3qy9;>5Ng1_DtiuhYzHCzzShnU^w=
zQbCLwDVjwW#YJgxFIg5hDiyK*1ybnF3T~t>3@+61eDlsXyt#d~g5c_%<jr^Qch5QR
z-gDm@=DY7qADih(rG%E2L(=YLLndznmmZ>rNM0somwpb*kfKPhUU?gKao$oB`^^tD
zV((?&WWo`m*nAMz9<n}p;t5MgB;TVv=DB6_aWP!9I@mbpIe$ASAuen4aq)nT!HDpM
z0oiU7_xa%chRtuukU6%~A@SQ^tr}XtTi>Q71#@Igx3FNf2SSj#;e&>c8vfA=^Zj7)
ze_G$d<&O2g;6yC${|40ODXhl!o%PzU{2t}U9R3OO&pP}g=I`<o=I`b?Wd7q$o@w)U
zc|1Otk2}w@^1J2NmO_`kqCNQMEkEWBdsQ#2*X6P8gL+|~vG=TlHf2CB?3>=bZP;tf
zr!VXZV!4fIV+<E^Z627+%=mJZ{>XKH@zz`N{pj}1?5CF(J{d2+e{|!gp^x{zd$D=>
z++&{|seZKo+kN}CPx+Ol4_e}RXG@Kmx4c?ge#1NC2f<3kzl*H<4RYpEJ6$TSlZ(da
z`0|@;vbs`TYd(+EIsKoIW3zLMOWq5)7j=F;v41+Cma@OAU;Z-mu=XF<i|-WH*rVe+
zYoDhv2E+cqQlsgEc$ZPzJ6gzjkXp!+LRPV<IHq_(aa{3=B8+)bZ!buynN5uj_VwdC
z2HT2zU(#IMD{$j_U39o9<+dCSbH3nktIB<-9G?~KCYDqnsX$VJqyk9=k_sdhNGgz2
z;9phX+K=islDR(e<a=%ZYqy>LNvD6KyFYQGu+a(zHotqOHKHn_uduNbWWN4+aC3O#
ztLy6ePnOo-;MCz!zqI~3r+)3`(?T8G&G&Zna5tan=;CgEm&EDWv??X);BNo^j{fiF
z2c!U@;8;4M|2PEA0ZrnrSAWK<-JKtLBTnz)H-DUtd{+559Sr?~Jg(k7X#TFgoHgF{
z&sm-^h!-_#nRRU=zpH~^GTzO9Lisp-jPnWbZXWTbUYk37eD;WH#Fyt5z3GBCvvBzM
zv{#r~h=@T`pK+qngruuaBT_V0v$nOU<QnUhpm<6#sE1f)tF&G%R#uiJrw#Rz+?ncH
zu3T)CLnf$)%vrzQSgBRJI$lX~e%U)+FIIf7TvAW=Bp3M2Kx^?|ZB!FL*F)#S_}mfo
zQEVF@U+$-EuRN`zDsS~o42|z2aV!##CgXXo1bvI#jOTkxoC?!+#u?vh{Bw#sdiKP4
zo_7)PT*Eld_>dLB`2g0=ah{J6c^*c8TMoN=3M$fy+@IeUM6Q$hT|BDsI7=hX?-k;t
z-HA1F=l{BnV@`~}*SVvm>747ZUv}d8Jw-f6M??4is1NSX^ThT+27K)S!FwDvJ~!l|
zb0-HpX^weY7|ybW^y2+lSDZib+0|ypuIve$=Q~W;aQAPw(sA*7?Hs##pZLE4>E9DK

literal 0
HcmV?d00001

-- 
2.25.1



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

* [PATCH 12/12] linux-user/hppa: Add vdso and use it for rt_sigreturn
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (10 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 11/12] linux-user/x86_64: Add vdso Richard Henderson
@ 2021-06-19  3:43 ` Richard Henderson
  2021-06-19  4:06 ` [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa no-reply
  12 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-19  3:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Building the vdso itself is not actually wired up to anything, since
we require a cross-compiler.  Just check in that file for now.

Drop the now-unused 9 trampoline words, and describe the frame
without the trampoline in __kernel_rt_sigreturn.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c          |   3 +
 linux-user/hppa/signal.c      |   8 +-
 linux-user/hppa/Makefile.vdso |   4 +
 linux-user/hppa/meson.build   |   6 ++
 linux-user/hppa/vdso.S        | 149 ++++++++++++++++++++++++++++++++++
 linux-user/hppa/vdso.ld       |  75 +++++++++++++++++
 linux-user/hppa/vdso.so       | Bin 0 -> 5192 bytes
 7 files changed, 238 insertions(+), 7 deletions(-)
 create mode 100644 linux-user/hppa/Makefile.vdso
 create mode 100644 linux-user/hppa/vdso.S
 create mode 100644 linux-user/hppa/vdso.ld
 create mode 100755 linux-user/hppa/vdso.so

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index b70a5c48a2..6cea556b70 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1457,6 +1457,9 @@ static inline void init_thread(struct target_pt_regs *regs,
 #define STACK_GROWS_DOWN 0
 #define STACK_ALIGNMENT  64
 
+#define HAVE_VDSO 1
+#include "vdso.c.inc"
+
 static inline void init_thread(struct target_pt_regs *regs,
                                struct image_info *infop)
 {
diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c
index 0e266f472d..44e2db6d3e 100644
--- a/linux-user/hppa/signal.c
+++ b/linux-user/hppa/signal.c
@@ -40,7 +40,6 @@ struct target_ucontext {
 };
 
 struct target_rt_sigframe {
-    abi_uint tramp[9];
     target_siginfo_t info;
     struct target_ucontext uc;
     /* hidden location of upper halves of pa2.0 64-bit gregs */
@@ -138,14 +137,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     setup_sigcontext(&frame->uc.tuc_mcontext, env);
 
-    __put_user(0x34190000, frame->tramp + 0); /* ldi 0,%r25 */
-    __put_user(0x3414015a, frame->tramp + 1); /* ldi __NR_rt_sigreturn,%r20 */
-    __put_user(0xe4008200, frame->tramp + 2); /* be,l 0x100(%sr2,%r0) */
-    __put_user(0x08000240, frame->tramp + 3); /* nop */
-
     unlock_user_struct(frame, frame_addr, 1);
 
-    env->gr[2] = h2g(frame->tramp);
+    env->gr[2] = default_rt_sigreturn;
     env->gr[30] = sp;
     env->gr[26] = sig;
     env->gr[25] = h2g(&frame->info);
diff --git a/linux-user/hppa/Makefile.vdso b/linux-user/hppa/Makefile.vdso
new file mode 100644
index 0000000000..ce92d51a37
--- /dev/null
+++ b/linux-user/hppa/Makefile.vdso
@@ -0,0 +1,4 @@
+vdso.so: vdso.S vdso.ld Makefile.vdso
+	hppa-linux-gnu-gcc -nostdlib -shared -Wl,-T,vdso.ld \
+	  -Wl,-h,linux-vdso.so.1 -Wl,--build-id=none \
+	  -Wl,--hash-style=both vdso.S -o $@
diff --git a/linux-user/hppa/meson.build b/linux-user/hppa/meson.build
index 4709508a09..3febe8523a 100644
--- a/linux-user/hppa/meson.build
+++ b/linux-user/hppa/meson.build
@@ -3,3 +3,9 @@ syscall_nr_generators += {
                     arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
                     output: '@BASENAME@_nr.h')
 }
+
+gen = [
+  gen_vdso.process('vdso.so')
+]
+
+linux_user_ss.add(when: 'TARGET_HPPA', if_true: gen)
diff --git a/linux-user/hppa/vdso.S b/linux-user/hppa/vdso.S
new file mode 100644
index 0000000000..eeae2c999a
--- /dev/null
+++ b/linux-user/hppa/vdso.S
@@ -0,0 +1,149 @@
+/*
+ * hppa linux kernel vdso replacement.
+ *
+ * Copyright 2021 Linaro, Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <asm/unistd.h>
+
+	.text
+
+#define sizeof_rt_sigframe		696
+#define offsetof_sigcontext		152
+#define offsetof_sigcontext_gr		offsetof_sigcontext + 4
+#define offsetof_sigcontext_fr		offsetof_sigcontext_gr + 32 * 4
+#define offsetof_sigcontext_iasq	offsetof_sigcontext_fr + 32 * 8
+#define offsetof_sigcontext_iaoq	offsetof_sigcontext_iasq + 8
+#define offsetof_sigcontext_sar		offsetof_sigcontext_iaoq + 8
+
+	/*
+	 * While this frame is marked as a signal frame, that only applies
+	 * to how this return address is handled for the outer frame.
+	 * The return address that arrived here, from the inner frame, is
+	 * not marked as a signal frame and so the unwinder still tries to
+	 * subtract 1 to examine the presumed call insn.  Thus we must
+	 * extend the unwind info to a nop before the start.
+	 */
+
+	.cfi_startproc simple
+	.cfi_signal_frame
+
+	/* Compare pa32_fallback_frame_state from libgcc. */
+
+	/* Record the size of the stack frame. */
+	.cfi_def_cfa	30, -sizeof_rt_sigframe
+
+	/* Record save offset of general registers. */
+	.cfi_offset	1, offsetof_sigcontext_gr + 1 * 4
+	.cfi_offset	2, offsetof_sigcontext_gr + 2 * 4
+	.cfi_offset	3, offsetof_sigcontext_gr + 3 * 4
+	.cfi_offset	4, offsetof_sigcontext_gr + 4 * 4
+	.cfi_offset	5, offsetof_sigcontext_gr + 5 * 4
+	.cfi_offset	6, offsetof_sigcontext_gr + 6 * 4
+	.cfi_offset	7, offsetof_sigcontext_gr + 7 * 4
+	.cfi_offset	8, offsetof_sigcontext_gr + 8 * 4
+	.cfi_offset	9, offsetof_sigcontext_gr + 9 * 4
+	.cfi_offset	10, offsetof_sigcontext_gr + 10 * 4
+	.cfi_offset	11, offsetof_sigcontext_gr + 11 * 4
+	.cfi_offset	12, offsetof_sigcontext_gr + 12 * 4
+	.cfi_offset	13, offsetof_sigcontext_gr + 13 * 4
+	.cfi_offset	14, offsetof_sigcontext_gr + 14 * 4
+	.cfi_offset	15, offsetof_sigcontext_gr + 15 * 4
+	.cfi_offset	16, offsetof_sigcontext_gr + 16 * 4
+	.cfi_offset	17, offsetof_sigcontext_gr + 17 * 4
+	.cfi_offset	18, offsetof_sigcontext_gr + 18 * 4
+	.cfi_offset	19, offsetof_sigcontext_gr + 19 * 4
+	.cfi_offset	20, offsetof_sigcontext_gr + 20 * 4
+	.cfi_offset	21, offsetof_sigcontext_gr + 21 * 4
+	.cfi_offset	22, offsetof_sigcontext_gr + 22 * 4
+	.cfi_offset	23, offsetof_sigcontext_gr + 23 * 4
+	.cfi_offset	24, offsetof_sigcontext_gr + 24 * 4
+	.cfi_offset	25, offsetof_sigcontext_gr + 25 * 4
+	.cfi_offset	26, offsetof_sigcontext_gr + 26 * 4
+	.cfi_offset	27, offsetof_sigcontext_gr + 27 * 4
+	.cfi_offset	28, offsetof_sigcontext_gr + 28 * 4
+	.cfi_offset	29, offsetof_sigcontext_gr + 29 * 4
+	.cfi_offset	30, offsetof_sigcontext_gr + 30 * 4
+	.cfi_offset	31, offsetof_sigcontext_gr + 31 * 4
+
+	/* Record save offset of fp registers, left and right halves. */
+	.cfi_offset	32, offsetof_sigcontext_fr + 4 * 8
+	.cfi_offset	33, offsetof_sigcontext_fr + 4 * 8 + 4
+	.cfi_offset	34, offsetof_sigcontext_fr + 5 * 8
+	.cfi_offset	35, offsetof_sigcontext_fr + 5 * 8 + 4
+	.cfi_offset	36, offsetof_sigcontext_fr + 6 * 8
+	.cfi_offset	37, offsetof_sigcontext_fr + 6 * 8 + 4
+	.cfi_offset	38, offsetof_sigcontext_fr + 7 * 8
+	.cfi_offset	39, offsetof_sigcontext_fr + 7 * 8 + 4
+	.cfi_offset	40, offsetof_sigcontext_fr + 8 * 8
+	.cfi_offset	41, offsetof_sigcontext_fr + 8 * 8 + 4
+	.cfi_offset	42, offsetof_sigcontext_fr + 9 * 8
+	.cfi_offset	43, offsetof_sigcontext_fr + 9 * 8 + 4
+	.cfi_offset	44, offsetof_sigcontext_fr + 10 * 8
+	.cfi_offset	45, offsetof_sigcontext_fr + 10 * 8 + 4
+	.cfi_offset	46, offsetof_sigcontext_fr + 11 * 8
+	.cfi_offset	47, offsetof_sigcontext_fr + 11 * 8 + 4
+	.cfi_offset	48, offsetof_sigcontext_fr + 12 * 8
+	.cfi_offset	49, offsetof_sigcontext_fr + 12 * 8 + 4
+	.cfi_offset	50, offsetof_sigcontext_fr + 13 * 8
+	.cfi_offset	51, offsetof_sigcontext_fr + 13 * 8 + 4
+	.cfi_offset	52, offsetof_sigcontext_fr + 14 * 8
+	.cfi_offset	53, offsetof_sigcontext_fr + 14 * 8 + 4
+	.cfi_offset	54, offsetof_sigcontext_fr + 15 * 8
+	.cfi_offset	55, offsetof_sigcontext_fr + 15 * 8 + 4
+	.cfi_offset	56, offsetof_sigcontext_fr + 16 * 8
+	.cfi_offset	57, offsetof_sigcontext_fr + 16 * 8 + 4
+	.cfi_offset	58, offsetof_sigcontext_fr + 17 * 8
+	.cfi_offset	59, offsetof_sigcontext_fr + 17 * 8 + 4
+	.cfi_offset	60, offsetof_sigcontext_fr + 18 * 8
+	.cfi_offset	61, offsetof_sigcontext_fr + 18 * 8 + 4
+	.cfi_offset	62, offsetof_sigcontext_fr + 19 * 8
+	.cfi_offset	63, offsetof_sigcontext_fr + 19 * 8 + 4
+	.cfi_offset	64, offsetof_sigcontext_fr + 20 * 8
+	.cfi_offset	65, offsetof_sigcontext_fr + 20 * 8 + 4
+	.cfi_offset	66, offsetof_sigcontext_fr + 21 * 8
+	.cfi_offset	67, offsetof_sigcontext_fr + 21 * 8 + 4
+	.cfi_offset	68, offsetof_sigcontext_fr + 22 * 8
+	.cfi_offset	69, offsetof_sigcontext_fr + 22 * 8 + 4
+	.cfi_offset	70, offsetof_sigcontext_fr + 23 * 8
+	.cfi_offset	71, offsetof_sigcontext_fr + 23 * 8 + 4
+	.cfi_offset	72, offsetof_sigcontext_fr + 24 * 8
+	.cfi_offset	73, offsetof_sigcontext_fr + 24 * 8 + 4
+	.cfi_offset	74, offsetof_sigcontext_fr + 25 * 8
+	.cfi_offset	75, offsetof_sigcontext_fr + 25 * 8 + 4
+	.cfi_offset	76, offsetof_sigcontext_fr + 26 * 8
+	.cfi_offset	77, offsetof_sigcontext_fr + 26 * 8 + 4
+	.cfi_offset	78, offsetof_sigcontext_fr + 27 * 8
+	.cfi_offset	79, offsetof_sigcontext_fr + 27 * 8 + 4
+	.cfi_offset	80, offsetof_sigcontext_fr + 28 * 8
+	.cfi_offset	81, offsetof_sigcontext_fr + 28 * 8 + 4
+	.cfi_offset	82, offsetof_sigcontext_fr + 29 * 8
+	.cfi_offset	83, offsetof_sigcontext_fr + 29 * 8 + 4
+	.cfi_offset	84, offsetof_sigcontext_fr + 30 * 8
+	.cfi_offset	85, offsetof_sigcontext_fr + 30 * 8 + 4
+	.cfi_offset	86, offsetof_sigcontext_fr + 31 * 8
+	.cfi_offset	87, offsetof_sigcontext_fr + 31 * 8 + 4
+
+	/* Record save offset of %sar */
+	.cfi_offset	88, offsetof_sigcontext_sar
+
+	/* Record save offset of return address, iaoq[0]. */
+	.cfi_return_column 89
+	.cfi_offset	89, offsetof_sigcontext_iaoq
+
+	nop
+
+__kernel_rt_sigreturn:
+
+	ldi	0, %r25
+	ldi	__NR_rt_sigreturn, %r20
+	be,l	0x100(%sr2, %r0), %sr0, %r31
+	nop
+
+	.cfi_endproc
+
+	.size	__kernel_rt_sigreturn, . - __kernel_rt_sigreturn
+	.type	__kernel_rt_sigreturn, @function
+	.globl	__kernel_rt_sigreturn
diff --git a/linux-user/hppa/vdso.ld b/linux-user/hppa/vdso.ld
new file mode 100644
index 0000000000..fed994c3eb
--- /dev/null
+++ b/linux-user/hppa/vdso.ld
@@ -0,0 +1,75 @@
+/*
+ * Linker script for linux hppa vdso.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Note that the kernel does not implement a vdso for hppa.
+ * Mirror the symbol that other targets use for this, e.g. i386.
+ */
+
+VERSION {
+        QEMU {
+        global:
+                __kernel_rt_sigreturn;
+        local: *;
+        };
+}
+
+
+PHDRS {
+        phdr            PT_PHDR         FLAGS(4) PHDRS;
+        data            PT_LOAD         FLAGS(6) FILEHDR PHDRS;
+        text            PT_LOAD         FLAGS(5);
+        dynamic         PT_DYNAMIC      FLAGS(4);
+        note            PT_NOTE         FLAGS(4);
+        eh_frame_hdr    PT_GNU_EH_FRAME;
+}
+
+SECTIONS {
+        . = SIZEOF_HEADERS;
+
+        /* The following, including the FILEHDRS and PHDRS, are modified
+           when we relocate the binary.  We want them to be initially
+           writable for the relocation; we'll force them read-only after.  */
+        .note           : { *(.note*) }         :data :note
+        .dynamic        : { *(.dynamic) }       :data :dynamic
+        .dynsym         : { *(.dynsym) }        :data
+        .data           : {
+                /* There ought not be any real read-write data.
+                   But since we manipulated the segment layout,
+                   we have to put these sections somewhere.  */
+                *(.data*)
+                *(.sdata*)
+                *(.got.plt) *(.got)
+                *(.gnu.linkonce.d.*)
+                *(.bss*)
+                *(.dynbss*)
+                *(.gnu.linkonce.b.*)
+        }
+
+        .rodata         : { *(.rodata) }
+        .hash           : { *(.hash) }
+        .gnu.hash       : { *(.gnu.hash) }
+        .dynstr         : { *(.dynstr) }
+        .gnu.version    : { *(.gnu.version) }
+        .gnu.version_d  : { *(.gnu.version_d) }
+        .gnu.version_r  : { *(.gnu.version_r) }
+        .eh_frame_hdr   : { *(.eh_frame_hdr) }  :data :eh_frame_hdr
+        .eh_frame       : { *(.eh_frame) }      :data
+
+        . = ALIGN(4096);
+        .text           : { *(.text*) }         :text
+}
diff --git a/linux-user/hppa/vdso.so b/linux-user/hppa/vdso.so
new file mode 100755
index 0000000000000000000000000000000000000000..a314dc70f2ae8548bfb1e4137039f983fad094e6
GIT binary patch
literal 5192
zcmeHLS#MiK6rOQ1r7WRN6$wxP@lZs8)^rJ_&;oH{J1IDuleA3;+`6?Jn<h@Uz6nkV
zDNPr;0BzZq0xguKQ1-Ad<p=P@ZvY7i2^9%=DunNwJ5whp4@gKn-J=|zb<Umn=H%hb
zj(9R5L$X3xst^mHN+H7Z)Cp02Mu<=t+ErqnSd8e!@XzyOjBEZDl3ZyR>t|BMun=Uf
z({)XK>e{Y>LRQ8OLH}(A?}JXZ^(p5f9nW|_wqwtIW!AM>->&BwF7a(SH8lO#?>O>z
zu<?C)1`_*}<B%7Cmw+z>bECkC`O{}ndlBTH@P#0;CUiOU|4P@`0@Y&rSLnovdk!!3
z_drZY#FuwQoGj5to06=KX~>|#9zSsM?2*!;pM~RW%esZ^fa7{jG2icIy%Dz{2J(fG
z($djPaVUbn<)S0r(#>@tQ&FO#tor5jarlTM&r1CKFNF|Qy;s9xjHJ&YYb(}3CvMnJ
z)d@dY{KN#gJ=G~HD|=+^!YjX@*tvM}+FjS}zJAY=y-OdC?7LzAvIENxu6ShSqjitn
zcxct(n~to0{N^Wad2-EDYoEULncJSd{ki(*qc1cZZG18IQvBt_v9{ywuXMbcI??%B
z*X!MHtbcRE$&GLIyxn{1u6O$0z5Bg;-giFO^kMp=%~M-G&U}*nbn9pRpXa{Fe|hg$
z+rA$7X7F@D)eouYuxhwZHM%NRRB=xwMpV<NYQA5sE2%ri)ScT^@&VN{u38^dZ4;_}
zhw6Aps?<)YIwz&-+9g%@ZmHJqk!r(UsWu*zs%Jm1K%X7GanVue7908l3J?eo2oMMm
z2oMMm2oMMm2oMMm2oU(+5tuJR^>vqFh_8{oKZr>|Tg***_T&KUhxL5SA=J#E@)Z5B
zIhTUu6n|lGeg*0Inl@%^ZDTIdalR#h{P`L2^NhWS683y!_Zj<qV-FjfGdhT4rq1WA
z&OPe=N`H<<4&MVbas3rY(fc*=l_n<4+`St0%5%39>uHU)tZT&Z+|=6b#G9Q&D%uiv
znqw*9G$q>_qDiMMk?4$fIbG3)WZd!R=eb915h;!hdg;xOp6kn;)iPs+^k9CAh(JLW
zWZFxMNPl4@l1mqJzTb0w&uG>y=7$Qi3@0NZ*_^Z0O%G<BTn3re5)m(3^6WAHjjTly
z?*><J?k$FIFy_AWz4C5&PsAL3z@E^3vCQQ09yE@Sd`F>;dc<DiZ|)Y}^4rWR=<E^J
zLl5aby41JvTh3d7cb7kWKYL5}7x!ZN@!VU_TKISd)<e(f_Z{xVlIdp=L%nG@k;h)t
z{m8T0dX(f2`|bl1-y;k3i^hd<o|m)<%-ZnTx2Rcf05-2MBM&_t0^2PiQm$7rdDv4J
xDtT5tyU2W#VN$pT^_W}*=Gz{>OPl`(#KllG&(UfvNL#NO`pi5R_QXH){sy-o1nd9+

literal 0
HcmV?d00001

-- 
2.25.1



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

* Re: [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa
  2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
                   ` (11 preceding siblings ...)
  2021-06-19  3:43 ` [PATCH 12/12] linux-user/hppa: Add vdso and use it for rt_sigreturn Richard Henderson
@ 2021-06-19  4:06 ` no-reply
  12 siblings, 0 replies; 17+ messages in thread
From: no-reply @ 2021-06-19  4:06 UTC (permalink / raw)
  To: richard.henderson; +Cc: alex.bennee, qemu-devel, laurent

Patchew URL: https://patchew.org/QEMU/20210619034329.532318-1-richard.henderson@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210619034329.532318-1-richard.henderson@linaro.org
Subject: [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/20210619034329.532318-1-richard.henderson@linaro.org -> patchew/20210619034329.532318-1-richard.henderson@linaro.org
Switched to a new branch 'test'
eb8d6c9 linux-user/hppa: Add vdso and use it for rt_sigreturn
52cca21 linux-user/x86_64: Add vdso
fd7f59e linux-user: Add gen-vdso tool
5228b92 linux-user: Load vdso image if available
0fc0b1b linux-user: Introduce imgsrc_mmap
e397043 linux-user: Replace bprm->fd with bprm->src.fd
832f702 linux-user: Use ImageSource in load_symbols
9d65bf5 linux-user: Use ImageSource in load_elf_image
b04a74d linux-user: Do not clobber bprm_buf swapping ehdr
acdaddc linux-user: Tidy loader_exec
63442e1 linux-user: Introduce imgsrc_read, imgsrc_read_alloc
a4d2a45 linux-user: Fix style problems in linuxload.c

=== OUTPUT BEGIN ===
1/12 Checking commit a4d2a4511b66 (linux-user: Fix style problems in linuxload.c)
2/12 Checking commit 63442e15ed05 (linux-user: Introduce imgsrc_read, imgsrc_read_alloc)
3/12 Checking commit acdaddc5dc89 (linux-user: Tidy loader_exec)
4/12 Checking commit b04a74dee4d8 (linux-user: Do not clobber bprm_buf swapping ehdr)
5/12 Checking commit 9d65bf56e0c7 (linux-user: Use ImageSource in load_elf_image)
6/12 Checking commit 832f702ccea5 (linux-user: Use ImageSource in load_symbols)
7/12 Checking commit e3970430bd3b (linux-user: Replace bprm->fd with bprm->src.fd)
8/12 Checking commit 0fc0b1bd7d79 (linux-user: Introduce imgsrc_mmap)
9/12 Checking commit 5228b920709c (linux-user: Load vdso image if available)
10/12 Checking commit fd7f59e94124 (linux-user: Add gen-vdso tool)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#21: 
new file mode 100644

ERROR: trailing whitespace
#31: FILE: linux-user/gen-vdso-elfn.c.inc:6:
+ * $

ERROR: spaces required around that '*' (ctx:WxV)
#92: FILE: linux-user/gen-vdso-elfn.c.inc:67:
+static void elfN(process)(FILE *outf, void *buf, long total_len,
                                ^

ERROR: trailing whitespace
#184: FILE: linux-user/gen-vdso-elfn.c.inc:159:
+        $

ERROR: trailing whitespace
#335: FILE: linux-user/gen-vdso.c:5:
+ * $

ERROR: spaces required around that ':' (ctx:VxW)
#350: FILE: linux-user/gen-vdso.c:20:
+                            uint16_t: __builtin_bswap16,       \
                                     ^

ERROR: spaces required around that ':' (ctx:VxW)
#351: FILE: linux-user/gen-vdso.c:21:
+                            uint32_t: __builtin_bswap32,       \
                                     ^

ERROR: spaces required around that ':' (ctx:VxW)
#352: FILE: linux-user/gen-vdso.c:22:
+                            uint64_t: __builtin_bswap64,       \
                                     ^

ERROR: spaces required around that ':' (ctx:VxW)
#353: FILE: linux-user/gen-vdso.c:23:
+                            int16_t: __builtin_bswap16,        \
                                    ^

ERROR: spaces required around that ':' (ctx:VxW)
#354: FILE: linux-user/gen-vdso.c:24:
+                            int32_t: __builtin_bswap32,        \
                                    ^

ERROR: spaces required around that ':' (ctx:VxW)
#355: FILE: linux-user/gen-vdso.c:25:
+                            int64_t: __builtin_bswap64)
                                    ^

WARNING: Block comments use a leading /* on a separate line
#436: FILE: linux-user/gen-vdso.c:106:
+    fputs("/* Automatically generated from linux-user/gen-vdso.c. */\n"

total: 10 errors, 2 warnings, 481 lines checked

Patch 10/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

11/12 Checking commit 52cca2161834 (linux-user/x86_64: Add vdso)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#38: 
new file mode 100644

ERROR: trailing whitespace
#70: FILE: linux-user/x86_64/vdso.S:5:
+ * $

ERROR: trailing whitespace
#198: FILE: linux-user/x86_64/vdso.ld:5:
+ * $

total: 2 errors, 1 warnings, 217 lines checked

Patch 11/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

12/12 Checking commit eb8d6c9db1a6 (linux-user/hppa: Add vdso and use it for rt_sigreturn)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#42: 
new file mode 100644

total: 0 errors, 1 warnings, 268 lines checked

Patch 12/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210619034329.532318-1-richard.henderson@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [PATCH 01/12] linux-user: Fix style problems in linuxload.c
  2021-06-19  3:43 ` [PATCH 01/12] linux-user: Fix style problems in linuxload.c Richard Henderson
@ 2021-06-19  9:47   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 17+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:47 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/19/21 5:43 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/linuxload.c | 42 ++++++++++++++++++++----------------------
>  1 file changed, 20 insertions(+), 22 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH 04/12] linux-user: Do not clobber bprm_buf swapping ehdr
  2021-06-19  3:43 ` [PATCH 04/12] linux-user: Do not clobber bprm_buf swapping ehdr Richard Henderson
@ 2021-06-19  9:50   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 17+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:50 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/19/21 5:43 AM, Richard Henderson wrote:
> Rearrange the allocation of storage for ehdr between load_elf_image
> and load_elf_binary.  The same set of copies are done, but we don't
> modify bprm_buf, which will be important later.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/elfload.c | 25 ++++++++++++++-----------
>  1 file changed, 14 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH 07/12] linux-user: Replace bprm->fd with bprm->src.fd
  2021-06-19  3:43 ` [PATCH 07/12] linux-user: Replace bprm->fd with bprm->src.fd Richard Henderson
@ 2021-06-19  9:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 17+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:54 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/19/21 5:43 AM, Richard Henderson wrote:
> There are only a couple of uses of bprm->fd remaining.
> Migrate to the other field.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/qemu.h      | 1 -
>  linux-user/flatload.c  | 8 ++++----
>  linux-user/linuxload.c | 5 ++---
>  3 files changed, 6 insertions(+), 8 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

end of thread, other threads:[~2021-06-19  9:56 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-19  3:43 [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa Richard Henderson
2021-06-19  3:43 ` [PATCH 01/12] linux-user: Fix style problems in linuxload.c Richard Henderson
2021-06-19  9:47   ` Philippe Mathieu-Daudé
2021-06-19  3:43 ` [PATCH 02/12] linux-user: Introduce imgsrc_read, imgsrc_read_alloc Richard Henderson
2021-06-19  3:43 ` [PATCH 03/12] linux-user: Tidy loader_exec Richard Henderson
2021-06-19  3:43 ` [PATCH 04/12] linux-user: Do not clobber bprm_buf swapping ehdr Richard Henderson
2021-06-19  9:50   ` Philippe Mathieu-Daudé
2021-06-19  3:43 ` [PATCH 05/12] linux-user: Use ImageSource in load_elf_image Richard Henderson
2021-06-19  3:43 ` [PATCH 06/12] linux-user: Use ImageSource in load_symbols Richard Henderson
2021-06-19  3:43 ` [PATCH 07/12] linux-user: Replace bprm->fd with bprm->src.fd Richard Henderson
2021-06-19  9:54   ` Philippe Mathieu-Daudé
2021-06-19  3:43 ` [PATCH 08/12] linux-user: Introduce imgsrc_mmap Richard Henderson
2021-06-19  3:43 ` [PATCH 09/12] linux-user: Load vdso image if available Richard Henderson
2021-06-19  3:43 ` [PATCH 10/12] linux-user: Add gen-vdso tool Richard Henderson
2021-06-19  3:43 ` [PATCH 11/12] linux-user/x86_64: Add vdso Richard Henderson
2021-06-19  3:43 ` [PATCH 12/12] linux-user/hppa: Add vdso and use it for rt_sigreturn Richard Henderson
2021-06-19  4:06 ` [PATCH 00/12] linux-user: Load a vdso for x86_64 and hppa no-reply

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.