All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Frysinger <vapier@gentoo.org>
To: qemu-devel@nongnu.org, Riku Voipio <riku.voipio@iki.fi>
Subject: [Qemu-devel] [PATCH 2/9] linux-user/elfload: add FDPIC support
Date: Mon,  7 Feb 2011 01:05:50 -0500	[thread overview]
Message-ID: <1297058757-7611-2-git-send-email-vapier@gentoo.org> (raw)
In-Reply-To: <1297058757-7611-1-git-send-email-vapier@gentoo.org>

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

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

  reply	other threads:[~2011-02-07  6:06 UTC|newest]

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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1297058757-7611-2-git-send-email-vapier@gentoo.org \
    --to=vapier@gentoo.org \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.