qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefano Bonifazi <stefboombastic@gmail.com>
To: Mike Frysinger <vapier@gentoo.org>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [RFC/PATCH] elfload: add FDPIC support
Date: Mon, 24 Jan 2011 14:34:12 +0100	[thread overview]
Message-ID: <4D3D7FD4.3090008@gmail.com> (raw)
In-Reply-To: <1294562938-20097-1-git-send-email-vapier@gentoo.org>

On 01/09/2011 09:48 AM, Mike Frysinger wrote:
> This is a PoC at this point, but it seems to be working for me.  At
> least, all the current crashes I'm seeing are due to my Blackfin port
> being incomplete.  All of the FDPIC table parsing seems to be OK ...
>
> If someone with a more functional target would like to try this, that'd
> be cool.  Or if people want to give feedback on how to approach this
> problem so I can adjust the details now.
>
> Signed-off-by: Mike Frysinger<vapier@gentoo.org>
> ---
>   elf.h                |   19 ++++++++++++++
>   linux-user/elfload.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   linux-user/qemu.h    |    8 ++++++
>   3 files changed, 94 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..8100ffd 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1075,6 +1075,32 @@ 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 */
> +    for (n = 0; n<  info->nsegs; ++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 +1113,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 +1238,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 +1256,11 @@ static void load_elf_image(const char *image_name, int image_fd,
>               if (a>  hiaddr) {
>                   hiaddr = a;
>               }
> +#ifdef CONFIG_USE_FDPIC
> +            ++info->nsegs;
> +        } else if (phdr[i].p_type == PT_DYNAMIC) {
> +            info->pt_dynamic_addr = phdr[i].p_vaddr;
> +#endif
>           }
>       }
>
> @@ -1290,6 +1341,22 @@ 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) {
> +            if (phdr[i].p_type != PT_LOAD)
> +                continue;
> +            loadsegs->addr = phdr[i].p_vaddr + load_bias;
> +            loadsegs->p_vaddr = phdr[i].p_vaddr;
> +            loadsegs->p_memsz = phdr[i].p_memsz;
> +			++loadsegs;
> +        }
> +    }
> +#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..0924a1a 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -51,6 +51,14 @@ struct image_info {
>           abi_ulong       arg_start;
>           abi_ulong       arg_end;
>   	int		personality;
> +#ifdef CONFIG_USE_FDPIC
> +#define FDPIC_MAX_LOAD_SEGS 4
> +        abi_ulong       loadmap_addr;
> +        uint16_t        nsegs;
> +        void           *loadsegs;
> +        abi_ulong       pt_dynamic_addr;
> +        struct image_info *other_info;
> +#endif
>   };
>
>   #ifdef TARGET_I386

Hi!
  Could you be so kind of explaining me, or addressing me to what this 
patch would do?
Is FDPIC something different than simply PIC code (position independent 
code)?
I am also trying to fight with the problem of changing the starting 
address of target code for qemu-user, and I was just moving into the 
option of using PIC target code .. but the original qemu-user 
load_elf_binary does not work on them.. and I was just about to try to 
edit it..
You would be more than a bless for me if you managed to do it! :)
You may want to have a look at my post:
http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg02361.html
Thank you very much in advance!
Stefano B

  parent reply	other threads:[~2011-01-24 13:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-09  8:48 [Qemu-devel] [RFC/PATCH] elfload: add FDPIC support Mike Frysinger
2011-01-09 18:20 ` Mike Frysinger
2011-01-23 19:51 ` [Qemu-devel] [PATCH] linux-user/FLAT: allow targets to override FLAT reloc processing Mike Frysinger
2011-01-23 19:54   ` Mike Frysinger
2011-01-23 19:51 ` [Qemu-devel] [PATCH v2] linux-user/elfload: add FDPIC support Mike Frysinger
2011-01-24 13:34 ` Stefano Bonifazi [this message]
2011-01-24 19:11   ` [Qemu-devel] Re: [RFC/PATCH] elfload: " Mike Frysinger
2011-01-24 21:06     ` Stefano Bonifazi
2011-01-24 21:27       ` Mike Frysinger
2011-01-24 22:07         ` Stefano Bonifazi

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=4D3D7FD4.3090008@gmail.com \
    --to=stefboombastic@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=vapier@gentoo.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).