All of lore.kernel.org
 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 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.