[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 08/22] libelf: introduce macros for memory access and pointer handling



On 07/06/13 19:27, Ian Jackson wrote:
> We introduce a collection of macros which abstract away all the
> pointer arithmetic and dereferences used for accessing the input ELF
> and the output area(s).  We use the new macros everywhere.
>
> For now, these macros are semantically identical to the code they
> replace, so this patch has no functional change.
>
> elf_is_elfbinary is an exception: since it doesn't take an elf*, we
> need to handle it differently.  In a future patch we will change it to
> take, and check, a length parameter.  For now we just mark it with a
> fixme.
>
> That this patch has no functional change can be verified as follows:
>
>   0. Copy the scripts "comparison-generate" and "function-filter"
>      out of this commit message.
>   1. Check out the tree before this patch.
>   2. Run the script ../comparison-generate .... ../before
>   3. Check out the tree after this patch.
>   4. Run the script ../comparison-generate .... ../after
>   5. diff --exclude=\*.[soi] -ruN before/ after/ |less
>
> Expect these differences:
>   * stubdom/zlib-x86_64/ztest*.s2
>       The filename of this test file apparently contains the pid.
>   * xen/common/version.s2
>       The xen build timestamp appears in two diff hunks.
>
> Verification that this is all that's needed:
>   In a completely built xen.git,
>      find * -name .*.d -type f | xargs grep -l libelf\.h
>   Expect results in:
>      xen/arch/x86:            Checked above.
>      tools/libxc:             Checked above.
>      tools/xcutils/readnotes: Checked above.
>      tools/xenstore:          Checked above.
>      xen/common/libelf:
>        This is the build for the hypervisor; checked in B above.
>      stubdom:
>        We have one stubdom which reads ELFs using our libelf,
>        pvgrub, which is checked above.
>
> I have not done this verification for ARM.
>
> This is part of the fix to a security issue, XSA-55.
>
> Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>

I believe I have independently verified that this patch has no relevant
differences in compiled output.

One thing to say is that I do not appear to have git-clean on my system
(Debian Wheezy), but changing to "git clean" seems to work fine.

~Andrew

>
> v4: Fix elf_load_binary's phdr message to be correct on 32-bit.
>     Fix ELF_OBSOLETE_VOIDP_CAST to work on 32-bit.
>     Indent scripts in commit message.
>
> v3.1:
>     Change elf_store_field to verify correctly on 32-bit.
>     comparison-generate copes with Xen 4.1's lack of ./configure.
>
> v2: Use Xen style for multi-line comments.
>     Postpone changes to readnotes.c:print_l1_mfn_valid_note.
>     Much improved verification instructions with new script.
>     Fixed commit message subject.
>
> -8<- comparison-generate -8<-
>  #!/bin/bash
>  # usage:
>  #  cd xen.git
>  #  .../comparison-generate OUR-CONFIG BUILD-RUNE-PREFIX ../before|../after
>  # eg:
>  #  .../comparison-generate ~/work/.config 'schroot -pc64 --' ../before
>  set -ex
>
>  test $# = 3 || need-exactly-three-arguments
>
>  our_config=$1
>  build_rune_prefix=$2
>  result_dir=$3
>
>  git-clean -x -d -f
>
>  cp "$our_config" .
>
>  cat <<END >>.config
>          debug_symbols=n
>          CFLAGS += -save-temps
>  END
>
>  perl -i~ -pe 's/ -g / -g0 / if m/^CFLAGS/' xen/Rules.mk
>
>  if [ -f ./configure ]; then
>          $build_rune_prefix ./configure
>  fi
>
>  $build_rune_prefix make -C xen
>  $build_rune_prefix make -C tools/include
>  $build_rune_prefix make -C stubdom grub
>  $build_rune_prefix make -C tools/libxc
>  $build_rune_prefix make -C tools/xenstore
>  $build_rune_prefix make -C tools/xcutils
>
>  rm -rf "$result_dir"
>  mkdir "$result_dir"
>
>  set +x
>  for f in `find xen tools stubdom -name \*.[soi]`; do
>          mkdir -p "$result_dir"/`dirname $f`
>          cp $f "$result_dir"/${f}
>          case $f in
>          *.s)
>                  ../function-filter <$f >"$result_dir"/${f}2
>                  ;;
>          esac
>  done
>
>  echo ok.
> -8<-
>
> -8<- function-filter -8<-
>  #!/usr/bin/perl -w
>  # function-filter
>  # script for massaging gcc-generated labels to be consistent
>  use strict;
>  our @lines;
>  my $sedderybody = "sub seddery () {\n";
>  while (<>) {
>      push @lines, $_;
>      if (m/^(__FUNCTION__|__func__)\.(\d+)\:/) {
>          $sedderybody .= "    s/\\b$1\\.$2\\b/__XSA55MANGLED__$1.$./g;\n";
>      }
>  }
>  $sedderybody .= "}\n1;\n";
>  eval $sedderybody or die $@;
>  foreach (@lines) {
>      seddery();
>      print or die $!;
>  }
> -8<-
> ---
>  tools/libxc/xc_dom_elfloader.c     |   30 +++---
>  tools/libxc/xc_hvm_build_x86.c     |    2 +-
>  tools/xcutils/readnotes.c          |   26 +++---
>  xen/common/libelf/libelf-dominfo.c |   51 +++++-----
>  xen/common/libelf/libelf-loader.c  |   84 +++++++++--------
>  xen/common/libelf/libelf-tools.c   |   94 +++++++++---------
>  xen/include/xen/libelf.h           |  188 
> +++++++++++++++++++++++++++++++-----
>  7 files changed, 312 insertions(+), 163 deletions(-)
>
> diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
> index 7ff51d1..b8089bc 100644
> --- a/tools/libxc/xc_dom_elfloader.c
> +++ b/tools/libxc/xc_dom_elfloader.c
> @@ -113,9 +113,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>                                    struct elf_binary *elf, int load)
>  {
>      struct elf_binary syms;
> -    const elf_shdr *shdr, *shdr2;
> +    ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
>      xen_vaddr_t symtab, maxaddr;
> -    char *hdr;
> +    ELF_PTRVAL_CHAR hdr;
>      size_t size;
>      int h, count, type, i, tables = 0;
>
> @@ -145,11 +145,11 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>          dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
>      }
>
> -    memcpy(hdr + sizeof(int),
> -           elf->image,
> +    elf_memcpy_safe(elf, hdr + sizeof(int),
> +           ELF_IMAGE_BASE(elf),
>             elf_size(elf, elf->ehdr));
> -    memcpy(hdr + sizeof(int) + elf_size(elf, elf->ehdr),
> -           elf->image + elf_uval(elf, elf->ehdr, e_shoff),
> +    elf_memcpy_safe(elf, hdr + sizeof(int) + elf_size(elf, elf->ehdr),
> +           ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
>             elf_shdr_count(elf) * elf_size(elf, shdr));
>      if ( elf_64bit(elf) )
>      {
> @@ -187,7 +187,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>      count = elf_shdr_count(&syms);
>      for ( h = 0; h < count; h++ )
>      {
> -        shdr = elf_shdr_by_index(&syms, h);
> +        shdr = ELF_OBSOLETE_VOIDP_CAST elf_shdr_by_index(&syms, h);
>          type = elf_uval(&syms, shdr, sh_type);
>          if ( type == SHT_STRTAB )
>          {
> @@ -203,9 +203,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>              if ( i == count )
>              {
>                  if ( elf_64bit(&syms) )
> -                    *(Elf64_Off*)(&shdr->e64.sh_offset) = 0;
> +                    elf_store_field(elf, shdr, e64.sh_offset, 0);
>                  else
> -                    *(Elf32_Off*)(&shdr->e32.sh_offset) = 0;
> +                    elf_store_field(elf, shdr, e32.sh_offset, 0);
>                  continue;
>              }
>          }
> @@ -214,9 +214,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>          {
>              /* Mangled to be based on ELF header location. */
>              if ( elf_64bit(&syms) )
> -                *(Elf64_Off*)(&shdr->e64.sh_offset) = maxaddr - symtab;
> +                elf_store_field(elf, shdr, e64.sh_offset, maxaddr - symtab);
>              else
> -                *(Elf32_Off*)(&shdr->e32.sh_offset) = maxaddr - symtab;
> +                elf_store_field(elf, shdr, e32.sh_offset, maxaddr - symtab);
>              size = elf_uval(&syms, shdr, sh_size);
>              maxaddr = elf_round_up(&syms, maxaddr + size);
>              tables++;
> @@ -228,7 +228,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>              if ( load )
>              {
>                  shdr2 = elf_shdr_by_index(elf, h);
> -                memcpy((void*)elf_section_start(&syms, shdr),
> +                elf_memcpy_safe(elf, ELF_OBSOLETE_VOIDP_CAST 
> elf_section_start(&syms, shdr),
>                         elf_section_start(elf, shdr2),
>                         size);
>              }
> @@ -236,9 +236,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
> *dom,
>
>          /* Name is NULL. */
>          if ( elf_64bit(&syms) )
> -            *(Elf64_Word*)(&shdr->e64.sh_name) = 0;
> +            elf_store_field(elf, shdr, e64.sh_name, 0);
>          else
> -            *(Elf32_Word*)(&shdr->e32.sh_name) = 0;
> +            elf_store_field(elf, shdr, e32.sh_name, 0);
>      }
>
>      if ( tables == 0 )
> @@ -273,7 +273,7 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image 
> *dom)
>      }
>
>      /* Find the section-header strings table. */
> -    if ( elf->sec_strtab == NULL )
> +    if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
>      {
>          xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
>                       " has no shstrtab", __FUNCTION__);
> diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
> index ab33a7f..39f93a3 100644
> --- a/tools/libxc/xc_hvm_build_x86.c
> +++ b/tools/libxc/xc_hvm_build_x86.c
> @@ -143,7 +143,7 @@ static int loadelfimage(xc_interface *xch, struct 
> elf_binary *elf,
>      if ( elf->dest == NULL )
>          goto err;
>
> -    elf->dest += elf->pstart & (PAGE_SIZE - 1);
> +    ELF_ADVANCE_DEST(elf, elf->pstart & (PAGE_SIZE - 1));
>
>      /* Load the initial elf image. */
>      rc = elf_load_binary(elf);
> diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
> index c926186..2af047d 100644
> --- a/tools/xcutils/readnotes.c
> +++ b/tools/xcutils/readnotes.c
> @@ -61,13 +61,13 @@ struct setup_header {
>  } __attribute__((packed));
>
>  static void print_string_note(const char *prefix, struct elf_binary *elf,
> -                             const elf_note *note)
> +                             ELF_HANDLE_DECL(elf_note) note)
>  {
>         printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note));
>  }
>
>  static void print_numeric_note(const char *prefix, struct elf_binary *elf,
> -                              const elf_note *note)
> +                              ELF_HANDLE_DECL(elf_note) note)
>  {
>         uint64_t value = elf_note_numeric(elf, note);
>         int descsz = elf_uval(elf, note, descsz);
> @@ -98,12 +98,12 @@ static void print_l1_mfn_valid_note(const char *prefix, 
> struct elf_binary *elf,
>
>  }
>
> -static int print_notes(struct elf_binary *elf, const elf_note *start, const 
> elf_note *end)
> +static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) 
> start, ELF_HANDLE_DECL(elf_note) end)
>  {
> -       const elf_note *note;
> +       ELF_HANDLE_DECL(elf_note) note;
>         int notes_found = 0;
>
> -       for ( note = start; note < end; note = elf_note_next(elf, note) )
> +       for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); 
> note = elf_note_next(elf, note) )
>         {
>                 if (0 != strcmp(elf_note_name(elf, note), "Xen"))
>                         continue;
> @@ -170,7 +170,7 @@ int main(int argc, char **argv)
>         void *image,*tmp;
>         struct stat st;
>         struct elf_binary elf;
> -       const elf_shdr *shdr;
> +       ELF_HANDLE_DECL(elf_shdr) shdr;
>         int notes_found = 0;
>
>         struct setup_header *hdr;
> @@ -257,7 +257,7 @@ int main(int argc, char **argv)
>         count = elf_phdr_count(&elf);
>         for ( h=0; h < count; h++)
>         {
> -               const elf_phdr *phdr;
> +               ELF_HANDLE_DECL(elf_phdr) phdr;
>                 phdr = elf_phdr_by_index(&elf, h);
>                 if (elf_uval(&elf, phdr, p_type) != PT_NOTE)
>                         continue;
> @@ -269,8 +269,8 @@ int main(int argc, char **argv)
>                         continue;
>
>                 notes_found = print_notes(&elf,
> -                                         elf_segment_start(&elf, phdr),
> -                                         elf_segment_end(&elf, phdr));
> +                                         ELF_MAKE_HANDLE(elf_note, 
> elf_segment_start(&elf, phdr)),
> +                                         ELF_MAKE_HANDLE(elf_note, 
> elf_segment_end(&elf, phdr)));
>         }
>
>         if ( notes_found == 0 )
> @@ -278,13 +278,13 @@ int main(int argc, char **argv)
>                 count = elf_shdr_count(&elf);
>                 for ( h=0; h < count; h++)
>                 {
> -                       const elf_shdr *shdr;
> +                       ELF_HANDLE_DECL(elf_shdr) shdr;
>                         shdr = elf_shdr_by_index(&elf, h);
>                         if (elf_uval(&elf, shdr, sh_type) != SHT_NOTE)
>                                 continue;
>                         notes_found = print_notes(&elf,
> -                                                 elf_section_start(&elf, 
> shdr),
> -                                                 elf_section_end(&elf, 
> shdr));
> +                                                 ELF_MAKE_HANDLE(elf_note, 
> elf_section_start(&elf, shdr)),
> +                                                 ELF_MAKE_HANDLE(elf_note, 
> elf_section_end(&elf, shdr)));
>                         if ( notes_found )
>                                 fprintf(stderr, "using notes from SHT_NOTE 
> section\n");
>
> @@ -292,7 +292,7 @@ int main(int argc, char **argv)
>         }
>
>         shdr = elf_shdr_by_name(&elf, "__xen_guest");
> -       if (shdr)
> +       if (ELF_HANDLE_VALID(shdr))
>                 printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, 
> shdr));
>
>         return 0;
> diff --git a/xen/common/libelf/libelf-dominfo.c 
> b/xen/common/libelf/libelf-dominfo.c
> index 3242f54..566f6f9 100644
> --- a/xen/common/libelf/libelf-dominfo.c
> +++ b/xen/common/libelf/libelf-dominfo.c
> @@ -44,7 +44,7 @@ int elf_xen_parse_features(const char *features,
>
>      for ( pos = 0; features[pos] != '\0'; pos += len )
>      {
> -        memset(feature, 0, sizeof(feature));
> +        elf_memset_unchecked(feature, 0, sizeof(feature));
>          for ( len = 0;; len++ )
>          {
>              if ( len >= sizeof(feature)-1 )
> @@ -96,7 +96,7 @@ int elf_xen_parse_features(const char *features,
>
>  int elf_xen_parse_note(struct elf_binary *elf,
>                         struct elf_dom_parms *parms,
> -                       const elf_note *note)
> +                       ELF_HANDLE_DECL(elf_note) note)
>  {
>  /* *INDENT-OFF* */
>      static const struct {
> @@ -215,15 +215,16 @@ int elf_xen_parse_note(struct elf_binary *elf,
>
>  static int elf_xen_parse_notes(struct elf_binary *elf,
>                                 struct elf_dom_parms *parms,
> -                               const void *start, const void *end)
> +                               ELF_PTRVAL_CONST_VOID start,
> +                               ELF_PTRVAL_CONST_VOID end)
>  {
>      int xen_elfnotes = 0;
> -    const elf_note *note;
> +    ELF_HANDLE_DECL(elf_note) note;
>
>      parms->elf_note_start = start;
>      parms->elf_note_end   = end;
> -    for ( note = parms->elf_note_start;
> -          (void *)note < parms->elf_note_end;
> +    for ( note = ELF_MAKE_HANDLE(elf_note, parms->elf_note_start);
> +          ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
>            note = elf_note_next(elf, note) )
>      {
>          if ( strcmp(elf_note_name(elf, note), "Xen") )
> @@ -241,45 +242,46 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
>  int elf_xen_parse_guest_info(struct elf_binary *elf,
>                               struct elf_dom_parms *parms)
>  {
> -    const char *h;
> +    ELF_PTRVAL_CONST_CHAR h;
>      char name[32], value[128];
>      int len;
>
>      h = parms->guest_info;
> -    while ( *h )
> +#define STAR(h) (*(h))
> +    while ( STAR(h) )
>      {
> -        memset(name, 0, sizeof(name));
> -        memset(value, 0, sizeof(value));
> +        elf_memset_unchecked(name, 0, sizeof(name));
> +        elf_memset_unchecked(value, 0, sizeof(value));
>          for ( len = 0;; len++, h++ )
>          {
>              if ( len >= sizeof(name)-1 )
>                  break;
> -            if ( *h == '\0' )
> +            if ( STAR(h) == '\0' )
>                  break;
> -            if ( *h == ',' )
> +            if ( STAR(h) == ',' )
>              {
>                  h++;
>                  break;
>              }
> -            if ( *h == '=' )
> +            if ( STAR(h) == '=' )
>              {
>                  h++;
>                  for ( len = 0;; len++, h++ )
>                  {
>                      if ( len >= sizeof(value)-1 )
>                          break;
> -                    if ( *h == '\0' )
> +                    if ( STAR(h) == '\0' )
>                          break;
> -                    if ( *h == ',' )
> +                    if ( STAR(h) == ',' )
>                      {
>                          h++;
>                          break;
>                      }
> -                    value[len] = *h;
> +                    value[len] = STAR(h);
>                  }
>                  break;
>              }
> -            name[len] = *h;
> +            name[len] = STAR(h);
>          }
>          elf_msg(elf, "%s: %s=\"%s\"\n", __FUNCTION__, name, value);
>
> @@ -328,7 +330,8 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
>  static int elf_xen_note_check(struct elf_binary *elf,
>                                struct elf_dom_parms *parms)
>  {
> -    if ( (parms->elf_note_start == NULL) && (parms->guest_info == NULL) )
> +    if ( (ELF_PTRVAL_INVALID(parms->elf_note_start)) &&
> +         (ELF_PTRVAL_INVALID(parms->guest_info)) )
>      {
>          int machine = elf_uval(elf, elf->ehdr, e_machine);
>          if ( (machine == EM_386) || (machine == EM_X86_64) )
> @@ -457,12 +460,12 @@ static int elf_xen_addr_calc_check(struct elf_binary 
> *elf,
>  int elf_xen_parse(struct elf_binary *elf,
>                    struct elf_dom_parms *parms)
>  {
> -    const elf_shdr *shdr;
> -    const elf_phdr *phdr;
> +    ELF_HANDLE_DECL(elf_shdr) shdr;
> +    ELF_HANDLE_DECL(elf_phdr) phdr;
>      int xen_elfnotes = 0;
>      int i, count, rc;
>
> -    memset(parms, 0, sizeof(*parms));
> +    elf_memset_unchecked(parms, 0, sizeof(*parms));
>      parms->virt_base = UNSET_ADDR;
>      parms->virt_entry = UNSET_ADDR;
>      parms->virt_hypercall = UNSET_ADDR;
> @@ -532,11 +535,11 @@ int elf_xen_parse(struct elf_binary *elf,
>          for ( i = 0; i < count; i++ )
>          {
>              shdr = elf_shdr_by_name(elf, "__xen_guest");
> -            if ( shdr )
> +            if ( ELF_HANDLE_VALID(shdr) )
>              {
>                  parms->guest_info = elf_section_start(elf, shdr);
> -                parms->elf_note_start = NULL;
> -                parms->elf_note_end   = NULL;
> +                parms->elf_note_start = ELF_INVALID_PTRVAL;
> +                parms->elf_note_end   = ELF_INVALID_PTRVAL;
>                  elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
>                          parms->guest_info);
>                  elf_xen_parse_guest_info(elf, parms);
> diff --git a/xen/common/libelf/libelf-loader.c 
> b/xen/common/libelf/libelf-loader.c
> index 94257f6..f7fe283 100644
> --- a/xen/common/libelf/libelf-loader.c
> +++ b/xen/common/libelf/libelf-loader.c
> @@ -26,7 +26,7 @@
>
>  int elf_init(struct elf_binary *elf, const char *image, size_t size)
>  {
> -    const elf_shdr *shdr;
> +    ELF_HANDLE_DECL(elf_shdr) shdr;
>      uint64_t i, count, section, offset;
>
>      if ( !elf_is_elfbinary(image) )
> @@ -35,7 +35,7 @@ int elf_init(struct elf_binary *elf, const char *image, 
> size_t size)
>          return -1;
>      }
>
> -    memset(elf, 0, sizeof(*elf));
> +    elf_memset_unchecked(elf, 0, sizeof(*elf));
>      elf->image = image;
>      elf->size = size;
>      elf->ehdr = (elf_ehdr *)image;
> @@ -65,7 +65,7 @@ int elf_init(struct elf_binary *elf, const char *image, 
> size_t size)
>      /* Find section string table. */
>      section = elf_uval(elf, elf->ehdr, e_shstrndx);
>      shdr = elf_shdr_by_index(elf, section);
> -    if ( shdr != NULL )
> +    if ( ELF_HANDLE_VALID(shdr) )
>          elf->sec_strtab = elf_section_start(elf, shdr);
>
>      /* Find symbol table and symbol string table. */
> @@ -77,9 +77,9 @@ int elf_init(struct elf_binary *elf, const char *image, 
> size_t size)
>              continue;
>          elf->sym_tab = shdr;
>          shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
> -        if ( shdr == NULL )
> +        if ( !ELF_HANDLE_VALID(shdr) )
>          {
> -            elf->sym_tab = NULL;
> +            elf->sym_tab = ELF_INVALID_HANDLE(elf_shdr);
>              continue;
>          }
>          elf->sym_strtab = elf_section_start(elf, shdr);
> @@ -113,10 +113,11 @@ void elf_set_log(struct elf_binary *elf, 
> elf_log_callback *log_callback,
>  }
>
>  static int elf_load_image(struct elf_binary *elf,
> -                          void *dst, const void *src, uint64_t filesz, 
> uint64_t memsz)
> +                          ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src,
> +                          uint64_t filesz, uint64_t memsz)
>  {
> -    memcpy(dst, src, filesz);
> -    memset(dst + filesz, 0, memsz - filesz);
> +    elf_memcpy_safe(elf, dst, src, filesz);
> +    elf_memset_safe(elf, dst + filesz, 0, memsz - filesz);
>      return 0;
>  }
>  #else
> @@ -126,16 +127,17 @@ void elf_set_verbose(struct elf_binary *elf)
>      elf->verbose = 1;
>  }
>
> -static int elf_load_image(struct elf_binary *elf,
> -                          void *dst, const void *src, uint64_t filesz, 
> uint64_t memsz)
> +static int elf_load_image(struct elf_binary *elf, ELF_PTRVAL_VOID dst, 
> ELF_PTRVAL_CONST_VOID src, uint64_t filesz, uint64_t memsz)
>  {
>      int rc;
>      if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
>          return -1;
> -    rc = raw_copy_to_guest(dst, src, filesz);
> +    /* We trust the dom0 kernel image completely, so we don't care
> +     * about overruns etc. here. */
> +    rc = raw_copy_to_guest(ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), filesz);
>      if ( rc != 0 )
>          return -1;
> -    rc = raw_clear_guest(dst + filesz, memsz - filesz);
> +    rc = raw_clear_guest(ELF_UNSAFE_PTR(dst + filesz), memsz - filesz);
>      if ( rc != 0 )
>          return -1;
>      return 0;
> @@ -146,10 +148,10 @@ static int elf_load_image(struct elf_binary *elf,
>  void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
>  {
>      uint64_t sz;
> -    const elf_shdr *shdr;
> +    ELF_HANDLE_DECL(elf_shdr) shdr;
>      int i, type;
>
> -    if ( !elf->sym_tab )
> +    if ( !ELF_HANDLE_VALID(elf->sym_tab) )
>          return;
>
>      pstart = elf_round_up(elf, pstart);
> @@ -166,7 +168,7 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t 
> pstart)
>      for ( i = 0; i < elf_shdr_count(elf); i++ )
>      {
>          shdr = elf_shdr_by_index(elf, i);
> -        type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
> +        type = elf_uval(elf, shdr, sh_type);
>          if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
>              sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
>      }
> @@ -177,10 +179,12 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t 
> pstart)
>
>  static void elf_load_bsdsyms(struct elf_binary *elf)
>  {
> -    elf_ehdr *sym_ehdr;
> +    ELF_HANDLE_DECL_NONCONST(elf_ehdr) sym_ehdr;
>      unsigned long sz;
> -    char *maxva, *symbase, *symtab_addr;
> -    elf_shdr *shdr;
> +    ELF_PTRVAL_VOID maxva;
> +    ELF_PTRVAL_VOID symbase;
> +    ELF_PTRVAL_VOID symtab_addr;
> +    ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr;
>      int i, type;
>
>      if ( !elf->bsd_symtab_pstart )
> @@ -189,18 +193,18 @@ static void elf_load_bsdsyms(struct elf_binary *elf)
>  #define elf_hdr_elm(_elf, _hdr, _elm, _val)     \
>  do {                                            \
>      if ( elf_64bit(_elf) )                      \
> -        (_hdr)->e64._elm = _val;                \
> +        elf_store_field(_elf, _hdr, e64._elm, _val);  \
>      else                                        \
> -        (_hdr)->e32._elm = _val;                \
> +        elf_store_field(_elf, _hdr, e32._elm, _val);  \
>  } while ( 0 )
>
>      symbase = elf_get_ptr(elf, elf->bsd_symtab_pstart);
>      symtab_addr = maxva = symbase + sizeof(uint32_t);
>
>      /* Set up Elf header. */
> -    sym_ehdr = (elf_ehdr *)symtab_addr;
> +    sym_ehdr = ELF_MAKE_HANDLE(elf_ehdr, symtab_addr);
>      sz = elf_uval(elf, elf->ehdr, e_ehsize);
> -    memcpy(sym_ehdr, elf->ehdr, sz);
> +    elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(sym_ehdr), 
> ELF_HANDLE_PTRVAL(elf->ehdr), sz);
>      maxva += sz; /* no round up */
>
>      elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
> @@ -209,37 +213,39 @@ do {                                            \
>      elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
>
>      /* Copy Elf section headers. */
> -    shdr = (elf_shdr *)maxva;
> +    shdr = ELF_MAKE_HANDLE(elf_shdr, maxva);
>      sz = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
> -    memcpy(shdr, elf->image + elf_uval(elf, elf->ehdr, e_shoff), sz);
> -    maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
> +    elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(shdr),
> +                    ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
> +                    sz);
> +    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
>
>      for ( i = 0; i < elf_shdr_count(elf); i++ )
>      {
>          type = elf_uval(elf, shdr, sh_type);
>          if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
>          {
> -             elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
> +             elf_msg(elf, "%s: shdr %i at 0x%"ELF_PRPTRVAL" -> 
> 0x%"ELF_PRPTRVAL"\n", __func__, i,
>                       elf_section_start(elf, shdr), maxva);
>               sz = elf_uval(elf, shdr, sh_size);
> -             memcpy(maxva, elf_section_start(elf, shdr), sz);
> +             elf_memcpy_safe(elf, maxva, elf_section_start(elf, shdr), sz);
>               /* Mangled to be based on ELF header location. */
>               elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
> -             maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
> +             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + 
> sz);
>          }
> -        shdr = (elf_shdr *)((long)shdr +
> +        shdr = ELF_MAKE_HANDLE(elf_shdr, ELF_HANDLE_PTRVAL(shdr) +
>                              (long)elf_uval(elf, elf->ehdr, e_shentsize));
>      }
>
>      /* Write down the actual sym size. */
> -    *(uint32_t *)symbase = maxva - symtab_addr;
> +    elf_store_val(elf, uint32_t, symbase, maxva - symtab_addr);
>
>  #undef elf_ehdr_elm
>  }
>
>  void elf_parse_binary(struct elf_binary *elf)
>  {
> -    const elf_phdr *phdr;
> +    ELF_HANDLE_DECL(elf_phdr) phdr;
>      uint64_t low = -1;
>      uint64_t high = 0;
>      uint64_t i, count, paddr, memsz;
> @@ -267,9 +273,9 @@ void elf_parse_binary(struct elf_binary *elf)
>
>  int elf_load_binary(struct elf_binary *elf)
>  {
> -    const elf_phdr *phdr;
> +    ELF_HANDLE_DECL(elf_phdr) phdr;
>      uint64_t i, count, paddr, offset, filesz, memsz;
> -    char *dest;
> +    ELF_PTRVAL_VOID dest;
>
>      count = elf_uval(elf, elf->ehdr, e_phnum);
>      for ( i = 0; i < count; i++ )
> @@ -282,9 +288,9 @@ int elf_load_binary(struct elf_binary *elf)
>          filesz = elf_uval(elf, phdr, p_filesz);
>          memsz = elf_uval(elf, phdr, p_memsz);
>          dest = elf_get_ptr(elf, paddr);
> -        elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n",
> -                __func__, i, dest, dest + filesz);
> -        if ( elf_load_image(elf, dest, elf->image + offset, filesz, memsz) 
> != 0 )
> +        elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%"ELF_PRPTRVAL" -> 
> 0x%"ELF_PRPTRVAL"\n",
> +                __func__, i, dest, (ELF_PTRVAL_VOID)(dest + filesz));
> +        if ( elf_load_image(elf, dest, ELF_IMAGE_BASE(elf) + offset, filesz, 
> memsz) != 0 )
>              return -1;
>      }
>
> @@ -292,18 +298,18 @@ int elf_load_binary(struct elf_binary *elf)
>      return 0;
>  }
>
> -void *elf_get_ptr(struct elf_binary *elf, unsigned long addr)
> +ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr)
>  {
>      return elf->dest + addr - elf->pstart;
>  }
>
>  uint64_t elf_lookup_addr(struct elf_binary * elf, const char *symbol)
>  {
> -    const elf_sym *sym;
> +    ELF_HANDLE_DECL(elf_sym) sym;
>      uint64_t value;
>
>      sym = elf_sym_by_name(elf, symbol);
> -    if ( sym == NULL )
> +    if ( !ELF_HANDLE_VALID(sym) )
>      {
>          elf_err(elf, "%s: not found: %s\n", __FUNCTION__, symbol);
>          return -1;
> diff --git a/xen/common/libelf/libelf-tools.c 
> b/xen/common/libelf/libelf-tools.c
> index 1f08407..bf68bcd 100644
> --- a/xen/common/libelf/libelf-tools.c
> +++ b/xen/common/libelf/libelf-tools.c
> @@ -67,10 +67,10 @@ int elf_phdr_count(struct elf_binary *elf)
>      return elf_uval(elf, elf->ehdr, e_phnum);
>  }
>
> -const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name)
> +ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const 
> char *name)
>  {
>      uint64_t count = elf_shdr_count(elf);
> -    const elf_shdr *shdr;
> +    ELF_HANDLE_DECL(elf_shdr) shdr;
>      const char *sname;
>      int i;
>
> @@ -81,76 +81,80 @@ const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, 
> const char *name)
>          if ( sname && !strcmp(sname, name) )
>              return shdr;
>      }
> -    return NULL;
> +    return ELF_INVALID_HANDLE(elf_shdr);
>  }
>
> -const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index)
> +ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int 
> index)
>  {
>      uint64_t count = elf_shdr_count(elf);
> -    const void *ptr;
> +    ELF_PTRVAL_CONST_VOID ptr;
>
>      if ( index >= count )
> -        return NULL;
> +        return ELF_INVALID_HANDLE(elf_shdr);
>
> -    ptr = (elf->image
> +    ptr = (ELF_IMAGE_BASE(elf)
>             + elf_uval(elf, elf->ehdr, e_shoff)
>             + elf_uval(elf, elf->ehdr, e_shentsize) * index);
> -    return ptr;
> +    return ELF_MAKE_HANDLE(elf_shdr, ptr);
>  }
>
> -const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index)
> +ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int 
> index)
>  {
>      uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
> -    const void *ptr;
> +    ELF_PTRVAL_CONST_VOID ptr;
>
>      if ( index >= count )
> -        return NULL;
> +        return ELF_INVALID_HANDLE(elf_phdr);
>
> -    ptr = (elf->image
> +    ptr = (ELF_IMAGE_BASE(elf)
>             + elf_uval(elf, elf->ehdr, e_phoff)
>             + elf_uval(elf, elf->ehdr, e_phentsize) * index);
> -    return ptr;
> +    return ELF_MAKE_HANDLE(elf_phdr, ptr);
>  }
>
> -const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr)
> +
> +const char *elf_section_name(struct elf_binary *elf,
> +                             ELF_HANDLE_DECL(elf_shdr) shdr)
>  {
> -    if ( elf->sec_strtab == NULL )
> +    if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
>          return "unknown";
> +
>      return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
>  }
>
> -const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr)
> +ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_shdr) shdr)
>  {
> -    return elf->image + elf_uval(elf, shdr, sh_offset);
> +    return ELF_IMAGE_BASE(elf) + elf_uval(elf, shdr, sh_offset);
>  }
>
> -const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr)
> +ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_shdr) shdr)
>  {
> -    return elf->image
> +    return ELF_IMAGE_BASE(elf)
>          + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
>  }
>
> -const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr)
> +ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_phdr) phdr)
>  {
> -    return elf->image + elf_uval(elf, phdr, p_offset);
> +    return ELF_IMAGE_BASE(elf)
> +        + elf_uval(elf, phdr, p_offset);
>  }
>
> -const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr)
> +ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_phdr) phdr)
>  {
> -    return elf->image
> +    return ELF_IMAGE_BASE(elf)
>          + elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
>  }
>
> -const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
> +ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char 
> *symbol)
>  {
> -    const void *ptr = elf_section_start(elf, elf->sym_tab);
> -    const void *end = elf_section_end(elf, elf->sym_tab);
> -    const elf_sym *sym;
> +    ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
> +    ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
> +    ELF_HANDLE_DECL(elf_sym) sym;
>      uint64_t info, name;
>
>      for ( ; ptr < end; ptr += elf_size(elf, sym) )
>      {
> -        sym = ptr;
> +        sym = ELF_MAKE_HANDLE(elf_sym, ptr);
>          info = elf_uval(elf, sym, st_info);
>          name = elf_uval(elf, sym, st_name);
>          if ( ELF32_ST_BIND(info) != STB_GLOBAL )
> @@ -159,33 +163,33 @@ const elf_sym *elf_sym_by_name(struct elf_binary *elf, 
> const char *symbol)
>              continue;
>          return sym;
>      }
> -    return NULL;
> +    return ELF_INVALID_HANDLE(elf_sym);
>  }
>
> -const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index)
> +ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
>  {
> -    const void *ptr = elf_section_start(elf, elf->sym_tab);
> -    const elf_sym *sym;
> +    ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
> +    ELF_HANDLE_DECL(elf_sym) sym;
>
> -    sym = ptr + index * elf_size(elf, sym);
> +    sym = ELF_MAKE_HANDLE(elf_sym, ptr + index * elf_size(elf, sym));
>      return sym;
>  }
>
> -const char *elf_note_name(struct elf_binary *elf, const elf_note * note)
> +const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) 
> note)
>  {
> -    return (void *)note + elf_size(elf, note);
> +    return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note);
>  }
>
> -const void *elf_note_desc(struct elf_binary *elf, const elf_note * note)
> +ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_note) note)
>  {
>      int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
>
> -    return (void *)note + elf_size(elf, note) + namesz;
> +    return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz;
>  }
>
> -uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note)
> +uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) 
> note)
>  {
> -    const void *desc = elf_note_desc(elf, note);
> +    ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
>      int descsz = elf_uval(elf, note, descsz);
>
>      switch (descsz)
> @@ -200,10 +204,10 @@ uint64_t elf_note_numeric(struct elf_binary *elf, const 
> elf_note * note)
>      }
>  }
>
> -uint64_t elf_note_numeric_array(struct elf_binary *elf, const elf_note *note,
> +uint64_t elf_note_numeric_array(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_note) note,
>                                  unsigned int unitsz, unsigned int idx)
>  {
> -    const void *desc = elf_note_desc(elf, note);
> +    ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
>      int descsz = elf_uval(elf, note, descsz);
>
>      if ( descsz % unitsz || idx >= descsz / unitsz )
> @@ -220,12 +224,12 @@ uint64_t elf_note_numeric_array(struct elf_binary *elf, 
> const elf_note *note,
>      }
>  }
>
> -const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
> +ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_note) note)
>  {
>      int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
>      int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
>
> -    return (void *)note + elf_size(elf, note) + namesz + descsz;
> +    return ELF_MAKE_HANDLE(elf_note, ELF_HANDLE_PTRVAL(note) + elf_size(elf, 
> note) + namesz + descsz);
>  }
>
>  /* ------------------------------------------------------------------------ 
> */
> @@ -234,10 +238,10 @@ int elf_is_elfbinary(const void *image)
>  {
>      const Elf32_Ehdr *ehdr = image;
>
> -    return IS_ELF(*ehdr);
> +    return IS_ELF(*ehdr); /* fixme unchecked */
>  }
>
> -int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
> +int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) 
> phdr)
>  {
>      uint64_t p_type = elf_uval(elf, phdr, p_type);
>      uint64_t p_flags = elf_uval(elf, phdr, p_flags);
> diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
> index ae03982..dc9b5ae 100644
> --- a/xen/include/xen/libelf.h
> +++ b/xen/include/xen/libelf.h
> @@ -48,6 +48,97 @@ typedef void elf_log_callback(struct elf_binary*, void 
> *caller_data,
>
>  /* ------------------------------------------------------------------------ 
> */
>
> +/* Macros for accessing the input image and output area. */
> +
> +/*
> + * We abstract away the pointerness of these pointers, replacing
> + * various void*, char* and struct* with the following:
> + *   PTRVAL      A pointer to a byte; one can do pointer arithmetic
> + *               on this.
> + *               This replaces variables which were char*,void*
> + *               and their const versions, so we provide four
> + *               different declaration macros:
> + *                   ELF_PTRVAL_{,CONST}{VOID,CHAR}
> + *   HANDLE      A pointer to a struct.  There is one of these types
> + *               for each pointer type - that is, for each "structname".
> + *               In the arguments to the various HANDLE macros, structname
> + *               must be a single identifier which is a typedef.
> + *               It is not permitted to do arithmetic on these
> + *               pointers.  In the current code attempts to do so will
> + *               compile, but in the next patch this will become a
> + *               compile error.
> + *               We provide two declaration macros for const and
> + *               non-const pointers.
> + */
> +
> +#define ELF_REALPTR2PTRVAL(realpointer) (realpointer)
> +  /* Converts an actual C pointer into a PTRVAL */
> +
> +#define ELF_HANDLE_DECL_NONCONST(structname)  structname *
> +#define ELF_HANDLE_DECL(structname)           const structname *
> +  /* Provides a type declaration for a HANDLE. */
> +  /* May only be used to declare ONE variable at a time */
> +
> +#define ELF_PTRVAL_VOID         void *
> +#define ELF_PTRVAL_CHAR         char *
> +#define ELF_PTRVAL_CONST_VOID   const void *
> +#define ELF_PTRVAL_CONST_CHAR   const char *
> +  /* Provides a type declaration for a PTRVAL. */
> +  /* May only be used to declare ONE variable at a time */
> +
> +#define ELF_DEFINE_HANDLE(structname) /* empty */
> +  /*
> +   * This must be invoked for each HANDLE type to define
> +   * the actual C type used for that kind of HANDLE.
> +   */
> +
> +#define ELF_PRPTRVAL "p"
> +  /* printf format a la PRId... for a PTRVAL */
> +
> +#define ELF_MAKE_HANDLE(structname, ptrval) (ptrval)
> +  /* Converts a PTRVAL to a HANDLE */
> +
> +#define ELF_IMAGE_BASE(elf) ((elf)->image)
> +  /* Returns the base of the image as a PTRVAL. */
> +
> +#define ELF_HANDLE_PTRVAL(handleval) ((void*)(handleval))
> +  /* Converts a HANDLE to a PTRVAL. */
> +
> +#define ELF_OBSOLETE_VOIDP_CAST (void*)(uintptr_t)
> +  /*
> +   * In some places the existing code needs to
> +   *  - cast away const (the existing code uses const a fair
> +   *    bit but actually sometimes wants to write to its input)
> +   *    from a PTRVAL.
> +   *  - convert an integer representing a pointer to a PTRVAL
> +   * This macro provides a suitable cast.
> +   */
> +
> +#define ELF_UNSAFE_PTR(ptrval) ((void*)(ptrval))
> +  /*
> +   * Turns a PTRVAL into an actual C pointer.  Before this is done
> +   * the caller must have ensured that the PTRVAL does in fact point
> +   * to a permissible location.
> +   */
> +
> +/* PTRVALs can be INVALID (ie, NULL). */
> +#define ELF_INVALID_PTRVAL            (NULL)        /* returns NULL PTRVAL */
> +#define ELF_INVALID_HANDLE(structname)             /* returns NULL handle */ 
> \
> +    ELF_MAKE_HANDLE(structname, ELF_INVALID_PTRVAL)
> +#define ELF_PTRVAL_VALID(ptrval)      (ptrval)            /* }            */
> +#define ELF_HANDLE_VALID(handleval)   (handleval)         /* } predicates */
> +#define ELF_PTRVAL_INVALID(ptrval)    ((ptrval) == NULL)  /* }            */
> +
> +/* For internal use by other macros here */
> +#define ELF__HANDLE_FIELD_TYPE(handleval, elm) \
> +  typeof((handleval)->elm)
> +#define ELF__HANDLE_FIELD_OFFSET(handleval, elm) \
> +  offsetof(typeof(*(handleval)),elm)
> +
> +
> +/* ------------------------------------------------------------------------ 
> */
> +
> +
>  typedef union {
>      Elf32_Ehdr e32;
>      Elf64_Ehdr e64;
> @@ -83,6 +174,12 @@ typedef union {
>      Elf64_Note e64;
>  } elf_note;
>
> +ELF_DEFINE_HANDLE(elf_ehdr)
> +ELF_DEFINE_HANDLE(elf_shdr)
> +ELF_DEFINE_HANDLE(elf_phdr)
> +ELF_DEFINE_HANDLE(elf_sym)
> +ELF_DEFINE_HANDLE(elf_note)
> +
>  struct elf_binary {
>      /* elf binary */
>      const char *image;
> @@ -90,10 +187,10 @@ struct elf_binary {
>      char class;
>      char data;
>
> -    const elf_ehdr *ehdr;
> -    const char *sec_strtab;
> -    const elf_shdr *sym_tab;
> -    const char *sym_strtab;
> +    ELF_HANDLE_DECL(elf_ehdr) ehdr;
> +    ELF_PTRVAL_CONST_CHAR sec_strtab;
> +    ELF_HANDLE_DECL(elf_shdr) sym_tab;
> +    ELF_PTRVAL_CONST_CHAR sym_strtab;
>
>      /* loaded to */
>      char *dest;
> @@ -135,45 +232,72 @@ struct elf_binary {
>       : elf_access_unsigned((elf), (str),                                \
>                             offsetof(typeof(*(str)),e32.elem),           \
>                             sizeof((str)->e32.elem)))
> +  /*
> +   * Reads an unsigned field in a header structure in the ELF.
> +   * str is a HANDLE, and elem is the field name in it.
> +   */
>
>  #define elf_size(elf, str)                              \
>      ((ELFCLASS64 == (elf)->class)                       \
>       ? sizeof((str)->e64) : sizeof((str)->e32))
> +  /*
> +   * Returns the size of the substructure for the appropriate 32/64-bitness.
> +   * str should be a HANDLE.
> +   */
>
> -uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
> +uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID 
> ptr,
>                               uint64_t offset, size_t size);
> +  /* Reads a field at arbitrary offset and alignemnt */
>
>  uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
>
> +
> +#define elf_memcpy_safe(elf, dst, src, sz) memcpy((dst),(src),(sz))
> +#define elf_memset_safe(elf, dst, c, sz)   memset((dst),(c),(sz))
> +  /*
> +   * Versions of memcpy and memset which will (in the next patch)
> +   * arrange never to write outside permitted areas.
> +   */
> +
> +#define elf_store_val(elf, type, ptr, val)   (*(type*)(ptr) = (val))
> +  /* Stores a value at a particular PTRVAL. */
> +
> +#define elf_store_field(elf, hdr, elm, val)                     \
> +    (elf_store_val((elf), ELF__HANDLE_FIELD_TYPE(hdr, elm),     \
> +                   &((hdr)->elm),                               \
> +                   (val)))
> +  /* Stores a 32/64-bit field.  hdr is a HANDLE and elm is the field name. */
> +
> +
>  /* ------------------------------------------------------------------------ 
> */
>  /* xc_libelf_tools.c                                                        
> */
>
>  int elf_shdr_count(struct elf_binary *elf);
>  int elf_phdr_count(struct elf_binary *elf);
>
> -const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name);
> -const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index);
> -const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index);
> +ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const 
> char *name);
> +ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int 
> index);
> +ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int 
> index);
>
> -const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr);
> -const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr);
> -const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr);
> +const char *elf_section_name(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_shdr) shdr);
> +ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_shdr) shdr);
> +ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_shdr) shdr);
>
> -const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr);
> -const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr);
> +ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_phdr) phdr);
> +ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_phdr) phdr);
>
> -const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol);
> -const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index);
> +ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char 
> *symbol);
> +ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
>
> -const char *elf_note_name(struct elf_binary *elf, const elf_note * note);
> -const void *elf_note_desc(struct elf_binary *elf, const elf_note * note);
> -uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note);
> -uint64_t elf_note_numeric_array(struct elf_binary *, const elf_note *,
> +const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) 
> note);
> +ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_note) note);
> +uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) 
> note);
> +uint64_t elf_note_numeric_array(struct elf_binary *, 
> ELF_HANDLE_DECL(elf_note),
>                                  unsigned int unitsz, unsigned int idx);
> -const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note);
> +ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, 
> ELF_HANDLE_DECL(elf_note) note);
>
>  int elf_is_elfbinary(const void *image);
> -int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
> +int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) 
> phdr);
>
>  /* ------------------------------------------------------------------------ 
> */
>  /* xc_libelf_loader.c                                                       
> */
> @@ -189,7 +313,7 @@ void elf_set_log(struct elf_binary *elf, 
> elf_log_callback*,
>  void elf_parse_binary(struct elf_binary *elf);
>  int elf_load_binary(struct elf_binary *elf);
>
> -void *elf_get_ptr(struct elf_binary *elf, unsigned long addr);
> +ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr);
>  uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
>
>  void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private 
> */
> @@ -221,9 +345,9 @@ struct xen_elfnote {
>
>  struct elf_dom_parms {
>      /* raw */
> -    const char *guest_info;
> -    const void *elf_note_start;
> -    const void *elf_note_end;
> +    ELF_PTRVAL_CONST_CHAR guest_info;
> +    ELF_PTRVAL_CONST_VOID elf_note_start;
> +    ELF_PTRVAL_CONST_VOID elf_note_end;
>      struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1];
>
>      /* parsed */
> @@ -262,10 +386,22 @@ int elf_xen_parse_features(const char *features,
>                             uint32_t *required);
>  int elf_xen_parse_note(struct elf_binary *elf,
>                         struct elf_dom_parms *parms,
> -                       const elf_note *note);
> +                       ELF_HANDLE_DECL(elf_note) note);
>  int elf_xen_parse_guest_info(struct elf_binary *elf,
>                               struct elf_dom_parms *parms);
>  int elf_xen_parse(struct elf_binary *elf,
>                    struct elf_dom_parms *parms);
>
> +#define elf_memcpy_unchecked memcpy
> +#define elf_memset_unchecked memset
> +  /*
> +   * Unsafe versions of memcpy and memset which take actual C
> +   * pointers.  These are just like real memcpy and memset.
> +   */
> +
> +
> +#define ELF_ADVANCE_DEST(elf, amount)  elf->dest += (amount)
> +  /* Advances past amount bytes of the current destination area. */
> +
> +
>  #endif /* __XEN_LIBELF_H__ */
> --
> 1.7.2.5
>


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.